playwright-core 1.58.0-alpha-2025-12-08 → 1.58.0-alpha-2025-12-10

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 (36) hide show
  1. package/browsers.json +8 -8
  2. package/lib/client/browserContext.js +7 -0
  3. package/lib/protocol/validator.js +10 -5
  4. package/lib/server/agent/actionRunner.js +16 -6
  5. package/lib/server/agent/agent.js +12 -10
  6. package/lib/server/agent/context.js +34 -10
  7. package/lib/server/agent/tools.js +51 -9
  8. package/lib/server/bidi/bidiBrowser.js +13 -4
  9. package/lib/server/bidi/bidiNetworkManager.js +1 -1
  10. package/lib/server/bidi/bidiPage.js +12 -2
  11. package/lib/server/bidi/third_party/bidiProtocolCore.js +1 -0
  12. package/lib/server/browserContext.js +1 -1
  13. package/lib/server/chromium/chromiumSwitches.js +0 -2
  14. package/lib/server/chromium/crBrowser.js +1 -1
  15. package/lib/server/chromium/crNetworkManager.js +39 -2
  16. package/lib/server/chromium/crPage.js +14 -81
  17. package/lib/server/deviceDescriptorsSource.json +2 -2
  18. package/lib/server/firefox/ffNetworkManager.js +2 -2
  19. package/lib/server/firefox/ffPage.js +9 -8
  20. package/lib/server/frames.js +2 -2
  21. package/lib/server/network.js +3 -0
  22. package/lib/server/page.js +4 -64
  23. package/lib/server/progress.js +3 -2
  24. package/lib/server/registry/index.js +1 -1
  25. package/lib/server/screencast.js +191 -0
  26. package/lib/server/trace/recorder/tracing.js +5 -5
  27. package/lib/server/utils/network.js +18 -26
  28. package/lib/server/{chromium/videoRecorder.js → videoRecorder.js} +3 -3
  29. package/lib/server/webkit/wkBrowser.js +1 -1
  30. package/lib/server/webkit/wkInterceptableRequest.js +29 -1
  31. package/lib/server/webkit/wkPage.js +20 -40
  32. package/lib/vite/traceViewer/uiMode.DiEbKRwa.js +5 -0
  33. package/lib/vite/traceViewer/uiMode.html +1 -1
  34. package/package.json +1 -1
  35. package/types/types.d.ts +8 -3
  36. package/lib/vite/traceViewer/uiMode.CmFFBCQb.js +0 -5
package/browsers.json CHANGED
@@ -17,35 +17,35 @@
17
17
  },
18
18
  {
19
19
  "name": "chromium-tip-of-tree",
20
- "revision": "1384",
20
+ "revision": "1389",
21
21
  "installByDefault": false,
22
- "browserVersion": "143.0.7499.25",
22
+ "browserVersion": "144.0.7559.3",
23
23
  "title": "Chrome Canary for Testing"
24
24
  },
25
25
  {
26
26
  "name": "chromium-tip-of-tree-headless-shell",
27
- "revision": "1384",
27
+ "revision": "1389",
28
28
  "installByDefault": false,
29
- "browserVersion": "143.0.7499.25",
29
+ "browserVersion": "144.0.7559.3",
30
30
  "title": "Chrome Canary Headless Shell"
31
31
  },
32
32
  {
33
33
  "name": "firefox",
34
- "revision": "1502",
34
+ "revision": "1504",
35
35
  "installByDefault": true,
36
- "browserVersion": "145.0.1",
36
+ "browserVersion": "145.0.2",
37
37
  "title": "Firefox"
38
38
  },
39
39
  {
40
40
  "name": "firefox-beta",
41
- "revision": "1498",
41
+ "revision": "1499",
42
42
  "installByDefault": false,
43
43
  "browserVersion": "146.0b8",
44
44
  "title": "Firefox Beta"
45
45
  },
46
46
  {
47
47
  "name": "webkit",
48
- "revision": "2235",
48
+ "revision": "2238",
49
49
  "installByDefault": true,
50
50
  "revisionOverrides": {
51
51
  "debian11-x64": "2105",
@@ -493,6 +493,7 @@ async function prepareBrowserContextParams(platform, options) {
493
493
  network.validateHeaders(options.extraHTTPHeaders);
494
494
  const contextParams = {
495
495
  ...options,
496
+ agent: toAgentProtocol(options.agent),
496
497
  viewport: options.viewport === null ? void 0 : options.viewport,
497
498
  noDefaultViewport: options.viewport === null,
498
499
  extraHTTPHeaders: options.extraHTTPHeaders ? (0, import_headers.headersObjectToArray)(options.extraHTTPHeaders) : void 0,
@@ -515,6 +516,12 @@ async function prepareBrowserContextParams(platform, options) {
515
516
  contextParams.recordVideo.dir = platform.path().resolve(contextParams.recordVideo.dir);
516
517
  return contextParams;
517
518
  }
519
+ function toAgentProtocol(agent) {
520
+ if (!agent)
521
+ return void 0;
522
+ const secrets = agent.secrets ? Object.entries(agent.secrets).map(([name, value]) => ({ name, value })) : void 0;
523
+ return { ...agent, secrets };
524
+ }
518
525
  function toAcceptDownloadsProtocol(acceptDownloads) {
519
526
  if (acceptDownloads === void 0)
520
527
  return void 0;
@@ -612,7 +612,8 @@ import_validatorPrimitives.scheme.BrowserTypeLaunchPersistentContextParams = (0,
612
612
  provider: import_validatorPrimitives.tString,
613
613
  model: import_validatorPrimitives.tString,
614
614
  cacheFile: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
615
- cacheMode: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tEnum)(["ignore", "force", "auto"]))
615
+ cacheMode: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tEnum)(["ignore", "force", "auto"])),
616
+ secrets: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)((0, import_validatorPrimitives.tType)("NameValue")))
616
617
  })),
617
618
  userDataDir: import_validatorPrimitives.tString,
618
619
  slowMo: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tFloat)
@@ -710,7 +711,8 @@ import_validatorPrimitives.scheme.BrowserNewContextParams = (0, import_validator
710
711
  provider: import_validatorPrimitives.tString,
711
712
  model: import_validatorPrimitives.tString,
712
713
  cacheFile: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
713
- cacheMode: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tEnum)(["ignore", "force", "auto"]))
714
+ cacheMode: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tEnum)(["ignore", "force", "auto"])),
715
+ secrets: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)((0, import_validatorPrimitives.tType)("NameValue")))
714
716
  })),
715
717
  proxy: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tObject)({
716
718
  server: import_validatorPrimitives.tString,
@@ -787,7 +789,8 @@ import_validatorPrimitives.scheme.BrowserNewContextForReuseParams = (0, import_v
787
789
  provider: import_validatorPrimitives.tString,
788
790
  model: import_validatorPrimitives.tString,
789
791
  cacheFile: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
790
- cacheMode: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tEnum)(["ignore", "force", "auto"]))
792
+ cacheMode: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tEnum)(["ignore", "force", "auto"])),
793
+ secrets: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)((0, import_validatorPrimitives.tType)("NameValue")))
791
794
  })),
792
795
  proxy: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tObject)({
793
796
  server: import_validatorPrimitives.tString,
@@ -909,7 +912,8 @@ import_validatorPrimitives.scheme.BrowserContextInitializer = (0, import_validat
909
912
  provider: import_validatorPrimitives.tString,
910
913
  model: import_validatorPrimitives.tString,
911
914
  cacheFile: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
912
- cacheMode: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tEnum)(["ignore", "force", "auto"]))
915
+ cacheMode: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tEnum)(["ignore", "force", "auto"])),
916
+ secrets: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)((0, import_validatorPrimitives.tType)("NameValue")))
913
917
  }))
914
918
  })
915
919
  });
@@ -2818,7 +2822,8 @@ import_validatorPrimitives.scheme.AndroidDeviceLaunchBrowserParams = (0, import_
2818
2822
  provider: import_validatorPrimitives.tString,
2819
2823
  model: import_validatorPrimitives.tString,
2820
2824
  cacheFile: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
2821
- cacheMode: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tEnum)(["ignore", "force", "auto"]))
2825
+ cacheMode: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tEnum)(["ignore", "force", "auto"])),
2826
+ secrets: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)((0, import_validatorPrimitives.tType)("NameValue")))
2822
2827
  })),
2823
2828
  pkg: (0, import_validatorPrimitives.tOptional)(import_validatorPrimitives.tString),
2824
2829
  args: (0, import_validatorPrimitives.tOptional)((0, import_validatorPrimitives.tArray)(import_validatorPrimitives.tString)),
@@ -21,7 +21,7 @@ __export(actionRunner_exports, {
21
21
  runAction: () => runAction
22
22
  });
23
23
  module.exports = __toCommonJS(actionRunner_exports);
24
- async function runAction(progress, page, action) {
24
+ async function runAction(progress, page, action, secrets) {
25
25
  const frame = page.mainFrame();
26
26
  switch (action.method) {
27
27
  case "click":
@@ -34,21 +34,31 @@ async function runAction(progress, page, action) {
34
34
  await frame.hover(progress, action.selector, { ...action.options, ...strictTrue });
35
35
  break;
36
36
  case "selectOption":
37
- await frame.selectOption(progress, action.selector, [], action.values.map((a) => ({ value: a })), { ...strictTrue });
37
+ await frame.selectOption(progress, action.selector, [], action.labels.map((a) => ({ label: a })), { ...strictTrue });
38
38
  break;
39
39
  case "pressKey":
40
40
  await page.keyboard.press(progress, action.key);
41
41
  break;
42
- case "pressSequentially":
43
- await frame.type(progress, action.selector, action.text, { ...strictTrue });
42
+ case "pressSequentially": {
43
+ const secret = secrets?.find((s) => s.name === action.text)?.value ?? action.text;
44
+ await frame.type(progress, action.selector, secret, { ...strictTrue });
44
45
  if (action.submit)
45
46
  await page.keyboard.press(progress, "Enter");
46
47
  break;
47
- case "fill":
48
- await frame.fill(progress, action.selector, action.text, { ...strictTrue });
48
+ }
49
+ case "fill": {
50
+ const secret = secrets?.find((s) => s.name === action.text)?.value ?? action.text;
51
+ await frame.fill(progress, action.selector, secret, { ...strictTrue });
49
52
  if (action.submit)
50
53
  await page.keyboard.press(progress, "Enter");
51
54
  break;
55
+ }
56
+ case "setChecked":
57
+ if (action.checked)
58
+ await frame.check(progress, action.selector, { ...strictTrue });
59
+ else
60
+ await frame.uncheck(progress, action.selector, { ...strictTrue });
61
+ break;
52
62
  }
53
63
  }
54
64
  const strictTrue = { strict: true };
@@ -83,28 +83,30 @@ ${full}
83
83
  }
84
84
  const allCaches = /* @__PURE__ */ new Map();
85
85
  async function cachedPerform(context, options) {
86
- const agentSettings = context.page.browserContext._options.agent;
87
- if (!agentSettings?.cacheFile || agentSettings.cacheMode === "ignore")
86
+ if (!context.options?.cacheFile || context.options.cacheMode === "ignore")
88
87
  return false;
89
- const cache = await cachedActions(agentSettings.cacheFile);
88
+ const cache = await cachedActions(context.options.cacheFile);
90
89
  const cacheKey = options.key ?? options.task;
91
- const actions = cache[cacheKey];
92
- if (!actions) {
93
- if (agentSettings.cacheMode === "force")
90
+ const entry = cache[cacheKey];
91
+ if (!entry) {
92
+ if (context.options.cacheMode === "force")
94
93
  throw new Error(`No cached actions for key "${cacheKey}", but cache mode is set to "force"`);
95
94
  return false;
96
95
  }
97
- for (const action of actions)
98
- await (0, import_actionRunner.runAction)(context.progress, context.page, action);
96
+ for (const action of entry.actions)
97
+ await (0, import_actionRunner.runAction)(context.progress, context.page, action, context.options.secrets ?? []);
99
98
  return true;
100
99
  }
101
100
  async function updateCache(context, options) {
102
- const cacheFile = context.page.browserContext._options.agent?.cacheFile;
101
+ const cacheFile = context.options?.cacheFile;
103
102
  if (!cacheFile)
104
103
  return;
105
104
  const cache = await cachedActions(cacheFile);
106
105
  const cacheKey = options.key ?? options.task;
107
- cache[cacheKey] = context.actions;
106
+ cache[cacheKey] = {
107
+ timestamp: Date.now(),
108
+ actions: context.actions
109
+ };
108
110
  await import_fs.default.promises.writeFile(cacheFile, JSON.stringify(cache, void 0, 2));
109
111
  }
110
112
  async function cachedActions(cacheFile) {
@@ -28,10 +28,18 @@ class Context {
28
28
  this.actions = [];
29
29
  this.progress = progress;
30
30
  this.page = page;
31
+ this.options = page.browserContext._options.agent;
31
32
  }
32
- async runAction(action) {
33
- await this.waitForCompletion(() => (0, import_actionRunner.runAction)(this.progress, this.page, action));
34
- this.actions.push(action);
33
+ async runActionAndWait(action) {
34
+ return await this.runActionsAndWait([action]);
35
+ }
36
+ async runActionsAndWait(action) {
37
+ await this.waitForCompletion(async () => {
38
+ for (const a of action) {
39
+ await (0, import_actionRunner.runAction)(this.progress, this.page, a, this.options?.secrets ?? []);
40
+ this.actions.push(a);
41
+ }
42
+ });
35
43
  return await this.snapshotResult();
36
44
  }
37
45
  async waitForCompletion(callback) {
@@ -40,6 +48,7 @@ class Context {
40
48
  const disposeListeners = () => {
41
49
  this.page.browserContext.off(import_browserContext.BrowserContext.Events.Request, requestListener);
42
50
  };
51
+ this.page.browserContext.on(import_browserContext.BrowserContext.Events.Request, requestListener);
43
52
  let result;
44
53
  try {
45
54
  result = await callback();
@@ -49,20 +58,24 @@ class Context {
49
58
  }
50
59
  const requestedNavigation = requests.some((request) => request.isNavigationRequest());
51
60
  if (requestedNavigation) {
52
- await this.page.performActionPreChecks(this.progress);
61
+ await this.page.mainFrame().waitForLoadState(this.progress, "load");
53
62
  return result;
54
63
  }
55
- const fiveSeconds = new Promise((resolve) => setTimeout(resolve, 1e3));
64
+ const promises = [];
56
65
  for (const request of requests) {
57
- if (request.failure())
58
- continue;
59
- const response = Promise.race([request.response(), fiveSeconds]);
60
- await this.progress.race(response);
66
+ if (["document", "stylesheet", "script", "xhr", "fetch"].includes(request.resourceType()))
67
+ promises.push(request.response().then((r) => r?.finished()));
68
+ else
69
+ promises.push(request.response());
61
70
  }
71
+ await this.progress.race(promises, { timeout: 5e3 });
72
+ if (requests.length)
73
+ await this.progress.wait(500);
62
74
  return result;
63
75
  }
64
76
  async snapshotResult() {
65
- const { full } = await this.page.snapshotForAI(this.progress);
77
+ let { full } = await this.page.snapshotForAI(this.progress);
78
+ full = this._redactText(full);
66
79
  const text = [`# Page snapshot
67
80
  ${full}`];
68
81
  return {
@@ -84,6 +97,17 @@ ${full}`];
84
97
  }
85
98
  }));
86
99
  }
100
+ _redactText(text) {
101
+ const secrets = this.options?.secrets;
102
+ if (!secrets)
103
+ return text;
104
+ const redactText = (text2) => {
105
+ for (const { name, value } of secrets)
106
+ text2 = text2.replaceAll(value, `<secret>${name}</secret>`);
107
+ return text2;
108
+ };
109
+ return redactText(text);
110
+ }
87
111
  }
88
112
  // Annotate the CommonJS export names for ESM import in node:
89
113
  0 && (module.exports = {
@@ -54,7 +54,7 @@ const click = defineTool({
54
54
  },
55
55
  handle: async (context, params) => {
56
56
  const [selector] = await context.refSelectors([params]);
57
- return await context.runAction({
57
+ return await context.runActionAndWait({
58
58
  method: "click",
59
59
  selector,
60
60
  options: {
@@ -82,7 +82,7 @@ const drag = defineTool({
82
82
  { ref: params.startRef, element: params.startElement },
83
83
  { ref: params.endRef, element: params.endElement }
84
84
  ]);
85
- return await context.runAction({
85
+ return await context.runActionAndWait({
86
86
  method: "drag",
87
87
  sourceSelector,
88
88
  targetSelector
@@ -101,7 +101,7 @@ const hover = defineTool({
101
101
  },
102
102
  handle: async (context, params) => {
103
103
  const [selector] = await context.refSelectors([params]);
104
- return await context.runAction({
104
+ return await context.runActionAndWait({
105
105
  method: "hover",
106
106
  selector,
107
107
  options: {
@@ -122,10 +122,10 @@ const selectOption = defineTool({
122
122
  },
123
123
  handle: async (context, params) => {
124
124
  const [selector] = await context.refSelectors([params]);
125
- return await context.runAction({
125
+ return await context.runActionAndWait({
126
126
  method: "selectOption",
127
127
  selector,
128
- values: params.values
128
+ labels: params.values
129
129
  });
130
130
  }
131
131
  });
@@ -139,7 +139,7 @@ const pressKey = defineTool({
139
139
  })
140
140
  },
141
141
  handle: async (context, params) => {
142
- return await context.runAction({
142
+ return await context.runActionAndWait({
143
143
  method: "pressKey",
144
144
  key: params.key
145
145
  });
@@ -160,14 +160,14 @@ const type = defineTool({
160
160
  handle: async (context, params) => {
161
161
  const [selector] = await context.refSelectors([params]);
162
162
  if (params.slowly) {
163
- return await context.runAction({
163
+ return await context.runActionAndWait({
164
164
  method: "pressSequentially",
165
165
  selector,
166
166
  text: params.text,
167
167
  submit: params.submit
168
168
  });
169
169
  } else {
170
- return await context.runAction({
170
+ return await context.runActionAndWait({
171
171
  method: "fill",
172
172
  selector,
173
173
  text: params.text,
@@ -176,6 +176,47 @@ const type = defineTool({
176
176
  }
177
177
  }
178
178
  });
179
+ const fillForm = defineTool({
180
+ schema: {
181
+ name: "browser_fill_form",
182
+ title: "Fill form",
183
+ description: "Fill multiple form fields",
184
+ inputSchema: import_mcpBundle.z.object({
185
+ fields: import_mcpBundle.z.array(import_mcpBundle.z.object({
186
+ name: import_mcpBundle.z.string().describe("Human-readable field name"),
187
+ type: import_mcpBundle.z.enum(["textbox", "checkbox", "radio", "combobox", "slider"]).describe("Type of the field"),
188
+ ref: import_mcpBundle.z.string().describe("Exact target field reference from the page snapshot"),
189
+ value: import_mcpBundle.z.string().describe("Value to fill in the field. If the field is a checkbox, the value should be `true` or `false`. If the field is a combobox, the value should be the text of the option.")
190
+ })).describe("Fields to fill in")
191
+ })
192
+ },
193
+ handle: async (context, params) => {
194
+ const actions = [];
195
+ for (const field of params.fields) {
196
+ const [selector] = await context.refSelectors([{ ref: field.ref, element: field.name }]);
197
+ if (field.type === "textbox" || field.type === "slider") {
198
+ actions.push({
199
+ method: "fill",
200
+ selector,
201
+ text: field.value
202
+ });
203
+ } else if (field.type === "checkbox" || field.type === "radio") {
204
+ actions.push({
205
+ method: "setChecked",
206
+ selector,
207
+ checked: field.value === "true"
208
+ });
209
+ } else if (field.type === "combobox") {
210
+ actions.push({
211
+ method: "selectOption",
212
+ selector,
213
+ labels: [field.value]
214
+ });
215
+ }
216
+ }
217
+ return await context.runActionsAndWait(actions);
218
+ }
219
+ });
179
220
  var tools_default = [
180
221
  snapshot,
181
222
  click,
@@ -183,5 +224,6 @@ var tools_default = [
183
224
  hover,
184
225
  selectOption,
185
226
  pressKey,
186
- type
227
+ type,
228
+ fillForm
187
229
  ];
@@ -366,19 +366,28 @@ class BidiBrowserContext extends import_browserContext.BrowserContext {
366
366
  }
367
367
  }
368
368
  async doUpdateDefaultViewport() {
369
- if (!this._options.viewport)
369
+ if (!this._options.viewport && !this._options.screen)
370
370
  return;
371
+ const screenSize = this._options.screen || this._options.viewport;
372
+ const viewportSize = this._options.viewport || this._options.screen;
371
373
  await Promise.all([
372
374
  this._browser._browserSession.send("browsingContext.setViewport", {
373
375
  viewport: {
374
- width: this._options.viewport.width,
375
- height: this._options.viewport.height
376
+ width: viewportSize.width,
377
+ height: viewportSize.height
376
378
  },
377
379
  devicePixelRatio: this._options.deviceScaleFactor || 1,
378
380
  userContexts: [this._userContextId()]
379
381
  }),
380
382
  this._browser._browserSession.send("emulation.setScreenOrientationOverride", {
381
- screenOrientation: getScreenOrientation(!!this._options.isMobile, this._options.viewport),
383
+ screenOrientation: getScreenOrientation(!!this._options.isMobile, screenSize),
384
+ userContexts: [this._userContextId()]
385
+ }),
386
+ this._browser._browserSession.send("emulation.setScreenSettingsOverride", {
387
+ screenArea: {
388
+ width: screenSize.width,
389
+ height: screenSize.height
390
+ },
382
391
  userContexts: [this._userContextId()]
383
392
  })
384
393
  ]);
@@ -342,7 +342,7 @@ function resourceTypeFromBidi(requestDestination, requestInitiatorType, eventIni
342
342
  case "image":
343
343
  return "image";
344
344
  case "object":
345
- return "object";
345
+ return "other";
346
346
  case "paintworklet":
347
347
  return "script";
348
348
  case "script":
@@ -306,6 +306,7 @@ ${params.stackTrace?.callFrames.map((f) => {
306
306
  const emulatedSize = this._page.emulatedSize();
307
307
  if (!emulatedSize)
308
308
  return;
309
+ const screenSize = emulatedSize.screen;
309
310
  const viewportSize = emulatedSize.viewport;
310
311
  await Promise.all([
311
312
  this._session.send("browsingContext.setViewport", {
@@ -318,7 +319,14 @@ ${params.stackTrace?.callFrames.map((f) => {
318
319
  }),
319
320
  this._session.send("emulation.setScreenOrientationOverride", {
320
321
  contexts: [this._session.sessionId],
321
- screenOrientation: (0, import_bidiBrowser.getScreenOrientation)(!!options.isMobile, viewportSize)
322
+ screenOrientation: (0, import_bidiBrowser.getScreenOrientation)(!!options.isMobile, screenSize)
323
+ }),
324
+ this._session.send("emulation.setScreenSettingsOverride", {
325
+ contexts: [this._session.sessionId],
326
+ screenArea: {
327
+ width: screenSize.width,
328
+ height: screenSize.height
329
+ }
322
330
  })
323
331
  ]);
324
332
  }
@@ -482,7 +490,9 @@ ${params.stackTrace?.callFrames.map((f) => {
482
490
  throw e;
483
491
  });
484
492
  }
485
- async setScreencastOptions(options) {
493
+ async startScreencast(options) {
494
+ }
495
+ async stopScreencast() {
486
496
  }
487
497
  rafCountForStablePosition() {
488
498
  return 1;
@@ -128,6 +128,7 @@ var Network;
128
128
  ((Network2) => {
129
129
  let DataType;
130
130
  ((DataType2) => {
131
+ DataType2["Request"] = "request";
131
132
  DataType2["Response"] = "response";
132
133
  })(DataType = Network2.DataType || (Network2.DataType = {}));
133
134
  })(Network || (Network = {}));
@@ -322,7 +322,7 @@ if (navigator.serviceWorker) navigator.serviceWorker.register = async () => { co
322
322
  const pageOrError = await progress.race(page.waitForInitializedOrError());
323
323
  if (pageOrError instanceof Error)
324
324
  throw pageOrError;
325
- await page.mainFrame()._waitForLoadState(progress, "load");
325
+ await page.mainFrame().waitForLoadState(progress, "load");
326
326
  return page;
327
327
  }
328
328
  async _loadDefaultContext(progress) {
@@ -22,8 +22,6 @@ __export(chromiumSwitches_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(chromiumSwitches_exports);
24
24
  const disabledFeatures = (assistantMode) => [
25
- // See https://github.com/microsoft/playwright/pull/10380
26
- "AcceptCHFrame",
27
25
  // See https://github.com/microsoft/playwright/issues/14047
28
26
  "AvoidUnnecessaryBeforeUnloadCheckSync",
29
27
  "DestroyProfileOnBrowserClose",
@@ -470,7 +470,7 @@ class CRBrowserContext extends import_browserContext.BrowserContext {
470
470
  }
471
471
  }
472
472
  async stopVideoRecording() {
473
- await Promise.all(this._crPages().map((crPage) => crPage._mainFrameSession._stopVideoRecording()));
473
+ await Promise.all(this._crPages().map((crPage) => crPage._page.screencast.stopVideoRecording()));
474
474
  }
475
475
  onClosePersistent() {
476
476
  }
@@ -482,12 +482,11 @@ class InterceptableRequest {
482
482
  url,
483
483
  postDataEntries = null
484
484
  } = requestPausedEvent ? requestPausedEvent.request : requestWillBeSentEvent.request;
485
- const type = (requestWillBeSentEvent.type || "").toLowerCase();
486
485
  let postDataBuffer = null;
487
486
  const entries = postDataEntries?.filter((entry) => entry.bytes);
488
487
  if (entries && entries.length)
489
488
  postDataBuffer = Buffer.concat(entries.map((entry) => Buffer.from(entry.bytes, "base64")));
490
- this.request = new network.Request(context, frame, serviceWorker, redirectedFrom?.request || null, documentId, url, type, method, postDataBuffer, headersOverride || (0, import_utils.headersObjectToArray)(headers));
489
+ this.request = new network.Request(context, frame, serviceWorker, redirectedFrom?.request || null, documentId, url, toResourceType(requestWillBeSentEvent.type || "Other"), method, postDataBuffer, headersOverride || (0, import_utils.headersObjectToArray)(headers));
491
490
  }
492
491
  }
493
492
  class RouteImpl {
@@ -660,6 +659,44 @@ class ResponseExtraInfoTracker {
660
659
  this._requests.delete(requestId);
661
660
  }
662
661
  }
662
+ function toResourceType(type) {
663
+ switch (type) {
664
+ case "Document":
665
+ return "document";
666
+ case "Stylesheet":
667
+ return "stylesheet";
668
+ case "Image":
669
+ return "image";
670
+ case "Media":
671
+ return "media";
672
+ case "Font":
673
+ return "font";
674
+ case "Script":
675
+ return "script";
676
+ case "TextTrack":
677
+ return "texttrack";
678
+ case "XHR":
679
+ return "xhr";
680
+ case "Fetch":
681
+ return "fetch";
682
+ case "EventSource":
683
+ return "eventsource";
684
+ case "WebSocket":
685
+ return "websocket";
686
+ case "Manifest":
687
+ return "manifest";
688
+ case "Ping":
689
+ return "ping";
690
+ case "CSPViolationReport":
691
+ return "cspreport";
692
+ case "Prefetch":
693
+ case "SignedExchange":
694
+ case "Preflight":
695
+ case "FedCM":
696
+ default:
697
+ return "other";
698
+ }
699
+ }
663
700
  // Annotate the CommonJS export names for ESM import in node:
664
701
  0 && (module.exports = {
665
702
  CRNetworkManager