phantomwright-driver-core 1.57.0 → 1.57.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/bin/reinstall_chrome_beta_linux.sh +0 -0
- package/bin/reinstall_chrome_beta_mac.sh +0 -0
- package/bin/reinstall_chrome_stable_linux.sh +0 -0
- package/bin/reinstall_chrome_stable_mac.sh +0 -0
- package/bin/reinstall_msedge_beta_linux.sh +0 -0
- package/bin/reinstall_msedge_beta_mac.sh +0 -0
- package/bin/reinstall_msedge_dev_linux.sh +0 -0
- package/bin/reinstall_msedge_dev_mac.sh +0 -0
- package/bin/reinstall_msedge_stable_linux.sh +0 -0
- package/bin/reinstall_msedge_stable_mac.sh +0 -0
- package/lib/client/browserContext.js +19 -0
- package/lib/client/clientHelper.js +1 -2
- package/lib/client/clock.js +1 -0
- package/lib/client/frame.js +9 -9
- package/lib/client/jsHandle.js +4 -4
- package/lib/client/locator.js +28 -7
- package/lib/client/page.js +25 -6
- package/lib/client/tracing.js +1 -0
- package/lib/client/worker.js +6 -6
- package/lib/generated/injectedScriptSource.js +1 -1
- package/lib/protocol/validator.js +20 -8
- package/lib/server/browserContext.js +10 -23
- package/lib/server/chromium/chromiumSwitches.js +2 -14
- package/lib/server/chromium/crBrowser.js +7 -2
- package/lib/server/chromium/crDevTools.js +0 -1
- package/lib/server/chromium/crNetworkManager.js +246 -7
- package/lib/server/chromium/crPage.js +119 -41
- package/lib/server/chromium/crServiceWorker.js +10 -2
- package/lib/server/clock.js +8 -0
- package/lib/server/dispatchers/frameDispatcher.js +3 -3
- package/lib/server/dispatchers/jsHandleDispatcher.js +2 -2
- package/lib/server/frameSelectors.js +167 -5
- package/lib/server/frames.js +525 -181
- package/lib/server/javascript.js +22 -6
- package/lib/server/page.js +40 -58
- package/lib/server/pageBinding.js +87 -0
- package/lib/server/registry/index.js +1 -1
- package/lib/utils/isomorphic/oldUtilityScriptSerializers.js +248 -0
- package/lib/utilsBundleImpl/xdg-open +0 -0
- package/lib/vite/recorder/assets/{codeMirrorModule-BoWUGj0J.js → codeMirrorModule-CBbSe-ZI.js} +1 -1
- package/lib/vite/recorder/assets/{index-DJqDAOZp.js → index-CpZVd2nA.js} +3 -3
- package/lib/vite/recorder/index.html +1 -1
- package/lib/vite/traceViewer/assets/{codeMirrorModule-Bucv2d7q.js → codeMirrorModule-DHz0wP2C.js} +1 -1
- package/lib/vite/traceViewer/assets/{defaultSettingsView-BEpdCv1S.js → defaultSettingsView-WsZP88O6.js} +87 -87
- package/lib/vite/traceViewer/{index.BxQ34UMZ.js → index.C8xAeo93.js} +1 -1
- package/lib/vite/traceViewer/index.html +2 -2
- package/lib/vite/traceViewer/{uiMode.BWTwXl41.js → uiMode.BltraIJB.js} +1 -1
- package/lib/vite/traceViewer/uiMode.html +2 -2
- package/package.json +42 -42
|
@@ -610,6 +610,7 @@ import_validatorPrimitives.scheme.BrowserTypeLaunchPersistentContextParams = (0,
|
|
|
610
610
|
serviceWorkers: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tEnum)(["allow", "block"])),
|
|
611
611
|
selectorEngines: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)((0, import_validatorPrimitives.tType)("SelectorEngine"))),
|
|
612
612
|
testIdAttributeName: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
613
|
+
focusControl: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tBoolean),
|
|
613
614
|
userDataDir: import_validatorPrimitives.tString,
|
|
614
615
|
slowMo: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tFloat)
|
|
615
616
|
});
|
|
@@ -702,6 +703,7 @@ import_validatorPrimitives.scheme.BrowserNewContextParams = (0, import_validator
|
|
|
702
703
|
serviceWorkers: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tEnum)(["allow", "block"])),
|
|
703
704
|
selectorEngines: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)((0, import_validatorPrimitives.tType)("SelectorEngine"))),
|
|
704
705
|
testIdAttributeName: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
706
|
+
focusControl: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tBoolean),
|
|
705
707
|
proxy: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tObject)({
|
|
706
708
|
server: import_validatorPrimitives.tString,
|
|
707
709
|
bypass: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
@@ -773,6 +775,7 @@ import_validatorPrimitives.scheme.BrowserNewContextForReuseParams = (0, import_v
|
|
|
773
775
|
serviceWorkers: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tEnum)(["allow", "block"])),
|
|
774
776
|
selectorEngines: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)((0, import_validatorPrimitives.tType)("SelectorEngine"))),
|
|
775
777
|
testIdAttributeName: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
778
|
+
focusControl: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tBoolean),
|
|
776
779
|
proxy: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tObject)({
|
|
777
780
|
server: import_validatorPrimitives.tString,
|
|
778
781
|
bypass: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
@@ -888,7 +891,8 @@ import_validatorPrimitives.scheme.BrowserContextInitializer = (0, import_validat
|
|
|
888
891
|
strictSelectors: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tBoolean),
|
|
889
892
|
serviceWorkers: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tEnum)(["allow", "block"])),
|
|
890
893
|
selectorEngines: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)((0, import_validatorPrimitives.tType)("SelectorEngine"))),
|
|
891
|
-
testIdAttributeName: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString)
|
|
894
|
+
testIdAttributeName: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
895
|
+
focusControl: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tBoolean)
|
|
892
896
|
})
|
|
893
897
|
});
|
|
894
898
|
import_validatorPrimitives.scheme.BrowserContextBindingCallEvent = (0, import_validatorPrimitives.tObject)({
|
|
@@ -1522,7 +1526,8 @@ import_validatorPrimitives.scheme.FrameEvalOnSelectorAllParams = (0, import_vali
|
|
|
1522
1526
|
selector: import_validatorPrimitives.tString,
|
|
1523
1527
|
expression: import_validatorPrimitives.tString,
|
|
1524
1528
|
isFunction: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tBoolean),
|
|
1525
|
-
arg: (0, import_validatorPrimitives.tType)("SerializedArgument")
|
|
1529
|
+
arg: (0, import_validatorPrimitives.tType)("SerializedArgument"),
|
|
1530
|
+
isolatedContext: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tBoolean)
|
|
1526
1531
|
});
|
|
1527
1532
|
import_validatorPrimitives.scheme.FrameEvalOnSelectorAllResult = (0, import_validatorPrimitives.tObject)({
|
|
1528
1533
|
value: (0, import_validatorPrimitives.tType)("SerializedValue")
|
|
@@ -1619,7 +1624,8 @@ import_validatorPrimitives.scheme.FrameDispatchEventResult = (0, import_validato
|
|
|
1619
1624
|
import_validatorPrimitives.scheme.FrameEvaluateExpressionParams = (0, import_validatorPrimitives.tObject)({
|
|
1620
1625
|
expression: import_validatorPrimitives.tString,
|
|
1621
1626
|
isFunction: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tBoolean),
|
|
1622
|
-
arg: (0, import_validatorPrimitives.tType)("SerializedArgument")
|
|
1627
|
+
arg: (0, import_validatorPrimitives.tType)("SerializedArgument"),
|
|
1628
|
+
isolatedContext: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tBoolean)
|
|
1623
1629
|
});
|
|
1624
1630
|
import_validatorPrimitives.scheme.FrameEvaluateExpressionResult = (0, import_validatorPrimitives.tObject)({
|
|
1625
1631
|
value: (0, import_validatorPrimitives.tType)("SerializedValue")
|
|
@@ -1627,7 +1633,8 @@ import_validatorPrimitives.scheme.FrameEvaluateExpressionResult = (0, import_val
|
|
|
1627
1633
|
import_validatorPrimitives.scheme.FrameEvaluateExpressionHandleParams = (0, import_validatorPrimitives.tObject)({
|
|
1628
1634
|
expression: import_validatorPrimitives.tString,
|
|
1629
1635
|
isFunction: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tBoolean),
|
|
1630
|
-
arg: (0, import_validatorPrimitives.tType)("SerializedArgument")
|
|
1636
|
+
arg: (0, import_validatorPrimitives.tType)("SerializedArgument"),
|
|
1637
|
+
isolatedContext: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tBoolean)
|
|
1631
1638
|
});
|
|
1632
1639
|
import_validatorPrimitives.scheme.FrameEvaluateExpressionHandleResult = (0, import_validatorPrimitives.tObject)({
|
|
1633
1640
|
handle: (0, import_validatorPrimitives.tChannel)(["ElementHandle", "JSHandle"])
|
|
@@ -1911,7 +1918,8 @@ import_validatorPrimitives.scheme.WorkerCloseEvent = (0, import_validatorPrimiti
|
|
|
1911
1918
|
import_validatorPrimitives.scheme.WorkerEvaluateExpressionParams = (0, import_validatorPrimitives.tObject)({
|
|
1912
1919
|
expression: import_validatorPrimitives.tString,
|
|
1913
1920
|
isFunction: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tBoolean),
|
|
1914
|
-
arg: (0, import_validatorPrimitives.tType)("SerializedArgument")
|
|
1921
|
+
arg: (0, import_validatorPrimitives.tType)("SerializedArgument"),
|
|
1922
|
+
isolatedContext: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tBoolean)
|
|
1915
1923
|
});
|
|
1916
1924
|
import_validatorPrimitives.scheme.WorkerEvaluateExpressionResult = (0, import_validatorPrimitives.tObject)({
|
|
1917
1925
|
value: (0, import_validatorPrimitives.tType)("SerializedValue")
|
|
@@ -1919,7 +1927,8 @@ import_validatorPrimitives.scheme.WorkerEvaluateExpressionResult = (0, import_va
|
|
|
1919
1927
|
import_validatorPrimitives.scheme.WorkerEvaluateExpressionHandleParams = (0, import_validatorPrimitives.tObject)({
|
|
1920
1928
|
expression: import_validatorPrimitives.tString,
|
|
1921
1929
|
isFunction: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tBoolean),
|
|
1922
|
-
arg: (0, import_validatorPrimitives.tType)("SerializedArgument")
|
|
1930
|
+
arg: (0, import_validatorPrimitives.tType)("SerializedArgument"),
|
|
1931
|
+
isolatedContext: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tBoolean)
|
|
1923
1932
|
});
|
|
1924
1933
|
import_validatorPrimitives.scheme.WorkerEvaluateExpressionHandleResult = (0, import_validatorPrimitives.tObject)({
|
|
1925
1934
|
handle: (0, import_validatorPrimitives.tChannel)(["ElementHandle", "JSHandle"])
|
|
@@ -1943,7 +1952,8 @@ import_validatorPrimitives.scheme.ElementHandleDisposeResult = (0, import_valida
|
|
|
1943
1952
|
import_validatorPrimitives.scheme.JSHandleEvaluateExpressionParams = (0, import_validatorPrimitives.tObject)({
|
|
1944
1953
|
expression: import_validatorPrimitives.tString,
|
|
1945
1954
|
isFunction: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tBoolean),
|
|
1946
|
-
arg: (0, import_validatorPrimitives.tType)("SerializedArgument")
|
|
1955
|
+
arg: (0, import_validatorPrimitives.tType)("SerializedArgument"),
|
|
1956
|
+
isolatedContext: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tBoolean)
|
|
1947
1957
|
});
|
|
1948
1958
|
import_validatorPrimitives.scheme.ElementHandleEvaluateExpressionParams = (0, import_validatorPrimitives.tType)("JSHandleEvaluateExpressionParams");
|
|
1949
1959
|
import_validatorPrimitives.scheme.JSHandleEvaluateExpressionResult = (0, import_validatorPrimitives.tObject)({
|
|
@@ -1953,7 +1963,8 @@ import_validatorPrimitives.scheme.ElementHandleEvaluateExpressionResult = (0, im
|
|
|
1953
1963
|
import_validatorPrimitives.scheme.JSHandleEvaluateExpressionHandleParams = (0, import_validatorPrimitives.tObject)({
|
|
1954
1964
|
expression: import_validatorPrimitives.tString,
|
|
1955
1965
|
isFunction: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tBoolean),
|
|
1956
|
-
arg: (0, import_validatorPrimitives.tType)("SerializedArgument")
|
|
1966
|
+
arg: (0, import_validatorPrimitives.tType)("SerializedArgument"),
|
|
1967
|
+
isolatedContext: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tBoolean)
|
|
1957
1968
|
});
|
|
1958
1969
|
import_validatorPrimitives.scheme.ElementHandleEvaluateExpressionHandleParams = (0, import_validatorPrimitives.tType)("JSHandleEvaluateExpressionHandleParams");
|
|
1959
1970
|
import_validatorPrimitives.scheme.JSHandleEvaluateExpressionHandleResult = (0, import_validatorPrimitives.tObject)({
|
|
@@ -2778,6 +2789,7 @@ import_validatorPrimitives.scheme.AndroidDeviceLaunchBrowserParams = (0, import_
|
|
|
2778
2789
|
serviceWorkers: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tEnum)(["allow", "block"])),
|
|
2779
2790
|
selectorEngines: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)((0, import_validatorPrimitives.tType)("SelectorEngine"))),
|
|
2780
2791
|
testIdAttributeName: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
2792
|
+
focusControl: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tBoolean),
|
|
2781
2793
|
pkg: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
|
|
2782
2794
|
args: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)(import_validatorPrimitives.tString)),
|
|
2783
2795
|
proxy: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tObject)({
|
|
@@ -126,9 +126,7 @@ class BrowserContext extends import_instrumentation.SdkObject {
|
|
|
126
126
|
`);
|
|
127
127
|
}
|
|
128
128
|
if (this._options.serviceWorkers === "block")
|
|
129
|
-
await this.addInitScript(void 0, `
|
|
130
|
-
if (navigator.serviceWorker) navigator.serviceWorker.register = async () => { console.warn('Service Worker registration blocked by Playwright'); };
|
|
131
|
-
`);
|
|
129
|
+
await this.addInitScript(void 0, `navigator.serviceWorker.register = async () => { };`);
|
|
132
130
|
if (this._options.permissions)
|
|
133
131
|
await this.grantPermissions(this._options.permissions);
|
|
134
132
|
}
|
|
@@ -249,27 +247,16 @@ if (navigator.serviceWorker) navigator.serviceWorker.register = async () => { co
|
|
|
249
247
|
if (page.getBinding(name))
|
|
250
248
|
throw new Error(`Function "${name}" has been already registered in one of the pages`);
|
|
251
249
|
}
|
|
252
|
-
await progress.race(this.exposePlaywrightBindingIfNeeded());
|
|
253
250
|
const binding = new import_page2.PageBinding(name, playwrightBinding, needsHandle);
|
|
254
251
|
binding.forClient = forClient;
|
|
255
252
|
this._pageBindings.set(name, binding);
|
|
256
|
-
|
|
257
|
-
await progress.race(this.doAddInitScript(binding.initScript));
|
|
258
|
-
await progress.race(this.safeNonStallingEvaluateInAllFrames(binding.initScript.source, "main"));
|
|
259
|
-
return binding;
|
|
260
|
-
} catch (error) {
|
|
261
|
-
this._pageBindings.delete(name);
|
|
262
|
-
throw error;
|
|
263
|
-
}
|
|
253
|
+
await this.doExposeBinding(binding);
|
|
264
254
|
}
|
|
265
255
|
async removeExposedBindings(bindings) {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
await this.
|
|
270
|
-
const cleanup = bindings.map((binding) => `{ ${binding.cleanupScript} };
|
|
271
|
-
`).join("");
|
|
272
|
-
await this.safeNonStallingEvaluateInAllFrames(cleanup, "main");
|
|
256
|
+
for (const key of this._pageBindings.keys()) {
|
|
257
|
+
if (!key.startsWith("__pw")) this._pageBindings.delete(key);
|
|
258
|
+
}
|
|
259
|
+
await this.doRemoveExposedBindings();
|
|
273
260
|
}
|
|
274
261
|
async grantPermissions(permissions, origin) {
|
|
275
262
|
let resolvedOrigin = "*";
|
|
@@ -372,9 +359,8 @@ if (navigator.serviceWorker) navigator.serviceWorker.register = async () => { co
|
|
|
372
359
|
}
|
|
373
360
|
}
|
|
374
361
|
async removeInitScripts(initScripts) {
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
await this.doRemoveInitScripts(initScripts);
|
|
362
|
+
this.initScripts.splice(0, this.initScripts.length);
|
|
363
|
+
await this.doRemoveInitScripts();
|
|
378
364
|
}
|
|
379
365
|
async addRequestInterceptor(progress, handler) {
|
|
380
366
|
this.requestInterceptors.push(handler);
|
|
@@ -683,7 +669,8 @@ const defaultNewContextParamValues = {
|
|
|
683
669
|
acceptDownloads: "accept",
|
|
684
670
|
strictSelectors: false,
|
|
685
671
|
serviceWorkers: "allow",
|
|
686
|
-
locale: "en-US"
|
|
672
|
+
locale: "en-US",
|
|
673
|
+
focusControl: false
|
|
687
674
|
};
|
|
688
675
|
// Annotate the CommonJS export names for ESM import in node:
|
|
689
676
|
0 && (module.exports = {
|
|
@@ -56,27 +56,17 @@ const chromiumSwitches = (assistantMode, channel, android) => [
|
|
|
56
56
|
"--disable-background-networking",
|
|
57
57
|
"--disable-background-timer-throttling",
|
|
58
58
|
"--disable-backgrounding-occluded-windows",
|
|
59
|
-
"--disable-back-forward-cache",
|
|
60
59
|
// Avoids surprises like main request not being intercepted during page.goBack().
|
|
61
60
|
"--disable-breakpad",
|
|
62
|
-
"--disable-client-side-phishing-detection",
|
|
63
|
-
"--disable-component-extensions-with-background-pages",
|
|
64
|
-
"--disable-component-update",
|
|
65
61
|
// Avoids unneeded network activity after startup.
|
|
66
62
|
"--no-default-browser-check",
|
|
67
|
-
"--disable-default-apps",
|
|
68
63
|
"--disable-dev-shm-usage",
|
|
69
|
-
"--disable-extensions",
|
|
70
64
|
"--disable-features=" + disabledFeatures(assistantMode).join(","),
|
|
71
65
|
process.env.PLAYWRIGHT_LEGACY_SCREENSHOT ? "" : "--enable-features=CDPScreenshotNewSurface",
|
|
72
|
-
"--allow-pre-commit-input",
|
|
73
66
|
"--disable-hang-monitor",
|
|
74
|
-
"--disable-ipc-flooding-protection",
|
|
75
|
-
"--disable-popup-blocking",
|
|
76
67
|
"--disable-prompt-on-repost",
|
|
77
68
|
"--disable-renderer-backgrounding",
|
|
78
69
|
"--force-color-profile=srgb",
|
|
79
|
-
"--metrics-recording-only",
|
|
80
70
|
"--no-first-run",
|
|
81
71
|
"--password-store=basic",
|
|
82
72
|
"--use-mock-keychain",
|
|
@@ -85,18 +75,16 @@ const chromiumSwitches = (assistantMode, channel, android) => [
|
|
|
85
75
|
"--export-tagged-pdf",
|
|
86
76
|
// https://chromium-review.googlesource.com/c/chromium/src/+/4853540
|
|
87
77
|
"--disable-search-engine-choice-screen",
|
|
88
|
-
// https://issues.chromium.org/41491762
|
|
89
|
-
"--unsafely-disable-devtools-self-xss-warnings",
|
|
90
78
|
// Edge can potentially restart on Windows (msRelaunchNoCompatLayer) which looses its file descriptors (stdout/stderr) and CDP (3/4). Disable until fixed upstream.
|
|
91
79
|
"--edge-skip-compat-layer-relaunch",
|
|
92
|
-
assistantMode ? "" : "--enable-automation",
|
|
93
80
|
// This disables Chrome for Testing infobar that is visible in the persistent context.
|
|
94
81
|
// The switch is ignored everywhere else, including Chromium/Chrome/Edge.
|
|
95
82
|
"--disable-infobars",
|
|
96
83
|
// Less annoying popups.
|
|
97
84
|
"--disable-search-engine-choice-screen",
|
|
98
85
|
// Prevents the "three dots" menu crash in IdentityManager::HasPrimaryAccount for ephemeral contexts.
|
|
99
|
-
android ? "" : "--disable-sync"
|
|
86
|
+
android ? "" : "--disable-sync",
|
|
87
|
+
"--disable-blink-features=AutomationControlled"
|
|
100
88
|
].filter(Boolean);
|
|
101
89
|
// Annotate the CommonJS export names for ESM import in node:
|
|
102
90
|
0 && (module.exports = {
|
|
@@ -436,8 +436,7 @@ class CRBrowserContext extends import_browserContext.BrowserContext {
|
|
|
436
436
|
await page.delegate.addInitScript(initScript);
|
|
437
437
|
}
|
|
438
438
|
async doRemoveInitScripts(initScripts) {
|
|
439
|
-
for (const page of this.pages())
|
|
440
|
-
await page.delegate.removeInitScripts(initScripts);
|
|
439
|
+
for (const page of this.pages()) await page.delegate.removeInitScripts();
|
|
441
440
|
}
|
|
442
441
|
async doUpdateRequestInterception() {
|
|
443
442
|
for (const page of this.pages())
|
|
@@ -502,6 +501,12 @@ class CRBrowserContext extends import_browserContext.BrowserContext {
|
|
|
502
501
|
const rootSession = await this._browser._clientRootSession();
|
|
503
502
|
return rootSession.attachToTarget(targetId);
|
|
504
503
|
}
|
|
504
|
+
async doExposeBinding(binding) {
|
|
505
|
+
for (const page of this.pages()) await page.delegate.exposeBinding(binding);
|
|
506
|
+
}
|
|
507
|
+
async doRemoveExposedBindings() {
|
|
508
|
+
for (const page of this.pages()) await page.delegate.removeExposedBindings();
|
|
509
|
+
}
|
|
505
510
|
}
|
|
506
511
|
// Annotate the CommonJS export names for ESM import in node:
|
|
507
512
|
0 && (module.exports = {
|
|
@@ -72,7 +72,6 @@ class CRDevTools {
|
|
|
72
72
|
}).catch((e) => null);
|
|
73
73
|
});
|
|
74
74
|
Promise.all([
|
|
75
|
-
session.send("Runtime.enable"),
|
|
76
75
|
session.send("Runtime.addBinding", { name: kBindingName }),
|
|
77
76
|
session.send("Page.enable"),
|
|
78
77
|
session.send("Page.addScriptToEvaluateOnNewDocument", { source: `
|
|
@@ -31,6 +31,7 @@ __export(crNetworkManager_exports, {
|
|
|
31
31
|
CRNetworkManager: () => CRNetworkManager
|
|
32
32
|
});
|
|
33
33
|
module.exports = __toCommonJS(crNetworkManager_exports);
|
|
34
|
+
var import_crypto = __toESM(require("crypto"));
|
|
34
35
|
var import_utils = require("../../utils");
|
|
35
36
|
var import_eventsHelper = require("../utils/eventsHelper");
|
|
36
37
|
var import_helper = require("../helper");
|
|
@@ -49,6 +50,7 @@ class CRNetworkManager {
|
|
|
49
50
|
this._requestIdToRequestPausedEvent = /* @__PURE__ */ new Map();
|
|
50
51
|
this._responseExtraInfoTracker = new ResponseExtraInfoTracker();
|
|
51
52
|
this._sessions = /* @__PURE__ */ new Map();
|
|
53
|
+
this._alreadyTrackedNetworkIds = /* @__PURE__ */ new Set();
|
|
52
54
|
this._page = page;
|
|
53
55
|
this._serviceWorker = serviceWorker;
|
|
54
56
|
}
|
|
@@ -151,7 +153,7 @@ class CRNetworkManager {
|
|
|
151
153
|
const enabled = this._protocolRequestInterceptionEnabled;
|
|
152
154
|
if (initial && !enabled)
|
|
153
155
|
return;
|
|
154
|
-
const cachePromise = info.session.send("Network.setCacheDisabled", { cacheDisabled:
|
|
156
|
+
const cachePromise = info.session.send("Network.setCacheDisabled", { cacheDisabled: false });
|
|
155
157
|
let fetchPromise = Promise.resolve(void 0);
|
|
156
158
|
if (!info.workerFrame) {
|
|
157
159
|
if (enabled)
|
|
@@ -226,6 +228,7 @@ class CRNetworkManager {
|
|
|
226
228
|
return !this._credentials.origin || new URL(url).origin.toLowerCase() === this._credentials.origin.toLowerCase();
|
|
227
229
|
}
|
|
228
230
|
_onRequestPaused(sessionInfo, event) {
|
|
231
|
+
if (this._alreadyTrackedNetworkIds.has(event.networkId)) return;
|
|
229
232
|
if (!event.networkId) {
|
|
230
233
|
sessionInfo.session._sendMayFail("Fetch.continueRequest", { requestId: event.requestId });
|
|
231
234
|
return;
|
|
@@ -251,6 +254,7 @@ class CRNetworkManager {
|
|
|
251
254
|
}
|
|
252
255
|
}
|
|
253
256
|
_onRequest(requestWillBeSentSessionInfo, requestWillBeSentEvent, requestPausedSessionInfo, requestPausedEvent) {
|
|
257
|
+
if (this._alreadyTrackedNetworkIds.has(requestWillBeSentEvent.initiator.requestId)) return;
|
|
254
258
|
if (requestWillBeSentEvent.request.url.startsWith("data:"))
|
|
255
259
|
return;
|
|
256
260
|
let redirectedFrom = null;
|
|
@@ -298,7 +302,7 @@ class CRNetworkManager {
|
|
|
298
302
|
headersOverride = redirectedFrom?._originalRequestRoute?._alreadyContinuedParams?.headers;
|
|
299
303
|
requestPausedSessionInfo.session._sendMayFail("Fetch.continueRequest", { requestId: requestPausedEvent.requestId, headers: headersOverride });
|
|
300
304
|
} else {
|
|
301
|
-
route = new RouteImpl(requestPausedSessionInfo.session, requestPausedEvent.requestId);
|
|
305
|
+
route = new RouteImpl(requestPausedSessionInfo.session, requestPausedEvent.requestId, this._page, requestPausedEvent.networkId, this);
|
|
302
306
|
}
|
|
303
307
|
}
|
|
304
308
|
const isNavigationRequest = requestWillBeSentEvent.requestId === requestWillBeSentEvent.loaderId && requestWillBeSentEvent.type === "Document";
|
|
@@ -491,10 +495,17 @@ class InterceptableRequest {
|
|
|
491
495
|
}
|
|
492
496
|
}
|
|
493
497
|
class RouteImpl {
|
|
494
|
-
constructor(session, interceptionId) {
|
|
498
|
+
constructor(session, interceptionId, page, networkId, sessionManager) {
|
|
495
499
|
this._fulfilled = false;
|
|
500
|
+
this._sessionManager = void 0;
|
|
501
|
+
this._networkId = void 0;
|
|
502
|
+
this._page = void 0;
|
|
496
503
|
this._session = session;
|
|
497
504
|
this._interceptionId = interceptionId;
|
|
505
|
+
this._page = page;
|
|
506
|
+
this._networkId = networkId;
|
|
507
|
+
this._sessionManager = sessionManager;
|
|
508
|
+
import_eventsHelper.eventsHelper.addEventListener(this._session, "Fetch.requestPaused", async (e) => await this._networkRequestIntercepted(e));
|
|
498
509
|
}
|
|
499
510
|
async continue(overrides) {
|
|
500
511
|
this._alreadyContinuedParams = {
|
|
@@ -504,17 +515,134 @@ class RouteImpl {
|
|
|
504
515
|
method: overrides.method,
|
|
505
516
|
postData: overrides.postData ? overrides.postData.toString("base64") : void 0
|
|
506
517
|
};
|
|
507
|
-
|
|
508
|
-
await
|
|
509
|
-
|
|
518
|
+
if (overrides.url && (overrides.url === "http://patchright-init-script-inject.internal/" || overrides.url === "https://patchright-init-script-inject.internal/")) {
|
|
519
|
+
await catchDisallowedErrors(async () => {
|
|
520
|
+
this._sessionManager._alreadyTrackedNetworkIds.add(this._networkId);
|
|
521
|
+
this._session._sendMayFail("Fetch.continueRequest", { requestId: this._interceptionId, interceptResponse: true });
|
|
522
|
+
});
|
|
523
|
+
} else {
|
|
524
|
+
await catchDisallowedErrors(async () => {
|
|
525
|
+
await this._session._sendMayFail("Fetch.continueRequest", this._alreadyContinuedParams);
|
|
526
|
+
});
|
|
527
|
+
}
|
|
510
528
|
}
|
|
511
529
|
async fulfill(response) {
|
|
530
|
+
const isTextHtml = response.headers.some((header) => header.name.toLowerCase() === "content-type" && header.value.includes("text/html"));
|
|
531
|
+
var allInjections = [...this._page.delegate._mainFrameSession._evaluateOnNewDocumentScripts];
|
|
532
|
+
if (isTextHtml && allInjections.length) {
|
|
533
|
+
let useNonce = false;
|
|
534
|
+
let scriptNonce = null;
|
|
535
|
+
if (response.isBase64) {
|
|
536
|
+
response.isBase64 = false;
|
|
537
|
+
response.body = Buffer.from(response.body, "base64").toString("utf-8");
|
|
538
|
+
}
|
|
539
|
+
const cspHeaderNames = ["content-security-policy", "content-security-policy-report-only"];
|
|
540
|
+
for (let i = 0; i < response.headers.length; i++) {
|
|
541
|
+
const headerName = response.headers[i].name.toLowerCase();
|
|
542
|
+
if (cspHeaderNames.includes(headerName)) {
|
|
543
|
+
const originalCsp = response.headers[i].value || "";
|
|
544
|
+
if (!useNonce) {
|
|
545
|
+
const nonceMatch = originalCsp.match(/script-src[^;]*'nonce-([^'"\s;]+)'/i);
|
|
546
|
+
if (nonceMatch && nonceMatch[1]) {
|
|
547
|
+
scriptNonce = nonceMatch[1];
|
|
548
|
+
useNonce = true;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
const fixedCsp = this._fixCSP(originalCsp, scriptNonce);
|
|
552
|
+
response.headers[i].value = fixedCsp;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
if (typeof response.body === "string" && response.body.length) {
|
|
556
|
+
response.body = response.body.replace(
|
|
557
|
+
/<meta[^>]*http-equiv=(?:"|')?Content-Security-Policy(?:"|')?[^>]*>/gi,
|
|
558
|
+
(match) => {
|
|
559
|
+
const contentMatch = match.match(/content=(?:"|')([^"']*)(?:"|')/i);
|
|
560
|
+
if (contentMatch && contentMatch[1]) {
|
|
561
|
+
let originalCsp = contentMatch[1];
|
|
562
|
+
originalCsp = originalCsp.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/"/g, '"').replace(/ /g, " ").replace(/&#(d+);/g, (match2, dec) => String.fromCharCode(dec)).replace(/&#x([0-9a-fA-F]+);/g, (match2, hex) => String.fromCharCode(parseInt(hex, 16)));
|
|
563
|
+
if (!useNonce) {
|
|
564
|
+
const nonceMatch = originalCsp.match(/script-src[^;]*'nonce-([^'"\s;]+)'/i);
|
|
565
|
+
if (nonceMatch && nonceMatch[1]) {
|
|
566
|
+
scriptNonce = nonceMatch[1];
|
|
567
|
+
useNonce = true;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
const fixedCsp = this._fixCSP(originalCsp, scriptNonce);
|
|
571
|
+
const encodedCsp = fixedCsp.replace(/'/g, "'").replace(/"/g, """);
|
|
572
|
+
return match.replace(contentMatch[1], encodedCsp);
|
|
573
|
+
}
|
|
574
|
+
return match;
|
|
575
|
+
}
|
|
576
|
+
);
|
|
577
|
+
}
|
|
578
|
+
let injectionHTML = "";
|
|
579
|
+
allInjections.forEach((script) => {
|
|
580
|
+
let scriptId = import_crypto.default.randomBytes(22).toString("hex");
|
|
581
|
+
let scriptSource = script.source || script;
|
|
582
|
+
const nonceAttr = useNonce ? `nonce="${scriptNonce}"` : "";
|
|
583
|
+
injectionHTML += `<script class="${this._page.delegate.initScriptTag}" ${nonceAttr} id="${scriptId}" type="text/javascript">document.getElementById("${scriptId}")?.remove();${scriptSource}</script>`;
|
|
584
|
+
});
|
|
585
|
+
const lower = response.body.toLowerCase();
|
|
586
|
+
const headStartIndex = lower.indexOf("<head");
|
|
587
|
+
if (headStartIndex !== -1) {
|
|
588
|
+
const headEndTagIndex = lower.indexOf("</head>", headStartIndex);
|
|
589
|
+
if (headEndTagIndex !== -1) {
|
|
590
|
+
const headOpenEnd = response.body.indexOf(">", headStartIndex) + 1;
|
|
591
|
+
const headContent = response.body.slice(headOpenEnd, headEndTagIndex);
|
|
592
|
+
const headContentLower = headContent.toLowerCase();
|
|
593
|
+
let firstScriptIndex = -1;
|
|
594
|
+
let searchPos = 0;
|
|
595
|
+
const endSearchPos = headContentLower.length;
|
|
596
|
+
while (searchPos < endSearchPos) {
|
|
597
|
+
const commentStart = headContentLower.indexOf("<!--", searchPos);
|
|
598
|
+
const scriptStart = headContentLower.indexOf("<script", searchPos);
|
|
599
|
+
if (scriptStart === -1 || scriptStart >= endSearchPos) {
|
|
600
|
+
break;
|
|
601
|
+
}
|
|
602
|
+
if (commentStart !== -1 && commentStart < scriptStart) {
|
|
603
|
+
const commentEnd = headContentLower.indexOf("-->", commentStart);
|
|
604
|
+
if (commentEnd !== -1) {
|
|
605
|
+
searchPos = commentEnd + 3;
|
|
606
|
+
continue;
|
|
607
|
+
} else {
|
|
608
|
+
break;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
firstScriptIndex = scriptStart;
|
|
612
|
+
break;
|
|
613
|
+
}
|
|
614
|
+
if (firstScriptIndex !== -1) {
|
|
615
|
+
const insertPosition = headOpenEnd + firstScriptIndex;
|
|
616
|
+
response.body = response.body.slice(0, insertPosition) + injectionHTML + response.body.slice(insertPosition);
|
|
617
|
+
} else {
|
|
618
|
+
response.body = response.body.slice(0, headEndTagIndex) + injectionHTML + response.body.slice(headEndTagIndex);
|
|
619
|
+
}
|
|
620
|
+
} else {
|
|
621
|
+
const headStartTagEnd = response.body.indexOf(">", headStartIndex) + 1;
|
|
622
|
+
response.body = response.body.slice(0, headStartTagEnd) + injectionHTML + response.body.slice(headStartTagEnd);
|
|
623
|
+
}
|
|
624
|
+
} else {
|
|
625
|
+
const doctypeIndex = lower.indexOf("<!doctype");
|
|
626
|
+
if (doctypeIndex === 0) {
|
|
627
|
+
const doctypeEnd = response.body.indexOf(">", doctypeIndex) + 1;
|
|
628
|
+
response.body = response.body.slice(0, doctypeEnd) + injectionHTML + response.body.slice(doctypeEnd);
|
|
629
|
+
} else {
|
|
630
|
+
const htmlIndex = lower.indexOf("<html");
|
|
631
|
+
if (htmlIndex !== -1) {
|
|
632
|
+
const htmlTagEnd = response.body.indexOf(">", htmlIndex) + 1;
|
|
633
|
+
response.body = response.body.slice(0, htmlTagEnd) + `<head>${injectionHTML}</head>` + response.body.slice(htmlTagEnd);
|
|
634
|
+
} else {
|
|
635
|
+
response.body = injectionHTML + response.body;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
}
|
|
512
640
|
this._fulfilled = true;
|
|
513
641
|
const body = response.isBase64 ? response.body : Buffer.from(response.body).toString("base64");
|
|
514
642
|
const responseHeaders = splitSetCookieHeader(response.headers);
|
|
515
643
|
await catchDisallowedErrors(async () => {
|
|
516
644
|
await this._session.send("Fetch.fulfillRequest", {
|
|
517
|
-
requestId: this._interceptionId,
|
|
645
|
+
requestId: response.interceptionId ? response.interceptionId : this._interceptionId,
|
|
518
646
|
responseCode: response.status,
|
|
519
647
|
responsePhrase: network.statusText(response.status),
|
|
520
648
|
responseHeaders,
|
|
@@ -532,6 +660,117 @@ class RouteImpl {
|
|
|
532
660
|
});
|
|
533
661
|
});
|
|
534
662
|
}
|
|
663
|
+
_fixCSP(csp, scriptNonce) {
|
|
664
|
+
if (!csp || typeof csp !== "string") return csp;
|
|
665
|
+
const directives = csp.split(";").map((d) => d.trim()).filter((d) => d && d.length > 0);
|
|
666
|
+
const fixedDirectives = [];
|
|
667
|
+
let hasScriptSrc = false;
|
|
668
|
+
for (let directive of directives) {
|
|
669
|
+
if (!directive.trim()) continue;
|
|
670
|
+
const directiveMatch = directive.match(/^([a-zA-Z-]+)\s+(.*)$/);
|
|
671
|
+
if (!directiveMatch) {
|
|
672
|
+
fixedDirectives.push(directive);
|
|
673
|
+
continue;
|
|
674
|
+
}
|
|
675
|
+
const directiveName = directiveMatch[1].toLowerCase();
|
|
676
|
+
const directiveValues = directiveMatch[2].split(/\s+/).filter((v) => v.length > 0);
|
|
677
|
+
switch (directiveName) {
|
|
678
|
+
case "script-src":
|
|
679
|
+
hasScriptSrc = true;
|
|
680
|
+
let values = [...directiveValues];
|
|
681
|
+
if (scriptNonce && !values.some((v) => v.includes(`nonce-${scriptNonce}`))) {
|
|
682
|
+
values.push(`'nonce-${scriptNonce}'`);
|
|
683
|
+
}
|
|
684
|
+
if (!values.includes("'unsafe-eval'")) {
|
|
685
|
+
values.push("'unsafe-eval'");
|
|
686
|
+
}
|
|
687
|
+
if (!values.includes("'unsafe-inline'") && !scriptNonce) {
|
|
688
|
+
values.push("'unsafe-inline'");
|
|
689
|
+
}
|
|
690
|
+
if (!values.includes("*") && !values.includes("'self'") && !values.some((v) => v.includes("https:"))) {
|
|
691
|
+
values.push("*");
|
|
692
|
+
}
|
|
693
|
+
fixedDirectives.push(`script-src ${values.join(" ")}`);
|
|
694
|
+
break;
|
|
695
|
+
case "style-src":
|
|
696
|
+
let styleValues = [...directiveValues];
|
|
697
|
+
if (!styleValues.includes("'unsafe-inline'")) {
|
|
698
|
+
styleValues.push("'unsafe-inline'");
|
|
699
|
+
}
|
|
700
|
+
fixedDirectives.push(`style-src ${styleValues.join(" ")}`);
|
|
701
|
+
break;
|
|
702
|
+
case "img-src":
|
|
703
|
+
let imgValues = [...directiveValues];
|
|
704
|
+
if (!imgValues.includes("data:") && !imgValues.includes("*")) {
|
|
705
|
+
imgValues.push("data:");
|
|
706
|
+
}
|
|
707
|
+
fixedDirectives.push(`img-src ${imgValues.join(" ")}`);
|
|
708
|
+
break;
|
|
709
|
+
case "font-src":
|
|
710
|
+
let fontValues = [...directiveValues];
|
|
711
|
+
if (!fontValues.includes("data:") && !fontValues.includes("*")) {
|
|
712
|
+
fontValues.push("data:");
|
|
713
|
+
}
|
|
714
|
+
fixedDirectives.push(`font-src ${fontValues.join(" ")}`);
|
|
715
|
+
break;
|
|
716
|
+
case "connect-src":
|
|
717
|
+
let connectValues = [...directiveValues];
|
|
718
|
+
const hasWs = connectValues.some((v) => v.includes("ws:") || v.includes("wss:") || v === "*");
|
|
719
|
+
if (!hasWs) {
|
|
720
|
+
connectValues.push("ws:", "wss:");
|
|
721
|
+
}
|
|
722
|
+
fixedDirectives.push(`connect-src ${connectValues.join(" ")}`);
|
|
723
|
+
break;
|
|
724
|
+
case "frame-ancestors":
|
|
725
|
+
let frameAncestorValues = [...directiveValues];
|
|
726
|
+
if (frameAncestorValues.includes("'none'")) {
|
|
727
|
+
frameAncestorValues = ["'self'"];
|
|
728
|
+
}
|
|
729
|
+
fixedDirectives.push(`frame-ancestors ${frameAncestorValues.join(" ")}`);
|
|
730
|
+
break;
|
|
731
|
+
default:
|
|
732
|
+
fixedDirectives.push(directive);
|
|
733
|
+
break;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
if (!hasScriptSrc) {
|
|
737
|
+
if (scriptNonce) {
|
|
738
|
+
fixedDirectives.push(`script-src 'self' 'unsafe-eval' 'nonce-${scriptNonce}' *`);
|
|
739
|
+
} else {
|
|
740
|
+
fixedDirectives.push(`script-src 'self' 'unsafe-eval' 'unsafe-inline' *`);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
return fixedDirectives.join("; ");
|
|
744
|
+
}
|
|
745
|
+
async _networkRequestIntercepted(event) {
|
|
746
|
+
if (event.resourceType !== "Document") {
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
if (this._networkId != event.networkId || !this._sessionManager._alreadyTrackedNetworkIds.has(event.networkId)) return;
|
|
750
|
+
try {
|
|
751
|
+
const url = event.request?.url || "";
|
|
752
|
+
const isPrivilegePage = url.startsWith("https://ntp.msn");
|
|
753
|
+
if (isPrivilegePage) {
|
|
754
|
+
await this._session._sendMayFail("Fetch.continueRequest", { requestId: event.requestId });
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
if (event.responseStatusCode >= 301 && event.responseStatusCode <= 308 || event.redirectedRequestId && !event.responseStatusCode) {
|
|
758
|
+
await this._session.send("Fetch.continueRequest", { requestId: event.requestId, interceptResponse: true });
|
|
759
|
+
} else {
|
|
760
|
+
const responseBody = await this._session.send("Fetch.getResponseBody", { requestId: event.requestId });
|
|
761
|
+
await this.fulfill({
|
|
762
|
+
headers: event.responseHeaders,
|
|
763
|
+
isBase64: true,
|
|
764
|
+
body: responseBody.body,
|
|
765
|
+
status: event.responseStatusCode,
|
|
766
|
+
interceptionId: event.requestId,
|
|
767
|
+
resourceType: event.resourceType
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
} catch (error) {
|
|
771
|
+
await this._session._sendMayFail("Fetch.continueRequest", { requestId: event.requestId });
|
|
772
|
+
}
|
|
773
|
+
}
|
|
535
774
|
}
|
|
536
775
|
async function catchDisallowedErrors(callback) {
|
|
537
776
|
try {
|