patchright-core 1.51.3 → 1.52.1
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/browsers.json +15 -13
- package/lib/androidServerImpl.js +42 -48
- package/lib/browserServerImpl.js +54 -67
- package/lib/cli/driver.js +71 -69
- package/lib/cli/program.js +312 -328
- package/lib/cli/programWithTestStub.js +51 -45
- package/lib/client/accessibility.js +31 -32
- package/lib/client/android.js +141 -228
- package/lib/client/api.js +135 -283
- package/lib/client/artifact.js +39 -36
- package/lib/client/browser.js +57 -61
- package/lib/client/browserContext.js +297 -326
- package/lib/client/browserType.js +92 -106
- package/lib/client/cdpSession.js +29 -31
- package/lib/client/channelOwner.js +82 -95
- package/lib/client/clientHelper.js +46 -38
- package/lib/client/clientInstrumentation.js +40 -37
- package/lib/client/clientStackTrace.js +41 -37
- package/lib/client/clock.js +36 -36
- package/lib/client/connection.js +190 -212
- package/lib/client/consoleMessage.js +31 -28
- package/lib/client/coverage.js +25 -22
- package/lib/client/dialog.js +30 -31
- package/lib/client/download.js +25 -25
- package/lib/client/electron.js +73 -75
- package/lib/client/elementHandle.js +111 -147
- package/lib/client/errors.js +53 -53
- package/lib/client/eventEmitter.js +124 -121
- package/lib/client/events.js +72 -68
- package/lib/client/fetch.js +135 -158
- package/lib/client/fileChooser.js +25 -24
- package/lib/client/fileUtils.js +31 -28
- package/lib/client/frame.js +187 -306
- package/lib/client/harRouter.js +42 -52
- package/lib/client/input.js +40 -69
- package/lib/client/jsHandle.js +56 -71
- package/lib/client/jsonPipe.js +27 -23
- package/lib/client/localUtils.js +29 -28
- package/lib/client/locator.js +161 -245
- package/lib/client/network.js +277 -295
- package/lib/client/page.js +270 -318
- package/lib/client/platform.js +46 -43
- package/lib/client/playwright.js +51 -66
- package/lib/client/selectors.js +48 -46
- package/lib/client/stream.js +29 -25
- package/lib/client/timeoutSettings.js +49 -39
- package/lib/client/tracing.js +48 -84
- package/lib/client/types.js +26 -22
- package/lib/client/video.js +35 -27
- package/lib/client/waiter.js +69 -88
- package/lib/client/webError.js +25 -23
- package/lib/client/webSocket.js +61 -56
- package/lib/client/worker.js +48 -58
- package/lib/client/writableStream.js +27 -23
- package/lib/generated/clockSource.js +26 -5
- package/lib/generated/consoleApiSource.js +26 -5
- package/lib/generated/injectedScriptSource.js +26 -5
- package/lib/generated/pollingRecorderSource.js +26 -5
- package/lib/generated/utilityScriptSource.js +26 -5
- package/lib/generated/webSocketMockSource.js +371 -4
- package/lib/inProcessFactory.js +53 -53
- package/lib/inprocess.js +2 -19
- package/lib/outofprocess.js +53 -46
- package/lib/protocol/debug.js +209 -25
- package/lib/protocol/serializers.js +153 -134
- package/lib/protocol/validator.js +2714 -2714
- package/lib/protocol/validatorPrimitives.js +114 -73
- package/lib/remote/playwrightConnection.js +140 -157
- package/lib/remote/playwrightServer.js +99 -84
- package/lib/server/accessibility.js +44 -37
- package/lib/server/android/android.js +216 -209
- package/lib/server/android/backendAdb.js +89 -82
- package/lib/server/artifact.js +78 -55
- package/lib/server/bidi/bidiBrowser.js +221 -155
- package/lib/server/bidi/bidiChromium.js +106 -79
- package/lib/server/bidi/bidiConnection.js +66 -83
- package/lib/server/bidi/bidiExecutionContext.js +128 -113
- package/lib/server/bidi/bidiFirefox.js +76 -69
- package/lib/server/bidi/bidiInput.js +86 -97
- package/lib/server/bidi/bidiNetworkManager.js +137 -154
- package/lib/server/bidi/bidiOverCdp.js +57 -58
- package/lib/server/bidi/bidiPage.js +247 -219
- package/lib/server/bidi/bidiPdf.js +52 -86
- package/lib/server/bidi/third_party/bidiCommands.d.js +22 -0
- package/lib/server/bidi/third_party/bidiDeserializer.js +55 -50
- package/lib/server/bidi/third_party/bidiKeyboard.js +236 -220
- package/lib/server/bidi/third_party/bidiProtocol.js +144 -131
- package/lib/server/bidi/third_party/bidiSerializer.js +67 -63
- package/lib/server/bidi/third_party/firefoxPrefs.js +141 -119
- package/lib/server/browser.js +76 -84
- package/lib/server/browserContext.js +321 -346
- package/lib/server/browserType.js +169 -182
- package/lib/server/callLog.js +47 -44
- package/lib/server/chromium/chromium.js +212 -190
- package/lib/server/chromium/chromiumSwitches.js +86 -64
- package/lib/server/chromium/crAccessibility.js +157 -131
- package/lib/server/chromium/crBrowser.js +253 -273
- package/lib/server/chromium/crConnection.js +91 -116
- package/lib/server/chromium/crCoverage.js +113 -127
- package/lib/server/chromium/crDevTools.js +59 -51
- package/lib/server/chromium/crDragDrop.js +62 -79
- package/lib/server/chromium/crExecutionContext.js +88 -83
- package/lib/server/chromium/crInput.js +97 -95
- package/lib/server/chromium/crNetworkManager.js +284 -404
- package/lib/server/chromium/crPage.js +522 -608
- package/lib/server/chromium/crPdf.js +54 -86
- package/lib/server/chromium/crProtocolHelper.js +92 -80
- package/lib/server/chromium/crServiceWorker.js +82 -67
- package/lib/server/chromium/defaultFontFamilies.js +152 -135
- package/lib/server/chromium/protocol.d.js +16 -0
- package/lib/server/chromium/videoRecorder.js +65 -99
- package/lib/server/clock.js +62 -50
- package/lib/server/codegen/csharp.js +185 -160
- package/lib/server/codegen/java.js +155 -128
- package/lib/server/codegen/javascript.js +163 -148
- package/lib/server/codegen/jsonl.js +32 -28
- package/lib/server/codegen/language.js +75 -52
- package/lib/server/codegen/languages.js +65 -27
- package/lib/server/codegen/python.js +140 -125
- package/lib/server/codegen/types.js +15 -4
- package/lib/server/console.js +28 -32
- package/lib/server/cookieStore.js +105 -86
- package/lib/server/debugController.js +97 -124
- package/lib/server/debugger.js +82 -78
- package/lib/server/deviceDescriptors.js +37 -24
- package/lib/server/deviceDescriptorsSource.json +50 -50
- package/lib/server/dialog.js +36 -35
- package/lib/server/dispatchers/androidDispatcher.js +196 -107
- package/lib/server/dispatchers/artifactDispatcher.js +62 -62
- package/lib/server/dispatchers/browserContextDispatcher.js +176 -205
- package/lib/server/dispatchers/browserDispatcher.js +78 -97
- package/lib/server/dispatchers/browserTypeDispatcher.js +35 -35
- package/lib/server/dispatchers/cdpSessionDispatcher.js +32 -36
- package/lib/server/dispatchers/debugControllerDispatcher.js +48 -66
- package/lib/server/dispatchers/dialogDispatcher.js +30 -27
- package/lib/server/dispatchers/dispatcher.js +169 -220
- package/lib/server/dispatchers/electronDispatcher.js +54 -57
- package/lib/server/dispatchers/elementHandlerDispatcher.js +77 -119
- package/lib/server/dispatchers/frameDispatcher.js +99 -163
- package/lib/server/dispatchers/jsHandleDispatcher.js +49 -66
- package/lib/server/dispatchers/jsonPipeDispatcher.js +35 -36
- package/lib/server/dispatchers/localUtilsDispatcher.js +95 -80
- package/lib/server/dispatchers/networkDispatchers.js +90 -107
- package/lib/server/dispatchers/pageDispatcher.js +128 -169
- package/lib/server/dispatchers/playwrightDispatcher.js +69 -76
- package/lib/server/dispatchers/selectorsDispatcher.js +28 -24
- package/lib/server/dispatchers/streamDispatcher.js +42 -45
- package/lib/server/dispatchers/tracingDispatcher.js +36 -41
- package/lib/server/dispatchers/webSocketRouteDispatcher.js +96 -131
- package/lib/server/dispatchers/writableStreamDispatcher.js +54 -38
- package/lib/server/dom.js +413 -443
- package/lib/server/download.js +45 -35
- package/lib/server/electron/electron.js +156 -176
- package/lib/server/electron/loader.js +8 -36
- package/lib/server/errors.js +47 -46
- package/lib/server/fetch.js +289 -323
- package/lib/server/fileChooser.js +25 -24
- package/lib/server/fileUploadUtils.js +65 -59
- package/lib/server/firefox/ffAccessibility.js +153 -131
- package/lib/server/firefox/ffBrowser.js +213 -277
- package/lib/server/firefox/ffConnection.js +63 -84
- package/lib/server/firefox/ffExecutionContext.js +91 -73
- package/lib/server/firefox/ffInput.js +67 -69
- package/lib/server/firefox/ffNetworkManager.js +131 -110
- package/lib/server/firefox/ffPage.js +236 -273
- package/lib/server/firefox/firefox.js +76 -67
- package/lib/server/firefox/protocol.d.js +16 -0
- package/lib/server/formData.js +107 -35
- package/lib/server/frameSelectors.js +221 -112
- package/lib/server/frames.js +731 -894
- package/lib/server/har/harRecorder.js +85 -77
- package/lib/server/har/harTracer.js +287 -222
- package/lib/server/harBackend.js +80 -80
- package/lib/server/helper.js +56 -59
- package/lib/server/index.js +59 -99
- package/lib/server/input.js +134 -163
- package/lib/server/instrumentation.js +49 -44
- package/lib/server/javascript.js +143 -134
- package/lib/server/launchApp.js +92 -73
- package/lib/server/localUtils.js +130 -122
- package/lib/server/macEditingCommands.js +141 -137
- package/lib/server/network.js +262 -296
- package/lib/server/page.js +326 -423
- package/lib/server/pageBinding.js +88 -0
- package/lib/server/pipeTransport.js +49 -45
- package/lib/server/playwright.js +60 -67
- package/lib/server/progress.js +56 -51
- package/lib/server/protocolError.js +34 -31
- package/lib/server/recorder/chat.js +70 -86
- package/lib/server/recorder/contextRecorder.js +134 -138
- package/lib/server/recorder/recorderApp.js +127 -136
- package/lib/server/recorder/recorderCollection.js +56 -44
- package/lib/server/recorder/recorderFrontend.js +15 -4
- package/lib/server/recorder/recorderRunner.js +79 -103
- package/lib/server/recorder/recorderUtils.js +56 -45
- package/lib/server/recorder/throttledFile.js +42 -30
- package/lib/server/recorder.js +177 -186
- package/lib/server/registry/browserFetcher.js +106 -101
- package/lib/server/registry/dependencies.js +245 -196
- package/lib/server/registry/index.js +904 -792
- package/lib/server/registry/nativeDeps.js +1073 -464
- package/lib/server/registry/oopDownloadBrowserMain.js +57 -75
- package/lib/server/screenshotter.js +166 -182
- package/lib/server/selectors.js +85 -46
- package/lib/server/socksClientCertificatesInterceptor.js +166 -185
- package/lib/server/socksInterceptor.js +62 -70
- package/lib/server/storageScript.js +94 -100
- package/lib/server/timeoutSettings.js +58 -43
- package/lib/server/trace/recorder/snapshotter.js +70 -89
- package/lib/server/trace/recorder/snapshotterInjected.js +238 -217
- package/lib/server/trace/recorder/tracing.js +321 -333
- package/lib/server/trace/test/inMemorySnapshotter.js +46 -52
- package/lib/server/trace/viewer/traceViewer.js +168 -146
- package/lib/server/transport.js +124 -133
- package/lib/server/types.js +26 -22
- package/lib/server/usKeyboardLayout.js +135 -545
- package/lib/server/utils/ascii.js +39 -26
- package/lib/server/utils/comparators.js +105 -103
- package/lib/server/utils/crypto.js +157 -112
- package/lib/server/utils/debug.js +37 -28
- package/lib/server/utils/debugLogger.js +69 -48
- package/lib/server/utils/env.js +52 -37
- package/lib/server/utils/eventsHelper.js +29 -28
- package/lib/server/utils/expectUtils.js +31 -26
- package/lib/server/utils/fileUtils.js +123 -136
- package/lib/server/utils/happyEyeballs.js +138 -123
- package/lib/server/utils/hostPlatform.js +84 -120
- package/lib/server/utils/httpServer.js +106 -121
- package/lib/server/utils/image_tools/colorUtils.js +42 -51
- package/lib/server/utils/image_tools/compare.js +44 -43
- package/lib/server/utils/image_tools/imageChannel.js +38 -30
- package/lib/server/utils/image_tools/stats.js +40 -40
- package/lib/server/utils/linuxUtils.js +50 -37
- package/lib/server/utils/network.js +143 -86
- package/lib/server/utils/nodePlatform.js +87 -79
- package/lib/server/utils/pipeTransport.js +44 -42
- package/lib/server/utils/processLauncher.js +111 -121
- package/lib/server/utils/profiler.js +52 -39
- package/lib/server/utils/socksProxy.js +280 -339
- package/lib/server/utils/spawnAsync.js +37 -41
- package/lib/server/utils/task.js +31 -38
- package/lib/server/utils/userAgent.js +73 -66
- package/lib/server/utils/wsServer.js +73 -69
- package/lib/server/utils/zipFile.js +36 -37
- package/lib/server/utils/zones.js +37 -34
- package/lib/server/webkit/protocol.d.js +16 -0
- package/lib/server/webkit/webkit.js +76 -63
- package/lib/server/webkit/wkAccessibility.js +161 -118
- package/lib/server/webkit/wkBrowser.js +159 -176
- package/lib/server/webkit/wkConnection.js +59 -83
- package/lib/server/webkit/wkExecutionContext.js +84 -70
- package/lib/server/webkit/wkInput.js +82 -80
- package/lib/server/webkit/wkInterceptableRequest.js +102 -95
- package/lib/server/webkit/wkPage.js +525 -619
- package/lib/server/webkit/wkProvisionalPage.js +45 -56
- package/lib/server/webkit/wkWorkers.js +77 -77
- package/lib/utils/isomorphic/ariaSnapshot.js +144 -152
- package/lib/utils/isomorphic/assert.js +28 -22
- package/lib/utils/isomorphic/builtins.js +86 -0
- package/lib/utils/isomorphic/colors.js +66 -59
- package/lib/utils/isomorphic/cssParser.js +121 -125
- package/lib/utils/isomorphic/cssTokenizer.js +436 -364
- package/lib/utils/isomorphic/headers.js +38 -37
- package/lib/utils/isomorphic/locatorGenerators.js +340 -357
- package/lib/utils/isomorphic/locatorParser.js +96 -105
- package/lib/utils/isomorphic/locatorUtils.js +63 -44
- package/lib/utils/isomorphic/manualPromise.js +47 -39
- package/lib/utils/isomorphic/mimeType.js +448 -25
- package/lib/utils/isomorphic/multimap.js +35 -27
- package/lib/utils/isomorphic/rtti.js +35 -33
- package/lib/utils/isomorphic/selectorParser.js +183 -193
- package/lib/utils/isomorphic/semaphore.js +27 -24
- package/lib/utils/isomorphic/stackTrace.js +87 -98
- package/lib/utils/isomorphic/stringUtils.js +113 -106
- package/lib/utils/isomorphic/time.js +41 -22
- package/lib/utils/isomorphic/timeoutRunner.js +55 -54
- package/lib/utils/isomorphic/traceUtils.js +38 -41
- package/lib/utils/isomorphic/types.js +15 -4
- package/lib/utils/isomorphic/urlMatch.js +112 -67
- package/lib/utils/isomorphic/utilityScriptSerializers.js +248 -0
- package/lib/utils.js +97 -443
- package/lib/utilsBundle.js +101 -52
- package/lib/vite/htmlReport/index.html +21 -15
- package/lib/vite/recorder/assets/{codeMirrorModule-B9YMkrwa.js → codeMirrorModule-CXVeovup.js} +1 -1
- package/lib/vite/recorder/assets/index-BsWQsSGl.js +184 -0
- package/lib/vite/recorder/index.html +1 -1
- package/lib/vite/traceViewer/assets/{codeMirrorModule-1DiydmYA.js → codeMirrorModule-_GLjJL-7.js} +1 -1
- package/lib/vite/traceViewer/assets/defaultSettingsView-DtCQiGHe.js +265 -0
- package/lib/vite/traceViewer/{defaultSettingsView.5fN5lw10.css → defaultSettingsView.QdHITyLI.css} +1 -1
- package/lib/vite/traceViewer/index.cFZzK9RN.js +2 -0
- package/lib/vite/traceViewer/index.html +3 -3
- package/lib/vite/traceViewer/sw.bundle.js +3 -3
- package/lib/vite/traceViewer/uiMode.XVPIqBeS.js +5 -0
- package/lib/vite/traceViewer/uiMode.html +3 -3
- package/lib/zipBundle.js +32 -23
- package/package.json +1 -1
- package/types/protocol.d.ts +436 -17
- package/types/types.d.ts +35 -16
- package/lib/server/isomorphic/utilityScriptSerializers.js +0 -229
- package/lib/vite/recorder/assets/index-ELPgmkwA.js +0 -184
- package/lib/vite/traceViewer/assets/defaultSettingsView-l0TyP_G8.js +0 -259
- package/lib/vite/traceViewer/index.BqUZLSro.js +0 -2
- package/lib/vite/traceViewer/uiMode.C1d2m5sF.js +0 -5
|
@@ -1,249 +1,211 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.
|
|
4
|
-
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var locatorGenerators_exports = {};
|
|
20
|
+
__export(locatorGenerators_exports, {
|
|
21
|
+
CSharpLocatorFactory: () => CSharpLocatorFactory,
|
|
22
|
+
JavaLocatorFactory: () => JavaLocatorFactory,
|
|
23
|
+
JavaScriptLocatorFactory: () => JavaScriptLocatorFactory,
|
|
24
|
+
JsonlLocatorFactory: () => JsonlLocatorFactory,
|
|
25
|
+
PythonLocatorFactory: () => PythonLocatorFactory,
|
|
26
|
+
asLocator: () => asLocator,
|
|
27
|
+
asLocators: () => asLocators
|
|
5
28
|
});
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
var _selectorParser = require("./selectorParser");
|
|
10
|
-
var _stringUtils = require("./stringUtils");
|
|
11
|
-
/**
|
|
12
|
-
* Copyright (c) Microsoft Corporation.
|
|
13
|
-
*
|
|
14
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
15
|
-
* you may not use this file except in compliance with the License.
|
|
16
|
-
* You may obtain a copy of the License at
|
|
17
|
-
*
|
|
18
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
19
|
-
*
|
|
20
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
21
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
22
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
23
|
-
* See the License for the specific language governing permissions and
|
|
24
|
-
* limitations under the License.
|
|
25
|
-
*/
|
|
26
|
-
|
|
29
|
+
module.exports = __toCommonJS(locatorGenerators_exports);
|
|
30
|
+
var import_selectorParser = require("./selectorParser");
|
|
31
|
+
var import_stringUtils = require("./stringUtils");
|
|
27
32
|
function asLocator(lang, selector, isFrameLocator = false) {
|
|
28
33
|
return asLocators(lang, selector, isFrameLocator, 1)[0];
|
|
29
34
|
}
|
|
30
35
|
function asLocators(lang, selector, isFrameLocator = false, maxOutputSize = 20, preferredQuote) {
|
|
31
36
|
try {
|
|
32
|
-
return innerAsLocators(new generators[lang](preferredQuote), (0,
|
|
37
|
+
return innerAsLocators(new generators[lang](preferredQuote), (0, import_selectorParser.parseSelector)(selector), isFrameLocator, maxOutputSize);
|
|
33
38
|
} catch (e) {
|
|
34
|
-
// Tolerate invalid input.
|
|
35
39
|
return [selector];
|
|
36
40
|
}
|
|
37
41
|
}
|
|
38
42
|
function innerAsLocators(factory, parsed, isFrameLocator = false, maxOutputSize = 20) {
|
|
39
43
|
const parts = [...parsed.parts];
|
|
40
44
|
const tokens = [];
|
|
41
|
-
let nextBase = isFrameLocator ?
|
|
45
|
+
let nextBase = isFrameLocator ? "frame-locator" : "page";
|
|
42
46
|
for (let index = 0; index < parts.length; index++) {
|
|
43
47
|
const part = parts[index];
|
|
44
48
|
const base = nextBase;
|
|
45
|
-
nextBase =
|
|
46
|
-
if (part.name ===
|
|
47
|
-
if (part.body ===
|
|
49
|
+
nextBase = "locator";
|
|
50
|
+
if (part.name === "nth") {
|
|
51
|
+
if (part.body === "0")
|
|
52
|
+
tokens.push([factory.generateLocator(base, "first", ""), factory.generateLocator(base, "nth", "0")]);
|
|
53
|
+
else if (part.body === "-1")
|
|
54
|
+
tokens.push([factory.generateLocator(base, "last", ""), factory.generateLocator(base, "nth", "-1")]);
|
|
55
|
+
else
|
|
56
|
+
tokens.push([factory.generateLocator(base, "nth", part.body)]);
|
|
48
57
|
continue;
|
|
49
58
|
}
|
|
50
|
-
if (part.name ===
|
|
51
|
-
tokens.push([factory.generateLocator(base,
|
|
59
|
+
if (part.name === "visible") {
|
|
60
|
+
tokens.push([factory.generateLocator(base, "visible", part.body), factory.generateLocator(base, "default", `visible=${part.body}`)]);
|
|
52
61
|
continue;
|
|
53
62
|
}
|
|
54
|
-
if (part.name ===
|
|
55
|
-
const {
|
|
56
|
-
|
|
57
|
-
text
|
|
58
|
-
} = detectExact(part.body);
|
|
59
|
-
tokens.push([factory.generateLocator(base, 'text', text, {
|
|
60
|
-
exact
|
|
61
|
-
})]);
|
|
63
|
+
if (part.name === "internal:text") {
|
|
64
|
+
const { exact, text } = detectExact(part.body);
|
|
65
|
+
tokens.push([factory.generateLocator(base, "text", text, { exact })]);
|
|
62
66
|
continue;
|
|
63
67
|
}
|
|
64
|
-
if (part.name ===
|
|
65
|
-
const {
|
|
66
|
-
exact,
|
|
67
|
-
text
|
|
68
|
-
} = detectExact(part.body);
|
|
69
|
-
// There is no locator equivalent for strict has-text, leave it as is.
|
|
68
|
+
if (part.name === "internal:has-text") {
|
|
69
|
+
const { exact, text } = detectExact(part.body);
|
|
70
70
|
if (!exact) {
|
|
71
|
-
tokens.push([factory.generateLocator(base,
|
|
72
|
-
exact
|
|
73
|
-
})]);
|
|
71
|
+
tokens.push([factory.generateLocator(base, "has-text", text, { exact })]);
|
|
74
72
|
continue;
|
|
75
73
|
}
|
|
76
74
|
}
|
|
77
|
-
if (part.name ===
|
|
78
|
-
const {
|
|
79
|
-
exact,
|
|
80
|
-
text
|
|
81
|
-
} = detectExact(part.body);
|
|
82
|
-
// There is no locator equivalent for strict has-not-text, leave it as is.
|
|
75
|
+
if (part.name === "internal:has-not-text") {
|
|
76
|
+
const { exact, text } = detectExact(part.body);
|
|
83
77
|
if (!exact) {
|
|
84
|
-
tokens.push([factory.generateLocator(base,
|
|
85
|
-
exact
|
|
86
|
-
})]);
|
|
78
|
+
tokens.push([factory.generateLocator(base, "has-not-text", text, { exact })]);
|
|
87
79
|
continue;
|
|
88
80
|
}
|
|
89
81
|
}
|
|
90
|
-
if (part.name ===
|
|
82
|
+
if (part.name === "internal:has") {
|
|
91
83
|
const inners = innerAsLocators(factory, part.body.parsed, false, maxOutputSize);
|
|
92
|
-
tokens.push(inners.map(inner => factory.generateLocator(base,
|
|
84
|
+
tokens.push(inners.map((inner) => factory.generateLocator(base, "has", inner)));
|
|
93
85
|
continue;
|
|
94
86
|
}
|
|
95
|
-
if (part.name ===
|
|
87
|
+
if (part.name === "internal:has-not") {
|
|
96
88
|
const inners = innerAsLocators(factory, part.body.parsed, false, maxOutputSize);
|
|
97
|
-
tokens.push(inners.map(inner => factory.generateLocator(base,
|
|
89
|
+
tokens.push(inners.map((inner) => factory.generateLocator(base, "hasNot", inner)));
|
|
98
90
|
continue;
|
|
99
91
|
}
|
|
100
|
-
if (part.name ===
|
|
92
|
+
if (part.name === "internal:and") {
|
|
101
93
|
const inners = innerAsLocators(factory, part.body.parsed, false, maxOutputSize);
|
|
102
|
-
tokens.push(inners.map(inner => factory.generateLocator(base,
|
|
94
|
+
tokens.push(inners.map((inner) => factory.generateLocator(base, "and", inner)));
|
|
103
95
|
continue;
|
|
104
96
|
}
|
|
105
|
-
if (part.name ===
|
|
97
|
+
if (part.name === "internal:or") {
|
|
106
98
|
const inners = innerAsLocators(factory, part.body.parsed, false, maxOutputSize);
|
|
107
|
-
tokens.push(inners.map(inner => factory.generateLocator(base,
|
|
99
|
+
tokens.push(inners.map((inner) => factory.generateLocator(base, "or", inner)));
|
|
108
100
|
continue;
|
|
109
101
|
}
|
|
110
|
-
if (part.name ===
|
|
102
|
+
if (part.name === "internal:chain") {
|
|
111
103
|
const inners = innerAsLocators(factory, part.body.parsed, false, maxOutputSize);
|
|
112
|
-
tokens.push(inners.map(inner => factory.generateLocator(base,
|
|
104
|
+
tokens.push(inners.map((inner) => factory.generateLocator(base, "chain", inner)));
|
|
113
105
|
continue;
|
|
114
106
|
}
|
|
115
|
-
if (part.name ===
|
|
116
|
-
const {
|
|
117
|
-
|
|
118
|
-
text
|
|
119
|
-
} = detectExact(part.body);
|
|
120
|
-
tokens.push([factory.generateLocator(base, 'label', text, {
|
|
121
|
-
exact
|
|
122
|
-
})]);
|
|
107
|
+
if (part.name === "internal:label") {
|
|
108
|
+
const { exact, text } = detectExact(part.body);
|
|
109
|
+
tokens.push([factory.generateLocator(base, "label", text, { exact })]);
|
|
123
110
|
continue;
|
|
124
111
|
}
|
|
125
|
-
if (part.name ===
|
|
126
|
-
const attrSelector = (0,
|
|
127
|
-
const options = {
|
|
128
|
-
attrs: []
|
|
129
|
-
};
|
|
112
|
+
if (part.name === "internal:role") {
|
|
113
|
+
const attrSelector = (0, import_selectorParser.parseAttributeSelector)(part.body, true);
|
|
114
|
+
const options = { attrs: [] };
|
|
130
115
|
for (const attr of attrSelector.attributes) {
|
|
131
|
-
if (attr.name ===
|
|
116
|
+
if (attr.name === "name") {
|
|
132
117
|
options.exact = attr.caseSensitive;
|
|
133
118
|
options.name = attr.value;
|
|
134
119
|
} else {
|
|
135
|
-
if (attr.name ===
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
value: attr.value
|
|
139
|
-
});
|
|
120
|
+
if (attr.name === "level" && typeof attr.value === "string")
|
|
121
|
+
attr.value = +attr.value;
|
|
122
|
+
options.attrs.push({ name: attr.name === "include-hidden" ? "includeHidden" : attr.name, value: attr.value });
|
|
140
123
|
}
|
|
141
124
|
}
|
|
142
|
-
tokens.push([factory.generateLocator(base,
|
|
125
|
+
tokens.push([factory.generateLocator(base, "role", attrSelector.name, options)]);
|
|
143
126
|
continue;
|
|
144
127
|
}
|
|
145
|
-
if (part.name ===
|
|
146
|
-
const attrSelector = (0,
|
|
147
|
-
const {
|
|
148
|
-
|
|
149
|
-
} = attrSelector.attributes[0];
|
|
150
|
-
tokens.push([factory.generateLocator(base, 'test-id', value)]);
|
|
128
|
+
if (part.name === "internal:testid") {
|
|
129
|
+
const attrSelector = (0, import_selectorParser.parseAttributeSelector)(part.body, true);
|
|
130
|
+
const { value } = attrSelector.attributes[0];
|
|
131
|
+
tokens.push([factory.generateLocator(base, "test-id", value)]);
|
|
151
132
|
continue;
|
|
152
133
|
}
|
|
153
|
-
if (part.name ===
|
|
154
|
-
const attrSelector = (0,
|
|
155
|
-
const {
|
|
156
|
-
name,
|
|
157
|
-
value,
|
|
158
|
-
caseSensitive
|
|
159
|
-
} = attrSelector.attributes[0];
|
|
134
|
+
if (part.name === "internal:attr") {
|
|
135
|
+
const attrSelector = (0, import_selectorParser.parseAttributeSelector)(part.body, true);
|
|
136
|
+
const { name, value, caseSensitive } = attrSelector.attributes[0];
|
|
160
137
|
const text = value;
|
|
161
138
|
const exact = !!caseSensitive;
|
|
162
|
-
if (name ===
|
|
163
|
-
tokens.push([factory.generateLocator(base,
|
|
164
|
-
exact
|
|
165
|
-
})]);
|
|
139
|
+
if (name === "placeholder") {
|
|
140
|
+
tokens.push([factory.generateLocator(base, "placeholder", text, { exact })]);
|
|
166
141
|
continue;
|
|
167
142
|
}
|
|
168
|
-
if (name ===
|
|
169
|
-
tokens.push([factory.generateLocator(base,
|
|
170
|
-
exact
|
|
171
|
-
})]);
|
|
143
|
+
if (name === "alt") {
|
|
144
|
+
tokens.push([factory.generateLocator(base, "alt", text, { exact })]);
|
|
172
145
|
continue;
|
|
173
146
|
}
|
|
174
|
-
if (name ===
|
|
175
|
-
tokens.push([factory.generateLocator(base,
|
|
176
|
-
exact
|
|
177
|
-
})]);
|
|
147
|
+
if (name === "title") {
|
|
148
|
+
tokens.push([factory.generateLocator(base, "title", text, { exact })]);
|
|
178
149
|
continue;
|
|
179
150
|
}
|
|
180
151
|
}
|
|
181
|
-
if (part.name ===
|
|
182
|
-
// transform last tokens from `${selector}` into `${selector}.contentFrame()` and `frameLocator(${selector})`
|
|
152
|
+
if (part.name === "internal:control" && part.body === "enter-frame") {
|
|
183
153
|
const lastTokens = tokens[tokens.length - 1];
|
|
184
154
|
const lastPart = parts[index - 1];
|
|
185
|
-
const transformed = lastTokens.map(token => factory.chainLocators([token, factory.generateLocator(base,
|
|
186
|
-
if ([
|
|
187
|
-
transformed.push(
|
|
188
|
-
parts: [lastPart]
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}, true)));
|
|
155
|
+
const transformed = lastTokens.map((token) => factory.chainLocators([token, factory.generateLocator(base, "frame", "")]));
|
|
156
|
+
if (["xpath", "css"].includes(lastPart.name)) {
|
|
157
|
+
transformed.push(
|
|
158
|
+
factory.generateLocator(base, "frame-locator", (0, import_selectorParser.stringifySelector)({ parts: [lastPart] })),
|
|
159
|
+
factory.generateLocator(base, "frame-locator", (0, import_selectorParser.stringifySelector)({ parts: [lastPart] }, true))
|
|
160
|
+
);
|
|
192
161
|
}
|
|
193
162
|
lastTokens.splice(0, lastTokens.length, ...transformed);
|
|
194
|
-
nextBase =
|
|
163
|
+
nextBase = "frame-locator";
|
|
195
164
|
continue;
|
|
196
165
|
}
|
|
197
166
|
const nextPart = parts[index + 1];
|
|
198
|
-
const selectorPart = (0,
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
if (nextPart && ['internal:has-text', 'internal:has-not-text'].includes(nextPart.name)) {
|
|
203
|
-
const {
|
|
204
|
-
exact,
|
|
205
|
-
text
|
|
206
|
-
} = detectExact(nextPart.body);
|
|
207
|
-
// There is no locator equivalent for strict has-text and has-not-text, leave it as is.
|
|
167
|
+
const selectorPart = (0, import_selectorParser.stringifySelector)({ parts: [part] });
|
|
168
|
+
const locatorPart = factory.generateLocator(base, "default", selectorPart);
|
|
169
|
+
if (nextPart && ["internal:has-text", "internal:has-not-text"].includes(nextPart.name)) {
|
|
170
|
+
const { exact, text } = detectExact(nextPart.body);
|
|
208
171
|
if (!exact) {
|
|
209
|
-
const nextLocatorPart = factory.generateLocator(
|
|
210
|
-
exact
|
|
211
|
-
});
|
|
172
|
+
const nextLocatorPart = factory.generateLocator("locator", nextPart.name === "internal:has-text" ? "has-text" : "has-not-text", text, { exact });
|
|
212
173
|
const options = {};
|
|
213
|
-
if (nextPart.name ===
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
174
|
+
if (nextPart.name === "internal:has-text")
|
|
175
|
+
options.hasText = text;
|
|
176
|
+
else
|
|
177
|
+
options.hasNotText = text;
|
|
178
|
+
const combinedPart = factory.generateLocator(base, "default", selectorPart, options);
|
|
218
179
|
tokens.push([factory.chainLocators([locatorPart, nextLocatorPart]), combinedPart]);
|
|
219
180
|
index++;
|
|
220
181
|
continue;
|
|
221
182
|
}
|
|
222
183
|
}
|
|
223
|
-
|
|
224
|
-
// Selectors can be prefixed with engine name, e.g. xpath=//foo
|
|
225
184
|
let locatorPartWithEngine;
|
|
226
|
-
if ([
|
|
227
|
-
const
|
|
228
|
-
parts: [part]
|
|
229
|
-
|
|
230
|
-
|
|
185
|
+
if (["xpath", "css"].includes(part.name)) {
|
|
186
|
+
const selectorPart2 = (0, import_selectorParser.stringifySelector)(
|
|
187
|
+
{ parts: [part] },
|
|
188
|
+
/* forceEngineName */
|
|
189
|
+
true
|
|
190
|
+
);
|
|
191
|
+
locatorPartWithEngine = factory.generateLocator(base, "default", selectorPart2);
|
|
231
192
|
}
|
|
232
193
|
tokens.push([locatorPart, locatorPartWithEngine].filter(Boolean));
|
|
233
194
|
}
|
|
234
195
|
return combineTokens(factory, tokens, maxOutputSize);
|
|
235
196
|
}
|
|
236
197
|
function combineTokens(factory, tokens, maxOutputSize) {
|
|
237
|
-
const currentTokens = tokens.map(() =>
|
|
198
|
+
const currentTokens = tokens.map(() => "");
|
|
238
199
|
const result = [];
|
|
239
|
-
const visit = index => {
|
|
200
|
+
const visit = (index) => {
|
|
240
201
|
if (index === tokens.length) {
|
|
241
202
|
result.push(factory.chainLocators(currentTokens));
|
|
242
203
|
return result.length < maxOutputSize;
|
|
243
204
|
}
|
|
244
205
|
for (const taken of tokens[index]) {
|
|
245
206
|
currentTokens[index] = taken;
|
|
246
|
-
if (!visit(index + 1))
|
|
207
|
+
if (!visit(index + 1))
|
|
208
|
+
return false;
|
|
247
209
|
}
|
|
248
210
|
return true;
|
|
249
211
|
};
|
|
@@ -253,9 +215,8 @@ function combineTokens(factory, tokens, maxOutputSize) {
|
|
|
253
215
|
function detectExact(text) {
|
|
254
216
|
let exact = false;
|
|
255
217
|
const match = text.match(/^\/(.*)\/([igm]*)$/);
|
|
256
|
-
if (match)
|
|
257
|
-
text: new RegExp(match[1], match[2])
|
|
258
|
-
};
|
|
218
|
+
if (match)
|
|
219
|
+
return { text: new RegExp(match[1], match[2]) };
|
|
259
220
|
if (text.endsWith('"')) {
|
|
260
221
|
text = JSON.parse(text);
|
|
261
222
|
exact = true;
|
|
@@ -266,10 +227,7 @@ function detectExact(text) {
|
|
|
266
227
|
text = JSON.parse(text.substring(0, text.length - 1));
|
|
267
228
|
exact = false;
|
|
268
229
|
}
|
|
269
|
-
return {
|
|
270
|
-
exact,
|
|
271
|
-
text
|
|
272
|
-
};
|
|
230
|
+
return { exact, text };
|
|
273
231
|
}
|
|
274
232
|
class JavaScriptLocatorFactory {
|
|
275
233
|
constructor(preferredQuote) {
|
|
@@ -277,374 +235,389 @@ class JavaScriptLocatorFactory {
|
|
|
277
235
|
}
|
|
278
236
|
generateLocator(base, kind, body, options = {}) {
|
|
279
237
|
switch (kind) {
|
|
280
|
-
case
|
|
281
|
-
if (options.hasText !==
|
|
282
|
-
|
|
238
|
+
case "default":
|
|
239
|
+
if (options.hasText !== void 0)
|
|
240
|
+
return `locator(${this.quote(body)}, { hasText: ${this.toHasText(options.hasText)} })`;
|
|
241
|
+
if (options.hasNotText !== void 0)
|
|
242
|
+
return `locator(${this.quote(body)}, { hasNotText: ${this.toHasText(options.hasNotText)} })`;
|
|
283
243
|
return `locator(${this.quote(body)})`;
|
|
284
|
-
case
|
|
244
|
+
case "frame-locator":
|
|
285
245
|
return `frameLocator(${this.quote(body)})`;
|
|
286
|
-
case
|
|
246
|
+
case "frame":
|
|
287
247
|
return `contentFrame()`;
|
|
288
|
-
case
|
|
248
|
+
case "nth":
|
|
289
249
|
return `nth(${body})`;
|
|
290
|
-
case
|
|
250
|
+
case "first":
|
|
291
251
|
return `first()`;
|
|
292
|
-
case
|
|
252
|
+
case "last":
|
|
293
253
|
return `last()`;
|
|
294
|
-
case
|
|
295
|
-
return `filter({ visible: ${body ===
|
|
296
|
-
case
|
|
254
|
+
case "visible":
|
|
255
|
+
return `filter({ visible: ${body === "true" ? "true" : "false"} })`;
|
|
256
|
+
case "role":
|
|
297
257
|
const attrs = [];
|
|
298
258
|
if (isRegExp(options.name)) {
|
|
299
259
|
attrs.push(`name: ${this.regexToSourceString(options.name)}`);
|
|
300
|
-
} else if (typeof options.name ===
|
|
260
|
+
} else if (typeof options.name === "string") {
|
|
301
261
|
attrs.push(`name: ${this.quote(options.name)}`);
|
|
302
|
-
if (options.exact)
|
|
262
|
+
if (options.exact)
|
|
263
|
+
attrs.push(`exact: true`);
|
|
303
264
|
}
|
|
304
|
-
for (const {
|
|
305
|
-
name
|
|
306
|
-
|
|
307
|
-
} of options.attrs) attrs.push(`${name}: ${typeof value === 'string' ? this.quote(value) : value}`);
|
|
308
|
-
const attrString = attrs.length ? `, { ${attrs.join(', ')} }` : '';
|
|
265
|
+
for (const { name, value } of options.attrs)
|
|
266
|
+
attrs.push(`${name}: ${typeof value === "string" ? this.quote(value) : value}`);
|
|
267
|
+
const attrString = attrs.length ? `, { ${attrs.join(", ")} }` : "";
|
|
309
268
|
return `getByRole(${this.quote(body)}${attrString})`;
|
|
310
|
-
case
|
|
269
|
+
case "has-text":
|
|
311
270
|
return `filter({ hasText: ${this.toHasText(body)} })`;
|
|
312
|
-
case
|
|
271
|
+
case "has-not-text":
|
|
313
272
|
return `filter({ hasNotText: ${this.toHasText(body)} })`;
|
|
314
|
-
case
|
|
273
|
+
case "has":
|
|
315
274
|
return `filter({ has: ${body} })`;
|
|
316
|
-
case
|
|
275
|
+
case "hasNot":
|
|
317
276
|
return `filter({ hasNot: ${body} })`;
|
|
318
|
-
case
|
|
277
|
+
case "and":
|
|
319
278
|
return `and(${body})`;
|
|
320
|
-
case
|
|
279
|
+
case "or":
|
|
321
280
|
return `or(${body})`;
|
|
322
|
-
case
|
|
281
|
+
case "chain":
|
|
323
282
|
return `locator(${body})`;
|
|
324
|
-
case
|
|
283
|
+
case "test-id":
|
|
325
284
|
return `getByTestId(${this.toTestIdValue(body)})`;
|
|
326
|
-
case
|
|
327
|
-
return this.toCallWithExact(
|
|
328
|
-
case
|
|
329
|
-
return this.toCallWithExact(
|
|
330
|
-
case
|
|
331
|
-
return this.toCallWithExact(
|
|
332
|
-
case
|
|
333
|
-
return this.toCallWithExact(
|
|
334
|
-
case
|
|
335
|
-
return this.toCallWithExact(
|
|
285
|
+
case "text":
|
|
286
|
+
return this.toCallWithExact("getByText", body, !!options.exact);
|
|
287
|
+
case "alt":
|
|
288
|
+
return this.toCallWithExact("getByAltText", body, !!options.exact);
|
|
289
|
+
case "placeholder":
|
|
290
|
+
return this.toCallWithExact("getByPlaceholder", body, !!options.exact);
|
|
291
|
+
case "label":
|
|
292
|
+
return this.toCallWithExact("getByLabel", body, !!options.exact);
|
|
293
|
+
case "title":
|
|
294
|
+
return this.toCallWithExact("getByTitle", body, !!options.exact);
|
|
336
295
|
default:
|
|
337
|
-
throw new Error(
|
|
296
|
+
throw new Error("Unknown selector kind " + kind);
|
|
338
297
|
}
|
|
339
298
|
}
|
|
340
299
|
chainLocators(locators) {
|
|
341
|
-
return locators.join(
|
|
300
|
+
return locators.join(".");
|
|
342
301
|
}
|
|
343
302
|
regexToSourceString(re) {
|
|
344
|
-
return (0,
|
|
303
|
+
return (0, import_stringUtils.normalizeEscapedRegexQuotes)(String(re));
|
|
345
304
|
}
|
|
346
305
|
toCallWithExact(method, body, exact) {
|
|
347
|
-
if (isRegExp(body))
|
|
306
|
+
if (isRegExp(body))
|
|
307
|
+
return `${method}(${this.regexToSourceString(body)})`;
|
|
348
308
|
return exact ? `${method}(${this.quote(body)}, { exact: true })` : `${method}(${this.quote(body)})`;
|
|
349
309
|
}
|
|
350
310
|
toHasText(body) {
|
|
351
|
-
if (isRegExp(body))
|
|
311
|
+
if (isRegExp(body))
|
|
312
|
+
return this.regexToSourceString(body);
|
|
352
313
|
return this.quote(body);
|
|
353
314
|
}
|
|
354
315
|
toTestIdValue(value) {
|
|
355
|
-
if (isRegExp(value))
|
|
316
|
+
if (isRegExp(value))
|
|
317
|
+
return this.regexToSourceString(value);
|
|
356
318
|
return this.quote(value);
|
|
357
319
|
}
|
|
358
320
|
quote(text) {
|
|
359
|
-
|
|
360
|
-
return (0, _stringUtils.escapeWithQuotes)(text, (_this$preferredQuote = this.preferredQuote) !== null && _this$preferredQuote !== void 0 ? _this$preferredQuote : '\'');
|
|
321
|
+
return (0, import_stringUtils.escapeWithQuotes)(text, this.preferredQuote ?? "'");
|
|
361
322
|
}
|
|
362
323
|
}
|
|
363
|
-
exports.JavaScriptLocatorFactory = JavaScriptLocatorFactory;
|
|
364
324
|
class PythonLocatorFactory {
|
|
365
325
|
generateLocator(base, kind, body, options = {}) {
|
|
366
326
|
switch (kind) {
|
|
367
|
-
case
|
|
368
|
-
if (options.hasText !==
|
|
369
|
-
|
|
327
|
+
case "default":
|
|
328
|
+
if (options.hasText !== void 0)
|
|
329
|
+
return `locator(${this.quote(body)}, has_text=${this.toHasText(options.hasText)})`;
|
|
330
|
+
if (options.hasNotText !== void 0)
|
|
331
|
+
return `locator(${this.quote(body)}, has_not_text=${this.toHasText(options.hasNotText)})`;
|
|
370
332
|
return `locator(${this.quote(body)})`;
|
|
371
|
-
case
|
|
333
|
+
case "frame-locator":
|
|
372
334
|
return `frame_locator(${this.quote(body)})`;
|
|
373
|
-
case
|
|
335
|
+
case "frame":
|
|
374
336
|
return `content_frame`;
|
|
375
|
-
case
|
|
337
|
+
case "nth":
|
|
376
338
|
return `nth(${body})`;
|
|
377
|
-
case
|
|
339
|
+
case "first":
|
|
378
340
|
return `first`;
|
|
379
|
-
case
|
|
341
|
+
case "last":
|
|
380
342
|
return `last`;
|
|
381
|
-
case
|
|
382
|
-
return `filter(visible=${body ===
|
|
383
|
-
case
|
|
343
|
+
case "visible":
|
|
344
|
+
return `filter(visible=${body === "true" ? "True" : "False"})`;
|
|
345
|
+
case "role":
|
|
384
346
|
const attrs = [];
|
|
385
347
|
if (isRegExp(options.name)) {
|
|
386
348
|
attrs.push(`name=${this.regexToString(options.name)}`);
|
|
387
|
-
} else if (typeof options.name ===
|
|
349
|
+
} else if (typeof options.name === "string") {
|
|
388
350
|
attrs.push(`name=${this.quote(options.name)}`);
|
|
389
|
-
if (options.exact)
|
|
351
|
+
if (options.exact)
|
|
352
|
+
attrs.push(`exact=True`);
|
|
390
353
|
}
|
|
391
|
-
for (const {
|
|
392
|
-
|
|
393
|
-
value
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
if (typeof value === 'boolean') valueString = value ? 'True' : 'False';
|
|
397
|
-
attrs.push(`${(0, _stringUtils.toSnakeCase)(name)}=${valueString}`);
|
|
354
|
+
for (const { name, value } of options.attrs) {
|
|
355
|
+
let valueString = typeof value === "string" ? this.quote(value) : value;
|
|
356
|
+
if (typeof value === "boolean")
|
|
357
|
+
valueString = value ? "True" : "False";
|
|
358
|
+
attrs.push(`${(0, import_stringUtils.toSnakeCase)(name)}=${valueString}`);
|
|
398
359
|
}
|
|
399
|
-
const attrString = attrs.length ? `, ${attrs.join(
|
|
360
|
+
const attrString = attrs.length ? `, ${attrs.join(", ")}` : "";
|
|
400
361
|
return `get_by_role(${this.quote(body)}${attrString})`;
|
|
401
|
-
case
|
|
362
|
+
case "has-text":
|
|
402
363
|
return `filter(has_text=${this.toHasText(body)})`;
|
|
403
|
-
case
|
|
364
|
+
case "has-not-text":
|
|
404
365
|
return `filter(has_not_text=${this.toHasText(body)})`;
|
|
405
|
-
case
|
|
366
|
+
case "has":
|
|
406
367
|
return `filter(has=${body})`;
|
|
407
|
-
case
|
|
368
|
+
case "hasNot":
|
|
408
369
|
return `filter(has_not=${body})`;
|
|
409
|
-
case
|
|
370
|
+
case "and":
|
|
410
371
|
return `and_(${body})`;
|
|
411
|
-
case
|
|
372
|
+
case "or":
|
|
412
373
|
return `or_(${body})`;
|
|
413
|
-
case
|
|
374
|
+
case "chain":
|
|
414
375
|
return `locator(${body})`;
|
|
415
|
-
case
|
|
376
|
+
case "test-id":
|
|
416
377
|
return `get_by_test_id(${this.toTestIdValue(body)})`;
|
|
417
|
-
case
|
|
418
|
-
return this.toCallWithExact(
|
|
419
|
-
case
|
|
420
|
-
return this.toCallWithExact(
|
|
421
|
-
case
|
|
422
|
-
return this.toCallWithExact(
|
|
423
|
-
case
|
|
424
|
-
return this.toCallWithExact(
|
|
425
|
-
case
|
|
426
|
-
return this.toCallWithExact(
|
|
378
|
+
case "text":
|
|
379
|
+
return this.toCallWithExact("get_by_text", body, !!options.exact);
|
|
380
|
+
case "alt":
|
|
381
|
+
return this.toCallWithExact("get_by_alt_text", body, !!options.exact);
|
|
382
|
+
case "placeholder":
|
|
383
|
+
return this.toCallWithExact("get_by_placeholder", body, !!options.exact);
|
|
384
|
+
case "label":
|
|
385
|
+
return this.toCallWithExact("get_by_label", body, !!options.exact);
|
|
386
|
+
case "title":
|
|
387
|
+
return this.toCallWithExact("get_by_title", body, !!options.exact);
|
|
427
388
|
default:
|
|
428
|
-
throw new Error(
|
|
389
|
+
throw new Error("Unknown selector kind " + kind);
|
|
429
390
|
}
|
|
430
391
|
}
|
|
431
392
|
chainLocators(locators) {
|
|
432
|
-
return locators.join(
|
|
393
|
+
return locators.join(".");
|
|
433
394
|
}
|
|
434
395
|
regexToString(body) {
|
|
435
|
-
const suffix = body.flags.includes(
|
|
436
|
-
return `re.compile(r"${(0,
|
|
396
|
+
const suffix = body.flags.includes("i") ? ", re.IGNORECASE" : "";
|
|
397
|
+
return `re.compile(r"${(0, import_stringUtils.normalizeEscapedRegexQuotes)(body.source).replace(/\\\//, "/").replace(/"/g, '\\"')}"${suffix})`;
|
|
437
398
|
}
|
|
438
399
|
toCallWithExact(method, body, exact) {
|
|
439
|
-
if (isRegExp(body))
|
|
440
|
-
|
|
400
|
+
if (isRegExp(body))
|
|
401
|
+
return `${method}(${this.regexToString(body)})`;
|
|
402
|
+
if (exact)
|
|
403
|
+
return `${method}(${this.quote(body)}, exact=True)`;
|
|
441
404
|
return `${method}(${this.quote(body)})`;
|
|
442
405
|
}
|
|
443
406
|
toHasText(body) {
|
|
444
|
-
if (isRegExp(body))
|
|
407
|
+
if (isRegExp(body))
|
|
408
|
+
return this.regexToString(body);
|
|
445
409
|
return `${this.quote(body)}`;
|
|
446
410
|
}
|
|
447
411
|
toTestIdValue(value) {
|
|
448
|
-
if (isRegExp(value))
|
|
412
|
+
if (isRegExp(value))
|
|
413
|
+
return this.regexToString(value);
|
|
449
414
|
return this.quote(value);
|
|
450
415
|
}
|
|
451
416
|
quote(text) {
|
|
452
|
-
return (0,
|
|
417
|
+
return (0, import_stringUtils.escapeWithQuotes)(text, '"');
|
|
453
418
|
}
|
|
454
419
|
}
|
|
455
|
-
exports.PythonLocatorFactory = PythonLocatorFactory;
|
|
456
420
|
class JavaLocatorFactory {
|
|
457
421
|
generateLocator(base, kind, body, options = {}) {
|
|
458
422
|
let clazz;
|
|
459
423
|
switch (base) {
|
|
460
|
-
case
|
|
461
|
-
clazz =
|
|
424
|
+
case "page":
|
|
425
|
+
clazz = "Page";
|
|
462
426
|
break;
|
|
463
|
-
case
|
|
464
|
-
clazz =
|
|
427
|
+
case "frame-locator":
|
|
428
|
+
clazz = "FrameLocator";
|
|
465
429
|
break;
|
|
466
|
-
case
|
|
467
|
-
clazz =
|
|
430
|
+
case "locator":
|
|
431
|
+
clazz = "Locator";
|
|
468
432
|
break;
|
|
469
433
|
}
|
|
470
434
|
switch (kind) {
|
|
471
|
-
case
|
|
472
|
-
if (options.hasText !==
|
|
473
|
-
|
|
435
|
+
case "default":
|
|
436
|
+
if (options.hasText !== void 0)
|
|
437
|
+
return `locator(${this.quote(body)}, new ${clazz}.LocatorOptions().setHasText(${this.toHasText(options.hasText)}))`;
|
|
438
|
+
if (options.hasNotText !== void 0)
|
|
439
|
+
return `locator(${this.quote(body)}, new ${clazz}.LocatorOptions().setHasNotText(${this.toHasText(options.hasNotText)}))`;
|
|
474
440
|
return `locator(${this.quote(body)})`;
|
|
475
|
-
case
|
|
441
|
+
case "frame-locator":
|
|
476
442
|
return `frameLocator(${this.quote(body)})`;
|
|
477
|
-
case
|
|
443
|
+
case "frame":
|
|
478
444
|
return `contentFrame()`;
|
|
479
|
-
case
|
|
445
|
+
case "nth":
|
|
480
446
|
return `nth(${body})`;
|
|
481
|
-
case
|
|
447
|
+
case "first":
|
|
482
448
|
return `first()`;
|
|
483
|
-
case
|
|
449
|
+
case "last":
|
|
484
450
|
return `last()`;
|
|
485
|
-
case
|
|
486
|
-
return `filter(new ${clazz}.FilterOptions().setVisible(${body ===
|
|
487
|
-
case
|
|
451
|
+
case "visible":
|
|
452
|
+
return `filter(new ${clazz}.FilterOptions().setVisible(${body === "true" ? "true" : "false"}))`;
|
|
453
|
+
case "role":
|
|
488
454
|
const attrs = [];
|
|
489
455
|
if (isRegExp(options.name)) {
|
|
490
456
|
attrs.push(`.setName(${this.regexToString(options.name)})`);
|
|
491
|
-
} else if (typeof options.name ===
|
|
457
|
+
} else if (typeof options.name === "string") {
|
|
492
458
|
attrs.push(`.setName(${this.quote(options.name)})`);
|
|
493
|
-
if (options.exact)
|
|
459
|
+
if (options.exact)
|
|
460
|
+
attrs.push(`.setExact(true)`);
|
|
494
461
|
}
|
|
495
|
-
for (const {
|
|
496
|
-
name
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
return `getByRole(AriaRole.${(0, _stringUtils.toSnakeCase)(body).toUpperCase()}${attrString})`;
|
|
501
|
-
case 'has-text':
|
|
462
|
+
for (const { name, value } of options.attrs)
|
|
463
|
+
attrs.push(`.set${(0, import_stringUtils.toTitleCase)(name)}(${typeof value === "string" ? this.quote(value) : value})`);
|
|
464
|
+
const attrString = attrs.length ? `, new ${clazz}.GetByRoleOptions()${attrs.join("")}` : "";
|
|
465
|
+
return `getByRole(AriaRole.${(0, import_stringUtils.toSnakeCase)(body).toUpperCase()}${attrString})`;
|
|
466
|
+
case "has-text":
|
|
502
467
|
return `filter(new ${clazz}.FilterOptions().setHasText(${this.toHasText(body)}))`;
|
|
503
|
-
case
|
|
468
|
+
case "has-not-text":
|
|
504
469
|
return `filter(new ${clazz}.FilterOptions().setHasNotText(${this.toHasText(body)}))`;
|
|
505
|
-
case
|
|
470
|
+
case "has":
|
|
506
471
|
return `filter(new ${clazz}.FilterOptions().setHas(${body}))`;
|
|
507
|
-
case
|
|
472
|
+
case "hasNot":
|
|
508
473
|
return `filter(new ${clazz}.FilterOptions().setHasNot(${body}))`;
|
|
509
|
-
case
|
|
474
|
+
case "and":
|
|
510
475
|
return `and(${body})`;
|
|
511
|
-
case
|
|
476
|
+
case "or":
|
|
512
477
|
return `or(${body})`;
|
|
513
|
-
case
|
|
478
|
+
case "chain":
|
|
514
479
|
return `locator(${body})`;
|
|
515
|
-
case
|
|
480
|
+
case "test-id":
|
|
516
481
|
return `getByTestId(${this.toTestIdValue(body)})`;
|
|
517
|
-
case
|
|
518
|
-
return this.toCallWithExact(clazz,
|
|
519
|
-
case
|
|
520
|
-
return this.toCallWithExact(clazz,
|
|
521
|
-
case
|
|
522
|
-
return this.toCallWithExact(clazz,
|
|
523
|
-
case
|
|
524
|
-
return this.toCallWithExact(clazz,
|
|
525
|
-
case
|
|
526
|
-
return this.toCallWithExact(clazz,
|
|
482
|
+
case "text":
|
|
483
|
+
return this.toCallWithExact(clazz, "getByText", body, !!options.exact);
|
|
484
|
+
case "alt":
|
|
485
|
+
return this.toCallWithExact(clazz, "getByAltText", body, !!options.exact);
|
|
486
|
+
case "placeholder":
|
|
487
|
+
return this.toCallWithExact(clazz, "getByPlaceholder", body, !!options.exact);
|
|
488
|
+
case "label":
|
|
489
|
+
return this.toCallWithExact(clazz, "getByLabel", body, !!options.exact);
|
|
490
|
+
case "title":
|
|
491
|
+
return this.toCallWithExact(clazz, "getByTitle", body, !!options.exact);
|
|
527
492
|
default:
|
|
528
|
-
throw new Error(
|
|
493
|
+
throw new Error("Unknown selector kind " + kind);
|
|
529
494
|
}
|
|
530
495
|
}
|
|
531
496
|
chainLocators(locators) {
|
|
532
|
-
return locators.join(
|
|
497
|
+
return locators.join(".");
|
|
533
498
|
}
|
|
534
499
|
regexToString(body) {
|
|
535
|
-
const suffix = body.flags.includes(
|
|
536
|
-
return `Pattern.compile(${this.quote((0,
|
|
500
|
+
const suffix = body.flags.includes("i") ? ", Pattern.CASE_INSENSITIVE" : "";
|
|
501
|
+
return `Pattern.compile(${this.quote((0, import_stringUtils.normalizeEscapedRegexQuotes)(body.source))}${suffix})`;
|
|
537
502
|
}
|
|
538
503
|
toCallWithExact(clazz, method, body, exact) {
|
|
539
|
-
if (isRegExp(body))
|
|
540
|
-
|
|
504
|
+
if (isRegExp(body))
|
|
505
|
+
return `${method}(${this.regexToString(body)})`;
|
|
506
|
+
if (exact)
|
|
507
|
+
return `${method}(${this.quote(body)}, new ${clazz}.${(0, import_stringUtils.toTitleCase)(method)}Options().setExact(true))`;
|
|
541
508
|
return `${method}(${this.quote(body)})`;
|
|
542
509
|
}
|
|
543
510
|
toHasText(body) {
|
|
544
|
-
if (isRegExp(body))
|
|
511
|
+
if (isRegExp(body))
|
|
512
|
+
return this.regexToString(body);
|
|
545
513
|
return this.quote(body);
|
|
546
514
|
}
|
|
547
515
|
toTestIdValue(value) {
|
|
548
|
-
if (isRegExp(value))
|
|
516
|
+
if (isRegExp(value))
|
|
517
|
+
return this.regexToString(value);
|
|
549
518
|
return this.quote(value);
|
|
550
519
|
}
|
|
551
520
|
quote(text) {
|
|
552
|
-
return (0,
|
|
521
|
+
return (0, import_stringUtils.escapeWithQuotes)(text, '"');
|
|
553
522
|
}
|
|
554
523
|
}
|
|
555
|
-
exports.JavaLocatorFactory = JavaLocatorFactory;
|
|
556
524
|
class CSharpLocatorFactory {
|
|
557
525
|
generateLocator(base, kind, body, options = {}) {
|
|
558
526
|
switch (kind) {
|
|
559
|
-
case
|
|
560
|
-
if (options.hasText !==
|
|
561
|
-
|
|
527
|
+
case "default":
|
|
528
|
+
if (options.hasText !== void 0)
|
|
529
|
+
return `Locator(${this.quote(body)}, new() { ${this.toHasText(options.hasText)} })`;
|
|
530
|
+
if (options.hasNotText !== void 0)
|
|
531
|
+
return `Locator(${this.quote(body)}, new() { ${this.toHasNotText(options.hasNotText)} })`;
|
|
562
532
|
return `Locator(${this.quote(body)})`;
|
|
563
|
-
case
|
|
533
|
+
case "frame-locator":
|
|
564
534
|
return `FrameLocator(${this.quote(body)})`;
|
|
565
|
-
case
|
|
535
|
+
case "frame":
|
|
566
536
|
return `ContentFrame`;
|
|
567
|
-
case
|
|
537
|
+
case "nth":
|
|
568
538
|
return `Nth(${body})`;
|
|
569
|
-
case
|
|
539
|
+
case "first":
|
|
570
540
|
return `First`;
|
|
571
|
-
case
|
|
541
|
+
case "last":
|
|
572
542
|
return `Last`;
|
|
573
|
-
case
|
|
574
|
-
return `Filter(new() { Visible = ${body ===
|
|
575
|
-
case
|
|
543
|
+
case "visible":
|
|
544
|
+
return `Filter(new() { Visible = ${body === "true" ? "true" : "false"} })`;
|
|
545
|
+
case "role":
|
|
576
546
|
const attrs = [];
|
|
577
547
|
if (isRegExp(options.name)) {
|
|
578
548
|
attrs.push(`NameRegex = ${this.regexToString(options.name)}`);
|
|
579
|
-
} else if (typeof options.name ===
|
|
549
|
+
} else if (typeof options.name === "string") {
|
|
580
550
|
attrs.push(`Name = ${this.quote(options.name)}`);
|
|
581
|
-
if (options.exact)
|
|
551
|
+
if (options.exact)
|
|
552
|
+
attrs.push(`Exact = true`);
|
|
582
553
|
}
|
|
583
|
-
for (const {
|
|
584
|
-
name
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
return `GetByRole(AriaRole.${(0, _stringUtils.toTitleCase)(body)}${attrString})`;
|
|
589
|
-
case 'has-text':
|
|
554
|
+
for (const { name, value } of options.attrs)
|
|
555
|
+
attrs.push(`${(0, import_stringUtils.toTitleCase)(name)} = ${typeof value === "string" ? this.quote(value) : value}`);
|
|
556
|
+
const attrString = attrs.length ? `, new() { ${attrs.join(", ")} }` : "";
|
|
557
|
+
return `GetByRole(AriaRole.${(0, import_stringUtils.toTitleCase)(body)}${attrString})`;
|
|
558
|
+
case "has-text":
|
|
590
559
|
return `Filter(new() { ${this.toHasText(body)} })`;
|
|
591
|
-
case
|
|
560
|
+
case "has-not-text":
|
|
592
561
|
return `Filter(new() { ${this.toHasNotText(body)} })`;
|
|
593
|
-
case
|
|
562
|
+
case "has":
|
|
594
563
|
return `Filter(new() { Has = ${body} })`;
|
|
595
|
-
case
|
|
564
|
+
case "hasNot":
|
|
596
565
|
return `Filter(new() { HasNot = ${body} })`;
|
|
597
|
-
case
|
|
566
|
+
case "and":
|
|
598
567
|
return `And(${body})`;
|
|
599
|
-
case
|
|
568
|
+
case "or":
|
|
600
569
|
return `Or(${body})`;
|
|
601
|
-
case
|
|
570
|
+
case "chain":
|
|
602
571
|
return `Locator(${body})`;
|
|
603
|
-
case
|
|
572
|
+
case "test-id":
|
|
604
573
|
return `GetByTestId(${this.toTestIdValue(body)})`;
|
|
605
|
-
case
|
|
606
|
-
return this.toCallWithExact(
|
|
607
|
-
case
|
|
608
|
-
return this.toCallWithExact(
|
|
609
|
-
case
|
|
610
|
-
return this.toCallWithExact(
|
|
611
|
-
case
|
|
612
|
-
return this.toCallWithExact(
|
|
613
|
-
case
|
|
614
|
-
return this.toCallWithExact(
|
|
574
|
+
case "text":
|
|
575
|
+
return this.toCallWithExact("GetByText", body, !!options.exact);
|
|
576
|
+
case "alt":
|
|
577
|
+
return this.toCallWithExact("GetByAltText", body, !!options.exact);
|
|
578
|
+
case "placeholder":
|
|
579
|
+
return this.toCallWithExact("GetByPlaceholder", body, !!options.exact);
|
|
580
|
+
case "label":
|
|
581
|
+
return this.toCallWithExact("GetByLabel", body, !!options.exact);
|
|
582
|
+
case "title":
|
|
583
|
+
return this.toCallWithExact("GetByTitle", body, !!options.exact);
|
|
615
584
|
default:
|
|
616
|
-
throw new Error(
|
|
585
|
+
throw new Error("Unknown selector kind " + kind);
|
|
617
586
|
}
|
|
618
587
|
}
|
|
619
588
|
chainLocators(locators) {
|
|
620
|
-
return locators.join(
|
|
589
|
+
return locators.join(".");
|
|
621
590
|
}
|
|
622
591
|
regexToString(body) {
|
|
623
|
-
const suffix = body.flags.includes(
|
|
624
|
-
return `new Regex(${this.quote((0,
|
|
592
|
+
const suffix = body.flags.includes("i") ? ", RegexOptions.IgnoreCase" : "";
|
|
593
|
+
return `new Regex(${this.quote((0, import_stringUtils.normalizeEscapedRegexQuotes)(body.source))}${suffix})`;
|
|
625
594
|
}
|
|
626
595
|
toCallWithExact(method, body, exact) {
|
|
627
|
-
if (isRegExp(body))
|
|
628
|
-
|
|
596
|
+
if (isRegExp(body))
|
|
597
|
+
return `${method}(${this.regexToString(body)})`;
|
|
598
|
+
if (exact)
|
|
599
|
+
return `${method}(${this.quote(body)}, new() { Exact = true })`;
|
|
629
600
|
return `${method}(${this.quote(body)})`;
|
|
630
601
|
}
|
|
631
602
|
toHasText(body) {
|
|
632
|
-
if (isRegExp(body))
|
|
603
|
+
if (isRegExp(body))
|
|
604
|
+
return `HasTextRegex = ${this.regexToString(body)}`;
|
|
633
605
|
return `HasText = ${this.quote(body)}`;
|
|
634
606
|
}
|
|
635
607
|
toTestIdValue(value) {
|
|
636
|
-
if (isRegExp(value))
|
|
608
|
+
if (isRegExp(value))
|
|
609
|
+
return this.regexToString(value);
|
|
637
610
|
return this.quote(value);
|
|
638
611
|
}
|
|
639
612
|
toHasNotText(body) {
|
|
640
|
-
if (isRegExp(body))
|
|
613
|
+
if (isRegExp(body))
|
|
614
|
+
return `HasNotTextRegex = ${this.regexToString(body)}`;
|
|
641
615
|
return `HasNotText = ${this.quote(body)}`;
|
|
642
616
|
}
|
|
643
617
|
quote(text) {
|
|
644
|
-
return (0,
|
|
618
|
+
return (0, import_stringUtils.escapeWithQuotes)(text, '"');
|
|
645
619
|
}
|
|
646
620
|
}
|
|
647
|
-
exports.CSharpLocatorFactory = CSharpLocatorFactory;
|
|
648
621
|
class JsonlLocatorFactory {
|
|
649
622
|
generateLocator(base, kind, body, options = {}) {
|
|
650
623
|
return JSON.stringify({
|
|
@@ -654,12 +627,12 @@ class JsonlLocatorFactory {
|
|
|
654
627
|
});
|
|
655
628
|
}
|
|
656
629
|
chainLocators(locators) {
|
|
657
|
-
const objects = locators.map(l => JSON.parse(l));
|
|
658
|
-
for (let i = 0; i < objects.length - 1; ++i)
|
|
630
|
+
const objects = locators.map((l) => JSON.parse(l));
|
|
631
|
+
for (let i = 0; i < objects.length - 1; ++i)
|
|
632
|
+
objects[i].next = objects[i + 1];
|
|
659
633
|
return JSON.stringify(objects[0]);
|
|
660
634
|
}
|
|
661
635
|
}
|
|
662
|
-
exports.JsonlLocatorFactory = JsonlLocatorFactory;
|
|
663
636
|
const generators = {
|
|
664
637
|
javascript: JavaScriptLocatorFactory,
|
|
665
638
|
python: PythonLocatorFactory,
|
|
@@ -669,4 +642,14 @@ const generators = {
|
|
|
669
642
|
};
|
|
670
643
|
function isRegExp(obj) {
|
|
671
644
|
return obj instanceof RegExp;
|
|
672
|
-
}
|
|
645
|
+
}
|
|
646
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
647
|
+
0 && (module.exports = {
|
|
648
|
+
CSharpLocatorFactory,
|
|
649
|
+
JavaLocatorFactory,
|
|
650
|
+
JavaScriptLocatorFactory,
|
|
651
|
+
JsonlLocatorFactory,
|
|
652
|
+
PythonLocatorFactory,
|
|
653
|
+
asLocator,
|
|
654
|
+
asLocators
|
|
655
|
+
});
|