WebDriver: Difference between revisions

From AutoIt Wiki
Jump to navigation Jump to search
m (→‎References: "au3webdriver-boilerplate")
 
(246 intermediate revisions by 7 users not shown)
Line 1: Line 1:
{{WIP}}
The W3C WebDriver API is a platform and language-neutral interface and wire protocol allowing programs or scripts to control the behavior of a web browser.
The W3C WebDriver API is a platform and language-neutral interface and wire protocol allowing programs or scripts to control the behavior of a web browser.


Line 11: Line 10:


=== Requirements ===
=== Requirements ===
<small>(Last modified: 2020/01/25)<br></small>
<small>(Last modified: 2022/01/25)<br></small>


The following UDFs need to be installed - '''independent''' of the Browser you try to automate:
The following UDFs need to be installed - '''independent''' of the Browser you try to automate:
* [https://www.autoitscript.com/forum/topic/148114-a-non-strict-json-udf-jsmn JSON UDF]
* [https://www.autoitscript.com/forum/topic/148114-a-non-strict-json-udf-jsmn JSON UDF (AutoIt)] by Ward and Jos
* [https://www.autoitscript.com/forum/topic/84133-winhttp-functions/ WinHTTP UDF]
* [https://www.autoitscript.com/forum/topic/84133-winhttp-functions/ WinHTTP UDF (AutoIt)] by trancexx or [https://github.com/dragana-r/autoit-winhttp autoit-winhttp (GitHub)]
* [https://github.com/Danp2/WebDriver/releases/latest WebDriver UDF]
* [https://github.com/Danp2/au3WebDriver/releases/latest WebDriver UDF (GitHub)] by Danp2
One of the following Drivers needs to be installed - '''depending''' on the Browser type and version you try to automate:
One of the following Drivers needs to be installed - '''depending''' on the Browser type and version you try to automate:
{| class="wikitable"
{| class="wikitable"
|-
|-
! Browser !! Download Link !! Latest Version / Date !! Comments
! Browser !! Download Link !! Comments
|-
|-
| Chrome || [https://sites.google.com/a/chromium.org/chromedriver/downloads Google] || 80.0.3987.16 / 2019.12.19 || Follow this [https://sites.google.com/a/chromium.org/chromedriver/downloads/version-selection link] to select the correct version depending on the Chrome version you run!
| Chrome || [https://sites.google.com/chromium.org/driver/downloads Google] || Follow this [https://sites.google.com/a/chromium.org/chromedriver/downloads/version-selection link] to select the correct version depending on the Chrome version you run!
|-
|-
| Edge || [https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/ Microsoft] || 81.0.403.0 ||
| Edge || [https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/ Microsoft] ||
|-
|-
| Firefox || [https://github.com/mozilla/geckodriver/releases github] || 0.26 / 2019.10.12 || Firefox version ≥ 60 is recommended<br>
| Firefox || [https://github.com/mozilla/geckodriver/releases/latest GitHub] || Firefox version ≥ 60 is recommended<br>
'''Note:''' You must still have the Microsoft Visual Studio redistributable runtime installed on your system for the binary to run. This is a known bug in version 0.26 which the authors weren't able fix for this release.
'''Note:''' You must still have the Microsoft Visual Studio redistributable runtime installed on your system for the binary to run. This is a known bug in version 0.26 which the authors weren't able fix for this release.
|-
|-
| Opera || [https://github.com/operasoftware/operachromiumdriver/releases github] || 79.0.3945.79 - 2020.01.08 || The versioning of OperaDriver matches the Chromium version on which Opera browser is based on.
| Opera || [https://github.com/operasoftware/operachromiumdriver/releases/latest GitHub] || The versioning of OperaDriver matches the Chromium version on which Opera browser is based on.
|}
|}


Line 39: Line 38:
* [https://docs.microsoft.com/en-us/microsoft-edge/webdriver#w3c-webdriver-specification-supporthttpsw3cgithubiowebdriverwebdriver-spechtml Edge]
* [https://docs.microsoft.com/en-us/microsoft-edge/webdriver#w3c-webdriver-specification-supporthttpsw3cgithubiowebdriverwebdriver-spechtml Edge]
* [https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/WebDriver/status Firefox]
* [https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/WebDriver/status Firefox]
* [https://github.com/operasoftware/operachromiumdriver Opera]: "''OperaChromiumDriver is a WebDriver implementation derived from ChromeDriver and adapted by Opera''". That's why I think it has at least the same limitations as the chromedriver.
* [https://github.com/operasoftware/operachromiumdriver Opera]: "''OperaChromiumDriver is a WebDriver implementation derived from ChromeDriver and adapted by Opera''". That's why I think it has at least the same limitations as ChromeDriver.


=== Big Picture ===
=== Big Picture ===
Line 46: Line 45:
[[File:WebDriver.png|800px|||Big Picture - How everything fits together]]
[[File:WebDriver.png|800px|||Big Picture - How everything fits together]]


=== Used Terms ===
=== Technical terms ===
<small>(Last modified: 2020/01/03)<br></small>
<small>(Last modified: 2022/02/12)<br></small>
 
 
You will find the following terms when using WebDriver. We try to shed some light onto this subject here:
You will encounter the following technical terms when working with the WebDriver UDF.<br>
These terms are not unique to the UDF, so you will find just the general description in this section.
How to use these terms with the WebDriver UDF can be found in the FAQ.<br><br>
 
; CDP (Chrome DevTools Protocol) : Is a [https://chromedevtools.github.io/devtools-protocol/ protocol] that allows for tools to instrument, inspect, debug and profile Chromium, Chrome and other [https://en.wikipedia.org/wiki/Blink_(browser_engine) Blink]-based browsers.
 
; CSS Selector : Please see '''Selector'''.
 
; Locator Strategy : A Locator strategy describes the method to use to search elements. This includes Linktext, Partial Linktext, Tag Name, CSS selector, XPath selector.
 
; Marionette : Marionette is an automation driver for Mozilla’s Gecko engine. It can remotely control either the UI or the internal JavaScript of a Gecko platform, such as Firefox. It can control both the chrome (i.e. menus and functions) or the content (the webpage loaded inside the browsing context), giving a high level of control and ability to replicate user actions. In addition to performing actions on the browser, Marionette can also read the properties and attributes of the DOM.<br>Marionette consists of two parts: a server which takes requests and executes them in Gecko (the Marionette server ships with Firefox), and a client (the Marionette client ships with the GeckoDriver exe). The client sends commands to the server and the server executes the command inside the browser.<br>For details please [https://firefox-source-docs.mozilla.org/testing/marionette/Intro.html visit this site].
 
; Selector : Selectors are patterns used to select the element(s) you want to process. They are used by <br>CSS (see [https://www.w3schools.com/css/css_selectors.asp this link for Beginners] or [https://www.w3.org/TR/CSS21/selector.html this link for Advanced)] and<br>[https://www.w3schools.com/xml/xpath_syntax.asp XPath] (see [https://www.w3schools.com/xml/xml_xpath.asp this link for Beginners] and [https://www.w3.org/TR/1999/REC-xpath-19991116/ this link for Advanced]).


==== Firefox ====
; ShadowRoot : The ShadowRoot interface of the Shadow DOM API is the root node of a DOM sub tree that is rendered separately from a document's main DOM tree.<br>For details please [https://dom.spec.whatwg.org/#interface-shadowroot visit this site].
'''Marionette'''<br>
 
Marionette is an automation driver for Mozilla’s Gecko engine. It can remotely control either the UI or the internal JavaScript of a Gecko platform, such as Firefox. It can control both the chrome (i.e. menus and functions) or the content (the webpage loaded inside the browsing context), giving a high level of control and ability to replicate user actions. In addition to performing actions on the browser, Marionette can also read the properties and attributes of the DOM.<br>
; XPath : XPath is a language for navigating in XML documents. XPath is a major element in the XSLT standard and includes over 200 built-in functions.
Marionette consists of two parts: a server which takes requests and executes them in Gecko (the Marionette server ships with Firefox), and a client (the Marionette client ships with the GeckoDriver exe). The client sends commands to the server and the server executes the command inside the browser.<br>
 
For details please [https://firefox-source-docs.mozilla.org/testing/marionette/Intro.html visit this site].
; XQuery : XQuery is a language for querying XML documents.<br>For details please [https://www.w3schools.com/xml/xml_xquery.asp visit this site].
 
; XSLT : XSLT is a language for transforming XML documents.<br>For details please [https://www.w3schools.com/xml/xml_xslt.asp visit this site].


== Installation ==
== Installation ==
<small>(Last modified: 2020/01/23)<br></small>
<small>(Last modified: 2022/02/02)<br></small>


To automate your browser the following installation steps are needed:
To automate your browser the following installation steps are needed:
* Download the files listed in section "[[WebDriver#Requirements|Requirements]]"  
* Download the files listed in section "[[WebDriver#Requirements|Requirements]]"  
* Move the UDFs to a directory where SciTE and Autoit can find them:
* Move the UDFs to a directory where SciTE and Autoit can find them:
** wd_Core.au3, wd_helper.au3 , wd_cdp.au3 , wd_capabilities.au3 from the WebDriver UDF
** Json.au3 and BinaryCall.au3 from the JSON UDF
** Json.au3 and BinaryCall.au3 from the JSON UDF
** wd_Core.au3 and wd_helper.au3 from the WebDriver UDF
** WinHttp.au3 and WinHttpConstants.au3 from the WinHttp UDF
** WinHttp.au3 and WinHttpConstants.au3 from the WinHttp UDF
* Move the browser dependent WebDriver to the same directory:
* Move the browser dependent WebDriver to the same directory (with WD_Demo.au3):
** chromedriver.exe (Chrome)
** chromedriver.exe (Chrome)
** geckodriver.exe (Firefox)
** geckodriver.exe (Firefox)
** msedgedriver.exe (Edge - Chromium) or MicrosoftWebDriver.exe (Edge - EdgeHTML)
** msedgedriver.exe (Edge - Chromium) or MicrosoftWebDriver.exe (Edge - EdgeHTML)
** or use "Update" option by choosing one of ComboBox option in WD_Demo.au3
* Run WD_Demo.au3 and select "DemoNavigation" to validate the installation.<br>The result (for Firefox) displayed in the DOS window should be similar to the following:
* Run WD_Demo.au3 and select "DemoNavigation" to validate the installation.<br>The result (for Firefox) displayed in the DOS window should be similar to the following:
<syntaxhighlight lang="text">
<syntaxhighlight lang="text">
Line 80: Line 94:
1577745817392  geckodriver::marionette DEBUG  Connection to Marionette established on 127.0.0.1:55184.
1577745817392  geckodriver::marionette DEBUG  Connection to Marionette established on 127.0.0.1:55184.
1577745817464  webdriver::server      DEBUG  <- 200 OK {"value":{"sessionId":"925641bf-6c5d-4fe2-a985-02de9b1c7c74","capabilities":"acceptInsecureCerts":true,"browserName":"firefox", ...
1577745817464  webdriver::server      DEBUG  <- 200 OK {"value":{"sessionId":"925641bf-6c5d-4fe2-a985-02de9b1c7c74","capabilities":"acceptInsecureCerts":true,"browserName":"firefox", ...
</syntaxhighlight>
== Getting started example ==
<small>(Last modified: 2023/09/09)<br></small>
<syntaxhighlight lang="autoit">
#include "wd_helper.au3"
#include "wd_capabilities.au3"
_Example()
Func _Example()
# REMARK
#  This is not functional script
#  It only shows the concept how to use WebDriver UDF
#Region ; initialize webdriver sesion
; you should take care about download/update dirver
If $IDYES = MsgBox($MB_YESNO + $MB_TOPMOST + $MB_ICONQUESTION + $MB_DEFBUTTON1, "Question", _
"Do you want to download/update driver ?") Then
_WD_UpdateDriver('chrome')
EndIf
; specify driver, port and other options
_WD_Option('Driver', 'chromedriver.exe')
_WD_Option('Port', 9515)
_WD_Option('DriverParams', '--verbose --log-path="' & @ScriptDir & '\chrome.log"')
; start the driver
_WD_Startup()
If @error Then Return SetError(@error, @extended, 0) ; always remember to check and handle error's
; create capabilites for session
_WD_CapabilitiesStartup()
_WD_CapabilitiesAdd('alwaysMatch', 'chrome')
_WD_CapabilitiesAdd('w3c', True)
_WD_CapabilitiesAdd('excludeSwitches', 'enable-automation')
Local $sCapabilities = _WD_CapabilitiesGet()
; create session with given Capabilities
Local $WD_SESSION = _WD_CreateSession($sCapabilities)
If @error Then Return SetError(@error, @extended, 0) ; always remember to check and handle error's
#EndRegion ; initialize webdriver sesion
#Region ; do your's stuff
; navigate to some website
Local $sURL = '******'
_WD_Navigate($WD_SESSION, $sURL)
If @error Then Return SetError(@error, @extended, 0) ; always remember to check and handle error's
; wait for loading process ends
_WD_LoadWait($WD_SESSION, 1000)
If @error Then Return SetError(@error, @extended, 0) ; always remember to check and handle error's
; for example find element
Local $sXPath = "*****"
Local $sElement = _WD_FindElement($WD_SESSION, $_WD_LOCATOR_ByXPath, $sXPath)
If @error Then Return SetError(@error, @extended, 0) ; always remember to check and handle error's
; get element text
Local $sText = _WD_ElementAction($WD_SESSION, $sElement, 'text')
If @error Then Return SetError(@error, @extended, 0) ; always remember to check and handle error's
ConsoleWrite($sText & @CRLF)
; or click the element
_WD_ElementAction($WD_SESSION, $sElement, 'click')
If @error Then Return SetError(@error, @extended, 0) ; always remember to check and handle error's
#EndRegion ; do your's stuff
#Region ; Clean Up
; on the end session should be deleted
_WD_DeleteSession($WD_SESSION)
If @error Then Return SetError(@error, @extended, 0) ; always remember to check and handle error's
; and driver should be closed
_WD_Shutdown()
If @error Then Return SetError(@error, @extended, 0) ; always remember to check and handle error's
#EndRegion ; Clean Up
EndFunc  ;==>_Example
</syntaxhighlight>
</syntaxhighlight>


== Function reference ==
== Function reference ==
<small>(Last modified: 2020/01/27 - based on version 0.2.0.5)<br></small>
<small>(Last modified: 2021/12/09)<br></small>
 
The functions are now documented in the CHM help file that comes with the UDF.
 
== Capabilities ==
WebDriver capabilities are used to communicate the features supported by a given implementation. The local end may use capabilities to define which features it requires the remote end to satisfy when creating a new session. Likewise, the remote end uses capabilities to describe the full feature set for a session. <br>
Details can be found at [[WebDriver_Capabilities|WebDriver Capabilities (sub page)]].


=== WD_CORE ===
== Browser related functionality ==
The WD_Core.au3 file holds functions to implement the Webdriver W3C document.
=== Google Chrome ===
ChromeDriver supports "Chrome DevTools Protocol" (CDP) commands (for an explanation of the term and related links please see the [[WebDriver#Used_Terms|Used Terms]] section).<br>
Details can be found in the CHM Help file that comes with the UDF.
 
=== Translate IE UDF to WebDriver ===
{{WIP}}
Internet Explorer is no longer supported by Microsoft. Therefore, it may be necessary to rewrite existing scripts for other browsers using the WebDriver UDF.
Below you will find a mapping of the functions of the IE UDF to the functions of the WebDriver UDF.
{| class="wikitable"
{| class="wikitable"
|-
|-
! Function !! Description !! Comment
! IE function !! WebDriver function !! Comments
|-
| _IEAction || _WD_ElementAction + _WD_ElementActionEx ||
|-
| _IEAttach || _WD_Attach ||
_WD_Attach: '''Attach to''' existing browser '''tab'''.
 
Attaching to running browser instance/session is much more difficult. [https://www.autoitscript.com/forum/topic/201537-webdriver-example-scripts-collection/?tab=comments#comment-1498168 Examples can be found here].
|-
| _IEBodyReadHTML || _WD_GetSource ||
|-
| _IEBodyReadText || _WD_ExecuteScript($sSession, 'return document.body.innerText',Default,Default, $_WD_JSON_Value) ||
|-
| _IEBodyWriteHTML || _WD_ExecuteScript($s_Session, "document.body.outerHTML='" & $sHTML & "'") ||
|-
| _IECreate || _WD_CreateSession ||
|-
| _IECreateEmbedded || N/A ||
|-
|-
| _WD_Action || Perform various interactions with the web driver session || Use one of the following values for parameter $sCommand: ''refresh'', ''back'', ''forward'', ''url'', ''title'', ''actions''.<br>For command ''actions'': Pass the actions to be set using parameter $sOption. If $sOption is empty then the set actions will be removed.
| _IEDocGetObj || ||  
|-
|-
| _WD_Alert || Respond to user prompt || Use one of the following actions to respond to the user prompt: ''dismiss'', ''accept'', ''gettext'', ''sendtext'', ''status''
| _IEDocInsertHTML || ||
|-
|-
| _WD_Cookies || Gets, sets, or deletes the session's cookies || Gets a single (command ''get'') or all (command ''getall'') cookies, ''adds'' or ''delete''s a single cookie
| _IEDocInsertText || ||
|- || ||  
|-
|-
| _WD_CreateSession|| Request new session from web driver || Define the capabilities of the browser with this function
| _IEDocReadHTML || _WD_GetSource ||  
|-
|-
| _WD_DeleteSession || Delete existing session || Closes the session created by _WD_CreateSession
| _IEDocWriteHTML || _WD_ExecuteScript($s_Session, "document.open();document.write(" & $sHTML & ");document.close();") || https://stackoverflow.com/a/11984907/5314940
|-
|-
| _WD_ElementAction || Perform action on designated element || Use one of the following actions: ''Name'', ''Rect'', ''Text'', ''Selected'', ''Enabled'', ''Displayed'', ''Active'', ''Attribute'', ''Property'', ''CSS'', ''Clear'', ''Click'', ''Value'', ''Screenshot''.<br>''Clear'', ''Click'' and ''Value'' use POST to modify or process the element. All other actions use GET to retrieve data from the element
| _IEErrorNotify || N/A || you can set debug level for example: $_WD_DEBUG = $_WD_DEBUG_Full
|-
|-
| _WD_ExecuteScript || Execute Javascipt commands ||  
| _IEFormElementCheckBoxSelect || _WD_ElementActionEx || _WD_FindElement + _WD_ElementActionEx($sSession, $sElement, "check")
|-
|-
| _WD_FindElement|| Find element(s) by designated strategy || You can specify whether the function should only return the first find or all of them
| _IEFormElementGetCollection || _WD_FindElement ||  
|-
|-
| _WD_GetSource || Get page source ||  
| _IEFormElementGetObjByName || _WD_GetElementByName ||  
|-
|-
| _WD_Navigate || Navigate to the designated URL ||  
| _IEFormElementGetValue || _WD_ElementAction || _WD_FindElement + _WD_ElementAction($sSession, $sSelectElement, "value")
|-
|-
| _WD_Option || Sets and get options for the web driver UDF || The following options can be used: ''Driver'' (set the full path name to web driver executable), ''DriverParams'' (parameters to pass to web driver executable), ''BaseURL'' (IP address used for web driver communication), ''Port'' (port used for web driver communication), ''BinaryFormat'' (format used to store binary data). If no value is passed to be set the current value is returned
| _IEFormElementOptionSelect || _WD_ElementSelectAction + _WD_ElementOptionSelect ||  
|-
|-
| _WD_Shutdown || Kill the web driver console app ||  
| _IEFormElementRadioSelect || _WD_ElementSelectAction ||  
|-
|-
| _WD_Startup || Launch the designated web driver console app || The PID for the WD console is returned
| _IEFormElementSetValue || _WD_SetElementValue ||  
|-
|-
| _WD_Status || Get current web driver state || Returns a raw JSON response from the web driver
| _IEFormGetCollection || _WD_FindElement ||  
|-
|-
| _WD_Timeouts || Set or retrieve the session timeout parameters || Specify the type and value of the timeout like this: '{"type":value}'. Example: '{"pageLoad":2000}'
| _IEFormGetObjByName || _WD_GetElementByName ||  
|-
|-
| _WD_Window || Perform interactions related to the current window || One of the following actions: ''window'' (get current tab's window handle), ''handles'' (get all window handles), ''maximize'' (maximize window), ''minimize'' (minimize window), ''fullscreen'' (set window to fullscreen), ''rect'' (get or set the window's size & position), ''screenshot'' (take screenshot of window), ''close'' (close current tab), ''switch'' (switch to designated tab), ''frame'' (switch to frame), ''parent'' (switch to parent frame)
| _IEFormImageClick || _WD_ElementAction || _WD_FindElement + _WD_ElementAction($sSession, $sElement, "click")
|-
|-
|}
| _IEFormReset || ||  
 
=== WD_HELPER ===
The WD_Helper.au3 file holds functions to help you automate a web site.
{| class="wikitable"
|-
|-
! Function !! Description !! Comment
| _IEFormSubmit || ||
|-
|-
| _WD_Attach || Attach to existing browser tab ||  
| _IEFrameGetCollection || _WD_FrameList || _WD_FrameList($sSession, True)
|-
|-
| _WD_ConsoleVisible || Control visibility of the webdriver console app ||  
| _IEFrameGetObjByName || _WD_GetElementByName + _WD_FrameEnter ||  
|-
|-
| _WD_DownloadFile || Download file and save to disk ||  
| _IEGetObjById || _WD_GetElementById ||  
|-
|-
| _WD_ElementOptionSelect || Find and click on an option from a Select element ||  
| _IEGetObjByName || _WD_GetElementByName ||  
|-
|-
| _WD_FrameEnter || Will enter the specified frame for subsequent WebDriver operations ||  
| _IEHeadInsertEventScript || ||  
|-
|-
| _WD_FrameLeave || Will leave the current frame, to its parent, not necessarily the Top, for subsequent WebDriver operations ||
| _IEImgClick || _WD_ElementAction || _WD_FindElement + _WD_ElementAction($sSession, $sElement, "click")
|-
|-
| _WD_GetElementFromPoint || Retrieves reference to element descriped by x/y coordinate ||  
| _IEImgGetCollection || _WD_FindElement ||  
|-
|-
| _WD_GetFrameCount || Returns how many frames/iframes are in your current window/frame || It will not traverse to nested frames
| _IEIsFrameSet || ||  
|-
|-
| _WD_GetMouseElement || Retrieves reference to element below mouse pointer ||  
| _IELinkClickByIndex || _WD_ElementAction || _WD_FindElement + _WD_ElementAction($sSession, $sElement, "click")
|-
|-
| _WD_GetShadowRoot || ||  
| _IELinkClickByText || _WD_LinkClickByText ||  
|-
|-
| _WD_HighlightElement || Will highlight the specified element ||  
| _IELinkGetCollection || _WD_FindElement ||  
|-
|-
| _WD_HighlightElements || Will highlight multiple elements passed as an array ||  
| _IELoadWait || _WD_LoadWait ||  
|-
|-
| _WD_IsLatestRelease || Compares local UDF version to latest release on Github ||  
| _IELoadWaitTimeout || _WD_SetTimeouts ||  
|-
|-
| _WD_IsWindowTop || Returns a boolean of the session being at the top level, or in a frame(s) ||  
| _IENavigate || _WD_Navigate ||  
|-
|-
| _WD_LastHTTPResult || Return the result of the last WinHTTP request ||  
| _IEPropertyGet || _WD_ElementAction || _WD_FindElement + _WD_ElementAction($sSession, $sElement, 'property', 'nodeName')
|-
|-
| _WD_LinkClickByText || Simulate a mouse click on a link with text matching the provided string ||  
| _IEPropertySet || _WD_ExecuteScript || _WD_FindElement + ......
|-
|-
| _WD_LoadWait || Wait for a browser page load to complete before returning ||  
| _IEQuit || _WD_DeleteSession ||
|-
|-
| _WD_NewTab || Create new tab using Javascript ||
| _IETableGetCollection || _WD_FindElement ||  
|-
|-
| _WD_Screenshot || Will return a screenshot of the browser window or a specified element ||  
| _IETableWriteToArray || _WD_GetTable || _WD_FindElement + _WD_GetTable( ......
|-
|-
| _WD_SelectFiles || ||  
| _IETagNameAllGetCollection || _WD_FindElement ||  
|-
|-
| _WD_UpdateDriver || Replace web driver with newer version, if available ||  
| _IETagNameGetCollection || _WD_FindElement ||  
|-
|-
| _WD_WaitElement || Wait for a element to be found in the current tab before returning ||
| _IE_Example || N/A || Take a look at wd_demo.au3 script
|-
|-
| _WD_jQuerify || Inject jQuery library into current session ||  
| _IE_Introduction || N/A || Take a look at  wd_demo.au3 script
|-
|-
| _IE_VersionInfo || _WD_Option('version') ||
|}
|}


== Debugging ==
== Troubleshooting ==
=== Debug the WebDriver setup ===
=== Debug the WebDriver setup ===
<small>(Last modified: 2020/01/27)<br></small>
<small>(Last modified: 2020/07/06)<br></small>
 
==== WinHTTP UDF ====
Make sure that you are running at least version 1.6.4.2 (currently unreleased, but can be obtained [https://raw.githubusercontent.com/dragana-r/autoit-winhttp/master/WinHttp.au3 here]).
==== Chrome ====
==== Chrome ====
<div class="usermessage mw-customtoggle-DebugChrome1">Chrome does not start and the DOS window for chromedriver does not get displayed</div>
<div class="usermessage mw-customtoggle-DebugChrome1">Chrome does not start and the DOS window for chromedriver does not get displayed</div>
Line 208: Line 337:


== FAQ ==
== FAQ ==
<small>(Last modified: 2020/02/17)<br></small>
<small>(Last modified: 2022/03/24)<br></small>


<div class="usermessage mw-customtoggle-FAQ1">How to connect to a running browser instance</div>
<div class="usermessage mw-customtoggle-FAQ1">1. How to connect to a running browser instance</div>
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ1">
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ1">
<div class="toccolours mw-collapsible-content">Q: How can I connect to a running browser instance?<br>A: That's described (for Firefox, but should work similar for other browsers) in this [https://www.autoitscript.com/forum/topic/201106-webdriver-udf-help-support-ii/?do=findComment&comment=1444173 post] or in the [https://github.com/Danp2/WebDriver/wiki/Connecting-to-existing-browser-instance Github wiki].</div>
<div class="toccolours mw-collapsible-content">Q: How can I connect to a running browser instance?<br>A: That's described (for Firefox, but should work similar for other browsers) in [https://www.autoitscript.com/forum/topic/201537-webdriver-example-scripts-collection/?do=findComment&comment=1498168 this post for FireFox] or [https://www.autoitscript.com/forum/topic/201537-webdriver-example-scripts-collection/page/2/#comment-1505978  this post for Google Chrome].</div>
</div>
</div>


<div class="usermessage mw-customtoggle-FAQ2">How to hide the webdriver console</div>
<div class="usermessage mw-customtoggle-FAQ2">2. How to hide the webdriver console</div>
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ2">
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ2">
<div class="toccolours mw-collapsible-content">Q: How can I hide the webdriver console?<br>A: The console can be completely hidden from the start by adding the following line near the beginning of your script:<br><syntaxhighlight lang="autoit">$_WD_DEBUG = $_WD_DEBUG_None ; You could also use $_WD_DEBUG_Error</syntaxhighlight>You can also control the visibility of the console with the function _WD_ConsoleVisible.</div>
<div class="toccolours mw-collapsible-content">Q: How can I hide the webdriver console?<br>A: The console can be completely hidden from the start by adding the following line near the beginning of your script:<br><syntaxhighlight lang="autoit">$_WD_DEBUG = $_WD_DEBUG_None ; You could also use $_WD_DEBUG_Error</syntaxhighlight>You can also control the visibility of the console with the function _WD_ConsoleVisible.</div>
</div>
</div>


<div class="usermessage mw-customtoggle-FAQ3">How to utilize an existing user profile</div>
<div class="usermessage mw-customtoggle-FAQ3">3. How to utilize an existing user profile</div>
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ3">
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ3">
<div class="toccolours mw-collapsible-content">Q: Can I use an existing user profile instead of the default behavior of using a new one?<br>A: This is controlled by your "capabilities" declaration, with each browser using a different method to implement. Here are some examples --<br>
<div class="toccolours mw-collapsible-content">Q: Can I use an existing user profile instead of the default behavior of using a new one?<br>A: This is controlled by your "capabilities" declaration, with each browser using a different method to implement. Here are some examples:<br>
<br>'''Chrome'''<syntaxhighlight lang="autoit">$sDesiredCapabilities = '{"capabilities": {"alwaysMatch": {"goog:chromeOptions": {"w3c": true, "args":["--user-data-dir=C:\\Users\\' & @UserName & '\\AppData\\Local\\Google\\Chrome\\User Data\\", "--profile-directory=Default"]}}}}'</syntaxhighlight>'''Firefox'''<syntaxhighlight lang="autoit">$sDesiredCapabilities = '{"capabilities":{"alwaysMatch": {"moz:firefoxOptions": {"args": ["-profile", "C:/Users/AppData/Roaming/Mozilla/Firefox/Profiles/gbjaumrnd.default"],"log": {"level": "trace"}}}}}'</syntaxhighlight></div>
<br>'''Chrome'''<syntaxhighlight lang="autoit">$sDesiredCapabilities = '{"capabilities": {"alwaysMatch": {"goog:chromeOptions": {"w3c": true, "args":["--user-data-dir=C:\\Users\\' & @UserName & '\\AppData\\Local\\Google\\Chrome\\User Data\\", "--profile-directory=Default"]}}}}'</syntaxhighlight>'''MS Edge'''<syntaxhighlight lang="autoit">$sDesiredCapabilities = '{"capabilities": {"alwaysMatch": {"ms:edgeOptions": {"args": ["user-data-dir=C:\\Users\\' & @UserName & '\\AppData\\Local\\Microsoft\\Edge\\User Data\\", "profile-directory=Default"]}}}}'</syntaxhighlight>'''Firefox'''<syntaxhighlight lang="autoit">
$sDesiredCapabilities = '{"capabilities":{"alwaysMatch": {"moz:firefoxOptions": {"args": ["-profile", "' & GetDefaultFFProfile() & '"],"log": {"level": "trace"}}}}}'
 
Func GetDefaultFFProfile()
Local $sDefault, $sProfilePath = ''
 
Local $sProfilesPath = StringReplace(@AppDataDir, '\', '/') & "/Mozilla/Firefox/"
Local $sFilename = $sProfilesPath & "profiles.ini"
Local $aSections = IniReadSectionNames ($sFilename)
 
If Not @error Then
For $i = 1 To $aSections[0]
$sDefault = IniRead($sFilename, $aSections[$i], 'Default', '0')
 
If $sDefault = '1' Then
$sProfilePath = $sProfilesPath & IniRead($sFilename, $aSections[$i], "Path", "")
ExitLoop
EndIf
Next
EndIf
 
Return $sProfilePath
EndFunc
</syntaxhighlight>You will also likely need to specify the marionette port:
<syntaxhighlight lang="autoit">_WD_Option('DriverParams', '--marionette-port 2828')</syntaxhighlight></div>
</div>
</div>


<div class="usermessage mw-customtoggle-FAQ4">How to specify location of browser executable</div>
<div class="usermessage mw-customtoggle-FAQ4">4. How to specify location of browser executable</div>
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ4">
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ4">
<div class="toccolours mw-collapsible-content">Q: Is it possible to launch a browser installed in a non-standard location?<br>A: This is controlled by your "capabilities" declaration. Here are some examples --<br>
<div class="toccolours mw-collapsible-content">Q: Is it possible to launch a browser installed in a non-standard location?<br>A: This is controlled by your "capabilities" declaration. Here are some examples:<br>
<br>'''Chrome'''<syntaxhighlight lang="autoit">$sDesiredCapabilities = '{"capabilities": {"alwaysMatch": {"goog:chromeOptions": {"w3c": true, "binary":"C:\\Path\\To\\Alternate\\Browser\\chrome.exe" }}}}'
<br>'''Chrome'''<syntaxhighlight lang="autoit">$sDesiredCapabilities = '{"capabilities": {"alwaysMatch": {"goog:chromeOptions": {"w3c": true, "binary":"C:\\Path\\To\\Alternate\\Browser\\chrome.exe" }}}}'
</syntaxhighlight>'''Firefox'''<syntaxhighlight lang="autoit">$sDesiredCapabilities = '{"desiredCapabilities":{"javascriptEnabled":true,"nativeEvents":true,"acceptInsecureCerts":true,"moz:firefoxOptions":{"binary":"C:\\Path\\To\\Alternate\\Browser\\firefox.exe"}}}'</syntaxhighlight>Alternate Firefox method --<br><syntaxhighlight lang="autoit">
</syntaxhighlight>'''Firefox'''<syntaxhighlight lang="autoit">$sDesiredCapabilities = '{"desiredCapabilities":{"javascriptEnabled":true,"nativeEvents":true,"acceptInsecureCerts":true,"moz:firefoxOptions":{"binary":"C:\\Path\\To\\Alternate\\Browser\\firefox.exe"}}}'</syntaxhighlight>Alternate Firefox method:<br><syntaxhighlight lang="autoit">
_WD_Option('DriverParams', '--binary "C:\Program Files\Mozilla Firefox\firefox.exe" --log trace ')</syntaxhighlight></div>
_WD_Option('DriverParams', '--binary "C:\Program Files\Mozilla Firefox\firefox.exe" --log trace ')</syntaxhighlight>
</div>
</div>
</div>


<div class="usermessage mw-customtoggle-FAQ5">How to maximize the browser window</div>
<div class="usermessage mw-customtoggle-FAQ5">5. How to maximize the browser window</div>
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ5">
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ5">
<div class="toccolours mw-collapsible-content">Q: Is it possible to maximize the browser window?<br>A: Simply call the following function:<syntaxhighlight lang="autoit">_WD_Window($sSession, "Maximize")
<div class="toccolours mw-collapsible-content">Q: Is it possible to maximize the browser window?<br>A: Simply call the following function:<syntaxhighlight lang="autoit">_WD_Window($sSession, "Maximize")
</syntaxhighlight></div>
</syntaxhighlight>Make sure to call _WD_Window after the session has been created with _WD_CreateSession.</div></div>
</div>


<div class="usermessage mw-customtoggle-FAQ6">How to specify location of WebDriver executable</div>
<div class="usermessage mw-customtoggle-FAQ6">6. How to specify location of WebDriver executable</div>
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ6">
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ6">
<div class="toccolours mw-collapsible-content">Q: Is it possible to launch the WebDriver executable from a specific location?<br>A: This is controlled by function "_WD_Option". Example:
<div class="toccolours mw-collapsible-content">Q: Is it possible to launch the WebDriver executable from a specific location?<br>A: This is controlled by function "_WD_Option". Example:
<br><syntaxhighlight lang="autoit">_WD_Option("Driver", "C:\local\WebDriver\WebDriver.exe")</syntaxhighlight></div>
<br><syntaxhighlight lang="autoit">_WD_Option("Driver", "C:\local\WebDriver\WebDriver.exe")</syntaxhighlight>
</div>
</div>
 
<div class="usermessage mw-customtoggle-FAQ7">7. How to retrieve the values of a drop-down list</div>
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ7">
<div class="toccolours mw-collapsible-content">Q: How to retrieve the values of a drop-down list (<Select> tag)?<br>A1: Here's a simple way to do it:
<br><syntaxhighlight lang="autoit">$sElement = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//select[@name='xxx']")
$sText = _WD_ElementAction($sSession, $sElement, 'property', 'innerText')
$aOptions = StringSplit ( $sText, @LF,  $STR_NOCOUNT)
_ArrayDisplay($aOptions)</syntaxhighlight>
'xxx' is the name of the drop-down list.
<br>A2: This can now be accomplished using the function _WD_ElementSelectAction:<br><syntaxhighlight lang="autoit">$sElement = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//select[@name='xxx']")
$aOptions = _WD_ElementSelectAction ($sSession, $sElement, 'options')
_ArrayDisplay($aOptions)</syntaxhighlight>
</div>
</div>
 
<div class="usermessage mw-customtoggle-FAQ8">8. How to run the browser in headless mode (hidden mode)</div>
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ8">
<div class="toccolours mw-collapsible-content">Q: How do I run the browser in "headless" mode?<br>A: This is controlled by the Capabilities string that is passed to _WD_CreateSession. Example:
<br><syntaxhighlight lang="autoit">$sDesiredCapabilities = '{"capabilities": {"alwaysMatch": {"goog:chromeOptions": {"w3c": true, "args": ["--headless", "--allow-running-insecure-content"] }}}}' </syntaxhighlight>
</div>
</div>
 
<div class="usermessage mw-customtoggle-FAQ9">9. How to configure the UDF to call a user-defined Sleep function</div>
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ9">
<div class="toccolours mw-collapsible-content">
Q: How to configure the UDF to call a user-defined Sleep function, and interact with _WD_WaitElement() and _WD_LoadWait() to make the script more responsive?
<br>
A: Try to use: _WD_Option("Sleep") . Example:
<br>
<syntaxhighlight lang="autoit">
#include <ButtonConstants.au3>
#include <GuiComboBoxEx.au3>
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <WindowsConstants.au3>
#include "wd_helper.au3"
 
Global $idAbortTest
Global $WD_SESSION
_Example()
 
Func _Example()
SetupChrome()
 
; Create a GUI with various controls.
Local $hGUI = GUICreate("Example")
Local $idTest = GUICtrlCreateButton("Test", 10, 370, 85, 25)
$idAbortTest = GUICtrlCreateButton("Abort", 150, 370, 85, 25)
 
; Display the GUI.
GUISetState(@SW_SHOW, $hGUI)
 
ConsoleWrite("- TESTING" & @CRLF)
 
Local $sFilePath = _WriteTestHtml()
 
; Loop until the user exits.
While 1
Switch GUIGetMsg()
Case $idTest
_WD_Navigate($WD_SESSION, $sFilePath)
_WD_WaitElement($WD_SESSION, $_WD_LOCATOR_ByXPath, '//a[contains(text(),"TEST")]', 100, 30 * 1000) ; timeout = 50 seconds
ConsoleWrite("---> @error=" & @error & "  @extended=" & @extended & _
" : after _WD_WaitElement()" & @CRLF)
 
Case $GUI_EVENT_CLOSE
ExitLoop
 
EndSwitch
WEnd
 
; Delete the previous GUI and all controls.
GUIDelete($hGUI)
 
EndFunc  ;==>_Example
 
Func _My_Sleep($iDelay)
Local $hTimer = TimerInit() ; Begin the timer and store the handle in a variable.
Do
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
ConsoleWrite("! USER EXIT" & @CRLF)
Exit
Case $idAbortTest
Return SetError($_WD_ERROR_UserAbort)
EndSwitch
Until TimerDiff($hTimer) > $iDelay
EndFunc  ;==>_My_Sleep
 
Func _WriteTestHtml($sFilePath = @ScriptDir & "\TestFile.html")
FileDelete($sFilePath)
Local Const $sHtml = _
"<html lang='en'>" & @CRLF & _
"    <head>" & @CRLF & _
"        <meta charset='utf-8'>" & @CRLF & _
"        <title>TESTING</title>" & @CRLF & _
"    </head>" & @CRLF & _
"    <body>" & @CRLF & _
"        <div id='MyLink'>Waiting</div>" & @CRLF & _
"    </body>" & @CRLF & _
"    <script type='text/javascript'>" & @CRLF & _
"    setTimeout(function()" & @CRLF & _
"    {" & @CRLF & _
"        // Delayed code in here" & @CRLF & _
"        document.getElementById('MyLink').innerHTML='<a>TESTING</a>';" & @CRLF & _
"    }, 20000); // 20000 = 20 seconds" & @CRLF & _
"    </script>" & @CRLF & _
"</html>"
FileWrite($sFilePath, $sHtml)
Return "file:///" & StringReplace($sFilePath, "\", "/")
EndFunc  ;==>_WriteTestHtml
 
Func SetupChrome()
_WD_Startup()
_WD_Option('Driver', 'chromedriver.exe')
_WD_Option('Port', 9515)
_WD_Option('HTTPTimeouts', True)
_WD_Option('DefaultTimeout', 40001)
_WD_Option('DriverParams', '--verbose --log-path="' & @ScriptDir & '\chrome.log"')
_WD_Option("Sleep", _My_Sleep)
 
Local $sCapabilities = '{"capabilities": {"alwaysMatch": {"goog:chromeOptions": {"w3c": true, "excludeSwitches": [ "enable-automation"]}}}}'
$WD_SESSION = _WD_CreateSession($sCapabilities)
_WD_Timeouts($WD_SESSION, 40002)
EndFunc  ;==>SetupChrome
</syntaxhighlight>
</div>
</div>
 
<div class="usermessage mw-customtoggle-FAQ10">10. How to keep my WebDriver environment up-to-date</div>
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ10">
<div class="toccolours mw-collapsible-content">
Q: How can I keep my WebDriver environment up-to-date?<br>
A: You have to check the following components:<p>
<b>WebDriver UDF:</b> Function _WD_IsLatestRelease compares local UDF version to latest release on Github. Returns True if the local UDF version is the latest, otherwise False. If you need to update the UDF you have to download it manually.<br>
<b>WebDriver Exe:</b> Function _WD_UpdateDriver checks or updates the Web Driver with newer version, if available.<br>
<b>Browser:</b> Function _WD_GetBrowserVersion returns the version number of the specified browser. If you need to update the Browser you have to download and install it by hand.<br>
</div>
</div>
 
<div class="usermessage mw-customtoggle-FAQ11">11. How to use "Locator strategy" and "Selectors"?</div>
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ11">
<div class="toccolours mw-collapsible-content">
Q: How to use "Locator strategies" and how to find "Selectors"?<br>
A: This UDF supports all locators defined in the Webdriver specifications. Below is a listing of predefined constants:<br>
{| class="wikitable"
|-
! Locator strategy !! Description how to use "Selector"
|-
| $_WD_LOCATOR_ByCSSSelector || CSS Selector string (see this [https://www.w3schools.com/css/css_selectors.asp site]). In CSS, pattern matching rules determine which style rules apply to elements in the HTML DOM document tree.
|-
| $_WD_LOCATOR_ByXPath || XPath string (see this [https://www.w3schools.com/xml/xml_xpath.asp site]). XPath is a language for addressing parts of an XML document.
|-
| $_WD_LOCATOR_ByLinkText || String with exact text of <a> element, which should be used to locate the proper <a> element.
|-
| $_WD_LOCATOR_ByPartialLinkText || String with partial text of <a> element, which should be used to locate the proper <a> element.
|-
| $_WD_LOCATOR_ByTagName || String that matches the desired element tag name, for example "button" is tag name of this element: <button name="ClickMe">
|}
<br>
Q: How can I check XPath and CSSSelector in the Browser?<br>
A: '''Work in progress....'''<br>
A: Take a look on this link: [https://developer.chrome.com/docs/devtools/dom/ Get Started With Viewing And Changing The DOM]<br>
A: Take a look on this link: [https://www.selenium.dev/documentation/webdriver/elements/locators/ Locator strategies]<br>
A: Take a look on this link: [https://testerlive.wordpress.com/2016/07/02/how-to-search-by-xpathcss-in-chrome-developer-tools/ How to search by Xpath/Css in Chrome Developer Tools?]<br>
 
 
</div>
</div>
 
<div class="usermessage mw-customtoggle-FAQ12">12. How to download PDF (or any other) file automatically?</div>
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ12">
<div class="toccolours mw-collapsible-content">
Q: How to avoid browsers asking what to do with a file after clicking the "Download" button on a website?<br>
A: In FireFox you should add additional capabilites settings:
<syntaxhighlight lang="autoit">
_WD_CapabilitiesAdd("prefs", "pdfjs.disabled", True)
_WD_CapabilitiesAdd("prefs", "browser.download.folderList", 2)
_WD_CapabilitiesAdd("prefs", "browser.download.dir", $s_Download_dir)
_WD_CapabilitiesAdd("prefs", "browser.helperApps.neverAsk.saveToDisk", "application/pdf,application/octet-stream")
_WD_CapabilitiesAdd("prefs", "browser.helperApps.neverAsk.openFile", "application/pdf,application/octet-stream")
_WD_CapabilitiesAdd("prefs", "browser.download.useDownloadDir", True)
_WD_CapabilitiesAdd("prefs", "browser.download.alwaysOpenPanel", False)
</syntaxhighlight>
 
In order to preset autodowloading another file type you have to change it accordingly by providing your desired MIME type:
 
https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
 
specifically here:
<syntaxhighlight lang="autoit">
_WD_CapabilitiesAdd("prefs", "browser.helperApps.neverAsk.saveToDisk", "application/pdf,application/octet-stream")
_WD_CapabilitiesAdd("prefs", "browser.helperApps.neverAsk.openFile", "application/pdf,application/octet-stream")
</syntaxhighlight>
 
</div>
</div>
 
<div class="usermessage mw-customtoggle-FAQ13">13. How to setup session with proxy?</div>
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ13">
<div class="toccolours mw-collapsible-content">
Q: How to automate websites behind proxy?<br>
A: Take a look on:
 
https://www.autoitscript.com/forum/topic/205553-webdriver-udf-help-support-iii/?do=findComment&comment=1498049
 
and
 
https://www.autoitscript.com/forum/topic/205553-webdriver-udf-help-support-iii/?do=findComment&comment=1498085
</div>
</div>
 
<div class="usermessage mw-customtoggle-FAQ14">14. How to add capabilities options for '''"goog:chromeOptions"''' or '''"ms:edgeOptions"''' or '''"moz:firefoxOptions"'''?</div>
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ14">
<div class="toccolours mw-collapsible-content">
Q: How to add options for '''"goog:chromeOptions"''' or '''"ms:edgeOptions"''' or '''"moz:firefoxOptions"''' ?<br>
A: Use _WD_CapabilitiesDefine() function like int the following example:
<syntaxhighlight lang="autoit">
_WD_CapabilitiesDefine($_WD_CAPS_TYPES__SPECIFICVENDOR_ARRAY, 'NewCapabilityArray')
</syntaxhighlight>
 
</div>
</div>
 
<div class="usermessage mw-customtoggle-FAQ15">15. How to change user-agent?</div>
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ15">
<div class="toccolours mw-collapsible-content">
Q: How to change user-agent?<br>
A: Example for chrome:
<syntaxhighlight lang="autoit">
_WD_CapabilitiesAdd("args", "user-agent", "Mozilla/5.0 (Windows NT 10.0; Win" & StringReplace(@OSArch, "X", "") & "; " & @CPUArch & ") AppleWebKit/537.36 (KHTML, like Gecko) Chrome/" & _WD_GetBrowserVersion("chrome") & " Safari/537.36")
</syntaxhighlight>
 
A: Example for firefox:
<syntaxhighlight lang="autoit">
_WD_CapabilitiesAdd("args", "user-agent", "Mozilla/5.0 (Windows NT 10.0; Win" & StringReplace(@OSArch, "X", "") & "; " & @CPUArch & ") AppleWebKit/537.36 (KHTML, like Gecko) Chrome/" & _WD_GetBrowserVersion("firefox") & " Safari/537.36")
</syntaxhighlight>
 
</div>
</div>
 
<div class="usermessage mw-customtoggle-FAQ16">16. How to enable/disable logging into webdriver console?</div>
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ16">
<div class="toccolours mw-collapsible-content">
Q: How to enable/disable logging into webdriver console?<br>
A: Example for chrome:
<syntaxhighlight lang="autoit">
_WD_CapabilitiesAdd("excludeSwitches", "enable-logging")
_WD_CapabilitiesAdd("excludeSwitches", "disable-logging")
</syntaxhighlight>
 
</div>
</div>
 
<div class="usermessage mw-customtoggle-FAQ17">17. How to use devtools in browsers?</div>
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ17">
<div class="toccolours mw-collapsible-content">
** [https://www.youtube.com/watch?v=Me9hjqd74m8&t=58s YouTube video: How to work with frames in Firefox?]
** [https://www.youtube.com/watch?v=TUpsyv9A9vU YouTube video: Inspecting a webpage's HTML using Developer Tools in Google Chrome]
** [https://www.youtube.com/watch?v=1l4xz1QQhew YouTube video: How to use Google Chrome Inspect Element tool]
** [https://www.youtube.com/watch?v=NRn70H8XOZc YouTube video: A Fun Way to Use the Inspect Tool in Chrome]
** [https://www.youtube.com/watch?v=f5pTCMPomuA YouTube video: How to use Inspect Element on disappearing items (hidden content) - Google Chrome Browser?]
** [https://www.youtube.com/watch?v=WfKG9C00giI YouTube video: How to Use the Google Chrome Inspect Tool]
 
</div>
</div>
 
<div class="usermessage mw-customtoggle-FAQ18">18. How to troubleshoot when you can't locate the desired element using _WD_FindElement() ?</div>
<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-FAQ18">
<div class="toccolours mw-collapsible-content">
When you encounter a problem locating an item with _WD_FindElement() you should follow this procedure:
 
WIP....
* check in your browser if your locator (XPATH , CSSSelector) is valid
* check in your browser if your locator (XPATH , CSSSelector) find one or multiple instances of the element
* check in your browser if your locator (XPATH , CSSSelector) find element in different frame or if this is within #shadow-root
* use _WD_FrameList() to check if you have multiple even nested frames in website you are trying to automate
* use _WD_LocateElement() to check Element location within multiple even nested frames
* use _WD_FrameEnter() to change frame to be able to use _WD_FindElement() in order to find element within desired frame
 
<syntaxhighlight lang="autoit">
</syntaxhighlight>
 
</div>
</div>
</div>


== Tools ==
== Tools ==
The following tools will help you to automate your browser:
The following tools will help you to automate your browser:
* [https://autonomiq.io/chropath/ ChroPath] plugin: Makes finding an element by XPath, ID or CSS incredibly easy (Chrome, Firefox, Opera)
* [https://autonomiq.io/deviq-chropath.html ChroPath] plugin: Makes finding an element by XPath, ID or CSS incredibly easy (Chrome, Firefox, Opera)
* [https://selectorshub.com/ SelectorsHub] plugin: Next Gen XPath tool to generate, write and verify the XPath and cssSelectors (All browsers)
* [https://addons.mozilla.org/pl/firefox/addon/save-page-we Save Page WE] plugin: helps to save web page content as single MHTML file ([https://addons.mozilla.org/pl/firefox/addon/save-page-we Save Page WE for Firefox], [https://chrome.google.com/webstore/detail/save-page-we/dhhpefjklgkmgeafimnjhojgjamoafof Save Page WE for Chrome])
* [https://github.com/openstyles/stylus Stylus] Stylus is a fork of Stylish for Chrome, also compatible with Firefox as a WebExtension


== References ==
== References ==
<small>(Last modified: 2020/01/28)<br></small>
<small>(Last modified: 2022/02/12)<br></small>


Further information sources:
Further information sources:
* W3C: https://www.w3.org/TR/webdriver/
* W3C: https://www.w3.org/TR/webdriver/
* AutoIt WebDriver threads:
* AutoIt WebDriver discussion threads:
** Danp2's thread in the '''[https://www.autoitscript.com/forum/topic/191990-webdriver-udf-w3c-compliant-version-12242019 Example Scripts]''' forum - WebDriver UDF (W3C compliant version)
** '''[https://www.autoitscript.com/forum/topic/208633-webdriver-udf-w3c-compliant-version-20221003/ WebDriver UDF (W3C compliant version)]''' by @Danp2
** Danp2's thread in the '''[https://www.autoitscript.com/forum/topic/192730-webdriver-udf-help-support/ General Help and Support]''' forum
** '''[https://www.autoitscript.com/forum/topic/192730-webdriver-udf-help-support/ WebDriver UDF - Help & Support]''' by @Danp2
** Water's thread in the '''[https://www.autoitscript.com/forum/topic/201283-im-creating-a-webdriver-tutorial General Help and Support]''' forum - Discussion about this Wiki Page
** '''[https://www.autoitscript.com/forum/topic/201106-webdriver-udf-help-support-ii/ WebDriver UDF - Help & Support (II)]''' by @Danp2
** WebDriver '''[https://www.autoitscript.com/forum/topic/201537-webdriver-example-scripts-collection/ Example Scripts Collection]'''
** '''[https://www.autoitscript.com/forum/topic/205553-webdriver-udf-help-support-iii/ WebDriver UDF - Help & Support (III)]''' by @Danp2
* WebDriver Exe documentation
** '''[https://www.autoitscript.com/forum/topic/208640-webdriver-udf-help-support-iv/ WebDriver UDF - Help & Support (IV)]''' by @Danp2
** [https://sites.google.com/a/chromium.org/chromedriver/ Chrome]
** '''[https://www.autoitscript.com/forum/topic/201283-im-creating-a-webdriver-tutorial I'm creating a WebDriver tutorial]''' by @Water
** '''[https://www.autoitscript.com/forum/topic/201537-webdriver-example-scripts-collection/ WebDriver example scripts collection]''' by @Water
** '''[https://www.autoitscript.com/forum/topic/201537-webdriver-example-scripts-collection/ Webdriver, Websockets, and Chrome DevTools Protocol]''' by @Danp2
 
* WebDriver Exe documentation:
** [https://sites.google.com/chromium.org/driver/ Chrome]
** [https://docs.microsoft.com/en-us/microsoft-edge/webdriver Edge]
** [https://docs.microsoft.com/en-us/microsoft-edge/webdriver Edge]
** [https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium Edge Chromium]
** [https://firefox-source-docs.mozilla.org/testing/geckodriver/ Firefox]
** [https://firefox-source-docs.mozilla.org/testing/geckodriver/ Firefox]
** [https://selenium.dev/documentation/en/webdriver/ Opera]
** [https://selenium.dev/documentation/en/webdriver/ Opera (Selenium)]
 
* Other useful links:
** [https://github.com/jlipps/simple-wd-spec/ The W3C WebDriver Spec: A Simplified Guide]
** [https://github.com/mlipok/Au3WebDriver-testing Au3WebDriver-testing - Some complex template for testing Au3WebDriver cases]
** [https://github.com/Sven-Seyfert/au3webdriver-boilerplate The project "au3webdriver-boilerplate" - A quick entry point for the au3WebDriver project]
 
[[Category:Tutorials]]
[[Category:UDF]]

Latest revision as of 08:12, 25 April 2024

The W3C WebDriver API is a platform and language-neutral interface and wire protocol allowing programs or scripts to control the behavior of a web browser.

Introduction

WebDriver API

WebDriver enables developers to create automated tests that simulate user interaction. This is different from JavaScript unit tests because WebDriver has access to functionality and information that JavaScript running in the browser doesn't, and it can more accurately simulate user events or OS-level events. WebDriver can also manage testing across multiple windows, tabs and webpages in a single test session.

WebDriver UDF

The WebDriver UDF allows to interact with any browser that supports the W3C WebDriver specifications. Supporting multiple browsers via the same code base is now possible with just a few configuration settings.

Requirements

(Last modified: 2022/01/25)

The following UDFs need to be installed - independent of the Browser you try to automate:

One of the following Drivers needs to be installed - depending on the Browser type and version you try to automate:

Browser Download Link Comments
Chrome Google Follow this link to select the correct version depending on the Chrome version you run!
Edge Microsoft
Firefox GitHub Firefox version ≥ 60 is recommended

Note: You must still have the Microsoft Visual Studio redistributable runtime installed on your system for the binary to run. This is a known bug in version 0.26 which the authors weren't able fix for this release.

Opera GitHub The versioning of OperaDriver matches the Chromium version on which Opera browser is based on.

Limitations

(Last modified: 2020/01/28)
Not all WebDriver functions have been implemented by each browser. To check the status goto the corresponding website below:

  • Chrome
  • Edge
  • Firefox
  • Opera: "OperaChromiumDriver is a WebDriver implementation derived from ChromeDriver and adapted by Opera". That's why I think it has at least the same limitations as ChromeDriver.

Big Picture

How the browser independent and browser dependent parts fit together:

Big Picture - How everything fits together

Technical terms

(Last modified: 2022/02/12)

You will encounter the following technical terms when working with the WebDriver UDF.
These terms are not unique to the UDF, so you will find just the general description in this section. How to use these terms with the WebDriver UDF can be found in the FAQ.

CDP (Chrome DevTools Protocol)
Is a protocol that allows for tools to instrument, inspect, debug and profile Chromium, Chrome and other Blink-based browsers.
CSS Selector
Please see Selector.
Locator Strategy
A Locator strategy describes the method to use to search elements. This includes Linktext, Partial Linktext, Tag Name, CSS selector, XPath selector.
Marionette
Marionette is an automation driver for Mozilla’s Gecko engine. It can remotely control either the UI or the internal JavaScript of a Gecko platform, such as Firefox. It can control both the chrome (i.e. menus and functions) or the content (the webpage loaded inside the browsing context), giving a high level of control and ability to replicate user actions. In addition to performing actions on the browser, Marionette can also read the properties and attributes of the DOM.
Marionette consists of two parts: a server which takes requests and executes them in Gecko (the Marionette server ships with Firefox), and a client (the Marionette client ships with the GeckoDriver exe). The client sends commands to the server and the server executes the command inside the browser.
For details please visit this site.
Selector
Selectors are patterns used to select the element(s) you want to process. They are used by
CSS (see this link for Beginners or this link for Advanced) and
XPath (see this link for Beginners and this link for Advanced).
ShadowRoot
The ShadowRoot interface of the Shadow DOM API is the root node of a DOM sub tree that is rendered separately from a document's main DOM tree.
For details please visit this site.
XPath
XPath is a language for navigating in XML documents. XPath is a major element in the XSLT standard and includes over 200 built-in functions.
XQuery
XQuery is a language for querying XML documents.
For details please visit this site.
XSLT
XSLT is a language for transforming XML documents.
For details please visit this site.

Installation

(Last modified: 2022/02/02)

To automate your browser the following installation steps are needed:

  • Download the files listed in section "Requirements"
  • Move the UDFs to a directory where SciTE and Autoit can find them:
    • wd_Core.au3, wd_helper.au3 , wd_cdp.au3 , wd_capabilities.au3 from the WebDriver UDF
    • Json.au3 and BinaryCall.au3 from the JSON UDF
    • WinHttp.au3 and WinHttpConstants.au3 from the WinHttp UDF
  • Move the browser dependent WebDriver to the same directory (with WD_Demo.au3):
    • chromedriver.exe (Chrome)
    • geckodriver.exe (Firefox)
    • msedgedriver.exe (Edge - Chromium) or MicrosoftWebDriver.exe (Edge - EdgeHTML)
    • or use "Update" option by choosing one of ComboBox option in WD_Demo.au3
  • Run WD_Demo.au3 and select "DemoNavigation" to validate the installation.
    The result (for Firefox) displayed in the DOS window should be similar to the following:
1577745813519   geckodriver     DEBUG   Listening on 127.0.0.1:4444
1577745813744   webdriver::server       DEBUG   -> POST /session {"capabilities": {"alwaysMatch": {"browserName": "firefox", "acceptInsecureCerts":true}}}
1577745813746   geckodriver::capabilities       DEBUG   Trying to read firefox version from ini files
1577745813747   geckodriver::capabilities       DEBUG   Found version 71.0
1577745813757   mozrunner::runner       INFO    Running command: "C:\\Program Files\\Mozilla Firefox\\firefox.exe" "-marionette" "-foreground" "-no-remote" "-profile" "C:\\ ...
1577745813783   geckodriver::marionette DEBUG   Waiting 60s to connect to browser on 127.0.0.1:55184
1577745817392   geckodriver::marionette DEBUG   Connection to Marionette established on 127.0.0.1:55184.
1577745817464   webdriver::server       DEBUG   <- 200 OK {"value":{"sessionId":"925641bf-6c5d-4fe2-a985-02de9b1c7c74","capabilities":"acceptInsecureCerts":true,"browserName":"firefox", ...

Getting started example

(Last modified: 2023/09/09)

#include "wd_helper.au3"
#include "wd_capabilities.au3"

_Example()

Func _Example()
	# REMARK
	#   This is not functional script
	#   It only shows the concept how to use WebDriver UDF

	#Region ; initialize webdriver sesion

	; you should take care about download/update dirver
	If $IDYES = MsgBox($MB_YESNO + $MB_TOPMOST + $MB_ICONQUESTION + $MB_DEFBUTTON1, "Question", _
			"Do you want to download/update driver ?") Then
		_WD_UpdateDriver('chrome')
	EndIf

	; specify driver, port and other options
	_WD_Option('Driver', 'chromedriver.exe')
	_WD_Option('Port', 9515)
	_WD_Option('DriverParams', '--verbose --log-path="' & @ScriptDir & '\chrome.log"')

	; start the driver
	_WD_Startup()
	If @error Then Return SetError(@error, @extended, 0) ; always remember to check and handle error's

	; create capabilites for session
	_WD_CapabilitiesStartup()
	_WD_CapabilitiesAdd('alwaysMatch', 'chrome')
	_WD_CapabilitiesAdd('w3c', True)
	_WD_CapabilitiesAdd('excludeSwitches', 'enable-automation')
	Local $sCapabilities = _WD_CapabilitiesGet()

	; create session with given Capabilities
	Local $WD_SESSION = _WD_CreateSession($sCapabilities)
	If @error Then Return SetError(@error, @extended, 0) ; always remember to check and handle error's

	#EndRegion ; initialize webdriver sesion

	#Region ; do your's stuff

	; navigate to some website
	Local $sURL = '******'
	_WD_Navigate($WD_SESSION, $sURL)
	If @error Then Return SetError(@error, @extended, 0) ; always remember to check and handle error's

	; wait for loading process ends
	_WD_LoadWait($WD_SESSION, 1000)
	If @error Then Return SetError(@error, @extended, 0) ; always remember to check and handle error's

	; for example find element
	Local $sXPath = "*****"
	Local $sElement = _WD_FindElement($WD_SESSION, $_WD_LOCATOR_ByXPath, $sXPath)
	If @error Then Return SetError(@error, @extended, 0) ; always remember to check and handle error's

	; get element text
	Local $sText = _WD_ElementAction($WD_SESSION, $sElement, 'text')
	If @error Then Return SetError(@error, @extended, 0) ; always remember to check and handle error's
	ConsoleWrite($sText & @CRLF)

	; or click the element
	_WD_ElementAction($WD_SESSION, $sElement, 'click')
	If @error Then Return SetError(@error, @extended, 0) ; always remember to check and handle error's

	#EndRegion ; do your's stuff

	#Region ; Clean Up

	; on the end session should be deleted
	_WD_DeleteSession($WD_SESSION)
	If @error Then Return SetError(@error, @extended, 0) ; always remember to check and handle error's

	; and driver should be closed
	_WD_Shutdown()
	If @error Then Return SetError(@error, @extended, 0) ; always remember to check and handle error's

	#EndRegion ; Clean Up

EndFunc   ;==>_Example

Function reference

(Last modified: 2021/12/09)

The functions are now documented in the CHM help file that comes with the UDF.

Capabilities

WebDriver capabilities are used to communicate the features supported by a given implementation. The local end may use capabilities to define which features it requires the remote end to satisfy when creating a new session. Likewise, the remote end uses capabilities to describe the full feature set for a session.
Details can be found at WebDriver Capabilities (sub page).

Browser related functionality

Google Chrome

ChromeDriver supports "Chrome DevTools Protocol" (CDP) commands (for an explanation of the term and related links please see the Used Terms section).
Details can be found in the CHM Help file that comes with the UDF.

Translate IE UDF to WebDriver

This page is still a work in progress.

Internet Explorer is no longer supported by Microsoft. Therefore, it may be necessary to rewrite existing scripts for other browsers using the WebDriver UDF. Below you will find a mapping of the functions of the IE UDF to the functions of the WebDriver UDF.

IE function WebDriver function Comments
_IEAction _WD_ElementAction + _WD_ElementActionEx
_IEAttach _WD_Attach

_WD_Attach: Attach to existing browser tab.

Attaching to running browser instance/session is much more difficult. Examples can be found here.

_IEBodyReadHTML _WD_GetSource
_IEBodyReadText _WD_ExecuteScript($sSession, 'return document.body.innerText',Default,Default, $_WD_JSON_Value)
_IEBodyWriteHTML _WD_ExecuteScript($s_Session, "document.body.outerHTML='" & $sHTML & "'")
_IECreate _WD_CreateSession
_IECreateEmbedded N/A
_IEDocGetObj
_IEDocInsertHTML
_IEDocInsertText
_IEDocReadHTML _WD_GetSource
_IEDocWriteHTML _WD_ExecuteScript($s_Session, "document.open();document.write(" & $sHTML & ");document.close();") https://stackoverflow.com/a/11984907/5314940
_IEErrorNotify N/A you can set debug level for example: $_WD_DEBUG = $_WD_DEBUG_Full
_IEFormElementCheckBoxSelect _WD_ElementActionEx _WD_FindElement + _WD_ElementActionEx($sSession, $sElement, "check")
_IEFormElementGetCollection _WD_FindElement
_IEFormElementGetObjByName _WD_GetElementByName
_IEFormElementGetValue _WD_ElementAction _WD_FindElement + _WD_ElementAction($sSession, $sSelectElement, "value")
_IEFormElementOptionSelect _WD_ElementSelectAction + _WD_ElementOptionSelect
_IEFormElementRadioSelect _WD_ElementSelectAction
_IEFormElementSetValue _WD_SetElementValue
_IEFormGetCollection _WD_FindElement
_IEFormGetObjByName _WD_GetElementByName
_IEFormImageClick _WD_ElementAction _WD_FindElement + _WD_ElementAction($sSession, $sElement, "click")
_IEFormReset
_IEFormSubmit
_IEFrameGetCollection _WD_FrameList _WD_FrameList($sSession, True)
_IEFrameGetObjByName _WD_GetElementByName + _WD_FrameEnter
_IEGetObjById _WD_GetElementById
_IEGetObjByName _WD_GetElementByName
_IEHeadInsertEventScript
_IEImgClick _WD_ElementAction _WD_FindElement + _WD_ElementAction($sSession, $sElement, "click")
_IEImgGetCollection _WD_FindElement
_IEIsFrameSet
_IELinkClickByIndex _WD_ElementAction _WD_FindElement + _WD_ElementAction($sSession, $sElement, "click")
_IELinkClickByText _WD_LinkClickByText
_IELinkGetCollection _WD_FindElement
_IELoadWait _WD_LoadWait
_IELoadWaitTimeout _WD_SetTimeouts
_IENavigate _WD_Navigate
_IEPropertyGet _WD_ElementAction _WD_FindElement + _WD_ElementAction($sSession, $sElement, 'property', 'nodeName')
_IEPropertySet _WD_ExecuteScript _WD_FindElement + ......
_IEQuit _WD_DeleteSession
_IETableGetCollection _WD_FindElement
_IETableWriteToArray _WD_GetTable _WD_FindElement + _WD_GetTable( ......
_IETagNameAllGetCollection _WD_FindElement
_IETagNameGetCollection _WD_FindElement
_IE_Example N/A Take a look at wd_demo.au3 script
_IE_Introduction N/A Take a look at wd_demo.au3 script
_IE_VersionInfo _WD_Option('version')

Troubleshooting

Debug the WebDriver setup

(Last modified: 2020/07/06)

WinHTTP UDF

Make sure that you are running at least version 1.6.4.2 (currently unreleased, but can be obtained here).

Chrome

Chrome does not start and the DOS window for chromedriver does not get displayed
Problem Solution Reference
When running WD_Demo.au3 it does not start up Chrome and does not display the DOS window for chromedriver.
When you manually run the chromedriver in a DOS window you get message "[0.023][SEVERE]: CreatePlatformSocket() returned an error: An invalid argument was supplied."
This could be caused by missing execution permission for the network drive. Please ask your IT admin for "Applocker" or "application directory whitelisting".
Or run the chrome driver from a local HDD and call _WD_Option to set the location of the webdriver executable. Example: _WD_Option("Driver", "C:\Local\WebDriver\chromedriver.exe")
Stackoverflow

Firefox

Firefox does not start and the DOS window for geckodriver does not get displayed
Problem Solution Reference
When running WD_Demo.au3 it does not start up Firefox and does not display the DOS window for geckodriver.
When you manually run the geckodriver in a DOS window you get message "geckodriver: error: An invalid argument was supplied. (os error 10022)"
This could be caused by missing execution permission for the network drive. Please ask your IT admin for "Applocker" or "application directory whitelisting".
Or run the gecko driver from a local HDD and call _WD_Option to set the location of the webdriver executable. Example: _WD_Option("Driver", "C:\Local\WebDriver\geckodriver.exe")
Stackoverflow

Debug your Script

FAQ

(Last modified: 2022/03/24)

1. How to connect to a running browser instance
Q: How can I connect to a running browser instance?
A: That's described (for Firefox, but should work similar for other browsers) in this post for FireFox or this post for Google Chrome.
2. How to hide the webdriver console
Q: How can I hide the webdriver console?
A: The console can be completely hidden from the start by adding the following line near the beginning of your script:
$_WD_DEBUG = $_WD_DEBUG_None ; You could also use $_WD_DEBUG_Error
You can also control the visibility of the console with the function _WD_ConsoleVisible.
3. How to utilize an existing user profile
Q: Can I use an existing user profile instead of the default behavior of using a new one?
A: This is controlled by your "capabilities" declaration, with each browser using a different method to implement. Here are some examples:

Chrome
$sDesiredCapabilities = '{"capabilities": {"alwaysMatch": {"goog:chromeOptions": {"w3c": true, "args":["--user-data-dir=C:\\Users\\' & @UserName & '\\AppData\\Local\\Google\\Chrome\\User Data\\", "--profile-directory=Default"]}}}}'
MS Edge
$sDesiredCapabilities = '{"capabilities": {"alwaysMatch": {"ms:edgeOptions": {"args": ["user-data-dir=C:\\Users\\' & @UserName & '\\AppData\\Local\\Microsoft\\Edge\\User Data\\", "profile-directory=Default"]}}}}'
Firefox
$sDesiredCapabilities = '{"capabilities":{"alwaysMatch": {"moz:firefoxOptions": {"args": ["-profile", "' & GetDefaultFFProfile() & '"],"log": {"level": "trace"}}}}}'

Func GetDefaultFFProfile()
	Local $sDefault, $sProfilePath = ''

	Local $sProfilesPath = StringReplace(@AppDataDir, '\', '/') & "/Mozilla/Firefox/"
	Local $sFilename = $sProfilesPath & "profiles.ini"
	Local $aSections = IniReadSectionNames ($sFilename)

	If Not @error Then
		For $i = 1 To $aSections[0]
			$sDefault = IniRead($sFilename, $aSections[$i], 'Default', '0')

			If $sDefault = '1' Then
				$sProfilePath = $sProfilesPath & IniRead($sFilename, $aSections[$i], "Path", "")
				ExitLoop
			EndIf
		Next
	EndIf

	Return $sProfilePath
EndFunc
You will also likely need to specify the marionette port:
_WD_Option('DriverParams', '--marionette-port 2828')
4. How to specify location of browser executable
Q: Is it possible to launch a browser installed in a non-standard location?
A: This is controlled by your "capabilities" declaration. Here are some examples:

Chrome
$sDesiredCapabilities = '{"capabilities": {"alwaysMatch": {"goog:chromeOptions": {"w3c": true, "binary":"C:\\Path\\To\\Alternate\\Browser\\chrome.exe" }}}}'
Firefox
$sDesiredCapabilities = '{"desiredCapabilities":{"javascriptEnabled":true,"nativeEvents":true,"acceptInsecureCerts":true,"moz:firefoxOptions":{"binary":"C:\\Path\\To\\Alternate\\Browser\\firefox.exe"}}}'
Alternate Firefox method:
_WD_Option('DriverParams', '--binary "C:\Program Files\Mozilla Firefox\firefox.exe" --log trace ')
5. How to maximize the browser window
Q: Is it possible to maximize the browser window?
A: Simply call the following function:
_WD_Window($sSession, "Maximize")
Make sure to call _WD_Window after the session has been created with _WD_CreateSession.
6. How to specify location of WebDriver executable
Q: Is it possible to launch the WebDriver executable from a specific location?
A: This is controlled by function "_WD_Option". Example:
_WD_Option("Driver", "C:\local\WebDriver\WebDriver.exe")
7. How to retrieve the values of a drop-down list
Q: How to retrieve the values of a drop-down list (<Select> tag)?
A1: Here's a simple way to do it:
$sElement = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//select[@name='xxx']")
$sText = _WD_ElementAction($sSession, $sElement, 'property', 'innerText')
$aOptions = StringSplit ( $sText, @LF,  $STR_NOCOUNT)
_ArrayDisplay($aOptions)

'xxx' is the name of the drop-down list.


A2: This can now be accomplished using the function _WD_ElementSelectAction:
$sElement = _WD_FindElement($sSession, $_WD_LOCATOR_ByXPath, "//select[@name='xxx']")
$aOptions = _WD_ElementSelectAction ($sSession, $sElement, 'options')
_ArrayDisplay($aOptions)
8. How to run the browser in headless mode (hidden mode)
Q: How do I run the browser in "headless" mode?
A: This is controlled by the Capabilities string that is passed to _WD_CreateSession. Example:
$sDesiredCapabilities = '{"capabilities": {"alwaysMatch": {"goog:chromeOptions": {"w3c": true, "args": ["--headless", "--allow-running-insecure-content"] }}}}'
9. How to configure the UDF to call a user-defined Sleep function

Q: How to configure the UDF to call a user-defined Sleep function, and interact with _WD_WaitElement() and _WD_LoadWait() to make the script more responsive?
A: Try to use: _WD_Option("Sleep") . Example:

#include <ButtonConstants.au3>
#include <GuiComboBoxEx.au3>
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <WindowsConstants.au3>
#include "wd_helper.au3"

Global $idAbortTest
Global $WD_SESSION
_Example()

Func _Example()
	SetupChrome()

	; Create a GUI with various controls.
	Local $hGUI = GUICreate("Example")
	Local $idTest = GUICtrlCreateButton("Test", 10, 370, 85, 25)
	$idAbortTest = GUICtrlCreateButton("Abort", 150, 370, 85, 25)

	; Display the GUI.
	GUISetState(@SW_SHOW, $hGUI)

	ConsoleWrite("- TESTING" & @CRLF)

	Local $sFilePath = _WriteTestHtml()

	; Loop until the user exits.
	While 1
		Switch GUIGetMsg()
			Case $idTest
				_WD_Navigate($WD_SESSION, $sFilePath)
				_WD_WaitElement($WD_SESSION, $_WD_LOCATOR_ByXPath, '//a[contains(text(),"TEST")]', 100, 30 * 1000) ; timeout = 50 seconds
				ConsoleWrite("---> @error=" & @error & "  @extended=" & @extended & _
						" : after _WD_WaitElement()" & @CRLF)

			Case $GUI_EVENT_CLOSE
				ExitLoop

		EndSwitch
	WEnd

	; Delete the previous GUI and all controls.
	GUIDelete($hGUI)

EndFunc   ;==>_Example

Func _My_Sleep($iDelay)
	Local $hTimer = TimerInit() ; Begin the timer and store the handle in a variable.
	Do
		Switch GUIGetMsg()
			Case $GUI_EVENT_CLOSE
				ConsoleWrite("! USER EXIT" & @CRLF)
				Exit
			Case $idAbortTest
				Return SetError($_WD_ERROR_UserAbort)
		EndSwitch
	Until TimerDiff($hTimer) > $iDelay
EndFunc   ;==>_My_Sleep

Func _WriteTestHtml($sFilePath = @ScriptDir & "\TestFile.html")
	FileDelete($sFilePath)
	Local Const $sHtml = _
			"<html lang='en'>" & @CRLF & _
			"    <head>" & @CRLF & _
			"        <meta charset='utf-8'>" & @CRLF & _
			"        <title>TESTING</title>" & @CRLF & _
			"    </head>" & @CRLF & _
			"    <body>" & @CRLF & _
			"        <div id='MyLink'>Waiting</div>" & @CRLF & _
			"    </body>" & @CRLF & _
			"    <script type='text/javascript'>" & @CRLF & _
			"    setTimeout(function()" & @CRLF & _
			"    {" & @CRLF & _
			"        // Delayed code in here" & @CRLF & _
			"        document.getElementById('MyLink').innerHTML='<a>TESTING</a>';" & @CRLF & _
			"    }, 20000); // 20000 = 20 seconds" & @CRLF & _
			"    </script>" & @CRLF & _
			"</html>"
	FileWrite($sFilePath, $sHtml)
	Return "file:///" & StringReplace($sFilePath, "\", "/")
EndFunc   ;==>_WriteTestHtml

Func SetupChrome()
	_WD_Startup()
	_WD_Option('Driver', 'chromedriver.exe')
	_WD_Option('Port', 9515)
	_WD_Option('HTTPTimeouts', True)
	_WD_Option('DefaultTimeout', 40001)
	_WD_Option('DriverParams', '--verbose --log-path="' & @ScriptDir & '\chrome.log"')
	_WD_Option("Sleep", _My_Sleep)

	Local $sCapabilities = '{"capabilities": {"alwaysMatch": {"goog:chromeOptions": {"w3c": true, "excludeSwitches": [ "enable-automation"]}}}}'
	$WD_SESSION = _WD_CreateSession($sCapabilities)
	_WD_Timeouts($WD_SESSION, 40002)
EndFunc   ;==>SetupChrome
10. How to keep my WebDriver environment up-to-date

Q: How can I keep my WebDriver environment up-to-date?

A: You have to check the following components:

WebDriver UDF: Function _WD_IsLatestRelease compares local UDF version to latest release on Github. Returns True if the local UDF version is the latest, otherwise False. If you need to update the UDF you have to download it manually.
WebDriver Exe: Function _WD_UpdateDriver checks or updates the Web Driver with newer version, if available.
Browser: Function _WD_GetBrowserVersion returns the version number of the specified browser. If you need to update the Browser you have to download and install it by hand.

11. How to use "Locator strategy" and "Selectors"?

Q: How to use "Locator strategies" and how to find "Selectors"?
A: This UDF supports all locators defined in the Webdriver specifications. Below is a listing of predefined constants:

Locator strategy Description how to use "Selector"
$_WD_LOCATOR_ByCSSSelector CSS Selector string (see this site). In CSS, pattern matching rules determine which style rules apply to elements in the HTML DOM document tree.
$_WD_LOCATOR_ByXPath XPath string (see this site). XPath is a language for addressing parts of an XML document.
$_WD_LOCATOR_ByLinkText String with exact text of <a> element, which should be used to locate the proper <a> element.
$_WD_LOCATOR_ByPartialLinkText String with partial text of <a> element, which should be used to locate the proper <a> element.
$_WD_LOCATOR_ByTagName String that matches the desired element tag name, for example "button" is tag name of this element: <button name="ClickMe">


Q: How can I check XPath and CSSSelector in the Browser?
A: Work in progress....
A: Take a look on this link: Get Started With Viewing And Changing The DOM
A: Take a look on this link: Locator strategies
A: Take a look on this link: How to search by Xpath/Css in Chrome Developer Tools?


12. How to download PDF (or any other) file automatically?

Q: How to avoid browsers asking what to do with a file after clicking the "Download" button on a website?
A: In FireFox you should add additional capabilites settings:

_WD_CapabilitiesAdd("prefs", "pdfjs.disabled", True)
_WD_CapabilitiesAdd("prefs", "browser.download.folderList", 2)
_WD_CapabilitiesAdd("prefs", "browser.download.dir", $s_Download_dir)
_WD_CapabilitiesAdd("prefs", "browser.helperApps.neverAsk.saveToDisk", "application/pdf,application/octet-stream")
_WD_CapabilitiesAdd("prefs", "browser.helperApps.neverAsk.openFile", "application/pdf,application/octet-stream")
_WD_CapabilitiesAdd("prefs", "browser.download.useDownloadDir", True)
_WD_CapabilitiesAdd("prefs", "browser.download.alwaysOpenPanel", False)

In order to preset autodowloading another file type you have to change it accordingly by providing your desired MIME type:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types

specifically here:

_WD_CapabilitiesAdd("prefs", "browser.helperApps.neverAsk.saveToDisk", "application/pdf,application/octet-stream")
_WD_CapabilitiesAdd("prefs", "browser.helperApps.neverAsk.openFile", "application/pdf,application/octet-stream")
13. How to setup session with proxy?
14. How to add capabilities options for "goog:chromeOptions" or "ms:edgeOptions" or "moz:firefoxOptions"?

Q: How to add options for "goog:chromeOptions" or "ms:edgeOptions" or "moz:firefoxOptions" ?
A: Use _WD_CapabilitiesDefine() function like int the following example:

_WD_CapabilitiesDefine($_WD_CAPS_TYPES__SPECIFICVENDOR_ARRAY, 'NewCapabilityArray')
15. How to change user-agent?

Q: How to change user-agent?
A: Example for chrome:

_WD_CapabilitiesAdd("args", "user-agent", "Mozilla/5.0 (Windows NT 10.0; Win" & StringReplace(@OSArch, "X", "") & "; " & @CPUArch & ") AppleWebKit/537.36 (KHTML, like Gecko) Chrome/" & _WD_GetBrowserVersion("chrome") & " Safari/537.36")

A: Example for firefox:

_WD_CapabilitiesAdd("args", "user-agent", "Mozilla/5.0 (Windows NT 10.0; Win" & StringReplace(@OSArch, "X", "") & "; " & @CPUArch & ") AppleWebKit/537.36 (KHTML, like Gecko) Chrome/" & _WD_GetBrowserVersion("firefox") & " Safari/537.36")
16. How to enable/disable logging into webdriver console?

Q: How to enable/disable logging into webdriver console?
A: Example for chrome:

_WD_CapabilitiesAdd("excludeSwitches", "enable-logging")
_WD_CapabilitiesAdd("excludeSwitches", "disable-logging")
17. How to use devtools in browsers?
18. How to troubleshoot when you can't locate the desired element using _WD_FindElement() ?

When you encounter a problem locating an item with _WD_FindElement() you should follow this procedure:

WIP....

  • check in your browser if your locator (XPATH , CSSSelector) is valid
  • check in your browser if your locator (XPATH , CSSSelector) find one or multiple instances of the element
  • check in your browser if your locator (XPATH , CSSSelector) find element in different frame or if this is within #shadow-root
  • use _WD_FrameList() to check if you have multiple even nested frames in website you are trying to automate
  • use _WD_LocateElement() to check Element location within multiple even nested frames
  • use _WD_FrameEnter() to change frame to be able to use _WD_FindElement() in order to find element within desired frame

Tools

The following tools will help you to automate your browser:

  • ChroPath plugin: Makes finding an element by XPath, ID or CSS incredibly easy (Chrome, Firefox, Opera)
  • SelectorsHub plugin: Next Gen XPath tool to generate, write and verify the XPath and cssSelectors (All browsers)
  • Save Page WE plugin: helps to save web page content as single MHTML file (Save Page WE for Firefox, Save Page WE for Chrome)
  • Stylus Stylus is a fork of Stylish for Chrome, also compatible with Firefox as a WebExtension

References

(Last modified: 2022/02/12)

Further information sources: