@serenity-js/webdriverio 3.0.0-rc.2 → 3.0.0-rc.3
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.
- package/CHANGELOG.md +19 -0
- package/lib/screenplay/abilities/BrowseTheWebWithWebdriverIO.d.ts +6 -32
- package/lib/screenplay/abilities/BrowseTheWebWithWebdriverIO.js +9 -47
- package/lib/screenplay/abilities/BrowseTheWebWithWebdriverIO.js.map +1 -1
- package/lib/screenplay/models/WebdriverIONativeElementLocator.d.ts +27 -0
- package/lib/screenplay/models/WebdriverIONativeElementLocator.js +56 -0
- package/lib/screenplay/models/WebdriverIONativeElementLocator.js.map +1 -0
- package/lib/screenplay/models/WebdriverIONativeElementRoot.d.ts +1 -1
- package/lib/screenplay/models/WebdriverIOPageElement.d.ts +13 -4
- package/lib/screenplay/models/WebdriverIOPageElement.js +44 -5
- package/lib/screenplay/models/WebdriverIOPageElement.js.map +1 -1
- package/lib/screenplay/models/index.d.ts +1 -1
- package/lib/screenplay/models/index.js +1 -1
- package/lib/screenplay/models/index.js.map +1 -1
- package/package.json +5 -5
- package/src/screenplay/abilities/BrowseTheWebWithWebdriverIO.ts +13 -61
- package/src/screenplay/models/WebdriverIONativeElementLocator.ts +78 -0
- package/src/screenplay/models/WebdriverIONativeElementRoot.ts +1 -1
- package/src/screenplay/models/WebdriverIOPageElement.ts +62 -9
- package/src/screenplay/models/index.ts +1 -1
- package/lib/screenplay/models/WebdriverIOPageElements.d.ts +0 -15
- package/lib/screenplay/models/WebdriverIOPageElements.js +0 -65
- package/lib/screenplay/models/WebdriverIOPageElements.js.map +0 -1
- package/src/screenplay/models/WebdriverIOPageElements.ts +0 -91
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,25 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [3.0.0-rc.3](https://github.com/serenity-js/serenity-js/compare/v3.0.0-rc.2...v3.0.0-rc.3) (2021-12-29)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **core:** refactored Mappable so that it's easier to implement filters ([176e0cd](https://github.com/serenity-js/serenity-js/commit/176e0cd0303d63271477b2b7a8e7b0572dda99a0)), closes [#1074](https://github.com/serenity-js/serenity-js/issues/1074)
|
|
12
|
+
* **deps:** updated tiny-types to 1.17.0 ([3187051](https://github.com/serenity-js/serenity-js/commit/3187051594158b4b450c82e851e417fd2ed21652))
|
|
13
|
+
* **web:** refactored Selector and NativeElementLocator classes to simplify the implementation ([f0c8f11](https://github.com/serenity-js/serenity-js/commit/f0c8f113433958877d36f13d0bc7f355ea68d280))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
* **web:** isVisible checks if the element is in viewport and not hidden behind other elements ([429040f](https://github.com/serenity-js/serenity-js/commit/429040fb32b04cd4bc7524100635203fd8128eb6))
|
|
19
|
+
* **web:** re-introduced PageElements.where DSL and universal By selectors ([39fe0a1](https://github.com/serenity-js/serenity-js/commit/39fe0a10edf7f652e93911159e4a4689c36d6876)), closes [#1081](https://github.com/serenity-js/serenity-js/issues/1081)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
6
25
|
# [3.0.0-rc.2](https://github.com/serenity-js/serenity-js/compare/v3.0.0-rc.1...v3.0.0-rc.2) (2021-12-09)
|
|
7
26
|
|
|
8
27
|
**Note:** Version bump only for package @serenity-js/webdriverio
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Duration, UsesAbilities } from '@serenity-js/core';
|
|
2
|
-
import { BrowserCapabilities, BrowseTheWeb, Cookie, CookieData, Key, ModalDialog, Page, PageElement } from '@serenity-js/web';
|
|
2
|
+
import { BrowserCapabilities, BrowseTheWeb, Cookie, CookieData, Key, ModalDialog, NativeElementLocator, Page, PageElement, Selector } from '@serenity-js/web';
|
|
3
3
|
import type * as wdio from 'webdriverio';
|
|
4
|
-
import { WebdriverIOPageElement
|
|
4
|
+
import { WebdriverIOPageElement } from '../models';
|
|
5
5
|
/**
|
|
6
6
|
* @desc
|
|
7
7
|
* An {@link @serenity-js/core/lib/screenplay~Ability} that enables the {@link @serenity-js/core/lib/screenplay/actor~Actor}
|
|
@@ -35,7 +35,7 @@ import { WebdriverIOPageElement, WebdriverIOPageElements } from '../models';
|
|
|
35
35
|
* @implements {@serenity-js/core/lib/screenplay~Ability}
|
|
36
36
|
* @see {@link @serenity-js/core/lib/screenplay/actor~Actor}
|
|
37
37
|
*/
|
|
38
|
-
export declare class BrowseTheWebWithWebdriverIO extends BrowseTheWeb {
|
|
38
|
+
export declare class BrowseTheWebWithWebdriverIO extends BrowseTheWeb<wdio.Element<'async'>> {
|
|
39
39
|
readonly browser: wdio.Browser<'async'>;
|
|
40
40
|
/**
|
|
41
41
|
* @param {@wdio/types~Browser} browserInstance
|
|
@@ -64,35 +64,9 @@ export declare class BrowseTheWebWithWebdriverIO extends BrowseTheWeb {
|
|
|
64
64
|
cookie(name: string): Promise<Cookie>;
|
|
65
65
|
setCookie(cookieData: CookieData): Promise<void>;
|
|
66
66
|
deleteAllCookies(): Promise<void>;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
* Retrieves a {@link @serenity-js/web/lib/screenplay/models~PageElement} which text includes `text`
|
|
71
|
-
* and which can be located using the CSS `selector`.
|
|
72
|
-
*
|
|
73
|
-
* Under the hood, this command uses https://webdriver.io/docs/selectors#element-with-certain-text
|
|
74
|
-
*
|
|
75
|
-
* This means that only some selectors are supported. For example:
|
|
76
|
-
* - 'h1'
|
|
77
|
-
* - 'h1.some-class'
|
|
78
|
-
* - '#someId'
|
|
79
|
-
* - 'h1[attribute-name="attribute-selector"]
|
|
80
|
-
*
|
|
81
|
-
* Notably, complex CSS selectors such as 'header h1' or 'header > h1' **WON'T WORK**.
|
|
82
|
-
*
|
|
83
|
-
* @param {string} selector
|
|
84
|
-
* @param {string} text
|
|
85
|
-
* @returns {@serenity-js/web/lib/screenplay/models~PageElement}
|
|
86
|
-
*/
|
|
87
|
-
findByCssContainingText(selector: string, text: RegExp | string): WebdriverIOPageElement;
|
|
88
|
-
findById(selector: string): WebdriverIOPageElement;
|
|
89
|
-
findByTagName(selector: string): WebdriverIOPageElement;
|
|
90
|
-
findByXPath(selector: string): WebdriverIOPageElement;
|
|
91
|
-
findAllByCss(selector: string): WebdriverIOPageElements;
|
|
92
|
-
findAllByTagName(selector: string): WebdriverIOPageElements;
|
|
93
|
-
findAllByXPath(selector: string): WebdriverIOPageElements;
|
|
94
|
-
private find;
|
|
95
|
-
private findAll;
|
|
67
|
+
locate<T>(selector: Selector<T>, locator?: NativeElementLocator<wdio.Element<'async'>>): WebdriverIOPageElement;
|
|
68
|
+
locateAll<T>(selector: Selector<T>, locator?: NativeElementLocator<wdio.Element<'async'>>): Promise<WebdriverIOPageElement[]>;
|
|
69
|
+
nativeElementLocator(): NativeElementLocator<wdio.Element<'async'>>;
|
|
96
70
|
/**
|
|
97
71
|
* @desc
|
|
98
72
|
* Navigate to a given destination, specified as an absolute URL
|
|
@@ -45,7 +45,7 @@ class BrowseTheWebWithWebdriverIO extends web_1.BrowseTheWeb {
|
|
|
45
45
|
super();
|
|
46
46
|
this.browser = browser;
|
|
47
47
|
if (!this.browser.$ || !this.browser.$$) {
|
|
48
|
-
throw new core_1.LogicError(`WebdriverIO browser object is not
|
|
48
|
+
throw new core_1.LogicError(`WebdriverIO browser object is not initialised yet, so can't be assigned to an actor. Are you trying to instantiate an actor outside of a test or a test hook?`);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
/**
|
|
@@ -90,54 +90,16 @@ class BrowseTheWebWithWebdriverIO extends web_1.BrowseTheWeb {
|
|
|
90
90
|
deleteAllCookies() {
|
|
91
91
|
return this.browser.deleteCookies();
|
|
92
92
|
}
|
|
93
|
-
|
|
94
|
-
return
|
|
93
|
+
locate(selector, locator) {
|
|
94
|
+
return new models_1.WebdriverIOPageElement(selector, locator !== null && locator !== void 0 ? locator : this.nativeElementLocator());
|
|
95
95
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
*
|
|
101
|
-
* Under the hood, this command uses https://webdriver.io/docs/selectors#element-with-certain-text
|
|
102
|
-
*
|
|
103
|
-
* This means that only some selectors are supported. For example:
|
|
104
|
-
* - 'h1'
|
|
105
|
-
* - 'h1.some-class'
|
|
106
|
-
* - '#someId'
|
|
107
|
-
* - 'h1[attribute-name="attribute-selector"]
|
|
108
|
-
*
|
|
109
|
-
* Notably, complex CSS selectors such as 'header h1' or 'header > h1' **WON'T WORK**.
|
|
110
|
-
*
|
|
111
|
-
* @param {string} selector
|
|
112
|
-
* @param {string} text
|
|
113
|
-
* @returns {@serenity-js/web/lib/screenplay/models~PageElement}
|
|
114
|
-
*/
|
|
115
|
-
findByCssContainingText(selector, text) {
|
|
116
|
-
return this.find(root => root.$(`${selector}*=${text}`));
|
|
117
|
-
}
|
|
118
|
-
findById(selector) {
|
|
119
|
-
return this.find(root => root.$(`#${selector}`));
|
|
120
|
-
}
|
|
121
|
-
findByTagName(selector) {
|
|
122
|
-
return this.find(root => root.$(`<${selector} />`));
|
|
123
|
-
}
|
|
124
|
-
findByXPath(selector) {
|
|
125
|
-
return this.find(root => root.$(selector));
|
|
126
|
-
}
|
|
127
|
-
findAllByCss(selector) {
|
|
128
|
-
return this.findAll(root => root.$$(selector));
|
|
129
|
-
}
|
|
130
|
-
findAllByTagName(selector) {
|
|
131
|
-
return this.findAll(root => root.$$(`<${selector} />`));
|
|
132
|
-
}
|
|
133
|
-
findAllByXPath(selector) {
|
|
134
|
-
return this.findAll(root => root.$$(selector));
|
|
135
|
-
}
|
|
136
|
-
find(locator) {
|
|
137
|
-
return new models_1.WebdriverIOPageElement(() => this.browser, locator);
|
|
96
|
+
async locateAll(selector, locator) {
|
|
97
|
+
const l = locator !== null && locator !== void 0 ? locator : this.nativeElementLocator();
|
|
98
|
+
const elements = await l.locateAll(selector);
|
|
99
|
+
return elements.map(element => new models_1.WebdriverIOPageElement(selector, new web_1.PassThroughNativeElementLocator(locator, element)));
|
|
138
100
|
}
|
|
139
|
-
|
|
140
|
-
return new models_1.
|
|
101
|
+
nativeElementLocator() {
|
|
102
|
+
return new models_1.WebdriverIONativeElementLocator(() => this.browser);
|
|
141
103
|
}
|
|
142
104
|
/**
|
|
143
105
|
* @desc
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BrowseTheWebWithWebdriverIO.js","sourceRoot":"","sources":["../../../src/screenplay/abilities/BrowseTheWebWithWebdriverIO.ts"],"names":[],"mappings":";;;AAAA,4CAAwE;AACxE,
|
|
1
|
+
{"version":3,"file":"BrowseTheWebWithWebdriverIO.js","sourceRoot":"","sources":["../../../src/screenplay/abilities/BrowseTheWebWithWebdriverIO.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { NativeElementLocator, Selector } from '@serenity-js/web';
|
|
2
|
+
import * as wdio from 'webdriverio';
|
|
3
|
+
import { WebdriverIONativeElementRoot } from './WebdriverIONativeElementRoot';
|
|
4
|
+
export declare class WebdriverIONativeElementLocator implements NativeElementLocator<wdio.Element<'async'>> {
|
|
5
|
+
private readonly resolver;
|
|
6
|
+
constructor(resolver: () => Promise<WebdriverIONativeElementRoot> | WebdriverIONativeElementRoot);
|
|
7
|
+
/**
|
|
8
|
+
* @desc
|
|
9
|
+
* Retrieves a {@link @serenity-js/web/lib/screenplay/models~PageElement} which text includes `text`
|
|
10
|
+
* and which can be located using the CSS `selector`.
|
|
11
|
+
*
|
|
12
|
+
* Under the hood, this command uses https://webdriver.io/docs/selectors#element-with-certain-text
|
|
13
|
+
*
|
|
14
|
+
* This means that only some selectors are supported. For example:
|
|
15
|
+
* - 'h1'
|
|
16
|
+
* - 'h1.some-class'
|
|
17
|
+
* - '#someId'
|
|
18
|
+
* - 'h1[attribute-name="attribute-selector"]
|
|
19
|
+
*
|
|
20
|
+
* Notably, complex CSS selectors such as 'header h1' or 'header > h1' **WON'T WORK**.
|
|
21
|
+
*
|
|
22
|
+
* @param {Selector<T>} selector
|
|
23
|
+
* @returns {Promise<wdio.Element<'async'>>}
|
|
24
|
+
*/
|
|
25
|
+
locate<T>(selector: Selector<T>): Promise<wdio.Element<'async'>>;
|
|
26
|
+
locateAll<T>(selector: Selector<T>): Promise<Array<wdio.Element<'async'>>>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WebdriverIONativeElementLocator = void 0;
|
|
4
|
+
const core_1 = require("@serenity-js/core");
|
|
5
|
+
const web_1 = require("@serenity-js/web");
|
|
6
|
+
const tiny_types_1 = require("tiny-types");
|
|
7
|
+
const f = (0, core_1.format)({ markQuestions: false });
|
|
8
|
+
class WebdriverIONativeElementLocator {
|
|
9
|
+
constructor(resolver) {
|
|
10
|
+
this.resolver = resolver;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* @desc
|
|
14
|
+
* Retrieves a {@link @serenity-js/web/lib/screenplay/models~PageElement} which text includes `text`
|
|
15
|
+
* and which can be located using the CSS `selector`.
|
|
16
|
+
*
|
|
17
|
+
* Under the hood, this command uses https://webdriver.io/docs/selectors#element-with-certain-text
|
|
18
|
+
*
|
|
19
|
+
* This means that only some selectors are supported. For example:
|
|
20
|
+
* - 'h1'
|
|
21
|
+
* - 'h1.some-class'
|
|
22
|
+
* - '#someId'
|
|
23
|
+
* - 'h1[attribute-name="attribute-selector"]
|
|
24
|
+
*
|
|
25
|
+
* Notably, complex CSS selectors such as 'header h1' or 'header > h1' **WON'T WORK**.
|
|
26
|
+
*
|
|
27
|
+
* @param {Selector<T>} selector
|
|
28
|
+
* @returns {Promise<wdio.Element<'async'>>}
|
|
29
|
+
*/
|
|
30
|
+
async locate(selector) {
|
|
31
|
+
const resolver = await this.resolver();
|
|
32
|
+
const byLocator = (0, tiny_types_1.match)(selector)
|
|
33
|
+
.when(web_1.ByCss, (s) => s.value)
|
|
34
|
+
.when(web_1.ByCssContainingText, (s) => `${s.value}*=${s.text}`)
|
|
35
|
+
.when(web_1.ById, (s) => `#${s.value}`)
|
|
36
|
+
.when(web_1.ByTagName, (s) => `<${s.value} />`)
|
|
37
|
+
.when(web_1.ByXPath, (s) => s.value)
|
|
38
|
+
.else(() => {
|
|
39
|
+
throw new core_1.LogicError(f `Selector ${selector} not supported`);
|
|
40
|
+
});
|
|
41
|
+
return resolver.$(byLocator);
|
|
42
|
+
}
|
|
43
|
+
async locateAll(selector) {
|
|
44
|
+
const resolver = await this.resolver();
|
|
45
|
+
const byLocator = (0, tiny_types_1.match)(selector)
|
|
46
|
+
.when(web_1.ByCss, (s) => s.value)
|
|
47
|
+
.when(web_1.ByTagName, (s) => `<${s.value} />`)
|
|
48
|
+
.when(web_1.ByXPath, (s) => s.value)
|
|
49
|
+
.else(() => {
|
|
50
|
+
throw new core_1.LogicError(f `Selector ${selector} not supported`);
|
|
51
|
+
});
|
|
52
|
+
return resolver.$$(byLocator);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.WebdriverIONativeElementLocator = WebdriverIONativeElementLocator;
|
|
56
|
+
//# sourceMappingURL=WebdriverIONativeElementLocator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebdriverIONativeElementLocator.js","sourceRoot":"","sources":["../../../src/screenplay/models/WebdriverIONativeElementLocator.ts"],"names":[],"mappings":";;;AAAA,4CAAuD;AACvD,0CAAwH;AACxH,2CAAmC;AAKnC,MAAM,CAAC,GAAG,IAAA,aAAM,EAAC,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC;AAE3C,MAAa,+BAA+B;IACxC,YAA6B,QAAoF;QAApF,aAAQ,GAAR,QAAQ,CAA4E;IACjH,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,MAAM,CAAI,QAAqB;QACjC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QAEvC,MAAM,SAAS,GAAG,IAAA,kBAAK,EAA4B,QAAQ,CAAC;aACvD,IAAI,CAAC,WAAK,EAAE,CAAC,CAAQ,EAAE,EAAE,CACtB,CAAC,CAAC,KAAK,CACV;aACA,IAAI,CAAC,yBAAmB,EAAE,CAAC,CAAsB,EAAE,EAAE,CAClD,GAAI,CAAC,CAAC,KAAM,KAAM,CAAC,CAAC,IAAK,EAAE,CAC9B;aACA,IAAI,CAAC,UAAI,EAAE,CAAC,CAAO,EAAE,EAAE,CACpB,IAAK,CAAC,CAAC,KAAM,EAAE,CAClB;aACA,IAAI,CAAC,eAAS,EAAE,CAAC,CAAY,EAAE,EAAE,CAC9B,IAAK,CAAC,CAAC,KAAM,KAAK,CACrB;aACA,IAAI,CAAC,aAAO,EAAE,CAAC,CAAU,EAAE,EAAE,CAC1B,CAAC,CAAC,KAAK,CACV;aACA,IAAI,CAAC,GAAG,EAAE;YACP,MAAM,IAAI,iBAAU,CAAC,CAAC,CAAA,YAAa,QAAS,gBAAgB,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QAEP,OAAO,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,SAAS,CAAI,QAAqB;QACpC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QAEvC,MAAM,SAAS,GAAG,IAAA,kBAAK,EAA4B,QAAQ,CAAC;aACvD,IAAI,CAAC,WAAK,EAAE,CAAC,CAAQ,EAAE,EAAE,CACtB,CAAC,CAAC,KAAK,CACV;aACA,IAAI,CAAC,eAAS,EAAE,CAAC,CAAY,EAAE,EAAE,CAC9B,IAAK,CAAC,CAAC,KAAM,KAAK,CACrB;aACA,IAAI,CAAC,aAAO,EAAE,CAAC,CAAU,EAAE,EAAE,CAC1B,CAAC,CAAC,KAAK,CACV;aACA,IAAI,CAAC,GAAG,EAAE;YACP,MAAM,IAAI,iBAAU,CAAC,CAAC,CAAA,YAAa,QAAS,gBAAgB,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QAEP,OAAO,QAAQ,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;CACJ;AAnED,0EAmEC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import * as wdio from 'webdriverio';
|
|
2
|
-
export declare type WebdriverIONativeElementRoot = Pick<wdio.Browser<'async'>, '$' | '$$'
|
|
2
|
+
export declare type WebdriverIONativeElementRoot = Pick<wdio.Browser<'async'>, '$' | '$$'>;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { PageElement } from '@serenity-js/web';
|
|
2
2
|
import * as wdio from 'webdriverio';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
of(parent: WebdriverIOPageElement): PageElement<WebdriverIONativeElementRoot, wdio.Element<'async'>>;
|
|
3
|
+
export declare class WebdriverIOPageElement extends PageElement<wdio.Element<'async'>> {
|
|
4
|
+
of(parent: WebdriverIOPageElement): WebdriverIOPageElement;
|
|
6
5
|
clearValue(): Promise<void>;
|
|
7
6
|
click(): Promise<void>;
|
|
8
7
|
doubleClick(): Promise<void>;
|
|
@@ -15,8 +14,18 @@ export declare class WebdriverIOPageElement extends PageElement<WebdriverIONativ
|
|
|
15
14
|
value(): Promise<string>;
|
|
16
15
|
isActive(): Promise<boolean>;
|
|
17
16
|
isClickable(): Promise<boolean>;
|
|
18
|
-
isDisplayed(): Promise<boolean>;
|
|
19
17
|
isEnabled(): Promise<boolean>;
|
|
20
18
|
isPresent(): Promise<boolean>;
|
|
21
19
|
isSelected(): Promise<boolean>;
|
|
20
|
+
/**
|
|
21
|
+
* @desc
|
|
22
|
+
* Checks if the PageElement:
|
|
23
|
+
* - is displayed,
|
|
24
|
+
* - is visible within the browser viewport,
|
|
25
|
+
* - has not its center covered by other elements
|
|
26
|
+
*
|
|
27
|
+
* @see https://webdriver.io/docs/api/element/isDisplayedInViewport/
|
|
28
|
+
*/
|
|
29
|
+
isVisible(): Promise<boolean>;
|
|
30
|
+
private browserFor;
|
|
22
31
|
}
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.WebdriverIOPageElement = void 0;
|
|
4
4
|
const web_1 = require("@serenity-js/web");
|
|
5
|
+
const WebdriverIONativeElementLocator_1 = require("./WebdriverIONativeElementLocator");
|
|
5
6
|
class WebdriverIOPageElement extends web_1.PageElement {
|
|
6
7
|
of(parent) {
|
|
7
|
-
return new WebdriverIOPageElement(() => parent.nativeElement()
|
|
8
|
+
return new WebdriverIOPageElement(this.selector, new WebdriverIONativeElementLocator_1.WebdriverIONativeElementLocator(() => parent.nativeElement()));
|
|
8
9
|
}
|
|
9
10
|
async clearValue() {
|
|
10
11
|
const element = await this.nativeElement();
|
|
@@ -54,10 +55,6 @@ class WebdriverIOPageElement extends web_1.PageElement {
|
|
|
54
55
|
const element = await this.nativeElement();
|
|
55
56
|
return element.isClickable();
|
|
56
57
|
}
|
|
57
|
-
async isDisplayed() {
|
|
58
|
-
const element = await this.nativeElement();
|
|
59
|
-
return element.isDisplayed();
|
|
60
|
-
}
|
|
61
58
|
async isEnabled() {
|
|
62
59
|
const element = await this.nativeElement();
|
|
63
60
|
return element.isEnabled();
|
|
@@ -70,6 +67,48 @@ class WebdriverIOPageElement extends web_1.PageElement {
|
|
|
70
67
|
const element = await this.nativeElement();
|
|
71
68
|
return element.isSelected();
|
|
72
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* @desc
|
|
72
|
+
* Checks if the PageElement:
|
|
73
|
+
* - is displayed,
|
|
74
|
+
* - is visible within the browser viewport,
|
|
75
|
+
* - has not its center covered by other elements
|
|
76
|
+
*
|
|
77
|
+
* @see https://webdriver.io/docs/api/element/isDisplayedInViewport/
|
|
78
|
+
*/
|
|
79
|
+
async isVisible() {
|
|
80
|
+
const element = await this.nativeElement();
|
|
81
|
+
if (!await element.isDisplayed()) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
if (!await element.isDisplayedInViewport()) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
const browser = await this.browserFor(element);
|
|
88
|
+
/* eslint-disable no-var */
|
|
89
|
+
// get element at cx/cy and see if the element we found is our element, and therefore it's visible.
|
|
90
|
+
return browser.execute(
|
|
91
|
+
/* istanbul ignore next */
|
|
92
|
+
function isVisible(element) {
|
|
93
|
+
if (!element.getBoundingClientRect) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
var box = element.getBoundingClientRect(), cx = box.left + box.width / 2, cy = box.top + box.height / 2, e = document.elementFromPoint(cx, cy);
|
|
97
|
+
for (; e; e = e.parentElement) {
|
|
98
|
+
if (e === element)
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
return false;
|
|
102
|
+
}, element);
|
|
103
|
+
/* eslint-enable no-var */
|
|
104
|
+
}
|
|
105
|
+
// based on https://github.com/webdriverio/webdriverio/blob/dec6da76b0e218af935dbf39735ae3491d5edd8c/packages/webdriverio/src/utils/index.ts#L98
|
|
106
|
+
async browserFor(nativeElement) {
|
|
107
|
+
const element = nativeElement;
|
|
108
|
+
return element.parent
|
|
109
|
+
? this.browserFor(element.parent)
|
|
110
|
+
: nativeElement;
|
|
111
|
+
}
|
|
73
112
|
}
|
|
74
113
|
exports.WebdriverIOPageElement = WebdriverIOPageElement;
|
|
75
114
|
//# sourceMappingURL=WebdriverIOPageElement.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebdriverIOPageElement.js","sourceRoot":"","sources":["../../../src/screenplay/models/WebdriverIOPageElement.ts"],"names":[],"mappings":";;;AAAA,0CAA+C;
|
|
1
|
+
{"version":3,"file":"WebdriverIOPageElement.js","sourceRoot":"","sources":["../../../src/screenplay/models/WebdriverIOPageElement.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from './WebdriverIOCookie';
|
|
2
2
|
export * from './WebdriverIOModalDialog';
|
|
3
|
+
export * from './WebdriverIONativeElementLocator';
|
|
3
4
|
export * from './WebdriverIONativeElementRoot';
|
|
4
5
|
export * from './WebdriverIOPage';
|
|
5
6
|
export * from './WebdriverIOPageElement';
|
|
6
|
-
export * from './WebdriverIOPageElements';
|
|
@@ -12,8 +12,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
__exportStar(require("./WebdriverIOCookie"), exports);
|
|
14
14
|
__exportStar(require("./WebdriverIOModalDialog"), exports);
|
|
15
|
+
__exportStar(require("./WebdriverIONativeElementLocator"), exports);
|
|
15
16
|
__exportStar(require("./WebdriverIONativeElementRoot"), exports);
|
|
16
17
|
__exportStar(require("./WebdriverIOPage"), exports);
|
|
17
18
|
__exportStar(require("./WebdriverIOPageElement"), exports);
|
|
18
|
-
__exportStar(require("./WebdriverIOPageElements"), exports);
|
|
19
19
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/screenplay/models/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,sDAAoC;AACpC,2DAAyC;AACzC,iEAA+C;AAC/C,oDAAkC;AAClC,2DAAyC
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/screenplay/models/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,sDAAoC;AACpC,2DAAyC;AACzC,oEAAkD;AAClD,iEAA+C;AAC/C,oDAAkC;AAClC,2DAAyC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@serenity-js/webdriverio",
|
|
3
|
-
"version": "3.0.0-rc.
|
|
3
|
+
"version": "3.0.0-rc.3",
|
|
4
4
|
"description": "Serenity/JS reporter and Screenplay Pattern library for WebdriverIO",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Jan Molak",
|
|
@@ -49,13 +49,13 @@
|
|
|
49
49
|
"npm": "^6 || ^7 || ^8"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@serenity-js/core": "3.0.0-rc.
|
|
53
|
-
"@serenity-js/web": "3.0.0-rc.
|
|
52
|
+
"@serenity-js/core": "3.0.0-rc.3",
|
|
53
|
+
"@serenity-js/web": "3.0.0-rc.3",
|
|
54
54
|
"@wdio/reporter": "^7.16.3",
|
|
55
55
|
"@wdio/types": "^7.16.3",
|
|
56
56
|
"deepmerge": "^4.2.2",
|
|
57
57
|
"is-plain-object": "^5.0.0",
|
|
58
|
-
"tiny-types": "^1.
|
|
58
|
+
"tiny-types": "^1.17.0"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"@serenity-js/cucumber": "^3.0.0-rc",
|
|
@@ -112,5 +112,5 @@
|
|
|
112
112
|
"cache": true,
|
|
113
113
|
"all": false
|
|
114
114
|
},
|
|
115
|
-
"gitHead": "
|
|
115
|
+
"gitHead": "69da7444e581c457e29e87edcd910ec06a069338"
|
|
116
116
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Duration, LogicError, UsesAbilities } from '@serenity-js/core';
|
|
2
|
-
import { BrowserCapabilities, BrowseTheWeb, Cookie, CookieData, Key, ModalDialog, Page, PageElement } from '@serenity-js/web';
|
|
2
|
+
import { BrowserCapabilities, BrowseTheWeb, Cookie, CookieData, Key, ModalDialog, NativeElementLocator, Page, PageElement, PassThroughNativeElementLocator, Selector } from '@serenity-js/web';
|
|
3
3
|
import type * as wdio from 'webdriverio';
|
|
4
4
|
|
|
5
|
-
import { WebdriverIOCookie, WebdriverIOModalDialog,
|
|
5
|
+
import { WebdriverIOCookie, WebdriverIOModalDialog, WebdriverIONativeElementLocator, WebdriverIOPage, WebdriverIOPageElement } from '../models';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* @desc
|
|
@@ -37,7 +37,7 @@ import { WebdriverIOCookie, WebdriverIOModalDialog, WebdriverIONativeElementRoot
|
|
|
37
37
|
* @implements {@serenity-js/core/lib/screenplay~Ability}
|
|
38
38
|
* @see {@link @serenity-js/core/lib/screenplay/actor~Actor}
|
|
39
39
|
*/
|
|
40
|
-
export class BrowseTheWebWithWebdriverIO extends BrowseTheWeb {
|
|
40
|
+
export class BrowseTheWebWithWebdriverIO extends BrowseTheWeb<wdio.Element<'async'>> {
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
43
|
* @param {@wdio/types~Browser} browserInstance
|
|
@@ -72,7 +72,7 @@ export class BrowseTheWebWithWebdriverIO extends BrowseTheWeb {
|
|
|
72
72
|
super();
|
|
73
73
|
|
|
74
74
|
if (! this.browser.$ || ! this.browser.$$) {
|
|
75
|
-
throw new LogicError(`WebdriverIO browser object is not
|
|
75
|
+
throw new LogicError(`WebdriverIO browser object is not initialised yet, so can't be assigned to an actor. Are you trying to instantiate an actor outside of a test or a test hook?`)
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
|
|
@@ -103,69 +103,21 @@ export class BrowseTheWebWithWebdriverIO extends BrowseTheWeb {
|
|
|
103
103
|
return this.browser.deleteCookies() as Promise<void>;
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
|
|
107
|
-
return
|
|
106
|
+
locate<T>(selector: Selector<T>, locator?: NativeElementLocator<wdio.Element<'async'>>): WebdriverIOPageElement {
|
|
107
|
+
return new WebdriverIOPageElement(selector, locator ?? this.nativeElementLocator());
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
* and which can be located using the CSS `selector`.
|
|
114
|
-
*
|
|
115
|
-
* Under the hood, this command uses https://webdriver.io/docs/selectors#element-with-certain-text
|
|
116
|
-
*
|
|
117
|
-
* This means that only some selectors are supported. For example:
|
|
118
|
-
* - 'h1'
|
|
119
|
-
* - 'h1.some-class'
|
|
120
|
-
* - '#someId'
|
|
121
|
-
* - 'h1[attribute-name="attribute-selector"]
|
|
122
|
-
*
|
|
123
|
-
* Notably, complex CSS selectors such as 'header h1' or 'header > h1' **WON'T WORK**.
|
|
124
|
-
*
|
|
125
|
-
* @param {string} selector
|
|
126
|
-
* @param {string} text
|
|
127
|
-
* @returns {@serenity-js/web/lib/screenplay/models~PageElement}
|
|
128
|
-
*/
|
|
129
|
-
findByCssContainingText(selector: string, text: RegExp | string): WebdriverIOPageElement {
|
|
130
|
-
return this.find(root => root.$(`${ selector }*=${ text }`));
|
|
131
|
-
}
|
|
110
|
+
async locateAll<T>(selector: Selector<T>, locator?: NativeElementLocator<wdio.Element<'async'>>): Promise<WebdriverIOPageElement[]> {
|
|
111
|
+
const l = locator ?? this.nativeElementLocator();
|
|
112
|
+
const elements = await l.locateAll(selector);
|
|
132
113
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
findByTagName(selector: string): WebdriverIOPageElement {
|
|
138
|
-
return this.find(root => root.$(`<${ selector } />`));
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
findByXPath(selector: string): WebdriverIOPageElement {
|
|
142
|
-
return this.find(root => root.$(selector));
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
findAllByCss(selector: string): WebdriverIOPageElements {
|
|
146
|
-
return this.findAll(root => root.$$(selector));
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
findAllByTagName(selector: string): WebdriverIOPageElements {
|
|
150
|
-
return this.findAll(root => root.$$(`<${ selector } />`));
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
findAllByXPath(selector: string): WebdriverIOPageElements {
|
|
154
|
-
return this.findAll(root => root.$$(selector));
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
private find(locator: (root: WebdriverIONativeElementRoot) => wdio.ChainablePromiseElement<Promise<wdio.Element<'async'>>> | Promise<wdio.Element<'async'>>): WebdriverIOPageElement {
|
|
158
|
-
return new WebdriverIOPageElement(
|
|
159
|
-
() => this.browser,
|
|
160
|
-
locator as unknown as (root: WebdriverIONativeElementRoot) => Promise<wdio.Element<'async'>>, // We don't need the ChainablePromiseElement
|
|
114
|
+
return elements.map(element =>
|
|
115
|
+
new WebdriverIOPageElement(selector, new PassThroughNativeElementLocator<wdio.Element<'async'>>(locator, element)),
|
|
161
116
|
);
|
|
162
117
|
}
|
|
163
118
|
|
|
164
|
-
|
|
165
|
-
return new
|
|
166
|
-
() => this.browser,
|
|
167
|
-
locator as unknown as (root: WebdriverIONativeElementRoot) => Promise<wdio.ElementArray>, // We don't need the ChainablePromiseArray
|
|
168
|
-
);
|
|
119
|
+
nativeElementLocator(): NativeElementLocator<wdio.Element<'async'>> {
|
|
120
|
+
return new WebdriverIONativeElementLocator(() => this.browser);
|
|
169
121
|
}
|
|
170
122
|
|
|
171
123
|
/**
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { format, LogicError } from '@serenity-js/core';
|
|
2
|
+
import { ByCss, ByCssContainingText, ById, ByTagName, ByXPath, NativeElementLocator, Selector } from '@serenity-js/web';
|
|
3
|
+
import { match } from 'tiny-types';
|
|
4
|
+
import * as wdio from 'webdriverio';
|
|
5
|
+
|
|
6
|
+
import { WebdriverIONativeElementRoot } from './WebdriverIONativeElementRoot';
|
|
7
|
+
|
|
8
|
+
const f = format({ markQuestions: false });
|
|
9
|
+
|
|
10
|
+
export class WebdriverIONativeElementLocator implements NativeElementLocator<wdio.Element<'async'>> {
|
|
11
|
+
constructor(private readonly resolver: () => Promise<WebdriverIONativeElementRoot> | WebdriverIONativeElementRoot) {
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @desc
|
|
16
|
+
* Retrieves a {@link @serenity-js/web/lib/screenplay/models~PageElement} which text includes `text`
|
|
17
|
+
* and which can be located using the CSS `selector`.
|
|
18
|
+
*
|
|
19
|
+
* Under the hood, this command uses https://webdriver.io/docs/selectors#element-with-certain-text
|
|
20
|
+
*
|
|
21
|
+
* This means that only some selectors are supported. For example:
|
|
22
|
+
* - 'h1'
|
|
23
|
+
* - 'h1.some-class'
|
|
24
|
+
* - '#someId'
|
|
25
|
+
* - 'h1[attribute-name="attribute-selector"]
|
|
26
|
+
*
|
|
27
|
+
* Notably, complex CSS selectors such as 'header h1' or 'header > h1' **WON'T WORK**.
|
|
28
|
+
*
|
|
29
|
+
* @param {Selector<T>} selector
|
|
30
|
+
* @returns {Promise<wdio.Element<'async'>>}
|
|
31
|
+
*/
|
|
32
|
+
async locate<T>(selector: Selector<T>): Promise<wdio.Element<'async'>> {
|
|
33
|
+
const resolver = await this.resolver();
|
|
34
|
+
|
|
35
|
+
const byLocator = match<Selector<unknown>, string>(selector)
|
|
36
|
+
.when(ByCss, (s: ByCss) =>
|
|
37
|
+
s.value,
|
|
38
|
+
)
|
|
39
|
+
.when(ByCssContainingText, (s: ByCssContainingText) =>
|
|
40
|
+
`${ s.value }*=${ s.text }`,
|
|
41
|
+
)
|
|
42
|
+
.when(ById, (s: ById) =>
|
|
43
|
+
`#${ s.value }`,
|
|
44
|
+
)
|
|
45
|
+
.when(ByTagName, (s: ByTagName) =>
|
|
46
|
+
`<${ s.value } />`,
|
|
47
|
+
)
|
|
48
|
+
.when(ByXPath, (s: ByXPath) =>
|
|
49
|
+
s.value,
|
|
50
|
+
)
|
|
51
|
+
.else(() => {
|
|
52
|
+
throw new LogicError(f`Selector ${ selector } not supported`);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
return resolver.$(byLocator);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async locateAll<T>(selector: Selector<T>): Promise<Array<wdio.Element<'async'>>> {
|
|
59
|
+
const resolver = await this.resolver();
|
|
60
|
+
|
|
61
|
+
const byLocator = match<Selector<unknown>, string>(selector)
|
|
62
|
+
.when(ByCss, (s: ByCss) =>
|
|
63
|
+
s.value,
|
|
64
|
+
)
|
|
65
|
+
.when(ByTagName, (s: ByTagName) =>
|
|
66
|
+
`<${ s.value } />`,
|
|
67
|
+
)
|
|
68
|
+
.when(ByXPath, (s: ByXPath) =>
|
|
69
|
+
s.value,
|
|
70
|
+
)
|
|
71
|
+
.else(() => {
|
|
72
|
+
throw new LogicError(f`Selector ${ selector } not supported`);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
return resolver.$$(byLocator);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { PageElement } from '@serenity-js/web';
|
|
2
2
|
import * as wdio from 'webdriverio';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { WebdriverIONativeElementLocator } from './WebdriverIONativeElementLocator';
|
|
5
5
|
|
|
6
6
|
export class WebdriverIOPageElement
|
|
7
|
-
extends PageElement<
|
|
7
|
+
extends PageElement<wdio.Element<'async'>>
|
|
8
8
|
{
|
|
9
|
-
of(parent: WebdriverIOPageElement):
|
|
10
|
-
return new WebdriverIOPageElement(() => parent.nativeElement()
|
|
9
|
+
of(parent: WebdriverIOPageElement): WebdriverIOPageElement {
|
|
10
|
+
return new WebdriverIOPageElement(this.selector, new WebdriverIONativeElementLocator(() => parent.nativeElement()));
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
async clearValue(): Promise<void> {
|
|
@@ -70,11 +70,6 @@ export class WebdriverIOPageElement
|
|
|
70
70
|
return element.isClickable();
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
async isDisplayed(): Promise<boolean> {
|
|
74
|
-
const element = await this.nativeElement();
|
|
75
|
-
return element.isDisplayed();
|
|
76
|
-
}
|
|
77
|
-
|
|
78
73
|
async isEnabled(): Promise<boolean> {
|
|
79
74
|
const element = await this.nativeElement();
|
|
80
75
|
return element.isEnabled();
|
|
@@ -89,4 +84,62 @@ export class WebdriverIOPageElement
|
|
|
89
84
|
const element = await this.nativeElement();
|
|
90
85
|
return element.isSelected();
|
|
91
86
|
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @desc
|
|
90
|
+
* Checks if the PageElement:
|
|
91
|
+
* - is displayed,
|
|
92
|
+
* - is visible within the browser viewport,
|
|
93
|
+
* - has not its center covered by other elements
|
|
94
|
+
*
|
|
95
|
+
* @see https://webdriver.io/docs/api/element/isDisplayedInViewport/
|
|
96
|
+
*/
|
|
97
|
+
async isVisible(): Promise<boolean> { // isVisible?
|
|
98
|
+
const element = await this.nativeElement();
|
|
99
|
+
|
|
100
|
+
if (! await element.isDisplayed()) {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (! await element.isDisplayedInViewport()) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const browser = await this.browserFor(element);
|
|
109
|
+
|
|
110
|
+
/* eslint-disable no-var */
|
|
111
|
+
|
|
112
|
+
// get element at cx/cy and see if the element we found is our element, and therefore it's visible.
|
|
113
|
+
return browser.execute(
|
|
114
|
+
/* istanbul ignore next */
|
|
115
|
+
function isVisible(element: any) {
|
|
116
|
+
if (! element.getBoundingClientRect) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
var
|
|
121
|
+
box = element.getBoundingClientRect(),
|
|
122
|
+
cx = box.left + box.width / 2,
|
|
123
|
+
cy = box.top + box.height / 2,
|
|
124
|
+
e = document.elementFromPoint(cx, cy);
|
|
125
|
+
|
|
126
|
+
for (; e; e = e.parentElement) {
|
|
127
|
+
if (e === element)
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
return false;
|
|
131
|
+
},
|
|
132
|
+
element,
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
/* eslint-enable no-var */
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// based on https://github.com/webdriverio/webdriverio/blob/dec6da76b0e218af935dbf39735ae3491d5edd8c/packages/webdriverio/src/utils/index.ts#L98
|
|
139
|
+
private async browserFor(nativeElement: wdio.Element<'async'> | wdio.Browser<'async'>): Promise<wdio.Browser<'async'>> {
|
|
140
|
+
const element = nativeElement as wdio.Element<'async'>;
|
|
141
|
+
return element.parent
|
|
142
|
+
? this.browserFor(element.parent)
|
|
143
|
+
: nativeElement
|
|
144
|
+
}
|
|
92
145
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from './WebdriverIOCookie';
|
|
2
2
|
export * from './WebdriverIOModalDialog';
|
|
3
|
+
export * from './WebdriverIONativeElementLocator';
|
|
3
4
|
export * from './WebdriverIONativeElementRoot';
|
|
4
5
|
export * from './WebdriverIOPage';
|
|
5
6
|
export * from './WebdriverIOPageElement';
|
|
6
|
-
export * from './WebdriverIOPageElements';
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { PageElement, PageElements } from '@serenity-js/web';
|
|
2
|
-
import * as wdio from 'webdriverio';
|
|
3
|
-
import { WebdriverIONativeElementRoot } from './WebdriverIONativeElementRoot';
|
|
4
|
-
import { WebdriverIOPageElement } from './WebdriverIOPageElement';
|
|
5
|
-
export declare class WebdriverIOPageElements extends PageElements<WebdriverIONativeElementRoot, wdio.ElementArray, wdio.Element<'async'>> {
|
|
6
|
-
of(parent: PageElement<WebdriverIONativeElementRoot, wdio.Element<'async'>>): WebdriverIOPageElements;
|
|
7
|
-
count(): Promise<number>;
|
|
8
|
-
first(): Promise<WebdriverIOPageElement>;
|
|
9
|
-
last(): Promise<WebdriverIOPageElement>;
|
|
10
|
-
get(index: number): Promise<WebdriverIOPageElement>;
|
|
11
|
-
private elementAt;
|
|
12
|
-
map<O>(fn: (element: PageElement, index?: number, elements?: PageElements) => Promise<O> | O): Promise<O[]>;
|
|
13
|
-
filter(fn: (element: PageElement, index?: number) => Promise<boolean> | boolean): WebdriverIOPageElements;
|
|
14
|
-
forEach(fn: (element: PageElement, index?: number, elements?: PageElements) => Promise<void> | void): Promise<void>;
|
|
15
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WebdriverIOPageElements = void 0;
|
|
4
|
-
const core_1 = require("@serenity-js/core");
|
|
5
|
-
const web_1 = require("@serenity-js/web");
|
|
6
|
-
const WebdriverIOPageElement_1 = require("./WebdriverIOPageElement");
|
|
7
|
-
class WebdriverIOPageElements extends web_1.PageElements {
|
|
8
|
-
of(parent) {
|
|
9
|
-
return new WebdriverIOPageElements(() => parent.nativeElement(), this.locator);
|
|
10
|
-
}
|
|
11
|
-
async count() {
|
|
12
|
-
const elements = await this.nativeElementList();
|
|
13
|
-
return elements.length;
|
|
14
|
-
}
|
|
15
|
-
first() {
|
|
16
|
-
return this.elementAt(0);
|
|
17
|
-
}
|
|
18
|
-
async last() {
|
|
19
|
-
const elements = await this.nativeElementList();
|
|
20
|
-
const index = elements.length - 1;
|
|
21
|
-
return this.elementAt(index);
|
|
22
|
-
}
|
|
23
|
-
get(index) {
|
|
24
|
-
return this.elementAt(index);
|
|
25
|
-
}
|
|
26
|
-
async elementAt(index) {
|
|
27
|
-
const elements = await this.nativeElementList();
|
|
28
|
-
if (!elements[index]) {
|
|
29
|
-
throw new core_1.LogicError(`There's no item at index ${index}`);
|
|
30
|
-
}
|
|
31
|
-
return new WebdriverIOPageElement_1.WebdriverIOPageElement(this.context, () => elements[index]);
|
|
32
|
-
}
|
|
33
|
-
async map(fn) {
|
|
34
|
-
const elements = await this.nativeElementList();
|
|
35
|
-
return Promise.all(elements.map((element, index) => fn(new WebdriverIOPageElement_1.WebdriverIOPageElement(this.context, () => element), index, this)));
|
|
36
|
-
}
|
|
37
|
-
filter(fn) {
|
|
38
|
-
return new WebdriverIOPageElements(this.context, async (context) => {
|
|
39
|
-
const elements = await this.locator(context);
|
|
40
|
-
const matching = await Promise.all(elements.map(async (nativeElement, index) => {
|
|
41
|
-
const element = new WebdriverIOPageElement_1.WebdriverIOPageElement(this.context, () => nativeElement);
|
|
42
|
-
const matches = await fn(element, index);
|
|
43
|
-
return matches
|
|
44
|
-
? nativeElement
|
|
45
|
-
: undefined;
|
|
46
|
-
}));
|
|
47
|
-
const results = matching.filter((element) => {
|
|
48
|
-
return element !== undefined;
|
|
49
|
-
});
|
|
50
|
-
results.selector = elements.selector;
|
|
51
|
-
results.parent = elements.parent;
|
|
52
|
-
results.foundWith = elements.foundWith;
|
|
53
|
-
results.props = elements.props;
|
|
54
|
-
return results;
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
async forEach(fn) {
|
|
58
|
-
const elements = await this.nativeElementList();
|
|
59
|
-
return elements.reduce((previous, element, index) => {
|
|
60
|
-
return previous.then(() => fn(new WebdriverIOPageElement_1.WebdriverIOPageElement(this.context, () => element), index, this));
|
|
61
|
-
}, Promise.resolve());
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
exports.WebdriverIOPageElements = WebdriverIOPageElements;
|
|
65
|
-
//# sourceMappingURL=WebdriverIOPageElements.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"WebdriverIOPageElements.js","sourceRoot":"","sources":["../../../src/screenplay/models/WebdriverIOPageElements.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { LogicError } from '@serenity-js/core';
|
|
2
|
-
import { PageElement, PageElements } from '@serenity-js/web';
|
|
3
|
-
import * as wdio from 'webdriverio';
|
|
4
|
-
|
|
5
|
-
import { WebdriverIONativeElementRoot } from './WebdriverIONativeElementRoot';
|
|
6
|
-
import { WebdriverIOPageElement } from './WebdriverIOPageElement';
|
|
7
|
-
|
|
8
|
-
export class WebdriverIOPageElements
|
|
9
|
-
extends PageElements<WebdriverIONativeElementRoot, wdio.ElementArray, wdio.Element<'async'>>
|
|
10
|
-
{
|
|
11
|
-
of(parent: PageElement<WebdriverIONativeElementRoot, wdio.Element<'async'>>): WebdriverIOPageElements {
|
|
12
|
-
return new WebdriverIOPageElements(() => parent.nativeElement(), this.locator);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
async count(): Promise<number> {
|
|
16
|
-
const elements = await this.nativeElementList();
|
|
17
|
-
return elements.length;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
first(): Promise<WebdriverIOPageElement> {
|
|
21
|
-
return this.elementAt(0);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
async last(): Promise<WebdriverIOPageElement> {
|
|
25
|
-
const elements = await this.nativeElementList();
|
|
26
|
-
const index = elements.length - 1;
|
|
27
|
-
|
|
28
|
-
return this.elementAt(index);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
get(index: number): Promise<WebdriverIOPageElement> {
|
|
32
|
-
return this.elementAt(index);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
private async elementAt(index: number): Promise<WebdriverIOPageElement> {
|
|
36
|
-
const elements = await this.nativeElementList();
|
|
37
|
-
|
|
38
|
-
if (! elements[index]) {
|
|
39
|
-
throw new LogicError(`There's no item at index ${ index }`);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return new WebdriverIOPageElement(this.context, () => elements[index])
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
async map<O>(fn: (element: PageElement, index?: number, elements?: PageElements) => Promise<O> | O): Promise<O[]> {
|
|
46
|
-
const elements = await this.nativeElementList();
|
|
47
|
-
|
|
48
|
-
return Promise.all(
|
|
49
|
-
elements.map((element, index) =>
|
|
50
|
-
fn(new WebdriverIOPageElement(this.context, () => element), index, this)
|
|
51
|
-
)
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
filter(fn: (element: PageElement, index?: number) => Promise<boolean> | boolean): WebdriverIOPageElements {
|
|
56
|
-
|
|
57
|
-
return new WebdriverIOPageElements(this.context, async context => {
|
|
58
|
-
const elements = await this.locator(context);
|
|
59
|
-
|
|
60
|
-
const matching = await Promise.all(
|
|
61
|
-
elements.map(async (nativeElement: wdio.Element<'async'>, index: number) => {
|
|
62
|
-
const element = new WebdriverIOPageElement(this.context, () => nativeElement);
|
|
63
|
-
const matches = await fn(element, index);
|
|
64
|
-
|
|
65
|
-
return matches
|
|
66
|
-
? nativeElement
|
|
67
|
-
: undefined;
|
|
68
|
-
})
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
const results = matching.filter((element: wdio.Element<'async'> | undefined) => {
|
|
72
|
-
return element !== undefined;
|
|
73
|
-
}) as wdio.ElementArray;
|
|
74
|
-
|
|
75
|
-
results.selector = elements.selector;
|
|
76
|
-
results.parent = elements.parent;
|
|
77
|
-
results.foundWith = elements.foundWith;
|
|
78
|
-
results.props = elements.props;
|
|
79
|
-
|
|
80
|
-
return results;
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
async forEach(fn: (element: PageElement, index?: number, elements?: PageElements) => Promise<void> | void): Promise<void> {
|
|
85
|
-
const elements = await this.nativeElementList();
|
|
86
|
-
|
|
87
|
-
return elements.reduce((previous: Promise<void>, element: wdio.Element<'async'>, index: number) => {
|
|
88
|
-
return previous.then(() => fn(new WebdriverIOPageElement(this.context, () => element), index, this));
|
|
89
|
-
}, Promise.resolve());
|
|
90
|
-
}
|
|
91
|
-
}
|