Sign in to follow this  
Followers 0
Jules

_FFGetPosition gives error "Array variable has incorrect number of subscripts or subscript dimension range exceeded"

3 posts in this topic

Hello :),

I am developing a script with AutoIt for Firefox, to automate performance tests. I have a map, that I have to wait to be loaded, and then I have to click at the center of this map.

In order to do this, I get the position of the HTML element representing the map, then I perform a few calculations to find center coordinates. But I have a problem.

I use the FF.au3 library, and the function _FFGetPosition to get the coordinates. My function call is

$CoordCarte = _FFGetPosition(".getElementById('OpenLayers.Layer.Annotation_3_svgRoot')")

and AutoIt gives me this error :

"C:\Program Files\AutoIt3\Include\FF.au3" (1928) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:
Local $aRet[6] = [$aElement[0], $aElement[1], $aContent[0], $aContent[1], $aContent[2], $aContent[3]]
Local $aRet[6] = [$aElement[0], ^ ERROR

I checked the HTML id of the element, and it is correct (I checked in Firefox with Javascript console).

I really can't figure out what is my mistake. Could you help me please ?

 

If this can help you, here is my script (comments are in French) :

; ##########
; INCLUSIONS
; ##########
#include <Array.au3>
#include <FF.au3>
#include <String.au3>


; ##################
; PARAMETRES GLOBAUX
; ##################
Opt("SendKeyDownDelay",80) ; pas trop rapide pour éviter que des frappes soient perdues
Opt("WinTitleMatchMode", 3) ; Noms des fenêtres correspondant exactement
Opt("GUIEventOptions", 1)


; ################################################
; ######## FONCTIONS POUR TESTS DE PERF. #########
; ################################################

Func FaireUnTest()
   ; Faire un test de performance pour ArcMap
   ;
   ; Return :
   ; Une chaine de caractères avec les temps de chaque tâche, séparés par des point-virgules

   Local $LigneTemps = "" ; Contient le temps de chaque tâche, séparés par des point-virgules

   ; Démarrer Firefox
   _FFStart()

   ; Handle de la fenêtre Firefox ouverte
   $hFirefox = _FFWindowGetHandle()

   ; Connexion MozRepl
   _FFConnect()



   ; ###########################
   ; ###########################
   ; ######### TACHE 1 #########
   ; ###########################
   ; ###########################

   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   ; Connexion au site de Carmen ;
   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

   ; Initialisation nouveau timer
   $hTimer = TimerInit()

   ; Aller à l'URL de Carmen et attendre son chargement
   _FFOpenURL("http://carmen.carmencarto.fr/179/OSUR.map#")

   ; Attendre le chargement de la carte
   AttendreChargementCarte()

   ; Ajout temps de la tâche
   $LigneTemps = $LigneTemps & ";" & TimerDiff($hTimer) / 1000

   ; ###########################
   ; ###########################
   ; ######### TACHE 2 #########
   ; ###########################
   ; ###########################

   ;;;;;;;;;;;;;;;;;;;;;
   ; Localiser 'ACHUN' ;
   ;;;;;;;;;;;;;;;;;;;;;

   ; Initialisation nouveau timer
   $hTimer = TimerInit()

   ; L'échelle avant le zoom
   $queryEchelle = ".getElementsByClassName('DescartesGraphicScale')[1].textContent"
   $EchelleAvantZoom = _FFCmd($queryEchelle)

   ; On écrit 'ACHUN' dans le champ de commune
   $InputCommune = _FFObjGet("combo2", "id")
   _FFObj($InputCommune, "value", "ACHUN")

   ; Il faut ensuite sélectionner l'élément 'ACHUN' dans la liste déroulante
   ControlSend($hFirefox, "", "", _StringRepeat("{TAB}", 27)) ; focus sur liste déroulante 'Commune'
   ControlSend($hFirefox, "", "", _StringRepeat("{DOWN}", 7)) ; sélection élément 'ACHUN'
   ControlSend($hFirefox, "", "", "{ENTER}") ; validation

   ; Clic bouton 'Localiser'
   _FFClick("button", "tag", 0)

   ; Attendre que le zoom soit fait (ie un changement d'échelle)
   While _FFCmd($queryEchelle) = $EchelleAvantZoom
   WEnd

   ; Attendre le chargement de la carte
   AttendreChargementCarte()

   ; Ajout temps de la tâche
   $LigneTemps = $LigneTemps & ";" & TimerDiff($hTimer) / 1000



   ; ###########################
   ; ###########################
   ; ######### TACHE 3 #########
   ; ###########################
   ; ###########################

   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   ; Sélection d'une station  ;
   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;

   ;########## NE COMPTE PAS DANS LES MESURES ##########

   ; Inputs 'x' et 'y' de la page web
   $InputX = _FFObjGet("x", "id")
   $InputY = _FFObjGet("y", "id")

   ; Saisie de la position géographique (dans la carte) de la station '04023310'
   _FFObj($InputX, "value", "747562")
   _FFObj($InputY, "value", "6667893")

   ; Centrage de la carte sur la station '04023310'
   ControlSend($hFirefox, "", "", _StringRepeat("{TAB}", 7)) ; focus sur bouton 'Centrer'
   ControlSend($hFirefox, "", "", "{ENTER}") ; validation

   ; On attend le chargement
   AttendreChargementCarte()

   ;########## LA SUITE COMPTE MAINTENANT POUR LES MESURES ##########


   ; Initialisation nouveau timer
   $hTimer = TimerInit()

   ; Clic bouton "Interroger les couches" (après navigation avec {TAB} car cela aurait ouvert une fenêtre non voulue)
   _FFClick("button", "tag", 9)


   ;$x = _FFObjGet("OpenLayers.Layer.Annotation_3_svgRoot", "id")
   ;MsgBox(0, $x, $x)
   ; Coordonnées de la carte, relativement à l'écran d'ordinateur
   $CoordCarte = _FFGetPosition(".getElementById('OpenLayers.Layer.Annotation_3_svgRoot')")


   ; Coordonnées coin supérieur gauche
   $XDebCarte = $CoordCarte[2]
   $YDebCarte = $CoordCarte[3]

   MsgBox(0, "$XDebCarte = ", $XDebCarte)
   MsgBox(0, "$YDebCarte = ", $YDebCarte)

   ; Coordonnées coin inférieur droit
   $XFinCarte = $XDebCarte + $CoordCarte[4]
   $YFinCarte = $YDebCarte + $CoordCarte[5]

   MsgBox(0, "$XFinCarte = ", $XDebCarte)
   MsgBox(0, "$YFinCarte = ", $YDebCarte)

   ; Coordonnées du centre de la carte, relativement à l'écran d'ordinateur
   $XMilieuCarte = ($XDebCarte + $XFinCarte) / 2
   $YMilieuCarte = ($YDebCarte + $YFinCarte) / 2

   MsgBox(0, "$XMilieuCarte = ", $XDebCarte)
   MsgBox(0, "$YMilieuCarte = ", $YDebCarte)

   ; Cliquer au milieu de la carte
   MouseClick("left", $XMilieuCarte, $YMilieuCarte, 1, 1)



EndFunc

FaireUnTest()


Func AttendreChargementCarte()
   ; Met le script en pause jusqu'au chargement complet
   ; de la carte de l'application Carmen

   ; Code JavaScript pour récupérer les images de la carte
   $imagesQuery = ".getElementsByClassName('olTileImage')"

   ; Le nombre d'images de la carte
   $NbImages = _FFCmd($imagesQuery & ".length")

   ; On attend que toutes les images de la carte soit chargées
   For $i = 0 To $NbImages - 1

      ; Le code JavaScript pour savoir si la i-ème image est chargée
      $imageCompleteQuery = $imagesQuery & "[" & $i & "].complete"

      ; Et on attend qu'elle soit chargée
      While Not _FFCmd($imageCompleteQuery)
      WEnd

   Next

EndFunc

 

Share this post


Link to post
Share on other sites



#3 ·  Posted (edited)

I downloaded the most recent version, but I still have the same error.

To me, the _FFGetPosition function takes as argument a String containing Javascript code that returns an element from the DOM.

Edited by Jules

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Similar Content

    • BOUNCER
      By BOUNCER
      I'm trying to get the output data from https://www.guilded.gg but it uses a web app that generates that output on the fly and this doesn't show up in the page source.
      Only in web inspector of each browser does this data show up. How do I read this data in autoit (equivalent to the web inspector)
       
      thank you
    • Pao
      By Pao
      Hello, I've recently updated from Firefox 50 to 54.0.1.
      My Autoit script that previously worked fine, now seems to have erratic problems.
      It's almost as if some Send() commands are sometimes skipped when dealing with the Firefox UI (it's still mostly fine on the actual pages).

      To temporarly fix the problem, I had to put some Sleep(200) pauses and avoid grouping keys together (e.g: TAB 2), but I'm not exactly sure about the correct way to deal with this..
      Could this be caused by the new multiprocess feature? (e10s)
      Are there better Autoit commands or rules that I should use?
       
    • czardas
      By czardas
      Haven't had much time to code recently. However the following thread inspired me.
      The debate about linear, parallel and binary search methods was rather interesting and, in an attempt to be diplomatic, I decided to combine @jchd's suggestion with @LarsJ's binary search example. I decided that the binary search algorithm required modification to make it more linear. As usual, 'if you invent something, it probably already exists and if it already exists, it exists for a reason'. My first attempt was not all that good. The code worked but was really a mess. I blame peer pressure (to post an example of a parallel search method).  I will delete that old code in due course.
      With a little memory jogging and a glance at the help file, the solution turned out to be quite easy: I just needed a better understanding of Euler. Further modification will be needed to work with more complicated unicode strings. The output could be returned as an array or a delimitered string. I'm not so interested in those details. I'm just going to post the algorithm for now and anyone, who wants to, can modify it to suit their needs. Both arrays must contain at least 1 element.
      Local $aFoo = [0,1,2,3,4,5,6,7,9,10,11,12,13,14,15,16,19,20,23,24,26,30,35,39,40,41] Local $aBar = [0,1,5,6,7,8,9,10,11,12,13,14,17,18,19,21,24,25,26,27,34,35,38,40] ParallelExponetialSearch($aFoo, $aBar) ; Compares two lists - returning positive matches. Each input array must be unique (individually) and in alphabetical order. Func ParallelExponetialSearch($aFoo, $aBar) Local $sFind, _ $iMin_F = -1, $iMax_F = UBound($aFoo) -1, $Lo_F = $iMin_F, $Hi_F, _ $iMin_B = -1, $iMax_B = UBound($aBar) -1, $Lo_B = $iMin_B, $Hi_B While $iMin_F < $iMax_F And $iMin_B < $iMax_B ; Toggle Arrays - Which array has most untested elements? This is the one we want to search next, ; so we can bypass more comparisons because (in theory) mismatches have a greater chance of being skipped. If $iMax_F - $iMin_F >= $iMax_B - $iMin_B Then ; $aFoo has more (or an equal number of) untested elements $Hi_F = $iMax_F $iMin_B += 1 $sFind = $aBar[$iMin_B] While $Lo_F < $Hi_F ; search $aFoo For $i = 0 To Floor(Log($Hi_F - $Lo_F) / Log(2)) $Lo_F = $iMin_F + 2^$i If $aFoo[$Lo_F] = $sFind Then $iMin_F = $Lo_F ; each match should be added to the output [perhaps an array] ConsoleWrite($sFind & " found at $aFoo[" & $Lo_F & "] = $aBar[" & $iMin_B & "]" & @LF) ExitLoop 2 ElseIf $aFoo[$Lo_F] > $sFind Then $Hi_F = $Lo_F -1 $iMin_F += Floor(2^($i -1)) $Lo_F = $iMin_F ContinueLoop 2 EndIf Next $iMin_F = $Lo_F ; minimum increment is one WEnd Else ; $aBar has more untested elements $Hi_B = $iMax_B $iMin_F += 1 $sFind = $aFoo[$iMin_F] While $Lo_B < $Hi_B ; search $aBar For $i = 0 To Floor(Log($Hi_B - $Lo_B) / Log(2)) $Lo_B = $iMin_B + 2^$i If $aBar[$Lo_B] = $sFind Then $iMin_B = $Lo_B ; each match should be added to the output [perhaps an array] ConsoleWrite($sFind & " found at $aFoo[" & $iMin_F & "] = $aBar[" & $Lo_B & "]" & @LF) ExitLoop 2 ElseIf $aBar[$Lo_B] > $sFind Then $Hi_B = $Lo_B -1 $iMin_B += Floor(2^($i -1)) $Lo_B = $iMin_B ContinueLoop 2 EndIf Next $iMin_B = $Lo_B ; minimum increment is one WEnd EndIf WEnd EndFunc ;==> ParallelExponetialSearch I hope this will be useful to someone. I believe it deserved a thread of its own!
    • RC86
      By RC86
      Afternoon!
      I have a requirement to return both a string and an array from a function so as a result I put them both into an array and returned that.  I can access them in their entirety after returning them but then I can't seem to access the array elements after this.  Should I be able to or is there a prettier way?
      #include <Array.au3> ;Memory info returned as a string and an array $memoryInfo = _getMemoryInfo() msgbox(0,"Memory Info",$memoryInfo[0]) _ArrayDisplay($memoryInfo[1],"Memory as an Array") Local $newArray[7] $memoryInfo[1] = $newArray msgbox(0,"Test element",$newArray[0]) _ArrayDisplay($newArray) Func _getMemoryInfo() Local $newArray[7] Local $array = MemGetStats() $newArray[0] = $array[0] ;% of memory in use $newArray[1] = Round($array[1]/1024 * 0.001,2) ;Total physical RAM $newArray[2] = Round($array[2]/1024 * 0.001,2) ;Availaible physical RAM $newArray[3] = Round($array[3]/1024 * 0.001,2) ;Total pagefile $newArray[4] = Round($array[4]/1024 * 0.001,2) ;Available pagefile $newArray[5] = Round($array[5]/1024 * 0.001,2) ;Total virtual $newArray[6] = Round($array[6]/1024 * 0.001,2) ;Available virtual $memoryUsage = $newArray[1] - $newarray[2] $pagefileUsage = $newArray[3] - $newarray[4] ;Output/Return Local $returnArray[2] $returnArray[0] = "Memory: " & $memoryUsage & " GB/" & $newArray[1] & " GB " & @CRLF & "Pagefile: " & $pagefileUsage & " GB/" & $newArray[3] & " GB " $returnArray[1] = $newArray return $returnArray EndFunc A bit messy but hopefully it's understandable what I'm trying to achieve.
      Thanks!
    • Jibberish
      By Jibberish
      I am having difficulties getting updated results from GUICtrlCreateInput. I wrote a small script to demonstrate what I am trying to do.
      This script reads a text file into an array and displays the Name and Number from the text file.
      The user can check a name and change the number, and the results are displayed in _ArrayDisplay.
      Only the Checked names are displayed in their original position. This is necessary for future
      plumbing.
      The problem with this script is the original number is returned, not the changed number. I cannot
      figure out how to get the updated number to be displayed.
      ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; ; This script reads a text file into an array and displays the Name and Number from the text file. ; The user can check a name and change the number, and the results are displayed in _ArrayDisplay. ; Only the Checked names are displayed in their original position. This is necessary for future ; plumbing. ; ; The problem with this script is the original number is returned, not the changed number. I cannot ; figure out how to get the updated number to be displayed. ; ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #include-once #include <MsgBoxConstants.au3> #include <array.au3> #include <Date.au3> #include <WinAPIFiles.au3> #include <AutoItConstants.au3> #include <Misc.au3> #include <File.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> Local $iMax = 6 ;Default number of Videos - 1 for the array counter Dim $aTextFile[$iMax][2] ; [start with 5 entries][Name, Number] Don't get confused! [Row][Column] Local $i = 0 Local $iLeft = 30 Local $iTop = 30 Local $sName Local $sNumber Local $aArray Local $iMaxCol = 5 Local $iRow = 0 Local $iCol = 0 Local $aNumberCount[$iMaxCol][2] $aArray1 = ReadFile() $aNamesNumbers = DisplayNames($aArray1) _ArrayDisplay($aNamesNumbers) ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; ; ReadFile() places the contents of the NameNumber.txt file in an array ; ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Func ReadFile() Local $sFileData = @ScriptDir & "\NameNumber.txt" Local $iStrReturn = 0 Local $aArrayFile Local $aTextFile[$iMaxCol][2] Local $aName Local $sCheckBox1 Const $iL = 10 ; Count from Left for GUI so all buttons line up Local $sFill Local $iA = 0, $iN = 0 ; Put the Names into an Array _FileReadToArray($sFileData, $aArrayFile) For $iA = 0 To $aArrayFile[0] ; Step through the array looking for Names If StringInStr($aArrayFile[$iA], "Name:") Then $aName = StringSplit($aArrayFile[$iA],":") $sFill = $aName[2] If UBound($aTextFile) <= $iRow Then ; Resize the array when $iRow is equal to the element count in the array to prevent subscript error ReDim $aTextFile[UBound($aTextFile) + 1][$iMaxCol] EndIf $aTextFile[$iRow][$iCol] = $sFill $iRow += 1 EndIf Next $iCol = 1 $iRow = 0 $sFill = "" For $iA = 1 To $aArrayFile[0] ; Step through the array looking for Numbers If StringInStr($aArrayFile[$iA], "Number:") Then $aName = StringSplit($aArrayFile[$iA],":") $sFill = $aName[2] If UBound($aTextFile) <= $iRow Then ; Resize the array when $iRow is equal to the element count in the array to prevent subscript error ReDim $aTextFile[UBound($aTextFile) + 1][$iMaxCol] EndIf $aTextFile[$iRow][$iCol] = $sFill $iRow += 1 EndIf Next Return $aTextFile EndFunc ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; ; Display the Name and Number ; ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Func DisplayNames($aArray1) Local $aName[$iMax] Local $aNumbers[$iMax] $iMMCount = UBound($aArray1) $iMMCount -=1 Local $iWidth = 300 Local $iLength = 300;$iMMCount * 30 GUISetFont(12) $hGUI = GUICreate("Edit / Update Number Test", $iWidth, $iLength, -1, -1) GUICtrlCreateLabel(" Name Number",1,5) ;$iTop += 30 ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; ; Display Name with a Checkbox. Only Checked Names should be saved. ; ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For $i = 0 to $iMMCount Step 1 $sNameText = $aArray1[$i][0] $iNameLength = StringLen($sNameText) $aName[$i] = GUICtrlCreateCheckbox($sNameText,$iLeft, $iTop) $iTop += 30 Next ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; ; Display the number from the text file below each name. Allow the user to change the number and display the ; new number. ; ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $iLeft = 60 GUIStartGroup() $iTop = 28 For $i = 0 to $iMMCount Step 1 $sNumberText = $aArray1[$i][1] $aNumberCount[$i][1] = $sNumberText $aNumberCount[$i][0] = GUICtrlCreateInput($sNumberText,$iLeft, $iTop, 50,18, $GUI_DOCKAUTO) GUICtrlSetPos($aNumberCount[$i][0],200) $iTop += 30 Next ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; ; Read the checked names and (possibly updated) number ; ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ $iMMCount = UBound($aNumberCount) $iMMNewCount = $iMMCount - 1 Local $aGUICheckbox[$iMMCount] Local $aCheckedNameNumber[$iMMCount][2] $iLeft = 30 Local $idCloseGUI = GUICtrlCreateButton("Close",$iLeft, $iTop) GUISetState(@SW_SHOW) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $idCloseGUI For $i = 0 To $iMMNewCount Step 1 Switch GUICtrlRead($aName[$i]) Case $GUI_CHECKED $aCheckedNameNumber[$i][0] = $aArray1[$i][0] Case $GUI_UNCHECKED EndSwitch Switch GUICtrlRead($aNumberCount[$i][0]) Case $aCheckedNameNumber[$i][1] = GUICtrlRead($aNumberCount[$i][1]) EndSwitch Next ExitLoop EndSwitch WEnd For $i = 0 to $iMMNewCount step 1 GUICtrlRead($aNumberCount[$i][0]) If $aCheckedNameNumber[$i][0] <> "" Then $aCheckedNameNumber[$i][1] = $aNumberCount[$i][1] EndIf Next GUIDelete($hGUI) Return $aCheckedNameNumber EndFunc This is the text file I am reading. If you want to try this out put the NameNumber.txt file in your script directory. It's attached to the post.
      * This is a dummy file with a Name and Number * The only purpose of this file is to read the updated Number. Name:Taggart Number:916 Name:Mongo Number:90 Name:Hedley Lamarr Number:22 Name:Bart Number:9999 Name:The Waco Kid Number:2244 If I change the number, the original number is displayed at the end, not the updated/modified number. I need the modified number to be displayed.
      Thanks in advance for any assistance!
      Jibberish
      NameNumber.txt