@serenity-js/playwright 3.0.0-rc.20
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 +30 -0
- package/LICENSE.md +201 -0
- package/NOTICE.md +1 -0
- package/README.md +145 -0
- package/lib/PlaywrightOptions.d.ts +40 -0
- package/lib/PlaywrightOptions.js +3 -0
- package/lib/PlaywrightOptions.js.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +19 -0
- package/lib/index.js.map +1 -0
- package/lib/screenplay/abilities/BrowseTheWebWithPlaywright.d.ts +71 -0
- package/lib/screenplay/abilities/BrowseTheWebWithPlaywright.js +86 -0
- package/lib/screenplay/abilities/BrowseTheWebWithPlaywright.js.map +1 -0
- package/lib/screenplay/abilities/index.d.ts +1 -0
- package/lib/screenplay/abilities/index.js +18 -0
- package/lib/screenplay/abilities/index.js.map +1 -0
- package/lib/screenplay/index.d.ts +2 -0
- package/lib/screenplay/index.js +19 -0
- package/lib/screenplay/index.js.map +1 -0
- package/lib/screenplay/models/PlaywrightBrowsingSession.d.ts +25 -0
- package/lib/screenplay/models/PlaywrightBrowsingSession.js +67 -0
- package/lib/screenplay/models/PlaywrightBrowsingSession.js.map +1 -0
- package/lib/screenplay/models/PlaywrightCookie.d.ts +8 -0
- package/lib/screenplay/models/PlaywrightCookie.js +39 -0
- package/lib/screenplay/models/PlaywrightCookie.js.map +1 -0
- package/lib/screenplay/models/PlaywrightModalDialogHandler.d.ts +13 -0
- package/lib/screenplay/models/PlaywrightModalDialogHandler.js +45 -0
- package/lib/screenplay/models/PlaywrightModalDialogHandler.js.map +1 -0
- package/lib/screenplay/models/PlaywrightPage.d.ts +58 -0
- package/lib/screenplay/models/PlaywrightPage.js +177 -0
- package/lib/screenplay/models/PlaywrightPage.js.map +1 -0
- package/lib/screenplay/models/PlaywrightPageElement.d.ts +24 -0
- package/lib/screenplay/models/PlaywrightPageElement.js +194 -0
- package/lib/screenplay/models/PlaywrightPageElement.js.map +1 -0
- package/lib/screenplay/models/index.d.ts +5 -0
- package/lib/screenplay/models/index.js +22 -0
- package/lib/screenplay/models/index.js.map +1 -0
- package/lib/screenplay/models/locators/PlaywrightLocator.d.ts +13 -0
- package/lib/screenplay/models/locators/PlaywrightLocator.js +77 -0
- package/lib/screenplay/models/locators/PlaywrightLocator.js.map +1 -0
- package/lib/screenplay/models/locators/PlaywrightRootLocator.d.ts +11 -0
- package/lib/screenplay/models/locators/PlaywrightRootLocator.js +26 -0
- package/lib/screenplay/models/locators/PlaywrightRootLocator.js.map +1 -0
- package/lib/screenplay/models/locators/index.d.ts +2 -0
- package/lib/screenplay/models/locators/index.js +19 -0
- package/lib/screenplay/models/locators/index.js.map +1 -0
- package/package.json +68 -0
- package/src/PlaywrightOptions.ts +43 -0
- package/src/index.ts +2 -0
- package/src/screenplay/abilities/BrowseTheWebWithPlaywright.ts +89 -0
- package/src/screenplay/abilities/index.ts +1 -0
- package/src/screenplay/index.ts +2 -0
- package/src/screenplay/models/PlaywrightBrowsingSession.ts +88 -0
- package/src/screenplay/models/PlaywrightCookie.ts +46 -0
- package/src/screenplay/models/PlaywrightModalDialogHandler.ts +53 -0
- package/src/screenplay/models/PlaywrightPage.ts +258 -0
- package/src/screenplay/models/PlaywrightPageElement.ts +235 -0
- package/src/screenplay/models/index.ts +5 -0
- package/src/screenplay/models/locators/PlaywrightLocator.ts +113 -0
- package/src/screenplay/models/locators/PlaywrightRootLocator.ts +29 -0
- package/src/screenplay/models/locators/index.ts +2 -0
- package/tsconfig.eslint.json +10 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PlaywrightPageElement = void 0;
|
|
4
|
+
const core_1 = require("@serenity-js/core");
|
|
5
|
+
const web_1 = require("@serenity-js/web");
|
|
6
|
+
const scripts = require("@serenity-js/web/lib/scripts");
|
|
7
|
+
const tiny_types_1 = require("tiny-types");
|
|
8
|
+
class PlaywrightPageElement extends web_1.PageElement {
|
|
9
|
+
of(parent) {
|
|
10
|
+
return new PlaywrightPageElement(this.locator.of(parent.locator));
|
|
11
|
+
}
|
|
12
|
+
async enterValue(value) {
|
|
13
|
+
const text = [].concat(value).join('');
|
|
14
|
+
const element = await this.nativeElement();
|
|
15
|
+
return element.fill(text);
|
|
16
|
+
}
|
|
17
|
+
async clearValue() {
|
|
18
|
+
try {
|
|
19
|
+
const element = await this.nativeElement();
|
|
20
|
+
await element.fill('');
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
throw new core_1.LogicError(`The input field doesn't seem to have a 'value' attribute that could be cleared.`, error);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async click() {
|
|
27
|
+
const element = await this.nativeElement();
|
|
28
|
+
return element.click();
|
|
29
|
+
}
|
|
30
|
+
async doubleClick() {
|
|
31
|
+
const element = await this.nativeElement();
|
|
32
|
+
return element.dblclick();
|
|
33
|
+
}
|
|
34
|
+
async scrollIntoView() {
|
|
35
|
+
const element = await this.nativeElement();
|
|
36
|
+
return element.scrollIntoViewIfNeeded();
|
|
37
|
+
}
|
|
38
|
+
async hoverOver() {
|
|
39
|
+
const element = await this.nativeElement();
|
|
40
|
+
return element.hover();
|
|
41
|
+
}
|
|
42
|
+
async rightClick() {
|
|
43
|
+
const element = await this.nativeElement();
|
|
44
|
+
return element.click({ button: 'right' });
|
|
45
|
+
}
|
|
46
|
+
async selectOptions(...options) {
|
|
47
|
+
const element = await this.nativeElement();
|
|
48
|
+
const optionsToSelect = options.map(option => ({
|
|
49
|
+
value: option.value,
|
|
50
|
+
label: option.label,
|
|
51
|
+
}));
|
|
52
|
+
await element.selectOption(optionsToSelect);
|
|
53
|
+
}
|
|
54
|
+
async selectedOptions() {
|
|
55
|
+
const element = await this.nativeElement();
|
|
56
|
+
const options = await element.$$eval('option',
|
|
57
|
+
/* istanbul ignore next */
|
|
58
|
+
(optionNodes) => optionNodes.map((optionNode) => {
|
|
59
|
+
return {
|
|
60
|
+
selected: optionNode.selected,
|
|
61
|
+
disabled: optionNode.disabled,
|
|
62
|
+
label: optionNode.label,
|
|
63
|
+
value: optionNode.value,
|
|
64
|
+
};
|
|
65
|
+
}));
|
|
66
|
+
return options.map(option => new web_1.SelectOption(option.label, option.value, option.selected, option.disabled));
|
|
67
|
+
}
|
|
68
|
+
async attribute(name) {
|
|
69
|
+
const element = await this.nativeElement();
|
|
70
|
+
return element.getAttribute(name);
|
|
71
|
+
}
|
|
72
|
+
async text() {
|
|
73
|
+
const element = await this.nativeElement();
|
|
74
|
+
return element.innerText(); // eslint-disable-line unicorn/prefer-dom-node-text-content
|
|
75
|
+
}
|
|
76
|
+
async value() {
|
|
77
|
+
const element = await this.nativeElement();
|
|
78
|
+
return element.inputValue();
|
|
79
|
+
}
|
|
80
|
+
async switchTo() {
|
|
81
|
+
try {
|
|
82
|
+
const element = await this.nativeElement();
|
|
83
|
+
const frame = await element.contentFrame();
|
|
84
|
+
if (frame) {
|
|
85
|
+
const locator = this.locator;
|
|
86
|
+
await locator.switchToFrame(element);
|
|
87
|
+
return {
|
|
88
|
+
switchBack: async () => {
|
|
89
|
+
await locator.switchToParentFrame();
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const previouslyFocusedElement = await element.evaluateHandle(
|
|
94
|
+
/* istanbul ignore next */
|
|
95
|
+
(domNode) => {
|
|
96
|
+
const currentlyFocusedElement = document.activeElement;
|
|
97
|
+
domNode.focus();
|
|
98
|
+
return currentlyFocusedElement;
|
|
99
|
+
});
|
|
100
|
+
return new PreviouslyFocusedElementSwitcher(previouslyFocusedElement);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
throw new core_1.LogicError(`Couldn't switch to page element located ${this.locator}`, error);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async isActive() {
|
|
107
|
+
try {
|
|
108
|
+
const element = await this.nativeElement();
|
|
109
|
+
return element.evaluate(
|
|
110
|
+
/* istanbul ignore next */
|
|
111
|
+
domNode => domNode === document.activeElement);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
async isClickable() {
|
|
118
|
+
try {
|
|
119
|
+
const element = await this.nativeElement();
|
|
120
|
+
await element.click({ trial: true });
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async isEnabled() {
|
|
128
|
+
try {
|
|
129
|
+
const element = await this.nativeElement();
|
|
130
|
+
return element.isEnabled();
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
async isPresent() {
|
|
137
|
+
try {
|
|
138
|
+
const element = await this.nativeElement();
|
|
139
|
+
return element !== null;
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
if (error.name === 'TimeoutError') {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
throw error;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
async isSelected() {
|
|
149
|
+
try {
|
|
150
|
+
const element = await this.nativeElement();
|
|
151
|
+
// works for <option />
|
|
152
|
+
const selected = await element.getAttribute('selected');
|
|
153
|
+
if (selected !== null) {
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
// works only for checkboxes and radio buttons, throws for other elements
|
|
157
|
+
return await element.isChecked();
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
async isVisible() {
|
|
164
|
+
try {
|
|
165
|
+
const element = await this.nativeElement();
|
|
166
|
+
const isVisible = await element.isVisible();
|
|
167
|
+
if (!isVisible) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
return await element.evaluate(scripts.isVisible);
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
exports.PlaywrightPageElement = PlaywrightPageElement;
|
|
178
|
+
/**
|
|
179
|
+
* @private
|
|
180
|
+
*/
|
|
181
|
+
class PreviouslyFocusedElementSwitcher {
|
|
182
|
+
constructor(node) {
|
|
183
|
+
this.node = node;
|
|
184
|
+
(0, tiny_types_1.ensure)('DOM element', node, (0, tiny_types_1.isDefined)());
|
|
185
|
+
}
|
|
186
|
+
async switchBack() {
|
|
187
|
+
await this.node.evaluate(
|
|
188
|
+
/* istanbul ignore next */
|
|
189
|
+
(domNode) => {
|
|
190
|
+
domNode.focus();
|
|
191
|
+
}, this.node);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=PlaywrightPageElement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlaywrightPageElement.js","sourceRoot":"","sources":["../../../src/screenplay/models/PlaywrightPageElement.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./locators"), exports);
|
|
18
|
+
__exportStar(require("./PlaywrightBrowsingSession"), exports);
|
|
19
|
+
__exportStar(require("./PlaywrightCookie"), exports);
|
|
20
|
+
__exportStar(require("./PlaywrightPage"), exports);
|
|
21
|
+
__exportStar(require("./PlaywrightPageElement"), exports);
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/screenplay/models/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6CAA2B;AAC3B,8DAA4C;AAC5C,qDAAmC;AACnC,mDAAiC;AACjC,0DAAwC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Locator, PageElement, RootLocator, Selector } from '@serenity-js/web';
|
|
2
|
+
import * as playwright from 'playwright';
|
|
3
|
+
import { PlaywrightRootLocator } from './PlaywrightRootLocator';
|
|
4
|
+
export declare class PlaywrightLocator extends Locator<playwright.ElementHandle, string> {
|
|
5
|
+
constructor(parent: RootLocator<playwright.ElementHandle>, selector: Selector);
|
|
6
|
+
protected nativeSelector(): string;
|
|
7
|
+
nativeElement(): Promise<playwright.ElementHandle>;
|
|
8
|
+
allNativeElements(): Promise<Array<playwright.ElementHandle>>;
|
|
9
|
+
of(parent: PlaywrightRootLocator): Locator<playwright.ElementHandle, string>;
|
|
10
|
+
locate(child: PlaywrightLocator): Locator<playwright.ElementHandle, string>;
|
|
11
|
+
element(): PageElement<playwright.ElementHandle>;
|
|
12
|
+
allElements(): Promise<Array<PageElement<playwright.ElementHandle>>>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PlaywrightLocator = void 0;
|
|
4
|
+
const core_1 = require("@serenity-js/core");
|
|
5
|
+
const web_1 = require("@serenity-js/web");
|
|
6
|
+
const PlaywrightPageElement_1 = require("../PlaywrightPageElement");
|
|
7
|
+
class PlaywrightLocator extends web_1.Locator {
|
|
8
|
+
constructor(parent, selector) {
|
|
9
|
+
super(parent, selector);
|
|
10
|
+
}
|
|
11
|
+
// todo: refactor; replace with a map and some more generic lookup mechanism
|
|
12
|
+
nativeSelector() {
|
|
13
|
+
if (this.selector instanceof web_1.ByCss) {
|
|
14
|
+
return `:light(${this.selector.value})`;
|
|
15
|
+
}
|
|
16
|
+
if (this.selector instanceof web_1.ByDeepCss) {
|
|
17
|
+
return this.selector.value;
|
|
18
|
+
}
|
|
19
|
+
if (this.selector instanceof web_1.ByCssContainingText) {
|
|
20
|
+
return `:light(${this.selector.value}):has-text("${this.selector.text}")`;
|
|
21
|
+
}
|
|
22
|
+
if (this.selector instanceof web_1.ById) {
|
|
23
|
+
return `id=${this.selector.value}`;
|
|
24
|
+
}
|
|
25
|
+
if (this.selector instanceof web_1.ByTagName) {
|
|
26
|
+
return `:light(${this.selector.value})`;
|
|
27
|
+
}
|
|
28
|
+
if (this.selector instanceof web_1.ByXPath) {
|
|
29
|
+
return `xpath=${this.selector.value}`;
|
|
30
|
+
}
|
|
31
|
+
throw new core_1.LogicError((0, core_1.f) `${this.selector} is not supported by ${this.constructor.name}`);
|
|
32
|
+
}
|
|
33
|
+
async nativeElement() {
|
|
34
|
+
const parent = await this.parent.nativeElement();
|
|
35
|
+
if (!parent) {
|
|
36
|
+
throw new core_1.LogicError(`Couldn't find parent element ${this.parent} of ${this}`);
|
|
37
|
+
}
|
|
38
|
+
return parent.waitForSelector(this.nativeSelector(), { state: 'attached' });
|
|
39
|
+
}
|
|
40
|
+
async allNativeElements() {
|
|
41
|
+
const parent = await this.parent.nativeElement();
|
|
42
|
+
if (!parent) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
return parent.$$(this.nativeSelector());
|
|
46
|
+
}
|
|
47
|
+
of(parent) {
|
|
48
|
+
return new PlaywrightLocator(parent, this.selector);
|
|
49
|
+
}
|
|
50
|
+
locate(child) {
|
|
51
|
+
return new PlaywrightLocator(this, child.selector);
|
|
52
|
+
}
|
|
53
|
+
element() {
|
|
54
|
+
return new PlaywrightPageElement_1.PlaywrightPageElement(this);
|
|
55
|
+
}
|
|
56
|
+
async allElements() {
|
|
57
|
+
const elements = await this.allNativeElements();
|
|
58
|
+
return elements.map(childElement => new PlaywrightPageElement_1.PlaywrightPageElement(new ExistingElementLocator(this.parent, this.selector, childElement)));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.PlaywrightLocator = PlaywrightLocator;
|
|
62
|
+
/**
|
|
63
|
+
* @private
|
|
64
|
+
*/
|
|
65
|
+
class ExistingElementLocator extends PlaywrightLocator {
|
|
66
|
+
constructor(parent, selector, existingNativeElement) {
|
|
67
|
+
super(parent, selector);
|
|
68
|
+
this.existingNativeElement = existingNativeElement;
|
|
69
|
+
}
|
|
70
|
+
async nativeElement() {
|
|
71
|
+
return this.existingNativeElement;
|
|
72
|
+
}
|
|
73
|
+
async allNativeElements() {
|
|
74
|
+
return [this.existingNativeElement];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=PlaywrightLocator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlaywrightLocator.js","sourceRoot":"","sources":["../../../../src/screenplay/models/locators/PlaywrightLocator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { RootLocator } from '@serenity-js/web';
|
|
2
|
+
import * as playwright from 'playwright';
|
|
3
|
+
export declare class PlaywrightRootLocator extends RootLocator<playwright.ElementHandle> {
|
|
4
|
+
private readonly page;
|
|
5
|
+
private currentFrame;
|
|
6
|
+
constructor(page: playwright.Page);
|
|
7
|
+
nativeElement(): Promise<Pick<playwright.ElementHandle, '$' | '$$' | 'waitForSelector'>>;
|
|
8
|
+
switchToFrame(frame: playwright.ElementHandle): Promise<void>;
|
|
9
|
+
switchToParentFrame(): Promise<void>;
|
|
10
|
+
switchToMainFrame(): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PlaywrightRootLocator = void 0;
|
|
4
|
+
const web_1 = require("@serenity-js/web");
|
|
5
|
+
const tiny_types_1 = require("tiny-types");
|
|
6
|
+
class PlaywrightRootLocator extends web_1.RootLocator {
|
|
7
|
+
constructor(page) {
|
|
8
|
+
super();
|
|
9
|
+
this.page = page;
|
|
10
|
+
this.currentFrame = this.page.mainFrame();
|
|
11
|
+
}
|
|
12
|
+
async nativeElement() {
|
|
13
|
+
return this.currentFrame;
|
|
14
|
+
}
|
|
15
|
+
async switchToFrame(frame) {
|
|
16
|
+
this.currentFrame = (0, tiny_types_1.ensure)('frame', await frame.contentFrame(), (0, tiny_types_1.isDefined)());
|
|
17
|
+
}
|
|
18
|
+
async switchToParentFrame() {
|
|
19
|
+
this.currentFrame = (0, tiny_types_1.ensure)('parent frame', this.currentFrame.parentFrame(), (0, tiny_types_1.isDefined)());
|
|
20
|
+
}
|
|
21
|
+
async switchToMainFrame() {
|
|
22
|
+
this.currentFrame = this.page.mainFrame();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.PlaywrightRootLocator = PlaywrightRootLocator;
|
|
26
|
+
//# sourceMappingURL=PlaywrightRootLocator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PlaywrightRootLocator.js","sourceRoot":"","sources":["../../../../src/screenplay/models/locators/PlaywrightRootLocator.ts"],"names":[],"mappings":";;;AAAA,0CAA+C;AAE/C,2CAA+C;AAE/C,MAAa,qBAAsB,SAAQ,iBAAqC;IAI5E,YAA6B,IAAqB;QAC9C,KAAK,EAAE,CAAC;QADiB,SAAI,GAAJ,IAAI,CAAiB;QAE9C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,aAAa;QACf,OAAO,IAAI,CAAC,YAAY,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,KAA+B;QAC/C,IAAI,CAAC,YAAY,GAAG,IAAA,mBAAM,EAAC,OAAO,EAAE,MAAM,KAAK,CAAC,YAAY,EAAE,EAAE,IAAA,sBAAS,GAAE,CAAC,CAAC;IACjF,CAAC;IAED,KAAK,CAAC,mBAAmB;QACrB,IAAI,CAAC,YAAY,GAAG,IAAA,mBAAM,EAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,EAAE,IAAA,sBAAS,GAAE,CAAC,CAAC;IAC7F,CAAC;IAED,KAAK,CAAC,iBAAiB;QACnB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;IAC9C,CAAC;CACJ;AAxBD,sDAwBC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./PlaywrightLocator"), exports);
|
|
18
|
+
__exportStar(require("./PlaywrightRootLocator"), exports);
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/screenplay/models/locators/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sDAAoC;AACpC,0DAAwC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@serenity-js/playwright",
|
|
3
|
+
"version": "3.0.0-rc.20",
|
|
4
|
+
"description": "Serenity/JS Screenplay Pattern library for Playwright",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Jan Molak",
|
|
7
|
+
"email": "jan.molak@smartcodeltd.co.uk",
|
|
8
|
+
"url": "https://janmolak.com"
|
|
9
|
+
},
|
|
10
|
+
"funding": {
|
|
11
|
+
"url": "https://github.com/sponsors/serenity-js"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://serenity-js.org",
|
|
14
|
+
"license": "Apache-2.0",
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"main": "lib/index.js",
|
|
19
|
+
"typings": "lib/index.d.ts",
|
|
20
|
+
"keywords": [
|
|
21
|
+
"serenity-js",
|
|
22
|
+
"playwright",
|
|
23
|
+
"tdd",
|
|
24
|
+
"bdd",
|
|
25
|
+
"test",
|
|
26
|
+
"testing"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"clean": "rimraf .nyc_output lib target",
|
|
30
|
+
"lint": "eslint --ext ts --config ../../.eslintrc.yml .",
|
|
31
|
+
"lint:fix": "npm run lint -- --fix",
|
|
32
|
+
"~test": "nyc mocha --config ../../.mocharc.yml 'spec/**/*.spec.*'",
|
|
33
|
+
"compile": "tsc --project tsconfig.json",
|
|
34
|
+
"site": "esdoc -c .esdoc.js"
|
|
35
|
+
},
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/serenity-js/serenity-js.git",
|
|
39
|
+
"directory": "packages/playwright"
|
|
40
|
+
},
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/serenity-js/serenity-js/issues"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": "^14 || ^16",
|
|
46
|
+
"npm": "^6 || ^7 || ^8"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@serenity-js/core": "3.0.0-rc.20",
|
|
50
|
+
"@serenity-js/web": "3.0.0-rc.20",
|
|
51
|
+
"tiny-types": "^1.18.4"
|
|
52
|
+
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"playwright-core": "^1.23.1"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@documentation/esdoc-template": "3.0.0",
|
|
58
|
+
"@integration/testing-tools": "3.0.0",
|
|
59
|
+
"@types/chai": "^4.3.1",
|
|
60
|
+
"@types/mocha": "^9.1.1",
|
|
61
|
+
"mocha": "^10.0.0",
|
|
62
|
+
"nyc": "^15.1.0",
|
|
63
|
+
"playwright-core": "^1.23.1",
|
|
64
|
+
"ts-node": "10.8.0",
|
|
65
|
+
"typescript": "^4.7.4"
|
|
66
|
+
},
|
|
67
|
+
"gitHead": "105a84c6ab140c06e38d328274473a32b290080d"
|
|
68
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as playwright from 'playwright-core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @desc
|
|
5
|
+
* Playwright-specific options used to configure the ability to {@link BrowseTheWebWithPlaywright}
|
|
6
|
+
*
|
|
7
|
+
* @extends {playwright~BrowserContextOptions}
|
|
8
|
+
*/
|
|
9
|
+
export interface PlaywrightOptions extends playwright.BrowserContextOptions {
|
|
10
|
+
/**
|
|
11
|
+
* @desc
|
|
12
|
+
* This setting will change the default maximum navigation time for the browser context used by {@link BrowseTheWebWithPlaywright}
|
|
13
|
+
*
|
|
14
|
+
* @see https://playwright.dev/docs/api/class-browsercontext#browser-context-set-default-navigation-timeout
|
|
15
|
+
*
|
|
16
|
+
* @type {?number}
|
|
17
|
+
*/
|
|
18
|
+
defaultNavigationTimeout?: number;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @desc
|
|
22
|
+
* When to consider navigation operation succeeded, defaults to `load`. Events can be either:
|
|
23
|
+
* - `'domcontentloaded'` - consider operation to be finished when the `DOMContentLoaded` event is fired.
|
|
24
|
+
* - `'load'` - consider operation to be finished when the `load` event is fired.
|
|
25
|
+
* - `'networkidle'` - consider operation to be finished when there are no network connections for at least `500` ms.
|
|
26
|
+
* - `'commit'` - consider operation to be finished when network response is received and the document started loading.
|
|
27
|
+
*
|
|
28
|
+
* @see https://playwright.dev/docs/api/class-page#page-goto-option-wait-until
|
|
29
|
+
*
|
|
30
|
+
* @type {?string}
|
|
31
|
+
*/
|
|
32
|
+
defaultNavigationWaitUntil?: 'load'|'domcontentloaded'|'networkidle'|'commit';
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @desc
|
|
36
|
+
* This setting will change the default maximum time for all Playwright methods accepting `timeout` option.
|
|
37
|
+
*
|
|
38
|
+
* @see https://playwright.dev/docs/api/class-page#page-set-default-timeout
|
|
39
|
+
*
|
|
40
|
+
* @type {?number}
|
|
41
|
+
*/
|
|
42
|
+
defaultTimeout?: number;
|
|
43
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Discardable } from '@serenity-js/core';
|
|
2
|
+
import { BrowserCapabilities, BrowseTheWeb } from '@serenity-js/web';
|
|
3
|
+
import * as playwright from 'playwright-core';
|
|
4
|
+
|
|
5
|
+
import { PlaywrightOptions } from '../../PlaywrightOptions';
|
|
6
|
+
import { PlaywrightBrowsingSession } from '../models';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @desc
|
|
10
|
+
* An {@link @serenity-js/core/lib/screenplay~Ability} that enables the {@link Actor}
|
|
11
|
+
* to interact with web front-ends using [Playwright](https://playwright.dev/).
|
|
12
|
+
*
|
|
13
|
+
* @example <caption>Using a Playwright browser</caption>
|
|
14
|
+
* import { actorCalled } from '@serenity-js/core';
|
|
15
|
+
* import { BrowseTheWebWithPlaywright } from '@serenity-js/playwright';
|
|
16
|
+
* import { By, Navigate, PageElement } from '@serenity-js/web';
|
|
17
|
+
* import { Ensure, equals } from '@serenity-js/assertions';
|
|
18
|
+
* import { Browser, chromium } from 'playwright';
|
|
19
|
+
*
|
|
20
|
+
* const HomePage = {
|
|
21
|
+
* title: PageElement.located(By.css('h1')).describedAs('title')
|
|
22
|
+
* }
|
|
23
|
+
*
|
|
24
|
+
* const browser = await chromium.launch({ headless: true });
|
|
25
|
+
*
|
|
26
|
+
* await actorCalled('Wendy')
|
|
27
|
+
* .whoCan(BrowseTheWebWithPlaywright.using(browser))
|
|
28
|
+
* .attemptsTo(
|
|
29
|
+
* Navigate.to(`https://serenity-js.org`),
|
|
30
|
+
* Ensure.that(Text.of(HomePage.title), equals('Serenity/JS')),
|
|
31
|
+
* );
|
|
32
|
+
*
|
|
33
|
+
* @extends {@serenity-js/web/lib/screenplay/abilities~BrowseTheWeb}
|
|
34
|
+
*
|
|
35
|
+
* @public
|
|
36
|
+
*
|
|
37
|
+
* @see https://playwright.dev/
|
|
38
|
+
* @see {@link @serenity-js/core/lib/screenplay/actor~Actor}
|
|
39
|
+
*/
|
|
40
|
+
export class BrowseTheWebWithPlaywright extends BrowseTheWeb<playwright.ElementHandle> implements Discardable {
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @param {playwright~Browser} browser
|
|
44
|
+
* @param {PlaywrightOptions} options
|
|
45
|
+
* @returns {BrowseTheWebWithPlaywright}
|
|
46
|
+
*/
|
|
47
|
+
static using(browser: playwright.Browser, options?: PlaywrightOptions): BrowseTheWebWithPlaywright {
|
|
48
|
+
return new BrowseTheWebWithPlaywright(browser, options);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @param {playwright~Browser} browser
|
|
53
|
+
* @param {PlaywrightOptions} browserContextOptions
|
|
54
|
+
*/
|
|
55
|
+
protected constructor(protected readonly browser: playwright.Browser, browserContextOptions: PlaywrightOptions = {}) {
|
|
56
|
+
super(new PlaywrightBrowsingSession(browser, browserContextOptions));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @desc
|
|
61
|
+
* Automatically closes any open {@link Page}s when the {@link SceneFinishes}
|
|
62
|
+
*
|
|
63
|
+
* @see {@link PlaywrightBrowsingSession#closeAllPages}
|
|
64
|
+
* @see {@link @serenity-js/core/lib/screenplay/abilities~Discardable}
|
|
65
|
+
*/
|
|
66
|
+
async discard(): Promise<void> {
|
|
67
|
+
await this.session.closeAllPages();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @desc
|
|
72
|
+
* Returns basic meta-data about the browser associated with this ability.
|
|
73
|
+
*
|
|
74
|
+
* **Please note** that since Playwright does not expose information about the operating system
|
|
75
|
+
* the tests are running on, **Serenity/JS assumes that the tests are running locally**
|
|
76
|
+
* and therefore returns the value of Node.js `process.platform` for `platformName`.
|
|
77
|
+
*
|
|
78
|
+
* @returns {Promise<BrowserCapabilities>}
|
|
79
|
+
*
|
|
80
|
+
* @see {@link @serenity-js/web/lib/screenplay/abilities~BrowserCapabilities}
|
|
81
|
+
*/
|
|
82
|
+
async browserCapabilities(): Promise<BrowserCapabilities> {
|
|
83
|
+
return {
|
|
84
|
+
browserName: (this.browser as any)._initializer.name, // todo: raise a PR to Playwright to expose this information
|
|
85
|
+
platformName: process.platform, // todo: get the actual platform from Playwright
|
|
86
|
+
browserVersion: this.browser.version()
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './BrowseTheWebWithPlaywright';
|