webdriverio 8.24.12 → 8.26.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.
@@ -0,0 +1,53 @@
1
+ /**
2
+ *
3
+ * Will return true when stable (in animation) or when unstable (not in animation)
4
+ *
5
+ * __Note:__ it's best to disable animations instead of using this command
6
+ *
7
+ * <example>
8
+ :index.html
9
+ <head>
10
+ <style>
11
+ div {
12
+ width: 200px;
13
+ height: 200px;
14
+ background-color: red;
15
+ }
16
+ #has-animation {
17
+ animation: 3s 0s alternate slidein;
18
+ }
19
+ @keyframes slidein {
20
+ from {
21
+ margin-left: 100%;
22
+ width: 300%;
23
+ }
24
+
25
+ to {
26
+ margin-left: 0%;
27
+ width: 100%;
28
+ }
29
+ }
30
+ </style>
31
+ </head>
32
+ <body>
33
+ <div #has-animation></div>
34
+ <div #has-no-animation></div>
35
+ </body>
36
+
37
+ :isStable.js
38
+ it('should detect if an element is stable', async () => {
39
+ let element = await $('#has-animation');
40
+ console.log(await element.isStable()); // outputs: false
41
+
42
+ element = await $('#has-no-animation')
43
+ console.log(await element.isStable()); // outputs: true
44
+ });
45
+ * </example>
46
+ *
47
+ * @alias element.isStable
48
+ * @return {Boolean} true if element is stable, false if unstable
49
+ * @type state
50
+ *
51
+ */
52
+ export declare function isStable(this: WebdriverIO.Element): Promise<boolean>;
53
+ //# sourceMappingURL=isStable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isStable.d.ts","sourceRoot":"","sources":["../../../src/commands/element/isStable.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,wBAAsB,QAAQ,CAAE,IAAI,EAAE,WAAW,CAAC,OAAO,oBAMxD"}
@@ -0,0 +1,61 @@
1
+ import { ELEMENT_KEY } from '../../constants.js';
2
+ import { getBrowserObject } from '../../utils/index.js';
3
+ import isElementStable from '../../scripts/isElementStable.js';
4
+ /**
5
+ *
6
+ * Will return true when stable (in animation) or when unstable (not in animation)
7
+ *
8
+ * __Note:__ it's best to disable animations instead of using this command
9
+ *
10
+ * <example>
11
+ :index.html
12
+ <head>
13
+ <style>
14
+ div {
15
+ width: 200px;
16
+ height: 200px;
17
+ background-color: red;
18
+ }
19
+ #has-animation {
20
+ animation: 3s 0s alternate slidein;
21
+ }
22
+ @keyframes slidein {
23
+ from {
24
+ margin-left: 100%;
25
+ width: 300%;
26
+ }
27
+
28
+ to {
29
+ margin-left: 0%;
30
+ width: 100%;
31
+ }
32
+ }
33
+ </style>
34
+ </head>
35
+ <body>
36
+ <div #has-animation></div>
37
+ <div #has-no-animation></div>
38
+ </body>
39
+
40
+ :isStable.js
41
+ it('should detect if an element is stable', async () => {
42
+ let element = await $('#has-animation');
43
+ console.log(await element.isStable()); // outputs: false
44
+
45
+ element = await $('#has-no-animation')
46
+ console.log(await element.isStable()); // outputs: true
47
+ });
48
+ * </example>
49
+ *
50
+ * @alias element.isStable
51
+ * @return {Boolean} true if element is stable, false if unstable
52
+ * @type state
53
+ *
54
+ */
55
+ export async function isStable() {
56
+ const browser = getBrowserObject(this);
57
+ return await browser.executeAsync(isElementStable, {
58
+ [ELEMENT_KEY]: this.elementId, // w3c compatible
59
+ ELEMENT: this.elementId // jsonwp compatible
60
+ });
61
+ }
@@ -0,0 +1,65 @@
1
+ import type { WaitForOptions } from '../../types.js';
2
+ /**
3
+ *
4
+ * Wait for an element for the provided amount of
5
+ * milliseconds to be stable (not animating). Returns true if the selector
6
+ * matches at least one element that is stable in the DOM, otherwise throws an
7
+ * error. If the reverse flag is true, the command will instead return true
8
+ * if the selector does not match any stable elements.
9
+ *
10
+ * __Note:__ it's best to disable animations instead of using this command
11
+ *
12
+ * <example>
13
+ :index.html
14
+ <head>
15
+ <style>
16
+ div {
17
+ width: 200px;
18
+ height: 200px;
19
+ background-color: red;
20
+ }
21
+ #has-animation {
22
+ animation: 3s 0s alternate slidein;
23
+ }
24
+ @keyframes slidein {
25
+ from {
26
+ margin-left: 100%;
27
+ width: 300%;
28
+ }
29
+
30
+ to {
31
+ margin-left: 0%;
32
+ width: 100%;
33
+ }
34
+ }
35
+ </style>
36
+ </head>
37
+ <body>
38
+ <div #has-animation></div>
39
+ <div #has-no-animation></div>
40
+ </body>
41
+
42
+ :waitForStable.js
43
+ it('should detect that element is instable and will wait for the element to become stable', async () => {
44
+ const elem = await $('#has-animation')
45
+ await elem.waitForStable({ timeout: 3000 });
46
+ });
47
+ it('should detect that element is stable and will not wait', async () => {
48
+ const elem = await $('#has-no-animation')
49
+ await elem.waitForStable();
50
+ });
51
+ * </example>
52
+ *
53
+ * @alias element.waitForStable
54
+ * @param {WaitForOptions=} options waitForStable options (optional)
55
+ * @param {Number=} options.timeout time in ms (default: 500)
56
+ * @param {Boolean=} options.reverse if true it waits for the opposite (default: false)
57
+ * @param {String=} options.timeoutMsg if exists it overrides the default error message
58
+ * @param {Number=} options.interval interval between checks (default: `waitforInterval`)
59
+ * @return {Boolean} true if element is stable
60
+ * @uses utility/waitUntil, state/isStable
61
+ * @type utility
62
+ *
63
+ */
64
+ export declare function waitForStable(this: WebdriverIO.Element, { timeout, interval, reverse, timeoutMsg }?: WaitForOptions): Promise<void>;
65
+ //# sourceMappingURL=waitForStable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waitForStable.d.ts","sourceRoot":"","sources":["../../../src/commands/element/waitForStable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,wBAAsB,aAAa,CAC/B,IAAI,EAAE,WAAW,CAAC,OAAO,EACzB,EACI,OAAqC,EACrC,QAAuC,EACvC,OAAe,EACf,UAAmG,EACtG,GAAE,cAAmB,iBA0BzB"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ *
3
+ * Wait for an element for the provided amount of
4
+ * milliseconds to be stable (not animating). Returns true if the selector
5
+ * matches at least one element that is stable in the DOM, otherwise throws an
6
+ * error. If the reverse flag is true, the command will instead return true
7
+ * if the selector does not match any stable elements.
8
+ *
9
+ * __Note:__ it's best to disable animations instead of using this command
10
+ *
11
+ * <example>
12
+ :index.html
13
+ <head>
14
+ <style>
15
+ div {
16
+ width: 200px;
17
+ height: 200px;
18
+ background-color: red;
19
+ }
20
+ #has-animation {
21
+ animation: 3s 0s alternate slidein;
22
+ }
23
+ @keyframes slidein {
24
+ from {
25
+ margin-left: 100%;
26
+ width: 300%;
27
+ }
28
+
29
+ to {
30
+ margin-left: 0%;
31
+ width: 100%;
32
+ }
33
+ }
34
+ </style>
35
+ </head>
36
+ <body>
37
+ <div #has-animation></div>
38
+ <div #has-no-animation></div>
39
+ </body>
40
+
41
+ :waitForStable.js
42
+ it('should detect that element is instable and will wait for the element to become stable', async () => {
43
+ const elem = await $('#has-animation')
44
+ await elem.waitForStable({ timeout: 3000 });
45
+ });
46
+ it('should detect that element is stable and will not wait', async () => {
47
+ const elem = await $('#has-no-animation')
48
+ await elem.waitForStable();
49
+ });
50
+ * </example>
51
+ *
52
+ * @alias element.waitForStable
53
+ * @param {WaitForOptions=} options waitForStable options (optional)
54
+ * @param {Number=} options.timeout time in ms (default: 500)
55
+ * @param {Boolean=} options.reverse if true it waits for the opposite (default: false)
56
+ * @param {String=} options.timeoutMsg if exists it overrides the default error message
57
+ * @param {Number=} options.interval interval between checks (default: `waitforInterval`)
58
+ * @return {Boolean} true if element is stable
59
+ * @uses utility/waitUntil, state/isStable
60
+ * @type utility
61
+ *
62
+ */
63
+ export async function waitForStable({ timeout = this.options.waitforTimeout, interval = this.options.waitforInterval, reverse = false, timeoutMsg = `element ("${this.selector}") still ${reverse ? '' : 'not '}stable after ${timeout}ms` } = {}) {
64
+ let errorMsg;
65
+ await this.waitUntil(async () => {
66
+ try {
67
+ return reverse !== await this.isStable();
68
+ }
69
+ catch (error) {
70
+ if (error instanceof Error) {
71
+ errorMsg = error.message;
72
+ }
73
+ else if (typeof error === 'string') {
74
+ errorMsg = error;
75
+ }
76
+ else {
77
+ errorMsg = 'The waitForStable command got an unknown error';
78
+ }
79
+ // fail early
80
+ return !reverse;
81
+ }
82
+ }, { timeout, interval, timeoutMsg });
83
+ if (errorMsg) {
84
+ throw Error(errorMsg);
85
+ }
86
+ }
@@ -26,6 +26,7 @@ export * from './element/isEqual.js';
26
26
  export * from './element/isExisting.js';
27
27
  export * from './element/isFocused.js';
28
28
  export * from './element/isSelected.js';
29
+ export * from './element/isStable.js';
29
30
  export * from './element/moveTo.js';
30
31
  export * from './element/nextElement.js';
31
32
  export * from './element/parentElement.js';
@@ -45,5 +46,6 @@ export * from './element/waitForClickable.js';
45
46
  export * from './element/waitForDisplayed.js';
46
47
  export * from './element/waitForEnabled.js';
47
48
  export * from './element/waitForExist.js';
49
+ export * from './element/waitForStable.js';
48
50
  export * from './element/waitUntil.js';
49
51
  //# sourceMappingURL=element.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../../src/commands/element.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,uBAAuB,CAAA;AACrC,cAAc,yBAAyB,CAAA;AACvC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,sBAAsB,CAAA;AACpC,cAAc,0BAA0B,CAAA;AACxC,cAAc,0BAA0B,CAAA;AACxC,cAAc,2BAA2B,CAAA;AACzC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,8BAA8B,CAAA;AAC5C,cAAc,+BAA+B,CAAA;AAC7C,cAAc,sBAAsB,CAAA;AACpC,cAAc,0BAA0B,CAAA;AACxC,cAAc,0BAA0B,CAAA;AACxC,cAAc,sBAAsB,CAAA;AACpC,cAAc,yBAAyB,CAAA;AACvC,cAAc,sBAAsB,CAAA;AACpC,cAAc,uBAAuB,CAAA;AACrC,cAAc,0BAA0B,CAAA;AACxC,cAAc,0BAA0B,CAAA;AACxC,cAAc,oCAAoC,CAAA;AAClD,cAAc,wBAAwB,CAAA;AACtC,cAAc,sBAAsB,CAAA;AACpC,cAAc,yBAAyB,CAAA;AACvC,cAAc,wBAAwB,CAAA;AACtC,cAAc,yBAAyB,CAAA;AACvC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,8BAA8B,CAAA;AAC5C,cAAc,sBAAsB,CAAA;AACpC,cAAc,qBAAqB,CAAA;AACnC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,kCAAkC,CAAA;AAChD,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,sBAAsB,CAAA;AACpC,cAAc,0BAA0B,CAAA;AACxC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,+BAA+B,CAAA;AAC7C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,2BAA2B,CAAA;AACzC,cAAc,wBAAwB,CAAA"}
1
+ {"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../../src/commands/element.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,uBAAuB,CAAA;AACrC,cAAc,yBAAyB,CAAA;AACvC,cAAc,oBAAoB,CAAA;AAClC,cAAc,uBAAuB,CAAA;AACrC,cAAc,sBAAsB,CAAA;AACpC,cAAc,0BAA0B,CAAA;AACxC,cAAc,0BAA0B,CAAA;AACxC,cAAc,2BAA2B,CAAA;AACzC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,8BAA8B,CAAA;AAC5C,cAAc,+BAA+B,CAAA;AAC7C,cAAc,sBAAsB,CAAA;AACpC,cAAc,0BAA0B,CAAA;AACxC,cAAc,0BAA0B,CAAA;AACxC,cAAc,sBAAsB,CAAA;AACpC,cAAc,yBAAyB,CAAA;AACvC,cAAc,sBAAsB,CAAA;AACpC,cAAc,uBAAuB,CAAA;AACrC,cAAc,0BAA0B,CAAA;AACxC,cAAc,0BAA0B,CAAA;AACxC,cAAc,oCAAoC,CAAA;AAClD,cAAc,wBAAwB,CAAA;AACtC,cAAc,sBAAsB,CAAA;AACpC,cAAc,yBAAyB,CAAA;AACvC,cAAc,wBAAwB,CAAA;AACtC,cAAc,yBAAyB,CAAA;AACvC,cAAc,uBAAuB,CAAA;AACrC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,8BAA8B,CAAA;AAC5C,cAAc,sBAAsB,CAAA;AACpC,cAAc,qBAAqB,CAAA;AACnC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,kCAAkC,CAAA;AAChD,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,sBAAsB,CAAA;AACpC,cAAc,0BAA0B,CAAA;AACxC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,+BAA+B,CAAA;AAC7C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,2BAA2B,CAAA;AACzC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,wBAAwB,CAAA"}
@@ -26,6 +26,7 @@ export * from './element/isEqual.js';
26
26
  export * from './element/isExisting.js';
27
27
  export * from './element/isFocused.js';
28
28
  export * from './element/isSelected.js';
29
+ export * from './element/isStable.js';
29
30
  export * from './element/moveTo.js';
30
31
  export * from './element/nextElement.js';
31
32
  export * from './element/parentElement.js';
@@ -45,4 +46,5 @@ export * from './element/waitForClickable.js';
45
46
  export * from './element/waitForDisplayed.js';
46
47
  export * from './element/waitForEnabled.js';
47
48
  export * from './element/waitForExist.js';
49
+ export * from './element/waitForStable.js';
48
50
  export * from './element/waitUntil.js';
@@ -0,0 +1,8 @@
1
+ /**
2
+ * check if element is stable (an element is considered unstable when it is animating/moving)
3
+ * @param {HTMLElement} elem element to check
4
+ * @param {Function} done callback function to be called when done
5
+ * @return {void}
6
+ */
7
+ export default function isElementStable(elem: HTMLElement, done: (returnValue: boolean) => void): void;
8
+ //# sourceMappingURL=isElementStable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isElementStable.d.ts","sourceRoot":"","sources":["../../src/scripts/isElementStable.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,OAAO,KAAK,IAAI,QAqB9F"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * check if element is stable (an element is considered unstable when it is animating/moving)
3
+ * @param {HTMLElement} elem element to check
4
+ * @param {Function} done callback function to be called when done
5
+ * @return {void}
6
+ */
7
+ export default function isElementStable(elem, done) {
8
+ if (document.visibilityState === 'hidden') {
9
+ throw Error('You are are checking for animations on an inactive tab, animations do not run for inactive tabs');
10
+ }
11
+ try {
12
+ const previousPosition = elem.getBoundingClientRect();
13
+ // wait for two consecutive frames to make sure there are no animations
14
+ requestAnimationFrame(() => {
15
+ requestAnimationFrame(() => {
16
+ const currentPosition = elem.getBoundingClientRect();
17
+ for (const prop in previousPosition) {
18
+ if (previousPosition[prop] !== currentPosition[prop]) {
19
+ done(false);
20
+ }
21
+ }
22
+ done(true);
23
+ });
24
+ });
25
+ }
26
+ catch (error) {
27
+ done(false);
28
+ }
29
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "webdriverio",
3
3
  "description": "Next-gen browser and mobile automation test framework for Node.js",
4
- "version": "8.24.12",
4
+ "version": "8.26.0",
5
5
  "homepage": "https://webdriver.io",
6
6
  "author": "Christian Bromann <mail@bromann.dev>",
7
7
  "license": "MIT",
@@ -101,5 +101,5 @@
101
101
  "optional": true
102
102
  }
103
103
  },
104
- "gitHead": "ebf1ba1875fe210fda7067c1c13944c50cb6a694"
104
+ "gitHead": "ddff99f6945ebe7d73904e0f3f607b7d46d372c4"
105
105
  }