From 8c1017fcac7a60a3d0ce6b1a2efd0d9c83e161db Mon Sep 17 00:00:00 2001 From: kobenguyent Date: Tue, 11 Feb 2025 14:56:45 +0100 Subject: [PATCH 1/3] fix: bidi error with webdriver --- lib/helper/WebDriver.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/helper/WebDriver.js b/lib/helper/WebDriver.js index 1afebb642..096a82ca5 100644 --- a/lib/helper/WebDriver.js +++ b/lib/helper/WebDriver.js @@ -488,6 +488,9 @@ class WebDriver extends Helper { config.capabilities = config.desiredCapabilities } config.capabilities.browserName = config.browser || config.capabilities.browserName + + config.capabilities.webSocketUrl = config.webSocketUrl || config.capabilities.webSocketUrl || true + config.capabilities.browserVersion = config.browserVersion || config.capabilities.browserVersion if (config.capabilities.chromeOptions) { config.capabilities['goog:chromeOptions'] = config.capabilities.chromeOptions From c590e3a689c9325fac11df5042dc13007f176d9a Mon Sep 17 00:00:00 2001 From: kobenguyent Date: Wed, 12 Feb 2025 06:26:38 +0100 Subject: [PATCH 2/3] fix: bidi error wdio --- lib/helper/WebDriver.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/helper/WebDriver.js b/lib/helper/WebDriver.js index 096a82ca5..5c23dbc27 100644 --- a/lib/helper/WebDriver.js +++ b/lib/helper/WebDriver.js @@ -35,6 +35,7 @@ let browserLogs = [] * @type {object} * @prop {string} url - base url of website to be tested. * @prop {string} browser - Browser in which to perform testing. + * @prop {boolean} [bidiProtocol=false] - WebDriver Bidi Protocol. Default: false. More info: https://webdriver.io/docs/api/webdriverBidi/ * @prop {string} [basicAuth] - (optional) the basic authentication to pass to base url. Example: {username: 'username', password: 'password'} * @prop {string} [host=localhost] - WebDriver host to connect. * @prop {number} [port=4444] - WebDriver port to connect. @@ -489,7 +490,8 @@ class WebDriver extends Helper { } config.capabilities.browserName = config.browser || config.capabilities.browserName - config.capabilities.webSocketUrl = config.webSocketUrl || config.capabilities.webSocketUrl || true + // WebDriver Bidi Protocol. Default: false + config.capabilities.webSocketUrl = config.bidiProtocol ?? config.capabilities.webSocketUrl ?? true config.capabilities.browserVersion = config.browserVersion || config.capabilities.browserVersion if (config.capabilities.chromeOptions) { From 73bc856d00c4b375123bfd76c8595b71a0baa2d1 Mon Sep 17 00:00:00 2001 From: kobenguyent Date: Wed, 12 Feb 2025 06:28:51 +0100 Subject: [PATCH 3/3] fix: bidi error wdio --- docs/helpers/WebDriver.md | 973 ++++++++++++++++++-------------------- 1 file changed, 454 insertions(+), 519 deletions(-) diff --git a/docs/helpers/WebDriver.md b/docs/helpers/WebDriver.md index 596d5b6d0..3dc5d60f3 100644 --- a/docs/helpers/WebDriver.md +++ b/docs/helpers/WebDriver.md @@ -23,8 +23,6 @@ One of the significant advantages of this update is that you can now get rid of For those who require custom driver options, fear not; WebDriver Helper allows you to pass in driver options through custom WebDriver configuration. If you have a custom grid, use a cloud service, or prefer to run your own driver, there's no need to worry since WebDriver Helper will only start a driver when there are no other connection information settings like hostname or port specified. - - ## Configuration This helper should be configured in codecept.conf.js @@ -33,29 +31,28 @@ Type: [object][17] ### Properties -* `url` **[string][18]** base url of website to be tested. -* `browser` **[string][18]** Browser in which to perform testing. -* `basicAuth` **[string][18]?** (optional) the basic authentication to pass to base url. Example: {username: 'username', password: 'password'} -* `host` **[string][18]?** WebDriver host to connect. -* `port` **[number][23]?** WebDriver port to connect. -* `protocol` **[string][18]?** protocol for WebDriver server. -* `path` **[string][18]?** path to WebDriver server. -* `restart` **[boolean][33]?** restart browser between tests. -* `smartWait` **([boolean][33] | [number][23])?** **enables [SmartWait][37]**; wait for additional milliseconds for element to appear. Enable for 5 secs: "smartWait": 5000. -* `disableScreenshots` **[boolean][33]?** don't save screenshots on failure. -* `fullPageScreenshots` **[boolean][33]?** (optional - make full page screenshots on failure. -* `uniqueScreenshotNames` **[boolean][33]?** option to prevent screenshot override if you have scenarios with the same name in different suites. -* `keepBrowserState` **[boolean][33]?** keep browser state between tests when `restart` is set to false. -* `keepCookies` **[boolean][33]?** keep cookies between tests when `restart` set to false. -* `windowSize` **[string][18]?** default window size. Set to `maximize` or a dimension in the format `640x480`. -* `waitForTimeout` **[number][23]?** sets default wait time in *ms* for all `wait*` functions. -* `desiredCapabilities` **[object][17]?** Selenium's [desired capabilities][7]. -* `manualStart` **[boolean][33]?** do not start browser before a test, start it manually inside a helper with `this.helpers["WebDriver"]._startBrowser()`. -* `timeouts` **[object][17]?** [WebDriver timeouts][38] defined as hash. -* `highlightElement` **[boolean][33]?** highlight the interacting elements. Default: false. Note: only activate under verbose mode (--verbose). -* `logLevel` **[string][18]?** level of logging verbosity. Default: silent. Options: trace | debug | info | warn | error | silent. More info: [https://webdriver.io/docs/configuration/#loglevel][39] - - +- `url` **[string][18]** base url of website to be tested. +- `browser` **[string][18]** Browser in which to perform testing. +- `bidiProtocol` **[boolean][33]?** WebDriver Bidi Protocol. Default: false. More info: [https://webdriver.io/docs/api/webdriverBidi/][37] +- `basicAuth` **[string][18]?** (optional) the basic authentication to pass to base url. Example: {username: 'username', password: 'password'} +- `host` **[string][18]?** WebDriver host to connect. +- `port` **[number][23]?** WebDriver port to connect. +- `protocol` **[string][18]?** protocol for WebDriver server. +- `path` **[string][18]?** path to WebDriver server. +- `restart` **[boolean][33]?** restart browser between tests. +- `smartWait` **([boolean][33] | [number][23])?** **enables [SmartWait][38]**; wait for additional milliseconds for element to appear. Enable for 5 secs: "smartWait": 5000. +- `disableScreenshots` **[boolean][33]?** don't save screenshots on failure. +- `fullPageScreenshots` **[boolean][33]?** (optional - make full page screenshots on failure. +- `uniqueScreenshotNames` **[boolean][33]?** option to prevent screenshot override if you have scenarios with the same name in different suites. +- `keepBrowserState` **[boolean][33]?** keep browser state between tests when `restart` is set to false. +- `keepCookies` **[boolean][33]?** keep cookies between tests when `restart` set to false. +- `windowSize` **[string][18]?** default window size. Set to `maximize` or a dimension in the format `640x480`. +- `waitForTimeout` **[number][23]?** sets default wait time in _ms_ for all `wait*` functions. +- `desiredCapabilities` **[object][17]?** Selenium's [desired capabilities][7]. +- `manualStart` **[boolean][33]?** do not start browser before a test, start it manually inside a helper with `this.helpers["WebDriver"]._startBrowser()`. +- `timeouts` **[object][17]?** [WebDriver timeouts][39] defined as hash. +- `highlightElement` **[boolean][33]?** highlight the interacting elements. Default: false. Note: only activate under verbose mode (--verbose). +- `logLevel` **[string][18]?** level of logging verbosity. Default: silent. Options: trace | debug | info | warn | error | silent. More info: [https://webdriver.io/docs/configuration/#loglevel][40] Example: @@ -396,7 +393,7 @@ Here is the [webdriverio docs][16] on the subject Receive a WebDriver client from a custom helper by accessing `browser` property: ```js -const { WebDriver } = this.helpers; +const { WebDriver } = this.helpers const browser = WebDriver.browser ``` @@ -404,31 +401,31 @@ const browser = WebDriver.browser ### Parameters -* `config` +- `config` -### _isShadowLocator +### \_isShadowLocator Check if locator is type of "Shadow" #### Parameters -* `locator` **[object][17]** +- `locator` **[object][17]** -### _locate +### \_locate Get elements by different locator types, including strict locator. Should be used in custom helpers: ```js -this.helpers['WebDriver']._locate({name: 'password'}).then //... +this.helpers['WebDriver']._locate({ name: 'password' }).then //... ``` #### Parameters -* `locator` **([string][18] | [object][17])** element located by CSS|XPath|strict locator. -* `smartWait` +- `locator` **([string][18] | [object][17])** element located by CSS|XPath|strict locator. +- `smartWait` -### _locateCheckable +### \_locateCheckable Find a checkbox by providing human-readable text: @@ -438,23 +435,23 @@ this.helpers['WebDriver']._locateCheckable('I agree with terms and conditions'). #### Parameters -* `locator` **([string][18] | [object][17])** element located by CSS|XPath|strict locator. +- `locator` **([string][18] | [object][17])** element located by CSS|XPath|strict locator. -### _locateClickable +### \_locateClickable Find a clickable element by providing human-readable text: ```js -const els = await this.helpers.WebDriver._locateClickable('Next page'); -const els = await this.helpers.WebDriver._locateClickable('Next page', '.pages'); +const els = await this.helpers.WebDriver._locateClickable('Next page') +const els = await this.helpers.WebDriver._locateClickable('Next page', '.pages') ``` #### Parameters -* `locator` **([string][18] | [object][17])** element located by CSS|XPath|strict locator. -* `context` +- `locator` **([string][18] | [object][17])** element located by CSS|XPath|strict locator. +- `context` -### _locateFields +### \_locateFields Find field elements by providing human-readable text: @@ -464,23 +461,23 @@ this.helpers['WebDriver']._locateFields('Your email').then // ... #### Parameters -* `locator` **([string][18] | [object][17])** element located by CSS|XPath|strict locator. +- `locator` **([string][18] | [object][17])** element located by CSS|XPath|strict locator. -### _locateShadow +### \_locateShadow Locate Element within the Shadow Dom #### Parameters -* `locator` **[object][17]** +- `locator` **[object][17]** -### _smartWait +### \_smartWait Smart Wait to locate an element #### Parameters -* `locator` **[object][17]** +- `locator` **[object][17]** ### acceptPopup @@ -494,14 +491,14 @@ Opens a web page in a browser. Requires relative or absolute url. If url starts with `/`, opens a web page of a site defined in `url` config parameter. ```js -I.amOnPage('/'); // opens main page of website -I.amOnPage('https://github.com'); // opens github -I.amOnPage('/login'); // opens a login page +I.amOnPage('/') // opens main page of website +I.amOnPage('https://github.com') // opens github +I.amOnPage('/login') // opens a login page ``` #### Parameters -* `url` **[string][18]** url path or global url. +- `url` **[string][18]** url path or global url. Returns **void** automatically synchronized promise through #recorder @@ -511,22 +508,20 @@ Appends text to a input field or textarea. Field is located by name, label, CSS or XPath ```js -I.appendField('#myTextField', 'appended'); +I.appendField('#myTextField', 'appended') // typing secret -I.appendField('password', secret('123456')); +I.appendField('password', secret('123456')) ``` #### Parameters -* `field` **([string][18] | [object][17])** located by label|name|CSS|XPath|strict locator -* `value` **[string][18]** text value to append. +- `field` **([string][18] | [object][17])** located by label|name|CSS|XPath|strict locator +- `value` **[string][18]** text value to append. Returns **void** automatically synchronized promise through #recorder - This action supports [React locators](https://codecept.io/react#locators) - ### attachFile Appium: not tested @@ -536,14 +531,14 @@ Path to file is relative current codecept directory (where codecept.conf.ts or c File will be uploaded to remote system (if tests are running remotely). ```js -I.attachFile('Avatar', 'data/avatar.jpg'); -I.attachFile('form input[name=avatar]', 'data/avatar.jpg'); +I.attachFile('Avatar', 'data/avatar.jpg') +I.attachFile('form input[name=avatar]', 'data/avatar.jpg') ``` #### Parameters -* `locator` **([string][18] | [object][17])** field located by label|name|CSS|XPath|strict locator. -* `pathToFile` **[string][18]** local file path relative to codecept.conf.ts or codecept.conf.js config file. +- `locator` **([string][18] | [object][17])** field located by label|name|CSS|XPath|strict locator. +- `pathToFile` **[string][18]** local file path relative to codecept.conf.ts or codecept.conf.js config file. Returns **void** automatically synchronized promise through #recorder @@ -560,15 +555,15 @@ I.blur('.text-area') ```js //element `#product-tile` is focused -I.see('#add-to-cart-btn'); +I.see('#add-to-cart-btn') I.blur('#product-tile') -I.dontSee('#add-to-cart-btn'); +I.dontSee('#add-to-cart-btn') ``` #### Parameters -* `locator` **([string][18] | [object][17])** field located by label|name|CSS|XPath|strict locator. -* `options` **any?** Playwright only: [Additional options][21] for available options object as 2nd argument. +- `locator` **([string][18] | [object][17])** field located by label|name|CSS|XPath|strict locator. +- `options` **any?** Playwright only: [Additional options][21] for available options object as 2nd argument. Returns **void** automatically synchronized promise through #recorder @@ -585,15 +580,15 @@ Element is located by label or name or CSS or XPath. The second parameter is a context (CSS or XPath locator) to narrow the search. ```js -I.checkOption('#agree'); -I.checkOption('I Agree to Terms and Conditions'); -I.checkOption('agree', '//form'); +I.checkOption('#agree') +I.checkOption('I Agree to Terms and Conditions') +I.checkOption('agree', '//form') ``` #### Parameters -* `field` **([string][18] | [object][17])** checkbox located by label | name | CSS | XPath | strict locator. -* `context` **([string][18]? | [object][17])** (optional, `null` by default) element located by CSS | XPath | strict locator. +- `field` **([string][18] | [object][17])** checkbox located by label | name | CSS | XPath | strict locator. +- `context` **([string][18]? | [object][17])** (optional, `null` by default) element located by CSS | XPath | strict locator. Returns **void** automatically synchronized promise through #recorder @@ -603,28 +598,28 @@ Clears a cookie by name, if none provided clears all cookies. ```js -I.clearCookie(); -I.clearCookie('test'); +I.clearCookie() +I.clearCookie('test') ``` #### Parameters -* `cookie` **[string][18]?** (optional, `null` by default) cookie name +- `cookie` **[string][18]?** (optional, `null` by default) cookie name ### clearField Clears a `