@serenity-js/web 3.0.0-rc.4 → 3.0.0-rc.5
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 +11 -0
- package/lib/screenplay/abilities/BrowseTheWeb.d.ts +6 -6
- package/lib/screenplay/abilities/BrowseTheWeb.js +13 -0
- package/lib/screenplay/abilities/BrowseTheWeb.js.map +1 -1
- package/lib/screenplay/interactions/Press.js +0 -1
- package/lib/screenplay/interactions/Press.js.map +1 -1
- package/lib/screenplay/models/Locator.d.ts +14 -0
- package/lib/screenplay/models/Locator.js +19 -0
- package/lib/screenplay/models/Locator.js.map +1 -0
- package/lib/screenplay/models/PageElement.d.ts +5 -7
- package/lib/screenplay/models/PageElement.js +7 -13
- package/lib/screenplay/models/PageElement.js.map +1 -1
- package/lib/screenplay/models/PageElements.d.ts +7 -9
- package/lib/screenplay/models/PageElements.js +30 -28
- package/lib/screenplay/models/PageElements.js.map +1 -1
- package/lib/screenplay/models/index.d.ts +1 -2
- package/lib/screenplay/models/index.js +1 -2
- package/lib/screenplay/models/index.js.map +1 -1
- package/lib/screenplay/models/selectors/ByCss.d.ts +3 -1
- package/lib/screenplay/models/selectors/ByCss.js +4 -0
- package/lib/screenplay/models/selectors/ByCss.js.map +1 -1
- package/lib/screenplay/models/selectors/ByCssContainingText.d.ts +3 -2
- package/lib/screenplay/models/selectors/ByCssContainingText.js +3 -2
- package/lib/screenplay/models/selectors/ByCssContainingText.js.map +1 -1
- package/lib/screenplay/models/selectors/ById.d.ts +3 -1
- package/lib/screenplay/models/selectors/ById.js +4 -0
- package/lib/screenplay/models/selectors/ById.js.map +1 -1
- package/lib/screenplay/models/selectors/ByTagName.d.ts +3 -1
- package/lib/screenplay/models/selectors/ByTagName.js +4 -0
- package/lib/screenplay/models/selectors/ByTagName.js.map +1 -1
- package/lib/screenplay/models/selectors/ByXPath.d.ts +3 -1
- package/lib/screenplay/models/selectors/ByXPath.js +4 -0
- package/lib/screenplay/models/selectors/ByXPath.js.map +1 -1
- package/lib/screenplay/models/selectors/Selector.d.ts +1 -3
- package/lib/screenplay/models/selectors/Selector.js +1 -3
- package/lib/screenplay/models/selectors/Selector.js.map +1 -1
- package/lib/screenplay/questions/Text.d.ts +2 -1
- package/lib/screenplay/questions/Text.js +16 -10
- package/lib/screenplay/questions/Text.js.map +1 -1
- package/package.json +4 -4
- package/src/screenplay/abilities/BrowseTheWeb.ts +25 -8
- package/src/screenplay/interactions/Press.ts +0 -1
- package/src/screenplay/models/Locator.ts +25 -0
- package/src/screenplay/models/PageElement.ts +11 -20
- package/src/screenplay/models/PageElements.ts +33 -36
- package/src/screenplay/models/index.ts +1 -2
- package/src/screenplay/models/selectors/ByCss.ts +4 -1
- package/src/screenplay/models/selectors/ByCssContainingText.ts +3 -3
- package/src/screenplay/models/selectors/ById.ts +4 -1
- package/src/screenplay/models/selectors/ByTagName.ts +4 -1
- package/src/screenplay/models/selectors/ByXPath.ts +4 -1
- package/src/screenplay/models/selectors/Selector.ts +2 -4
- package/src/screenplay/questions/Text.ts +30 -4
- package/lib/screenplay/models/NativeElementLocator.d.ts +0 -5
- package/lib/screenplay/models/NativeElementLocator.js +0 -3
- package/lib/screenplay/models/NativeElementLocator.js.map +0 -1
- package/lib/screenplay/models/PassThroughNativeElementLocator.d.ts +0 -9
- package/lib/screenplay/models/PassThroughNativeElementLocator.js +0 -17
- package/lib/screenplay/models/PassThroughNativeElementLocator.js.map +0 -1
- package/src/screenplay/models/NativeElementLocator.ts +0 -6
- package/src/screenplay/models/PassThroughNativeElementLocator.ts +0 -18
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
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.5](https://github.com/serenity-js/serenity-js/compare/v3.0.0-rc.4...v3.0.0-rc.5) (2022-01-07)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **web:** support for advanced PageElement locator patterns ([c1ff8b7](https://github.com/serenity-js/serenity-js/commit/c1ff8b7539ebc1da8f79ea2b6d17bb01c42f443d)), closes [#1084](https://github.com/serenity-js/serenity-js/issues/1084)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
# [3.0.0-rc.4](https://github.com/serenity-js/serenity-js/compare/v3.0.0-rc.3...v3.0.0-rc.4) (2021-12-30)
|
|
7
18
|
|
|
8
19
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Ability, Duration, UsesAbilities } from '@serenity-js/core';
|
|
2
2
|
import { Key } from '../../input';
|
|
3
|
-
import { Cookie, CookieData,
|
|
3
|
+
import { Cookie, CookieData, Locator, ModalDialog, Page, PageElement, Selector } from '../models';
|
|
4
4
|
import { BrowserCapabilities } from './BrowserCapabilities';
|
|
5
|
-
export declare abstract class BrowseTheWeb<Native_Element_Type = any> implements Ability {
|
|
5
|
+
export declare abstract class BrowseTheWeb<Native_Element_Type = any, Native_Root_Element_Type = unknown> implements Ability {
|
|
6
|
+
protected locators: Map<new (...args: unknown[]) => Selector, (selector: Selector) => Locator<Native_Element_Type, Native_Root_Element_Type>>;
|
|
6
7
|
/**
|
|
7
8
|
* @desc
|
|
8
9
|
* Used to access the Actor's ability to {@link BrowseTheWeb}
|
|
@@ -12,16 +13,15 @@ export declare abstract class BrowseTheWeb<Native_Element_Type = any> implements
|
|
|
12
13
|
* @param {@serenity-js/core/lib/screenplay/actor~UsesAbilities} actor
|
|
13
14
|
* @return {BrowseTheWeb}
|
|
14
15
|
*/
|
|
15
|
-
static as(actor: UsesAbilities): BrowseTheWeb
|
|
16
|
+
static as<NET = any, NRET = unknown>(actor: UsesAbilities): BrowseTheWeb<NET, NRET>;
|
|
17
|
+
constructor(locators: Map<new (...args: unknown[]) => Selector, (selector: Selector) => Locator<Native_Element_Type, Native_Root_Element_Type>>);
|
|
16
18
|
abstract navigateTo(destination: string): Promise<void>;
|
|
17
19
|
abstract navigateBack(): Promise<void>;
|
|
18
20
|
abstract navigateForward(): Promise<void>;
|
|
19
21
|
abstract reloadPage(): Promise<void>;
|
|
20
22
|
abstract waitFor(duration: Duration): Promise<void>;
|
|
21
23
|
abstract waitUntil(condition: () => boolean | Promise<boolean>, timeout: Duration): Promise<void>;
|
|
22
|
-
|
|
23
|
-
abstract locateAll<T>(selector: Selector<T>, locator?: NativeElementLocator<Native_Element_Type>): Promise<Array<PageElement<Native_Element_Type>>>;
|
|
24
|
-
abstract nativeElementLocator(): NativeElementLocator<Native_Element_Type>;
|
|
24
|
+
locate(selector: Selector): Locator<Native_Element_Type, Native_Root_Element_Type>;
|
|
25
25
|
abstract browserCapabilities(): Promise<BrowserCapabilities>;
|
|
26
26
|
abstract sendKeys(keys: Array<Key | string>): Promise<void>;
|
|
27
27
|
abstract executeScript<Result, InnerArguments extends any[]>(script: string | ((...parameters: InnerArguments) => Result), ...args: InnerArguments): Promise<Result>;
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.BrowseTheWeb = void 0;
|
|
4
|
+
const core_1 = require("@serenity-js/core");
|
|
5
|
+
const f = (0, core_1.format)({ markQuestions: true });
|
|
4
6
|
class BrowseTheWeb {
|
|
7
|
+
constructor(locators) {
|
|
8
|
+
this.locators = locators;
|
|
9
|
+
}
|
|
5
10
|
/**
|
|
6
11
|
* @desc
|
|
7
12
|
* Used to access the Actor's ability to {@link BrowseTheWeb}
|
|
@@ -14,6 +19,14 @@ class BrowseTheWeb {
|
|
|
14
19
|
static as(actor) {
|
|
15
20
|
return actor.abilityTo(BrowseTheWeb);
|
|
16
21
|
}
|
|
22
|
+
locate(selector) {
|
|
23
|
+
for (const [type, locatorFactory] of this.locators) {
|
|
24
|
+
if (selector instanceof type) {
|
|
25
|
+
return locatorFactory(selector);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
throw new core_1.LogicError(f `${selector} is not supported by ${this.constructor.name}`);
|
|
29
|
+
}
|
|
17
30
|
}
|
|
18
31
|
exports.BrowseTheWeb = BrowseTheWeb;
|
|
19
32
|
//# sourceMappingURL=BrowseTheWeb.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BrowseTheWeb.js","sourceRoot":"","sources":["../../../src/screenplay/abilities/BrowseTheWeb.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"BrowseTheWeb.js","sourceRoot":"","sources":["../../../src/screenplay/abilities/BrowseTheWeb.ts"],"names":[],"mappings":";;;AAAA,4CAAyF;AAMzF,MAAM,CAAC,GAAG,IAAA,aAAM,EAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;AAE1C,MAAsB,YAAY;IAc9B,YACc,QAIT;QAJS,aAAQ,GAAR,QAAQ,CAIjB;IAEL,CAAC;IApBD;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,CAA4B,KAAoB;QACrD,OAAO,KAAK,CAAC,SAAS,CAAC,YAAY,CAA4B,CAAC;IACpE,CAAC;IAuBD,MAAM,CAAC,QAAkB;QACrB,KAAK,MAAM,CAAE,IAAI,EAAE,cAAc,CAAE,IAAI,IAAI,CAAC,QAAQ,EAAE;YAClD,IAAI,QAAQ,YAAY,IAAI,EAAE;gBAC1B,OAAO,cAAc,CAAC,QAAQ,CAAC,CAAC;aACnC;SACJ;QAED,MAAM,IAAI,iBAAU,CAAC,CAAC,CAAC,GAAI,QAAS,wBAAyB,IAAI,CAAC,WAAW,CAAC,IAAK,EAAE,CAAC,CAAC;IAC3F,CAAC;CA+CJ;AA1FD,oCA0FC"}
|
|
@@ -112,7 +112,6 @@ class PressKeyInField extends PageElementInteraction_1.PageElementInteraction {
|
|
|
112
112
|
const field = await this.resolve(actor, this.field);
|
|
113
113
|
const keys = await actor.answer(this.keys);
|
|
114
114
|
// fix for protractor
|
|
115
|
-
// todo: should this wait on focus to occur?
|
|
116
115
|
await abilities_1.BrowseTheWeb.as(actor).executeScript(
|
|
117
116
|
/* istanbul ignore next */
|
|
118
117
|
function focus(element) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Press.js","sourceRoot":"","sources":["../../../src/screenplay/interactions/Press.ts"],"names":[],"mappings":";;;AAAA,4CAAiH;AACjH,iDAA+D;AAE/D,uCAAkC;AAClC,4CAA4C;AAE5C,qEAAkE;AAGlE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,MAAa,KAAM,SAAQ,+CAAsB;IAmB7C;;;OAGG;IACH,YACqB,IAAqC;QAEtD,KAAK,CAAC,IAAA,cAAS,EAAC,kBAAmB,IAAK,EAAE,CAAC,CAAC;QAF3B,SAAI,GAAJ,IAAI,CAAiC;IAG1D,CAAC;IAzBD;;;;;;;;OAQG;IACH,MAAM,CAAC,GAAG,CAAC,GAAG,IAAwD;QAClE,OAAO,IAAI,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,EAAE,CAAC,KAA8B,CAAC,6CAA6C;QAC3E,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;IAChD,CAAC;IAYD;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,SAAS,CAAC,KAAuC;QACnD,MAAM,IAAI,GAAI,MAAM,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,OAAO,wBAAY,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC;CACJ;AA/CD,sBA+CC;AAED,MAAM,eAAgB,SAAQ,+CAAsB;IAChD;;;;;;OAMG;IACH,YACqB,IAAqC,EACrC,KAA8B,CAAC,kDAAkD;QAElG,KAAK,CAAC,IAAA,cAAS,EAAC,kBAAmB,IAAK,OAAQ,KAAM,EAAE,CAAC,CAAC;QAHzC,SAAI,GAAJ,IAAI,CAAiC;QACrC,UAAK,GAAL,KAAK,CAAyB;IAGnD,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,KAAuC;QACnD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACpD,MAAM,IAAI,GAAI,MAAM,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE5C,qBAAqB;QACrB,
|
|
1
|
+
{"version":3,"file":"Press.js","sourceRoot":"","sources":["../../../src/screenplay/interactions/Press.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { PageElement } from './PageElement';
|
|
2
|
+
import { Selector } from './selectors';
|
|
3
|
+
export declare abstract class Locator<Native_Element_Type, Native_Root_Element_Type = any, Selector_Type extends Selector = Selector> {
|
|
4
|
+
protected readonly parentRoot: () => Promise<Native_Root_Element_Type> | Native_Root_Element_Type;
|
|
5
|
+
protected readonly selector: Selector_Type;
|
|
6
|
+
protected readonly locateElement: (root: Native_Root_Element_Type) => Promise<Native_Element_Type> | Native_Element_Type;
|
|
7
|
+
protected readonly locateAllElements: (root: Native_Root_Element_Type) => Promise<Array<Native_Element_Type>> | Array<Native_Element_Type>;
|
|
8
|
+
constructor(parentRoot: () => Promise<Native_Root_Element_Type> | Native_Root_Element_Type, selector: Selector_Type, locateElement: (root: Native_Root_Element_Type) => Promise<Native_Element_Type> | Native_Element_Type, locateAllElements: (root: Native_Root_Element_Type) => Promise<Array<Native_Element_Type>> | Array<Native_Element_Type>);
|
|
9
|
+
nativeElement(): Promise<Native_Element_Type>;
|
|
10
|
+
abstract of(parent: Locator<Native_Element_Type, Native_Root_Element_Type>): Locator<Native_Element_Type, Native_Root_Element_Type>;
|
|
11
|
+
abstract element(): PageElement<Native_Element_Type>;
|
|
12
|
+
abstract allElements(): Promise<Array<PageElement<Native_Element_Type>>>;
|
|
13
|
+
toString(): string;
|
|
14
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Locator = void 0;
|
|
4
|
+
class Locator {
|
|
5
|
+
constructor(parentRoot, selector, locateElement, locateAllElements) {
|
|
6
|
+
this.parentRoot = parentRoot;
|
|
7
|
+
this.selector = selector;
|
|
8
|
+
this.locateElement = locateElement;
|
|
9
|
+
this.locateAllElements = locateAllElements;
|
|
10
|
+
}
|
|
11
|
+
async nativeElement() {
|
|
12
|
+
return this.locateElement(await this.parentRoot());
|
|
13
|
+
}
|
|
14
|
+
toString() {
|
|
15
|
+
return this.selector.toString();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.Locator = Locator;
|
|
19
|
+
//# sourceMappingURL=Locator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Locator.js","sourceRoot":"","sources":["../../../src/screenplay/models/Locator.ts"],"names":[],"mappings":";;;AAGA,MAAsB,OAAO;IACzB,YACuB,UAA8E,EAC9E,QAAuB,EACvB,aAAqG,EACrG,iBAAuH;QAHvH,eAAU,GAAV,UAAU,CAAoE;QAC9E,aAAQ,GAAR,QAAQ,CAAe;QACvB,kBAAa,GAAb,aAAa,CAAwF;QACrG,sBAAiB,GAAjB,iBAAiB,CAAsG;IAE9I,CAAC;IAEM,KAAK,CAAC,aAAa;QACtB,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IACvD,CAAC;IAOD,QAAQ;QACJ,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;IACpC,CAAC;CACJ;AArBD,0BAqBC"}
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { Adapter, Answerable, Question } from '@serenity-js/core';
|
|
2
|
-
import {
|
|
2
|
+
import { Locator } from './Locator';
|
|
3
3
|
import { Selector } from './selectors';
|
|
4
4
|
export declare abstract class PageElement<Native_Element_Type = any> {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
static located<NET, ST>(selector: Answerable<Selector<ST>>): Question<Promise<PageElement<NET>>> & Adapter<PageElement<NET>>;
|
|
5
|
+
readonly locator: Locator<Native_Element_Type>;
|
|
6
|
+
static located<NET>(selector: Answerable<Selector>): Question<Promise<PageElement<NET>>> & Adapter<PageElement<NET>>;
|
|
8
7
|
static of<NET>(childElement: Answerable<PageElement<NET>>, parentElement: Answerable<PageElement<NET>>): Question<Promise<PageElement<NET>>> & Adapter<PageElement<NET>>;
|
|
9
|
-
constructor(
|
|
10
|
-
abstract of(
|
|
8
|
+
constructor(locator: Locator<Native_Element_Type>);
|
|
9
|
+
abstract of(parentElement: PageElement<Native_Element_Type>): PageElement<Native_Element_Type>;
|
|
11
10
|
nativeElement(): Promise<Native_Element_Type>;
|
|
12
|
-
nativeElementLocator(): NativeElementLocator<Native_Element_Type>;
|
|
13
11
|
toString(): string;
|
|
14
12
|
abstract enterValue(value: string | number | Array<string | number>): Promise<void>;
|
|
15
13
|
abstract clearValue(): Promise<void>;
|
|
@@ -2,19 +2,21 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PageElement = void 0;
|
|
4
4
|
const core_1 = require("@serenity-js/core");
|
|
5
|
+
const tiny_types_1 = require("tiny-types");
|
|
5
6
|
const abilities_1 = require("../abilities");
|
|
6
7
|
const d = (0, core_1.format)({ markQuestions: false });
|
|
7
8
|
class PageElement {
|
|
8
|
-
constructor(
|
|
9
|
-
this.selector = selector;
|
|
9
|
+
constructor(locator) {
|
|
10
10
|
this.locator = locator;
|
|
11
|
+
(0, tiny_types_1.ensure)('native element locator', locator, (0, tiny_types_1.isDefined)());
|
|
11
12
|
}
|
|
12
13
|
static located(selector) {
|
|
13
14
|
return core_1.Question.about(d `page element located ${selector}`, async (actor) => {
|
|
14
15
|
const bySelector = await actor.answer(selector);
|
|
15
|
-
return abilities_1.BrowseTheWeb.as(actor).locate(bySelector);
|
|
16
|
+
return abilities_1.BrowseTheWeb.as(actor).locate(bySelector).element();
|
|
16
17
|
});
|
|
17
18
|
}
|
|
19
|
+
// todo: review usages and consider removing if not used
|
|
18
20
|
static of(childElement, parentElement) {
|
|
19
21
|
return core_1.Question.about(d `${childElement} of ${parentElement})`, async (actor) => {
|
|
20
22
|
const child = await actor.answer(childElement);
|
|
@@ -23,18 +25,10 @@ class PageElement {
|
|
|
23
25
|
});
|
|
24
26
|
}
|
|
25
27
|
async nativeElement() {
|
|
26
|
-
|
|
27
|
-
return this.locator.locate(this.selector);
|
|
28
|
-
}
|
|
29
|
-
catch (error) {
|
|
30
|
-
throw new core_1.LogicError(`Couldn't find element`, error);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
nativeElementLocator() {
|
|
34
|
-
return this.locator;
|
|
28
|
+
return this.locator.nativeElement();
|
|
35
29
|
}
|
|
36
30
|
toString() {
|
|
37
|
-
return `PageElement located ${this.
|
|
31
|
+
return `PageElement located ${this.locator.toString()}`;
|
|
38
32
|
}
|
|
39
33
|
}
|
|
40
34
|
exports.PageElement = PageElement;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PageElement.js","sourceRoot":"","sources":["../../../src/screenplay/models/PageElement.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"PageElement.js","sourceRoot":"","sources":["../../../src/screenplay/models/PageElement.ts"],"names":[],"mappings":";;;AAAA,4CAA0E;AAC1E,2CAA+C;AAE/C,4CAA4C;AAI5C,MAAM,CAAC,GAAG,IAAA,aAAM,EAAC,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC;AAE3C,MAAsB,WAAW;IAmB7B,YAA4B,OAAqC;QAArC,YAAO,GAAP,OAAO,CAA8B;QAC7D,IAAA,mBAAM,EAAC,wBAAwB,EAAE,OAAO,EAAE,IAAA,sBAAS,GAAE,CAAC,CAAC;IAC3D,CAAC;IAnBD,MAAM,CAAC,OAAO,CAAM,QAA8B;QAC9C,OAAO,eAAQ,CAAC,KAAK,CAAC,CAAC,CAAA,wBAAyB,QAAS,EAAE,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE;YACvE,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAChD,OAAO,wBAAY,CAAC,EAAE,CAAM,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC;QACpE,CAAC,CAAC,CAAC;IACP,CAAC;IAED,wDAAwD;IACxD,MAAM,CAAC,EAAE,CAAM,YAA0C,EAAE,aAA2C;QAClG,OAAO,eAAQ,CAAC,KAAK,CAAC,CAAC,CAAA,GAAI,YAAa,OAAQ,aAAc,GAAG,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE;YAC7E,MAAM,KAAK,GAAO,MAAM,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YACnD,MAAM,MAAM,GAAM,MAAM,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;YAEpD,OAAO,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;IACP,CAAC;IAQD,KAAK,CAAC,aAAa;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;IACxC,CAAC;IAED,QAAQ;QACJ,OAAO,uBAAwB,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAG,EAAE,CAAC;IAC9D,CAAC;CAoBJ;AAnDD,kCAmDC"}
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import { Answerable, List } from '@serenity-js/core';
|
|
1
|
+
import { Answerable, List, MetaQuestion, Question } from '@serenity-js/core';
|
|
2
|
+
import { Locator } from './Locator';
|
|
2
3
|
import { PageElement } from './PageElement';
|
|
3
4
|
import { Selector } from './selectors';
|
|
4
|
-
export declare class PageElements<Native_Element_Type = any> extends List<PageElement<Native_Element_Type>> {
|
|
5
|
-
protected readonly
|
|
6
|
-
|
|
7
|
-
static located<NET, ST>(selector: Answerable<Selector<ST>>): PageElements<NET>;
|
|
5
|
+
export declare class PageElements<Native_Element_Type = any> extends List<PageElement<Native_Element_Type>> implements MetaQuestion<Answerable<PageElement<Native_Element_Type>>, Promise<Array<PageElement<Native_Element_Type>>>> {
|
|
6
|
+
protected readonly locator: Question<Promise<Locator<Native_Element_Type>>>;
|
|
7
|
+
static located<NET>(selector: Answerable<Selector>): PageElements<NET>;
|
|
8
8
|
/**
|
|
9
|
-
* @param
|
|
10
|
-
* @param {Answerable<PageElement>} [parent]
|
|
11
|
-
* if not specified, browser root selector is used
|
|
9
|
+
* @param locator
|
|
12
10
|
*/
|
|
13
|
-
constructor(
|
|
11
|
+
constructor(locator: Question<Promise<Locator<Native_Element_Type>>>);
|
|
14
12
|
of(parent: Answerable<PageElement<Native_Element_Type>>): PageElements<Native_Element_Type>;
|
|
15
13
|
}
|
|
@@ -6,20 +6,17 @@ const abilities_1 = require("../abilities");
|
|
|
6
6
|
const f = (0, core_1.format)({ markQuestions: true });
|
|
7
7
|
class PageElements extends core_1.List {
|
|
8
8
|
/**
|
|
9
|
-
* @param
|
|
10
|
-
* @param {Answerable<PageElement>} [parent]
|
|
11
|
-
* if not specified, browser root selector is used
|
|
9
|
+
* @param locator
|
|
12
10
|
*/
|
|
13
|
-
constructor(
|
|
14
|
-
super(
|
|
15
|
-
this.
|
|
16
|
-
this.parent = parent;
|
|
11
|
+
constructor(locator) {
|
|
12
|
+
super(allElementsOf(locator));
|
|
13
|
+
this.locator = locator;
|
|
17
14
|
}
|
|
18
15
|
static located(selector) {
|
|
19
|
-
return new PageElements(selector);
|
|
16
|
+
return new PageElements(relativeToDocumentRoot(selector));
|
|
20
17
|
}
|
|
21
18
|
of(parent) {
|
|
22
|
-
return new PageElements(this.
|
|
19
|
+
return new PageElements(relativeToParent(this.locator, parent))
|
|
23
20
|
.describedAs(`<<${this.toString()}>>` + f `.of(${parent})`);
|
|
24
21
|
}
|
|
25
22
|
}
|
|
@@ -27,24 +24,29 @@ exports.PageElements = PageElements;
|
|
|
27
24
|
/**
|
|
28
25
|
* @package
|
|
29
26
|
*/
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
27
|
+
function relativeToDocumentRoot(selector) {
|
|
28
|
+
return core_1.Question.about(selector.toString(), async (actor) => {
|
|
29
|
+
const bySelector = await actor.answer(selector);
|
|
30
|
+
return abilities_1.BrowseTheWeb.as(actor).locate(bySelector);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* @package
|
|
35
|
+
*/
|
|
36
|
+
function relativeToParent(relativeLocator, parent) {
|
|
37
|
+
return core_1.Question.about(relativeLocator.toString() + f `.of${parent}`, async (actor) => {
|
|
38
|
+
const locator = await actor.answer(relativeLocator);
|
|
39
|
+
const parentElement = await actor.answer(parent);
|
|
40
|
+
return locator.of(parentElement.locator);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* @package
|
|
45
|
+
*/
|
|
46
|
+
function allElementsOf(locator) {
|
|
47
|
+
return core_1.Question.about(`page elements located ${locator.toString()}`, async (actor) => {
|
|
48
|
+
const resolved = await actor.answer(locator);
|
|
49
|
+
return resolved.allElements();
|
|
50
|
+
});
|
|
49
51
|
}
|
|
50
52
|
//# sourceMappingURL=PageElements.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PageElements.js","sourceRoot":"","sources":["../../../src/screenplay/models/PageElements.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"PageElements.js","sourceRoot":"","sources":["../../../src/screenplay/models/PageElements.ts"],"names":[],"mappings":";;;AAAA,4CAAqF;AAErF,4CAA4C;AAK5C,MAAM,CAAC,GAAG,IAAA,aAAM,EAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;AAE1C,MAAa,YACT,SAAQ,WAAsC;IAO9C;;OAEG;IACH,YAA+B,OAAwD;QACnF,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;QADH,YAAO,GAAP,OAAO,CAAiD;IAEvF,CAAC;IATD,MAAM,CAAC,OAAO,CAAM,QAA8B;QAC9C,OAAO,IAAI,YAAY,CAAC,sBAAsB,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC9D,CAAC;IASD,EAAE,CAAC,MAAoD;QACnD,OAAO,IAAI,YAAY,CAAsB,gBAAgB,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;aAC/E,WAAW,CAAC,KAAK,IAAI,CAAC,QAAQ,EAAE,IAAI,GAAG,CAAC,CAAA,OAAQ,MAAO,GAAG,CAAC,CAAC;IACrE,CAAC;CACJ;AAnBD,oCAmBC;AAED;;GAEG;AACH,SAAS,sBAAsB,CAAsB,QAA8B;IAC/E,OAAO,eAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE;QACrD,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAChD,OAAO,wBAAY,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACP,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAsB,eAAyD,EAAE,MAAoD;IAC1J,OAAO,eAAQ,CAAC,KAAK,CAAC,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA,MAAO,MAAO,EAAE,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE;QAChF,MAAM,OAAO,GAA6C,MAAM,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;QAC9F,MAAM,aAAa,GAAuC,MAAM,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAErF,OAAO,OAAO,CAAC,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;AACP,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAsB,OAAwD;IAChG,OAAO,eAAQ,CAAC,KAAK,CAAC,yBAA0B,OAAO,CAAC,QAAQ,EAAG,EAAE,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE;QACjF,MAAM,QAAQ,GAAiC,MAAM,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC3E,OAAO,QAAQ,CAAC,WAAW,EAAE,CAAC;IAClC,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
export * from './Cookie';
|
|
2
2
|
export * from './CookieData';
|
|
3
|
+
export * from './Locator';
|
|
3
4
|
export * from './ModalDialog';
|
|
4
|
-
export * from './NativeElementLocator';
|
|
5
5
|
export * from './Page';
|
|
6
6
|
export * from './PageElement';
|
|
7
7
|
export * from './PageElements';
|
|
8
|
-
export * from './PassThroughNativeElementLocator';
|
|
9
8
|
export * from './selectors';
|
|
@@ -12,11 +12,10 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
__exportStar(require("./Cookie"), exports);
|
|
14
14
|
__exportStar(require("./CookieData"), exports);
|
|
15
|
+
__exportStar(require("./Locator"), exports);
|
|
15
16
|
__exportStar(require("./ModalDialog"), exports);
|
|
16
|
-
__exportStar(require("./NativeElementLocator"), exports);
|
|
17
17
|
__exportStar(require("./Page"), exports);
|
|
18
18
|
__exportStar(require("./PageElement"), exports);
|
|
19
19
|
__exportStar(require("./PageElements"), exports);
|
|
20
|
-
__exportStar(require("./PassThroughNativeElementLocator"), exports);
|
|
21
20
|
__exportStar(require("./selectors"), exports);
|
|
22
21
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/screenplay/models/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAyB;AACzB,+CAA6B;AAC7B,gDAA8B;AAC9B,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/screenplay/models/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAyB;AACzB,+CAA6B;AAC7B,4CAA0B;AAC1B,gDAA8B;AAC9B,yCAAuB;AACvB,gDAA8B;AAC9B,iDAA+B;AAC/B,8CAA4B"}
|
|
@@ -3,6 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ByCss = void 0;
|
|
4
4
|
const Selector_1 = require("./Selector");
|
|
5
5
|
class ByCss extends Selector_1.Selector {
|
|
6
|
+
constructor(value) {
|
|
7
|
+
super();
|
|
8
|
+
this.value = value;
|
|
9
|
+
}
|
|
6
10
|
}
|
|
7
11
|
exports.ByCss = ByCss;
|
|
8
12
|
//# sourceMappingURL=ByCss.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ByCss.js","sourceRoot":"","sources":["../../../../src/screenplay/models/selectors/ByCss.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAEtC,MAAa,KAAM,SAAQ,
|
|
1
|
+
{"version":3,"file":"ByCss.js","sourceRoot":"","sources":["../../../../src/screenplay/models/selectors/ByCss.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAEtC,MAAa,KAAM,SAAQ,mBAAQ;IAC/B,YAA4B,KAAa;QACrC,KAAK,EAAE,CAAC;QADgB,UAAK,GAAL,KAAK,CAAQ;IAEzC,CAAC;CACJ;AAJD,sBAIC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Selector } from './Selector';
|
|
2
|
-
export declare class ByCssContainingText extends Selector
|
|
2
|
+
export declare class ByCssContainingText extends Selector {
|
|
3
|
+
readonly value: string;
|
|
3
4
|
readonly text: string;
|
|
4
|
-
constructor(
|
|
5
|
+
constructor(value: string, text: string);
|
|
5
6
|
}
|
|
@@ -3,8 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ByCssContainingText = void 0;
|
|
4
4
|
const Selector_1 = require("./Selector");
|
|
5
5
|
class ByCssContainingText extends Selector_1.Selector {
|
|
6
|
-
constructor(
|
|
7
|
-
super(
|
|
6
|
+
constructor(value, text) {
|
|
7
|
+
super();
|
|
8
|
+
this.value = value;
|
|
8
9
|
this.text = text;
|
|
9
10
|
}
|
|
10
11
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ByCssContainingText.js","sourceRoot":"","sources":["../../../../src/screenplay/models/selectors/ByCssContainingText.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAEtC,MAAa,mBAAoB,SAAQ,
|
|
1
|
+
{"version":3,"file":"ByCssContainingText.js","sourceRoot":"","sources":["../../../../src/screenplay/models/selectors/ByCssContainingText.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAEtC,MAAa,mBAAoB,SAAQ,mBAAQ;IAC7C,YAA4B,KAAa,EAAkB,IAAY;QACnE,KAAK,EAAE,CAAC;QADgB,UAAK,GAAL,KAAK,CAAQ;QAAkB,SAAI,GAAJ,IAAI,CAAQ;IAEvE,CAAC;CACJ;AAJD,kDAIC"}
|
|
@@ -3,6 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ById = void 0;
|
|
4
4
|
const Selector_1 = require("./Selector");
|
|
5
5
|
class ById extends Selector_1.Selector {
|
|
6
|
+
constructor(value) {
|
|
7
|
+
super();
|
|
8
|
+
this.value = value;
|
|
9
|
+
}
|
|
6
10
|
}
|
|
7
11
|
exports.ById = ById;
|
|
8
12
|
//# sourceMappingURL=ById.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ById.js","sourceRoot":"","sources":["../../../../src/screenplay/models/selectors/ById.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAEtC,MAAa,IAAK,SAAQ,
|
|
1
|
+
{"version":3,"file":"ById.js","sourceRoot":"","sources":["../../../../src/screenplay/models/selectors/ById.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAEtC,MAAa,IAAK,SAAQ,mBAAQ;IAC9B,YAA4B,KAAa;QACrC,KAAK,EAAE,CAAC;QADgB,UAAK,GAAL,KAAK,CAAQ;IAEzC,CAAC;CACJ;AAJD,oBAIC"}
|
|
@@ -3,6 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ByTagName = void 0;
|
|
4
4
|
const Selector_1 = require("./Selector");
|
|
5
5
|
class ByTagName extends Selector_1.Selector {
|
|
6
|
+
constructor(value) {
|
|
7
|
+
super();
|
|
8
|
+
this.value = value;
|
|
9
|
+
}
|
|
6
10
|
}
|
|
7
11
|
exports.ByTagName = ByTagName;
|
|
8
12
|
//# sourceMappingURL=ByTagName.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ByTagName.js","sourceRoot":"","sources":["../../../../src/screenplay/models/selectors/ByTagName.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAEtC,MAAa,SAAU,SAAQ,
|
|
1
|
+
{"version":3,"file":"ByTagName.js","sourceRoot":"","sources":["../../../../src/screenplay/models/selectors/ByTagName.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAEtC,MAAa,SAAU,SAAQ,mBAAQ;IACnC,YAA4B,KAAa;QACrC,KAAK,EAAE,CAAC;QADgB,UAAK,GAAL,KAAK,CAAQ;IAEzC,CAAC;CACJ;AAJD,8BAIC"}
|
|
@@ -3,6 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ByXPath = void 0;
|
|
4
4
|
const Selector_1 = require("./Selector");
|
|
5
5
|
class ByXPath extends Selector_1.Selector {
|
|
6
|
+
constructor(value) {
|
|
7
|
+
super();
|
|
8
|
+
this.value = value;
|
|
9
|
+
}
|
|
6
10
|
}
|
|
7
11
|
exports.ByXPath = ByXPath;
|
|
8
12
|
//# sourceMappingURL=ByXPath.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ByXPath.js","sourceRoot":"","sources":["../../../../src/screenplay/models/selectors/ByXPath.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAEtC,MAAa,OAAQ,SAAQ,
|
|
1
|
+
{"version":3,"file":"ByXPath.js","sourceRoot":"","sources":["../../../../src/screenplay/models/selectors/ByXPath.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAEtC,MAAa,OAAQ,SAAQ,mBAAQ;IACjC,YAA4B,KAAa;QACrC,KAAK,EAAE,CAAC;QADgB,UAAK,GAAL,KAAK,CAAQ;IAEzC,CAAC;CACJ;AAJD,0BAIC"}
|
|
@@ -4,10 +4,8 @@ exports.Selector = void 0;
|
|
|
4
4
|
const core_1 = require("@serenity-js/core");
|
|
5
5
|
const f = (0, core_1.format)({ markQuestions: true });
|
|
6
6
|
class Selector {
|
|
7
|
-
constructor(value) {
|
|
8
|
-
this.value = value;
|
|
9
|
-
}
|
|
10
7
|
toString() {
|
|
8
|
+
// todo: strip anything preceding "By", like "WebdriverIOByCss|
|
|
11
9
|
const selectorDescription = this.constructor.name.replace(/([a-z]+)([A-Z])/g, '$1 $2').toLowerCase();
|
|
12
10
|
const parametersDescription = Object.keys(this).map(field => f `${this[field]}`).join(', ');
|
|
13
11
|
return `${selectorDescription} (${parametersDescription})`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Selector.js","sourceRoot":"","sources":["../../../../src/screenplay/models/selectors/Selector.ts"],"names":[],"mappings":";;;AAAA,4CAA2C;AAE3C,MAAM,CAAC,GAAG,IAAA,aAAM,EAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;AAE1C,MAAsB,QAAQ;IAE1B,
|
|
1
|
+
{"version":3,"file":"Selector.js","sourceRoot":"","sources":["../../../../src/screenplay/models/selectors/Selector.ts"],"names":[],"mappings":";;;AAAA,4CAA2C;AAE3C,MAAM,CAAC,GAAG,IAAA,aAAM,EAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;AAE1C,MAAsB,QAAQ;IAE1B,QAAQ;QACJ,+DAA+D;QAC/D,MAAM,mBAAmB,GAAK,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;QACvG,MAAM,qBAAqB,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE3F,OAAO,GAAI,mBAAoB,KAAM,qBAAsB,GAAG,CAAC;IACnE,CAAC;CACJ;AATD,4BASC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Adapter, Answerable, MetaQuestion, Question } from '@serenity-js/core';
|
|
2
|
-
import { PageElement } from '../models';
|
|
2
|
+
import { PageElement, PageElements } from '../models';
|
|
3
3
|
/**
|
|
4
4
|
* @desc
|
|
5
5
|
* Resolves to the visible (i.e. not hidden by CSS) `innerText` of:
|
|
@@ -93,5 +93,6 @@ export declare class Text {
|
|
|
93
93
|
*
|
|
94
94
|
* @see {@link @serenity-js/core/lib/screenplay/questions~MetaQuestion}
|
|
95
95
|
*/
|
|
96
|
+
static ofAll(elements: PageElements): Question<Promise<string[]>> & MetaQuestion<Answerable<PageElement>, Promise<string[]>> & Adapter<string[]>;
|
|
96
97
|
static ofAll(elements: Answerable<PageElement[]>): Question<Promise<string[]>> & Adapter<string[]>;
|
|
97
98
|
}
|
|
@@ -89,17 +89,10 @@ class Text {
|
|
|
89
89
|
static of(element) {
|
|
90
90
|
return (0, core_1.createAdapter)(new TextOfSingleElement(element));
|
|
91
91
|
}
|
|
92
|
-
/**
|
|
93
|
-
* @desc
|
|
94
|
-
* Retrieves text of a group of {@link WebElement}s,
|
|
95
|
-
* represented by Answerable<{@link @wdio/types~ElementList}>
|
|
96
|
-
*
|
|
97
|
-
* @param {Answerable<PageElement[]>} elements
|
|
98
|
-
* @returns {Question<Promise<string[]>> & MetaQuestion<Answerable<PageElement>, Promise<string[]>>}
|
|
99
|
-
*
|
|
100
|
-
* @see {@link @serenity-js/core/lib/screenplay/questions~MetaQuestion}
|
|
101
|
-
*/
|
|
102
92
|
static ofAll(elements) {
|
|
93
|
+
if (elements instanceof models_1.PageElements) {
|
|
94
|
+
return (0, core_1.createAdapter)(new TextOfMultipleElements(elements));
|
|
95
|
+
}
|
|
103
96
|
return core_1.Question.about(f `the text of ${elements}`, async (actor) => {
|
|
104
97
|
const pageElements = await actor.answer(elements);
|
|
105
98
|
return (0, io_1.asyncMap)(pageElements, element => element.text());
|
|
@@ -120,4 +113,17 @@ class TextOfSingleElement extends ElementQuestion_1.ElementQuestion {
|
|
|
120
113
|
return element.text();
|
|
121
114
|
}
|
|
122
115
|
}
|
|
116
|
+
class TextOfMultipleElements extends ElementQuestion_1.ElementQuestion {
|
|
117
|
+
constructor(elements) {
|
|
118
|
+
super(f `the text of ${elements}`);
|
|
119
|
+
this.elements = elements;
|
|
120
|
+
}
|
|
121
|
+
of(parent) {
|
|
122
|
+
return new TextOfMultipleElements(this.elements.of(parent));
|
|
123
|
+
}
|
|
124
|
+
async answeredBy(actor) {
|
|
125
|
+
const elements = await actor.answer(this.elements);
|
|
126
|
+
return (0, io_1.asyncMap)(elements, element => element.text());
|
|
127
|
+
}
|
|
128
|
+
}
|
|
123
129
|
//# sourceMappingURL=Text.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Text.js","sourceRoot":"","sources":["../../../src/screenplay/questions/Text.ts"],"names":[],"mappings":";;;AAAA,4CAAwI;AACxI,iDAAoD;AAEpD,
|
|
1
|
+
{"version":3,"file":"Text.js","sourceRoot":"","sources":["../../../src/screenplay/questions/Text.ts"],"names":[],"mappings":";;;AAAA,4CAAwI;AACxI,iDAAoD;AAEpD,sCAAsD;AACtD,uDAAoD;AAEpD,MAAM,CAAC,GAAG,IAAA,aAAM,EAAC,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AACH,MAAa,IAAI;IAEb;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,CAAC,OAAgC;QAKtC,OAAO,IAAA,oBAAa,EAChB,IAAI,mBAAmB,CAAC,OAAO,CAAC,CACnC,CAAC;IACN,CAAC;IAcD,MAAM,CAAC,KAAK,CAAC,QAAkD;QAC3D,IAAI,QAAQ,YAAY,qBAAY,EAAE;YAClC,OAAO,IAAA,oBAAa,EAChB,IAAI,sBAAsB,CAAC,QAAQ,CAAC,CACvC,CAAC;SACL;QAED,OAAO,eAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,eAAgB,QAAS,EAAE,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE;YAC/D,MAAM,YAAY,GAAkB,MAAM,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAEjE,OAAO,IAAA,aAAQ,EAAC,YAAY,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;IACP,CAAC;CACJ;AA/CD,oBA+CC;AAED,MAAM,mBACF,SAAQ,iCAAgC;IAGxC,YAA6B,OAAgC;QACzD,KAAK,CAAC,eAAgB,OAAQ,EAAE,CAAC,CAAC;QADT,YAAO,GAAP,OAAO,CAAyB;IAE7D,CAAC;IAED,EAAE,CAAC,MAA+B;QAC9B,OAAO,IAAI,mBAAmB,CAAC,oBAAW,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,KAAuC;QACpD,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEjD,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC;IAC1B,CAAC;CACJ;AAED,MAAM,sBACF,SAAQ,iCAAkC;IAG1C,YAA6B,QAAsB;QAC/C,KAAK,CAAC,CAAC,CAAC,eAAgB,QAAS,EAAE,CAAC,CAAC;QADZ,aAAQ,GAAR,QAAQ,CAAc;IAEnD,CAAC;IAED,EAAE,CAAC,MAA+B;QAC9B,OAAO,IAAI,sBAAsB,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,KAAuC;QACpD,MAAM,QAAQ,GAAkB,MAAM,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAElE,OAAO,IAAA,aAAQ,EAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;CACJ"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@serenity-js/web",
|
|
3
|
-
"version": "3.0.0-rc.
|
|
3
|
+
"version": "3.0.0-rc.5",
|
|
4
4
|
"description": "Serenity/JS Screenplay Pattern APIs for the Web",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Jan Molak",
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"npm": "^6 || ^7"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@serenity-js/assertions": "3.0.0-rc.
|
|
50
|
-
"@serenity-js/core": "3.0.0-rc.
|
|
49
|
+
"@serenity-js/assertions": "3.0.0-rc.5",
|
|
50
|
+
"@serenity-js/core": "3.0.0-rc.5",
|
|
51
51
|
"tiny-types": "^1.17.0"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
@@ -81,5 +81,5 @@
|
|
|
81
81
|
"cache": true,
|
|
82
82
|
"all": true
|
|
83
83
|
},
|
|
84
|
-
"gitHead": "
|
|
84
|
+
"gitHead": "b63bb1465731d922fde0ade3b77ddebb96dbf990"
|
|
85
85
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { Ability, Duration, UsesAbilities } from '@serenity-js/core';
|
|
1
|
+
import { Ability, Duration, format, LogicError, UsesAbilities } from '@serenity-js/core';
|
|
2
2
|
|
|
3
3
|
import { Key } from '../../input';
|
|
4
|
-
import { Cookie, CookieData,
|
|
4
|
+
import { Cookie, CookieData, Locator, ModalDialog, Page, PageElement, Selector } from '../models';
|
|
5
5
|
import { BrowserCapabilities } from './BrowserCapabilities';
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
const f = format({ markQuestions: true });
|
|
8
|
+
|
|
9
|
+
export abstract class BrowseTheWeb<Native_Element_Type = any, Native_Root_Element_Type = unknown> implements Ability {
|
|
8
10
|
/**
|
|
9
11
|
* @desc
|
|
10
12
|
* Used to access the Actor's ability to {@link BrowseTheWeb}
|
|
@@ -14,8 +16,17 @@ export abstract class BrowseTheWeb<Native_Element_Type = any> implements Ability
|
|
|
14
16
|
* @param {@serenity-js/core/lib/screenplay/actor~UsesAbilities} actor
|
|
15
17
|
* @return {BrowseTheWeb}
|
|
16
18
|
*/
|
|
17
|
-
static as(actor: UsesAbilities): BrowseTheWeb {
|
|
18
|
-
return actor.abilityTo(BrowseTheWeb)
|
|
19
|
+
static as<NET = any, NRET = unknown>(actor: UsesAbilities): BrowseTheWeb<NET, NRET> {
|
|
20
|
+
return actor.abilityTo(BrowseTheWeb) as BrowseTheWeb<NET, NRET>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
constructor(
|
|
24
|
+
protected locators: Map<
|
|
25
|
+
new (...args: unknown[]) => Selector,
|
|
26
|
+
(selector: Selector) =>
|
|
27
|
+
Locator<Native_Element_Type, Native_Root_Element_Type>
|
|
28
|
+
>
|
|
29
|
+
) {
|
|
19
30
|
}
|
|
20
31
|
|
|
21
32
|
abstract navigateTo(destination: string): Promise<void>;
|
|
@@ -30,9 +41,15 @@ export abstract class BrowseTheWeb<Native_Element_Type = any> implements Ability
|
|
|
30
41
|
|
|
31
42
|
abstract waitUntil(condition: () => boolean | Promise<boolean>, timeout: Duration): Promise<void>;
|
|
32
43
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
44
|
+
locate(selector: Selector): Locator<Native_Element_Type, Native_Root_Element_Type> {
|
|
45
|
+
for (const [ type, locatorFactory ] of this.locators) {
|
|
46
|
+
if (selector instanceof type) {
|
|
47
|
+
return locatorFactory(selector);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
throw new LogicError(f `${ selector } is not supported by ${ this.constructor.name }`);
|
|
52
|
+
}
|
|
36
53
|
|
|
37
54
|
abstract browserCapabilities(): Promise<BrowserCapabilities>;
|
|
38
55
|
|
|
@@ -121,7 +121,6 @@ class PressKeyInField extends PageElementInteraction {
|
|
|
121
121
|
const keys = await actor.answer(this.keys);
|
|
122
122
|
|
|
123
123
|
// fix for protractor
|
|
124
|
-
// todo: should this wait on focus to occur?
|
|
125
124
|
await BrowseTheWeb.as(actor).executeScript(
|
|
126
125
|
/* istanbul ignore next */
|
|
127
126
|
function focus(element: any) {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { PageElement } from './PageElement';
|
|
2
|
+
import { Selector } from './selectors';
|
|
3
|
+
|
|
4
|
+
export abstract class Locator<Native_Element_Type, Native_Root_Element_Type = any, Selector_Type extends Selector = Selector> {
|
|
5
|
+
constructor(
|
|
6
|
+
protected readonly parentRoot: () => Promise<Native_Root_Element_Type> | Native_Root_Element_Type,
|
|
7
|
+
protected readonly selector: Selector_Type,
|
|
8
|
+
protected readonly locateElement: (root: Native_Root_Element_Type) => Promise<Native_Element_Type> | Native_Element_Type,
|
|
9
|
+
protected readonly locateAllElements: (root: Native_Root_Element_Type) => Promise<Array<Native_Element_Type>> | Array<Native_Element_Type>,
|
|
10
|
+
) {
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public async nativeElement(): Promise<Native_Element_Type> {
|
|
14
|
+
return this.locateElement(await this.parentRoot());
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
abstract of(parent: Locator<Native_Element_Type, Native_Root_Element_Type>): Locator<Native_Element_Type, Native_Root_Element_Type>;
|
|
18
|
+
|
|
19
|
+
abstract element(): PageElement<Native_Element_Type>;
|
|
20
|
+
abstract allElements(): Promise<Array<PageElement<Native_Element_Type>>>;
|
|
21
|
+
|
|
22
|
+
toString(): string {
|
|
23
|
+
return this.selector.toString();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -1,20 +1,22 @@
|
|
|
1
|
-
import { Adapter, Answerable, format,
|
|
1
|
+
import { Adapter, Answerable, format, Question } from '@serenity-js/core';
|
|
2
|
+
import { ensure, isDefined } from 'tiny-types';
|
|
2
3
|
|
|
3
4
|
import { BrowseTheWeb } from '../abilities';
|
|
4
|
-
import {
|
|
5
|
+
import { Locator } from './Locator';
|
|
5
6
|
import { Selector } from './selectors';
|
|
6
7
|
|
|
7
8
|
const d = format({ markQuestions: false });
|
|
8
9
|
|
|
9
10
|
export abstract class PageElement<Native_Element_Type = any> {
|
|
10
11
|
|
|
11
|
-
static located<NET
|
|
12
|
+
static located<NET>(selector: Answerable<Selector>): Question<Promise<PageElement<NET>>> & Adapter<PageElement<NET>> {
|
|
12
13
|
return Question.about(d`page element located ${ selector }`, async actor => {
|
|
13
14
|
const bySelector = await actor.answer(selector);
|
|
14
|
-
return BrowseTheWeb.as(actor).locate
|
|
15
|
+
return BrowseTheWeb.as<NET>(actor).locate(bySelector).element();
|
|
15
16
|
});
|
|
16
17
|
}
|
|
17
18
|
|
|
19
|
+
// todo: review usages and consider removing if not used
|
|
18
20
|
static of<NET>(childElement: Answerable<PageElement<NET>>, parentElement: Answerable<PageElement<NET>>): Question<Promise<PageElement<NET>>> & Adapter<PageElement<NET>> {
|
|
19
21
|
return Question.about(d`${ childElement } of ${ parentElement })`, async actor => {
|
|
20
22
|
const child = await actor.answer(childElement);
|
|
@@ -24,29 +26,18 @@ export abstract class PageElement<Native_Element_Type = any> {
|
|
|
24
26
|
});
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
constructor(
|
|
28
|
-
|
|
29
|
-
private readonly locator: NativeElementLocator<Native_Element_Type>,
|
|
30
|
-
) {
|
|
29
|
+
constructor(public readonly locator: Locator<Native_Element_Type>) {
|
|
30
|
+
ensure('native element locator', locator, isDefined());
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
abstract of(
|
|
33
|
+
abstract of(parentElement: PageElement<Native_Element_Type>): PageElement<Native_Element_Type>;
|
|
34
34
|
|
|
35
35
|
async nativeElement(): Promise<Native_Element_Type> {
|
|
36
|
-
|
|
37
|
-
return this.locator.locate(this.selector);
|
|
38
|
-
}
|
|
39
|
-
catch (error) {
|
|
40
|
-
throw new LogicError(`Couldn't find element`, error);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
nativeElementLocator(): NativeElementLocator<Native_Element_Type> {
|
|
45
|
-
return this.locator;
|
|
36
|
+
return this.locator.nativeElement();
|
|
46
37
|
}
|
|
47
38
|
|
|
48
39
|
toString(): string {
|
|
49
|
-
return `PageElement located ${ this.
|
|
40
|
+
return `PageElement located ${ this.locator.toString() }`;
|
|
50
41
|
}
|
|
51
42
|
|
|
52
43
|
abstract enterValue(value: string | number | Array<string | number>): Promise<void>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { Answerable,
|
|
1
|
+
import { Answerable, format, List, MetaQuestion, Question } from '@serenity-js/core';
|
|
2
2
|
|
|
3
3
|
import { BrowseTheWeb } from '../abilities';
|
|
4
|
+
import { Locator } from './Locator';
|
|
4
5
|
import { PageElement } from './PageElement';
|
|
5
6
|
import { Selector } from './selectors';
|
|
6
7
|
|
|
@@ -8,25 +9,21 @@ const f = format({ markQuestions: true });
|
|
|
8
9
|
|
|
9
10
|
export class PageElements<Native_Element_Type = any>
|
|
10
11
|
extends List<PageElement<Native_Element_Type>>
|
|
12
|
+
implements MetaQuestion<Answerable<PageElement<Native_Element_Type>>, Promise<Array<PageElement<Native_Element_Type>>>>
|
|
11
13
|
{
|
|
12
|
-
static located<NET
|
|
13
|
-
return new PageElements(selector);
|
|
14
|
+
static located<NET>(selector: Answerable<Selector>): PageElements<NET> {
|
|
15
|
+
return new PageElements(relativeToDocumentRoot(selector));
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
/**
|
|
17
|
-
* @param
|
|
18
|
-
* @param {Answerable<PageElement>} [parent]
|
|
19
|
-
* if not specified, browser root selector is used
|
|
19
|
+
* @param locator
|
|
20
20
|
*/
|
|
21
|
-
constructor(
|
|
22
|
-
|
|
23
|
-
private readonly parent?: Answerable<PageElement>
|
|
24
|
-
) {
|
|
25
|
-
super(new PageElementCollection<Native_Element_Type>(selector, parent));
|
|
21
|
+
constructor(protected readonly locator: Question<Promise<Locator<Native_Element_Type>>>) {
|
|
22
|
+
super(allElementsOf(locator));
|
|
26
23
|
}
|
|
27
24
|
|
|
28
25
|
of(parent: Answerable<PageElement<Native_Element_Type>>): PageElements<Native_Element_Type> {
|
|
29
|
-
return new PageElements<Native_Element_Type>(this.
|
|
26
|
+
return new PageElements<Native_Element_Type>(relativeToParent(this.locator, parent))
|
|
30
27
|
.describedAs(`<<${this.toString()}>>` + f`.of(${ parent })`);
|
|
31
28
|
}
|
|
32
29
|
}
|
|
@@ -34,31 +31,31 @@ export class PageElements<Native_Element_Type = any>
|
|
|
34
31
|
/**
|
|
35
32
|
* @package
|
|
36
33
|
*/
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
private readonly parent?: Answerable<PageElement>,
|
|
44
|
-
) {
|
|
45
|
-
super();
|
|
46
|
-
this.subject = `page elements located ${ selector.toString() }`;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
async answeredBy(actor: AnswersQuestions & UsesAbilities): Promise<Array<PageElement<Native_Element_Type>>> {
|
|
50
|
-
const bySelector = await actor.answer(this.selector);
|
|
51
|
-
const parent = await actor.answer(this.parent);
|
|
34
|
+
function relativeToDocumentRoot<Native_Element_Type>(selector: Answerable<Selector>): Question<Promise<Locator<Native_Element_Type>>> {
|
|
35
|
+
return Question.about(selector.toString(), async actor => {
|
|
36
|
+
const bySelector = await actor.answer(selector);
|
|
37
|
+
return BrowseTheWeb.as(actor).locate(bySelector);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
52
40
|
|
|
53
|
-
|
|
54
|
-
|
|
41
|
+
/**
|
|
42
|
+
* @package
|
|
43
|
+
*/
|
|
44
|
+
function relativeToParent<Native_Element_Type>(relativeLocator: Answerable<Locator<Native_Element_Type>>, parent: Answerable<PageElement<Native_Element_Type>>): Question<Promise<Locator<Native_Element_Type>>> {
|
|
45
|
+
return Question.about(relativeLocator.toString() + f`.of${ parent }`, async actor => {
|
|
46
|
+
const locator: Locator<Native_Element_Type> = await actor.answer(relativeLocator);
|
|
47
|
+
const parentElement: PageElement<Native_Element_Type> = await actor.answer(parent);
|
|
55
48
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
49
|
+
return locator.of(parentElement.locator);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
60
52
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
53
|
+
/**
|
|
54
|
+
* @package
|
|
55
|
+
*/
|
|
56
|
+
function allElementsOf<Native_Element_Type>(locator: Question<Promise<Locator<Native_Element_Type>>>): Question<Promise<Array<PageElement<Native_Element_Type>>>> {
|
|
57
|
+
return Question.about(`page elements located ${ locator.toString() }`, async actor => {
|
|
58
|
+
const resolved: Locator<Native_Element_Type> = await actor.answer(locator);
|
|
59
|
+
return resolved.allElements();
|
|
60
|
+
});
|
|
64
61
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
export * from './Cookie';
|
|
2
2
|
export * from './CookieData';
|
|
3
|
+
export * from './Locator';
|
|
3
4
|
export * from './ModalDialog';
|
|
4
|
-
export * from './NativeElementLocator';
|
|
5
5
|
export * from './Page';
|
|
6
6
|
export * from './PageElement';
|
|
7
7
|
export * from './PageElements';
|
|
8
|
-
export * from './PassThroughNativeElementLocator';
|
|
9
8
|
export * from './selectors';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Selector } from './Selector';
|
|
2
2
|
|
|
3
|
-
export class ByCssContainingText extends Selector
|
|
4
|
-
constructor(
|
|
5
|
-
super(
|
|
3
|
+
export class ByCssContainingText extends Selector {
|
|
4
|
+
constructor(public readonly value: string, public readonly text: string) {
|
|
5
|
+
super();
|
|
6
6
|
}
|
|
7
7
|
}
|
|
@@ -2,12 +2,10 @@ import { format } from '@serenity-js/core';
|
|
|
2
2
|
|
|
3
3
|
const f = format({ markQuestions: true });
|
|
4
4
|
|
|
5
|
-
export abstract class Selector
|
|
6
|
-
|
|
7
|
-
constructor(public readonly value: T) {
|
|
8
|
-
}
|
|
5
|
+
export abstract class Selector {
|
|
9
6
|
|
|
10
7
|
toString(): string {
|
|
8
|
+
// todo: strip anything preceding "By", like "WebdriverIOByCss|
|
|
11
9
|
const selectorDescription = this.constructor.name.replace(/([a-z]+)([A-Z])/g, '$1 $2').toLowerCase();
|
|
12
10
|
const parametersDescription = Object.keys(this).map(field => f`${this[field]}`).join(', ');
|
|
13
11
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Adapter, Answerable, AnswersQuestions, createAdapter, format, MetaQuestion, Question, UsesAbilities } from '@serenity-js/core';
|
|
2
2
|
import { asyncMap } from '@serenity-js/core/lib/io';
|
|
3
3
|
|
|
4
|
-
import { PageElement } from '../models';
|
|
4
|
+
import { PageElement, PageElements } from '../models';
|
|
5
5
|
import { ElementQuestion } from './ElementQuestion';
|
|
6
6
|
|
|
7
7
|
const f = format({ markQuestions: false });
|
|
@@ -107,13 +107,20 @@ export class Text {
|
|
|
107
107
|
*
|
|
108
108
|
* @see {@link @serenity-js/core/lib/screenplay/questions~MetaQuestion}
|
|
109
109
|
*/
|
|
110
|
-
static ofAll(elements:
|
|
111
|
-
|
|
110
|
+
static ofAll(elements: PageElements): Question<Promise<string[]>> & MetaQuestion<Answerable<PageElement>, Promise<string[]>> & Adapter<string[]>
|
|
111
|
+
static ofAll(elements: Answerable<PageElement[]>): Question<Promise<string[]>> & Adapter<string[]>
|
|
112
|
+
static ofAll(elements: PageElements | Answerable<PageElement[]>): Question<Promise<string[]>> & Adapter<string[]> {
|
|
113
|
+
if (elements instanceof PageElements) {
|
|
114
|
+
return createAdapter<Promise<string[]>, ElementQuestion<Promise<string[]>> & MetaQuestion<Answerable<PageElement>, Promise<string[]>>>(
|
|
115
|
+
new TextOfMultipleElements(elements)
|
|
116
|
+
);
|
|
117
|
+
}
|
|
112
118
|
|
|
119
|
+
return Question.about(f `the text of ${ elements }`, async actor => {
|
|
113
120
|
const pageElements: PageElement[] = await actor.answer(elements);
|
|
114
121
|
|
|
115
122
|
return asyncMap(pageElements, element => element.text());
|
|
116
|
-
})
|
|
123
|
+
});
|
|
117
124
|
}
|
|
118
125
|
}
|
|
119
126
|
|
|
@@ -135,3 +142,22 @@ class TextOfSingleElement
|
|
|
135
142
|
return element.text();
|
|
136
143
|
}
|
|
137
144
|
}
|
|
145
|
+
|
|
146
|
+
class TextOfMultipleElements
|
|
147
|
+
extends ElementQuestion<Promise<string[]>>
|
|
148
|
+
implements MetaQuestion<Answerable<PageElement>, Promise<string[]>>
|
|
149
|
+
{
|
|
150
|
+
constructor(private readonly elements: PageElements) {
|
|
151
|
+
super(f `the text of ${ elements }`);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
of(parent: Answerable<PageElement>): Question<Promise<string[]>> {
|
|
155
|
+
return new TextOfMultipleElements(this.elements.of(parent));
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async answeredBy(actor: AnswersQuestions & UsesAbilities): Promise<string[]> {
|
|
159
|
+
const elements: PageElement[] = await actor.answer(this.elements);
|
|
160
|
+
|
|
161
|
+
return asyncMap(elements, element => element.text());
|
|
162
|
+
}
|
|
163
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"NativeElementLocator.js","sourceRoot":"","sources":["../../../src/screenplay/models/NativeElementLocator.ts"],"names":[],"mappings":""}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { NativeElementLocator } from './NativeElementLocator';
|
|
2
|
-
import { Selector } from './selectors';
|
|
3
|
-
export declare class PassThroughNativeElementLocator<Native_Element_Type = any> implements NativeElementLocator<Native_Element_Type> {
|
|
4
|
-
private readonly locator;
|
|
5
|
-
private readonly element;
|
|
6
|
-
constructor(locator: NativeElementLocator<Native_Element_Type>, element: Native_Element_Type);
|
|
7
|
-
locate<T>(selector: Selector<T>): Promise<Native_Element_Type>;
|
|
8
|
-
locateAll<T>(selector: Selector<T>): Promise<Native_Element_Type[]>;
|
|
9
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PassThroughNativeElementLocator = void 0;
|
|
4
|
-
class PassThroughNativeElementLocator {
|
|
5
|
-
constructor(locator, element) {
|
|
6
|
-
this.locator = locator;
|
|
7
|
-
this.element = element;
|
|
8
|
-
}
|
|
9
|
-
async locate(selector) {
|
|
10
|
-
return this.element;
|
|
11
|
-
}
|
|
12
|
-
locateAll(selector) {
|
|
13
|
-
return this.locator.locateAll(selector);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
exports.PassThroughNativeElementLocator = PassThroughNativeElementLocator;
|
|
17
|
-
//# sourceMappingURL=PassThroughNativeElementLocator.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PassThroughNativeElementLocator.js","sourceRoot":"","sources":["../../../src/screenplay/models/PassThroughNativeElementLocator.ts"],"names":[],"mappings":";;;AAGA,MAAa,+BAA+B;IACxC,YACqB,OAAkD,EAClD,OAA4B;QAD5B,YAAO,GAAP,OAAO,CAA2C;QAClD,YAAO,GAAP,OAAO,CAAqB;IAEjD,CAAC;IAED,KAAK,CAAC,MAAM,CAAI,QAAqB;QACjC,OAAO,IAAI,CAAC,OAAO,CAAC;IACxB,CAAC;IAED,SAAS,CAAI,QAAqB;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC5C,CAAC;CACJ;AAdD,0EAcC"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { NativeElementLocator } from './NativeElementLocator';
|
|
2
|
-
import { Selector } from './selectors';
|
|
3
|
-
|
|
4
|
-
export class PassThroughNativeElementLocator<Native_Element_Type = any> implements NativeElementLocator<Native_Element_Type> {
|
|
5
|
-
constructor(
|
|
6
|
-
private readonly locator: NativeElementLocator<Native_Element_Type>,
|
|
7
|
-
private readonly element: Native_Element_Type
|
|
8
|
-
) {
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
async locate<T>(selector: Selector<T>): Promise<Native_Element_Type> {
|
|
12
|
-
return this.element;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
locateAll<T>(selector: Selector<T>): Promise<Native_Element_Type[]> {
|
|
16
|
-
return this.locator.locateAll(selector);
|
|
17
|
-
}
|
|
18
|
-
}
|