rebrowser-playwright-core 1.47.2 → 1.48.2
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 +2 -0
- package/browsers.json +14 -10
- package/lib/cli/program.js +26 -14
- package/lib/client/api.js +6 -0
- package/lib/client/browserContext.js +20 -2
- package/lib/client/channelOwner.js +5 -1
- package/lib/client/connection.js +3 -0
- package/lib/client/fetch.js +16 -21
- package/lib/client/jsHandle.js +0 -8
- package/lib/client/localUtils.js +1 -0
- package/lib/client/network.js +175 -17
- package/lib/client/page.js +21 -0
- package/lib/client/playwright.js +6 -3
- package/lib/client/tracing.js +16 -20
- package/lib/generated/consoleApiSource.js +1 -1
- package/lib/generated/injectedScriptSource.js +1 -1
- package/lib/generated/pollingRecorderSource.js +7 -0
- package/lib/generated/webSocketMockSource.js +7 -0
- package/lib/protocol/validator.js +80 -14
- package/lib/server/bidi/bidiBrowser.js +23 -8
- package/lib/server/bidi/bidiChromium.js +124 -0
- package/lib/server/bidi/bidiConnection.js +1 -1
- package/lib/server/bidi/bidiExecutionContext.js +0 -3
- package/lib/server/bidi/bidiFirefox.js +15 -21
- package/lib/server/bidi/bidiInput.js +16 -32
- package/lib/server/bidi/bidiNetworkManager.js +39 -5
- package/lib/server/bidi/bidiOverCdp.js +103 -0
- package/lib/server/bidi/bidiPage.js +98 -25
- package/lib/server/bidi/bidiPdf.js +140 -0
- package/lib/server/bidi/third_party/firefoxPrefs.js +221 -0
- package/lib/server/browser.js +13 -2
- package/lib/server/browserContext.js +6 -23
- package/lib/server/browserType.js +39 -11
- package/lib/server/chromium/chromium.js +3 -15
- package/lib/server/chromium/chromiumSwitches.js +3 -1
- package/lib/server/chromium/crBrowser.js +4 -3
- package/lib/server/chromium/crExecutionContext.js +0 -7
- package/lib/server/chromium/crPage.js +16 -6
- package/lib/server/chromium/videoRecorder.js +1 -1
- package/lib/server/codegen/csharp.js +1 -1
- package/lib/server/codegen/java.js +1 -1
- package/lib/server/codegen/javascript.js +1 -1
- package/lib/server/codegen/language.js +14 -2
- package/lib/server/codegen/python.js +1 -1
- package/lib/server/cookieStore.js +73 -0
- package/lib/server/debugController.js +2 -2
- package/lib/server/deviceDescriptorsSource.json +50 -50
- package/lib/server/dialog.js +1 -0
- package/lib/server/dispatchers/browserContextDispatcher.js +19 -2
- package/lib/server/dispatchers/jsHandleDispatcher.js +0 -5
- package/lib/server/dispatchers/pageDispatcher.js +9 -0
- package/lib/server/dispatchers/playwrightDispatcher.js +2 -1
- package/lib/server/dispatchers/webSocketRouteDispatcher.js +189 -0
- package/lib/server/download.js +9 -2
- package/lib/server/fetch.js +90 -94
- package/lib/server/firefox/ffBrowser.js +6 -4
- package/lib/server/firefox/ffExecutionContext.js +0 -3
- package/lib/server/firefox/ffPage.js +6 -3
- package/lib/server/firefox/firefox.js +2 -13
- package/lib/server/frameSelectors.js +1 -1
- package/lib/server/frames.js +164 -28
- package/lib/server/har/harTracer.js +11 -0
- package/lib/server/input.js +0 -1
- package/lib/server/javascript.js +0 -7
- package/lib/server/page.js +5 -1
- package/lib/server/playwright.js +5 -2
- package/lib/server/recorder/contextRecorder.js +33 -50
- package/lib/server/recorder/recorderApp.js +16 -10
- package/lib/server/recorder/recorderCollection.js +68 -79
- package/lib/server/recorder/recorderInTraceViewer.js +144 -0
- package/lib/server/recorder/recorderRunner.js +75 -97
- package/lib/server/recorder/recorderUtils.js +47 -6
- package/lib/server/recorder.js +30 -25
- package/lib/server/registry/index.js +85 -4
- package/lib/server/socksClientCertificatesInterceptor.js +15 -3
- package/lib/server/trace/recorder/snapshotter.js +1 -0
- package/lib/server/trace/recorder/snapshotterInjected.js +2 -2
- package/lib/server/trace/recorder/tracing.js +58 -2
- package/lib/server/trace/test/inMemorySnapshotter.js +1 -1
- package/lib/server/trace/viewer/traceViewer.js +2 -5
- package/lib/server/webkit/webkit.js +1 -1
- package/lib/server/webkit/wkBrowser.js +6 -5
- package/lib/server/webkit/wkExecutionContext.js +0 -3
- package/lib/server/webkit/wkPage.js +7 -4
- package/lib/utils/happy-eyeballs.js +13 -0
- package/lib/utils/hostPlatform.js +2 -2
- package/lib/utils/httpServer.js +1 -0
- package/lib/utils/isomorphic/locatorGenerators.js +9 -18
- package/lib/utils/isomorphic/locatorParser.js +2 -2
- package/lib/utils/isomorphic/recorderUtils.js +195 -0
- package/lib/vite/htmlReport/index.html +12 -12
- package/lib/vite/recorder/assets/{codeMirrorModule-aW6Vz3gf.js → codeMirrorModule-baozm8ur.js} +1 -1
- package/lib/vite/recorder/assets/{index-DCpXOVIh.js → index-2ElAIWFB.js} +10 -15
- package/lib/vite/recorder/assets/{index-B-MT5gKo.css → index-BW-aOBcL.css} +1 -1
- package/lib/vite/recorder/index.html +2 -2
- package/lib/vite/traceViewer/assets/{codeMirrorModule-eFKCUIu2.js → codeMirrorModule-Bh1rfd2w.js} +1 -1
- package/lib/vite/traceViewer/assets/inspectorTab-7GHnKvSD.js +64 -0
- package/lib/vite/traceViewer/assets/workbench-DPQnTHYP.js +9 -0
- package/lib/vite/traceViewer/embedded.BlHoW5LY.js +2 -0
- package/lib/vite/traceViewer/embedded.html +5 -3
- package/lib/vite/traceViewer/index.DaWVfou1.js +2 -0
- package/lib/vite/traceViewer/index.html +5 -3
- package/lib/vite/traceViewer/inspectorTab.DLjBDrQR.css +1 -0
- package/lib/vite/traceViewer/recorder.B_SY1GJM.css +0 -0
- package/lib/vite/traceViewer/recorder.C4zxcvd2.js +2 -0
- package/lib/vite/traceViewer/recorder.html +17 -0
- package/lib/vite/traceViewer/sw.bundle.js +3 -3
- package/lib/vite/traceViewer/{uiMode.D3cNFP6u.css → uiMode.CAYqod-m.css} +1 -1
- package/lib/vite/traceViewer/uiMode.html +6 -4
- package/lib/vite/traceViewer/uiMode.mTXWniJb.js +5 -0
- package/lib/vite/traceViewer/workbench.D3JVcA9K.css +1 -0
- package/package.json +1 -1
- package/types/protocol.d.ts +79 -8
- package/types/types.d.ts +2037 -949
- package/lib/generated/recorderSource.js +0 -7
- package/lib/vite/traceViewer/assets/workbench-D0cirtfA.js +0 -72
- package/lib/vite/traceViewer/embedded.BkuvsLJp.js +0 -2
- package/lib/vite/traceViewer/index.C968kAiC.js +0 -2
- package/lib/vite/traceViewer/uiMode.BkFnr4V0.js +0 -10
- package/lib/vite/traceViewer/workbench.DjbIuxix.css +0 -1
- /package/lib/server/recorder/{recorderActions.js → recorderFrontend.js} +0 -0
|
@@ -7,6 +7,7 @@ exports.createConnectionAsync = createConnectionAsync;
|
|
|
7
7
|
exports.createSocket = createSocket;
|
|
8
8
|
exports.createTLSSocket = createTLSSocket;
|
|
9
9
|
exports.httpsHappyEyeballsAgent = exports.httpHappyEyeballsAgent = void 0;
|
|
10
|
+
exports.timingForSocket = timingForSocket;
|
|
10
11
|
var dns = _interopRequireWildcard(require("dns"));
|
|
11
12
|
var http = _interopRequireWildcard(require("http"));
|
|
12
13
|
var https = _interopRequireWildcard(require("https"));
|
|
@@ -14,6 +15,7 @@ var net = _interopRequireWildcard(require("net"));
|
|
|
14
15
|
var tls = _interopRequireWildcard(require("tls"));
|
|
15
16
|
var _manualPromise = require("./manualPromise");
|
|
16
17
|
var _debug = require("./debug");
|
|
18
|
+
var _time = require("./time");
|
|
17
19
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
18
20
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
19
21
|
/**
|
|
@@ -37,6 +39,8 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
|
|
|
37
39
|
|
|
38
40
|
// Same as in Chromium (https://source.chromium.org/chromium/chromium/src/+/5666ff4f5077a7e2f72902f3a95f5d553ea0d88d:net/socket/transport_connect_job.cc;l=102)
|
|
39
41
|
const connectionAttemptDelayMs = 300;
|
|
42
|
+
const kDNSLookupAt = Symbol('kDNSLookupAt');
|
|
43
|
+
const kTCPConnectionAt = Symbol('kTCPConnectionAt');
|
|
40
44
|
class HttpHappyEyeballsAgent extends http.Agent {
|
|
41
45
|
createConnection(options, oncreate) {
|
|
42
46
|
// There is no ambiguity in case of IP address.
|
|
@@ -101,6 +105,7 @@ async function createConnectionAsync(options, oncreate, useTLS) {
|
|
|
101
105
|
const lookup = options.__testHookLookup || lookupAddresses;
|
|
102
106
|
const hostname = clientRequestArgsToHostName(options);
|
|
103
107
|
const addresses = await lookup(hostname);
|
|
108
|
+
const dnsLookupAt = (0, _time.monotonicTime)();
|
|
104
109
|
const sockets = new Set();
|
|
105
110
|
let firstError;
|
|
106
111
|
let errorCount = 0;
|
|
@@ -125,10 +130,12 @@ async function createConnectionAsync(options, oncreate, useTLS) {
|
|
|
125
130
|
port: options.port,
|
|
126
131
|
host: address
|
|
127
132
|
});
|
|
133
|
+
socket[kDNSLookupAt] = dnsLookupAt;
|
|
128
134
|
|
|
129
135
|
// Each socket may fire only one of 'connect', 'timeout' or 'error' events.
|
|
130
136
|
// None of these events are fired after socket.destroy() is called.
|
|
131
137
|
socket.on('connect', () => {
|
|
138
|
+
socket[kTCPConnectionAt] = (0, _time.monotonicTime)();
|
|
132
139
|
connected.resolve();
|
|
133
140
|
oncreate === null || oncreate === void 0 || oncreate(null, socket);
|
|
134
141
|
// TODO: Cache the result?
|
|
@@ -178,4 +185,10 @@ function clientRequestArgsToHostName(options) {
|
|
|
178
185
|
if (options.hostname) return options.hostname;
|
|
179
186
|
if (options.host) return options.host;
|
|
180
187
|
throw new Error('Either options.hostname or options.host must be provided');
|
|
188
|
+
}
|
|
189
|
+
function timingForSocket(socket) {
|
|
190
|
+
return {
|
|
191
|
+
dnsLookupAt: socket[kDNSLookupAt],
|
|
192
|
+
tcpConnectionAt: socket[kTCPConnectionAt]
|
|
193
|
+
};
|
|
181
194
|
}
|
|
@@ -37,9 +37,9 @@ function calculatePlatform() {
|
|
|
37
37
|
macVersion = 'mac10.15';
|
|
38
38
|
} else {
|
|
39
39
|
// ver[0] >= 20
|
|
40
|
-
const
|
|
40
|
+
const LAST_STABLE_MACOS_MAJOR_VERSION = 15;
|
|
41
41
|
// Best-effort support for MacOS beta versions.
|
|
42
|
-
macVersion = 'mac' + Math.min(ver[0] - 9,
|
|
42
|
+
macVersion = 'mac' + Math.min(ver[0] - 9, LAST_STABLE_MACOS_MAJOR_VERSION);
|
|
43
43
|
// BigSur is the first version that might run on Apple Silicon.
|
|
44
44
|
if (_os.default.cpus().some(cpu => cpu.model.includes('Apple'))) macVersion += '-arm64';
|
|
45
45
|
}
|
package/lib/utils/httpServer.js
CHANGED
|
@@ -37,15 +37,6 @@ function asLocators(lang, selector, isFrameLocator = false, maxOutputSize = 20,
|
|
|
37
37
|
}
|
|
38
38
|
function innerAsLocators(factory, parsed, isFrameLocator = false, maxOutputSize = 20) {
|
|
39
39
|
const parts = [...parsed.parts];
|
|
40
|
-
// frameLocator('iframe').first is actually "iframe >> nth=0 >> internal:control=enter-frame"
|
|
41
|
-
// To make it easier to parse, we turn it into "iframe >> internal:control=enter-frame >> nth=0"
|
|
42
|
-
for (let index = 0; index < parts.length - 1; index++) {
|
|
43
|
-
if (parts[index].name === 'nth' && parts[index + 1].name === 'internal:control' && parts[index + 1].body === 'enter-frame') {
|
|
44
|
-
// Swap nth and enter-frame.
|
|
45
|
-
const [nth] = parts.splice(index, 1);
|
|
46
|
-
parts.splice(index + 1, 0, nth);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
40
|
const tokens = [];
|
|
50
41
|
let nextBase = isFrameLocator ? 'frame-locator' : 'page';
|
|
51
42
|
for (let index = 0; index < parts.length; index++) {
|
|
@@ -183,13 +174,13 @@ function innerAsLocators(factory, parsed, isFrameLocator = false, maxOutputSize
|
|
|
183
174
|
continue;
|
|
184
175
|
}
|
|
185
176
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if (nextPart && nextPart.name === 'internal:control' && nextPart.body === 'enter-frame') {
|
|
189
|
-
locatorType = 'frame';
|
|
177
|
+
if (part.name === 'internal:control' && part.body === 'enter-frame') {
|
|
178
|
+
tokens.push([factory.generateLocator(base, 'frame', '')]);
|
|
190
179
|
nextBase = 'frame-locator';
|
|
191
|
-
|
|
180
|
+
continue;
|
|
192
181
|
}
|
|
182
|
+
let locatorType = 'default';
|
|
183
|
+
const nextPart = parts[index + 1];
|
|
193
184
|
const selectorPart = (0, _selectorParser.stringifySelector)({
|
|
194
185
|
parts: [part]
|
|
195
186
|
});
|
|
@@ -277,7 +268,7 @@ class JavaScriptLocatorFactory {
|
|
|
277
268
|
if (options.hasNotText !== undefined) return `locator(${this.quote(body)}, { hasNotText: ${this.toHasText(options.hasNotText)} })`;
|
|
278
269
|
return `locator(${this.quote(body)})`;
|
|
279
270
|
case 'frame':
|
|
280
|
-
return `
|
|
271
|
+
return `contentFrame()`;
|
|
281
272
|
case 'nth':
|
|
282
273
|
return `nth(${body})`;
|
|
283
274
|
case 'first':
|
|
@@ -360,7 +351,7 @@ class PythonLocatorFactory {
|
|
|
360
351
|
if (options.hasNotText !== undefined) return `locator(${this.quote(body)}, has_not_text=${this.toHasText(options.hasNotText)})`;
|
|
361
352
|
return `locator(${this.quote(body)})`;
|
|
362
353
|
case 'frame':
|
|
363
|
-
return `
|
|
354
|
+
return `content_frame`;
|
|
364
355
|
case 'nth':
|
|
365
356
|
return `nth(${body})`;
|
|
366
357
|
case 'first':
|
|
@@ -460,7 +451,7 @@ class JavaLocatorFactory {
|
|
|
460
451
|
if (options.hasNotText !== undefined) return `locator(${this.quote(body)}, new ${clazz}.LocatorOptions().setHasNotText(${this.toHasText(options.hasNotText)}))`;
|
|
461
452
|
return `locator(${this.quote(body)})`;
|
|
462
453
|
case 'frame':
|
|
463
|
-
return `
|
|
454
|
+
return `contentFrame()`;
|
|
464
455
|
case 'nth':
|
|
465
456
|
return `nth(${body})`;
|
|
466
457
|
case 'first':
|
|
@@ -544,7 +535,7 @@ class CSharpLocatorFactory {
|
|
|
544
535
|
if (options.hasNotText !== undefined) return `Locator(${this.quote(body)}, new() { ${this.toHasNotText(options.hasNotText)} })`;
|
|
545
536
|
return `Locator(${this.quote(body)})`;
|
|
546
537
|
case 'frame':
|
|
547
|
-
return `
|
|
538
|
+
return `ContentFrame`;
|
|
548
539
|
case 'nth':
|
|
549
540
|
return `Nth(${body})`;
|
|
550
541
|
case 'first':
|
|
@@ -63,7 +63,7 @@ function parseLocator(locator, testIdAttributeName) {
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
// Equalize languages.
|
|
66
|
-
template = template.toLowerCase().replace(/get_by_alt_text/g, 'getbyalttext').replace(/get_by_test_id/g, 'getbytestid').replace(/get_by_([\w]+)/g, 'getby$1').replace(/has_not_text/g, 'hasnottext').replace(/has_text/g, 'hastext').replace(/has_not/g, 'hasnot').replace(/frame_locator/g, 'framelocator').replace(/[{}\s]/g, '').replace(/new\(\)/g, '').replace(/new[\w]+\.[\w]+options\(\)/g, '').replace(/\.set/g, ',set').replace(/\.or_\(/g, 'or(') // Python has "or_" instead of "or".
|
|
66
|
+
template = template.toLowerCase().replace(/get_by_alt_text/g, 'getbyalttext').replace(/get_by_test_id/g, 'getbytestid').replace(/get_by_([\w]+)/g, 'getby$1').replace(/has_not_text/g, 'hasnottext').replace(/has_text/g, 'hastext').replace(/has_not/g, 'hasnot').replace(/frame_locator/g, 'framelocator').replace(/content_frame/g, 'contentframe').replace(/[{}\s]/g, '').replace(/new\(\)/g, '').replace(/new[\w]+\.[\w]+options\(\)/g, '').replace(/\.set/g, ',set').replace(/\.or_\(/g, 'or(') // Python has "or_" instead of "or".
|
|
67
67
|
.replace(/\.and_\(/g, 'and(') // Python has "and_" instead of "and".
|
|
68
68
|
.replace(/:/g, '=').replace(/,re\.ignorecase/g, 'i').replace(/,pattern.case_insensitive/g, 'i').replace(/,regexoptions.ignorecase/g, 'i').replace(/re.compile\(([^)]+)\)/g, '$1') // Python has regex strings as r"foo"
|
|
69
69
|
.replace(/pattern.compile\(([^)]+)\)/g, 'r$1').replace(/newregex\(([^)]+)\)/g, 'r$1').replace(/string=/g, '=').replace(/regex=/g, '=').replace(/,,/g, ',');
|
|
@@ -123,7 +123,7 @@ function transform(template, params, testIdAttributeName) {
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
// Transform to selector engines.
|
|
126
|
-
template = template.replace(/\,set([\w]+)\(([^)]+)\)/g, (_, group1, group2) => ',' + group1.toLowerCase() + '=' + group2.toLowerCase()).replace(/framelocator\(([^)]+)\)/g, '$1.internal:control=enter-frame').replace(/locator\(([^)]+),hastext=([^),]+)\)/g, 'locator($1).internal:has-text=$2').replace(/locator\(([^)]+),hasnottext=([^),]+)\)/g, 'locator($1).internal:has-not-text=$2').replace(/locator\(([^)]+),hastext=([^),]+)\)/g, 'locator($1).internal:has-text=$2').replace(/locator\(([^)]+)\)/g, '$1').replace(/getbyrole\(([^)]+)\)/g, 'internal:role=$1').replace(/getbytext\(([^)]+)\)/g, 'internal:text=$1').replace(/getbylabel\(([^)]+)\)/g, 'internal:label=$1').replace(/getbytestid\(([^)]+)\)/g, `internal:testid=[${testIdAttributeName}=$1]`).replace(/getby(placeholder|alt|title)(?:text)?\(([^)]+)\)/g, 'internal:attr=[$1=$2]').replace(/first(\(\))?/g, 'nth=0').replace(/last(\(\))?/g, 'nth=-1').replace(/nth\(([^)]+)\)/g, 'nth=$1').replace(/filter\(,?hastext=([^)]+)\)/g, 'internal:has-text=$1').replace(/filter\(,?hasnottext=([^)]+)\)/g, 'internal:has-not-text=$1').replace(/filter\(,?has2=([^)]+)\)/g, 'internal:has=$1').replace(/filter\(,?hasnot2=([^)]+)\)/g, 'internal:has-not=$1').replace(/,exact=false/g, '').replace(/,exact=true/g, 's').replace(/\,/g, '][');
|
|
126
|
+
template = template.replace(/\,set([\w]+)\(([^)]+)\)/g, (_, group1, group2) => ',' + group1.toLowerCase() + '=' + group2.toLowerCase()).replace(/framelocator\(([^)]+)\)/g, '$1.internal:control=enter-frame').replace(/contentframe(\(\))?/g, 'internal:control=enter-frame').replace(/locator\(([^)]+),hastext=([^),]+)\)/g, 'locator($1).internal:has-text=$2').replace(/locator\(([^)]+),hasnottext=([^),]+)\)/g, 'locator($1).internal:has-not-text=$2').replace(/locator\(([^)]+),hastext=([^),]+)\)/g, 'locator($1).internal:has-text=$2').replace(/locator\(([^)]+)\)/g, '$1').replace(/getbyrole\(([^)]+)\)/g, 'internal:role=$1').replace(/getbytext\(([^)]+)\)/g, 'internal:text=$1').replace(/getbylabel\(([^)]+)\)/g, 'internal:label=$1').replace(/getbytestid\(([^)]+)\)/g, `internal:testid=[${testIdAttributeName}=$1]`).replace(/getby(placeholder|alt|title)(?:text)?\(([^)]+)\)/g, 'internal:attr=[$1=$2]').replace(/first(\(\))?/g, 'nth=0').replace(/last(\(\))?/g, 'nth=-1').replace(/nth\(([^)]+)\)/g, 'nth=$1').replace(/filter\(,?hastext=([^)]+)\)/g, 'internal:has-text=$1').replace(/filter\(,?hasnottext=([^)]+)\)/g, 'internal:has-not-text=$1').replace(/filter\(,?has2=([^)]+)\)/g, 'internal:has=$1').replace(/filter\(,?hasnot2=([^)]+)\)/g, 'internal:has-not=$1').replace(/,exact=false/g, '').replace(/,exact=true/g, 's').replace(/\,/g, '][');
|
|
127
127
|
const parts = template.split('.');
|
|
128
128
|
// Turn "internal:control=enter-frame >> nth=0" into "nth=0 >> internal:control=enter-frame"
|
|
129
129
|
// because these are swapped in locators vs selectors.
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.buildFullSelector = buildFullSelector;
|
|
7
|
+
exports.toKeyboardModifiers = toKeyboardModifiers;
|
|
8
|
+
exports.traceParamsForAction = traceParamsForAction;
|
|
9
|
+
/**
|
|
10
|
+
* Copyright (c) Microsoft Corporation.
|
|
11
|
+
*
|
|
12
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
13
|
+
* you may not use this file except in compliance with the License.
|
|
14
|
+
* You may obtain a copy of the License at
|
|
15
|
+
*
|
|
16
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
17
|
+
*
|
|
18
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
19
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
20
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
21
|
+
* See the License for the specific language governing permissions and
|
|
22
|
+
* limitations under the License.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
function buildFullSelector(framePath, selector) {
|
|
26
|
+
return [...framePath, selector].join(' >> internal:control=enter-frame >> ');
|
|
27
|
+
}
|
|
28
|
+
function traceParamsForAction(actionInContext) {
|
|
29
|
+
const {
|
|
30
|
+
action
|
|
31
|
+
} = actionInContext;
|
|
32
|
+
switch (action.name) {
|
|
33
|
+
case 'navigate':
|
|
34
|
+
{
|
|
35
|
+
const params = {
|
|
36
|
+
url: action.url
|
|
37
|
+
};
|
|
38
|
+
return {
|
|
39
|
+
method: 'goto',
|
|
40
|
+
params
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
case 'openPage':
|
|
44
|
+
case 'closePage':
|
|
45
|
+
throw new Error('Not reached');
|
|
46
|
+
}
|
|
47
|
+
const selector = buildFullSelector(actionInContext.frame.framePath, action.selector);
|
|
48
|
+
switch (action.name) {
|
|
49
|
+
case 'click':
|
|
50
|
+
{
|
|
51
|
+
const params = {
|
|
52
|
+
selector,
|
|
53
|
+
strict: true,
|
|
54
|
+
modifiers: toKeyboardModifiers(action.modifiers),
|
|
55
|
+
button: action.button,
|
|
56
|
+
clickCount: action.clickCount,
|
|
57
|
+
position: action.position
|
|
58
|
+
};
|
|
59
|
+
return {
|
|
60
|
+
method: 'click',
|
|
61
|
+
params
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
case 'press':
|
|
65
|
+
{
|
|
66
|
+
const params = {
|
|
67
|
+
selector,
|
|
68
|
+
strict: true,
|
|
69
|
+
key: [...toKeyboardModifiers(action.modifiers), action.key].join('+')
|
|
70
|
+
};
|
|
71
|
+
return {
|
|
72
|
+
method: 'press',
|
|
73
|
+
params
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
case 'fill':
|
|
77
|
+
{
|
|
78
|
+
const params = {
|
|
79
|
+
selector,
|
|
80
|
+
strict: true,
|
|
81
|
+
value: action.text
|
|
82
|
+
};
|
|
83
|
+
return {
|
|
84
|
+
method: 'fill',
|
|
85
|
+
params
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
case 'setInputFiles':
|
|
89
|
+
{
|
|
90
|
+
const params = {
|
|
91
|
+
selector,
|
|
92
|
+
strict: true,
|
|
93
|
+
localPaths: action.files
|
|
94
|
+
};
|
|
95
|
+
return {
|
|
96
|
+
method: 'setInputFiles',
|
|
97
|
+
params
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
case 'check':
|
|
101
|
+
{
|
|
102
|
+
const params = {
|
|
103
|
+
selector,
|
|
104
|
+
strict: true
|
|
105
|
+
};
|
|
106
|
+
return {
|
|
107
|
+
method: 'check',
|
|
108
|
+
params
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
case 'uncheck':
|
|
112
|
+
{
|
|
113
|
+
const params = {
|
|
114
|
+
selector,
|
|
115
|
+
strict: true
|
|
116
|
+
};
|
|
117
|
+
return {
|
|
118
|
+
method: 'uncheck',
|
|
119
|
+
params
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
case 'select':
|
|
123
|
+
{
|
|
124
|
+
const params = {
|
|
125
|
+
selector,
|
|
126
|
+
strict: true,
|
|
127
|
+
options: action.options.map(option => ({
|
|
128
|
+
value: option
|
|
129
|
+
}))
|
|
130
|
+
};
|
|
131
|
+
return {
|
|
132
|
+
method: 'selectOption',
|
|
133
|
+
params
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
case 'assertChecked':
|
|
137
|
+
{
|
|
138
|
+
const params = {
|
|
139
|
+
selector: action.selector,
|
|
140
|
+
expression: 'to.be.checked',
|
|
141
|
+
isNot: !action.checked
|
|
142
|
+
};
|
|
143
|
+
return {
|
|
144
|
+
method: 'expect',
|
|
145
|
+
params
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
case 'assertText':
|
|
149
|
+
{
|
|
150
|
+
const params = {
|
|
151
|
+
selector,
|
|
152
|
+
expression: 'to.have.text',
|
|
153
|
+
expectedText: [],
|
|
154
|
+
isNot: false
|
|
155
|
+
};
|
|
156
|
+
return {
|
|
157
|
+
method: 'expect',
|
|
158
|
+
params
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
case 'assertValue':
|
|
162
|
+
{
|
|
163
|
+
const params = {
|
|
164
|
+
selector,
|
|
165
|
+
expression: 'to.have.value',
|
|
166
|
+
expectedValue: undefined,
|
|
167
|
+
isNot: false
|
|
168
|
+
};
|
|
169
|
+
return {
|
|
170
|
+
method: 'expect',
|
|
171
|
+
params
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
case 'assertVisible':
|
|
175
|
+
{
|
|
176
|
+
const params = {
|
|
177
|
+
selector,
|
|
178
|
+
expression: 'to.be.visible',
|
|
179
|
+
isNot: false
|
|
180
|
+
};
|
|
181
|
+
return {
|
|
182
|
+
method: 'expect',
|
|
183
|
+
params
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
function toKeyboardModifiers(modifiers) {
|
|
189
|
+
const result = [];
|
|
190
|
+
if (modifiers & 1) result.push('Alt');
|
|
191
|
+
if (modifiers & 2) result.push('ControlOrMeta');
|
|
192
|
+
if (modifiers & 4) result.push('ControlOrMeta');
|
|
193
|
+
if (modifiers & 8) result.push('Shift');
|
|
194
|
+
return result;
|
|
195
|
+
}
|