patchright-core 1.49.2 → 1.50.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 (119) hide show
  1. package/ThirdPartyNotices.txt +9 -9
  2. package/bin/reinstall_msedge_beta_linux.sh +6 -0
  3. package/bin/reinstall_msedge_dev_linux.sh +6 -0
  4. package/bin/reinstall_msedge_stable_linux.sh +6 -0
  5. package/browsers.json +17 -16
  6. package/lib/androidServerImpl.js +1 -1
  7. package/lib/cli/program.js +6 -30
  8. package/lib/client/channelOwner.js +35 -55
  9. package/lib/client/clientInstrumentation.js +2 -0
  10. package/lib/client/connection.js +3 -3
  11. package/lib/client/network.js +3 -1
  12. package/lib/client/waiter.js +1 -1
  13. package/lib/generated/consoleApiSource.js +1 -1
  14. package/lib/generated/injectedScriptSource.js +1 -1
  15. package/lib/generated/pollingRecorderSource.js +1 -1
  16. package/lib/inProcessFactory.js +2 -0
  17. package/lib/protocol/debug.js +1 -1
  18. package/lib/protocol/validator.js +2 -2
  19. package/lib/remote/playwrightConnection.js +4 -3
  20. package/lib/remote/playwrightServer.js +2 -1
  21. package/lib/server/bidi/bidiBrowser.js +9 -6
  22. package/lib/server/bidi/bidiExecutionContext.js +20 -1
  23. package/lib/server/bidi/bidiInput.js +7 -5
  24. package/lib/server/bidi/bidiNetworkManager.js +8 -9
  25. package/lib/server/bidi/bidiPage.js +9 -20
  26. package/lib/server/bidi/third_party/bidiKeyboard.js +9 -7
  27. package/lib/server/browserContext.js +24 -16
  28. package/lib/server/chromium/crBrowser.js +10 -10
  29. package/lib/server/chromium/crExecutionContext.js +1 -5
  30. package/lib/server/chromium/crInput.js +15 -4
  31. package/lib/server/chromium/crPage.js +17 -31
  32. package/lib/server/codegen/csharp.js +12 -2
  33. package/lib/server/codegen/java.js +14 -3
  34. package/lib/server/codegen/javascript.js +10 -2
  35. package/lib/server/codegen/jsonl.js +1 -1
  36. package/lib/server/codegen/python.js +5 -4
  37. package/lib/server/debugController.js +15 -40
  38. package/lib/server/debugger.js +1 -1
  39. package/lib/server/deviceDescriptorsSource.json +50 -50
  40. package/lib/server/dispatchers/browserContextDispatcher.js +2 -13
  41. package/lib/server/dispatchers/debugControllerDispatcher.js +4 -2
  42. package/lib/server/dispatchers/frameDispatcher.js +3 -2
  43. package/lib/server/dispatchers/pageDispatcher.js +1 -1
  44. package/lib/server/dispatchers/webSocketRouteDispatcher.js +10 -11
  45. package/lib/server/dom.js +7 -2
  46. package/lib/server/firefox/ffBrowser.js +6 -6
  47. package/lib/server/firefox/ffInput.js +15 -4
  48. package/lib/server/firefox/ffPage.js +13 -28
  49. package/lib/server/frames.js +25 -30
  50. package/lib/server/har/harTracer.js +1 -1
  51. package/lib/server/input.js +2 -3
  52. package/lib/server/network.js +2 -2
  53. package/lib/server/page.js +23 -16
  54. package/lib/server/recorder/chat.js +177 -0
  55. package/lib/server/recorder/contextRecorder.js +6 -15
  56. package/lib/server/recorder/recorderApp.js +1 -1
  57. package/lib/server/recorder/recorderCollection.js +4 -16
  58. package/lib/server/recorder/recorderRunner.js +7 -3
  59. package/lib/server/recorder/recorderUtils.js +5 -29
  60. package/lib/server/recorder.js +12 -9
  61. package/lib/server/registry/browserFetcher.js +1 -1
  62. package/lib/server/registry/dependencies.js +5 -5
  63. package/lib/server/registry/index.js +118 -5
  64. package/lib/server/registry/nativeDeps.js +7 -4
  65. package/lib/server/trace/recorder/snapshotterInjected.js +12 -5
  66. package/lib/server/trace/viewer/traceViewer.js +6 -1
  67. package/lib/server/transport.js +1 -0
  68. package/lib/server/webkit/webkit.js +1 -1
  69. package/lib/server/webkit/wkBrowser.js +6 -6
  70. package/lib/server/webkit/wkExecutionContext.js +1 -0
  71. package/lib/server/webkit/wkInput.js +15 -5
  72. package/lib/server/webkit/wkPage.js +7 -25
  73. package/lib/utils/comparators.js +16 -10
  74. package/lib/utils/debugLogger.js +3 -1
  75. package/lib/utils/hostPlatform.js +14 -8
  76. package/lib/utils/isomorphic/ariaSnapshot.js +176 -52
  77. package/lib/utils/isomorphic/cssParser.js +4 -4
  78. package/lib/utils/isomorphic/locatorGenerators.js +2 -2
  79. package/lib/utils/isomorphic/locatorParser.js +18 -12
  80. package/lib/utils/isomorphic/urlMatch.js +2 -4
  81. package/lib/utils/processLauncher.js +1 -1
  82. package/lib/utils/wsServer.js +1 -0
  83. package/lib/utils/zones.js +18 -20
  84. package/lib/utilsBundleImpl/index.js +95 -95
  85. package/lib/vite/htmlReport/index.html +14 -14
  86. package/lib/vite/{traceViewer/assets/codeMirrorModule-VZNWuWvU.js → recorder/assets/codeMirrorModule-3Qn3tPnZ.js} +1 -1
  87. package/lib/vite/recorder/assets/{index-CqeZmzx8.js → index-Bek6JFv8.js} +78 -78
  88. package/lib/vite/recorder/assets/{index-iA1aAGZg.css → index-CAQewHss.css} +1 -1
  89. package/lib/vite/recorder/index.html +2 -2
  90. package/lib/vite/{recorder/assets/codeMirrorModule-DUzBrnvO.js → traceViewer/assets/codeMirrorModule-aLkSUGpW.js} +1 -1
  91. package/lib/vite/traceViewer/assets/defaultSettingsView-CxUo6zd3.js +243 -0
  92. package/lib/vite/traceViewer/defaultSettingsView.DtIkrKWn.css +1 -0
  93. package/lib/vite/traceViewer/index.Bhu5cv5R.js +2 -0
  94. package/lib/vite/traceViewer/index.html +3 -6
  95. package/lib/vite/traceViewer/sw.bundle.js +3 -3
  96. package/lib/vite/traceViewer/uiMode.BBy7FOVd.js +5 -0
  97. package/lib/vite/traceViewer/{uiMode.voC1ZiOQ.css → uiMode.Be_ME-Go.css} +1 -1
  98. package/lib/vite/traceViewer/uiMode.html +4 -7
  99. package/package.json +1 -1
  100. package/types/protocol.d.ts +269 -20
  101. package/types/types.d.ts +44 -23
  102. package/bin/PrintDeps.exe +0 -0
  103. package/bin/README.md +0 -2
  104. package/lib/server/ariaSnapshot.js +0 -33
  105. package/lib/server/recorder/recorderInTraceViewer.js +0 -144
  106. package/lib/utils/isomorphic/recorderUtils.js +0 -227
  107. package/lib/vite/traceViewer/assets/inspectorTab-BV-Uf3j9.js +0 -68
  108. package/lib/vite/traceViewer/assets/testServerConnection-DeE2kSzz.js +0 -1
  109. package/lib/vite/traceViewer/assets/workbench-B4WPcYi9.js +0 -9
  110. package/lib/vite/traceViewer/embedded.BLPSqdbm.js +0 -2
  111. package/lib/vite/traceViewer/embedded.html +0 -18
  112. package/lib/vite/traceViewer/embedded.w7WN2u1R.css +0 -1
  113. package/lib/vite/traceViewer/index.BGZfFXXF.js +0 -2
  114. package/lib/vite/traceViewer/inspectorTab.DEOUW62d.css +0 -1
  115. package/lib/vite/traceViewer/recorder.B_SY1GJM.css +0 -0
  116. package/lib/vite/traceViewer/recorder.eWs2vuTG.js +0 -2
  117. package/lib/vite/traceViewer/recorder.html +0 -17
  118. package/lib/vite/traceViewer/uiMode.CW2d9h0S.js +0 -5
  119. package/lib/vite/traceViewer/workbench.C-zR9ysA.css +0 -1
@@ -6,7 +6,7 @@ This project incorporates components from the projects listed below. The origina
6
6
 
7
7
  - @types/node@17.0.24 (https://github.com/DefinitelyTyped/DefinitelyTyped)
8
8
  - @types/yauzl@2.10.0 (https://github.com/DefinitelyTyped/DefinitelyTyped)
9
- - agent-base@7.1.1 (https://github.com/TooTallNate/proxy-agents)
9
+ - agent-base@7.1.3 (https://github.com/TooTallNate/proxy-agents)
10
10
  - balanced-match@1.0.2 (https://github.com/juliangruber/balanced-match)
11
11
  - brace-expansion@1.1.11 (https://github.com/juliangruber/brace-expansion)
12
12
  - buffer-crc32@0.2.13 (https://github.com/brianloveswords/buffer-crc32)
@@ -24,7 +24,7 @@ This project incorporates components from the projects listed below. The origina
24
24
  - fd-slicer@1.1.0 (https://github.com/andrewrk/node-fd-slicer)
25
25
  - get-stream@5.2.0 (https://github.com/sindresorhus/get-stream)
26
26
  - graceful-fs@4.2.10 (https://github.com/isaacs/node-graceful-fs)
27
- - https-proxy-agent@7.0.5 (https://github.com/TooTallNate/proxy-agents)
27
+ - https-proxy-agent@7.0.6 (https://github.com/TooTallNate/proxy-agents)
28
28
  - ip-address@9.0.5 (https://github.com/beaugunderson/ip-address)
29
29
  - is-docker@2.2.1 (https://github.com/sindresorhus/is-docker)
30
30
  - is-wsl@2.2.0 (https://github.com/sindresorhus/is-wsl)
@@ -43,7 +43,7 @@ This project incorporates components from the projects listed below. The origina
43
43
  - retry@0.12.0 (https://github.com/tim-kos/node-retry)
44
44
  - signal-exit@3.0.7 (https://github.com/tapjs/signal-exit)
45
45
  - smart-buffer@4.2.0 (https://github.com/JoshGlazebrook/smart-buffer)
46
- - socks-proxy-agent@8.0.4 (https://github.com/TooTallNate/proxy-agents)
46
+ - socks-proxy-agent@8.0.5 (https://github.com/TooTallNate/proxy-agents)
47
47
  - socks@2.8.3 (https://github.com/JoshGlazebrook/socks)
48
48
  - sprintf-js@1.1.3 (https://github.com/alexei/sprintf.js)
49
49
  - stack-utils@2.0.5 (https://github.com/tapjs/stack-utils)
@@ -105,7 +105,7 @@ MIT License
105
105
  =========================================
106
106
  END OF @types/yauzl@2.10.0 AND INFORMATION
107
107
 
108
- %% agent-base@7.1.1 NOTICES AND INFORMATION BEGIN HERE
108
+ %% agent-base@7.1.3 NOTICES AND INFORMATION BEGIN HERE
109
109
  =========================================
110
110
  (The MIT License)
111
111
 
@@ -130,7 +130,7 @@ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
130
130
  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
131
131
  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
132
132
  =========================================
133
- END OF agent-base@7.1.1 AND INFORMATION
133
+ END OF agent-base@7.1.3 AND INFORMATION
134
134
 
135
135
  %% balanced-match@1.0.2 NOTICES AND INFORMATION BEGIN HERE
136
136
  =========================================
@@ -542,7 +542,7 @@ IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
542
542
  =========================================
543
543
  END OF graceful-fs@4.2.10 AND INFORMATION
544
544
 
545
- %% https-proxy-agent@7.0.5 NOTICES AND INFORMATION BEGIN HERE
545
+ %% https-proxy-agent@7.0.6 NOTICES AND INFORMATION BEGIN HERE
546
546
  =========================================
547
547
  (The MIT License)
548
548
 
@@ -567,7 +567,7 @@ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
567
567
  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
568
568
  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
569
569
  =========================================
570
- END OF https-proxy-agent@7.0.5 AND INFORMATION
570
+ END OF https-proxy-agent@7.0.6 AND INFORMATION
571
571
 
572
572
  %% ip-address@9.0.5 NOTICES AND INFORMATION BEGIN HERE
573
573
  =========================================
@@ -1005,7 +1005,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1005
1005
  =========================================
1006
1006
  END OF smart-buffer@4.2.0 AND INFORMATION
1007
1007
 
1008
- %% socks-proxy-agent@8.0.4 NOTICES AND INFORMATION BEGIN HERE
1008
+ %% socks-proxy-agent@8.0.5 NOTICES AND INFORMATION BEGIN HERE
1009
1009
  =========================================
1010
1010
  (The MIT License)
1011
1011
 
@@ -1030,7 +1030,7 @@ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
1030
1030
  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
1031
1031
  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1032
1032
  =========================================
1033
- END OF socks-proxy-agent@8.0.4 AND INFORMATION
1033
+ END OF socks-proxy-agent@8.0.5 AND INFORMATION
1034
1034
 
1035
1035
  %% socks@2.8.3 NOTICES AND INFORMATION BEGIN HERE
1036
1036
  =========================================
@@ -32,6 +32,12 @@ if ! command -v curl >/dev/null; then
32
32
  apt-get install -y curl
33
33
  fi
34
34
 
35
+ # GnuPG is not preinstalled in slim images
36
+ if ! command -v gpg >/dev/null; then
37
+ apt-get update
38
+ apt-get install -y gpg
39
+ fi
40
+
35
41
  # 3. Add the GPG key, the apt repo, update the apt cache, and install the package
36
42
  curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /tmp/microsoft.gpg
37
43
  install -o root -g root -m 644 /tmp/microsoft.gpg /etc/apt/trusted.gpg.d/
@@ -32,6 +32,12 @@ if ! command -v curl >/dev/null; then
32
32
  apt-get install -y curl
33
33
  fi
34
34
 
35
+ # GnuPG is not preinstalled in slim images
36
+ if ! command -v gpg >/dev/null; then
37
+ apt-get update
38
+ apt-get install -y gpg
39
+ fi
40
+
35
41
  # 3. Add the GPG key, the apt repo, update the apt cache, and install the package
36
42
  curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /tmp/microsoft.gpg
37
43
  install -o root -g root -m 644 /tmp/microsoft.gpg /etc/apt/trusted.gpg.d/
@@ -32,6 +32,12 @@ if ! command -v curl >/dev/null; then
32
32
  apt-get install -y curl
33
33
  fi
34
34
 
35
+ # GnuPG is not preinstalled in slim images
36
+ if ! command -v gpg >/dev/null; then
37
+ apt-get update
38
+ apt-get install -y gpg
39
+ fi
40
+
35
41
  # 3. Add the GPG key, the apt repo, update the apt cache, and install the package
36
42
  curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /tmp/microsoft.gpg
37
43
  install -o root -g root -m 644 /tmp/microsoft.gpg /etc/apt/trusted.gpg.d/
package/browsers.json CHANGED
@@ -3,39 +3,35 @@
3
3
  "browsers": [
4
4
  {
5
5
  "name": "chromium",
6
- "revision": "1148",
6
+ "revision": "1155",
7
7
  "installByDefault": true,
8
- "browserVersion": "131.0.6778.33"
9
- },
10
- {
11
- "name": "chromium-headless-shell",
12
- "revision": "1148",
13
- "installByDefault": true,
14
- "browserVersion": "131.0.6778.33"
8
+ "browserVersion": "133.0.6943.16"
15
9
  },
16
10
  {
17
11
  "name": "chromium-tip-of-tree",
18
- "revision": "1277",
12
+ "revision": "1293",
19
13
  "installByDefault": false,
20
- "browserVersion": "132.0.6834.0"
14
+ "browserVersion": "133.0.6943.0"
21
15
  },
22
16
  {
23
17
  "name": "firefox",
24
- "revision": "1466",
18
+ "revision": "1471",
25
19
  "installByDefault": true,
26
- "browserVersion": "132.0"
20
+ "browserVersion": "134.0"
27
21
  },
28
22
  {
29
23
  "name": "firefox-beta",
30
- "revision": "1465",
24
+ "revision": "1467",
31
25
  "installByDefault": false,
32
- "browserVersion": "132.0b8"
26
+ "browserVersion": "133.0b9"
33
27
  },
34
28
  {
35
29
  "name": "webkit",
36
- "revision": "2104",
30
+ "revision": "2123",
37
31
  "installByDefault": true,
38
32
  "revisionOverrides": {
33
+ "debian11-x64": "2105",
34
+ "debian11-arm64": "2105",
39
35
  "mac10.14": "1446",
40
36
  "mac10.15": "1616",
41
37
  "mac11": "1816",
@@ -49,13 +45,18 @@
49
45
  },
50
46
  {
51
47
  "name": "ffmpeg",
52
- "revision": "1010",
48
+ "revision": "1011",
53
49
  "installByDefault": true,
54
50
  "revisionOverrides": {
55
51
  "mac12": "1010",
56
52
  "mac12-arm64": "1010"
57
53
  }
58
54
  },
55
+ {
56
+ "name": "winldd",
57
+ "revision": "1007",
58
+ "installByDefault": false
59
+ },
59
60
  {
60
61
  "name": "android",
61
62
  "revision": "1001",
@@ -39,7 +39,7 @@ class AndroidServerLauncherImpl {
39
39
  if (devices.length === 0) throw new Error('No devices found');
40
40
  if (options.deviceSerialNumber) {
41
41
  devices = devices.filter(d => d.serial === options.deviceSerialNumber);
42
- if (devices.length === 0) throw new Error(`No device with serial number '${options.deviceSerialNumber}' not found`);
42
+ if (devices.length === 0) throw new Error(`No device with serial number '${options.deviceSerialNumber}' was found`);
43
43
  }
44
44
  if (devices.length > 1) throw new Error(`More than one device found. Please specify deviceSerialNumber`);
45
45
  const device = devices[0];
@@ -16,7 +16,6 @@ var _utilsBundle = require("../utilsBundle");
16
16
  var _driver = require("./driver");
17
17
  var _traceViewer = require("../server/trace/viewer/traceViewer");
18
18
  var playwright = _interopRequireWildcard(require("../.."));
19
- var _child_process = require("child_process");
20
19
  var _utils = require("../utils");
21
20
  var _server = require("../server");
22
21
  var _errors = require("../client/errors");
@@ -56,7 +55,7 @@ Examples:
56
55
 
57
56
  $ open
58
57
  $ open -b webkit https://example.com`);
59
- commandWithOpenOptions('codegen [url]', 'open page and generate code for user actions', [['-o, --output <file name>', 'saves the generated script to a file'], ['--target <language>', `language to generate, one of javascript, playwright-test, python, python-async, python-pytest, csharp, csharp-mstest, csharp-nunit, java, java-junit`, codegenId()], ['--save-trace <filename>', 'record a trace for the session and save it to a file'], ['--test-id-attribute <attributeName>', 'use the specified attribute to generate data test ID selectors']]).action(function (url, options) {
58
+ commandWithOpenOptions('codegen [url]', 'open page and generate code for user actions', [['-o, --output <file name>', 'saves the generated script to a file'], ['--target <language>', `language to generate, one of javascript, playwright-test, python, python-async, python-pytest, csharp, csharp-mstest, csharp-nunit, java, java-junit`, codegenId()], ['--test-id-attribute <attributeName>', 'use the specified attribute to generate data test ID selectors']]).action(function (url, options) {
60
59
  codegen(options, url).catch(logErrorAndExit);
61
60
  }).addHelpText('afterAll', `
62
61
  Examples:
@@ -64,21 +63,6 @@ Examples:
64
63
  $ codegen
65
64
  $ codegen --target=python
66
65
  $ codegen -b webkit https://example.com`);
67
- _utilsBundle.program.command('debug <app> [args...]', {
68
- hidden: true
69
- }).description('run command in debug mode: disable timeout, open inspector').allowUnknownOption(true).action(function (app, options) {
70
- (0, _child_process.spawn)(app, options, {
71
- env: {
72
- ...process.env,
73
- PWDEBUG: '1'
74
- },
75
- stdio: 'inherit'
76
- });
77
- }).addHelpText('afterAll', `
78
- Examples:
79
-
80
- $ debug node test.js
81
- $ debug npm run test`);
82
66
  function suggestedBrowsersToInstall() {
83
67
  return _server.registry.executables().filter(e => e.installType !== 'none' && e.type !== 'tool').map(e => e.name).join(', ');
84
68
  }
@@ -105,6 +89,7 @@ function checkBrowsersToInstall(args, options) {
105
89
  handleArgument(arg);
106
90
  }
107
91
  }
92
+ if (process.platform === 'win32') executables.push(_server.registry.findExecutable('winldd'));
108
93
  if (faultyArguments.length) throw new Error(`Invalid installation targets: ${faultyArguments.map(name => `'${name}'`).join(', ')}. Expecting one of: ${suggestedBrowsersToInstall()}`);
109
94
  return executables;
110
95
  }
@@ -221,9 +206,7 @@ _utilsBundle.program.command('run-driver', {
221
206
  }).action(function (options) {
222
207
  (0, _driver.runDriver)();
223
208
  });
224
- _utilsBundle.program.command('run-server', {
225
- hidden: true
226
- }).option('--port <port>', 'Server port').option('--host <host>', 'Server host').option('--path <path>', 'Endpoint Path', '/').option('--max-clients <maxClients>', 'Maximum clients').option('--mode <mode>', 'Server mode, either "default" or "extension"').action(function (options) {
209
+ _utilsBundle.program.command('run-server').option('--port <port>', 'Server port').option('--host <host>', 'Server host').option('--path <path>', 'Endpoint Path', '/').option('--max-clients <maxClients>', 'Maximum clients').option('--mode <mode>', 'Server mode, either "default" or "extension"').action(function (options) {
227
210
  (0, _driver.runServer)({
228
211
  port: options.port ? +options.port : undefined,
229
212
  host: options.host,
@@ -317,13 +300,14 @@ async function launchContext(options, extraOptions) {
317
300
  // Viewport size
318
301
  if (options.viewportSize) {
319
302
  try {
320
- const [width, height] = options.viewportSize.split(',').map(n => parseInt(n, 10));
303
+ const [width, height] = options.viewportSize.split(',').map(n => +n);
304
+ if (isNaN(width) || isNaN(height)) throw new Error('bad values');
321
305
  contextOptions.viewport = {
322
306
  width,
323
307
  height
324
308
  };
325
309
  } catch (e) {
326
- throw new Error('Invalid viewport size format: use "width, height", for example --viewport-size=800,600');
310
+ throw new Error('Invalid viewport size format: use "width,height", for example --viewport-size="800,600"');
327
311
  }
328
312
  }
329
313
 
@@ -383,9 +367,6 @@ async function launchContext(options, extraOptions) {
383
367
  // a temporary page and we call closeBrowser again when that page closes.
384
368
  if (closingBrowser) return;
385
369
  closingBrowser = true;
386
- if (options.saveTrace) await context.tracing.stop({
387
- path: options.saveTrace
388
- });
389
370
  if (options.saveStorage) await context.storageState({
390
371
  path: options.saveStorage
391
372
  }).catch(e => null);
@@ -408,10 +389,6 @@ async function launchContext(options, extraOptions) {
408
389
  const timeout = options.timeout ? parseInt(options.timeout, 10) : 0;
409
390
  context.setDefaultTimeout(timeout);
410
391
  context.setDefaultNavigationTimeout(timeout);
411
- if (options.saveTrace) await context.tracing.start({
412
- screenshots: true,
413
- snapshots: true
414
- });
415
392
 
416
393
  // Omit options that we add automatically for presentation purpose.
417
394
  delete launchOptions.headless;
@@ -486,7 +463,6 @@ async function codegen(options, url) {
486
463
  device: options.device,
487
464
  saveStorage: options.saveStorage,
488
465
  mode: 'recording',
489
- codegenMode: process.env.PW_RECORDER_IS_TRACE_VIEWER ? 'trace-events' : 'actions',
490
466
  testIdAttributeName,
491
467
  outputFile: outputFile ? _path.default.resolve(outputFile) : undefined,
492
468
  handleSIGINT: false
@@ -126,30 +126,21 @@ class ChannelOwner extends _eventEmitter.EventEmitter {
126
126
  if (validator) {
127
127
  return async params => {
128
128
  return await this._wrapApiCall(async apiZone => {
129
- const {
130
- apiName,
131
- frames,
132
- csi,
133
- callCookie,
134
- stepId
135
- } = apiZone.reported ? {
136
- apiName: undefined,
137
- csi: undefined,
138
- callCookie: undefined,
139
- frames: [],
140
- stepId: undefined
141
- } : apiZone;
142
- apiZone.reported = true;
143
- let currentStepId = stepId;
144
- if (csi && apiName) {
145
- const out = {};
146
- csi.onApiCallBegin(apiName, params, frames, callCookie, out);
147
- currentStepId = out.stepId;
148
- }
149
- return await this._connection.sendMessageToServer(this, prop, validator(params, '', {
129
+ const validatedParams = validator(params, '', {
150
130
  tChannelImpl: tChannelImplToWire,
151
131
  binary: this._connection.rawBuffers() ? 'buffer' : 'toBase64'
152
- }), apiName, frames, currentStepId);
132
+ });
133
+ if (!apiZone.isInternal && !apiZone.reported) {
134
+ // Reporting/tracing/logging this api call for the first time.
135
+ apiZone.params = params;
136
+ apiZone.reported = true;
137
+ this._instrumentation.onApiCallBegin(apiZone);
138
+ logApiCall(this._logger, `=> ${apiZone.apiName} started`);
139
+ return await this._connection.sendMessageToServer(this, prop, validatedParams, apiZone.apiName, apiZone.frames, apiZone.stepId);
140
+ }
141
+ // Since this api call is either internal, or has already been reported/traced once,
142
+ // passing undefined apiName will avoid an extra unneeded tracing entry.
143
+ return await this._connection.sendMessageToServer(this, prop, validatedParams, undefined, [], undefined);
153
144
  });
154
145
  };
155
146
  }
@@ -162,45 +153,35 @@ class ChannelOwner extends _eventEmitter.EventEmitter {
162
153
  }
163
154
  async _wrapApiCall(func, isInternal) {
164
155
  const logger = this._logger;
165
- const apiZone = _zones.zones.zoneData('apiZone');
166
- if (apiZone) return await func(apiZone);
167
- const stackTrace = (0, _stackTrace.captureLibraryStackTrace)();
168
- let apiName = stackTrace.apiName;
169
- const frames = stackTrace.frames;
156
+ const existingApiZone = _zones.zones.zoneData('apiZone');
157
+ if (existingApiZone) return await func(existingApiZone);
170
158
  if (isInternal === undefined) isInternal = this._isInternalType;
171
- if (isInternal) apiName = undefined;
172
-
173
- // Enclosing zone could have provided the apiName and wallTime.
174
- const expectZone = _zones.zones.zoneData('expectZone');
175
- const stepId = expectZone === null || expectZone === void 0 ? void 0 : expectZone.stepId;
176
- if (!isInternal && expectZone) apiName = expectZone.title;
177
-
178
- // If we are coming from the expectZone, there is no need to generate a new
179
- // step for the API call, since it will be generated by the expect itself.
180
- const csi = isInternal || expectZone ? undefined : this._instrumentation;
181
- const callCookie = {};
159
+ const stackTrace = (0, _stackTrace.captureLibraryStackTrace)();
160
+ const apiZone = {
161
+ apiName: stackTrace.apiName,
162
+ frames: stackTrace.frames,
163
+ isInternal,
164
+ reported: false,
165
+ userData: undefined,
166
+ stepId: undefined
167
+ };
182
168
  try {
183
- logApiCall(logger, `=> ${apiName} started`, isInternal);
184
- const apiZone = {
185
- apiName,
186
- frames,
187
- isInternal,
188
- reported: false,
189
- csi,
190
- callCookie,
191
- stepId
192
- };
193
169
  const result = await _zones.zones.run('apiZone', apiZone, async () => await func(apiZone));
194
- csi === null || csi === void 0 || csi.onApiCallEnd(callCookie);
195
- logApiCall(logger, `<= ${apiName} succeeded`, isInternal);
170
+ if (!isInternal) {
171
+ logApiCall(logger, `<= ${apiZone.apiName} succeeded`);
172
+ this._instrumentation.onApiCallEnd(apiZone);
173
+ }
196
174
  return result;
197
175
  } catch (e) {
198
176
  const innerError = (process.env.PWDEBUGIMPL || (0, _utils.isUnderTest)()) && e.stack ? '\n<inner error>\n' + e.stack : '';
199
- if (apiName && !apiName.includes('<anonymous>')) e.message = apiName + ': ' + e.message;
177
+ if (apiZone.apiName && !apiZone.apiName.includes('<anonymous>')) e.message = apiZone.apiName + ': ' + e.message;
200
178
  const stackFrames = '\n' + (0, _stackTrace.stringifyStackFrames)(stackTrace.frames).join('\n') + innerError;
201
179
  if (stackFrames.trim()) e.stack = e.message + stackFrames;else e.stack = '';
202
- csi === null || csi === void 0 || csi.onApiCallEnd(callCookie, e);
203
- logApiCall(logger, `<= ${apiName} failed`, isInternal);
180
+ if (!isInternal) {
181
+ apiZone.error = e;
182
+ logApiCall(logger, `<= ${apiZone.apiName} failed`);
183
+ this._instrumentation.onApiCallEnd(apiZone);
184
+ }
204
185
  throw e;
205
186
  }
206
187
  }
@@ -220,8 +201,7 @@ class ChannelOwner extends _eventEmitter.EventEmitter {
220
201
  }
221
202
  }
222
203
  exports.ChannelOwner = ChannelOwner;
223
- function logApiCall(logger, message, isNested) {
224
- if (isNested) return;
204
+ function logApiCall(logger, message) {
225
205
  if (logger && logger.isEnabled('api', 'info')) logger.log('api', 'info', message, [], {
226
206
  color: 'cyan'
227
207
  });
@@ -20,6 +20,8 @@ exports.createInstrumentation = createInstrumentation;
20
20
  * limitations under the License.
21
21
  */
22
22
 
23
+ // Instrumentation can mutate the data, for example change apiName or stepId.
24
+
23
25
  function createInstrumentation() {
24
26
  const listeners = [];
25
27
  return new Proxy({}, {
@@ -76,9 +76,9 @@ class Connection extends _events.EventEmitter {
76
76
  this.toImpl = void 0;
77
77
  this._tracingCount = 0;
78
78
  this._instrumentation = void 0;
79
- this._rootObject = new Root(this);
80
- this._localUtils = localUtils;
81
79
  this._instrumentation = instrumentation || (0, _clientInstrumentation.createInstrumentation)();
80
+ this._localUtils = localUtils;
81
+ this._rootObject = new Root(this);
82
82
  }
83
83
  markAsRemote() {
84
84
  this._isRemote = true;
@@ -140,7 +140,7 @@ class Connection extends _events.EventEmitter {
140
140
  }).catch(() => {});
141
141
  // We need to exit zones before calling into the server, otherwise
142
142
  // when we receive events from the server, we would be in an API zone.
143
- _utils.zones.exitZones(() => this.onmessage({
143
+ _utils.zones.empty().run(() => this.onmessage({
144
144
  ...message,
145
145
  metadata
146
146
  }));
@@ -50,6 +50,7 @@ class Request extends _channelOwner.ChannelOwner {
50
50
  this._actualHeadersPromise = void 0;
51
51
  this._timing = void 0;
52
52
  this._fallbackOverrides = {};
53
+ this.markAsInternalType();
53
54
  this._redirectedFrom = Request.fromNullable(initializer.redirectedFrom);
54
55
  if (this._redirectedFrom) this._redirectedFrom._redirectedTo = this;
55
56
  this._provisionalHeaders = new RawHeaders(initializer.headers);
@@ -510,6 +511,7 @@ class Response extends _channelOwner.ChannelOwner {
510
511
  this._actualHeadersPromise = void 0;
511
512
  this._request = void 0;
512
513
  this._finishedPromise = new _manualPromise.ManualPromise();
514
+ this.markAsInternalType();
513
515
  this._provisionalHeaders = new RawHeaders(initializer.headers);
514
516
  this._request = Request.from(this._initializer.request);
515
517
  Object.assign(this._request._timing, this._initializer.timing);
@@ -659,7 +661,7 @@ class RouteHandler {
659
661
  this._times = times;
660
662
  this.url = url;
661
663
  this.handler = handler;
662
- this._svedZone = _utils.zones.currentZone();
664
+ this._svedZone = _utils.zones.current().without('apiZone');
663
665
  }
664
666
  static prepareInterceptionPatterns(handlers) {
665
667
  const patterns = [];
@@ -35,7 +35,7 @@ class Waiter {
35
35
  this._savedZone = void 0;
36
36
  this._waitId = (0, _utils.createGuid)();
37
37
  this._channelOwner = channelOwner;
38
- this._savedZone = _utils.zones.currentZone();
38
+ this._savedZone = _utils.zones.current().without('apiZone');
39
39
  this._channelOwner._channel.waitForEventInfo({
40
40
  info: {
41
41
  waitId: this._waitId,