diff --git a/javascript/node/selenium-webdriver/.eslintrc.js b/javascript/node/selenium-webdriver/.eslintrc.js index 934fac69ac0ef..e64343f401e4e 100644 --- a/javascript/node/selenium-webdriver/.eslintrc.js +++ b/javascript/node/selenium-webdriver/.eslintrc.js @@ -4,18 +4,11 @@ module.exports = { node: true, es6: true, }, - extends: [ - 'eslint:recommended', - 'plugin:node/recommended', - 'plugin:prettier/recommended', - ], + extends: ['eslint:recommended', 'plugin:node/recommended', 'plugin:prettier/recommended'], parserOptions: { ecmaVersion: 2022, }, - ignorePatterns: [ - '.eslintrc.js', - '.prettierrc', - ], + ignorePatterns: ['.eslintrc.js', '.prettierrc'], plugins: ['no-only-tests'], rules: { 'no-const-assign': 'error', diff --git a/javascript/node/selenium-webdriver/CHANGES.md b/javascript/node/selenium-webdriver/CHANGES.md index 7480a3dfed789..dec17546a27f3 100644 --- a/javascript/node/selenium-webdriver/CHANGES.md +++ b/javascript/node/selenium-webdriver/CHANGES.md @@ -56,7 +56,8 @@ #### :rocket: New Feature * Add BiDi captureScreenshot command (#12510) -* Add BiDi browsing context activate command, handle user prompt command and reload command +* Add BiDi browsing context activate command, handle user prompt command and + reload command * Add BiDi browsing context commands and events (#13078) ## 4.14.0 @@ -118,7 +119,8 @@ #### :bug: Bug Fix -* fix SeleniumServer.start() crashes on MacOS with nodejs selenium-webdriver (#12158) +* fix SeleniumServer.start() crashes on MacOS with nodejs selenium-webdriver ( + #12158) * Update by.js: Add forgotten RelativeBy in check options (#12289) ## v4.10.0 @@ -264,15 +266,15 @@ fix: iedriver download with selenium-manager #11579 #### :rocket: New Feature * Adds 'Select' support package - * selectByIndex - * selectByValue - * selectByVisibleText - * getAllSelectedOptions - * getFirstSelectedOption - * deselectAll - * deselectByVisibleText - * deselectByIndex - * deselectByValue + * selectByIndex + * selectByValue + * selectByVisibleText + * getAllSelectedOptions + * getFirstSelectedOption + * deselectAll + * deselectByVisibleText + * deselectByIndex + * deselectByValue * Add support for Actions API sendKeys to designated element * Adds mouse button enum for forward and backward navigation @@ -282,7 +284,8 @@ fix: iedriver download with selenium-manager #11579 * fix: geckodriver session with node 18.x.x (issue 2 in #10970) * fix: JS firefox driver crashes on setting a profile (fixed with [commit](https://github.com/SeleniumHQ/selenium/commit/fa6deeea6bda1e73317157845772e114bd569b7d)) -* fix: "SetExperimental" option is not available in webdriverjs (Javascript/Typescript) (#10959) +* fix: "SetExperimental" option is not available in webdriverjs ( + Javascript/Typescript) (#10959) * fix: Do not allow Select class to select disabled options (#10812) #### :nail_care: Polish @@ -343,7 +346,8 @@ fix: iedriver download with selenium-manager #11579 ## v4.1.1 -* Add support for installing unpacked addons at runtime in Firefox webdriver (#10216) +* Add support for installing unpacked addons at runtime in Firefox webdriver ( + #10216) * Enables firefox debugger for devtools test * Sets correct browserName when set via SELENIUM_BROWSER fixes #10218 * add support for Chrome v97 @@ -351,7 +355,8 @@ fix: iedriver download with selenium-manager #11579 * ignore errors arising from trying to use file detector fixes #6343 * Added RelativeBy class on the main api (#10148) * Code cleanup and minor improvements -* Implements 'getDomAttribute' to get attribute value as defined by w3c spec and removes legacy +* Implements 'getDomAttribute' to get attribute value as defined by w3c spec and + removes legacy command usages * Remove legacy JWP support and w3c switch (#10095) * update map/filter clean up to common format (#10094) @@ -361,7 +366,8 @@ fix: iedriver download with selenium-manager #11579 * add support for handling Shadow DOM elements * Capture browser console logs when using BiDi onLogEvent api * add CDP support for v96 and remove v93 -* remove useless package, change io public api import to more common approach (#10037) +* remove useless package, change io public api import to more common approach ( + #10037) * Fix flaky CDP dom mutation (#10029) * Fix edge test failures (#10012) * code cleanup second iteration (#9979) @@ -393,16 +399,20 @@ fix: iedriver download with selenium-manager #11579 * Deprecates withCapabilities method and removes tests (#9701) * expose `withLocator` method at the top level -* Enables Mobile feature for Firefox (Still need to expand this to chromium based browsers) +* Enables Mobile feature for Firefox (Still need to expand this to chromium + based browsers) * Add the ability to do Relative Locators with all By types. Fixes #9559 * Add default Opera capabilities. Fixes #9654 -* Add support for ChromeDriver `--enable-chrome-logs` (#9575) [Author: Mark Stacey] +* Add support for ChromeDriver `--enable-chrome-logs` ( + #9575) [Author: Mark Stacey] - The `--enable-chrome-logs` ChromeDriver option can now be enabled using the Chromium (or Chrome) + The `--enable-chrome-logs` ChromeDriver option can now be enabled using the + Chromium (or Chrome) ServiceBuilder, similarly to the other options provided by ChromeDriver. -* Add the debuggerAddress option to chromium.js (#9561) [Author: Brandon Walderman] +* Add the debuggerAddress option to chromium.js ( + #9561) [Author: Brandon Walderman] * Adds http client options [#9638](Author: Dharin Shah) * Updating edge.js to extend chromium.driver (fixes #9626) @@ -413,7 +423,8 @@ fix: iedriver download with selenium-manager #11579 ## v4.0.0-beta.3 -* Removed support for legacy actions. This will also remove "Bride Mode" support, which was +* Removed support for legacy actions. This will also remove "Bride Mode" + support, which was introduced to translate of action class to legacy API. * Remove devtools support for v86,v87 and adding support for v89, v90, v91 * make isPromise() return boolean value for null and undefined cases (#6785) @@ -435,7 +446,7 @@ fix: iedriver download with selenium-manager #11579 ## v4.0.0-beta.1 * JS Binding support for WebDriver Bidi in Firefox - * This requires Firefox 87 and Geckodriver 0.29 to be able to work + * This requires Firefox 87 and Geckodriver 0.29 to be able to work * Update the supported CDP versions * Update tmp package version (#9155) * Adding support for /computedlabel (getAccessibleName) (#9073) @@ -449,12 +460,12 @@ fix: iedriver download with selenium-manager #11579 * Rolling back native support for Opera Browser * Added new ieOptions capabilities: - * fileUploadDialogTimeout - * setEdgePath - * setEdgeChromium - * setScrollBehavior - * For consistent naming, deprecating `addArguments(...args)` in favor - of `addBrowserCommandSwitches(...args)` + * fileUploadDialogTimeout + * setEdgePath + * setEdgeChromium + * setScrollBehavior + * For consistent naming, deprecating `addArguments(...args)` in favor + of `addBrowserCommandSwitches(...args)` * Added relative locators * Added Chrome DevTools Protocol (CDP) support @@ -510,190 +521,214 @@ mode (see `example/headless.js`) ### Changes for W3C WebDriver Spec Compliance * Revamped the actions API to conform with the WebDriver Spec: - . For details, refer to the JS doc on + . For details, refer to the JS doc + on the `lib/input.Actions` class. - As of January, 2018, only Firefox natively supports this new API. You can put the `Actions` class - into "bridge mode" and it will attempt to translate mouse and keyboard actions to the legacy API ( - see class docs). Alternatively, you may continue to use the legacy API directly via + As of January, 2018, only Firefox natively supports this new API. You can put + the `Actions` class + into "bridge mode" and it will attempt to translate mouse and keyboard actions + to the legacy API ( + see class docs). Alternatively, you may continue to use the legacy API + directly via the `lib/actions` module. - __NOTE:__ The legacy API is considered strongly deprecated and will be removed in a minor release + __NOTE:__ The legacy API is considered strongly deprecated and will be removed + in a minor release once Google's Chrome and Microsoft's Edge browsers support the new API. * All window manipulation commands are now supported. * Added `driver.switchTo().parentFrame()` * When a named cookie is requested, attempt to fetch it directly using the W3C - endpoint, `GET /session/{session id}/cookie/{name}`. If this command is not recognized by the - remote end, fallback to fetching all cookies and then searching for the desired name. + endpoint, `GET /session/{session id}/cookie/{name}`. If this command is not + recognized by the + remote end, fallback to fetching all cookies and then searching for the + desired name. * Replaced `WebElement.getSize()` and `WebElement.getLocation()` with a single method, `WebElement.getRect()`. ### API Changes * The core WebDriver API no longer uses promise manager - * Removed `index.Builder#setControlFlow()` - * The following thenable types no longer have a `cancel()` method: - * The dynamically generated thenable WebDrivers created by `index.Builder` - * `lib/webdriver.AlertPromise` - * `lib/webdriver.WebElementPromise` + * Removed `index.Builder#setControlFlow()` + * The following thenable types no longer have a `cancel()` method: + * The dynamically generated thenable WebDrivers created by `index.Builder` + * `lib/webdriver.AlertPromise` + * `lib/webdriver.WebElementPromise` * Removed `remote/index.DriverService.prototype.stop()` (use `#kill()` instead) * Removed the `lib/actions` module * Removed the `lib/events` module * Removed the `phantomjs` module * Removed the 'opera' module -* Removed the promise manager from `lib/promise`, which includes the removal of the following +* Removed the promise manager from `lib/promise`, which includes the removal of + the following exported names (replacements, if any, in parentheses): - * CancellableThenable - * CancellationError - * ControlFlow - * Deferred - * LONG_STACK_TRACES - * MultipleUnhandledRejectionError - * Promise (use native Promises) - * Resolver - * Scheduler - * Thenable - * USE_PROMISE_MANAGER - * all (use Promise.all) - * asap (use Promise.resolve) - * captureStackTrace (use Error.captureStackTrace) - * consume (use async functions) - * controlFlow - * createPromise (use new Promise) - * defer - * fulfilled (use Promise.resolve) - * isGenerator - * rejected (use Promise.reject) - * setDefaultFlow - * when (use Promise.resolve) + * CancellableThenable + * CancellationError + * ControlFlow + * Deferred + * LONG_STACK_TRACES + * MultipleUnhandledRejectionError + * Promise (use native Promises) + * Resolver + * Scheduler + * Thenable + * USE_PROMISE_MANAGER + * all (use Promise.all) + * asap (use Promise.resolve) + * captureStackTrace (use Error.captureStackTrace) + * consume (use async functions) + * controlFlow + * createPromise (use new Promise) + * defer + * fulfilled (use Promise.resolve) + * isGenerator + * rejected (use Promise.reject) + * setDefaultFlow + * when (use Promise.resolve) * Changes to the `Builder` class: - * Added setChromeService, setEdgeService, & setFirefoxService - * Removed setEnableNativeEvents - * Removed setScrollBehavior + * Added setChromeService, setEdgeService, & setFirefoxService + * Removed setEnableNativeEvents + * Removed setScrollBehavior * Changes to `chrome.Driver` - * Added sendDevToolsCommand - * Added setDownloadPath + * Added sendDevToolsCommand + * Added setDownloadPath * Changes to `chrome.Options` - * Now extends the `Capabilities` class - * Removed from/toCapabilities + * Now extends the `Capabilities` class + * Removed from/toCapabilities * Changes to `edge.Options` - * Now extends the `Capabilities` class - * Removed from/toCapabilities + * Now extends the `Capabilities` class + * Removed from/toCapabilities * Changes to `ie.Options` - * Now extends the `Capabilities` class - * Removed from/toCapabilities + * Now extends the `Capabilities` class + * Removed from/toCapabilities * Removed the `firefox.Binary` class. Custom binaries can still be selected - using `firefox.Options#setBinary()`. Likewise, custom binary arguments can be specified + using `firefox.Options#setBinary()`. Likewise, custom binary arguments can be + specified with `firefox.Options#addArguments()`. * Changes to `firefox.Driver` - * Added installAddon(path) - * Added uninstallAddon(id) + * Added installAddon(path) + * Added uninstallAddon(id) * Changes to `firefox.Options` - * Now extends the `Capabilities` class - * Removed from/toCapabilities - * Removed setLoggingPreferences (was a no-op) - * setProfile now only accepts a path to an existing profile - * Added addExtensions - * Added setPreference -* Removed the `firefox.Profile` class. All of its functionality is now provided directly + * Now extends the `Capabilities` class + * Removed from/toCapabilities + * Removed setLoggingPreferences (was a no-op) + * setProfile now only accepts a path to an existing profile + * Added addExtensions + * Added setPreference +* Removed the `firefox.Profile` class. All of its functionality is now provided + directly by `firefox.Options` * Removed the `firefox/binary` module * Removed the `firefox/profile` module * Changes to `safari.Options` - * Now extends the `Capabilities` class - * Removed from/toCapabilities - * Removed setCleanSession (was a no-op) + * Now extends the `Capabilities` class + * Removed from/toCapabilities + * Removed setCleanSession (was a no-op) * Changes to `lib/capabilities.Browser`: - * Removed several enum values. - * ANDROID (use Chrome for Android; see docs on the chrome module) - * IPAD (no support available) - * IPHONE (no support available) - * OPERA (use Chrome) - * PHANTOM_JS (use Chrome or Firefox in headless mode) - * HTMLUNIT (use Chrome or Firefox in headless mode) + * Removed several enum values. + * ANDROID (use Chrome for Android; see docs on the chrome module) + * IPAD (no support available) + * IPHONE (no support available) + * OPERA (use Chrome) + * PHANTOM_JS (use Chrome or Firefox in headless mode) + * HTMLUNIT (use Chrome or Firefox in headless mode) * Changes to `lib/capabilities.Capabilities`: - * Removed static factory methods android(), ipad(), iphone(), opera(), phantomjs(), htmlunit(), - and htmlunitwithjs(). Users can still manually configure capabilities for these, but their use - is not recommended and they will no longer be surfaced in the API. + * Removed static factory methods android(), ipad(), iphone(), opera(), + phantomjs(), htmlunit(), + and htmlunitwithjs(). Users can still manually configure capabilities for + these, but their use + is not recommended and they will no longer be surfaced in the API. * Changes to `lib/error`: - * Added - * ElementClickInterceptedError - * InsecureCertificateError - * InvalidCoordinatesError - * NoSuchCookieError - * Removed - * ElementNotVisibleError - * InvalidElementCoordinatesError + * Added + * ElementClickInterceptedError + * InsecureCertificateError + * InvalidCoordinatesError + * NoSuchCookieError + * Removed + * ElementNotVisibleError + * InvalidElementCoordinatesError * Changes to `lib/webdriver.WebDriver`: - * Dropped support for "requiredCapabilities" from WebDriver.createSession - * actions() now returns the new `lib/input.Actions` class - * Removed touchActions - * Renamed schedule to execute - * Removed the `WebDriver.attachToSession()` factory method. Users can just the `WebDriver` - constructor directly instead. - * Removed the `call()` method. This was used to inject custom function calls into the control - flow. Now that the promise manager is no longer used, this method is no longer necessary. - Users are now responsible for coordinating actions (ideally with async functions) and can just - call functions directly instead of through `driver.call()`. + * Dropped support for "requiredCapabilities" from WebDriver.createSession + * actions() now returns the new `lib/input.Actions` class + * Removed touchActions + * Renamed schedule to execute + * Removed the `WebDriver.attachToSession()` factory method. Users can just + the `WebDriver` + constructor directly instead. + * Removed the `call()` method. This was used to inject custom function calls + into the control + flow. Now that the promise manager is no longer used, this method is no + longer necessary. + Users are now responsible for coordinating actions (ideally with async + functions) and can just + call functions directly instead of through `driver.call()`. * Changes to `lib/webdriver.WebElement`: - * Replaced getSize & getLocation with getRect + * Replaced getSize & getLocation with getRect * Changes to `lib/webdriver.Alert`: - * Removed authenticateAs + * Removed authenticateAs * Changes to `lib/webdriver.Options` (`driver.manage()`): - * Removed timeouts (use get/setTimeouts) + * Removed timeouts (use get/setTimeouts) * Changes to `lib/webdriver.Window` (`driver.manage().window()`): - * Added - * getRect - * setRect - * fullscreen - * minimize - * Removed (use the getRect/setRect methods) - * getPosition - * setPosition - * getSize - * setSize + * Added + * getRect + * setRect + * fullscreen + * minimize + * Removed (use the getRect/setRect methods) + * getPosition + * setPosition + * getSize + * setSize * Removed the `testing/assert` module * Changes to `testing/index` - * Since the promise manager has been removed, it is no longer necessary to wrap the Mocha test - hooks; instead, users can simply use async functions. The following have all been removed: - * describe - * before - * beforeEach - * after - * afterEach - * it - * Added the `suite` function. For details, refer to the jsdoc or - `example/google_search_test.js` + * Since the promise manager has been removed, it is no longer necessary to + wrap the Mocha test + hooks; instead, users can simply use async functions. The following have all + been removed: + * describe + * before + * beforeEach + * after + * afterEach + * it + * Added the `suite` function. For details, refer to the jsdoc or + `example/google_search_test.js` ## v3.6.0 ### Bug Fixes * The Capabilities factory methods should only specify the name of the browser. -* Protect against the remote end sometimes not returning a list to findElements commands. +* Protect against the remote end sometimes not returning a list to findElements + commands. * Properly reset state in `remote.DriverService#kill()` -* The firefox module will no longer apply the preferences required by the legacy FirefoxDriver. - These preferences were only required when using the legacy driver, support for which was dropped +* The firefox module will no longer apply the preferences required by the legacy + FirefoxDriver. + These preferences were only required when using the legacy driver, support for + which was dropped in v3.5.0. ### API Changes * Added new methods to `selenium-webdriver/firefox.Options`: - * addArguments() - * headless() - * windowSize() + * addArguments() + * headless() + * windowSize() * Deprecated `selenium-webdriver/firefox/binary.Binary` * Removed `selenium-webdriver/firefox.Options#useGeckoDriver()` * Removed the unused `selenium-webdriver/firefox/profile.decode()` -* Removed methods from `selenium-webdriver/firefox/profile.Profile` that had no effect since support +* Removed methods from `selenium-webdriver/firefox/profile.Profile` that had no + effect since support for the legacy FirefoxDriver was dropped in 3.5.0: - * setNativeEventsEnabled - * nativeEventsEnabled - * getPort - * setPort -* Removed `selenium-webdriver/firefox.ServiceBuilder#setFirefoxBinary()`; custom binaries should be + * setNativeEventsEnabled + * nativeEventsEnabled + * getPort + * setPort +* Removed `selenium-webdriver/firefox.ServiceBuilder#setFirefoxBinary()`; custom + binaries should be configured through the `firefox.Options` class. -* Removed `selenium-webdriver/firefox.Capability`. These hold overs from the legacy FirefoxDriver +* Removed `selenium-webdriver/firefox.Capability`. These hold overs from the + legacy FirefoxDriver are no longer supported. ### Changes for W3C WebDriver Spec Compliance @@ -712,39 +747,52 @@ to a remote Selenium server that supports Firefox 45. ### Changes * Removed native support for Firefox 46 and older. - * The `SELENIUM_MARIONETTE` enviornment variable no longer has an effect. - * `selenium-webdriver/firefox.Capability.MARIONETTE` is deprecated. - * `selenium-webdriver/firefox.Options#useGeckoDriver()` is deprecated and now a no-op. -* `firefox.Options` will no longer discard the `"moz:firefoxOptions"` set in user provided - capabilities (via `Builder.withCapabilities({})`). When both are used, the settings + * The `SELENIUM_MARIONETTE` enviornment variable no longer has an effect. + * `selenium-webdriver/firefox.Capability.MARIONETTE` is deprecated. + * `selenium-webdriver/firefox.Options#useGeckoDriver()` is deprecated and now + a no-op. +* `firefox.Options` will no longer discard the `"moz:firefoxOptions"` set in + user provided + capabilities (via `Builder.withCapabilities({})`). When both are used, the + settings in `firefox.Options` will be applied _last_. -* Added `chrome.Options#headless()` and `chrome.Options#windowSize()`, which may be used to start - Chrome in headless mode (requires Chrome 59+) and to set the initial window size, respectively. +* Added `chrome.Options#headless()` and `chrome.Options#windowSize()`, which may + be used to start + Chrome in headless mode (requires Chrome 59+) and to set the initial window + size, respectively. ### Changes for W3C WebDriver Spec Compliance -* Added `error.WebDriverError#remoteStacktrace` to capture the stacktrace reported by a remote +* Added `error.WebDriverError#remoteStacktrace` to capture the stacktrace + reported by a remote WebDriver endpoint (if any). -* Fixed `WebElement#sendKeys` to send text as a string instead of an array of strings. +* Fixed `WebElement#sendKeys` to send text as a string instead of an array of + strings. ## v3.4.0 ### Notice This release -requires [geckodriver 0.15.0](https://github.com/mozilla/geckodriver/releases/tag/v0.15.0) or newer. +requires [geckodriver 0.15.0](https://github.com/mozilla/geckodriver/releases/tag/v0.15.0) +or newer. ### API Changes -* Added `Options#getTimeouts()` for retrieving the currently configured session timeouts (i.e. - implicit wait). This method will only work with W3C compatible WebDriver implementations. -* Deprecated the `Timeouts` class in favor of `Options#setTimeouts()`, which supports setting +* Added `Options#getTimeouts()` for retrieving the currently configured session + timeouts (i.e. + implicit wait). This method will only work with W3C compatible WebDriver + implementations. +* Deprecated the `Timeouts` class in favor of `Options#setTimeouts()`, which + supports setting multiple timeouts at once. -* Added support for emulating different network conditions (e.g., offline, 2G, WiFi) on Chrome. +* Added support for emulating different network conditions (e.g., offline, 2G, + WiFi) on Chrome. ### Changes for W3C WebDriver Spec Compliance -* Fixed W3C response parsing, which expects response data to always be a JSON object with a `value` +* Fixed W3C response parsing, which expects response data to always be a JSON + object with a `value` key. * Added W3C endpoints for interacting with various types of [user prompts](https://w3c.github.io/webdriver/webdriver-spec.html#user-prompts). @@ -753,7 +801,8 @@ requires [geckodriver 0.15.0](https://github.com/mozilla/geckodriver/releases/ta ## v3.3.0 -* Added warning log messages when the user creates new managed promises, or schedules unchained +* Added warning log messages when the user creates new managed promises, or + schedules unchained tasks. Users may opt in to printing these log messages with ```js @@ -774,89 +823,111 @@ requires [geckodriver 0.15.0](https://github.com/mozilla/geckodriver/releases/ta * Deprecated `promise.when(value, callback, errback)`. Use `promise.fulfilled(value).then(callback, errback)` * Changed `promise.fulfilled(value)`, `promise.rejected(reason)` and - `promise.defer()` to all use native promises when the promise manager is disabled. + `promise.defer()` to all use native promises when the promise manager is + disabled. * Properly handle W3C error responses to new session commands. * Updated `selenium-webdriver/testing` to export `describe.only` along with `describe.skip`. -* Fixed `selenium-webdriver/lib/until.ableToSwitchToFrame`. It was previously dropping arguments and +* Fixed `selenium-webdriver/lib/until.ableToSwitchToFrame`. It was previously + dropping arguments and would never work. * Added the ability to use Firefox Nightly * If Firefox cannot be found in the default location, look for it on the PATH * Allow SafariDriver to use Safari Technology Preview. -* Use the proper wire command for WebElement.getLocation() and WebElement.getSize() for W3C +* Use the proper wire command for WebElement.getLocation() and + WebElement.getSize() for W3C compliant drivers. ## v3.0.1 * More API adjustments to align with native Promises - * Deprecated `promise.fulfilled(value)`, use `promise.Promise#resolve(value)` - * Deprecated `promise.rejected(reason)`, use `promise.Promise#reject(reason)` -* When a `wait()` condition times out, the returned promise will now be rejected with + * Deprecated `promise.fulfilled(value)`, use `promise.Promise#resolve(value)` + * Deprecated `promise.rejected(reason)`, use `promise.Promise#reject(reason)` +* When a `wait()` condition times out, the returned promise will now be rejected + with an `error.TimeoutError` instead of a generic `Error` object. -* `WebDriver#wait()` will now throw a TypeError if an invalid wait condition is provided. -* Properly catch unhandled promise rejections with an action sequence (only impacts when the promise +* `WebDriver#wait()` will now throw a TypeError if an invalid wait condition is + provided. +* Properly catch unhandled promise rejections with an action sequence (only + impacts when the promise manager is disabled). ## v3.0.0 * (__NOTICE__) The minimum supported version of Node is now 6.9.0 LTS -* Removed support for the SafariDriver browser extension. This has been replaced by Apple's +* Removed support for the SafariDriver browser extension. This has been replaced + by Apple's safaridriver, which is included wtih Safari 10 (available on OS X El Capitan and macOS Sierra). To use Safari 9 or older, users will have to use an older version of Selenium. * geckodriver v0.11.0 or newer is now required for Firefox. -* Fixed potential reference errors in `selenium-webdriver/testing` when users create a cycle with +* Fixed potential reference errors in `selenium-webdriver/testing` when users + create a cycle with mocha by running with mocha's `--hook` flag. -* Fixed `WebDriver.switchTo().activeElement()` to use the correct HTTP method for compatibility with +* Fixed `WebDriver.switchTo().activeElement()` to use the correct HTTP method + for compatibility with the W3C spec. * Update the `selenium-webdriver/firefox` module to use geckodriver's "moz:firefoxOptions" dictionary for Firefox-specific configuration values. -* Extending the `selenium-webdriver/testing` module to support tests defined using generator +* Extending the `selenium-webdriver/testing` module to support tests defined + using generator functions. * The promise manager can be disabled by setting an enviornment variable: - `SELENIUM_PROMISE_MANAGER=0`. This is part of a larger plan to remove the promise manager, as + `SELENIUM_PROMISE_MANAGER=0`. This is part of a larger plan to remove the + promise manager, as documented at * When communicating with a W3C-compliant remote end, use the atoms library for - the `WebElement.getAttribute()` and `WebElement.isDisplayed()` commands. This behavior is + the `WebElement.getAttribute()` and `WebElement.isDisplayed()` commands. This + behavior is consistent with the java, .net, python, and ruby clients. ### API Changes * Removed `safari.Options#useLegacyDriver()` * Reduced the API on `promise.Thenable` for compatibility with native promises: - * Removed `#isPending()` - * Removed `#cancel()` - * Removed `#finally()` + * Removed `#isPending()` + * Removed `#cancel()` + * Removed `#finally()` * Changed all subclasses of `webdriver.WebDriver` to overload the static - function `WebDriver.createSession()` instead of doing work in the constructor. All constructors - now inherit the base class' function signature. Users are still encouraged to use the `Builder` + function `WebDriver.createSession()` instead of doing work in the constructor. + All constructors + now inherit the base class' function signature. Users are still encouraged to + use the `Builder` class instead of creating drivers directly. -* `Builder#build()` now returns a "thenable" WebDriver instance, allowing users to immediately - schedule commands (as before), or issue them through standard promise callbacks. This is the same +* `Builder#build()` now returns a "thenable" WebDriver instance, allowing users + to immediately + schedule commands (as before), or issue them through standard promise + callbacks. This is the same pattern already employed for WebElements. * Removed `Builder#buildAsync()` as it was redundant with the new semantics of `build()`. ## v3.0.0-beta-3 -* Fixed a bug where the promise manager would silently drop callbacks after recovering from an +* Fixed a bug where the promise manager would silently drop callbacks after + recovering from an unhandled promise rejection. -* Added the `firefox.ServiceBuilder` class, which may be used to customize the geckodriver used +* Added the `firefox.ServiceBuilder` class, which may be used to customize the + geckodriver used for `firefox.Driver` instances. * Added support for Safari 10 safaridriver. safaridriver may be disabled via tha API, `safari.Options#useLegacyDriver`, to use the safari extension driver. * Updated the `lib/proxy` module to support configuring a SOCKS proxy. -* For the `promise.ControlFlow`, fire the "uncaughtException" event in a new turn of the JS event - loop. As a result of this change, any errors thrown by an event listener will propagate to the - global error handler. Previously, this event was fired with in the context of a (native) promise +* For the `promise.ControlFlow`, fire the "uncaughtException" event in a new + turn of the JS event + loop. As a result of this change, any errors thrown by an event listener will + propagate to the + global error handler. Previously, this event was fired with in the context of + a (native) promise callback, causing errors to be silently suppressed in the promise chain. ### API Changes -* Added `remote.DriverService.Builder` as a base class for configuring DriverService instances that +* Added `remote.DriverService.Builder` as a base class for configuring + DriverService instances that run in a child-process. The `chrome.ServiceBuilder`, `edge.ServiceBuilder`, and `opera.ServiceBuilder` classes now all extend this base class with browser-specific options. @@ -882,7 +953,8 @@ requires [geckodriver 0.15.0](https://github.com/mozilla/geckodriver/releases/ta * Moved the `builder.Builder` class into the main module (`selenium-webdriver`). * Removed the `builder` module. -* Fix `webdriver.WebDriver#setFileDetector` when driving Chrome or Firefox on a remote machine. +* Fix `webdriver.WebDriver#setFileDetector` when driving Chrome or Firefox on a + remote machine. ## v3.0.0-beta-1 @@ -890,62 +962,72 @@ requires [geckodriver 0.15.0](https://github.com/mozilla/geckodriver/releases/ta `builder.Builder#usingHttpAgent()` * Added new wait conditions: `until.urlIs()`, `until.urlContains()`, `until.urlMatches()` -* Added work around for [GeckoDriver bug](https://bugzilla.mozilla.org/show_bug.cgi?id=1274924) +* Added work around + for [GeckoDriver bug](https://bugzilla.mozilla.org/show_bug.cgi?id=1274924) raising a type conversion error * Internal cleanup replacing uses of managed promises with native promises * Removed the mandatory use of Firefox Dev Edition, when using Marionette driver * Fixed timeouts' URL * Properly send HTTP requests when using a WebDriver server proxy * Properly configure proxies when using the geckodriver -* `http.Executor` now accepts a promised client. The `builder.Builder` class will now use this +* `http.Executor` now accepts a promised client. The `builder.Builder` class + will now use this instead of a `command.DeferredExecutor` when creating WebDriver instances. * For Chrome and Firefox, the `builder.Builder` class will always return an - instanceof `chrome.Driver` and `firefox.Driver`, respectively, even when configured to use a + instanceof `chrome.Driver` and `firefox.Driver`, respectively, even when + configured to use a remote server (from `builder.Builder#usingServer(url)`, `SELENIUM_REMOTE_URL`, etc). ### API Changes * `promise.Deferred` is no longer a thenable object. -* `Options#addCookie()` now takes a record object instead of 7 individual parameters. A TypeError +* `Options#addCookie()` now takes a record object instead of 7 individual + parameters. A TypeError will be thrown if addCookie() is called with invalid arguments. * When adding cookies, the desired expiry must be provided as a Date or in - _seconds_ since epoch. When retrieving cookies, the expiration is always returned in seconds. + _seconds_ since epoch. When retrieving cookies, the expiration is always + returned in seconds. * Renamed `firefox.Options#useMarionette` to `firefox.Options#useGeckoDriver` * Removed deprecated modules: - * `selenium-webdriver/error` (use `selenium-webdriver/lib/error`,\ - or the `error` property exported by `selenium-webdriver`) - * `selenium-webdriver/executors` — this was not previously deprecated, but is no longer used. + * `selenium-webdriver/error` (use `selenium-webdriver/lib/error`,\ + or the `error` property exported by `selenium-webdriver`) + * `selenium-webdriver/executors` — this was not previously deprecated, but is + no longer used. * Removed deprecated types: - * `command.DeferredExecutor` — this was not previously deprecated, but is no longer used. It can - be trivially implemented by clients should it be needed. - * `error.InvalidSessionIdError` (use `error.NoSuchSessionError`) - * `executors.DeferredExecutor` - * `until.Condition` (use `webdriver.Condition`) - * `until.WebElementCondition` (use `webdriver.WebElementCondition`) - * `webdriver.UnhandledAlertError` (use `error.UnexpectedAlertOpenError`) + * `command.DeferredExecutor` — this was not previously deprecated, but is no + longer used. It can + be trivially implemented by clients should it be needed. + * `error.InvalidSessionIdError` (use `error.NoSuchSessionError`) + * `executors.DeferredExecutor` + * `until.Condition` (use `webdriver.Condition`) + * `until.WebElementCondition` (use `webdriver.WebElementCondition`) + * `webdriver.UnhandledAlertError` (use `error.UnexpectedAlertOpenError`) * Removed deprecated functions: - * `Deferred#cancel()` - * `Deferred#catch()` - * `Deferred#finally()` - * `Deferred#isPending()` - * `Deferred#then()` - * `Promise#thenCatch()` - * `Promise#thenFinally()` - * `WebDriver#isElementPresent()` - * `WebElement#getInnerHtml()` - * `WebElement#getOuterHtml()` - * `WebElement#getRawId()` - * `WebElement#isElementPresent()` + * `Deferred#cancel()` + * `Deferred#catch()` + * `Deferred#finally()` + * `Deferred#isPending()` + * `Deferred#then()` + * `Promise#thenCatch()` + * `Promise#thenFinally()` + * `WebDriver#isElementPresent()` + * `WebElement#getInnerHtml()` + * `WebElement#getOuterHtml()` + * `WebElement#getRawId()` + * `WebElement#isElementPresent()` * Removed deprecated properties: - * `WebDriverError#code` + * `WebDriverError#code` ## v2.53.2 -* Changed `io.exists()` to return a rejected promise if the input path is not a string -* Deprecated `Promise#thenFinally()` - use `Promise#finally()`. The thenFinally shim added to the +* Changed `io.exists()` to return a rejected promise if the input path is not a + string +* Deprecated `Promise#thenFinally()` - use `Promise#finally()`. The thenFinally + shim added to the promise module in v2.53.0 will be removed in v3.0 Sorry for the churn! -* FIXED: capabilities serialization now properly handles undefined vs. false-like values. +* FIXED: capabilities serialization now properly handles undefined vs. + false-like values. * FIXED: properly handle responses from the remote end in `WebDriver.attachToSession` @@ -958,41 +1040,53 @@ requires [geckodriver 0.15.0](https://github.com/mozilla/geckodriver/releases/ta ### Change Summary -* Added preliminary support for Marionette, Mozilla's WebDriver implementation for Firefox. +* Added preliminary support for Marionette, Mozilla's WebDriver implementation + for Firefox. Marionette may be enabled via the API, `firefox.Options#useMarionette`, or by setting the `SELENIUM_MARIONETTE` environment variable. -* Moved all logic for parsing and interpreting responses from the remote end into the +* Moved all logic for parsing and interpreting responses from the remote end + into the individual `command.Executor` implementations. * For consistency with the other Selenium language bindings, - `WebDriver#isElementPresent()` and `WebElement#isElementPresent()` have been deprecated. These - methods will be removed in v3.0. Use the findElements command to test for the presence of an + `WebDriver#isElementPresent()` and `WebElement#isElementPresent()` have been + deprecated. These + methods will be removed in v3.0. Use the findElements command to test for the + presence of an element: driver.findElements(By.css('.foo')).then(found => !!found.length); * Added support for W3C-spec compliant servers. * For consistent naming, deprecating `error.InvalidSessionIdError` in favor of `error.NoSuchSessionError`. -* Moved the `error` module to `lib/error` so all core modules are co-located. The top-level `error` +* Moved the `error` module to `lib/error` so all core modules are co-located. + The top-level `error` module will be removed in v3.0. -* Moved `until.Condition` and `until.WebElementCondition` to the webdriver module to break a +* Moved `until.Condition` and `until.WebElementCondition` to the webdriver + module to break a circular dependency. -* Added support for setting the username and password in basic auth pop-up dialogs (currently IE +* Added support for setting the username and password in basic auth pop-up + dialogs (currently IE only). * Deprecated `WebElement#getInnerHtml()` and `WebEleemnt#getOuterHtml()` * Deprecated `Promise#thenCatch()` - use `Promise#catch()` instead * Deprecated `Promise#thenFinally()` - use `promise.thenFinally()` instead -* FIXED: `io.findInPath()` will no longer match against directories that have the same basename as +* FIXED: `io.findInPath()` will no longer match against directories that have + the same basename as the target file. -* FIXED: `phantomjs.Driver` now takes a third argument that defines the path to a log file to use +* FIXED: `phantomjs.Driver` now takes a third argument that defines the path to + a log file to use for the phantomjs executable's output. This may be quickly set at runtime with the `SELENIUM_PHANTOMJS_LOG` environment variable. ### Changes for W3C WebDriver Spec Compliance -* Changed `element.sendKeys(...)` to send the key sequence as an array where each element defines a - single key. The legacy wire protocol permits arrays where each element is a string of arbitrary - length. This change is solely at the protocol level and should have no user-visible effect. +* Changed `element.sendKeys(...)` to send the key sequence as an array where + each element defines a + single key. The legacy wire protocol permits arrays where each element is a + string of arbitrary + length. This change is solely at the protocol level and should have no + user-visible effect. ## v2.52.0 @@ -1006,17 +1100,23 @@ the selenium-webdriver package README. ### Change Summary * Add support for Microsoft's Edge web browser -* Added `webdriver.Builder#buildAsync()`, which returns a promise that will be fulfilled with the - newly created WebDriver instance once the associated browser has been full initialized. This is - purely a convenient alternative to the existing build() method as the WebDriver class will always +* Added `webdriver.Builder#buildAsync()`, which returns a promise that will be + fulfilled with the + newly created WebDriver instance once the associated browser has been full + initialized. This is + purely a convenient alternative to the existing build() method as the + WebDriver class will always defer commands until it has a fully created browser. -* Added `firefox.Profile#setHost()` which may be used to set the host that the FirefoxDriver's +* Added `firefox.Profile#setHost()` which may be used to set the host that the + FirefoxDriver's server listens for commands on. The server uses "localhost" by default. * Added `promise.Promise#catch()` for API compatibility with native Promises. - `promise.Promise#thenCatch()` is not yet deprecated, but it simply delegates to `catch`. + `promise.Promise#thenCatch()` is not yet deprecated, but it simply delegates + to `catch`. * Changed some `io` operations to use native promises. -* Changed `command.Executor#execute()` and `HttpClient#send()` to return promises instead of using +* Changed `command.Executor#execute()` and `HttpClient#send()` to return + promises instead of using callback passing. * Replaced the `Serializable` class with an internal, Symbol-defined method. * Changed the `Capabilities` class to extend the native `Map` type. @@ -1024,23 +1124,29 @@ the selenium-webdriver package README. (Map semantics). To check whether the value is true, use `get(key)`. * Deprecated `executors.DeferredExecutor` in favor of `lib/command.DeferredExecutor`. -* API documentation is no longer distributed with the npm package, but remains available +* API documentation is no longer distributed with the npm package, but remains + available at -* Rewrote the `error` module to export an Error subtype for each type of error defined in +* Rewrote the `error` module to export an Error subtype for each type of error + defined in the [W3C WebDriver spec](https://w3c.github.io/webdriver/webdriver-spec.html#handling-errors). -* Changed the `http.Request` and `http.Response` classes to store headers in maps instead of object +* Changed the `http.Request` and `http.Response` classes to store headers in + maps instead of object literals. * Updated `ws` dependency to version `1.0.1`. * Removed fluent predicates "is" and "not" from the experimental `testing/assert` module. -* Wait conditions that locate an element, or that wait on an element's state, will return a +* Wait conditions that locate an element, or that wait on an element's state, + will return a WebElementPromise. -* Lots of internal clean-up to break selenium-webdriver's long standing dependency on Google's +* Lots of internal clean-up to break selenium-webdriver's long standing + dependency on Google's Closure library. ### Changes for W3C WebDriver Spec Compliance -* Updated the `By` locators that are not in the W3C spec to delegated to using CSS +* Updated the `By` locators that are not in the W3C spec to delegated to using + CSS selectors: `By.className`, `By.id`, `By.name`, and `By.tagName`. ## v2.49-51 @@ -1054,21 +1160,28 @@ the selenium-webdriver package README. ## v2.48.1 -* FIXED: Adjusted how the control flow tracks promise callbacks to avoid a potential deadlock. +* FIXED: Adjusted how the control flow tracks promise callbacks to avoid a + potential deadlock. ## v2.48.0 -* Node v0.12.x users must run with --harmony. _This is the last release that will support v0.12.x_ -* FIXED: (Promise/A+ compliance) When a promise is rejected with a thenable, the promise adopts the - thenable as its rejection reason instead of waiting for it to settle. The previous (incorrect) - behavior was hidden by bugs in the `promises-aplus-tests` compliance test suite that were fixed in +* Node v0.12.x users must run with --harmony. _This is the last release that + will support v0.12.x_ +* FIXED: (Promise/A+ compliance) When a promise is rejected with a thenable, the + promise adopts the + thenable as its rejection reason instead of waiting for it to settle. The + previous (incorrect) + behavior was hidden by bugs in the `promises-aplus-tests` compliance test + suite that were fixed in version `2.1.1`. -* FIXED: the `webdriver.promise.ControlFlow` now has a consistent execution order for +* FIXED: the `webdriver.promise.ControlFlow` now has a consistent execution + order for tasks/callbacks scheduled in different turns of the JS event loop. Refer to the `webdriver.promise` documentation for more details. * FIXED: do not drop user auth from the WebDriver server URL. -* FIXED: a single `firefox.Binary` instance may be used to configure and launch multiple +* FIXED: a single `firefox.Binary` instance may be used to configure and launch + multiple FirefoxDriver sessions. var binary = new firefox.Binary(); @@ -1078,10 +1191,13 @@ the selenium-webdriver package README. var driver1 = builder.build(); var driver2 = builder.build(); -* FIXED: zip files created for transfer to a remote WebDriver server are no longer compressed. If - the zip contained a file that was already compressed, the server would return an "invalid code +* FIXED: zip files created for transfer to a remote WebDriver server are no + longer compressed. If + the zip contained a file that was already compressed, the server would return + an "invalid code lengths set" error. -* FIXED: Surfaced the `loopback` option to `remote/SeleniumServer`. When set, the server will be +* FIXED: Surfaced the `loopback` option to `remote/SeleniumServer`. When set, + the server will be accessed using the current host's loopback address. ## v2.47.0 @@ -1096,8 +1212,9 @@ continue to be supported, but will require setting the `--harmony` flag. ### Change Summary * Add support for [Node v4.0.0](https://nodejs.org/en/blog/release/v4.0.0/) - * Updated `ws` dependency from `0.7.1` to `0.8.0` -* Bumped the minimum supported version of Node from `0.10.x` to `0.12.x`. This is in accordance with + * Updated `ws` dependency from `0.7.1` to `0.8.0` +* Bumped the minimum supported version of Node from `0.10.x` to `0.12.x`. This + is in accordance with the Node support policy established in `v2.45.0`. ## v2.46.1 @@ -1110,40 +1227,52 @@ continue to be supported, but will require setting the `--harmony` flag. * Exposed a new logging API via the `webdriver.logging` module. For usage, see `example/logging.js`. -* Added support for using a proxy server for WebDriver commands. See `Builder#usingWebDriverProxy()` +* Added support for using a proxy server for WebDriver commands. + See `Builder#usingWebDriverProxy()` for more info. * Removed deprecated functions: - * Capabilities#toJSON() - * UnhandledAlertError#getAlert() - * chrome.createDriver() - * phantomjs.createDriver() - * promise.ControlFlow#annotateError() - * promise.ControlFlow#await() - * promise.ControlFlow#clearHistory() - * promise.ControlFlow#getHistory() + * Capabilities#toJSON() + * UnhandledAlertError#getAlert() + * chrome.createDriver() + * phantomjs.createDriver() + * promise.ControlFlow#annotateError() + * promise.ControlFlow#await() + * promise.ControlFlow#clearHistory() + * promise.ControlFlow#getHistory() * Removed deprecated enum values: `ErrorCode.NO_MODAL_DIALOG_OPEN` and `ErrorCode.MODAL_DIALOG_OPENED`. Use `ErrorCode.NO_SUCH_ALERT` and `ErrorCode.UNEXPECTED_ALERT_OPEN`, respectively. -* FIXED: The `promise.ControlFlow` will maintain state for promise chains generated in a loop. +* FIXED: The `promise.ControlFlow` will maintain state for promise chains + generated in a loop. * FIXED: Correct serialize target elements used in an action sequence. -* FIXED: `promise.ControlFlow#wait()` now has consistent semantics for an omitted or 0-timeout: it +* FIXED: `promise.ControlFlow#wait()` now has consistent semantics for an + omitted or 0-timeout: it will wait indefinitely. -* FIXED: `remote.DriverService#start()` will now fail if the child process dies while waiting for - the server to start accepting requests. Previously, start would continue to poll the server +* FIXED: `remote.DriverService#start()` will now fail if the child process dies + while waiting for + the server to start accepting requests. Previously, start would continue to + poll the server address until the timeout expired. -* FIXED: Skip launching Firefox with the `-silent` flag to preheat the profile. Starting with - Firefox 38, this would cause the browser to crash. This step, which was first introduced for +* FIXED: Skip launching Firefox with the `-silent` flag to preheat the profile. + Starting with + Firefox 38, this would cause the browser to crash. This step, which was first + introduced for Selenium's java client back with Firefox 2, no longer appears to be required. -* FIXED: 8564: `firefox.Driver#quit()` will wait for the Firefox process to terminate before - deleting the temporary webdriver profile. This eliminates a race condition where Firefox would - write profile data during shutdown, causing the `rm -rf` operation on the profile directory to +* FIXED: 8564: `firefox.Driver#quit()` will wait for the Firefox process to + terminate before + deleting the temporary webdriver profile. This eliminates a race condition + where Firefox would + write profile data during shutdown, causing the `rm -rf` operation on the + profile directory to fail. ## v2.45.1 -* FIXED: 8548: Task callbacks are once again dropped if the task was cancelled due to a previously +* FIXED: 8548: Task callbacks are once again dropped if the task was cancelled + due to a previously uncaught error within the frame. -* FIXED: 8496: Extended the `chrome.Options` API to cover all configuration options (e.g. mobile +* FIXED: 8496: Extended the `chrome.Options` API to cover all configuration + options (e.g. mobile emulation and performance logging) documented on the ChromeDriver [project site](https://chromedriver.chromium.org/capabilities). @@ -1160,10 +1289,12 @@ major version release (i.e. 1.0.0). ### Change Summary * Added native browser support for Internet Explorer, Opera 26+, and Safari -* With the release of [Node 0.12.0](http://blog.nodejs.org/2015/02/06/node-v0-12-0-stable/) +* With the release + of [Node 0.12.0](http://blog.nodejs.org/2015/02/06/node-v0-12-0-stable/) (finally!), the minimum supported version of Node is now `0.10.x`. * The `promise` module is now [Promises/A+](https://promisesaplus.com/) - compliant. The biggest compliance change is that promise callbacks are now invoked in a future + compliant. The biggest compliance change is that promise callbacks are now + invoked in a future turn of the JS event loop. For example: var promise = require('selenium-webdriver').promise; @@ -1183,10 +1314,13 @@ major version release (i.e. 1.0.0). // end // middle - The `promise.ControlFlow` class has been updated to track the asynchronous breaks required by + The `promise.ControlFlow` class has been updated to track the asynchronous + breaks required by Promises/A+, so there are no changes to task execution order. -* Updated how errors are annotated on failures. When a task fails, the stacktrace from when that - task was scheduled is appended to the rejection reason with a `From:` prefix (if it is an Error +* Updated how errors are annotated on failures. When a task fails, the + stacktrace from when that + task was scheduled is appended to the rejection reason with a `From:` prefix ( + if it is an Error object). For example: var driver = new webdriver.Builder().forBrowser('chrome').build(); @@ -1207,31 +1341,45 @@ major version release (i.e. 1.0.0). From: Task: WebDriver.call(function) at -* Changed the format of strings returned by `promise.ControlFlow#getSchedule`. This function now - accepts a boolean to control whether the returned string should include the stacktraces for when +* Changed the format of strings returned by `promise.ControlFlow#getSchedule`. + This function now + accepts a boolean to control whether the returned string should include the + stacktraces for when each task was scheduled. * Deprecating `promise.ControlFlow#getHistory`, - `promise.ControlFlow#clearHistory`, and `promise.ControlFlow#annotateError`. These functions were - all intended for internal use and are no longer necessary, so they have been made no-ops. -* `WebDriver.wait()` may now be used to wait for a promise to resolve, with an optional timeout. + `promise.ControlFlow#clearHistory`, and `promise.ControlFlow#annotateError`. + These functions were + all intended for internal use and are no longer necessary, so they have been + made no-ops. +* `WebDriver.wait()` may now be used to wait for a promise to resolve, with an + optional timeout. Refer to the API documentation for more information. -* Added support for copying files to a remote Selenium via `sendKeys` to test file uploads. Refer to - the API documentation for more information. Sample usage included in `test/upload_test.js` -* Expanded the interactions API to include touch actions. See `WebDriver.touchActions()`. +* Added support for copying files to a remote Selenium via `sendKeys` to test + file uploads. Refer to + the API documentation for more information. Sample usage included + in `test/upload_test.js` +* Expanded the interactions API to include touch actions. + See `WebDriver.touchActions()`. * FIXED: 8380: `firefox.Driver` will delete its temporary profile on `quit`. * FIXED: 8306: Stack overflow in promise callbacks eliminated. -* FIXED: 8221: Added support for defining custom command mappings. Includes support for - PhantomJS's `executePhantomJS` (requires PhantomJS 1.9.7 or GhostDriver 1.1.0). +* FIXED: 8221: Added support for defining custom command mappings. Includes + support for + PhantomJS's `executePhantomJS` (requires PhantomJS 1.9.7 or GhostDriver + 1.1.0). * FIXED: 8128: When the FirefoxDriver marshals an object to the page for - `executeScript`, it defines additional properties (required by the driver's implementation). These - properties will no longer be enumerable and should be omitted (i.e. they won't show up in + `executeScript`, it defines additional properties (required by the driver's + implementation). These + properties will no longer be enumerable and should be omitted (i.e. they won't + show up in JSON.stringify output). -* FIXED: 8094: The control flow will no longer deadlock when a task returns a promise that depends +* FIXED: 8094: The control flow will no longer deadlock when a task returns a + promise that depends on the completion of sub-tasks. ## v2.44.0 -* Added the `until` module, which defines common explicit wait conditions. Sample usage: +* Added the `until` module, which defines common explicit wait conditions. + Sample usage: var firefox = require('selenium-webdriver/firefox'), until = require('selenium-webdriver/until'); @@ -1240,42 +1388,55 @@ major version release (i.e. 1.0.0). driver.get('http://www.google.com/ncr'); driver.wait(until.titleIs('Google Search'), 1000); -* FIXED: 8000: `Builder.forBrowser()` now accepts an empty string since some WebDriver - implementations ignore the value. A value must still be specified, however, since it is a required +* FIXED: 8000: `Builder.forBrowser()` now accepts an empty string since some + WebDriver + implementations ignore the value. A value must still be specified, however, + since it is a required field in WebDriver's wire protocol. -* FIXED: 7994: The `stacktrace` module will not modify stack traces if the initial parse fails (e.g. +* FIXED: 7994: The `stacktrace` module will not modify stack traces if the + initial parse fails (e.g. the user defined `Error.prepareStackTrace`) -* FIXED: 5855: Added a module (`until`) that defines several common conditions for use with explicit +* FIXED: 5855: Added a module (`until`) that defines several common conditions + for use with explicit waits. See updated examples for usage. ## v2.43.5 -* FIXED: 7905: `Builder.usingServer(url)` once again returns `this` for chaining. +* FIXED: 7905: `Builder.usingServer(url)` once again returns `this` for + chaining. ## v2.43.2-4 -* No changes; version bumps while attempting to work around an issue with publishing to npm (a +* No changes; version bumps while attempting to work around an issue with + publishing to npm (a version string may only be used once). ## v2.43.1 -* Fixed an issue with flakiness when setting up the Firefox profile that could prevent the driver +* Fixed an issue with flakiness when setting up the Firefox profile that could + prevent the driver from initializing properly. ## v2.43.0 -* Added native support for Firefox - the Java Selenium server is no longer required. +* Added native support for Firefox - the Java Selenium server is no longer + required. * Added support for generator functions to `ControlFlow#execute` and `ControlFlow#wait`. For more information, see documentation on `webdriver.promise.consume`. Requires harmony support (run with `node --harmony-generators` in `v0.11.x`). -* Various improvements to the `Builder` API. Notably, the `build()` function will no longer default +* Various improvements to the `Builder` API. Notably, the `build()` function + will no longer default to attempting to use a server at - `http://localhost:4444/wd/hub` if it cannot start a browser directly - you must specify the - WebDriver server with `usingServer(url)`. You can also set the target browser and WebDriver server - through a pair of environment variables. See the documentation on the `Builder` constructor for + `http://localhost:4444/wd/hub` if it cannot start a browser directly - you + must specify the + WebDriver server with `usingServer(url)`. You can also set the target browser + and WebDriver server + through a pair of environment variables. See the documentation on + the `Builder` constructor for more information. -* For consistency with the other language bindings, added browser specific classes that can be used +* For consistency with the other language bindings, added browser specific + classes that can be used to start a browser without the builder. var webdriver = require('selenium-webdriver') @@ -1292,9 +1453,11 @@ major version release (i.e. 1.0.0). * FIXED: 7641: Deprecated `ErrorCode.NO_MODAL_DIALOG_OPEN` and `ErrorCode.MODAL_DIALOG_OPENED` in favor of the new `ErrorCode.NO_SUCH_ALERT` and `ErrorCode.UNEXPECTED_ALERT_OPEN`, respectively. -* FIXED: 7563: Mocha integration no longer disables timeouts. Default Mocha timeouts apply (2000 ms) +* FIXED: 7563: Mocha integration no longer disables timeouts. Default Mocha + timeouts apply (2000 ms) and may be changed using `this.timeout(ms)`. -* FIXED: 7470: Make it easier to create WebDriver instances in custom flows for parallel execution. +* FIXED: 7470: Make it easier to create WebDriver instances in custom flows for + parallel execution. ## v2.42.1 @@ -1307,9 +1470,11 @@ major version release (i.e. 1.0.0). * Removed deprecated functions `Promise#addCallback()`, `Promise#addCallbacks()`, `Promise#addErrback()`, and `Promise#addBoth()`. * Fail with a more descriptive error if the server returns a malformed redirect -* FIXED: 7300: Connect to ChromeDriver using the loopback address since ChromeDriver 2.10.267517 +* FIXED: 7300: Connect to ChromeDriver using the loopback address since + ChromeDriver 2.10.267517 binds to localhost by default. -* FIXED: 7339: Preserve wrapped test function's string representation for Mocha's BDD interface. +* FIXED: 7339: Preserve wrapped test function's string representation for Mocha' + s BDD interface. ## v2.41.0 @@ -1333,26 +1498,32 @@ major version release (i.e. 1.0.0). ## v2.38.1 -* FIXED: 6686: Changed `webdriver.promise.Deferred#cancel()` to silently no-op if the deferred has +* FIXED: 6686: Changed `webdriver.promise.Deferred#cancel()` to silently no-op + if the deferred has already been resolved. ## v2.38.0 -* When a promise is rejected, always annotate the stacktrace with the parent flow state so users can +* When a promise is rejected, always annotate the stacktrace with the parent + flow state so users can identify the source of an error. * Updated tests to reflect features not working correctly in the SafariDriver (cookie management and proxy support; see issues 5051, 5212, and 5503) -* FIXED: 6284: For mouse moves, correctly omit the x/y offsets if not specified as a function +* FIXED: 6284: For mouse moves, correctly omit the x/y offsets if not specified + as a function argument (instead of passing (0,0)). * FIXED: 6471: Updated documentation on `webdriver.WebElement#getAttribute` -* FIXED: 6612: On Unix, use the default IANA ephemeral port range if unable to retrieve the current +* FIXED: 6612: On Unix, use the default IANA ephemeral port range if unable to + retrieve the current system's port range. -* FIXED: 6617: Avoid triggering the node debugger when initializing the stacktrace module. +* FIXED: 6617: Avoid triggering the node debugger when initializing the + stacktrace module. * FIXED: 6627: Safely rebuild chrome.Options from a partial JSON spec. ## v2.37.0 -* FIXED: 6346: The remote.SeleniumServer class now accepts JVM arguments using the `jvmArgs` option. +* FIXED: 6346: The remote.SeleniumServer class now accepts JVM arguments using + the `jvmArgs` option. ## v2.36.0 @@ -1372,16 +1543,20 @@ major version release (i.e. 1.0.0). ## v2.34.1 -* FIXED: 6079: The parent process should not wait for spawn driver service processes (chromedriver, +* FIXED: 6079: The parent process should not wait for spawn driver service + processes (chromedriver, phantomjs, etc.) ## v2.34.0 -* Added the `selenium-webdriver/testing/assert` module. This module simplifies writing assertions +* Added the `selenium-webdriver/testing/assert` module. This module simplifies + writing assertions against promised values (see example in module documentation). * Added the `webdriver.Capabilities` class. -* Added native support for the ChromeDriver. When using the `Builder`, requesting chrome without - specifying a remote server URL will default to the native ChromeDriver implementation. The +* Added native support for the ChromeDriver. When using the `Builder`, + requesting chrome without + specifying a remote server URL will default to the native ChromeDriver + implementation. The [ChromeDriver server](https://code.google.com/p/chromedriver/downloads/list) must be downloaded separately. @@ -1400,10 +1575,12 @@ major version release (i.e. 1.0.0). `selenium-webdriver/test/proxy_test`. * Added native support for PhantomJS. * Changed signature of `SeleniumServer` to `SeleniumServer(jar, options)`. -* Tests are now included in the npm published package. See `README.md` for execution instructions +* Tests are now included in the npm published package. See `README.md` for + execution instructions * Removed the deprecated `webdriver.Deferred#resolve` and `webdriver.promise.resolved` functions. -* Removed the ability to connect to an existing session from the Builder. This feature is intended +* Removed the ability to connect to an existing session from the Builder. This + feature is intended for use with the browser-based client. ## v2.33.0 @@ -1418,28 +1595,33 @@ major version release (i.e. 1.0.0). ## v2.32.0 -* Added the `selenium-webdriver/testing` package, which provides a basic framework for writing tests +* Added the `selenium-webdriver/testing` package, which provides a basic + framework for writing tests using Mocha. See `selenium-webdriver/example/google_search_test.js` for usage. -* For Promises/A+ compatibility, backing out the change in 2.30.0 that ensured rejections were +* For Promises/A+ compatibility, backing out the change in 2.30.0 that ensured + rejections were always Error objects. Rejection reasons are now left as is. * Removed deprecated functions originally scheduled for removal in 2.31.0 - * promise.Application.getInstance() - * promise.ControlFlow#schedule() - * promise.ControlFlow#scheduleTimeout() - * promise.ControlFlow#scheduleWait() -* Renamed some functions for consistency with Promises/A+ terminology. The original functions have + * promise.Application.getInstance() + * promise.ControlFlow#schedule() + * promise.ControlFlow#scheduleTimeout() + * promise.ControlFlow#scheduleWait() +* Renamed some functions for consistency with Promises/A+ terminology. The + original functions have been deprecated and will be removed in 2.34.0: - * promise.resolved() -> promise.fulfilled() - * promise.Deferred#resolve() -> promise.Deferred#fulfill() -* FIXED: remote.SeleniumServer#stop now shuts down within the active control flow, allowing scripts + * promise.resolved() -> promise.fulfilled() + * promise.Deferred#resolve() -> promise.Deferred#fulfill() +* FIXED: remote.SeleniumServer#stop now shuts down within the active control + flow, allowing scripts to finish. Use #kill to shutdown immediately. * FIXED: 5321: cookie deletion commands ## v2.31.0 * Added an example script. -* Added a class for controlling the standalone Selenium server (server available separately) +* Added a class for controlling the standalone Selenium server (server available + separately) * Added a portprober for finding free ports * FIXED: WebElements now belong to the same flow as their parent driver. diff --git a/javascript/node/selenium-webdriver/README.md b/javascript/node/selenium-webdriver/README.md index 6cb3e63a14907..92b6ced4b8481 100644 --- a/javascript/node/selenium-webdriver/README.md +++ b/javascript/node/selenium-webdriver/README.md @@ -13,19 +13,18 @@ Selenium may be installed via npm with You will need to download additional components to work with each of the major browsers. The drivers for Chrome, Firefox, and Microsoft's IE and Edge web browsers are all standalone executables that should be placed on your system -[PATH]. Apple's safaridriver (v10 and above) can be found at the -following path – /usr/bin/safaridriver. To enable automation on safari, +[PATH]. Apple's safaridriver (v10 and above) can be found at the +following path – /usr/bin/safaridriver. To enable automation on safari, you need to run command `safaridriver --enable`. - -| Browser | Component | -|:-------------------|:------------------------------------| -| Chrome | [chromedriver(.exe)][chrome] | -| Internet Explorer | [IEDriverServer.exe][release] | -| Edge | [MicrosoftWebDriver.msi][edge] | -| Firefox | [geckodriver(.exe)][geckodriver] | -| Opera | [operadriver(.exe)][operadriver] | -| Safari | [safaridriver] | +| Browser | Component | +|:------------------|:---------------------------------| +| Chrome | [chromedriver(.exe)][chrome] | +| Internet Explorer | [IEDriverServer.exe][release] | +| Edge | [MicrosoftWebDriver.msi][edge] | +| Firefox | [geckodriver(.exe)][geckodriver] | +| Opera | [operadriver(.exe)][operadriver] | +| Safari | [safaridriver] | ## Usage @@ -103,6 +102,7 @@ let driver = new webdriver.Builder() .usingServer('http://localhost:4444/wd/hub') .build(); ``` + Or change the Builder's configuration at runtime with the `SELENIUM_REMOTE_URL` environment variable: @@ -135,43 +135,44 @@ will also have "best effort" support. Releases older than the latest LTS, _semver-major_ releases, and all unstable release branches (e.g. "v.Next") are considered strictly unsupported. -For example, suppose the current LTS and stable releases are v14.20.0 and v18.8.0, +For example, suppose the current LTS and stable releases are v14.20.0 and +v18.8.0, respectively. Then a Selenium release would have the following support levels: -| Version | Support | -|:----------:|:---------------:| -| <= 14.19 | _unsupported_ | -| 14.20.0 | supported | -| 18.0-7 | best effort | -| 18.8.0 | supported | -| >= 18.8.0 | best effort | -| v.Next | _unsupported_ | +| Version | Support | +|:---------:|:-------------:| +| <= 14.19 | _unsupported_ | +| 14.20.0 | supported | +| 18.0-7 | best effort | +| 18.8.0 | supported | +| >= 18.8.0 | best effort | +| v.Next | _unsupported_ | ### Support Level Definitions - _supported:_ A selenium-webdriver release will be API compatible with the - platform API, without the use of runtime flags. + platform API, without the use of runtime flags. - _best effort:_ Bugs will be investigated as time permits. API compatibility is - only guaranteed where required by a _supported_ release. This effectively - means the adoption of new JS features, such as ES2015 modules, will depend - on what is supported in Node's LTS. + only guaranteed where required by a _supported_ release. This effectively + means the adoption of new JS features, such as ES2015 modules, will depend + on what is supported in Node's LTS. - _unsupported:_ Bug submissions will be closed as will-not-fix and API - compatibility is not guaranteed. + compatibility is not guaranteed. ### Projected Support Schedule If Node releases a new [LTS] each October and a new major version every 6 months, the support window for selenium-webdriver will be roughly: -| Release | Status | END-OF-LIFE | -|:---------:|:----------------:|:------------:| -| v14.x | Maintenance LTS | 2023-04-30 | -| v16.x | Active LTS | 2023-09-11 | -| v18.x | Current | 2025-04-30 | -| v19.x | Pending | 2023-06-01 | -| v20 | Pending | 2026-04-30 | +| Release | Status | END-OF-LIFE | +|:-------:|:---------------:|:-----------:| +| v14.x | Maintenance LTS | 2023-04-30 | +| v16.x | Active LTS | 2023-09-11 | +| v18.x | Current | 2025-04-30 | +| v19.x | Pending | 2023-06-01 | +| v20 | Pending | 2026-04-30 | ## Issues @@ -180,52 +181,62 @@ the issue tracker - __Do__ include a detailed description of the problem. - __Do__ include a link to a [gist](http://gist.github.com/) with any - interesting stack traces/logs (you may also attach these directly to the bug - report). + interesting stack traces/logs (you may also attach these directly to the bug + report). - __Do__ include a [reduced test case][reduction]. Reporting "unable to find - element on the page" is _not_ a valid report - there's nothing for us to - look into. Expect your bug report to be closed if you do not provide enough - information for us to investigate. + element on the page" is _not_ a valid report - there's nothing for us to + look into. Expect your bug report to be closed if you do not provide enough + information for us to investigate. - __Do not__ use the issue tracker to submit basic help requests. All help - inquiries should be directed to the [user forum][users] or #selenium IRC - channel. + inquiries should be directed to the [user forum][users] or #selenium IRC + channel. - __Do not__ post empty "I see this too" or "Any updates?" comments. These - provide no additional information and clutter the log. + provide no additional information and clutter the log. - __Do not__ report regressions on closed bugs as they are not actively - monitored for updates (especially bugs that are >6 months old). Please open a - new issue and reference the original bug in your report. + monitored for updates (especially bugs that are >6 months old). Please open a + new issue and reference the original bug in your report. ## License Licensed to the Software Freedom Conservancy (SFC) under one -or more contributor license agreements. See the NOTICE file +or more contributor license agreements. See the NOTICE file distributed with this work for additional information -regarding copyright ownership. The SFC licenses this file +regarding copyright ownership. The SFC licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at +with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the +KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. [LTS]: https://github.com/nodejs/LTS + [PATH]: http://en.wikipedia.org/wiki/PATH_%28variable%29 + [api]: http://seleniumhq.github.io/selenium/docs/api/javascript/module/selenium-webdriver/ + [chrome]: http://chromedriver.storage.googleapis.com/index.html + [gh]: https://github.com/SeleniumHQ/selenium/ + [issues]: https://github.com/SeleniumHQ/selenium/issues + [edge]: http://go.microsoft.com/fwlink/?LinkId=619687 + [geckodriver]: https://github.com/mozilla/geckodriver/releases/ + [reduction]: http://www.webkit.org/quality/reduction.html [release]: https://www.selenium.dev/downloads/ [users]: https://groups.google.com/forum/#!forum/selenium-users + [safaridriver]: https://developer.apple.com/library/prerelease/content/releasenotes/General/WhatsNewInSafari/Articles/Safari_10_0.html#//apple_ref/doc/uid/TP40014305-CH11-DontLinkElementID_28 + [operadriver]: https://github.com/operasoftware/operachromiumdriver/releases diff --git a/javascript/node/selenium-webdriver/bidi/addInterceptParameters.js b/javascript/node/selenium-webdriver/bidi/addInterceptParameters.js index 46393287b87ac..cd5e51025c078 100644 --- a/javascript/node/selenium-webdriver/bidi/addInterceptParameters.js +++ b/javascript/node/selenium-webdriver/bidi/addInterceptParameters.js @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -const {UrlPattern} = require("./urlPattern"); +const { UrlPattern } = require('./urlPattern') class AddInterceptParameters { #phases = [] @@ -23,64 +23,58 @@ class AddInterceptParameters { constructor(phases) { if (phases instanceof Array) { - phases.forEach(phase => this.#phases.push(phase)) + phases.forEach((phase) => this.#phases.push(phase)) } else { this.#phases.push(phases) } } - urlPattern(pattern) - { + urlPattern(pattern) { + if (!pattern instanceof UrlPattern) { + throw new Error(`Pattern must be an instance of UrlPattern. Received: '${pattern})'`) + } + this.#urlPatterns.push(Object.fromEntries(pattern.asMap())) + return this + } + + urlPatterns(patterns) { + patterns.forEach((pattern) => { if (!pattern instanceof UrlPattern) { - throw new Error(`Pattern must be an instance of UrlPattern. Received: '${pattern})'`) + throw new Error(`Pattern must be an instance of UrlPattern. Received:'${pattern}'`) } this.#urlPatterns.push(Object.fromEntries(pattern.asMap())) - return this - } + }) + return this + } - urlPatterns(patterns) - { - patterns.forEach(pattern => { - if (!pattern instanceof UrlPattern) { - throw new Error(`Pattern must be an instance of UrlPattern. Received:'${pattern}'`) - } - this.#urlPatterns.push(Object.fromEntries(pattern.asMap())) - }) - return this + urlStringPattern(pattern) { + if (!pattern instanceof String) { + throw new Error(`Pattern must be an instance of String. Received:'${pattern}'`) } - urlStringPattern(pattern) - { + this.#urlPatterns.push({ type: 'string', pattern: pattern }) + return this + } + + urlStringPatterns(patterns) { + patterns.forEach((pattern) => { if (!pattern instanceof String) { throw new Error(`Pattern must be an instance of String. Received:'${pattern}'`) } + this.#urlPatterns.push({ type: 'string', pattern: pattern }) + }) + return this + } - this.#urlPatterns.push({'type': 'string', 'pattern': pattern}) - return this - } - - urlStringPatterns(patterns) - { - patterns.forEach(pattern => { - if (!pattern instanceof String) { - throw new Error(`Pattern must be an instance of String. Received:'${pattern}'`) - } - this.#urlPatterns.push({'type': 'string', 'pattern': pattern}) - }) - return this + asMap() { + const map = new Map() + map.set('phases', this.#phases) + if (this.#urlPatterns.length > 0) { + map.set('urlPatterns', this.#urlPatterns) } - - asMap() - { - const map = new Map() - map.set('phases', this.#phases) - if (this.#urlPatterns.length > 0) { - map.set('urlPatterns', this.#urlPatterns) - } - - return map - } + return map } +} - module.exports = {AddInterceptParameters} +module.exports = { AddInterceptParameters } diff --git a/javascript/node/selenium-webdriver/bidi/argumentValue.js b/javascript/node/selenium-webdriver/bidi/argumentValue.js index 47335906d1caf..57ee705652671 100644 --- a/javascript/node/selenium-webdriver/bidi/argumentValue.js +++ b/javascript/node/selenium-webdriver/bidi/argumentValue.js @@ -16,6 +16,7 @@ // under the License. const { LocalValue } = require('./protocolValue') + class ArgumentValue { constructor(value) { this.value = value diff --git a/javascript/node/selenium-webdriver/bidi/browsingContext.js b/javascript/node/selenium-webdriver/bidi/browsingContext.js index f740bb2ca26f5..ebb624448f754 100644 --- a/javascript/node/selenium-webdriver/bidi/browsingContext.js +++ b/javascript/node/selenium-webdriver/bidi/browsingContext.js @@ -71,6 +71,13 @@ class BrowsingContext { this._driver = driver } + /** + * @returns id + */ + get id() { + return this._id + } + async init({ browsingContextId, type, referenceContext }) { if (!(await this._driver.getCapabilities()).get('webSocketUrl')) { throw Error('WebDriver instance must support BiDi protocol') @@ -101,13 +108,6 @@ class BrowsingContext { return await this.bidi.send(params) } - /** - * @returns id - */ - get id() { - return this._id - } - /** * @param url the url to navigate to * @param readinessState type of readiness state: "none" / "interactive" / "complete" diff --git a/javascript/node/selenium-webdriver/bidi/index.js b/javascript/node/selenium-webdriver/bidi/index.js index 3763e49376976..a27683ade98cb 100644 --- a/javascript/node/selenium-webdriver/bidi/index.js +++ b/javascript/node/selenium-webdriver/bidi/index.js @@ -40,6 +40,31 @@ class Index extends EventEmitter { }) } + /** + * @returns {WebSocket} + */ + get socket() { + return this._ws + } + + /** + * @returns {boolean|*} + */ + get isConnected() { + return this.connected + } + + /** + * Get Bidi Status + * @returns {Promise<*>} + */ + get status() { + return this.send({ + method: 'session.status', + params: {}, + }) + } + /** * Resolve connection * @returns {Promise} @@ -56,20 +81,6 @@ class Index extends EventEmitter { }) } - /** - * @returns {WebSocket} - */ - get socket() { - return this._ws - } - - /** - * @returns {boolean|*} - */ - get isConnected() { - return this.connected - } - /** * Sends a bidi request * @param params @@ -183,17 +194,6 @@ class Index extends EventEmitter { await this.send(params) } - /** - * Get Bidi Status - * @returns {Promise<*>} - */ - get status() { - return this.send({ - method: 'session.status', - params: {}, - }) - } - /** * Close ws connection. * @returns {Promise} diff --git a/javascript/node/selenium-webdriver/bidi/interceptPhase.js b/javascript/node/selenium-webdriver/bidi/interceptPhase.js index 0079effec0da7..fd18eb770f444 100644 --- a/javascript/node/selenium-webdriver/bidi/interceptPhase.js +++ b/javascript/node/selenium-webdriver/bidi/interceptPhase.js @@ -21,4 +21,4 @@ const InterceptPhase = { AUTH_REQUIRED: 'authRequired', } -module.exports = {InterceptPhase} +module.exports = { InterceptPhase } diff --git a/javascript/node/selenium-webdriver/bidi/network.js b/javascript/node/selenium-webdriver/bidi/network.js index db5e3702424ab..4d41de99c56ae 100644 --- a/javascript/node/selenium-webdriver/bidi/network.js +++ b/javascript/node/selenium-webdriver/bidi/network.js @@ -15,8 +15,8 @@ // specific language governing permissions and limitations // under the License. -const { BeforeRequestSent, ResponseStarted, FetchError} = require('./networkTypes') -const {AddInterceptParameters} = require("./addInterceptParameters"); +const { BeforeRequestSent, ResponseStarted, FetchError } = require('./networkTypes') +const { AddInterceptParameters } = require('./addInterceptParameters') class Network { constructor(driver, browsingContextIds) { @@ -92,19 +92,18 @@ class Network { ) } callback(response) - } + } }) } async addIntercept(params) { - if (!params instanceof AddInterceptParameters) { throw new Error(`Params must be an instance of AddInterceptParamenters. Received:'${params}'`) } const command = { method: 'network.addIntercept', - params: Object.fromEntries(params.asMap()) + params: Object.fromEntries(params.asMap()), } let response = await this.bidi.send(command) @@ -115,7 +114,7 @@ class Network { async removeIntercept(interceptId) { const command = { method: 'network.removeIntercept', - params: {intercept: interceptId}, + params: { intercept: interceptId }, } await this.bidi.send(command) @@ -123,17 +122,17 @@ class Network { async continueWithAuth(requestId, username, password) { const command = { - method: 'network.continueWithAuth', - params: { - request: requestId.toString(), - action: 'provideCredentials', - credentials: { - type: 'password', - username: username, - password: password - }, - }, - } + method: 'network.continueWithAuth', + params: { + request: requestId.toString(), + action: 'provideCredentials', + credentials: { + type: 'password', + username: username, + password: password, + }, + }, + } await this.bidi.send(command) } @@ -142,7 +141,7 @@ class Network { method: 'network.continueWithAuth', params: { request: requestId.toString(), - action: 'default' + action: 'default', }, } await this.bidi.send(command) @@ -153,7 +152,7 @@ class Network { method: 'network.continueWithAuth', params: { request: requestId.toString(), - action: 'cancel' + action: 'cancel', }, } await this.bidi.send(command) @@ -164,9 +163,9 @@ class Network { 'network.beforeRequestSent', 'network.responseStarted', 'network.responseCompleted', - 'network.authRequired') + 'network.authRequired', + ) } - } async function getNetworkInstance(driver, browsingContextIds = null) { diff --git a/javascript/node/selenium-webdriver/bidi/urlPattern.js b/javascript/node/selenium-webdriver/bidi/urlPattern.js index 95067c15bf3f6..80635817857da 100644 --- a/javascript/node/selenium-webdriver/bidi/urlPattern.js +++ b/javascript/node/selenium-webdriver/bidi/urlPattern.js @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. -const {LocalValue} = require('./protocolValue') +const { LocalValue } = require('./protocolValue') class UrlPattern { #map = new Map() @@ -55,4 +55,4 @@ class UrlPattern { } } -module.exports = {UrlPattern} +module.exports = { UrlPattern } diff --git a/javascript/node/selenium-webdriver/chromium.js b/javascript/node/selenium-webdriver/chromium.js index ffd312f41e47a..79e126f9d1ac0 100644 --- a/javascript/node/selenium-webdriver/chromium.js +++ b/javascript/node/selenium-webdriver/chromium.js @@ -287,6 +287,7 @@ class Options extends Capabilities { throw TypeError('Arguments must be {width, height} with numbers > 0') } } + checkArg(width) checkArg(height) return this.addArguments(`window-size=${width},${height}`) diff --git a/javascript/node/selenium-webdriver/devtools/CDPConnection.js b/javascript/node/selenium-webdriver/devtools/CDPConnection.js index 49cc387e5f0bc..4084e64d0c4a6 100644 --- a/javascript/node/selenium-webdriver/devtools/CDPConnection.js +++ b/javascript/node/selenium-webdriver/devtools/CDPConnection.js @@ -18,6 +18,7 @@ const logging = require('../lib/logging') const RESPONSE_TIMEOUT = 1000 * 30 + class CDPConnection { constructor(wsConnection) { this._wsConnection = wsConnection diff --git a/javascript/node/selenium-webdriver/devtools/networkinterceptor.js b/javascript/node/selenium-webdriver/devtools/networkinterceptor.js index 4d04acc0c72c2..75a96354dc7fa 100644 --- a/javascript/node/selenium-webdriver/devtools/networkinterceptor.js +++ b/javascript/node/selenium-webdriver/devtools/networkinterceptor.js @@ -85,4 +85,5 @@ class HttpResponse { return this.returnMethod } } + exports.HttpResponse = HttpResponse diff --git a/javascript/node/selenium-webdriver/http/util.js b/javascript/node/selenium-webdriver/http/util.js index a61ed551bc43d..a4eca68dd2ac2 100644 --- a/javascript/node/selenium-webdriver/http/util.js +++ b/javascript/node/selenium-webdriver/http/util.js @@ -72,6 +72,7 @@ function waitForServer(url, timeout, opt_cancelToken) { } checkServerStatus() + function checkServerStatus() { return getStatus(url).then((status) => resolve(status), onError) } diff --git a/javascript/node/selenium-webdriver/lib/capabilities.js b/javascript/node/selenium-webdriver/lib/capabilities.js index 75e3efc46c826..c1aed54b27e4a 100644 --- a/javascript/node/selenium-webdriver/lib/capabilities.js +++ b/javascript/node/selenium-webdriver/lib/capabilities.js @@ -246,6 +246,11 @@ class Capabilities { this.map_ = new Map(other) } + /** @return {number} The number of capabilities set. */ + get size() { + return this.map_.size + } + /** * @return {!Capabilities} A basic set of capabilities for Chrome. */ @@ -315,11 +320,6 @@ class Capabilities { return this.map_.keys() } - /** @return {number} The number of capabilities set. */ - get size() { - return this.map_.size - } - /** * Merges another set of capabilities into this instance. * @param {!(Capabilities|Map|Object)} other The other diff --git a/javascript/node/selenium-webdriver/lib/http.js b/javascript/node/selenium-webdriver/lib/http.js index 6afe53ffa35c1..7365ea4bf1995 100644 --- a/javascript/node/selenium-webdriver/lib/http.js +++ b/javascript/node/selenium-webdriver/lib/http.js @@ -147,12 +147,15 @@ const Atom = { function post(path) { return resource('POST', path) } + function del(path) { return resource('DELETE', path) } + function get(path) { return resource('GET', path) } + function resource(method, path) { return { method: method, path: path } } diff --git a/javascript/node/selenium-webdriver/lib/select.js b/javascript/node/selenium-webdriver/lib/select.js index 7f2b449381c52..6d24a3bd64063 100644 --- a/javascript/node/selenium-webdriver/lib/select.js +++ b/javascript/node/selenium-webdriver/lib/select.js @@ -161,9 +161,9 @@ class Select { * * const selectBox = await driver.findElement(By.id("selectbox")); await selectObject.selectByIndex(1); diff --git a/javascript/node/selenium-webdriver/lib/test/build.js b/javascript/node/selenium-webdriver/lib/test/build.js index f3a83f0028946..b9fd43327fb28 100644 --- a/javascript/node/selenium-webdriver/lib/test/build.js +++ b/javascript/node/selenium-webdriver/lib/test/build.js @@ -133,7 +133,8 @@ exports.isDevMode = isDevMode * @return {!Build} The new build. * @throws {Error} If not running in dev mode. */ -exports.of = function (var_args) { // eslint-disable-line +exports.of = function (var_args) { + // eslint-disable-line let targets = Array.prototype.slice.call(arguments, 0) return new Build(targets) } diff --git a/javascript/node/selenium-webdriver/lib/test/data/actions/click.html b/javascript/node/selenium-webdriver/lib/test/data/actions/click.html index 403ff9c3f8fdf..b67752fecd841 100644 --- a/javascript/node/selenium-webdriver/lib/test/data/actions/click.html +++ b/javascript/node/selenium-webdriver/lib/test/data/actions/click.html @@ -1,24 +1,31 @@
diff --git a/javascript/node/selenium-webdriver/lib/test/data/actions/drag.html b/javascript/node/selenium-webdriver/lib/test/data/actions/drag.html index ccbc95b860d38..c556a4b7d91f7 100644 --- a/javascript/node/selenium-webdriver/lib/test/data/actions/drag.html +++ b/javascript/node/selenium-webdriver/lib/test/data/actions/drag.html @@ -1,77 +1,90 @@ -
-
-
-
-
-
- + document.body.addEventListener('mouseup', function() { + mouseDown = false + }) + diff --git a/javascript/node/selenium-webdriver/lib/test/data/actions/record_click.html b/javascript/node/selenium-webdriver/lib/test/data/actions/record_click.html index f47e11fb566b3..144300b37d728 100644 --- a/javascript/node/selenium-webdriver/lib/test/data/actions/record_click.html +++ b/javascript/node/selenium-webdriver/lib/test/data/actions/record_click.html @@ -1,21 +1,22 @@ - +
diff --git a/javascript/node/selenium-webdriver/lib/test/fileserver.js b/javascript/node/selenium-webdriver/lib/test/fileserver.js index 82b010549e476..73137c1fd6a5c 100644 --- a/javascript/node/selenium-webdriver/lib/test/fileserver.js +++ b/javascript/node/selenium-webdriver/lib/test/fileserver.js @@ -38,6 +38,7 @@ const jsDirectory = resources.locate('javascript') const Pages = (function () { let pages = {} + function addPage(page, path) { pages.__defineGetter__(page, function () { return exports.whereIs(path) diff --git a/javascript/node/selenium-webdriver/lib/virtual_authenticator.js b/javascript/node/selenium-webdriver/lib/virtual_authenticator.js index 641db27437e8a..e93e8e2a2a18f 100644 --- a/javascript/node/selenium-webdriver/lib/virtual_authenticator.js +++ b/javascript/node/selenium-webdriver/lib/virtual_authenticator.js @@ -128,6 +128,14 @@ class Credential { this._signCount = signCount } + static createResidentCredential(id, rpId, userHandle, privateKey, signCount) { + return new Credential(id, true, rpId, userHandle, privateKey, signCount) + } + + static createNonResidentCredential(id, rpId, privateKey, signCount) { + return new Credential(id, false, rpId, null, privateKey, signCount) + } + id() { return this._id } @@ -169,10 +177,6 @@ class Credential { return new Credential(id, true, rpId, userHandle, privateKey, signCount) } - static createResidentCredential(id, rpId, userHandle, privateKey, signCount) { - return new Credential(id, true, rpId, userHandle, privateKey, signCount) - } - /** * Creates a non-resident (i.e. stateless) credential. * @param id Unique base64 encoded string. @@ -186,10 +190,6 @@ class Credential { return new Credential(id, false, rpId, null, privateKey, signCount) } - static createNonResidentCredential(id, rpId, privateKey, signCount) { - return new Credential(id, false, rpId, null, privateKey, signCount) - } - toDict() { let credentialData = { credentialId: Buffer.from(this._id).toString('base64url'), diff --git a/javascript/node/selenium-webdriver/lib/webdriver.js b/javascript/node/selenium-webdriver/lib/webdriver.js index f6216808bd51a..9489f9543b711 100644 --- a/javascript/node/selenium-webdriver/lib/webdriver.js +++ b/javascript/node/selenium-webdriver/lib/webdriver.js @@ -461,7 +461,7 @@ class IWebDriver { condition, // eslint-disable-line timeout = undefined, // eslint-disable-line message = undefined, // eslint-disable-line - pollTimeout = undefined // eslint-disable-line + pollTimeout = undefined, // eslint-disable-line ) {} /** @@ -887,6 +887,7 @@ class WebDriver { } const driver = this + function evaluateCondition() { return new Promise((resolve, reject) => { try { @@ -1379,6 +1380,7 @@ class WebDriver { null, ) } + /** * * @param connection @@ -1966,6 +1968,7 @@ class Options { let cmd = new command.Command(command.Name.SET_TIMEOUT) let valid = false + function setParam(key, value) { if (value === null || typeof value === 'number') { valid = true @@ -1974,6 +1977,7 @@ class Options { throw TypeError('invalid timeouts configuration:' + ` expected "${key}" to be a number, got ${typeof value}`) } } + setParam('implicit', implicit) setParam('pageLoad', pageLoad) setParam('script', script) @@ -2854,6 +2858,7 @@ class WebElement { getAccessibleName() { return this.execute_(new command.Command(command.Name.GET_COMPUTED_LABEL)) } + /** * Returns an object describing an element's location, in pixels relative to * the document element, and the element's size in pixels. diff --git a/javascript/node/selenium-webdriver/test/bidi/add_intercept_parameters_test.js b/javascript/node/selenium-webdriver/test/bidi/add_intercept_parameters_test.js index 08405aafe0f0b..c782177d4ba9f 100644 --- a/javascript/node/selenium-webdriver/test/bidi/add_intercept_parameters_test.js +++ b/javascript/node/selenium-webdriver/test/bidi/add_intercept_parameters_test.js @@ -19,22 +19,19 @@ const assert = require('assert') const firefox = require('../../firefox') -const {Browser, By, WebElement} = require('../../') +const { Browser, By, WebElement } = require('../../') const { suite } = require('../../lib/test') const Network = require('../../bidi/network') -const {AddInterceptParameters} = require("../../bidi/addInterceptParameters"); -const {InterceptPhase} = require("../../bidi/interceptPhase"); -const {UrlPattern} = require("../../bidi/urlPattern"); +const { AddInterceptParameters } = require('../../bidi/addInterceptParameters') +const { InterceptPhase } = require('../../bidi/interceptPhase') +const { UrlPattern } = require('../../bidi/urlPattern') suite( function (env) { let driver beforeEach(async function () { - driver = await env - .builder() - .setFirefoxOptions(new firefox.Options().enableBidi()) - .build() + driver = await env.builder().setFirefoxOptions(new firefox.Options().enableBidi()).build() }) afterEach(async function () { @@ -51,35 +48,38 @@ suite( xit('can add intercept phases', async function () { const network = await Network(driver) const intercept = await network.addIntercept( - new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED, InterceptPhase.BEFORE_REQUEST_SENT)) + new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED, InterceptPhase.BEFORE_REQUEST_SENT), + ) assert.notEqual(intercept, null) }) xit('can add string url pattern', async function () { const network = await Network(driver) const intercept = await network.addIntercept( - new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT).urlStringPattern('http://localhost:4444/basicAuth')) + new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT).urlStringPattern( + 'http://localhost:4444/basicAuth', + ), + ) assert.notEqual(intercept, null) }) xit('can add string url patterns', async function () { const network = await Network(driver) const intercept = await network.addIntercept( - new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT) - .urlStringPatterns(['http://localhost:4444/basicAuth', 'http://localhost:4445/logEntryAdded'])) + new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT).urlStringPatterns([ + 'http://localhost:4444/basicAuth', + 'http://localhost:4445/logEntryAdded', + ]), + ) assert.notEqual(intercept, null) }) xit('can add url pattern', async function () { const network = await Network(driver) - const urlPattern = new UrlPattern() - .protocol('http') - .hostname('localhost') - .port(4444) - .pathname('basicAuth') + const urlPattern = new UrlPattern().protocol('http').hostname('localhost').port(4444).pathname('basicAuth') const intercept = await network.addIntercept( - new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT) - .urlPattern(urlPattern)) + new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT).urlPattern(urlPattern), + ) assert.notEqual(intercept, null) }) @@ -100,12 +100,11 @@ suite( .search('auth') const intercept = await network.addIntercept( - new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT) - .urlPatterns([urlPattern1, urlPattern2])) + new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT).urlPatterns([urlPattern1, urlPattern2]), + ) assert.notEqual(intercept, null) }) - }) }, - {browsers: [Browser.FIREFOX]} + { browsers: [Browser.FIREFOX] }, ) diff --git a/javascript/node/selenium-webdriver/test/bidi/network_commands_test.js b/javascript/node/selenium-webdriver/test/bidi/network_commands_test.js index 3138ae9b14fbf..c38a122bc0d30 100644 --- a/javascript/node/selenium-webdriver/test/bidi/network_commands_test.js +++ b/javascript/node/selenium-webdriver/test/bidi/network_commands_test.js @@ -19,12 +19,12 @@ const assert = require('assert') const firefox = require('../../firefox') -const {Browser, By, WebElement} = require('../../') +const { Browser, By, WebElement } = require('../../') const { Pages, suite } = require('../../lib/test') const Network = require('../../bidi/network') -const {AddInterceptParameters} = require("../../bidi/addInterceptParameters"); -const {InterceptPhase} = require("../../bidi/interceptPhase"); -const {until} = require("../../index"); +const { AddInterceptParameters } = require('../../bidi/addInterceptParameters') +const { InterceptPhase } = require('../../bidi/interceptPhase') +const { until } = require('../../index') suite( function (env) { @@ -32,10 +32,7 @@ suite( let network beforeEach(async function () { - driver = await env - .builder() - .setFirefoxOptions(new firefox.Options().enableBidi()) - .build() + driver = await env.builder().setFirefoxOptions(new firefox.Options().enableBidi()).build() network = await Network(driver) }) @@ -63,7 +60,7 @@ suite( await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED)) await network.authRequired(async (event) => { - await network.continueWithAuth(event.request.request, 'genie','bottle') + await network.continueWithAuth(event.request.request, 'genie', 'bottle') }) await driver.get(Pages.basicAuth) @@ -96,12 +93,12 @@ suite( }) try { const alert = await driver.wait(until.alertIsPresent(), 3000) - assert.fail("Alert should not be present") + assert.fail('Alert should not be present') } catch (e) { assert.strictEqual(e.name, 'TimeoutError') } }) }) }, - {browsers: [Browser.FIREFOX]}, + { browsers: [Browser.FIREFOX] }, ) diff --git a/javascript/node/selenium-webdriver/test/bidi/network_test.js b/javascript/node/selenium-webdriver/test/bidi/network_test.js index aa4b12dac8e3a..0bc8077b7cc1b 100644 --- a/javascript/node/selenium-webdriver/test/bidi/network_test.js +++ b/javascript/node/selenium-webdriver/test/bidi/network_test.js @@ -19,8 +19,8 @@ const assert = require('assert') const firefox = require('../../firefox') -const {Browser} = require('../../') -const {Pages, suite} = require('../../lib/test') +const { Browser } = require('../../') +const { Pages, suite } = require('../../lib/test') const Network = require('../../bidi/network') const until = require('../../lib/until') @@ -217,5 +217,5 @@ suite( }) }) }, - {browsers: [Browser.FIREFOX]}, + { browsers: [Browser.FIREFOX] }, ) diff --git a/javascript/node/selenium-webdriver/test/execute_script_test.js b/javascript/node/selenium-webdriver/test/execute_script_test.js index 2b88be8b57b96..16af3a4029616 100644 --- a/javascript/node/selenium-webdriver/test/execute_script_test.js +++ b/javascript/node/selenium-webdriver/test/execute_script_test.js @@ -280,10 +280,12 @@ suite(function (env) { var input = ['fa', 'fe', 'fi'] return execute(function (thearray) { var ret = [] + function build_response(thearray, ret) { ret.push(thearray.shift()) return (!thearray.length && ret) || build_response(thearray, ret) } + return build_response(thearray, ret) }, input).then(verifyJson(input)) }) @@ -294,11 +296,13 @@ suite(function (env) { } return execute(function (thing) { var ret = [] + function build_response(thing, ret) { var item = thing.words.shift() ret.push(item.word) return (!thing.words.length && ret) || build_response(thing, ret) } + return build_response(thing, ret) }, input).then(verifyJson(['fa', 'fe', 'fi'])) }) diff --git a/javascript/node/selenium-webdriver/test/lib/promise_test.js b/javascript/node/selenium-webdriver/test/lib/promise_test.js index 2fb93d98c01fa..757b1950d99a5 100644 --- a/javascript/node/selenium-webdriver/test/lib/promise_test.js +++ b/javascript/node/selenium-webdriver/test/lib/promise_test.js @@ -58,7 +58,9 @@ describe('promise', function () { const x = new Promise(v, v) const p = createRejectedPromise('reject') const q = Promise.resolve('resolved') - const t = { then() {} } + const t = { + then() {}, + } const f = () => {} f.then = () => {} assert.equal(true, promise.isPromise(x)) @@ -96,6 +98,7 @@ describe('promise', function () { function runTest(value) { return promise.fullyResolved(value).then((resolved) => assert.strictEqual(value, resolved)) } + return runTest(true) .then(() => runTest(function () {})) .then(() => runTest(null)) @@ -245,6 +248,7 @@ describe('promise', function () { function Foo() { this.bar = 'baz' } + var foo = new Foo() return promise.fullyResolved(foo).then(function (resolvedFoo) { diff --git a/javascript/node/selenium-webdriver/test/lib/testutil.js b/javascript/node/selenium-webdriver/test/lib/testutil.js index aceac6d5495e0..b89d0f8d55868 100644 --- a/javascript/node/selenium-webdriver/test/lib/testutil.js +++ b/javascript/node/selenium-webdriver/test/lib/testutil.js @@ -26,6 +26,7 @@ class StubError extends Error { this.name = this.constructor.name } } + exports.StubError = StubError exports.throwStubError = function () { @@ -77,6 +78,7 @@ function callbackPair(cb, eb) { assertNeither, } } + exports.callbackPair = callbackPair exports.callbackHelper = function (cb) { diff --git a/javascript/node/selenium-webdriver/test/lib/webdriver_test.js b/javascript/node/selenium-webdriver/test/lib/webdriver_test.js index d59909acf5985..9ca6a88e96359 100644 --- a/javascript/node/selenium-webdriver/test/lib/webdriver_test.js +++ b/javascript/node/selenium-webdriver/test/lib/webdriver_test.js @@ -991,10 +991,12 @@ describe('WebDriver', function () { let executor = new FakeExecutor() let driver = executor.createDriver() let count = 0 + function condition() { count++ return true } + return driver.wait(condition, 1).then(() => assert.strictEqual(1, count)) }) @@ -1002,9 +1004,11 @@ describe('WebDriver', function () { let executor = new FakeExecutor() let driver = executor.createDriver() let count = 0 + function condition() { return ++count === 3 } + return driver.wait(condition, 250).then(() => assert.strictEqual(3, count)) }) @@ -1013,6 +1017,7 @@ describe('WebDriver', function () { let driver = executor.createDriver() let count = 0 + function condition() { count += 1 return new Promise((resolve) => { @@ -1028,6 +1033,7 @@ describe('WebDriver', function () { let driver = executor.createDriver() let count = 0 + function condition() { count += 1 return new Promise((resolve) => { @@ -1047,9 +1053,11 @@ describe('WebDriver', function () { it('fails if condition returns a rejected promise', function () { let executor = new FakeExecutor() let driver = executor.createDriver() + function condition() { return new Promise((_, reject) => reject(new StubError())) } + return driver.wait(condition, 0, 'goes boom').then(fail, assertIsStubError) }) diff --git a/javascript/node/selenium-webdriver/testing/index.js b/javascript/node/selenium-webdriver/testing/index.js index cee6028c4c480..e379d14aa3551 100644 --- a/javascript/node/selenium-webdriver/testing/index.js +++ b/javascript/node/selenium-webdriver/testing/index.js @@ -72,15 +72,19 @@ TargetBrowser.prototype.platform function color(c, s) { return isatty(process.stdout) ? `\u001b[${c}m${s}\u001b[0m` : s } + function green(s) { return color(32, s) } + function cyan(s) { return color(36, s) } + function info(msg) { console.info(`${green('[INFO]')} ${msg}`) } + function warn(msg) { console.warn(`${cyan('[WARNING]')} ${msg}`) } @@ -396,6 +400,7 @@ function suite(fn, options = undefined) { seleniumServer = new remote.SeleniumServer(seleniumJar) const startTimeout = 65 * 1000 + // eslint-disable-next-line no-inner-declarations function startSelenium() { if (typeof this.timeout === 'function') {