Closed mlipok closed 2 years ago
of course sometimes it will fire:
Uncaught DOMException: Permission denied to access property "document" on cross-origin object
for example here: https://www.w3schools.com/html/tryit.asp?filename=tryhtml_iframe_height_width
But I think that I can do this in another aproach.
- I don't agree with adding this functionality to _WD_FrameEnter. It would need to become a new, standalone function (ie: _WD_FrameList)
Ok.
- I'll have to try out your code on some different sites to better understand how nested frames are handled / represented
Waiting for your test results.
@mlipok Please post your Autoit code that implements the above so that I can perform some tests.
As for now I only have the JS code which I already posted in opening post. Just try it on different websites.
If the JS code will be it will be inspiring (for you), I will try to translate it more into AutoIt, because it will be required to go to a given Frame and check its data from the frame level.
Because using only JS we will hit this following restriction:
Uncaught DOMException: Permission denied to access property "document" on cross-origin object
Side note:
I studied JS and this was one of my test scripts that I had on my study list. For this reason, I only have JS and not AutoIt code. But anyway, I want to move it to AutoIt just waiting for your recommendation.
so I had such code:
Func _WD_FrameList($sSession)
Local $sResult = __WD_FrameList_Internal($sSession, 'null', '')
Return SetError(@error, @extended, $sResult)
EndFunc ;==>_WD_FrameList
Func __WD_FrameList_Internal($sSession, $s_level_string, $s_Path)
#WARRNING some kind of remark in the header should be aded first proposal below:
; changing frames may affect your further coding by changing contex in browser to different frames
Local Const $sFuncName = "_WD_FrameList"
Local $iErr = $_WD_ERROR_Success
Local $sResult = '', $s_URL = '', $sMessage = ''
If Not @compiled Then ConsoleWrite('TESTING=' & $s_level_string & '|' & $s_Path & @CRLF)
Local $a_Level = StringSplit($s_level_string, '/')
For $i =1 To $a_Level[0]
If $a_Level[$i] = 'null' Then
_WD_FrameEnter($sSession, Null)
Else
_WD_FrameEnter($sSession, Int($a_Level[$i]))
EndIf
If @error Then ExitLoop
Next
If @error Then
$sMessage = 'Error occured on "' & $s_level_string & '" level when trying to entering frame'
Else
$s_URL = _WD_ExecuteScript($sSession, "return window.location.href", Default, Default, $_WD_JSON_Value)
If @error Then
$sMessage = 'Error occured on "' & $s_level_string & '" level when checking URL'
Else
$sResult = $s_level_string & ' | ' & $s_URL & ' | ' & $s_Path & @CRLF
EndIf
EndIf
$iErr = @error
If Not @error Then
Local $iFrameCount = _WD_GetFrameCount($sSession)
$iErr = @error
If @error Then
$sMessage = 'Error occured on "' & $s_level_string & '" level when trying to check frames count'
Else
For $iFrame = 0 To $iFrameCount - 1
$s_Path = _WD_ExecuteScript($sSession, "return document.querySelectorAll('iframe')[" & $iFrame & "].outerHTML", Default, Default, $_WD_JSON_Value)
$iErr = @error
If @error Then
$sMessage = 'Error occured on "' & $s_level_string & '" level when trying to check atributes child frames #' & $iFrame
Else
$sResult &= __WD_FrameList_Internal($sSession, $s_level_string & '/' & $iFrame, $s_Path)
$iErr = @error
EndIf
If @error Then ExitLoop
Next
EndIf
EndIf
Return SetError(__WD_Error($sFuncName, $iErr, $sMessage), 0, $sResult)
EndFunc ;==>__WD_FrameList_Internal
test it with:
Func UserTesting() ; here you can replace the code to test your stuff before you ask on the forum
_WD_Navigate($sSession, 'https://www.w3schools.com')
_WD_LoadWait($sSession)
Local $sFrameList = _WD_FrameList($sSession)
ConsoleWrite($sFrameList & @CRLF)
Return
EndFunc
The only difference is that with AutoIt I get:
null | https://www.w3schools.com/ |
null/0 | https://www.w3schools.com/howto/tryhow_js_slideshow_ifr.htm | <iframe src="/howto/tryhow_js_slideshow_ifr.htm" id="howto_iframe"></iframe>
when JavaScript version (from opening post) shows:
null|https://www.w3schools.com/|
null/0|https://www.w3schools.com/howto/tryhow_js_slideshow_ifr.htm|<iframe src="/howto/tryhow_js_slideshow_ifr.htm" id="howto_iframe"></iframe>
null/1|about:blank|<iframe name="__tcfapiLocator" style="display: none;"></iframe>
null/2|about:blank|<iframe name="__uspapiLocator" style="display: none;"></iframe>
and this is related that the two other frames are not visible.
but it is related to
_WD_ExecuteScript ==> Javascript Exception [21] : Error occurred when trying to ExecuteScript
_WD_FrameList ==> Javascript Exception [21] : Error occured on "null" level when trying to check atributes child frames #1
wchich mean that _WD_GetFrameCount
is getting numbers of frame in wrong way.
Working on.
I found reason must find solution
now you can check:
#Region - UserTesting
Func UserTesting() ; here you can replace the code to test your stuff before you ask on the forum
_WD_Navigate($sSession, 'https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_iframe')
_WD_LoadWait($sSession)
; get frame list as string
ConsoleWrite(_WD_FrameList($sSession, False) & @CRLF)
; get frame list as array
Local $aFrameList = _WD_FrameList($sSession)
_ArrayDisplay($aFrameList)
Return
EndFunc ;==>UserTesting
Func _WD_FrameList($sSession, $bReturnAsArray = True)
Local $a_Result[0][3]
Local $vResult = __WD_FrameList_Internal($sSession, 'null', '')
If @error = $_WD_ERROR_Success Then
$vResult = StringTrimRight($vResult, 2) ; last @CRLF
If $bReturnAsArray then
_ArrayAdd($a_Result, $vResult)
$vResult = $a_Result
EndIf
EndIf
Return SetError(@error, @extended, $vResult)
EndFunc ;==>_WD_FrameList
Func __WD_FrameList_Internal($sSession, $s_level_string, $s_Path)
#WARRNING some kind of remark in the header should be aded first proposal below:
; changing frames may affect your further coding by changing contex in browser to different frames
Local Const $sFuncName = "_WD_FrameList"
Local $iErr = $_WD_ERROR_Success
Local $vResult = '', $s_URL = '', $sMessage = ''
Local $a_Level = StringSplit($s_level_string, '/')
For $i = 1 To $a_Level[0]
If $a_Level[$i] = 'null' Then
_WD_FrameEnter($sSession, Null)
Else
_WD_FrameEnter($sSession, Int($a_Level[$i]))
EndIf
If @error Then ExitLoop
Next
If @error Then
$sMessage = 'Error occured on "' & $s_level_string & '" level when trying to entering frame'
Else
$s_URL = _WD_ExecuteScript($sSession, "return window.location.href", Default, Default, $_WD_JSON_Value)
If @error Then
$sMessage = 'Error occured on "' & $s_level_string & '" level when checking URL'
Else
$vResult = $s_level_string & '| ' & $s_URL & '|' & $s_Path & @CRLF
EndIf
EndIf
$iErr = @error
If Not @error Then
Local $iFrameCount = _WD_GetFrameCount($sSession)
$iErr = @error
If $iErr Then
$sMessage = 'Error occured on "' & $s_level_string & '" level when trying to check frames count'
Else
For $iFrame = 0 To $iFrameCount - 1
$s_Path = _WD_ExecuteScript($sSession, "return document.querySelectorAll('iframe')[" & $iFrame & "].outerHTML;", Default, Default, $_WD_JSON_Value)
$iErr = @error
If @error Then
$sMessage = 'Error occured on "' & $s_level_string & '" level when trying to check atributes child frames #' & $iFrame
Else
$vResult &= __WD_FrameList_Internal($sSession, $s_level_string & '/' & $iFrame, $s_Path)
$iErr = @error
If Not @error Then
_WD_FrameLeave($sSession)
$iErr = @error
If @error Then
$sMessage = 'Error occured on "' & $s_level_string & '" level when trying to leave frames #' & $iFrame
EndIf
EndIf
EndIf
If @error Then ExitLoop
Next
EndIf
EndIf
Return SetError(__WD_Error($sFuncName, $iErr, $sMessage), 0, $vResult)
EndFunc ;==>__WD_FrameList_Internal
#EndRegion - UserTesting
my results are:
null| https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_iframe|
null/0| about:blank|<iframe id="iframeResult" name="iframeResult" allowfullscreen="true" frameborder="0"></iframe>
null/1| about:blank|<iframe style="display: none;" name="__tcfapiLocator"></iframe>
null/2| https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_iframe|<iframe style="display: none;" name="__uspapiLocator"></iframe>
null/2/0| https://www.w3schools.com/|<iframe src="https://www.w3schools.com" title="W3Schools Free Online Web Tutorials">
</iframe>
null/2/0/0| https://www.w3schools.com/howto/tryhow_js_slideshow_ifr.htm|<iframe src="/howto/tryhow_js_slideshow_ifr.htm" id="howto_iframe"></iframe>
null/2/0/1| about:blank|<iframe style="display: none;" name="__tcfapiLocator"></iframe>
null/2/0/2| about:blank|<iframe style="display: none;" name="__uspapiLocator"></iframe>
I wonder if it will be easier for You to test this FeatureRequest ISSUE ... if I make PR related to this ISSUE ?
No, that shouldn't be necessary. I just haven't been able to test it yet due to other priorities. I would like you to explain your thinking on the column with contents of "null", "null/0", etc.
These are my current questions / thoughts about this --
No, that shouldn't be necessary. I just haven't been able to test it yet due to other priorities.
ok
I would like you to explain your thinking on the column with contents of "null", "null/0", etc.
These are my current questions / thoughts about this --
- Why is the first line with "null" even in the list? IMO, it doesn't belong because it isn't a frame.
because the first is window.top
which is the main document and is not frames as such, but it is needed, to know how to use _WD_FrameEnter()
- I don't see the benefit of preceding each entry with "null"
It is very important because it shows the full path you need to walk to achieve particular context.
For example if you want to go to this frame:
you need to perform such steps:
_WD_FrameEnter($sSession, Null)
_WD_FrameEnter($sSession, 2)
_WD_FrameEnter($sSession, 0)
_WD_FrameEnter($sSession, 0)
Ultimately I am thinking to be possible of something like this:
_WD_FrameEnter($sSession, "Null/2/0/0")
I also want to retrive each window.document.outerHTML
as a additionall column.
And also want to add speciall parameter to filter results, which will allow you to easily find the frame you want to use with your target DOM element.
Please check it with this version:
#Region - UserTesting
Func UserTesting() ; here you can replace the code to test your stuff before you ask on the forum
_WD_CheckContext($sSession, False)
If @error Then ; return if session is NOT OK
ConsoleWrite("! ---> @error=" & @error & " @extended=" & @extended & _
" : _WD_CheckContext reported a problem with the session" & @CRLF)
Return
EndIf
_WD_Navigate($sSession, 'https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_iframe')
_WD_LoadWait($sSession)
; Example 1 - from 'https://www.w3schools.com' get frame list as string
ConsoleWrite(_WD_FrameList($sSession, False) & @CRLF)
; Example 2 - from 'https://www.w3schools.com' get frame list as array
Local $aFrameList = _WD_FrameList($sSession)
_ArrayDisplay($aFrameList, @ScriptLineNumber)
_WD_Navigate($sSession, 'https://stackoverflow.com/questions/19669786/check-if-element-is-visible-in-dom')
_WD_LoadWait($sSession)
; Example 3 - from 'https://stackoverflow.com' get frame list as string
ConsoleWrite(_WD_FrameList($sSession, False) & @CRLF)
; Example 4 - from 'https://stackoverflow.com' get frame list as array
$aFrameList = _WD_FrameList($sSession, True)
_ArrayDisplay($aFrameList, @ScriptLineNumber)
; Example 5 - from 'https://stackoverflow.com' get frame list as array - but only this one which contain id="question-header"
$aFrameList = _WD_FrameList($sSession, True, '(?i)id=.question-header.')
_ArrayDisplay($aFrameList, @ScriptLineNumber)
; go thru the Frames
EndFunc ;==>UserTesting
Func _WD_FrameList($sSession, $bReturnAsArray = True, $sFilter = '')
Local $a_Result[0][4]
Local $vResult = __WD_FrameList_Internal($sSession, 'null', '', $sFilter)
If @error = $_WD_ERROR_Success Then
$vResult = StringTrimRight($vResult, 2) ; last @CRLF
If $bReturnAsArray Then
_ArrayAdd($a_Result, $vResult)
$vResult = $a_Result
EndIf
EndIf
Return SetError(@error, @extended, $vResult)
EndFunc ;==>_WD_FrameList
Func __WD_FrameList_Internal($sSession, $s_level_string, $s_Path, $sFilter)
#WARRNING some kind of remark in the header should be aded first proposal below:
; changing frames may affect your further coding by changing contex in browser to different frames
Local Const $sFuncName = "_WD_FrameList"
Local $iErr = $_WD_ERROR_Success
Local $vResult = '', $s_URL = '', $s_HTML = '', $sMessage = ''
Local $a_Level = StringSplit($s_level_string, '/')
For $i = 1 To $a_Level[0]
If $a_Level[$i] = 'null' Then
_WD_FrameEnter($sSession, Null)
Else
_WD_FrameEnter($sSession, Int($a_Level[$i]))
EndIf
If @error Then ExitLoop
Next
If @error Then
$sMessage = 'Error occured on "' & $s_level_string & '" level when trying to entering frame'
Else
$s_URL = _WD_ExecuteScript($sSession, "return window.location.href", Default, Default, $_WD_JSON_Value)
If @error Then
$sMessage = 'Error occured on "' & $s_level_string & '" level when checking URL'
Else
$s_HTML = _WD_GetSource($sSession)
If @error Then
$sMessage = 'Error occured on "' & $s_level_string & '" level when getting HTML Source'
Else
If $sFilter = '' Or StringRegExp($s_HTML, $sFilter, $STR_REGEXPMATCH) Then
$vResult = $s_level_string & '|' & $s_Path & '| ' & $s_URL & '|' & StringToBinary($s_HTML, $SB_UTF8) & @CRLF
EndIf
EndIf
EndIf
EndIf
$iErr = @error
If Not @error Then
Local $iFrameCount = _WD_GetFrameCount($sSession)
$iErr = @error
If $iErr Then
$sMessage = 'Error occured on "' & $s_level_string & '" level when trying to check frames count'
Else
For $iFrame = 0 To $iFrameCount - 1
$s_Path = _WD_ExecuteScript($sSession, "return document.querySelectorAll('iframe')[" & $iFrame & "].outerHTML;", Default, Default, $_WD_JSON_Value)
$iErr = @error
If @error Then
$sMessage = 'Error occured on "' & $s_level_string & '" level when trying to check atributes child frames #' & $iFrame
Else
$vResult &= __WD_FrameList_Internal($sSession, $s_level_string & '/' & $iFrame, $s_Path, $sFilter)
$iErr = @error
If Not @error Then
_WD_FrameLeave($sSession)
$iErr = @error
If @error Then
$sMessage = 'Error occured on "' & $s_level_string & '" level when trying to leave frames #' & $iFrame
EndIf
EndIf
EndIf
If @error Then ExitLoop
Next
EndIf
EndIf
Return SetError(__WD_Error($sFuncName, $iErr, $sMessage), 0, $vResult)
EndFunc ;==>__WD_FrameList_Internal
; if necessary, add any additional function required for testing within this region here
#EndRegion - UserTesting
because the first is window.top which is the main document and is not frames as such, but it is needed, to know how to use _WD_FrameEnter()
IMO, if the function is going to list all frames, then the Null should be implied and the first entry should be excluded. The results would then look like this --
0| about:blank|<iframe id="iframeResult" name="iframeResult" allowfullscreen="true" frameborder="0"></iframe>
1| about:blank|<iframe style="display: none;" name="__tcfapiLocator"></iframe>
2| https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_iframe|<iframe style="display: none;" name="__uspapiLocator"></iframe>
2/0| https://www.w3schools.com/|<iframe src="https://www.w3schools.com" title="W3Schools Free Online Web Tutorials"></iframe>
2/0/0| https://www.w3schools.com/howto/tryhow_js_slideshow_ifr.htm|<iframe src="/howto/tryhow_js_slideshow_ifr.htm" id="howto_iframe"></iframe>
2/0/1| about:blank|<iframe style="display: none;" name="__tcfapiLocator"></iframe>
2/0/2| about:blank|<iframe style="display: none;" name="__uspapiLocator"></iframe>
It is very important because it shows the full path you need to walk to achieve particular context.
I think it is a matter of perspective. Your version forces a return to the top level by including the Null. I would recommend that the user make this decision instead. Perhaps the solution is to add an optional parameter that controls if "null" is generated.
Ultimately I am thinking to be possible of something like this: _WD_FrameEnter($sSession, "Null/2/0/0")
That could be interesting indeed. But the Null should be optional. 😛
I also want to retrive each window.document.outerHTML as a additionall column.
Why? That could add a bunch of unnecessary overhead. If you add this, it should be optional and it should not be included by default.
Why? That could add a bunch of unnecessary overhead. If you add this, it should be optional and it should not be included by default.
As already get HTML to check it with $sFilter
then why not return them ?
_WD_FrameEnter($sSession, "Null/2/0/0")
That could be interesting indeed.
I'm happy to hear that.
But the Null should be optional.
Why ?
In my opinion the string parameter "Null/2/0/0"
_WD_FrameEnter($sSession, "Null/2/0/0")
should contain all the action necessary to do
For example if you need to switch between:
_WD_FrameEnter($sSession, "Null/2/0/0")
_WD_FrameEnter($sSession, "Null/1/2/2")
_WD_FrameEnter($sSession, "Null/2/1/1")
normally, doing this with multpile _WD_FrameEnter
calls, you must 3 times goes thru Null
.
I want to keep the string parameter Null/2/1/1
consistent with the path of conduct as it is now when you must pass 'Null' each time when you want back to top window
If you add this, it should be optional and it should not be included by default.
Ok. $bReturnHTML
added in my background work.
Func _WD_FrameList($sSession, $bReturnAsArray = True, $sFilter = '', $bReturnHTML = False)
As already get HTML to check it with $sFilter then why not return them ?
If you aren't filtering the result, then no need to retrieve the HTML, right? 😉
But the Null should be optional.
Why ?
By prepending "Null" at the beginning, you force a potential extra step of switching to the top level browsing context when it isn't needed if the browsing context is already at the top level. Look at it from the POV of other developers, who may have different needs than your own.
This string Null/2/0/0
as for now is only informationall to show the path that allways fit no matter on what level of the document (in what context / frame) you are currently..
I know that If you know that you are on top then you do not must back to top.
But for this is _WD_IsWindowTop($sSession)
and can be used internally in:
_WD_FrameEnter($sSession, "Null")
because as for now it is not used.
And as far as I understand it should be checked ?
If you aren't filtering the result, then no need to retrieve the HTML, right?
yeah, agree, already fixed in my background code.
current version:
#Region - UserTesting
Func UserTesting() ; here you can replace the code to test your stuff before you ask on the forum
_WD_CheckContext($sSession, False)
If @error Then ; return if session is NOT OK
ConsoleWrite("! ---> @error=" & @error & " @extended=" & @extended & _
" : _WD_CheckContext reported a problem with the session" & @CRLF)
Return
EndIf
_WD_Navigate($sSession, 'https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_iframe')
_WD_LoadWait($sSession)
; Example 1 - from 'https://www.w3schools.com' get frame list as string
ConsoleWrite(_WD_FrameList($sSession, False) & @CRLF)
; Example 2 - from 'https://www.w3schools.com' get frame list as array, with HTML content of each document
Local $aFrameList = _WD_FrameList($sSession, True, '', True)
_ArrayDisplay($aFrameList, 'Example 2', 0, 0, Default, '_WD_FrameEnter Identifiers|IFRAME attributes|URL|HTML')
_WD_Navigate($sSession, 'https://stackoverflow.com/questions/19669786/check-if-element-is-visible-in-dom')
_WD_LoadWait($sSession)
; Example 3 - from 'https://stackoverflow.com' get frame list as string
ConsoleWrite(_WD_FrameList($sSession, False) & @CRLF)
; Example 4 - from 'https://stackoverflow.com' get frame list as array
#TODO this following line - NOT WORKS - should be checked
;~ $aFrameList = _WD_FrameList($sSession, True)
$aFrameList = _WD_FrameList($sSession, True, '', False)
_ArrayDisplay($aFrameList, 'Example 4', 0, 0, Default, '_WD_FrameEnter Identifiers|IFRAME attributes|URL|HTML')
; Example 5 - from 'https://stackoverflow.com' get frame list as array - but only this one which contain id="question-header"
$aFrameList = _WD_FrameList($sSession, True, '(?i)id=.question-header.')
_ArrayDisplay($aFrameList, 'Example 5', 0, 0, Default, '_WD_FrameEnter Identifiers|IFRAME attributes|URL|HTML')
EndFunc ;==>UserTesting
Func _WD_FrameList($sSession, $bReturnAsArray = True, $sFilter = '', $bReturnHTML = False)
Local $a_Result[0][4]
Local $vResult = __WD_FrameList_Internal($sSession, 'null', '', $sFilter, $bReturnHTML)
If @error = $_WD_ERROR_Success Then
$vResult = StringTrimRight($vResult, 2) ; last @CRLF
If $bReturnAsArray Then
_ArrayAdd($a_Result, $vResult)
$vResult = $a_Result
EndIf
EndIf
Return SetError(@error, @extended, $vResult)
EndFunc ;==>_WD_FrameList
Func __WD_FrameList_Internal($sSession, $s_level_string, $s_Path, $sFilter, $bReturnHTML)
#WARRNING some kind of remark in the header should be aded first proposal below:
; changing frames may affect your further coding by changing contex in browser to different frames
Local Const $sFuncName = "_WD_FrameList"
Local $iErr = $_WD_ERROR_Success
Local $vResult = '', $s_URL = '', $s_HTML = '', $sMessage = ''
Local $a_Level = StringSplit($s_level_string, '/')
For $i = 1 To $a_Level[0]
If $a_Level[$i] = 'null' Then
_WD_FrameEnter($sSession, Null)
Else
_WD_FrameEnter($sSession, Int($a_Level[$i]))
EndIf
If @error Then ExitLoop
Next
If @error Then
$sMessage = 'Error occured on "' & $s_level_string & '" level when trying to entering frame'
Else
$s_URL = _WD_ExecuteScript($sSession, "return window.location.href", Default, Default, $_WD_JSON_Value)
If @error Then
$sMessage = 'Error occured on "' & $s_level_string & '" level when checking URL'
Else
If $bReturnHTML Or $sFilter <> '' Then $s_HTML = _WD_GetSource($sSession)
If @error Then
$sMessage = 'Error occured on "' & $s_level_string & '" level when getting HTML Source'
Else
If $sFilter = '' Or StringRegExp($s_HTML, $sFilter, $STR_REGEXPMATCH) Then
$s_HTML = ($bReturnHTML) ? (StringToBinary($s_HTML, $SB_UTF8)) : ('')
$vResult = $s_level_string & '|' & $s_Path & '| ' & $s_URL & '|' & $s_HTML & @CRLF
EndIf
EndIf
EndIf
EndIf
$iErr = @error
If Not @error Then
Local $iFrameCount = _WD_GetFrameCount($sSession)
$iErr = @error
If $iErr Then
$sMessage = 'Error occured on "' & $s_level_string & '" level when trying to check frames count'
Else
For $iFrame = 0 To $iFrameCount - 1
$s_Path = _WD_ExecuteScript($sSession, "return document.querySelectorAll('iframe')[" & $iFrame & "].outerHTML;", Default, Default, $_WD_JSON_Value)
$iErr = @error
If @error Then
$sMessage = 'Error occured on "' & $s_level_string & '" level when trying to check atributes child frames #' & $iFrame
Else
$vResult &= __WD_FrameList_Internal($sSession, $s_level_string & '/' & $iFrame, $s_Path, $sFilter, $bReturnHTML)
$iErr = @error
If Not @error Then
_WD_FrameLeave($sSession)
$iErr = @error
If @error Then
$sMessage = 'Error occured on "' & $s_level_string & '" level when trying to leave frames #' & $iFrame
EndIf
EndIf
EndIf
If @error Then ExitLoop
Next
EndIf
EndIf
Return SetError(__WD_Error($sFuncName, $iErr, $sMessage), 0, $vResult)
EndFunc ;==>__WD_FrameList_Internal
; if necessary, add any additional function required for testing within this region here
#EndRegion - UserTesting
Look at it from the POV of other developers, who may have different needs than your own
POV ?
POV ?
Point of view
But for this is _WD_IsWindowTop($sSession) and can be used internally in:
_WD_FrameEnter($sSession, "Null")
because as for now it is not used.
And as far as I understand it should be checked ?
Why do you believe that _WD_FrameEnter should check this? Please explain your reasoning.
Why do you believe that _WD_FrameEnter should check this? Please explain your reasoning.
because of your statement
By prepending "Null" at the beginning, you force a potential extra step of switching to the top level browsing context when it isn't needed if the browsing context is already at the top level. Look at it from the POV of other developers, who may have different needs than your own.
and from this my resoning is that we have two possible way how UDF should behaves:
_WD_FrameEnter()
not only in _WD_FrameList()
, changing by adding such protection/check to _WD_FrameEnter()
we also protect _WD_FrameList()
_WD_FrameEnter()
then this is user case/care to parse result form _WD_FrameList()
_WD_FrameList()
in my intention was not to give to user relative path from current frame level to any other level, but always relative to Null
in the meaning of top window.
IMHO: If user wants to calculate relative steps:
Null/2/0/1
to Null/2/0/2
Null/2/0/2
to Null/1
Null/1
to Null/2/0/0
then he always must to keep current level and recalculate them manually.
btw. After reflection, the following questions arose for me, which I would ask you to reflect on.
Why calling
_WD_FrameEnter($sSession, Null)
from top window is so bad ?
Won't storing the current level information be a more difficult task taking more CPU time and user intervention (on his own code) ?
What user should do if he is not on top window ?
How he should check it ? And how to check his current level if it is no top window ?
Why checking of this should not be performed by _WD_FrameEnter()
?
How many switching between frames will be performed in each minutes of processing that would affect speed ?
If we remove the Null
how user should be awer that he must to use them ?
Finnaly to sum up:
My intention is to add the full path required by _WD_FrameEnter()
to each correct transition to a given frame regardless of its current position to ensure that the result given is always reliable and effective with no additional processing beyond the UDF.
If the user wants to control it in a different way, no problem, he can just parse the result even with a regular
StringReplace($sPath, 'Null', '')
because of your statement
You are twisting my words to suit your POV.
and from this my resoning is that we have two possible way how UDF should behaves:
It's been a long day and there is currently a guy jack hammering outside my room, so my brain isn't "absorbing" at full capacity. I didn't completely understand the two scenarios you described. However, I don't believe we need to be "protecting the user" in this scenario.
_WD_FrameList() in my intention was not to give to user relative path from current frame level to any other level, but always relative to Null in the meaning of top window.
Why? Maybe the script writer is only interested in the relative path from the current browsing context. This should be an option IMO.
Why calling _WD_FrameEnter($sSession, Null) from top window is so bad ?
I never said it was bad. I said that by prepending Null to the results you are causing extra work (either calling _WD_FrameEnter($sSession, Null)
unnecessarily or having to check _WD_IsWindowTop($sSession)
)
Won't storing the current level information be a more difficult task taking more CPU time and user intervention (on his own code) ?
You really don't want to go there (unless I completely misunderstood your point). I can virtually guarantee that your argument is invalid as there's no way that storing the current level information (ie: update a variable) will take anywhere close to the amount of time / cycles it will take to return to perform all of your actions.
Why checking of this should not be performed by _WD_FrameEnter() ?
Because it's the responsibility of the calling script.
Maybe the script writer is only interested in the relative path from the current browsing context. This should be an option IMO.
maybe in the future it will be possible but for now let stick with current solution that is workable.
the only way that I can see is to use:
Func _WD_FrameList($sSession, $sCurrentLoaction = Default, $bReturnAsArray = True, $sFilter = '', $bReturnHTML = False)
#forceref $sCurrentLoaction ; not supported yet
I never said it was bad. I said that by prepending Null to the results you are causing extra work (either calling
_WD_FrameEnter($sSession, Null)
unnecessarily or having to check_WD_IsWindowTop($sSession)
)
so somebody must to check.
I ask again: Who should to check UDF or user (in calling script) ?
I was asking (in a very convoluted way) about this here:
my resoning is that we have two possible way how UDF should behaves:
- if UDF should protect user from doing this internally it must be also done in
_WD_FrameEnter()
not only in_WD_FrameList()
, changing by adding such protection/check to_WD_FrameEnter()
we also protect_WD_FrameList()
- if UDF should not protect user from doing this internally in
_WD_FrameEnter()
then this is user case/care to parse result form_WD_FrameList()
......
Why checking of this should not be performed by _WD_FrameEnter() ?
Because it's the responsibility of the calling script.
and simply I'm saying the same about result from _WD_FrameList
: result should always shows full path including Null and this is resposibility of calling script to parse or not full path to relative path
.
way that I can see is to use:
Func _WD_FrameList($sSession, $sCurrentLoaction = Default, $bReturnAsArray = True, $sFilter = '', $bReturnHTML = False) #forceref $sCurrentLoaction ; not supported yet
I just had an enlightenment and I have an idea how to support it
You've misspelled location
😆
something like this:
If $sCurrentLocation <> Default Then
If StringRight($sCurrentLocation, 1) <> '/' Then $sCurrentLocation &= '/'
For $i = 0 To UBound($a_Result) - 1
If $a_Result[$i][0] = StringTrimRight($sCurrentLocation, 1) Then $a_Result[$i][0] = ''
$a_Result[$i][0] = StringRegExpReplace($a_Result[$i][0], '\A' & $sCurrentLocation, '')
Next
EndIf
as you can see it is easy to implement but it is user responsibility to store current location in null/2/0/2
format
WIP:
; Example 2 - from 'https://www.w3schools.com' get frame list as array, with HTML content of each document
Local $aFrameList = _WD_FrameList($sSession, Default, True, '', True)
_ArrayDisplay($aFrameList, 'Example 2', 0, 0, Default, '_WD_FrameEnter Identifiers|IFRAME attributes|URL|HTML')
; Example 3 - from 'https://www.w3schools.com' get frame list as array, with
Local $aFrameList = _WD_FrameList($sSession, 'null/2', True, '', False)
_ArrayDisplay($aFrameList, 'Example 3', 0, 0, Default, '_WD_FrameEnter Identifiers|IFRAME attributes|URL|HTML')
is this what you are requesting ?
@Danp2 I plan to make PR today to continue posting code changes over PR and not as a snippet in conversation.
btw.
I also plan to modify DemoFrames()
I ask again: Who should to check UDF or user (in calling script) ?
My belief is that the responsibility lies with the calling script, not the UDF. The UDF should simply perform that actions requested by the calling script. If there's a null
present, then the calling script wants the browsing context reset to the top level. Otherwise, all actions should occur from the current browsing context.
is this what you are requesting?
No. I never suggested passing a string representing the current location into _WD_FrameList. When I said this --
Why? Maybe the script writer is only interested in the relative path from the current browsing context. This should be an option IMO.
I was thinking of a boolean flag that would determine if the path was full vs relative.
No. I never suggested passing a string representing the current location into _WD_FrameList. I was thinking of a boolean flag that would determine if the path was full vs relative.
Ok I understand you resoning about boolean
paramater instead string
parameter.
As you know It is simple to check is it on TOP or not. But do you have any idea how to check the current level to have possibility to pass relative path ?
I need to ask you about the way I represents data in relative way
:
Is this result fit to what you was expecting ?
Thinking about it some more, I'm not sure that the boolean parameter is even needed. I think that the results from _WD_FrameList
should always be relative to the current browsing context. If _WD_IsWindowTop()
is True, then prepend null
to the results to indicate that it's a fullpath.
Thinking about it some more, I'm not sure that the boolean parameter is even needed
Yes it is needed. But it can be as default set to RELATIVE mode and the option to retunr FULL path will be set as not default.
What this EYES mean ? (in this particular case)
That I'm watching you. 😆
So be careful because the bell is about to ring.
Is this PR#362 _FrameList() fits to what you was requesting ? If so you can close this ISSUE and we can start continue in PR.
Ultimately I am thinking to be possible of something like this:
_WD_FrameEnter($sSession, "Null/2/0/0")
Please take a look on: https://github.com/Danp2/au3WebDriver/pull/364
Feature request
Is your feature request related to a problem? Please describe
Very often, automation concerns websites with frames. Mostly novice users (AutoIt novice scripts) do not understand them. Even for the more advanced ones, a diagnostic tool would be useful.
Describe the solution you'd like
I would like to add new feature to _WD_FrameEnter - list all frames.
which should use my own JavaScript:
Describe alternatives you've considered
Manually check the webpage
Additional context
Example: using for testing this website: https://www.w3schools.com/
I get
and of course it can be easily transform to AutoIt array:
frame position / Identifier | HREF | element -- | -- | -- null | https://www.w3schools.com/ | null/0 | https://www.w3schools.com/howto/tryhow_js_slideshow_ifr.htm | null/1 | about:blank | null/2 | about:blank |Question
Do you agree to add such feature to UDF ?
Example usage: