@memlab/e2e 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/dist/BaseSynthesizer.d.ts +63 -0
- package/dist/BaseSynthesizer.d.ts.map +1 -0
- package/dist/BaseSynthesizer.js +433 -0
- package/dist/E2EInteractionManager.d.ts +41 -0
- package/dist/E2EInteractionManager.d.ts.map +1 -0
- package/dist/E2EInteractionManager.js +347 -0
- package/dist/TestRunnerLoader.d.ts +16 -0
- package/dist/TestRunnerLoader.d.ts.map +1 -0
- package/dist/TestRunnerLoader.js +41 -0
- package/dist/TypesThirdParty.d.ts +25 -0
- package/dist/TypesThirdParty.d.ts.map +1 -0
- package/dist/TypesThirdParty.js +10 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/lib/E2EUtils.d.ts +59 -0
- package/dist/lib/E2EUtils.d.ts.map +1 -0
- package/dist/lib/E2EUtils.js +286 -0
- package/dist/lib/SynthesisUtils.d.ts +25 -0
- package/dist/lib/SynthesisUtils.d.ts.map +1 -0
- package/dist/lib/SynthesisUtils.js +30 -0
- package/dist/lib/operations/BackOperation.d.ts +17 -0
- package/dist/lib/operations/BackOperation.d.ts.map +1 -0
- package/dist/lib/operations/BackOperation.js +37 -0
- package/dist/lib/operations/BackspaceOperation.d.ts +18 -0
- package/dist/lib/operations/BackspaceOperation.d.ts.map +1 -0
- package/dist/lib/operations/BackspaceOperation.js +36 -0
- package/dist/lib/operations/BaseOperation.d.ts +22 -0
- package/dist/lib/operations/BaseOperation.d.ts.map +1 -0
- package/dist/lib/operations/BaseOperation.js +67 -0
- package/dist/lib/operations/CachePageContent.d.ts +22 -0
- package/dist/lib/operations/CachePageContent.d.ts.map +1 -0
- package/dist/lib/operations/CachePageContent.js +46 -0
- package/dist/lib/operations/ClickOperation.d.ts +36 -0
- package/dist/lib/operations/ClickOperation.d.ts.map +1 -0
- package/dist/lib/operations/ClickOperation.js +131 -0
- package/dist/lib/operations/CompoundOperation.d.ts +20 -0
- package/dist/lib/operations/CompoundOperation.d.ts.map +1 -0
- package/dist/lib/operations/CompoundOperation.js +39 -0
- package/dist/lib/operations/EnterOperation.d.ts +18 -0
- package/dist/lib/operations/EnterOperation.d.ts.map +1 -0
- package/dist/lib/operations/EnterOperation.js +36 -0
- package/dist/lib/operations/EscOperation.d.ts +17 -0
- package/dist/lib/operations/EscOperation.d.ts.map +1 -0
- package/dist/lib/operations/EscOperation.js +36 -0
- package/dist/lib/operations/HoverOperation.d.ts +28 -0
- package/dist/lib/operations/HoverOperation.d.ts.map +1 -0
- package/dist/lib/operations/HoverOperation.js +73 -0
- package/dist/lib/operations/InteractionUtils.d.ts +33 -0
- package/dist/lib/operations/InteractionUtils.d.ts.map +1 -0
- package/dist/lib/operations/InteractionUtils.js +207 -0
- package/dist/lib/operations/Operations.d.ts +25 -0
- package/dist/lib/operations/Operations.d.ts.map +1 -0
- package/dist/lib/operations/Operations.js +45 -0
- package/dist/lib/operations/RevertOperation.d.ts +18 -0
- package/dist/lib/operations/RevertOperation.d.ts.map +1 -0
- package/dist/lib/operations/RevertOperation.js +55 -0
- package/dist/lib/operations/RunJSCode.d.ts +25 -0
- package/dist/lib/operations/RunJSCode.d.ts.map +1 -0
- package/dist/lib/operations/RunJSCode.js +51 -0
- package/dist/lib/operations/ScrollOperation.d.ts +27 -0
- package/dist/lib/operations/ScrollOperation.d.ts.map +1 -0
- package/dist/lib/operations/ScrollOperation.js +85 -0
- package/dist/lib/operations/TargetExtraOperation.d.ts +18 -0
- package/dist/lib/operations/TargetExtraOperation.d.ts.map +1 -0
- package/dist/lib/operations/TargetExtraOperation.js +28 -0
- package/dist/lib/operations/TestPlanner.d.ts +46 -0
- package/dist/lib/operations/TestPlanner.d.ts.map +1 -0
- package/dist/lib/operations/TestPlanner.js +182 -0
- package/dist/lib/operations/TypeOperation.d.ts +29 -0
- package/dist/lib/operations/TypeOperation.d.ts.map +1 -0
- package/dist/lib/operations/TypeOperation.js +64 -0
- package/dist/lib/operations/UploadOperation.d.ts +25 -0
- package/dist/lib/operations/UploadOperation.d.ts.map +1 -0
- package/dist/lib/operations/UploadOperation.js +56 -0
- package/dist/lib/operations/WaitForElementOperation.d.ts +32 -0
- package/dist/lib/operations/WaitForElementOperation.d.ts.map +1 -0
- package/dist/lib/operations/WaitForElementOperation.js +67 -0
- package/dist/lib/operations/WaitOperation.d.ts +19 -0
- package/dist/lib/operations/WaitOperation.d.ts.map +1 -0
- package/dist/lib/operations/WaitOperation.js +42 -0
- package/dist/lib/operations/WithCachedPageContent.d.ts +26 -0
- package/dist/lib/operations/WithCachedPageContent.d.ts.map +1 -0
- package/dist/lib/operations/WithCachedPageContent.js +53 -0
- package/dist/lib/operations/XVirtualFrameBuffer.d.ts +15 -0
- package/dist/lib/operations/XVirtualFrameBuffer.d.ts.map +1 -0
- package/dist/lib/operations/XVirtualFrameBuffer.js +44 -0
- package/dist/plugins/DefaultScenarioSynthesizer.d.ts +23 -0
- package/dist/plugins/DefaultScenarioSynthesizer.d.ts.map +1 -0
- package/dist/plugins/DefaultScenarioSynthesizer.js +61 -0
- package/dist/plugins/TestSPAVisitSynthesizer.d.ts +23 -0
- package/dist/plugins/TestSPAVisitSynthesizer.d.ts.map +1 -0
- package/dist/plugins/TestSPAVisitSynthesizer.js +72 -0
- package/dist/plugins/scenarios/test-airbnb.d.ts +14 -0
- package/dist/plugins/scenarios/test-airbnb.d.ts.map +1 -0
- package/dist/plugins/scenarios/test-airbnb.js +48 -0
- package/dist/plugins/scenarios/test-databricks.d.ts +14 -0
- package/dist/plugins/scenarios/test-databricks.d.ts.map +1 -0
- package/dist/plugins/scenarios/test-databricks.js +40 -0
- package/dist/plugins/scenarios/test-ebay.d.ts +14 -0
- package/dist/plugins/scenarios/test-ebay.d.ts.map +1 -0
- package/dist/plugins/scenarios/test-ebay.js +48 -0
- package/dist/plugins/scenarios/test-google-maps.d.ts +14 -0
- package/dist/plugins/scenarios/test-google-maps.d.ts.map +1 -0
- package/dist/plugins/scenarios/test-google-maps.js +41 -0
- package/dist/plugins/scenarios/test-shopify.d.ts +14 -0
- package/dist/plugins/scenarios/test-shopify.d.ts.map +1 -0
- package/dist/plugins/scenarios/test-shopify.js +40 -0
- package/dist/plugins/scenarios/test-youtube.d.ts +14 -0
- package/dist/plugins/scenarios/test-youtube.d.ts.map +1 -0
- package/dist/plugins/scenarios/test-youtube.js +40 -0
- package/package.json +53 -0
- package/static/links/index.html +18 -0
- package/static/links/min.js +3 -0
- package/static/links/package.json +36 -0
- package/static/links/src/App.js +48 -0
- package/static/links/src/index.js +20 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*
|
|
8
|
+
* @emails oncall+ws_labs
|
|
9
|
+
* @format
|
|
10
|
+
*/
|
|
11
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
14
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
15
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
16
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
17
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
21
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
22
|
+
};
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
const core_1 = require("@memlab/core");
|
|
25
|
+
const BaseOperation_1 = __importDefault(require("./BaseOperation"));
|
|
26
|
+
const InteractionUtils_1 = __importDefault(require("./InteractionUtils"));
|
|
27
|
+
class ClickOperation extends BaseOperation_1.default {
|
|
28
|
+
constructor(selector, args = {}) {
|
|
29
|
+
super();
|
|
30
|
+
this.kind = 'click';
|
|
31
|
+
this.selector = selector;
|
|
32
|
+
this.delay = args.delay;
|
|
33
|
+
this.optional = !!args.optional;
|
|
34
|
+
this.waitFor = args.waitFor;
|
|
35
|
+
this.clickCount = args.clickCount;
|
|
36
|
+
this.indexInMatches = args.indexInMatches;
|
|
37
|
+
// Takes a selector (string) to check if the selector is present or takes
|
|
38
|
+
// a function and evaluates that function to conditionally do the click
|
|
39
|
+
// operation
|
|
40
|
+
this.if = args.if;
|
|
41
|
+
}
|
|
42
|
+
_shouldClick(page) {
|
|
43
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
44
|
+
if (this.if == null) {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
let shouldClick;
|
|
48
|
+
if (typeof this.if === 'string') {
|
|
49
|
+
const element = yield page.$(this.if);
|
|
50
|
+
shouldClick = !!element;
|
|
51
|
+
if (element != null) {
|
|
52
|
+
yield element.dispose();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else if (typeof this.if === 'function') {
|
|
56
|
+
shouldClick = yield this.if(page);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
throw core_1.utils.haltOrThrow(`ClickOperation: 'if' must be a string or function`);
|
|
60
|
+
}
|
|
61
|
+
return shouldClick;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
useContains() {
|
|
65
|
+
return this.selector.startsWith('contains:');
|
|
66
|
+
}
|
|
67
|
+
// click element with specified settings
|
|
68
|
+
clickElement(page) {
|
|
69
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
70
|
+
const clickCount = this.clickCount || 1;
|
|
71
|
+
if (!this.useContains() && this.indexInMatches == null) {
|
|
72
|
+
yield page.click(this.selector, { clickCount });
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
let elems;
|
|
76
|
+
// if given a special contains-text selector
|
|
77
|
+
if (this.useContains()) {
|
|
78
|
+
const text = this.selector.slice('contains:'.length);
|
|
79
|
+
elems = yield InteractionUtils_1.default.getElementsContainingText(page, text);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
elems = yield page.$$(this.selector);
|
|
83
|
+
}
|
|
84
|
+
if (!elems || elems.length === 0) {
|
|
85
|
+
core_1.utils.haltOrThrow(`selector not found: ${this.selector}`);
|
|
86
|
+
}
|
|
87
|
+
let idx = this.indexInMatches != null ? this.indexInMatches : 0;
|
|
88
|
+
if (idx < 0) {
|
|
89
|
+
idx = elems.length + idx;
|
|
90
|
+
}
|
|
91
|
+
if (idx < 0 || idx >= elems.length) {
|
|
92
|
+
core_1.utils.haltOrThrow(`clicking ${idx + 1}-th element, which doesn't exist`);
|
|
93
|
+
}
|
|
94
|
+
yield elems[idx].click({ clickCount });
|
|
95
|
+
yield Promise.all(elems.map(e => e.dispose()));
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
act(page) {
|
|
99
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
100
|
+
const shouldClick = yield this._shouldClick(page);
|
|
101
|
+
if (!shouldClick) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const present = yield InteractionUtils_1.default.checkIfPresent(page, this.selector, this.optional);
|
|
105
|
+
if (!present) {
|
|
106
|
+
if (!this.optional) {
|
|
107
|
+
core_1.utils.haltOrThrow(`Cannot find element ${this.selector}`);
|
|
108
|
+
}
|
|
109
|
+
return; // if optional element is not found
|
|
110
|
+
}
|
|
111
|
+
this.log(`clicking ${this.selector}`);
|
|
112
|
+
yield this.clickElement(page);
|
|
113
|
+
// extra delay
|
|
114
|
+
const delay = this.delay != null ? this.delay : core_1.config.defaultAfterClickDelay;
|
|
115
|
+
yield InteractionUtils_1.default.waitFor(delay);
|
|
116
|
+
// waiting for elements
|
|
117
|
+
if (this.waitFor != null) {
|
|
118
|
+
if (typeof this.waitFor === 'string') {
|
|
119
|
+
yield InteractionUtils_1.default.waitForSelector(page, this.waitFor, 'exist', this.optional);
|
|
120
|
+
}
|
|
121
|
+
else if (typeof this.waitFor === 'function') {
|
|
122
|
+
yield this.waitFor(page);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
core_1.info.error(`ClickOperation: 'waitFor' must be a string or function`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
exports.default = ClickOperation;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @emails oncall+ws_labs
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
import { Page } from 'puppeteer';
|
|
11
|
+
import type { E2EOperation } from '@memlab/core';
|
|
12
|
+
import BaseOperation from './BaseOperation';
|
|
13
|
+
declare class CompoundOperation extends BaseOperation {
|
|
14
|
+
kind: string;
|
|
15
|
+
protected operations: E2EOperation[];
|
|
16
|
+
constructor(operations?: never[]);
|
|
17
|
+
act(page: Page): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
export default CompoundOperation;
|
|
20
|
+
//# sourceMappingURL=CompoundOperation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CompoundOperation.d.ts","sourceRoot":"","sources":["../../../src/lib/operations/CompoundOperation.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AAC/B,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,cAAc,CAAC;AAC/C,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAE5C,cAAM,iBAAkB,SAAQ,aAAa;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC;gBACzB,UAAU,UAAK;IAMrB,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;CAKrC;AAED,eAAe,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*
|
|
8
|
+
* @emails oncall+ws_labs
|
|
9
|
+
* @format
|
|
10
|
+
*/
|
|
11
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
14
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
15
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
16
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
17
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
21
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
22
|
+
};
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
const BaseOperation_1 = __importDefault(require("./BaseOperation"));
|
|
25
|
+
class CompoundOperation extends BaseOperation_1.default {
|
|
26
|
+
constructor(operations = []) {
|
|
27
|
+
super();
|
|
28
|
+
this.kind = 'compound';
|
|
29
|
+
this.operations = operations;
|
|
30
|
+
}
|
|
31
|
+
act(page) {
|
|
32
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
33
|
+
for (const op of this.operations) {
|
|
34
|
+
yield op.act(page);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.default = CompoundOperation;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @emails oncall+ws_labs
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
import { Page } from 'puppeteer';
|
|
11
|
+
import BaseOperation from './BaseOperation';
|
|
12
|
+
declare class EnterOperation extends BaseOperation {
|
|
13
|
+
kind: string;
|
|
14
|
+
constructor();
|
|
15
|
+
act(page: Page): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export default EnterOperation;
|
|
18
|
+
//# sourceMappingURL=EnterOperation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EnterOperation.d.ts","sourceRoot":"","sources":["../../../src/lib/operations/EnterOperation.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AAC/B,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAE5C,cAAM,cAAe,SAAQ,aAAa;IACxC,IAAI,EAAE,MAAM,CAAC;;IAMP,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;CAGrC;AAED,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*
|
|
8
|
+
* @emails oncall+ws_labs
|
|
9
|
+
* @format
|
|
10
|
+
*/
|
|
11
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
14
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
15
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
16
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
17
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
21
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
22
|
+
};
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
const BaseOperation_1 = __importDefault(require("./BaseOperation"));
|
|
25
|
+
class EnterOperation extends BaseOperation_1.default {
|
|
26
|
+
constructor() {
|
|
27
|
+
super();
|
|
28
|
+
this.kind = 'enter';
|
|
29
|
+
}
|
|
30
|
+
act(page) {
|
|
31
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
32
|
+
yield page.keyboard.press('Enter');
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.default = EnterOperation;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @emails oncall+ws_labs
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
import BaseOperation from './BaseOperation';
|
|
11
|
+
import type { Page } from 'puppeteer';
|
|
12
|
+
export default class EscOperation extends BaseOperation {
|
|
13
|
+
kind: string;
|
|
14
|
+
constructor();
|
|
15
|
+
act(page: Page): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=EscOperation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EscOperation.d.ts","sourceRoot":"","sources":["../../../src/lib/operations/EscOperation.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AAEpC,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,aAAa;IACrD,IAAI,EAAE,MAAM,CAAC;;IAOP,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;CAGrC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*
|
|
8
|
+
* @emails oncall+ws_labs
|
|
9
|
+
* @format
|
|
10
|
+
*/
|
|
11
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
14
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
15
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
16
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
17
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
21
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
22
|
+
};
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
const BaseOperation_1 = __importDefault(require("./BaseOperation"));
|
|
25
|
+
class EscOperation extends BaseOperation_1.default {
|
|
26
|
+
constructor() {
|
|
27
|
+
super();
|
|
28
|
+
this.kind = 'escape';
|
|
29
|
+
}
|
|
30
|
+
act(page) {
|
|
31
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
32
|
+
yield page.keyboard.press('Escape');
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.default = EscOperation;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @emails oncall+ws_labs
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
import { Page } from 'puppeteer';
|
|
11
|
+
import type { Optional } from '@memlab/core';
|
|
12
|
+
import BaseOperation from './BaseOperation';
|
|
13
|
+
declare type HoverOptions = {
|
|
14
|
+
delay?: number;
|
|
15
|
+
optional?: boolean;
|
|
16
|
+
indexInMatches?: number;
|
|
17
|
+
};
|
|
18
|
+
declare class HoverOperation extends BaseOperation {
|
|
19
|
+
kind: string;
|
|
20
|
+
selector: string;
|
|
21
|
+
delay: Optional<number>;
|
|
22
|
+
indexInMatches: Optional<number>;
|
|
23
|
+
constructor(selector: string, args?: HoverOptions);
|
|
24
|
+
private hoverOverElement;
|
|
25
|
+
act(page: Page): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
export default HoverOperation;
|
|
28
|
+
//# sourceMappingURL=HoverOperation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HoverOperation.d.ts","sourceRoot":"","sources":["../../../src/lib/operations/HoverOperation.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AAE/B,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,cAAc,CAAC;AAC3C,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAG5C,aAAK,YAAY,GAAG;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,cAAM,cAAe,SAAQ,aAAa;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACxB,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACrB,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,YAAiB;YAUvC,gBAAgB;IAyBxB,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;CAcrC;AAED,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*
|
|
8
|
+
* @emails oncall+ws_labs
|
|
9
|
+
* @format
|
|
10
|
+
*/
|
|
11
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
14
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
15
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
16
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
17
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
21
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
22
|
+
};
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
const core_1 = require("@memlab/core");
|
|
25
|
+
const BaseOperation_1 = __importDefault(require("./BaseOperation"));
|
|
26
|
+
const InteractionUtils_1 = __importDefault(require("./InteractionUtils"));
|
|
27
|
+
class HoverOperation extends BaseOperation_1.default {
|
|
28
|
+
constructor(selector, args = {}) {
|
|
29
|
+
super();
|
|
30
|
+
this.kind = 'hover';
|
|
31
|
+
this.selector = selector;
|
|
32
|
+
this.delay = args.delay;
|
|
33
|
+
this.optional = !!args.optional;
|
|
34
|
+
this.indexInMatches = args.indexInMatches;
|
|
35
|
+
}
|
|
36
|
+
// hover over element with specified settings
|
|
37
|
+
hoverOverElement(page) {
|
|
38
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
if (this.indexInMatches == null) {
|
|
40
|
+
yield page.hover(this.selector);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const elems = yield page.$$(this.selector);
|
|
44
|
+
if (!elems || elems.length === 0) {
|
|
45
|
+
core_1.utils.haltOrThrow(`selector not found: ${this.selector}`);
|
|
46
|
+
}
|
|
47
|
+
let idx = this.indexInMatches;
|
|
48
|
+
if (idx < 0) {
|
|
49
|
+
idx = elems.length + idx;
|
|
50
|
+
}
|
|
51
|
+
if (idx < 0 || idx >= elems.length) {
|
|
52
|
+
core_1.utils.haltOrThrow(`hovering over ${idx + 1}-th element, which doesn't exist`);
|
|
53
|
+
}
|
|
54
|
+
yield elems[idx].hover();
|
|
55
|
+
yield Promise.all(elems.map(e => e.dispose()));
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
act(page) {
|
|
59
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
60
|
+
const present = yield InteractionUtils_1.default.checkIfPresent(page, this.selector);
|
|
61
|
+
if (!present && !this.optional) {
|
|
62
|
+
core_1.utils.haltOrThrow(`Cannot find element ${this.selector}`);
|
|
63
|
+
}
|
|
64
|
+
if (present) {
|
|
65
|
+
this.log(`hovering over ${this.selector}`);
|
|
66
|
+
yield this.hoverOverElement(page);
|
|
67
|
+
const delay = this.delay != null ? this.delay : core_1.config.defaultAfterClickDelay;
|
|
68
|
+
yield InteractionUtils_1.default.waitFor(delay);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.default = HoverOperation;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @emails oncall+ws_labs
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
import type { Page, ElementHandle } from 'puppeteer';
|
|
11
|
+
import type { CheckPageLoadCallback, OperationArgs } from '@memlab/core';
|
|
12
|
+
declare function waitFor(delay: number): Promise<void>;
|
|
13
|
+
declare function WaitUntilCallbackReturnsTrue(page: Page, isPageLoaded: CheckPageLoadCallback, options?: OperationArgs): Promise<void>;
|
|
14
|
+
declare function waitUntilLoaded(page: Page, options?: OperationArgs): Promise<void>;
|
|
15
|
+
declare function screenshot(page: Page, name: string | number): Promise<void>;
|
|
16
|
+
declare function waitForSelector(page: Page, selector: string, whatToWaitForSelectorToDo?: string, optional?: boolean): Promise<boolean>;
|
|
17
|
+
declare function checkIfPresent(page: Page, selector: string, optional?: boolean): Promise<boolean>;
|
|
18
|
+
declare function checkIfVisible(page: Page, selector: string, optional?: boolean): Promise<boolean>;
|
|
19
|
+
declare function waitForDisappearance(page: Page, selector: string, optional?: boolean): Promise<boolean>;
|
|
20
|
+
declare function getElementsContainingText(page: Page, text: string): Promise<ElementHandle<Element>[]>;
|
|
21
|
+
declare const _default: {
|
|
22
|
+
checkIfPresent: typeof checkIfPresent;
|
|
23
|
+
checkIfVisible: typeof checkIfVisible;
|
|
24
|
+
getElementsContainingText: typeof getElementsContainingText;
|
|
25
|
+
screenshot: typeof screenshot;
|
|
26
|
+
waitFor: typeof waitFor;
|
|
27
|
+
waitForDisappearance: typeof waitForDisappearance;
|
|
28
|
+
waitForSelector: typeof waitForSelector;
|
|
29
|
+
WaitUntilCallbackReturnsTrue: typeof WaitUntilCallbackReturnsTrue;
|
|
30
|
+
waitUntilLoaded: typeof waitUntilLoaded;
|
|
31
|
+
};
|
|
32
|
+
export default _default;
|
|
33
|
+
//# sourceMappingURL=InteractionUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InteractionUtils.d.ts","sourceRoot":"","sources":["../../../src/lib/operations/InteractionUtils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,OAAO,KAAK,EAAC,IAAI,EAAE,aAAa,EAAC,MAAM,WAAW,CAAC;AACnD,OAAO,KAAK,EAAC,qBAAqB,EAAE,aAAa,EAAC,MAAM,cAAc,CAAC;AAEvE,iBAAS,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7C;AAED,iBAAe,4BAA4B,CACzC,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,qBAAqB,EACnC,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CA8Cf;AAED,iBAAe,eAAe,CAC5B,IAAI,EAAE,IAAI,EACV,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAwBf;AAED,iBAAe,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO1E;AASD,iBAAe,eAAe,CAC5B,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM,EAChB,yBAAyB,SAAU,EACnC,QAAQ,UAAQ,GACf,OAAO,CAAC,OAAO,CAAC,CAyClB;AAmBD,iBAAe,cAAc,CAC3B,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM,EAChB,QAAQ,UAAQ,GACf,OAAO,CAAC,OAAO,CAAC,CAElB;AAED,iBAAe,cAAc,CAC3B,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM,EAChB,QAAQ,UAAQ,GACf,OAAO,CAAC,OAAO,CAAC,CAElB;AAED,iBAAe,oBAAoB,CACjC,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,MAAM,EAChB,QAAQ,UAAQ,GACf,OAAO,CAAC,OAAO,CAAC,CAElB;AAED,iBAAe,yBAAyB,CACtC,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,CAInC;;;;;;;;;;;;AAED,wBAUE"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @emails oncall+ws_labs
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
'use strict';
|
|
11
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
14
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
15
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
16
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
17
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
21
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
22
|
+
};
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
const core_1 = require("@memlab/core");
|
|
25
|
+
const path_1 = __importDefault(require("path"));
|
|
26
|
+
function waitFor(delay) {
|
|
27
|
+
return new Promise(resolve => {
|
|
28
|
+
setTimeout(resolve, delay);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function WaitUntilCallbackReturnsTrue(page, isPageLoaded, options = {}) {
|
|
32
|
+
var _a;
|
|
33
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
34
|
+
if (options.showProgress) {
|
|
35
|
+
core_1.info.overwrite('waiting for page load...');
|
|
36
|
+
}
|
|
37
|
+
let isSuccessful = false;
|
|
38
|
+
const failedURLs = (_a = options.failedURLs) !== null && _a !== void 0 ? _a : Object.create(null);
|
|
39
|
+
const url = new URL(page.url());
|
|
40
|
+
if (failedURLs[url.pathname]) {
|
|
41
|
+
return yield waitFor(core_1.config.delayWhenNoPageLoadCheck);
|
|
42
|
+
}
|
|
43
|
+
// retry check for at most 10 minutes
|
|
44
|
+
for (let i = 0; i < 10 * 60 * 50; ++i) {
|
|
45
|
+
// now check
|
|
46
|
+
let doneOrError;
|
|
47
|
+
try {
|
|
48
|
+
doneOrError = yield isPageLoaded(page);
|
|
49
|
+
}
|
|
50
|
+
catch (_b) {
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
// if Check succeed
|
|
54
|
+
if (doneOrError === true) {
|
|
55
|
+
isSuccessful = true;
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
else if (typeof doneOrError === 'string') {
|
|
59
|
+
// if error during page load check
|
|
60
|
+
return core_1.info.warning(`Checking page load got: ${doneOrError}`);
|
|
61
|
+
}
|
|
62
|
+
// Check page load is not successful yet, check again
|
|
63
|
+
yield waitFor(200);
|
|
64
|
+
}
|
|
65
|
+
if (!isSuccessful) {
|
|
66
|
+
if (!options.mute) {
|
|
67
|
+
core_1.info.overwrite(`Check timeout '${url.pathname}' set wait: ${core_1.config.delayWhenNoPageLoadCheck}ms`);
|
|
68
|
+
}
|
|
69
|
+
failedURLs[url.pathname] = true;
|
|
70
|
+
}
|
|
71
|
+
if (!options.noWaitAfterPageLoad) {
|
|
72
|
+
yield waitFor(core_1.config.waitAfterPageLoad);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
function waitUntilLoaded(page, options = {}) {
|
|
77
|
+
var _a;
|
|
78
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
79
|
+
// manual delay supercedes page load checker
|
|
80
|
+
let delay = (_a = options.delay) !== null && _a !== void 0 ? _a : 0;
|
|
81
|
+
if (delay > 0) {
|
|
82
|
+
if (!options.mute && delay > 2000) {
|
|
83
|
+
core_1.info.overwrite(`wait for ${delay / 1000}s`);
|
|
84
|
+
}
|
|
85
|
+
yield waitFor(delay);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
// check page load with specified checker
|
|
89
|
+
const isPageLoaded = options.isPageLoaded;
|
|
90
|
+
if (isPageLoaded) {
|
|
91
|
+
yield WaitUntilCallbackReturnsTrue(page, isPageLoaded, options);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
// if nothing is specified, use default delay
|
|
95
|
+
delay = core_1.config.delayWhenNoPageLoadCheck;
|
|
96
|
+
if (!options.mute && delay > 2000) {
|
|
97
|
+
core_1.info.overwrite(`wait for ${delay / 1000}s`);
|
|
98
|
+
}
|
|
99
|
+
yield waitFor(delay);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
function screenshot(page, name) {
|
|
103
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
104
|
+
if (core_1.config.isContinuousTest) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const screenshotFile = path_1.default.join(core_1.config.curDataDir, `screenshot-${name}.png`);
|
|
108
|
+
core_1.info.overwrite('taking screenshot...');
|
|
109
|
+
yield page.screenshot({ path: screenshotFile });
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
function getWaitTimeout(optional) {
|
|
113
|
+
if (optional) {
|
|
114
|
+
return 3000;
|
|
115
|
+
}
|
|
116
|
+
return core_1.config.presenceCheckTimeout || 60000;
|
|
117
|
+
}
|
|
118
|
+
function waitForSelector(page, selector, whatToWaitForSelectorToDo = 'exist', optional = false) {
|
|
119
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
120
|
+
const timeout = getWaitTimeout(optional);
|
|
121
|
+
let waitConfig = null;
|
|
122
|
+
switch (whatToWaitForSelectorToDo) {
|
|
123
|
+
case 'appear':
|
|
124
|
+
waitConfig = {
|
|
125
|
+
visible: true, // ie. not `display:none` or `visibility:hidden`
|
|
126
|
+
};
|
|
127
|
+
break;
|
|
128
|
+
case 'disappear':
|
|
129
|
+
waitConfig = {
|
|
130
|
+
hidden: true, // ie. `display:none`, `visibility:hidden`, or removed
|
|
131
|
+
};
|
|
132
|
+
break;
|
|
133
|
+
case 'exist': // ie. existent, whether visible or not; default config.
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
core_1.info.overwrite(`wait for ${selector} to ${whatToWaitForSelectorToDo}`);
|
|
137
|
+
if (selector.startsWith('contains:')) {
|
|
138
|
+
return yield keepTryingUntil(() => __awaiter(this, void 0, void 0, function* () {
|
|
139
|
+
const text = selector.slice('contains:'.length);
|
|
140
|
+
const elems = yield getElementsContainingText(page, text);
|
|
141
|
+
if (!elems || elems.length === 0) {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
yield Promise.all(elems.map(e => e.dispose()));
|
|
145
|
+
return true;
|
|
146
|
+
}), timeout);
|
|
147
|
+
}
|
|
148
|
+
try {
|
|
149
|
+
const elem = yield page.waitForSelector(selector, Object.assign(Object.assign({}, waitConfig), { timeout }));
|
|
150
|
+
if (elem) {
|
|
151
|
+
yield elem.dispose();
|
|
152
|
+
}
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
catch (_a) {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
function keepTryingUntil(checkCallback, timeout = 2000) {
|
|
161
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
162
|
+
const startTimestamp = Date.now();
|
|
163
|
+
let currentTimestamp = Date.now();
|
|
164
|
+
while (currentTimestamp - startTimestamp < timeout) {
|
|
165
|
+
const flag = yield checkCallback();
|
|
166
|
+
if (flag) {
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
yield waitFor(200);
|
|
170
|
+
currentTimestamp = Date.now();
|
|
171
|
+
}
|
|
172
|
+
return false;
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
function checkIfPresent(page, selector, optional = false) {
|
|
176
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
177
|
+
return waitForSelector(page, selector, 'exist', optional);
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
function checkIfVisible(page, selector, optional = false) {
|
|
181
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
182
|
+
return waitForSelector(page, selector, 'appear', optional);
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
function waitForDisappearance(page, selector, optional = false) {
|
|
186
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
187
|
+
return waitForSelector(page, selector, 'disappear', optional);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
function getElementsContainingText(page, text) {
|
|
191
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
192
|
+
const xpath = `//*[not(self::script)][contains(text(), '${text}')]`;
|
|
193
|
+
const elements = yield page.$x(xpath);
|
|
194
|
+
return elements;
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
exports.default = {
|
|
198
|
+
checkIfPresent,
|
|
199
|
+
checkIfVisible,
|
|
200
|
+
getElementsContainingText,
|
|
201
|
+
screenshot,
|
|
202
|
+
waitFor,
|
|
203
|
+
waitForDisappearance,
|
|
204
|
+
waitForSelector,
|
|
205
|
+
WaitUntilCallbackReturnsTrue,
|
|
206
|
+
waitUntilLoaded,
|
|
207
|
+
};
|