webdriverio 8.33.0 → 9.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +1 -1
  2. package/build/cjs/package.json +3 -1
  3. package/build/commands/browser/$$.d.ts.map +1 -1
  4. package/build/commands/browser/$$.js +25 -0
  5. package/build/commands/browser/$.d.ts.map +1 -1
  6. package/build/commands/browser/$.js +25 -1
  7. package/build/commands/browser/getPuppeteer.d.ts +1 -1
  8. package/build/commands/browser/getPuppeteer.d.ts.map +1 -1
  9. package/build/commands/browser/getPuppeteer.js +6 -1
  10. package/build/commands/browser/getWindowSize.d.ts.map +1 -1
  11. package/build/commands/browser/getWindowSize.js +0 -3
  12. package/build/commands/browser/keys.d.ts.map +1 -1
  13. package/build/commands/browser/keys.js +2 -8
  14. package/build/commands/browser/mock.d.ts +2 -2
  15. package/build/commands/browser/mock.d.ts.map +1 -1
  16. package/build/commands/browser/mock.js +3 -1
  17. package/build/commands/browser/saveScreenshot.d.ts +4 -4
  18. package/build/commands/browser/saveScreenshot.js +4 -4
  19. package/build/commands/browser/setTimeout.d.ts.map +1 -1
  20. package/build/commands/browser/setTimeout.js +0 -11
  21. package/build/commands/browser/setWindowSize.d.ts.map +1 -1
  22. package/build/commands/browser/setWindowSize.js +0 -3
  23. package/build/commands/browser/url.d.ts.map +1 -1
  24. package/build/commands/browser/url.js +2 -1
  25. package/build/commands/element/addValue.d.ts.map +1 -1
  26. package/build/commands/element/addValue.js +1 -5
  27. package/build/commands/element/click.d.ts +1 -1
  28. package/build/commands/element/click.d.ts.map +1 -1
  29. package/build/commands/element/click.js +70 -59
  30. package/build/commands/element/doubleClick.d.ts.map +1 -1
  31. package/build/commands/element/doubleClick.js +0 -7
  32. package/build/commands/element/dragAndDrop.d.ts.map +1 -1
  33. package/build/commands/element/dragAndDrop.js +0 -10
  34. package/build/commands/element/getLocation.js +3 -8
  35. package/build/commands/element/getProperty.d.ts +1 -1
  36. package/build/commands/element/getProperty.d.ts.map +1 -1
  37. package/build/commands/element/getProperty.js +1 -7
  38. package/build/commands/element/getSize.js +1 -3
  39. package/build/commands/element/isDisplayed.d.ts +23 -1
  40. package/build/commands/element/isDisplayed.d.ts.map +1 -1
  41. package/build/commands/element/isDisplayed.js +34 -6
  42. package/build/commands/element/moveTo.d.ts.map +1 -1
  43. package/build/commands/element/moveTo.js +0 -3
  44. package/build/commands/element/waitForDisplayed.d.ts +8 -7
  45. package/build/commands/element/waitForDisplayed.d.ts.map +1 -1
  46. package/build/commands/element/waitForDisplayed.js +9 -8
  47. package/build/commands/element.d.ts +0 -1
  48. package/build/commands/element.d.ts.map +1 -1
  49. package/build/commands/element.js +0 -1
  50. package/build/constants.d.ts +0 -1
  51. package/build/constants.d.ts.map +1 -1
  52. package/build/constants.js +0 -17
  53. package/build/index.d.ts +3 -1
  54. package/build/index.d.ts.map +1 -1
  55. package/build/index.js +3 -0
  56. package/build/protocol-stub.d.ts +1 -2
  57. package/build/protocol-stub.d.ts.map +1 -1
  58. package/build/protocol-stub.js +3 -4
  59. package/build/scripts/customElement.d.ts +2 -0
  60. package/build/scripts/customElement.d.ts.map +1 -0
  61. package/build/scripts/customElement.js +16 -0
  62. package/build/scripts/isDescendant.d.ts +2 -0
  63. package/build/scripts/isDescendant.d.ts.map +1 -0
  64. package/build/scripts/isDescendant.js +3 -0
  65. package/build/shadowRoot.d.ts +34 -0
  66. package/build/shadowRoot.d.ts.map +1 -0
  67. package/build/shadowRoot.js +124 -0
  68. package/build/types.d.ts +9 -8
  69. package/build/types.d.ts.map +1 -1
  70. package/build/utils/actions/pointer.d.ts +7 -2
  71. package/build/utils/actions/pointer.d.ts.map +1 -1
  72. package/build/utils/actions/pointer.js +22 -6
  73. package/build/utils/driver.d.ts +11 -3
  74. package/build/utils/driver.d.ts.map +1 -1
  75. package/build/utils/driver.js +19 -27
  76. package/build/utils/getElementObject.d.ts.map +1 -1
  77. package/build/utils/getElementObject.js +3 -0
  78. package/build/utils/index.d.ts +35 -1
  79. package/build/utils/index.d.ts.map +1 -1
  80. package/build/utils/index.js +166 -7
  81. package/build/utils/interception/devtools.d.ts +4 -5
  82. package/build/utils/interception/devtools.d.ts.map +1 -1
  83. package/build/utils/interception/index.d.ts +4 -5
  84. package/build/utils/interception/index.d.ts.map +1 -1
  85. package/build/utils/interception/types.d.ts +2 -1
  86. package/build/utils/interception/types.d.ts.map +1 -1
  87. package/package.json +13 -16
  88. package/build/commands/element/isDisplayedInViewport.d.ts +0 -53
  89. package/build/commands/element/isDisplayedInViewport.d.ts.map +0 -1
  90. package/build/commands/element/isDisplayedInViewport.js +0 -64
package/README.md CHANGED
@@ -3,7 +3,7 @@ WebdriverIO
3
3
 
4
4
  > Next-gen browser and mobile automation test framework for Node.js
5
5
 
6
- This package provides an easy-to-manage API and a lot of syntactical sugar on top of the WebDriver specification. You can use WebdriverIO as a standalone package or via a test runner using [`@wdio/cli`](https://webdriver.io/docs/clioptions). WebdriverIO allows you to run tests locally using the WebDriver or Chrome DevTools protocol as well as remote user agents using cloud providers like [Sauce Labs](https://saucelabs.com/).
6
+ This package provides an easy-to-manage API and a lot of syntactical sugar on top of the WebDriver specification. You can use WebdriverIO as a standalone package or via a test runner using [`@wdio/cli`](https://webdriver.io/docs/clioptions). WebdriverIO allows you to run tests locally using the WebDriver as well as remote user agents using cloud providers like [Sauce Labs](https://saucelabs.com/).
7
7
 
8
8
  ## Installation
9
9
 
@@ -1,3 +1,5 @@
1
1
  {
2
- "type": "commonjs"
2
+ "name": "webdriverio-cjs",
3
+ "type": "commonjs",
4
+ "private": true
3
5
  }
@@ -1 +1 @@
1
- {"version":3,"file":"$$.d.ts","sourceRoot":"","sources":["../../../src/commands/browser/$$.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAIvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAsB,EAAE,CACpB,IAAI,EAAE,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,OAAO,EAC/C,QAAQ,EAAE,QAAQ,GAAG,gBAAgB,EAAE,GAAG,WAAW,CAAC,OAAO,EAAE,GAAG,WAAW,EAAE,qCAmBlF"}
1
+ {"version":3,"file":"$$.d.ts","sourceRoot":"","sources":["../../../src/commands/browser/$$.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAMvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAsB,EAAE,CACpB,IAAI,EAAE,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,OAAO,EAC/C,QAAQ,EAAE,QAAQ,GAAG,gBAAgB,EAAE,GAAG,WAAW,CAAC,OAAO,EAAE,GAAG,WAAW,EAAE,GAChF,OAAO,CAAC,WAAW,CAAC,YAAY,CAAC,CA2CnC"}
@@ -1,5 +1,7 @@
1
1
  import { findElements, enhanceElementsArray, isElement, findElement } from '../../utils/index.js';
2
2
  import { getElements } from '../../utils/getElementObject.js';
3
+ import { findDeepElements } from '../../utils/index.js';
4
+ import { DEEP_SELECTOR } from '../../constants.js';
3
5
  /**
4
6
  * The `$$` command is a short and handy way in order to fetch multiple elements on the page.
5
7
  * It returns a `ChainablePromiseArray` containing a set of WebdriverIO elements.
@@ -41,6 +43,29 @@ import { getElements } from '../../utils/getElementObject.js';
41
43
  *
42
44
  */
43
45
  export async function $$(selector) {
46
+ /**
47
+ * do a deep lookup if
48
+ * - we are using Bidi
49
+ * - have a string selector
50
+ * - that is not a deep selector
51
+ */
52
+ if (this.isBidi && typeof selector === 'string' && !selector.startsWith(DEEP_SELECTOR)) {
53
+ /**
54
+ * run this in Node.js land if we are using browser runner
55
+ */
56
+ if (globalThis.wdio?.execute) {
57
+ const command = '$$';
58
+ const res = 'elementId' in this
59
+ ? await globalThis.wdio.executeWithScope(command, this.elementId, selector)
60
+ : await globalThis.wdio.execute(command, selector);
61
+ const elements = await getElements.call(this, selector, res);
62
+ return enhanceElementsArray(elements, this, selector);
63
+ }
64
+ const res = await findDeepElements.call(this, selector);
65
+ const elements = await getElements.call(this, selector, res);
66
+ const a = enhanceElementsArray(elements, this, selector);
67
+ return a;
68
+ }
44
69
  let res = Array.isArray(selector)
45
70
  ? selector
46
71
  : await findElements.call(this, selector);
@@ -1 +1 @@
1
- {"version":3,"file":"$.d.ts","sourceRoot":"","sources":["../../../src/commands/browser/$.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AACH,wBAAsB,CAAC,CACnB,IAAI,EAAE,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,OAAO,EAC/C,QAAQ,EAAE,QAAQ,GACnB,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAc9B"}
1
+ {"version":3,"file":"$.d.ts","sourceRoot":"","sources":["../../../src/commands/browser/$.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AACH,wBAAsB,CAAC,CACnB,IAAI,EAAE,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,OAAO,EAC/C,QAAQ,EAAE,QAAQ,GACnB,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAuC9B"}
@@ -1,6 +1,7 @@
1
1
  import { ELEMENT_KEY } from 'webdriver';
2
- import { findElement } from '../../utils/index.js';
2
+ import { findElement, findDeepElement } from '../../utils/index.js';
3
3
  import { getElement } from '../../utils/getElementObject.js';
4
+ import { DEEP_SELECTOR } from '../../constants.js';
4
5
  /**
5
6
  * The `$` command is a short and handy way in order to fetch a single element on the page.
6
7
  *
@@ -61,6 +62,29 @@ import { getElement } from '../../utils/getElementObject.js';
61
62
  *
62
63
  */
63
64
  export async function $(selector) {
65
+ /**
66
+ * do a deep lookup if
67
+ * - we are using Bidi
68
+ * - have a string selector
69
+ * - that is not a deep selector
70
+ */
71
+ if (this.isBidi && typeof selector === 'string' && !selector.startsWith(DEEP_SELECTOR)) {
72
+ /**
73
+ * run this in Node.js land if we are using browser runner
74
+ */
75
+ if (globalThis.wdio) {
76
+ /**
77
+ * `res` is an element reference as we strip down the element
78
+ * result to its element id
79
+ */
80
+ const res = 'elementId' in this
81
+ ? await globalThis.wdio.executeWithScope('$', this.elementId, selector)
82
+ : await globalThis.wdio.execute('$', selector);
83
+ return getElement.call(this, selector, res);
84
+ }
85
+ const res = await findDeepElement.call(this, selector);
86
+ return getElement.call(this, selector, res);
87
+ }
64
88
  /**
65
89
  * convert protocol result into WebdriverIO element
66
90
  * e.g. when element was fetched with `getActiveElement`
@@ -1,4 +1,4 @@
1
- import type { Browser as PuppeteerBrowser } from 'puppeteer-core/lib/esm/puppeteer/api/Browser.js';
1
+ import type { Browser as PuppeteerBrowser } from 'puppeteer-core';
2
2
  /**
3
3
  * Get the [Puppeteer Browser instance](https://pptr.dev/#?product=Puppeteer&version=v5.1.0&show=api-class-browser)
4
4
  * to run commands with Puppeteer. Note that all Puppeteer commands are
@@ -1 +1 @@
1
- {"version":3,"file":"getPuppeteer.d.ts","sourceRoot":"","sources":["../../../src/commands/browser/getPuppeteer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,iDAAiD,CAAA;AAOlG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAsB,YAAY,CAAE,IAAI,EAAE,WAAW,CAAC,OAAO,6BAgG5D"}
1
+ {"version":3,"file":"getPuppeteer.d.ts","sourceRoot":"","sources":["../../../src/commands/browser/getPuppeteer.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAa,OAAO,IAAI,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAM5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAsB,YAAY,CAAE,IAAI,EAAE,WAAW,CAAC,OAAO,6BAyG5D"}
@@ -1,5 +1,5 @@
1
- import puppeteer from 'puppeteer-core';
2
1
  import logger from '@wdio/logger';
2
+ import { userImport } from '@wdio/utils';
3
3
  import { FF_REMOTE_DEBUG_ARG } from '../../constants.js';
4
4
  const log = logger('webdriverio');
5
5
  /**
@@ -38,6 +38,11 @@ const log = logger('webdriverio');
38
38
  * @return {PuppeteerBrowser} initiated puppeteer instance connected to the browser
39
39
  */
40
40
  export async function getPuppeteer() {
41
+ const puppeteer = await userImport('puppeteer-core');
42
+ if (!puppeteer) {
43
+ throw new Error('You need to install "puppeteer-core" package as a dependency ' +
44
+ 'in order to use the "getPuppeteer" method');
45
+ }
41
46
  /**
42
47
  * check if we already connected Puppeteer and if so return
43
48
  * that instance
@@ -1 +1 @@
1
- {"version":3,"file":"getWindowSize.d.ts","sourceRoot":"","sources":["../../../src/commands/browser/getWindowSize.ts"],"names":[],"mappings":"AAEA,UAAU,WAAW;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC,OAAO,wBAS5D"}
1
+ {"version":3,"file":"getWindowSize.d.ts","sourceRoot":"","sources":["../../../src/commands/browser/getWindowSize.ts"],"names":[],"mappings":"AAEA,UAAU,WAAW;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC,OAAO,wBAK5D"}
@@ -19,9 +19,6 @@ import { getBrowserObject } from '../../utils/index.js';
19
19
  */
20
20
  export async function getWindowSize() {
21
21
  const browser = getBrowserObject(this);
22
- if (!browser.isW3C) {
23
- return browser._getWindowSize();
24
- }
25
22
  const { width, height } = await browser.getWindowRect();
26
23
  return { width, height };
27
24
  }
@@ -1 +1 @@
1
- {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../../src/commands/browser/keys.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,IAAI,CACtB,IAAI,EAAE,WAAW,CAAC,OAAO,EACzB,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,iBAyC3B"}
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../../src/commands/browser/keys.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,IAAI,CACtB,IAAI,EAAE,WAAW,CAAC,OAAO,EACzB,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,iBAkC3B"}
@@ -26,23 +26,17 @@ export async function keys(value) {
26
26
  * replace key with corresponding unicode character
27
27
  */
28
28
  if (typeof value === 'string') {
29
- keySequence = checkUnicode(value, this.isDevTools);
29
+ keySequence = checkUnicode(value);
30
30
  }
31
31
  else if (Array.isArray(value)) {
32
32
  const charArray = value;
33
33
  for (const charSet of charArray) {
34
- keySequence = keySequence.concat(checkUnicode(charSet, this.isDevTools));
34
+ keySequence = keySequence.concat(checkUnicode(charSet));
35
35
  }
36
36
  }
37
37
  else {
38
38
  throw new Error('"keys" command requires a string or array of strings as parameter');
39
39
  }
40
- /**
41
- * JsonWireProtocol action
42
- */
43
- if (!this.isW3C) {
44
- return this.sendKeys(keySequence);
45
- }
46
40
  /**
47
41
  * W3C way of handle it key actions
48
42
  */
@@ -1,7 +1,7 @@
1
- import type Interception from '../../utils/interception/index.js';
1
+ import type { CDPSession } from 'puppeteer-core';
2
2
  import type { Mock } from '../../types.js';
3
3
  import type { MockFilterOptions } from '../../utils/interception/types.js';
4
- import type { CDPSession } from 'puppeteer-core/lib/esm/puppeteer/common/Connection.js';
4
+ import type Interception from '../../utils/interception/index.js';
5
5
  export declare const SESSION_MOCKS: Record<string, Set<Interception>>;
6
6
  export declare const CDP_SESSIONS: Record<string, CDPSession>;
7
7
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../../src/commands/browser/mock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,YAAY,MAAM,mCAAmC,CAAA;AAIjE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAA;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uDAAuD,CAAA;AAEvF,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,YAAY,CAAC,CAAM,CAAA;AAClE,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAM,CAAA;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyGG;AACH,wBAAsB,IAAI,CACtB,IAAI,EAAE,WAAW,CAAC,OAAO,EACzB,GAAG,EAAE,MAAM,GAAG,MAAM,EACpB,aAAa,CAAC,EAAE,iBAAiB,iBA6DpC"}
1
+ {"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../../src/commands/browser/mock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAOhD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAA;AAC1E,OAAO,KAAK,YAAY,MAAM,mCAAmC,CAAA;AAEjE,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,YAAY,CAAC,CAAM,CAAA;AAClE,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAM,CAAA;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyGG;AACH,wBAAsB,IAAI,CACtB,IAAI,EAAE,WAAW,CAAC,OAAO,EACzB,GAAG,EAAE,MAAM,GAAG,MAAM,EACpB,aAAa,CAAC,EAAE,iBAAiB,iBA8DpC"}
@@ -147,7 +147,9 @@ export async function mock(url, filterOptions) {
147
147
  await client.send('Fetch.enable', {
148
148
  patterns: [{ requestStage: 'Request' }, { requestStage: 'Response' }]
149
149
  });
150
- client.on('Fetch.requestPaused', NetworkInterception
150
+ client.on('Fetch.requestPaused',
151
+ // @ts-expect-error fix me
152
+ NetworkInterception
151
153
  .handleRequestInterception(client, SESSION_MOCKS[handle]));
152
154
  }
153
155
  const networkInterception = new NetworkInterception(url, filterOptions, browser);
@@ -14,10 +14,10 @@
14
14
  *
15
15
  * When running from a hook, make sure to explicitly define the hook as async:
16
16
  * <example>
17
- :wdio.conf.js
18
- afterTest: async function(test) {
19
- await browser.saveScreenshot('./some/path/screenshot.png');
20
- }
17
+ :wdio.conf.js
18
+ afterTest: async function(test) {
19
+ await browser.saveScreenshot('./some/path/screenshot.png');
20
+ }
21
21
  * </example>
22
22
  * @alias browser.saveScreenshot
23
23
  * @param {String} filepath path to the generated image (`.png` suffix is required) relative to the execution directory
@@ -15,10 +15,10 @@ import { getAbsoluteFilepath, assertDirectoryExists } from '../../utils/index.js
15
15
  *
16
16
  * When running from a hook, make sure to explicitly define the hook as async:
17
17
  * <example>
18
- :wdio.conf.js
19
- afterTest: async function(test) {
20
- await browser.saveScreenshot('./some/path/screenshot.png');
21
- }
18
+ :wdio.conf.js
19
+ afterTest: async function(test) {
20
+ await browser.saveScreenshot('./some/path/screenshot.png');
21
+ }
22
22
  * </example>
23
23
  * @alias browser.saveScreenshot
24
24
  * @param {String} filepath path to the generated image (`.png` suffix is required) relative to the execution directory
@@ -1 +1 @@
1
- {"version":3,"file":"setTimeout.d.ts","sourceRoot":"","sources":["../../../src/commands/browser/setTimeout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,wBAAsB,UAAU,CAC5B,IAAI,EAAE,WAAW,CAAC,OAAO,EACzB,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,GAC5B,OAAO,CAAC,IAAI,CAAC,CAiCf"}
1
+ {"version":3,"file":"setTimeout.d.ts","sourceRoot":"","sources":["../../../src/commands/browser/setTimeout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,wBAAsB,UAAU,CAC5B,IAAI,EAAE,WAAW,CAAC,OAAO,EACzB,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,GAC5B,OAAO,CAAC,IAAI,CAAC,CAqBf"}
@@ -50,16 +50,5 @@ export async function setTimeout(timeouts) {
50
50
  const pageLoad = timeouts['page load'] || timeouts.pageLoad;
51
51
  const script = timeouts.script;
52
52
  const setTimeouts = this.setTimeouts.bind(this);
53
- /**
54
- * JsonWireProtocol action
55
- */
56
- if (!this.isW3C) {
57
- await Promise.all([
58
- isFinite(implicit) && setTimeouts('implicit', implicit),
59
- isFinite(pageLoad) && setTimeouts('page load', pageLoad),
60
- isFinite(script) && setTimeouts('script', script),
61
- ].filter(Boolean));
62
- return;
63
- }
64
53
  return setTimeouts(implicit, pageLoad, script);
65
54
  }
@@ -1 +1 @@
1
- {"version":3,"file":"setWindowSize.d.ts","sourceRoot":"","sources":["../../../src/commands/browser/setWindowSize.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,aAAa,CAC/B,IAAI,EAAE,WAAW,CAAC,OAAO,EACzB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,iBAuBjB"}
1
+ {"version":3,"file":"setWindowSize.d.ts","sourceRoot":"","sources":["../../../src/commands/browser/setWindowSize.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,aAAa,CAC/B,IAAI,EAAE,WAAW,CAAC,OAAO,EACzB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,iBAmBjB"}
@@ -33,8 +33,5 @@ export async function setWindowSize(width, height) {
33
33
  throw new Error('setWindowSize expects width and height to be a number in the 0 to 2^31 − 1 range');
34
34
  }
35
35
  const browser = getBrowserObject(this);
36
- if (!browser.isW3C) {
37
- return browser._setWindowSize(width, height);
38
- }
39
36
  await browser.setWindowRect(null, null, width, height);
40
37
  }
@@ -1 +1 @@
1
- {"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../../../src/commands/browser/url.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAsB,GAAG,CACrB,IAAI,EAAE,WAAW,CAAC,OAAO,EACzB,IAAI,EAAE,MAAM,mBAoBf"}
1
+ {"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../../../src/commands/browser/url.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAsB,GAAG,CACrB,IAAI,EAAE,WAAW,CAAC,OAAO,EACzB,IAAI,EAAE,MAAM,mBAqBf"}
@@ -46,7 +46,8 @@ export async function url(path) {
46
46
  const context = await this.getWindowHandle();
47
47
  const res = await this.browsingContextNavigate({
48
48
  context,
49
- url: path
49
+ url: path,
50
+ wait: 'interactive'
50
51
  });
51
52
  return res.url;
52
53
  }
@@ -1 +1 @@
1
- {"version":3,"file":"addValue.d.ts","sourceRoot":"","sources":["../../../src/commands/element/addValue.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,QAAQ,CACpB,IAAI,EAAE,WAAW,CAAC,OAAO,EACzB,KAAK,EAAE,MAAM,GAAG,MAAM,iBAoBzB"}
1
+ {"version":3,"file":"addValue.d.ts","sourceRoot":"","sources":["../../../src/commands/element/addValue.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,QAAQ,CACpB,IAAI,EAAE,WAAW,CAAC,OAAO,EACzB,KAAK,EAAE,MAAM,GAAG,MAAM,iBAezB"}
@@ -36,9 +36,5 @@ export function addValue(value) {
36
36
  throw new Error('The setValue/addValue command only take string or number values. ' +
37
37
  'If you like to use special characters, use the "keys" command.');
38
38
  }
39
- if (this.isW3C) {
40
- return this.elementSendKeys(this.elementId, value.toString());
41
- }
42
- // @ts-expect-error command is not typed as JWP command
43
- return this.elementSendKeys(this.elementId, [value.toString()]);
39
+ return this.elementSendKeys(this.elementId, value.toString());
44
40
  }
@@ -78,5 +78,5 @@ import type { ClickOptions } from '../../types.js';
78
78
  * @param {number=} options.y Number (optional)
79
79
  * @param {boolean=} options.skipRelease Boolean (optional)
80
80
  */
81
- export declare function click(this: WebdriverIO.Element, options?: ClickOptions): Promise<void>;
81
+ export declare function click(this: WebdriverIO.Element, options?: Partial<ClickOptions>): Promise<void>;
82
82
  //# sourceMappingURL=click.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"click.d.ts","sourceRoot":"","sources":["../../../src/commands/element/click.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAIlD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8EG;AACH,wBAAsB,KAAK,CACvB,IAAI,EAAE,WAAW,CAAC,OAAO,EACzB,OAAO,CAAC,EAAE,YAAY,iBA+EzB"}
1
+ {"version":3,"file":"click.d.ts","sourceRoot":"","sources":["../../../src/commands/element/click.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAGlD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8EG;AACH,wBAAgB,KAAK,CACjB,IAAI,EAAE,WAAW,CAAC,OAAO,EACzB,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,iBAUlC"}
@@ -1,5 +1,6 @@
1
1
  import logger from '@wdio/logger';
2
2
  import { getBrowserObject } from '../../utils/index.js';
3
+ import { buttonValue } from '../../utils/actions/index.js';
3
4
  const log = logger('webdriver');
4
5
  /**
5
6
  *
@@ -80,72 +81,82 @@ const log = logger('webdriver');
80
81
  * @param {number=} options.y Number (optional)
81
82
  * @param {boolean=} options.skipRelease Boolean (optional)
82
83
  */
83
- export async function click(options) {
84
- if (typeof options === 'undefined') {
85
- return this.elementClick(this.elementId);
86
- }
87
- if (typeof options !== 'object' || Array.isArray(options)) {
88
- throw new TypeError('Options must be an object');
89
- }
90
- let button = (options.button || 0);
91
- const { x: xOffset = 0, y: yOffset = 0, skipRelease = false } = options || {};
92
- if (typeof xOffset !== 'number'
93
- || typeof yOffset !== 'number'
94
- || !Number.isInteger(xOffset)
95
- || !Number.isInteger(yOffset)) {
96
- throw new TypeError('Coordinates must be integers');
84
+ export function click(options) {
85
+ if (typeof options !== 'undefined') {
86
+ if (typeof options !== 'object' || Array.isArray(options)) {
87
+ throw new TypeError('Options must be an object');
88
+ }
89
+ return actionClick(this, options);
97
90
  }
98
- if (options.button === 'left') {
99
- button = 0;
91
+ return elementClick(this);
92
+ }
93
+ /**
94
+ * Workaround function, because sometimes browser.action().move() flaky and isn't able to scroll pointer to into view
95
+ * Moreover the action with 'nearest' behavior by default where element is aligned at the bottom of its ancestor.
96
+ * and could be overlapped. Scroll to center should definitely work even if element was covered with sticky header/footer
97
+ */
98
+ async function workaround(element) {
99
+ await element.scrollIntoView({ block: 'center', inline: 'center' });
100
+ }
101
+ async function elementClick(element) {
102
+ try {
103
+ return await element.elementClick(element.elementId);
100
104
  }
101
- if (options.button === 'middle') {
102
- button = 1;
105
+ catch (error) {
106
+ let err = error;
107
+ if (typeof error === 'string') {
108
+ err = new Error(error);
109
+ }
110
+ if (!err.message.includes('element click intercepted')) {
111
+ // we only apply the workaround when the click got intercepted
112
+ // so that the middleware can handle any other errors
113
+ throw err;
114
+ }
115
+ await workaround(element);
116
+ return element.elementClick(element.elementId);
103
117
  }
104
- if (options.button === 'right') {
105
- button = 2;
118
+ }
119
+ async function actionClick(element, options) {
120
+ const defaultOptions = {
121
+ button: 0,
122
+ x: 0,
123
+ y: 0,
124
+ skipRelease: false,
125
+ };
126
+ const { button, x, y, skipRelease } = { ...defaultOptions, ...options };
127
+ if (typeof x !== 'number'
128
+ || typeof y !== 'number'
129
+ || !Number.isInteger(x)
130
+ || !Number.isInteger(y)) {
131
+ throw new TypeError('Coordinates must be integers');
106
132
  }
107
- if (![0, 1, 2].includes(button)) {
133
+ if (!buttonValue.includes(button)) {
108
134
  throw new Error('Button type not supported.');
109
135
  }
110
- if (this.isW3C) {
111
- const browser = getBrowserObject(this);
112
- if (xOffset || yOffset) {
113
- const { width, height } = await browser.getElementRect(this.elementId);
114
- if ((xOffset && xOffset < (-Math.floor(width / 2))) || (xOffset && xOffset > Math.floor(width / 2))) {
115
- log.warn('xOffset would cause a out of bounds error as it goes outside of element');
116
- }
117
- if ((yOffset && yOffset < (-Math.floor(height / 2))) || (yOffset && yOffset > Math.floor(height / 2))) {
118
- log.warn('yOffset would cause a out of bounds error as it goes outside of element');
119
- }
120
- }
121
- const clickNested = async () => {
122
- await browser.action('pointer', {
123
- parameters: { pointerType: 'mouse' }
124
- })
125
- .move({
126
- origin: this,
127
- x: xOffset,
128
- y: yOffset
129
- })
130
- .down({ button })
131
- .up({ button })
132
- .perform(skipRelease);
133
- };
134
- try {
135
- await clickNested();
136
+ const browser = getBrowserObject(element);
137
+ if (x || y) {
138
+ const { width, height } = await browser.getElementRect(element.elementId);
139
+ if ((x && x < (-Math.floor(width / 2))) || (x && x > Math.floor(width / 2))) {
140
+ log.warn('x would cause a out of bounds error as it goes outside of element');
136
141
  }
137
- catch {
138
- /**
139
- * Workaround, because sometimes browser.action().move() flaky and isn't able to scroll pointer to into view
140
- * Moreover the action with 'nearest' behavior by default where element is aligned at the bottom of its ancestor.
141
- * and could be overlapped. Scroll to center should definitely work even if element was covered with sticky header/footer
142
- */
143
- await this.scrollIntoView({ block: 'center', inline: 'center' });
144
- await clickNested();
142
+ if ((y && y < (-Math.floor(height / 2))) || (y && y > Math.floor(height / 2))) {
143
+ log.warn('y would cause a out of bounds error as it goes outside of element');
145
144
  }
146
- return;
147
145
  }
148
- const { width, height } = await this.getElementSize(this.elementId);
149
- await this.moveToElement(this.elementId, xOffset + (width / 2), yOffset + (height / 2));
150
- return this.positionClick(button);
146
+ const clickNested = async () => {
147
+ await browser.action('pointer', {
148
+ parameters: { pointerType: 'mouse' }
149
+ })
150
+ .move({ origin: element, x, y })
151
+ .down({ button })
152
+ .up({ button })
153
+ .perform(skipRelease);
154
+ };
155
+ try {
156
+ return await clickNested();
157
+ }
158
+ catch {
159
+ await workaround(element);
160
+ return clickNested();
161
+ }
151
162
  }
@@ -1 +1 @@
1
- {"version":3,"file":"doubleClick.d.ts","sourceRoot":"","sources":["../../../src/commands/element/doubleClick.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,WAAW,CAAE,IAAI,EAAE,WAAW,CAAC,OAAO,iBAqB3D"}
1
+ {"version":3,"file":"doubleClick.d.ts","sourceRoot":"","sources":["../../../src/commands/element/doubleClick.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,WAAW,CAAE,IAAI,EAAE,WAAW,CAAC,OAAO,iBAa3D"}
@@ -23,13 +23,6 @@ import { getBrowserObject } from '../../utils/index.js';
23
23
  *
24
24
  */
25
25
  export async function doubleClick() {
26
- /**
27
- * move to element
28
- */
29
- if (!this.isW3C) {
30
- await this.moveTo();
31
- return this.positionDoubleClick();
32
- }
33
26
  /**
34
27
  * W3C way of handle the double click actions
35
28
  */
@@ -1 +1 @@
1
- {"version":3,"file":"dragAndDrop.d.ts","sourceRoot":"","sources":["../../../src/commands/element/dragAndDrop.ts"],"names":[],"mappings":"AASA,KAAK,kBAAkB,GAAG;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,KAAK,kBAAkB,GAAG;IACtB,CAAC,CAAC,EAAE,MAAM,CAAA;IACV,CAAC,CAAC,EAAE,MAAM,CAAA;CACb,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAsB,WAAW,CAC7B,IAAI,EAAE,WAAW,CAAC,OAAO,EACzB,MAAM,EAAE,WAAW,CAAC,OAAO,GAAG,kBAAkB,EAChD,EAAE,QAAa,EAAE,GAAE,kBAAuB,iBAmE7C"}
1
+ {"version":3,"file":"dragAndDrop.d.ts","sourceRoot":"","sources":["../../../src/commands/element/dragAndDrop.ts"],"names":[],"mappings":"AAOA,KAAK,kBAAkB,GAAG;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,KAAK,kBAAkB,GAAG;IACtB,CAAC,CAAC,EAAE,MAAM,CAAA;IACV,CAAC,CAAC,EAAE,MAAM,CAAA;CACb,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAsB,WAAW,CAC7B,IAAI,EAAE,WAAW,CAAC,OAAO,EACzB,MAAM,EAAE,WAAW,CAAC,OAAO,GAAG,kBAAkB,EAChD,EAAE,QAAa,EAAE,GAAE,kBAAuB,iBAuD7C"}
@@ -1,7 +1,6 @@
1
1
  import { ELEMENT_KEY } from 'webdriver';
2
2
  import { getBrowserObject } from '../../utils/index.js';
3
3
  const ACTION_BUTTON = 0;
4
- const sleep = (time = 0) => new Promise((resolve) => setTimeout(resolve, time));
5
4
  /**
6
5
  *
7
6
  * Drag an item to a destination element or position.
@@ -60,15 +59,6 @@ export async function dragAndDrop(target, { duration = 10 } = {}) {
60
59
  * allow to specify an element or an x/y vector
61
60
  */
62
61
  const isMovingToElement = target.constructor.name === 'Element';
63
- if (!this.isW3C) {
64
- await this.moveTo();
65
- await this.buttonDown(ACTION_BUTTON);
66
- isMovingToElement
67
- ? await moveToElement.moveTo()
68
- : await this.moveToElement(null, moveToCoordinates.x, moveToCoordinates.y);
69
- await sleep(duration);
70
- return this.buttonUp(ACTION_BUTTON);
71
- }
72
62
  const sourceRef = { [ELEMENT_KEY]: this[ELEMENT_KEY] };
73
63
  const targetRef = { [ELEMENT_KEY]: moveToElement[ELEMENT_KEY] };
74
64
  const origin = sourceRef;
@@ -28,14 +28,9 @@ import { getElementRect } from '../../utils/index.js';
28
28
  */
29
29
  export async function getLocation(prop) {
30
30
  let location = {};
31
- if (this.isW3C) {
32
- location = await getElementRect(this);
33
- delete location.width;
34
- delete location.height;
35
- }
36
- else {
37
- location = await this.getElementLocation(this.elementId);
38
- }
31
+ location = await getElementRect(this);
32
+ delete location.width;
33
+ delete location.height;
39
34
  if (prop === 'x' || prop === 'y') {
40
35
  return location[prop];
41
36
  }
@@ -14,5 +14,5 @@
14
14
  * @param {string} property name of the element property
15
15
  * @return {Object|String|Boolean|Number|null} the value of the property of the selected element
16
16
  */
17
- export declare function getProperty(this: WebdriverIO.Element, property: string): Promise<any>;
17
+ export declare function getProperty(this: WebdriverIO.Element, property: string): Promise<string>;
18
18
  //# sourceMappingURL=getProperty.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getProperty.d.ts","sourceRoot":"","sources":["../../../src/commands/element/getProperty.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CACvB,IAAI,EAAE,WAAW,CAAC,OAAO,EACzB,QAAQ,EAAE,MAAM,gBAYnB"}
1
+ {"version":3,"file":"getProperty.d.ts","sourceRoot":"","sources":["../../../src/commands/element/getProperty.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CACvB,IAAI,EAAE,WAAW,CAAC,OAAO,EACzB,QAAQ,EAAE,MAAM,mBAGnB"}
@@ -1,5 +1,3 @@
1
- import { getBrowserObject } from '../../utils/index.js';
2
- import getPropertyScript from '../../scripts/getProperty.js';
3
1
  /**
4
2
  * The Get Element Property command will return the result of getting a property of an element.
5
3
  *
@@ -17,9 +15,5 @@ import getPropertyScript from '../../scripts/getProperty.js';
17
15
  * @return {Object|String|Boolean|Number|null} the value of the property of the selected element
18
16
  */
19
17
  export function getProperty(property) {
20
- if (this.isW3C) {
21
- return this.getElementProperty(this.elementId, property);
22
- }
23
- const browser = getBrowserObject(this);
24
- return browser.execute(getPropertyScript, { ELEMENT: this.elementId }, property);
18
+ return this.getElementProperty(this.elementId, property);
25
19
  }
@@ -27,9 +27,7 @@ import { getElementRect } from '../../utils/index.js';
27
27
  *
28
28
  */
29
29
  export async function getSize(prop) {
30
- const rect = this.isW3C
31
- ? await getElementRect(this)
32
- : await this.getElementSize(this.elementId);
30
+ const rect = await getElementRect(this);
33
31
  if (prop && typeof rect[prop] === 'number') {
34
32
  return rect[prop];
35
33
  }