patchright-core 1.56.1 → 1.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/ThirdPartyNotices.txt +40 -381
  2. package/bin/install_webkit_wsl.ps1 +1 -3
  3. package/browsers.json +13 -13
  4. package/lib/cli/program.js +14 -57
  5. package/lib/client/api.js +0 -3
  6. package/lib/client/browserContext.js +22 -4
  7. package/lib/client/consoleMessage.js +5 -1
  8. package/lib/client/electron.js +1 -1
  9. package/lib/client/events.js +2 -1
  10. package/lib/client/locator.js +4 -1
  11. package/lib/client/page.js +2 -5
  12. package/lib/client/playwright.js +1 -5
  13. package/lib/client/tracing.js +6 -4
  14. package/lib/client/worker.js +22 -0
  15. package/lib/generated/clockSource.js +1 -1
  16. package/lib/generated/injectedScriptSource.js +1 -1
  17. package/lib/generated/pollingRecorderSource.js +1 -1
  18. package/lib/inProcessFactory.js +0 -2
  19. package/lib/protocol/validator.js +24 -46
  20. package/lib/server/android/android.js +1 -1
  21. package/lib/server/bidi/bidiBrowser.js +26 -11
  22. package/lib/server/bidi/bidiChromium.js +1 -1
  23. package/lib/server/bidi/bidiFirefox.js +1 -1
  24. package/lib/server/bidi/bidiPage.js +25 -5
  25. package/lib/server/browserContext.js +9 -10
  26. package/lib/server/chromium/chromium.js +12 -1
  27. package/lib/server/chromium/chromiumSwitches.js +10 -1
  28. package/lib/server/chromium/crBrowser.js +8 -0
  29. package/lib/server/chromium/crNetworkManager.js +15 -6
  30. package/lib/server/chromium/crPage.js +7 -9
  31. package/lib/server/chromium/crServiceWorker.js +14 -1
  32. package/lib/server/chromium/videoRecorder.js +14 -12
  33. package/lib/server/console.js +5 -1
  34. package/lib/server/deviceDescriptorsSource.json +56 -56
  35. package/lib/server/dispatchers/browserContextDispatcher.js +23 -6
  36. package/lib/server/dispatchers/pageDispatcher.js +10 -22
  37. package/lib/server/dispatchers/playwrightDispatcher.js +0 -4
  38. package/lib/server/electron/electron.js +1 -1
  39. package/lib/server/firefox/ffPage.js +3 -6
  40. package/lib/server/firefox/firefox.js +12 -1
  41. package/lib/server/frameSelectors.js +2 -4
  42. package/lib/server/frames.js +6 -1
  43. package/lib/server/input.js +7 -3
  44. package/lib/server/localUtils.js +4 -8
  45. package/lib/server/page.js +54 -38
  46. package/lib/server/playwright.js +2 -4
  47. package/lib/server/recorder/recorderApp.js +1 -1
  48. package/lib/server/recorder.js +3 -2
  49. package/lib/server/registry/index.js +114 -48
  50. package/lib/server/registry/oopDownloadBrowserMain.js +6 -2
  51. package/lib/server/socksClientCertificatesInterceptor.js +1 -1
  52. package/lib/server/trace/recorder/tracing.js +2 -0
  53. package/lib/server/trace/viewer/traceViewer.js +37 -36
  54. package/lib/server/utils/comparators.js +3 -25
  55. package/lib/server/utils/hostPlatform.js +15 -3
  56. package/lib/server/utils/imageUtils.js +141 -0
  57. package/lib/server/utils/network.js +22 -16
  58. package/lib/server/webkit/webkit.js +1 -10
  59. package/lib/server/webkit/wkPage.js +1 -5
  60. package/lib/server/webkit/wkWorkers.js +2 -1
  61. package/lib/utils/isomorphic/ariaSnapshot.js +5 -0
  62. package/lib/utils/isomorphic/locatorGenerators.js +24 -8
  63. package/lib/utils/isomorphic/mimeType.js +1 -1
  64. package/lib/utils/isomorphic/protocolFormatter.js +3 -0
  65. package/lib/utils/isomorphic/protocolMetainfo.js +2 -1
  66. package/lib/utils/isomorphic/urlMatch.js +19 -5
  67. package/lib/utils.js +2 -0
  68. package/lib/utilsBundle.js +6 -3
  69. package/lib/utilsBundleImpl/index.js +171 -171
  70. package/lib/vite/htmlReport/index.html +18 -18
  71. package/lib/vite/recorder/assets/codeMirrorModule-CBbSe-ZI.js +25 -0
  72. package/lib/vite/recorder/assets/{index-Y-X2TGJv.js → index-CpZVd2nA.js} +32 -32
  73. package/lib/vite/recorder/index.html +1 -1
  74. package/lib/vite/traceViewer/assets/codeMirrorModule-DHz0wP2C.js +25 -0
  75. package/lib/vite/traceViewer/assets/defaultSettingsView-WsZP88O6.js +266 -0
  76. package/lib/vite/traceViewer/defaultSettingsView.ConWv5KN.css +1 -0
  77. package/lib/vite/traceViewer/index.C4Y3Aw8n.css +1 -0
  78. package/lib/vite/traceViewer/index.C8xAeo93.js +2 -0
  79. package/lib/vite/traceViewer/index.html +6 -6
  80. package/lib/vite/traceViewer/manifest.webmanifest +16 -0
  81. package/lib/vite/traceViewer/snapshot.html +3 -3
  82. package/lib/vite/traceViewer/sw.bundle.js +3 -3
  83. package/lib/vite/traceViewer/{uiMode.B_CpmIpF.js → uiMode.BltraIJB.js} +3 -3
  84. package/lib/vite/traceViewer/uiMode.html +3 -3
  85. package/package.json +1 -1
  86. package/types/protocol.d.ts +213 -98
  87. package/types/types.d.ts +120 -117
  88. package/lib/client/accessibility.js +0 -49
  89. package/lib/server/accessibility.js +0 -69
  90. package/lib/server/chromium/crAccessibility.js +0 -263
  91. package/lib/server/firefox/ffAccessibility.js +0 -238
  92. package/lib/server/webkit/wkAccessibility.js +0 -237
  93. package/lib/server/webkit/wsl/webkit-wsl-transport-client.js +0 -74
  94. package/lib/server/webkit/wsl/webkit-wsl-transport-server.js +0 -113
  95. package/lib/vite/recorder/assets/codeMirrorModule-RJCXzfmE.js +0 -24
  96. package/lib/vite/traceViewer/assets/codeMirrorModule-rbQPefq7.js +0 -24
  97. package/lib/vite/traceViewer/assets/defaultSettingsView-CLbol9XR.js +0 -265
  98. package/lib/vite/traceViewer/defaultSettingsView.TQ8_7ybu.css +0 -1
  99. package/lib/vite/traceViewer/index.I8N9v4jT.css +0 -1
  100. package/lib/vite/traceViewer/index.zIVi6mN9.js +0 -2
@@ -62,12 +62,16 @@ class BidiBrowser extends import_browser.Browser {
62
62
  browser._bidiSessionInfo = await browser._browserSession.send("session.new", {
63
63
  capabilities: {
64
64
  alwaysMatch: {
65
- acceptInsecureCerts: options.persistent?.internalIgnoreHTTPSErrors || options.persistent?.ignoreHTTPSErrors,
66
- proxy: getProxyConfiguration(options.originalLaunchOptions.proxyOverride ?? options.proxy),
67
- unhandledPromptBehavior: {
65
+ "acceptInsecureCerts": options.persistent?.internalIgnoreHTTPSErrors || options.persistent?.ignoreHTTPSErrors,
66
+ "proxy": getProxyConfiguration(options.originalLaunchOptions.proxyOverride ?? options.proxy),
67
+ "unhandledPromptBehavior": {
68
68
  default: bidi.Session.UserPromptHandlerType.Ignore
69
69
  },
70
- webSocketUrl: true
70
+ "webSocketUrl": true,
71
+ // Chrome with WebDriver BiDi does not support prerendering
72
+ // yet because WebDriver BiDi behavior is not specified. See
73
+ // https://github.com/w3c/webdriver-bidi/issues/321.
74
+ "goog:prerenderingDisabled": true
71
75
  }
72
76
  }
73
77
  });
@@ -76,7 +80,8 @@ class BidiBrowser extends import_browser.Browser {
76
80
  "browsingContext",
77
81
  "network",
78
82
  "log",
79
- "script"
83
+ "script",
84
+ "input"
80
85
  ]
81
86
  });
82
87
  await browser._browserSession.send("network.addDataCollector", {
@@ -122,16 +127,13 @@ class BidiBrowser extends import_browser.Browser {
122
127
  _onBrowsingContextCreated(event) {
123
128
  if (event.parent) {
124
129
  const parentFrameId = event.parent;
125
- for (const page2 of this._bidiPages.values()) {
126
- const parentFrame = page2._page.frameManager.frame(parentFrameId);
127
- if (!parentFrame)
128
- continue;
130
+ const page2 = this._findPageForFrame(parentFrameId);
131
+ if (page2) {
129
132
  page2._session.addFrameBrowsingContext(event.context);
130
133
  page2._page.frameManager.frameAttached(event.context, parentFrameId);
131
134
  const frame = page2._page.frameManager.frame(event.context);
132
135
  if (frame)
133
136
  frame._url = event.url;
134
- return;
135
137
  }
136
138
  return;
137
139
  }
@@ -141,7 +143,7 @@ class BidiBrowser extends import_browser.Browser {
141
143
  if (!context)
142
144
  return;
143
145
  const session = this._connection.createMainFrameBrowsingContextSession(event.context);
144
- const opener = event.originalOpener && this._bidiPages.get(event.originalOpener);
146
+ const opener = event.originalOpener && this._findPageForFrame(event.originalOpener);
145
147
  const page = new import_bidiPage.BidiPage(context, session, opener || null);
146
148
  page._page.mainFrame()._url = event.url;
147
149
  this._bidiPages.set(event.context, page);
@@ -171,6 +173,12 @@ class BidiBrowser extends import_browser.Browser {
171
173
  return;
172
174
  }
173
175
  }
176
+ _findPageForFrame(frameId) {
177
+ for (const page of this._bidiPages.values()) {
178
+ if (page._page.frameManager.frame(frameId))
179
+ return page;
180
+ }
181
+ }
174
182
  }
175
183
  class BidiBrowserContext extends import_browserContext.BrowserContext {
176
184
  constructor(browser, browserContextId, options) {
@@ -207,6 +215,8 @@ class BidiBrowserContext extends import_browserContext.BrowserContext {
207
215
  userContexts: [this._userContextId()]
208
216
  }));
209
217
  }
218
+ if (this._options.extraHTTPHeaders)
219
+ promises.push(this.doUpdateExtraHTTPHeaders());
210
220
  await Promise.all(promises);
211
221
  }
212
222
  possiblyUninitializedPages() {
@@ -300,6 +310,11 @@ class BidiBrowserContext extends import_browserContext.BrowserContext {
300
310
  });
301
311
  }
302
312
  async doUpdateExtraHTTPHeaders() {
313
+ const allHeaders = this._options.extraHTTPHeaders || [];
314
+ await this._browser._browserSession.send("network.setExtraHeaders", {
315
+ headers: allHeaders.map(({ name, value }) => ({ name, value: { type: "string", value } })),
316
+ userContexts: [this._userContextId()]
317
+ });
303
318
  }
304
319
  async setUserAgent(userAgent) {
305
320
  this._options.userAgent = userAgent;
@@ -40,7 +40,7 @@ var import_chromiumSwitches = require("../chromium/chromiumSwitches");
40
40
  var import_chromium = require("../chromium/chromium");
41
41
  class BidiChromium extends import_browserType.BrowserType {
42
42
  constructor(parent) {
43
- super(parent, "_bidiChromium");
43
+ super(parent, "chromium");
44
44
  }
45
45
  async connectToTransport(transport, options, browserLogsCollector) {
46
46
  const bidiTransport = await require("./bidiOverCdp").connectBidiOverCdp(transport);
@@ -41,7 +41,7 @@ var import_firefoxPrefs = require("./third_party/firefoxPrefs");
41
41
  var import_manualPromise = require("../../utils/isomorphic/manualPromise");
42
42
  class BidiFirefox extends import_browserType.BrowserType {
43
43
  constructor(parent) {
44
- super(parent, "_bidiFirefox");
44
+ super(parent, "firefox");
45
45
  }
46
46
  executablePath() {
47
47
  return "";
@@ -42,6 +42,7 @@ var import_bidiInput = require("./bidiInput");
42
42
  var import_bidiNetworkManager = require("./bidiNetworkManager");
43
43
  var import_bidiPdf = require("./bidiPdf");
44
44
  var bidi = __toESM(require("./third_party/bidiProtocol"));
45
+ var network = __toESM(require("../network"));
45
46
  const UTILITY_WORLD_NAME = "__playwright_utility_world__";
46
47
  const kPlaywrightBindingChannel = "playwrightChannel";
47
48
  class BidiPage {
@@ -75,7 +76,8 @@ class BidiPage {
75
76
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.downloadWillBegin", this._onDownloadWillBegin.bind(this)),
76
77
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.downloadEnd", this._onDownloadEnded.bind(this)),
77
78
  import_eventsHelper.eventsHelper.addEventListener(bidiSession, "browsingContext.userPromptOpened", this._onUserPromptOpened.bind(this)),
78
- import_eventsHelper.eventsHelper.addEventListener(bidiSession, "log.entryAdded", this._onLogEntryAdded.bind(this))
79
+ import_eventsHelper.eventsHelper.addEventListener(bidiSession, "log.entryAdded", this._onLogEntryAdded.bind(this)),
80
+ import_eventsHelper.eventsHelper.addEventListener(bidiSession, "input.fileDialogOpened", this._onFileDialogOpened.bind(this))
79
81
  ];
80
82
  this._initialize().then(
81
83
  () => this._page.reportAsNew(this._opener?._page),
@@ -113,6 +115,7 @@ class BidiPage {
113
115
  const delegate2 = new import_bidiExecutionContext.BidiExecutionContext(this._session, realmInfo);
114
116
  const worker = new import_page.Worker(this._page, realmInfo.origin);
115
117
  this._realmToWorkerContext.set(realmInfo.realm, worker.createExecutionContext(delegate2));
118
+ worker.workerScriptLoaded();
116
119
  this._page.addWorker(realmInfo.realm, worker);
117
120
  return;
118
121
  }
@@ -260,7 +263,17 @@ ${params.stackTrace?.callFrames.map((f) => {
260
263
  return;
261
264
  const callFrame = params.stackTrace?.callFrames[0];
262
265
  const location = callFrame ?? { url: "", lineNumber: 1, columnNumber: 1 };
263
- this._page.addConsoleMessage(entry.method, entry.args.map((arg) => (0, import_bidiExecutionContext.createHandle)(context, arg)), location, params.text || void 0);
266
+ this._page.addConsoleMessage(null, entry.method, entry.args.map((arg) => (0, import_bidiExecutionContext.createHandle)(context, arg)), location, params.text || void 0);
267
+ }
268
+ async _onFileDialogOpened(params) {
269
+ if (!params.element)
270
+ return;
271
+ const frame = this._page.frameManager.frame(params.context);
272
+ if (!frame)
273
+ return;
274
+ const executionContext = await frame._mainContext();
275
+ const handle = await toBidiExecutionContext(executionContext).remoteObjectForNodeId(executionContext, { sharedId: params.element.sharedId });
276
+ await this._page._onFileChooserOpened(handle);
264
277
  }
265
278
  async navigateFrame(frame, url, referrer) {
266
279
  const { navigation } = await this._session.send("browsingContext.navigate", {
@@ -270,6 +283,14 @@ ${params.stackTrace?.callFrames.map((f) => {
270
283
  return { newDocumentId: navigation || void 0 };
271
284
  }
272
285
  async updateExtraHTTPHeaders() {
286
+ const allHeaders = network.mergeHeaders([
287
+ this._browserContext._options.extraHTTPHeaders,
288
+ this._page.extraHTTPHeaders()
289
+ ]);
290
+ await this._session.send("network.setExtraHeaders", {
291
+ headers: allHeaders.map(({ name, value }) => ({ name, value: { type: "string", value } })),
292
+ contexts: [this._session.sessionId]
293
+ });
273
294
  }
274
295
  async updateEmulateMedia() {
275
296
  }
@@ -379,6 +400,8 @@ ${params.stackTrace?.callFrames.map((f) => {
379
400
  }
380
401
  }
381
402
  async setBackgroundColor(color) {
403
+ if (color)
404
+ throw new Error("Not implemented");
382
405
  }
383
406
  async takeScreenshot(progress, format, documentRect, viewportRect, quality, fitsViewport, scale) {
384
407
  const rect = documentRect || viewportRect;
@@ -503,9 +526,6 @@ ${params.stackTrace?.callFrames.map((f) => {
503
526
  const executionContext = toBidiExecutionContext(to);
504
527
  return await executionContext.remoteObjectForNodeId(to, nodeId);
505
528
  }
506
- async getAccessibilityTree(needle) {
507
- throw new Error("Method not implemented.");
508
- }
509
529
  async inputActionEpilogue() {
510
530
  }
511
531
  async resetForReuse(progress) {
@@ -69,7 +69,6 @@ class BrowserContext extends import_instrumentation.SdkObject {
69
69
  this._creatingStorageStatePage = false;
70
70
  this.initScripts = [];
71
71
  this._routesInFlight = /* @__PURE__ */ new Set();
72
- this._playwrightBindingExposed = false;
73
72
  this.attribution.context = this;
74
73
  this._browser = browser;
75
74
  this._options = options;
@@ -229,17 +228,17 @@ class BrowserContext extends import_instrumentation.SdkObject {
229
228
  return this._pageBindings.get(name)?.forClient;
230
229
  }
231
230
  async exposePlaywrightBindingIfNeeded() {
232
- if (this._playwrightBindingExposed)
233
- return;
234
- this._playwrightBindingExposed = true;
235
- await this.doExposePlaywrightBinding();
236
- this.bindingsInitScript = import_page2.PageBinding.createInitScript();
237
- this.initScripts.push(this.bindingsInitScript);
238
- await this.doAddInitScript(this.bindingsInitScript);
239
- await this.safeNonStallingEvaluateInAllFrames(this.bindingsInitScript.source, "main");
231
+ this._playwrightBindingExposed ??= (async () => {
232
+ await this.doExposePlaywrightBinding();
233
+ this.bindingsInitScript = import_page2.PageBinding.createInitScript();
234
+ this.initScripts.push(this.bindingsInitScript);
235
+ await this.doAddInitScript(this.bindingsInitScript);
236
+ await this.safeNonStallingEvaluateInAllFrames(this.bindingsInitScript.source, "main");
237
+ })();
238
+ return await this._playwrightBindingExposed;
240
239
  }
241
240
  needsPlaywrightBinding() {
242
- return this._playwrightBindingExposed;
241
+ return this._playwrightBindingExposed !== void 0;
243
242
  }
244
243
  async exposeBinding(progress, name, needsHandle, playwrightBinding, forClient) {
245
244
  if (this._pageBindings.has(name))
@@ -55,11 +55,22 @@ var import_fileUtils = require("../utils/fileUtils");
55
55
  var import_processLauncher = require("../utils/processLauncher");
56
56
  const ARTIFACTS_FOLDER = import_path.default.join(import_os.default.tmpdir(), "playwright-artifacts-");
57
57
  class Chromium extends import_browserType.BrowserType {
58
- constructor(parent) {
58
+ constructor(parent, bidiChromium) {
59
59
  super(parent, "chromium");
60
+ this._bidiChromium = bidiChromium;
60
61
  if ((0, import_utils.debugMode)() === "inspector")
61
62
  this._devtools = this._createDevTools();
62
63
  }
64
+ launch(progress, options, protocolLogger) {
65
+ if (options.channel?.startsWith("bidi-"))
66
+ return this._bidiChromium.launch(progress, options, protocolLogger);
67
+ return super.launch(progress, options, protocolLogger);
68
+ }
69
+ async launchPersistentContext(progress, userDataDir, options) {
70
+ if (options.channel?.startsWith("bidi-"))
71
+ return this._bidiChromium.launchPersistentContext(progress, userDataDir, options);
72
+ return super.launchPersistentContext(progress, userDataDir, options);
73
+ }
63
74
  async connectOverCDP(progress, endpointURL, options) {
64
75
  return await this._connectOverCDPInternal(progress, endpointURL, options);
65
76
  }
@@ -46,9 +46,11 @@ const disabledFeatures = (assistantMode) => [
46
46
  "AutoDeElevate",
47
47
  // See https://github.com/microsoft/playwright/issues/37714
48
48
  "RenderDocument",
49
+ // Prevents downloading optimization hints on startup.
50
+ "OptimizationHints",
49
51
  assistantMode ? "AutomationControlled" : ""
50
52
  ].filter(Boolean);
51
- const chromiumSwitches = (assistantMode, channel) => [
53
+ const chromiumSwitches = (assistantMode, channel, android) => [
52
54
  "--disable-field-trial-config",
53
55
  // https://source.chromium.org/chromium/chromium/src/+/main:testing/variations/README.md
54
56
  "--disable-background-networking",
@@ -75,6 +77,13 @@ const chromiumSwitches = (assistantMode, channel) => [
75
77
  "--disable-search-engine-choice-screen",
76
78
  // Edge can potentially restart on Windows (msRelaunchNoCompatLayer) which looses its file descriptors (stdout/stderr) and CDP (3/4). Disable until fixed upstream.
77
79
  "--edge-skip-compat-layer-relaunch",
80
+ // This disables Chrome for Testing infobar that is visible in the persistent context.
81
+ // The switch is ignored everywhere else, including Chromium/Chrome/Edge.
82
+ "--disable-infobars",
83
+ // Less annoying popups.
84
+ "--disable-search-engine-choice-screen",
85
+ // Prevents the "three dots" menu crash in IdentityManager::HasPrimaryAccount for ephemeral contexts.
86
+ android ? "" : "--disable-sync",
78
87
  "--disable-blink-features=AutomationControlled"
79
88
  ].filter(Boolean);
80
89
  // Annotate the CommonJS export names for ESM import in node:
@@ -53,6 +53,7 @@ class CRBrowser extends import_browser.Browser {
53
53
  this._crPages = /* @__PURE__ */ new Map();
54
54
  this._serviceWorkers = /* @__PURE__ */ new Map();
55
55
  this._version = "";
56
+ this._majorVersion = 0;
56
57
  this._tracingRecording = false;
57
58
  this._userAgent = "";
58
59
  this._connection = connection;
@@ -75,6 +76,10 @@ class CRBrowser extends import_browser.Browser {
75
76
  await options.__testHookOnConnectToBrowser();
76
77
  const version = await session.send("Browser.getVersion");
77
78
  browser._version = version.product.substring(version.product.indexOf("/") + 1);
79
+ try {
80
+ browser._majorVersion = +browser._version.split(".")[0];
81
+ } catch {
82
+ }
78
83
  browser._userAgent = version.userAgent;
79
84
  browser.options.headful = !version.userAgent.includes("Headless");
80
85
  if (!options.persistent) {
@@ -116,6 +121,9 @@ class CRBrowser extends import_browser.Browser {
116
121
  version() {
117
122
  return this._version;
118
123
  }
124
+ majorVersion() {
125
+ return this._majorVersion;
126
+ }
119
127
  userAgent() {
120
128
  return this._userAgent;
121
129
  }
@@ -650,10 +650,13 @@ class RouteImpl {
650
650
  let hasScriptSrc = false;
651
651
  for (let directive of directives) {
652
652
  if (!directive.trim()) continue;
653
- const parts = directive.trim().split(/s+/);
654
- if (parts.length === 0) continue;
655
- const directiveName = parts[0].toLowerCase();
656
- const directiveValues = parts.slice(1);
653
+ const directiveMatch = directive.match(/^([a-zA-Z-]+)\s+(.*)$/);
654
+ if (!directiveMatch) {
655
+ fixedDirectives.push(directive);
656
+ continue;
657
+ }
658
+ const directiveName = directiveMatch[1].toLowerCase();
659
+ const directiveValues = directiveMatch[2].split(/\s+/).filter((v) => v.length > 0);
657
660
  switch (directiveName) {
658
661
  case "script-src":
659
662
  hasScriptSrc = true;
@@ -664,6 +667,12 @@ class RouteImpl {
664
667
  if (!values.includes("'unsafe-eval'")) {
665
668
  values.push("'unsafe-eval'");
666
669
  }
670
+ if (!values.includes("'unsafe-inline'") && !scriptNonce) {
671
+ values.push("'unsafe-inline'");
672
+ }
673
+ if (!values.includes("*") && !values.includes("'self'") && !values.some((v) => v.includes("https:"))) {
674
+ values.push("*");
675
+ }
667
676
  fixedDirectives.push(`script-src ${values.join(" ")}`);
668
677
  break;
669
678
  case "style-src":
@@ -709,9 +718,9 @@ class RouteImpl {
709
718
  }
710
719
  if (!hasScriptSrc) {
711
720
  if (scriptNonce) {
712
- fixedDirectives.push(`script-src 'self' 'unsafe-eval' 'nonce-${scriptNonce}'`);
721
+ fixedDirectives.push(`script-src 'self' 'unsafe-eval' 'nonce-${scriptNonce}' *`);
713
722
  } else {
714
- fixedDirectives.push(`script-src 'self' 'unsafe-eval'`);
723
+ fixedDirectives.push(`script-src 'self' 'unsafe-eval' 'unsafe-inline' *`);
715
724
  }
716
725
  }
717
726
  return fixedDirectives.join("; ");
@@ -44,7 +44,6 @@ var import_helper = require("../helper");
44
44
  var network = __toESM(require("../network"));
45
45
  var import_page = require("../page");
46
46
  var import_registry = require("../registry");
47
- var import_crAccessibility = require("./crAccessibility");
48
47
  var import_crCoverage = require("./crCoverage");
49
48
  var import_crDragDrop = require("./crDragDrop");
50
49
  var import_crExecutionContext = require("./crExecutionContext");
@@ -271,9 +270,6 @@ class CRPage {
271
270
  async adoptElementHandle(handle, to) {
272
271
  return this._sessionForHandle(handle)._adoptElementHandle(handle, to);
273
272
  }
274
- async getAccessibilityTree(needle) {
275
- return (0, import_crAccessibility.getAccessibilityTree)(this._mainFrameSession._client, needle);
276
- }
277
273
  async inputActionEpilogue() {
278
274
  await this._mainFrameSession._client.send("Page.enable").catch((e) => {
279
275
  });
@@ -450,8 +446,6 @@ class FrameSession {
450
446
  if (!this._page.isStorageStatePage) {
451
447
  if (this._crPage._browserContext.needsPlaywrightBinding())
452
448
  promises.push(this.exposePlaywrightBinding());
453
- if (this._isMainFrame())
454
- promises.push(this._client.send("Emulation.setFocusEmulationEnabled", { enabled: true }));
455
449
  const options = this._crPage._browserContext._options;
456
450
  if (options.bypassCSP)
457
451
  promises.push(this._client.send("Page.setBypassCSP", { enabled: true }));
@@ -680,6 +674,10 @@ class FrameSession {
680
674
  var executionContextId = parseInt(globalThisObjId.split(".")[1], 10);
681
675
  worker.createExecutionContext(new import_crExecutionContext.CRExecutionContext(session, { id: executionContextId }));
682
676
  }
677
+ if (this._crPage._browserContext._browser.majorVersion() >= 143)
678
+ session.on("Inspector.workerScriptLoaded", () => worker.workerScriptLoaded());
679
+ else
680
+ worker.workerScriptLoaded();
683
681
  this._crPage._networkManager.addSession(session, this._page.frameManager.frame(this._targetId) ?? void 0).catch(() => {
684
682
  });
685
683
  session._sendMayFail("Runtime.runIfWaitingForDebugger");
@@ -688,7 +686,7 @@ class FrameSession {
688
686
  session.on("Target.detachedFromTarget", (event2) => this._onDetachedFromTarget(event2));
689
687
  session.on("Runtime.consoleAPICalled", (event2) => {
690
688
  const args = event2.args.map((o) => (0, import_crExecutionContext.createHandle)(worker.existingExecutionContext, o));
691
- this._page.addConsoleMessage(event2.type, args, (0, import_crProtocolHelper.toConsoleMessageLocation)(event2.stackTrace));
689
+ this._page.addConsoleMessage(worker, event2.type, args, (0, import_crProtocolHelper.toConsoleMessageLocation)(event2.stackTrace));
692
690
  });
693
691
  session.on("Runtime.exceptionThrown", (exception) => this._page.addPageError((0, import_crProtocolHelper.exceptionToError)(exception.exceptionDetails)));
694
692
  }
@@ -723,7 +721,7 @@ class FrameSession {
723
721
  if (!context)
724
722
  return;
725
723
  const values = event.args.map((arg) => (0, import_crExecutionContext.createHandle)(context, arg));
726
- this._page.addConsoleMessage(event.type, values, (0, import_crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));
724
+ this._page.addConsoleMessage(null, event.type, values, (0, import_crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));
727
725
  }
728
726
  async _onBindingCalled(event) {
729
727
  const pageOrError = await this._crPage._page.waitForInitializedOrError();
@@ -765,7 +763,7 @@ class FrameSession {
765
763
  lineNumber: lineNumber || 0,
766
764
  columnNumber: 0
767
765
  };
768
- this._page.addConsoleMessage(level, [], location, text);
766
+ this._page.addConsoleMessage(null, level, [], location, text);
769
767
  }
770
768
  }
771
769
  async _onFileChooserOpened(event) {
@@ -36,16 +36,22 @@ var import_crExecutionContext = require("./crExecutionContext");
36
36
  var import_crNetworkManager = require("./crNetworkManager");
37
37
  var import_browserContext = require("../browserContext");
38
38
  var network = __toESM(require("../network"));
39
+ var import_console = require("../console");
40
+ var import_crProtocolHelper = require("./crProtocolHelper");
39
41
  class CRServiceWorker extends import_page.Worker {
40
42
  constructor(browserContext, session, url) {
41
43
  super(browserContext, url);
42
44
  this._session = session;
43
45
  this.browserContext = browserContext;
44
- if (!!process.env.PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS)
46
+ if (!process.env.PLAYWRIGHT_DISABLE_SERVICE_WORKER_NETWORK)
45
47
  this._networkManager = new import_crNetworkManager.CRNetworkManager(null, this);
46
48
  session.once("Runtime.executionContextCreated", (event) => {
47
49
  this.createExecutionContext(new import_crExecutionContext.CRExecutionContext(session, event.context));
48
50
  });
51
+ if (this.browserContext._browser.majorVersion() >= 143)
52
+ session.on("Inspector.workerScriptLoaded", () => this.workerScriptLoaded());
53
+ else
54
+ this.workerScriptLoaded();
49
55
  if (this._networkManager && this._isNetworkInspectionEnabled()) {
50
56
  this.updateRequestInterception();
51
57
  this.updateExtraHTTPHeaders();
@@ -59,6 +65,13 @@ class CRServiceWorker extends import_page.Worker {
59
65
  ).catch(() => {
60
66
  });
61
67
  }
68
+ session.on("Runtime.consoleAPICalled", (event) => {
69
+ if (!this.existingExecutionContext || process.env.PLAYWRIGHT_DISABLE_SERVICE_WORKER_CONSOLE)
70
+ return;
71
+ const args = event.args.map((o) => (0, import_crExecutionContext.createHandle)(this.existingExecutionContext, o));
72
+ const message = new import_console.ConsoleMessage(null, this, event.type, void 0, args, (0, import_crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));
73
+ this.browserContext.emit(import_browserContext.BrowserContext.Events.Console, message);
74
+ });
62
75
  session.send("Runtime.runIfWaitingForDebugger").catch((e) => {
63
76
  });
64
77
  session.on("Inspector.targetReloadedAfterCrash", () => {
@@ -30,9 +30,9 @@ class VideoRecorder {
30
30
  this._process = null;
31
31
  this._gracefullyClose = null;
32
32
  this._lastWritePromise = Promise.resolve();
33
- this._lastFrameTimestamp = 0;
34
- this._lastFrameBuffer = null;
35
- this._lastWriteTimestamp = 0;
33
+ this._firstFrameTimestamp = 0;
34
+ this._lastFrame = null;
35
+ this._lastWriteNodeTime = 0;
36
36
  this._frameQueue = [];
37
37
  this._isStopped = false;
38
38
  this._ffmpegPath = ffmpegPath;
@@ -77,16 +77,17 @@ class VideoRecorder {
77
77
  (0, import_utils.assert)(this._process);
78
78
  if (this._isStopped)
79
79
  return;
80
- if (this._lastFrameBuffer) {
81
- const durationSec = timestamp - this._lastFrameTimestamp;
82
- const repeatCount = Math.max(1, Math.round(fps * durationSec));
80
+ if (!this._firstFrameTimestamp)
81
+ this._firstFrameTimestamp = timestamp;
82
+ const frameNumber = Math.floor((timestamp - this._firstFrameTimestamp) * fps);
83
+ if (this._lastFrame) {
84
+ const repeatCount = frameNumber - this._lastFrame.frameNumber;
83
85
  for (let i = 0; i < repeatCount; ++i)
84
- this._frameQueue.push(this._lastFrameBuffer);
86
+ this._frameQueue.push(this._lastFrame.buffer);
85
87
  this._lastWritePromise = this._lastWritePromise.then(() => this._sendFrames());
86
88
  }
87
- this._lastFrameBuffer = frame;
88
- this._lastFrameTimestamp = timestamp;
89
- this._lastWriteTimestamp = (0, import_utils.monotonicTime)();
89
+ this._lastFrame = { buffer: frame, timestamp, frameNumber };
90
+ this._lastWriteNodeTime = (0, import_utils.monotonicTime)();
90
91
  }
91
92
  async _sendFrames() {
92
93
  while (this._frameQueue.length)
@@ -99,9 +100,10 @@ class VideoRecorder {
99
100
  });
100
101
  }
101
102
  async stop() {
102
- if (this._isStopped)
103
+ if (this._isStopped || !this._lastFrame)
103
104
  return;
104
- this.writeFrame(Buffer.from([]), this._lastFrameTimestamp + ((0, import_utils.monotonicTime)() - this._lastWriteTimestamp) / 1e3);
105
+ const addTime = Math.max(((0, import_utils.monotonicTime)() - this._lastWriteNodeTime) / 1e3, 1);
106
+ this.writeFrame(Buffer.from([]), this._lastFrame.timestamp + addTime);
105
107
  this._isStopped = true;
106
108
  await this._lastWritePromise;
107
109
  await this._gracefullyClose();
@@ -22,8 +22,9 @@ __export(console_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(console_exports);
24
24
  class ConsoleMessage {
25
- constructor(page, type, text, args, location) {
25
+ constructor(page, worker, type, text, args, location) {
26
26
  this._page = page;
27
+ this._worker = worker;
27
28
  this._type = type;
28
29
  this._text = text;
29
30
  this._args = args;
@@ -32,6 +33,9 @@ class ConsoleMessage {
32
33
  page() {
33
34
  return this._page;
34
35
  }
36
+ worker() {
37
+ return this._worker;
38
+ }
35
39
  type() {
36
40
  return this._type;
37
41
  }