rae-playwright-mcp 0.0.1 → 0.0.2

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 (160) hide show
  1. package/README.md +63 -21
  2. package/cli.js +7 -3
  3. package/index.js +1 -1
  4. package/lib/common/config.js +282 -0
  5. package/lib/common/config.js.map +7 -0
  6. package/lib/common/configLoader.js +345 -0
  7. package/lib/common/configLoader.js.map +7 -0
  8. package/lib/common/esmLoaderHost.js +105 -0
  9. package/lib/common/esmLoaderHost.js.map +7 -0
  10. package/lib/common/expectBundle.js +44 -0
  11. package/lib/common/expectBundle.js.map +7 -0
  12. package/lib/common/expectBundleImpl.js +15781 -0
  13. package/lib/common/expectBundleImpl.js.map +7 -0
  14. package/lib/common/fixtures.js +303 -0
  15. package/lib/common/fixtures.js.map +7 -0
  16. package/lib/common/globals.js +59 -0
  17. package/lib/common/globals.js.map +7 -0
  18. package/lib/common/ipc.js +61 -0
  19. package/lib/common/ipc.js.map +7 -0
  20. package/lib/common/poolBuilder.js +86 -0
  21. package/lib/common/poolBuilder.js.map +7 -0
  22. package/lib/common/process.js +133 -0
  23. package/lib/common/process.js.map +7 -0
  24. package/lib/common/suiteUtils.js +141 -0
  25. package/lib/common/suiteUtils.js.map +7 -0
  26. package/lib/common/test.js +323 -0
  27. package/lib/common/test.js.map +7 -0
  28. package/lib/common/testLoader.js +102 -0
  29. package/lib/common/testLoader.js.map +7 -0
  30. package/lib/common/testType.js +299 -0
  31. package/lib/common/testType.js.map +7 -0
  32. package/lib/common/validators.js +69 -0
  33. package/lib/common/validators.js.map +7 -0
  34. package/lib/mcp/browser/actions.d.js +17 -0
  35. package/lib/mcp/browser/actions.d.js.map +7 -0
  36. package/lib/mcp/browser/browserContextFactory.js +343 -0
  37. package/lib/mcp/browser/browserContextFactory.js.map +7 -0
  38. package/lib/mcp/browser/browserServerBackend.js +78 -0
  39. package/lib/mcp/browser/browserServerBackend.js.map +7 -0
  40. package/lib/mcp/browser/config.js +421 -0
  41. package/lib/mcp/browser/config.js.map +7 -0
  42. package/lib/mcp/browser/context.js +287 -0
  43. package/lib/mcp/browser/context.js.map +7 -0
  44. package/lib/mcp/browser/response.js +353 -0
  45. package/lib/mcp/browser/response.js.map +7 -0
  46. package/lib/mcp/browser/sessionLog.js +161 -0
  47. package/lib/mcp/browser/sessionLog.js.map +7 -0
  48. package/lib/mcp/browser/tab.js +329 -0
  49. package/lib/mcp/browser/tab.js.map +7 -0
  50. package/lib/mcp/browser/tools/common.js +64 -0
  51. package/lib/mcp/browser/tools/common.js.map +7 -0
  52. package/lib/mcp/browser/tools/console.js +45 -0
  53. package/lib/mcp/browser/tools/console.js.map +7 -0
  54. package/lib/mcp/browser/tools/dialogs.js +61 -0
  55. package/lib/mcp/browser/tools/dialogs.js.map +7 -0
  56. package/lib/mcp/browser/tools/evaluate.js +60 -0
  57. package/lib/mcp/browser/tools/evaluate.js.map +7 -0
  58. package/lib/mcp/browser/tools/files.js +59 -0
  59. package/lib/mcp/browser/tools/files.js.map +7 -0
  60. package/lib/mcp/browser/tools/form.js +64 -0
  61. package/lib/mcp/browser/tools/form.js.map +7 -0
  62. package/lib/mcp/browser/tools/install.js +70 -0
  63. package/lib/mcp/browser/tools/install.js.map +7 -0
  64. package/lib/mcp/browser/tools/keyboard.js +85 -0
  65. package/lib/mcp/browser/tools/keyboard.js.map +7 -0
  66. package/lib/mcp/browser/tools/mouse.js +108 -0
  67. package/lib/mcp/browser/tools/mouse.js.map +7 -0
  68. package/lib/mcp/browser/tools/navigate.js +63 -0
  69. package/lib/mcp/browser/tools/navigate.js.map +7 -0
  70. package/lib/mcp/browser/tools/network.js +61 -0
  71. package/lib/mcp/browser/tools/network.js.map +7 -0
  72. package/lib/mcp/browser/tools/pdf.js +49 -0
  73. package/lib/mcp/browser/tools/pdf.js.map +7 -0
  74. package/lib/mcp/browser/tools/runCode.js +78 -0
  75. package/lib/mcp/browser/tools/runCode.js.map +7 -0
  76. package/lib/mcp/browser/tools/screenshot.js +106 -0
  77. package/lib/mcp/browser/tools/screenshot.js.map +7 -0
  78. package/lib/mcp/browser/tools/snapshot.js +192 -0
  79. package/lib/mcp/browser/tools/snapshot.js.map +7 -0
  80. package/lib/mcp/browser/tools/tabs.js +68 -0
  81. package/lib/mcp/browser/tools/tabs.js.map +7 -0
  82. package/lib/mcp/browser/tools/tool.js +51 -0
  83. package/lib/mcp/browser/tools/tool.js.map +7 -0
  84. package/lib/mcp/browser/tools/tracing.js +76 -0
  85. package/lib/mcp/browser/tools/tracing.js.map +7 -0
  86. package/lib/mcp/browser/tools/utils.js +95 -0
  87. package/lib/mcp/browser/tools/utils.js.map +7 -0
  88. package/lib/mcp/browser/tools/verify.js +144 -0
  89. package/lib/mcp/browser/tools/verify.js.map +7 -0
  90. package/lib/mcp/browser/tools/wait.js +64 -0
  91. package/lib/mcp/browser/tools/wait.js.map +7 -0
  92. package/lib/mcp/browser/tools.js +83 -0
  93. package/lib/mcp/browser/tools.js.map +7 -0
  94. package/lib/mcp/browser/watchdog.js +45 -0
  95. package/lib/mcp/browser/watchdog.js.map +7 -0
  96. package/lib/mcp/config.d.js +17 -0
  97. package/lib/mcp/config.d.js.map +7 -0
  98. package/lib/mcp/config.d.ts +197 -0
  99. package/lib/mcp/extension/cdpRelay.js +352 -0
  100. package/lib/mcp/extension/cdpRelay.js.map +7 -0
  101. package/lib/mcp/extension/extensionContextFactory.js +77 -0
  102. package/lib/mcp/extension/extensionContextFactory.js.map +7 -0
  103. package/lib/mcp/extension/protocol.js +29 -0
  104. package/lib/mcp/extension/protocol.js.map +7 -0
  105. package/lib/mcp/index.js +62 -0
  106. package/lib/mcp/index.js.map +7 -0
  107. package/lib/mcp/log.js +36 -0
  108. package/lib/mcp/log.js.map +7 -0
  109. package/lib/mcp/program.js +94 -0
  110. package/lib/mcp/program.js.map +7 -0
  111. package/lib/mcp/sdk/exports.js +29 -0
  112. package/lib/mcp/sdk/exports.js.map +7 -0
  113. package/lib/mcp/sdk/http.js +153 -0
  114. package/lib/mcp/sdk/http.js.map +7 -0
  115. package/lib/mcp/sdk/inProcessTransport.js +72 -0
  116. package/lib/mcp/sdk/inProcessTransport.js.map +7 -0
  117. package/lib/mcp/sdk/server.js +208 -0
  118. package/lib/mcp/sdk/server.js.map +7 -0
  119. package/lib/mcp/sdk/tool.js +48 -0
  120. package/lib/mcp/sdk/tool.js.map +7 -0
  121. package/lib/mcp/test/browserBackend.js +99 -0
  122. package/lib/mcp/test/browserBackend.js.map +7 -0
  123. package/lib/mcp/test/generatorTools.js +123 -0
  124. package/lib/mcp/test/generatorTools.js.map +7 -0
  125. package/lib/mcp/test/plannerTools.js +145 -0
  126. package/lib/mcp/test/plannerTools.js.map +7 -0
  127. package/lib/mcp/test/seed.js +83 -0
  128. package/lib/mcp/test/seed.js.map +7 -0
  129. package/lib/mcp/test/streams.js +45 -0
  130. package/lib/mcp/test/streams.js.map +7 -0
  131. package/lib/mcp/test/testBackend.js +100 -0
  132. package/lib/mcp/test/testBackend.js.map +7 -0
  133. package/lib/mcp/test/testContext.js +280 -0
  134. package/lib/mcp/test/testContext.js.map +7 -0
  135. package/lib/mcp/test/testTool.js +31 -0
  136. package/lib/mcp/test/testTool.js.map +7 -0
  137. package/lib/mcp/test/testTools.js +109 -0
  138. package/lib/mcp/test/testTools.js.map +7 -0
  139. package/lib/third_party/pirates.js +63 -0
  140. package/lib/third_party/pirates.js.map +7 -0
  141. package/lib/third_party/tsconfig-loader.js +104 -0
  142. package/lib/third_party/tsconfig-loader.js.map +7 -0
  143. package/lib/transform/babelBundle.js +44 -0
  144. package/lib/transform/babelBundle.js.map +7 -0
  145. package/lib/transform/babelBundleImpl.js +68726 -0
  146. package/lib/transform/babelBundleImpl.js.map +7 -0
  147. package/lib/transform/babelHighlightUtils.js +64 -0
  148. package/lib/transform/babelHighlightUtils.js.map +7 -0
  149. package/lib/transform/compilationCache.js +273 -0
  150. package/lib/transform/compilationCache.js.map +7 -0
  151. package/lib/transform/esmLoader.js +104 -0
  152. package/lib/transform/esmLoader.js.map +7 -0
  153. package/lib/transform/portTransport.js +68 -0
  154. package/lib/transform/portTransport.js.map +7 -0
  155. package/lib/transform/transform.js +297 -0
  156. package/lib/transform/transform.js.map +7 -0
  157. package/lib/util.js +404 -0
  158. package/lib/utilsBundle.js +44 -0
  159. package/lib/utilsBundleImpl.js +13122 -0
  160. package/package.json +4 -3
package/README.md CHANGED
@@ -1,17 +1,37 @@
1
- ## Playwright MCP
1
+ ## RAE Playwright MCP
2
2
 
3
- A Model Context Protocol (MCP) server that provides browser automation capabilities using [Playwright](https://playwright.dev). This server enables LLMs to interact with web pages through structured accessibility snapshots, bypassing the need for screenshots or visually-tuned models.
3
+ A fork of [Playwright MCP](https://github.com/microsoft/playwright) with enhanced features for browser automation and network recording. This Model Context Protocol (MCP) server provides browser automation capabilities using [Playwright](https://playwright.dev), enabling LLMs to interact with web pages through structured accessibility snapshots.
4
4
 
5
5
  ### Key Features
6
6
 
7
7
  - **Fast and lightweight**. Uses Playwright's accessibility tree, not pixel-based input.
8
8
  - **LLM-friendly**. No vision models needed, operates purely on structured data.
9
9
  - **Deterministic tool application**. Avoids ambiguity common with screenshot-based approaches.
10
+ - **HAR Recording**. Automatically records network traffic (HAR files) for all browser sessions.
11
+ - **Customizable Run IDs**. Use `--run-id` to specify custom identifiers for HAR file organization.
12
+ - **Enhanced Tracing**. Tracing capabilities enabled by default with source code capture.
10
13
 
11
14
  ### Requirements
12
15
  - Node.js 18 or newer
13
16
  - VS Code, Cursor, Windsurf, Claude Desktop, Goose or any other MCP client
14
17
 
18
+ ### Repository
19
+
20
+ - **GitHub**: [https://github.com/kalil0321/rae-playwright-mcp](https://github.com/kalil0321/rae-playwright-mcp)
21
+ - **npm**: `rae-playwright-mcp`
22
+
23
+ ### Development
24
+
25
+ To test locally:
26
+ ```bash
27
+ # Run the MCP server
28
+ node cli.js run-mcp-server
29
+
30
+ # Or test with MCP Inspector
31
+ npx @modelcontextprotocol/inspector
32
+ # Then configure: command=node, args=cli.js run-mcp-server
33
+ ```
34
+
15
35
  <!--
16
36
  // Generate using:
17
37
  node utils/generate-links.js
@@ -29,13 +49,15 @@ First, install the Playwright MCP server with your client.
29
49
  "playwright": {
30
50
  "command": "npx",
31
51
  "args": [
32
- "@playwright/mcp@latest"
52
+ "rae-playwright-mcp@latest"
33
53
  ]
34
54
  }
35
55
  }
36
56
  }
37
57
  ```
38
58
 
59
+ > **Note**: This is a fork with custom features. For the original Playwright MCP, use `@playwright/mcp@latest`.
60
+
39
61
  [<img src="https://img.shields.io/badge/VS_Code-VS_Code?style=flat-square&label=Install%20Server&color=0098FF" alt="Install in VS Code">](https://insiders.vscode.dev/redirect?url=vscode%3Amcp%2Finstall%3F%257B%2522name%2522%253A%2522playwright%2522%252C%2522command%2522%253A%2522npx%2522%252C%2522args%2522%253A%255B%2522%2540playwright%252Fmcp%2540latest%2522%255D%257D) [<img alt="Install in VS Code Insiders" src="https://img.shields.io/badge/VS_Code_Insiders-VS_Code_Insiders?style=flat-square&label=Install%20Server&color=24bfa5">](https://insiders.vscode.dev/redirect?url=vscode-insiders%3Amcp%2Finstall%3F%257B%2522name%2522%253A%2522playwright%2522%252C%2522command%2522%253A%2522npx%2522%252C%2522args%2522%253A%255B%2522%2540playwright%252Fmcp%2540latest%2522%255D%257D)
40
62
 
41
63
  <details>
@@ -48,7 +70,7 @@ Add via the Amp VS Code extension settings screen or by updating your settings.j
48
70
  "playwright": {
49
71
  "command": "npx",
50
72
  "args": [
51
- "@playwright/mcp@latest"
73
+ "rae-playwright-mcp@latest"
52
74
  ]
53
75
  }
54
76
  }
@@ -59,7 +81,7 @@ Add via the Amp VS Code extension settings screen or by updating your settings.j
59
81
  Add via the `amp mcp add`command below
60
82
 
61
83
  ```bash
62
- amp mcp add playwright -- npx @playwright/mcp@latest
84
+ amp mcp add playwright -- npx rae-playwright-mcp@latest
63
85
  ```
64
86
 
65
87
  </details>
@@ -70,7 +92,7 @@ amp mcp add playwright -- npx @playwright/mcp@latest
70
92
  Use the Claude Code CLI to add the Playwright MCP server:
71
93
 
72
94
  ```bash
73
- claude mcp add playwright npx @playwright/mcp@latest
95
+ claude mcp add playwright npx rae-playwright-mcp@latest
74
96
  ```
75
97
  </details>
76
98
 
@@ -87,7 +109,7 @@ Follow the MCP install [guide](https://modelcontextprotocol.io/quickstart/user),
87
109
  Use the Codex CLI to add the Playwright MCP server:
88
110
 
89
111
  ```bash
90
- codex mcp add playwright npx "@playwright/mcp@latest"
112
+ codex mcp add playwright npx "rae-playwright-mcp@latest"
91
113
  ```
92
114
 
93
115
  Alternatively, create or edit the configuration file `~/.codex/config.toml` and add:
@@ -95,7 +117,7 @@ Alternatively, create or edit the configuration file `~/.codex/config.toml` and
95
117
  ```toml
96
118
  [mcp_servers.playwright]
97
119
  command = "npx"
98
- args = ["@playwright/mcp@latest"]
120
+ args = ["rae-playwright-mcp@latest"]
99
121
  ```
100
122
 
101
123
  For more information, see the [Codex MCP documentation](https://github.com/openai/codex/blob/main/codex-rs/config.md#mcp_servers).
@@ -123,7 +145,7 @@ Alternatively, create or edit the configuration file `~/.copilot/mcp-config.json
123
145
  "*"
124
146
  ],
125
147
  "args": [
126
- "@playwright/mcp@latest"
148
+ "rae-playwright-mcp@latest"
127
149
  ]
128
150
  }
129
151
  }
@@ -143,7 +165,7 @@ For more information, see the [Copilot CLI documentation](https://docs.github.co
143
165
 
144
166
  #### Or install manually:
145
167
 
146
- Go to `Cursor Settings` -> `MCP` -> `Add new MCP Server`. Name to your liking, use `command` type with the command `npx @playwright/mcp@latest`. You can also verify config or add command like arguments via clicking `Edit`.
168
+ Go to `Cursor Settings` -> `MCP` -> `Add new MCP Server`. Name to your liking, use `command` type with the command `npx rae-playwright-mcp@latest`. You can also verify config or add command like arguments via clicking `Edit`.
147
169
 
148
170
  </details>
149
171
 
@@ -153,7 +175,7 @@ Go to `Cursor Settings` -> `MCP` -> `Add new MCP Server`. Name to your liking, u
153
175
  Use the Factory CLI to add the Playwright MCP server:
154
176
 
155
177
  ```bash
156
- droid mcp add playwright "npx @playwright/mcp@latest"
178
+ droid mcp add playwright "npx rae-playwright-mcp@latest"
157
179
  ```
158
180
 
159
181
  Alternatively, type `/mcp` within Factory droid to open an interactive UI for managing MCP servers.
@@ -178,7 +200,7 @@ Follow the MCP install [guide](https://github.com/google-gemini/gemini-cli/blob/
178
200
 
179
201
  #### Or install manually:
180
202
 
181
- Go to `Advanced settings` -> `Extensions` -> `Add custom extension`. Name to your liking, use type `STDIO`, and set the `command` to `npx @playwright/mcp`. Click "Add Extension".
203
+ Go to `Advanced settings` -> `Extensions` -> `Add custom extension`. Name to your liking, use type `STDIO`, and set the `command` to `npx rae-playwright-mcp`. Click "Add Extension".
182
204
  </details>
183
205
 
184
206
  <details>
@@ -192,7 +214,7 @@ Follow the MCP Servers [documentation](https://kiro.dev/docs/mcp/). For example
192
214
  "playwright": {
193
215
  "command": "npx",
194
216
  "args": [
195
- "@playwright/mcp@latest"
217
+ "rae-playwright-mcp@latest"
196
218
  ]
197
219
  }
198
220
  }
@@ -225,7 +247,7 @@ Follow the MCP Servers [documentation](https://opencode.ai/docs/mcp-servers/). F
225
247
  "type": "local",
226
248
  "command": [
227
249
  "npx",
228
- "@playwright/mcp@latest"
250
+ "rae-playwright-mcp@latest"
229
251
  ],
230
252
  "enabled": true
231
253
  }
@@ -256,7 +278,7 @@ Follow the MCP install [guide](https://code.visualstudio.com/docs/copilot/chat/m
256
278
 
257
279
  ```bash
258
280
  # For VS Code
259
- code --add-mcp '{"name":"playwright","command":"npx","args":["@playwright/mcp@latest"]}'
281
+ code --add-mcp '{"name":"playwright","command":"npx","args":["rae-playwright-mcp@latest"]}'
260
282
  ```
261
283
 
262
284
  After installation, the Playwright MCP server will be available for use with your GitHub Copilot agent in VS Code.
@@ -274,7 +296,7 @@ Alternatively, use the slash command `/add-mcp` in the Warp prompt and paste the
274
296
  "playwright": {
275
297
  "command": "npx",
276
298
  "args": [
277
- "@playwright/mcp@latest"
299
+ "rae-playwright-mcp@latest"
278
300
  ]
279
301
  }
280
302
  }
@@ -294,10 +316,30 @@ Follow Windsurf MCP [documentation](https://docs.windsurf.com/windsurf/cascade/m
294
316
 
295
317
  Playwright MCP server supports following arguments. They can be provided in the JSON configuration above, as a part of the `"args"` list:
296
318
 
319
+ #### Custom Features in This Fork
320
+
321
+ This fork includes additional features beyond the original Playwright MCP:
322
+
323
+ - **`--run-id <id>`**: Specify a custom UUID for HAR file organization. HAR files are saved to `~/.reverse-api-engineer/runs/testing-playwright/{run-id}/network.har`. If not provided, a UUID is automatically generated.
324
+ - **Automatic HAR Recording**: All browser sessions automatically record network traffic in HAR format. The HAR file path is logged when the server starts.
325
+ - **Default Tracing**: Tracing capabilities are enabled by default with source code capture (`sources: true`)
326
+ - **Self-contained Package**: All MCP code is bundled in the package, no dependency on the Playwright monorepo
327
+
328
+ #### Differences from Original
329
+
330
+ This is a fork of the official [Playwright MCP](https://github.com/microsoft/playwright) with the following modifications:
331
+
332
+ - HAR recording enabled by default for all browser contexts
333
+ - Custom `--run-id` CLI option for organizing HAR files
334
+ - Tracing enabled by default with source code capture
335
+ - Self-contained package (all code bundled, no monorepo dependency)
336
+
337
+ For the original Playwright MCP, visit: [@playwright/mcp](https://www.npmjs.com/package/@playwright/mcp)
338
+
297
339
  <!--- Options generated by update-readme.js -->
298
340
 
299
341
  ```
300
- > npx @playwright/mcp@latest --help
342
+ > npx rae-playwright-mcp@latest --help
301
343
  --allowed-hosts <hosts...> comma-separated list of hosts this
302
344
  server is allowed to serve from.
303
345
  Defaults to the host the server is bound
@@ -437,7 +479,7 @@ state [here](https://playwright.dev/docs/auth).
437
479
  "playwright": {
438
480
  "command": "npx",
439
481
  "args": [
440
- "@playwright/mcp@latest",
482
+ "rae-playwright-mcp@latest",
441
483
  "--isolated",
442
484
  "--storage-state={path/to/storage.json}"
443
485
  ]
@@ -485,7 +527,7 @@ The Playwright MCP server can be configured using a JSON configuration file. You
485
527
  using the `--config` command line option:
486
528
 
487
529
  ```bash
488
- npx @playwright/mcp@latest --config path/to/config.json
530
+ npx rae-playwright-mcp@latest --config path/to/config.json
489
531
  ```
490
532
 
491
533
  <details>
@@ -683,7 +725,7 @@ When running headed browser on system w/o display or from worker processes of th
683
725
  run the MCP server from environment with the DISPLAY and pass the `--port` flag to enable HTTP transport.
684
726
 
685
727
  ```bash
686
- npx @playwright/mcp@latest --port 8931
728
+ npx rae-playwright-mcp@latest --port 8931
687
729
  ```
688
730
 
689
731
  And then in MCP client config, set the `url` to the HTTP endpoint:
@@ -740,7 +782,7 @@ docker build -t mcr.microsoft.com/playwright/mcp .
740
782
  ```js
741
783
  import http from 'http';
742
784
 
743
- import { createConnection } from '@playwright/mcp';
785
+ import { createConnection } from 'rae-playwright-mcp';
744
786
  import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
745
787
 
746
788
  http.createServer(async (req, res) => {
package/cli.js CHANGED
@@ -16,9 +16,13 @@
16
16
  */
17
17
 
18
18
  const { program } = require('playwright-core/lib/utilsBundle');
19
- const { decorateCommand } = require('playwright/lib/mcp/program');
19
+ const { decorateCommand } = require('./lib/mcp/program');
20
20
 
21
21
  const packageJSON = require('./package.json');
22
22
  const p = program.version('Version ' + packageJSON.version).name('Playwright MCP');
23
- decorateCommand(p, packageJSON.version)
24
- void program.parseAsync(process.argv);
23
+
24
+ // Create the run-mcp-server subcommand
25
+ const command = p.command('run-mcp-server', { hidden: true });
26
+ decorateCommand(command, packageJSON.version);
27
+
28
+ void p.parseAsync(process.argv);
package/index.js CHANGED
@@ -15,5 +15,5 @@
15
15
  * limitations under the License.
16
16
  */
17
17
 
18
- const { createConnection } = require('playwright/lib/mcp/index');
18
+ const { createConnection } = require('./lib/mcp/index');
19
19
  module.exports = { createConnection };
@@ -0,0 +1,282 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var config_exports = {};
30
+ __export(config_exports, {
31
+ FullConfigInternal: () => FullConfigInternal,
32
+ FullProjectInternal: () => FullProjectInternal,
33
+ builtInReporters: () => builtInReporters,
34
+ defaultGrep: () => defaultGrep,
35
+ defaultReporter: () => defaultReporter,
36
+ defaultTimeout: () => defaultTimeout,
37
+ getProjectId: () => getProjectId,
38
+ takeFirst: () => takeFirst,
39
+ toReporters: () => toReporters
40
+ });
41
+ module.exports = __toCommonJS(config_exports);
42
+ var import_fs = __toESM(require("fs"));
43
+ var import_os = __toESM(require("os"));
44
+ var import_path = __toESM(require("path"));
45
+ var import_util = require("../util");
46
+ const defaultTimeout = 3e4;
47
+ class FullConfigInternal {
48
+ constructor(location, userConfig, configCLIOverrides, metadata) {
49
+ this.projects = [];
50
+ this.cliArgs = [];
51
+ this.cliListOnly = false;
52
+ this.preOnlyTestFilters = [];
53
+ this.postShardTestFilters = [];
54
+ this.defineConfigWasUsed = false;
55
+ this.globalSetups = [];
56
+ this.globalTeardowns = [];
57
+ if (configCLIOverrides.projects && userConfig.projects)
58
+ throw new Error(`Cannot use --browser option when configuration file defines projects. Specify browserName in the projects instead.`);
59
+ const { resolvedConfigFile, configDir } = location;
60
+ const packageJsonPath = (0, import_util.getPackageJsonPath)(configDir);
61
+ const packageJsonDir = packageJsonPath ? import_path.default.dirname(packageJsonPath) : process.cwd();
62
+ this.configDir = configDir;
63
+ this.configCLIOverrides = configCLIOverrides;
64
+ const privateConfiguration = userConfig["@playwright/test"];
65
+ this.plugins = (privateConfiguration?.plugins || []).map((p) => ({ factory: p }));
66
+ this.singleTSConfigPath = pathResolve(configDir, userConfig.tsconfig);
67
+ this.captureGitInfo = userConfig.captureGitInfo;
68
+ this.failOnFlakyTests = takeFirst(configCLIOverrides.failOnFlakyTests, userConfig.failOnFlakyTests, false);
69
+ this.globalSetups = (Array.isArray(userConfig.globalSetup) ? userConfig.globalSetup : [userConfig.globalSetup]).map((s) => resolveScript(s, configDir)).filter((script) => script !== void 0);
70
+ this.globalTeardowns = (Array.isArray(userConfig.globalTeardown) ? userConfig.globalTeardown : [userConfig.globalTeardown]).map((s) => resolveScript(s, configDir)).filter((script) => script !== void 0);
71
+ userConfig.metadata = userConfig.metadata || {};
72
+ const globalTags = Array.isArray(userConfig.tag) ? userConfig.tag : userConfig.tag ? [userConfig.tag] : [];
73
+ for (const tag of globalTags) {
74
+ if (tag[0] !== "@")
75
+ throw new Error(`Tag must start with "@" symbol, got "${tag}" instead.`);
76
+ }
77
+ this.config = {
78
+ configFile: resolvedConfigFile,
79
+ rootDir: pathResolve(configDir, userConfig.testDir) || configDir,
80
+ forbidOnly: takeFirst(configCLIOverrides.forbidOnly, userConfig.forbidOnly, false),
81
+ fullyParallel: takeFirst(configCLIOverrides.fullyParallel, userConfig.fullyParallel, false),
82
+ globalSetup: this.globalSetups[0] ?? null,
83
+ globalTeardown: this.globalTeardowns[0] ?? null,
84
+ globalTimeout: takeFirst(configCLIOverrides.debug ? 0 : void 0, configCLIOverrides.globalTimeout, userConfig.globalTimeout, 0),
85
+ grep: takeFirst(userConfig.grep, defaultGrep),
86
+ grepInvert: takeFirst(userConfig.grepInvert, null),
87
+ maxFailures: takeFirst(configCLIOverrides.debug ? 1 : void 0, configCLIOverrides.maxFailures, userConfig.maxFailures, 0),
88
+ metadata: metadata ?? userConfig.metadata,
89
+ preserveOutput: takeFirst(userConfig.preserveOutput, "always"),
90
+ projects: [],
91
+ quiet: takeFirst(configCLIOverrides.quiet, userConfig.quiet, false),
92
+ reporter: takeFirst(configCLIOverrides.reporter, resolveReporters(userConfig.reporter, configDir), [[defaultReporter]]),
93
+ reportSlowTests: takeFirst(userConfig.reportSlowTests, {
94
+ max: 5,
95
+ threshold: 3e5
96
+ /* 5 minutes */
97
+ }),
98
+ runAgents: takeFirst(configCLIOverrides.runAgents, userConfig.runAgents, "none"),
99
+ shard: takeFirst(configCLIOverrides.shard, userConfig.shard, null),
100
+ tags: globalTags,
101
+ updateSnapshots: takeFirst(configCLIOverrides.updateSnapshots, userConfig.updateSnapshots, "missing"),
102
+ updateSourceMethod: takeFirst(configCLIOverrides.updateSourceMethod, userConfig.updateSourceMethod, "patch"),
103
+ version: require("../../package.json").version,
104
+ workers: resolveWorkers(takeFirst(configCLIOverrides.debug ? 1 : void 0, configCLIOverrides.workers, userConfig.workers, "50%")),
105
+ webServer: null
106
+ };
107
+ for (const key in userConfig) {
108
+ if (key.startsWith("@"))
109
+ this.config[key] = userConfig[key];
110
+ }
111
+ this.config[configInternalSymbol] = this;
112
+ const webServers = takeFirst(userConfig.webServer, null);
113
+ if (Array.isArray(webServers)) {
114
+ this.config.webServer = null;
115
+ this.webServers = webServers;
116
+ } else if (webServers) {
117
+ this.config.webServer = webServers;
118
+ this.webServers = [webServers];
119
+ } else {
120
+ this.webServers = [];
121
+ }
122
+ const projectConfigs = configCLIOverrides.projects || userConfig.projects || [{ ...userConfig, workers: void 0 }];
123
+ this.projects = projectConfigs.map((p) => new FullProjectInternal(configDir, userConfig, this, p, this.configCLIOverrides, packageJsonDir));
124
+ resolveProjectDependencies(this.projects);
125
+ this._assignUniqueProjectIds(this.projects);
126
+ this.config.projects = this.projects.map((p) => p.project);
127
+ }
128
+ _assignUniqueProjectIds(projects) {
129
+ const usedNames = /* @__PURE__ */ new Set();
130
+ for (const p of projects) {
131
+ const name = p.project.name || "";
132
+ for (let i = 0; i < projects.length; ++i) {
133
+ const candidate = name + (i ? i : "");
134
+ if (usedNames.has(candidate))
135
+ continue;
136
+ p.id = candidate;
137
+ p.project.__projectId = p.id;
138
+ usedNames.add(candidate);
139
+ break;
140
+ }
141
+ }
142
+ }
143
+ }
144
+ class FullProjectInternal {
145
+ constructor(configDir, config, fullConfig, projectConfig, configCLIOverrides, packageJsonDir) {
146
+ this.id = "";
147
+ this.deps = [];
148
+ this.fullConfig = fullConfig;
149
+ const testDir = takeFirst(pathResolve(configDir, projectConfig.testDir), pathResolve(configDir, config.testDir), fullConfig.configDir);
150
+ this.snapshotPathTemplate = takeFirst(projectConfig.snapshotPathTemplate, config.snapshotPathTemplate);
151
+ this.project = {
152
+ grep: takeFirst(projectConfig.grep, config.grep, defaultGrep),
153
+ grepInvert: takeFirst(projectConfig.grepInvert, config.grepInvert, null),
154
+ outputDir: takeFirst(configCLIOverrides.outputDir, pathResolve(configDir, projectConfig.outputDir), pathResolve(configDir, config.outputDir), import_path.default.join(packageJsonDir, "test-results")),
155
+ // Note: we either apply the cli override for repeatEach or not, depending on whether the
156
+ // project is top-level vs dependency. See collectProjectsAndTestFiles in loadUtils.
157
+ repeatEach: takeFirst(projectConfig.repeatEach, config.repeatEach, 1),
158
+ retries: takeFirst(configCLIOverrides.retries, projectConfig.retries, config.retries, 0),
159
+ metadata: takeFirst(projectConfig.metadata, config.metadata, {}),
160
+ name: takeFirst(projectConfig.name, config.name, ""),
161
+ testDir,
162
+ snapshotDir: takeFirst(pathResolve(configDir, projectConfig.snapshotDir), pathResolve(configDir, config.snapshotDir), testDir),
163
+ testIgnore: takeFirst(projectConfig.testIgnore, config.testIgnore, []),
164
+ testMatch: takeFirst(projectConfig.testMatch, config.testMatch, "**/*.@(spec|test).?(c|m)[jt]s?(x)"),
165
+ timeout: takeFirst(configCLIOverrides.debug ? 0 : void 0, configCLIOverrides.timeout, projectConfig.timeout, config.timeout, defaultTimeout),
166
+ use: (0, import_util.mergeObjects)(config.use, projectConfig.use, configCLIOverrides.use),
167
+ dependencies: projectConfig.dependencies || [],
168
+ teardown: projectConfig.teardown
169
+ };
170
+ this.fullyParallel = takeFirst(configCLIOverrides.fullyParallel, projectConfig.fullyParallel, config.fullyParallel, void 0);
171
+ this.expect = takeFirst(projectConfig.expect, config.expect, {});
172
+ if (this.expect.toHaveScreenshot?.stylePath) {
173
+ const stylePaths = Array.isArray(this.expect.toHaveScreenshot.stylePath) ? this.expect.toHaveScreenshot.stylePath : [this.expect.toHaveScreenshot.stylePath];
174
+ this.expect.toHaveScreenshot.stylePath = stylePaths.map((stylePath) => import_path.default.resolve(configDir, stylePath));
175
+ }
176
+ this.respectGitIgnore = takeFirst(projectConfig.respectGitIgnore, config.respectGitIgnore, !projectConfig.testDir && !config.testDir);
177
+ this.ignoreSnapshots = takeFirst(configCLIOverrides.ignoreSnapshots, projectConfig.ignoreSnapshots, config.ignoreSnapshots, false);
178
+ this.workers = projectConfig.workers ? resolveWorkers(projectConfig.workers) : void 0;
179
+ if (configCLIOverrides.debug && this.workers)
180
+ this.workers = 1;
181
+ }
182
+ }
183
+ function takeFirst(...args) {
184
+ for (const arg of args) {
185
+ if (arg !== void 0)
186
+ return arg;
187
+ }
188
+ return void 0;
189
+ }
190
+ function pathResolve(baseDir, relative) {
191
+ if (!relative)
192
+ return void 0;
193
+ return import_path.default.resolve(baseDir, relative);
194
+ }
195
+ function resolveReporters(reporters, rootDir) {
196
+ return toReporters(reporters)?.map(([id, arg]) => {
197
+ if (builtInReporters.includes(id))
198
+ return [id, arg];
199
+ return [require.resolve(id, { paths: [rootDir] }), arg];
200
+ });
201
+ }
202
+ function resolveWorkers(workers) {
203
+ if (typeof workers === "string") {
204
+ if (workers.endsWith("%")) {
205
+ const cpus = import_os.default.cpus().length;
206
+ return Math.max(1, Math.floor(cpus * (parseInt(workers, 10) / 100)));
207
+ }
208
+ const parsedWorkers = parseInt(workers, 10);
209
+ if (isNaN(parsedWorkers))
210
+ throw new Error(`Workers ${workers} must be a number or percentage.`);
211
+ return parsedWorkers;
212
+ }
213
+ return workers;
214
+ }
215
+ function resolveProjectDependencies(projects) {
216
+ const teardownSet = /* @__PURE__ */ new Set();
217
+ for (const project of projects) {
218
+ for (const dependencyName of project.project.dependencies) {
219
+ const dependencies = projects.filter((p) => p.project.name === dependencyName);
220
+ if (!dependencies.length)
221
+ throw new Error(`Project '${project.project.name}' depends on unknown project '${dependencyName}'`);
222
+ if (dependencies.length > 1)
223
+ throw new Error(`Project dependencies should have unique names, reading ${dependencyName}`);
224
+ project.deps.push(...dependencies);
225
+ }
226
+ if (project.project.teardown) {
227
+ const teardowns = projects.filter((p) => p.project.name === project.project.teardown);
228
+ if (!teardowns.length)
229
+ throw new Error(`Project '${project.project.name}' has unknown teardown project '${project.project.teardown}'`);
230
+ if (teardowns.length > 1)
231
+ throw new Error(`Project teardowns should have unique names, reading ${project.project.teardown}`);
232
+ const teardown = teardowns[0];
233
+ project.teardown = teardown;
234
+ teardownSet.add(teardown);
235
+ }
236
+ }
237
+ for (const teardown of teardownSet) {
238
+ if (teardown.deps.length)
239
+ throw new Error(`Teardown project ${teardown.project.name} must not have dependencies`);
240
+ }
241
+ for (const project of projects) {
242
+ for (const dep of project.deps) {
243
+ if (teardownSet.has(dep))
244
+ throw new Error(`Project ${project.project.name} must not depend on a teardown project ${dep.project.name}`);
245
+ }
246
+ }
247
+ }
248
+ function toReporters(reporters) {
249
+ if (!reporters)
250
+ return;
251
+ if (typeof reporters === "string")
252
+ return [[reporters]];
253
+ return reporters;
254
+ }
255
+ const builtInReporters = ["list", "line", "dot", "json", "junit", "null", "github", "html", "blob"];
256
+ function resolveScript(id, rootDir) {
257
+ if (!id)
258
+ return void 0;
259
+ const localPath = import_path.default.resolve(rootDir, id);
260
+ if (import_fs.default.existsSync(localPath))
261
+ return localPath;
262
+ return require.resolve(id, { paths: [rootDir] });
263
+ }
264
+ const defaultGrep = /.*/;
265
+ const defaultReporter = process.env.CI ? "dot" : "list";
266
+ const configInternalSymbol = Symbol("configInternalSymbol");
267
+ function getProjectId(project) {
268
+ return project.__projectId;
269
+ }
270
+ // Annotate the CommonJS export names for ESM import in node:
271
+ 0 && (module.exports = {
272
+ FullConfigInternal,
273
+ FullProjectInternal,
274
+ builtInReporters,
275
+ defaultGrep,
276
+ defaultReporter,
277
+ defaultTimeout,
278
+ getProjectId,
279
+ takeFirst,
280
+ toReporters
281
+ });
282
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/common/config.ts"],
4
+ "sourcesContent": ["/**\n * Copyright Microsoft Corporation. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport fs from 'fs';\nimport os from 'os';\nimport path from 'path';\n\nimport { getPackageJsonPath, mergeObjects } from '../util';\n\nimport type { Config, Fixtures, Metadata, Project, ReporterDescription } from '../../types/test';\nimport type { TestRunnerPluginRegistration } from '../plugins';\nimport type { TestCaseFilter } from '../util';\nimport type { ConfigCLIOverrides } from './ipc';\nimport type { Location } from '../../types/testReporter';\nimport type { FullConfig, FullProject } from '../../types/testReporter';\n\nexport type ConfigLocation = {\n resolvedConfigFile?: string;\n configDir: string;\n};\n\nexport type FixturesWithLocation = {\n fixtures: Fixtures;\n location: Location;\n};\n\nexport const defaultTimeout = 30000;\n\nexport class FullConfigInternal {\n readonly config: FullConfig;\n readonly configDir: string;\n readonly configCLIOverrides: ConfigCLIOverrides;\n readonly webServers: NonNullable<FullConfig['webServer']>[];\n readonly plugins: TestRunnerPluginRegistration[];\n readonly projects: FullProjectInternal[] = [];\n readonly singleTSConfigPath?: string;\n readonly captureGitInfo: Config['captureGitInfo'];\n readonly failOnFlakyTests: boolean;\n cliArgs: string[] = [];\n cliGrep: string | undefined;\n cliGrepInvert: string | undefined;\n cliOnlyChanged: string | undefined;\n cliProjectFilter?: string[];\n cliListOnly = false;\n cliPassWithNoTests?: boolean;\n cliLastFailed?: boolean;\n cliTestList?: string;\n cliTestListInvert?: string;\n preOnlyTestFilters: TestCaseFilter[] = [];\n postShardTestFilters: TestCaseFilter[] = [];\n defineConfigWasUsed = false;\n\n globalSetups: string[] = [];\n globalTeardowns: string[] = [];\n\n constructor(location: ConfigLocation, userConfig: Config, configCLIOverrides: ConfigCLIOverrides, metadata?: Metadata) {\n if (configCLIOverrides.projects && userConfig.projects)\n throw new Error(`Cannot use --browser option when configuration file defines projects. Specify browserName in the projects instead.`);\n\n const { resolvedConfigFile, configDir } = location;\n const packageJsonPath = getPackageJsonPath(configDir);\n const packageJsonDir = packageJsonPath ? path.dirname(packageJsonPath) : process.cwd();\n\n this.configDir = configDir;\n this.configCLIOverrides = configCLIOverrides;\n const privateConfiguration = (userConfig as any)['@playwright/test'];\n this.plugins = (privateConfiguration?.plugins || []).map((p: any) => ({ factory: p }));\n this.singleTSConfigPath = pathResolve(configDir, userConfig.tsconfig);\n this.captureGitInfo = userConfig.captureGitInfo;\n this.failOnFlakyTests = takeFirst(configCLIOverrides.failOnFlakyTests, userConfig.failOnFlakyTests, false);\n\n this.globalSetups = (Array.isArray(userConfig.globalSetup) ? userConfig.globalSetup : [userConfig.globalSetup]).map(s => resolveScript(s, configDir)).filter(script => script !== undefined);\n this.globalTeardowns = (Array.isArray(userConfig.globalTeardown) ? userConfig.globalTeardown : [userConfig.globalTeardown]).map(s => resolveScript(s, configDir)).filter(script => script !== undefined);\n\n // Make sure we reuse same metadata instance between FullConfigInternal instances,\n // so that plugins such as gitCommitInfoPlugin can populate metadata once.\n userConfig.metadata = userConfig.metadata || {};\n\n const globalTags = Array.isArray(userConfig.tag) ? userConfig.tag : (userConfig.tag ? [userConfig.tag] : []);\n for (const tag of globalTags) {\n if (tag[0] !== '@')\n throw new Error(`Tag must start with \"@\" symbol, got \"${tag}\" instead.`);\n }\n\n this.config = {\n configFile: resolvedConfigFile,\n rootDir: pathResolve(configDir, userConfig.testDir) || configDir,\n forbidOnly: takeFirst(configCLIOverrides.forbidOnly, userConfig.forbidOnly, false),\n fullyParallel: takeFirst(configCLIOverrides.fullyParallel, userConfig.fullyParallel, false),\n globalSetup: this.globalSetups[0] ?? null,\n globalTeardown: this.globalTeardowns[0] ?? null,\n globalTimeout: takeFirst(configCLIOverrides.debug ? 0 : undefined, configCLIOverrides.globalTimeout, userConfig.globalTimeout, 0),\n grep: takeFirst(userConfig.grep, defaultGrep),\n grepInvert: takeFirst(userConfig.grepInvert, null),\n maxFailures: takeFirst(configCLIOverrides.debug ? 1 : undefined, configCLIOverrides.maxFailures, userConfig.maxFailures, 0),\n metadata: metadata ?? userConfig.metadata,\n preserveOutput: takeFirst(userConfig.preserveOutput, 'always'),\n projects: [],\n quiet: takeFirst(configCLIOverrides.quiet, userConfig.quiet, false),\n reporter: takeFirst(configCLIOverrides.reporter, resolveReporters(userConfig.reporter, configDir), [[defaultReporter]]),\n reportSlowTests: takeFirst(userConfig.reportSlowTests, { max: 5, threshold: 300_000 /* 5 minutes */ }),\n runAgents: takeFirst(configCLIOverrides.runAgents, userConfig.runAgents, 'none'),\n shard: takeFirst(configCLIOverrides.shard, userConfig.shard, null),\n tags: globalTags,\n updateSnapshots: takeFirst(configCLIOverrides.updateSnapshots, userConfig.updateSnapshots, 'missing'),\n updateSourceMethod: takeFirst(configCLIOverrides.updateSourceMethod, userConfig.updateSourceMethod, 'patch'),\n version: require('../../package.json').version,\n workers: resolveWorkers(takeFirst(configCLIOverrides.debug ? 1 : undefined, configCLIOverrides.workers, userConfig.workers, '50%')),\n webServer: null,\n };\n for (const key in userConfig) {\n if (key.startsWith('@'))\n (this.config as any)[key] = (userConfig as any)[key];\n }\n\n (this.config as any)[configInternalSymbol] = this;\n\n const webServers = takeFirst(userConfig.webServer, null);\n if (Array.isArray(webServers)) { // multiple web server mode\n // Due to previous choices, this value shows up to the user in globalSetup as part of FullConfig. Arrays are not supported by the old type.\n this.config.webServer = null;\n this.webServers = webServers;\n } else if (webServers) { // legacy singleton mode\n this.config.webServer = webServers;\n this.webServers = [webServers];\n } else {\n this.webServers = [];\n }\n\n // When no projects are defined, do not use config.workers as a hard limit for project.workers.\n const projectConfigs = configCLIOverrides.projects || userConfig.projects || [{ ...userConfig, workers: undefined }];\n this.projects = projectConfigs.map(p => new FullProjectInternal(configDir, userConfig, this, p, this.configCLIOverrides, packageJsonDir));\n resolveProjectDependencies(this.projects);\n this._assignUniqueProjectIds(this.projects);\n this.config.projects = this.projects.map(p => p.project);\n }\n\n private _assignUniqueProjectIds(projects: FullProjectInternal[]) {\n const usedNames = new Set();\n for (const p of projects) {\n const name = p.project.name || '';\n for (let i = 0; i < projects.length; ++i) {\n const candidate = name + (i ? i : '');\n if (usedNames.has(candidate))\n continue;\n p.id = candidate;\n (p.project as any).__projectId = p.id;\n usedNames.add(candidate);\n break;\n }\n }\n }\n}\n\nexport class FullProjectInternal {\n readonly project: FullProject;\n readonly fullConfig: FullConfigInternal;\n readonly fullyParallel: boolean;\n readonly expect: Project['expect'];\n readonly respectGitIgnore: boolean;\n readonly snapshotPathTemplate: string | undefined;\n readonly ignoreSnapshots: boolean;\n readonly workers: number | undefined;\n id = '';\n deps: FullProjectInternal[] = [];\n teardown: FullProjectInternal | undefined;\n\n constructor(configDir: string, config: Config, fullConfig: FullConfigInternal, projectConfig: Project, configCLIOverrides: ConfigCLIOverrides, packageJsonDir: string) {\n this.fullConfig = fullConfig;\n const testDir = takeFirst(pathResolve(configDir, projectConfig.testDir), pathResolve(configDir, config.testDir), fullConfig.configDir);\n this.snapshotPathTemplate = takeFirst(projectConfig.snapshotPathTemplate, config.snapshotPathTemplate);\n\n this.project = {\n grep: takeFirst(projectConfig.grep, config.grep, defaultGrep),\n grepInvert: takeFirst(projectConfig.grepInvert, config.grepInvert, null),\n outputDir: takeFirst(configCLIOverrides.outputDir, pathResolve(configDir, projectConfig.outputDir), pathResolve(configDir, config.outputDir), path.join(packageJsonDir, 'test-results')),\n // Note: we either apply the cli override for repeatEach or not, depending on whether the\n // project is top-level vs dependency. See collectProjectsAndTestFiles in loadUtils.\n repeatEach: takeFirst(projectConfig.repeatEach, config.repeatEach, 1),\n retries: takeFirst(configCLIOverrides.retries, projectConfig.retries, config.retries, 0),\n metadata: takeFirst(projectConfig.metadata, config.metadata, {}),\n name: takeFirst(projectConfig.name, config.name, ''),\n testDir,\n snapshotDir: takeFirst(pathResolve(configDir, projectConfig.snapshotDir), pathResolve(configDir, config.snapshotDir), testDir),\n testIgnore: takeFirst(projectConfig.testIgnore, config.testIgnore, []),\n testMatch: takeFirst(projectConfig.testMatch, config.testMatch, '**/*.@(spec|test).?(c|m)[jt]s?(x)'),\n timeout: takeFirst(configCLIOverrides.debug ? 0 : undefined, configCLIOverrides.timeout, projectConfig.timeout, config.timeout, defaultTimeout),\n use: mergeObjects(config.use, projectConfig.use, configCLIOverrides.use),\n dependencies: projectConfig.dependencies || [],\n teardown: projectConfig.teardown,\n };\n this.fullyParallel = takeFirst(configCLIOverrides.fullyParallel, projectConfig.fullyParallel, config.fullyParallel, undefined);\n this.expect = takeFirst(projectConfig.expect, config.expect, {});\n if (this.expect.toHaveScreenshot?.stylePath) {\n const stylePaths = Array.isArray(this.expect.toHaveScreenshot.stylePath) ? this.expect.toHaveScreenshot.stylePath : [this.expect.toHaveScreenshot.stylePath];\n this.expect.toHaveScreenshot.stylePath = stylePaths.map(stylePath => path.resolve(configDir, stylePath));\n }\n this.respectGitIgnore = takeFirst(projectConfig.respectGitIgnore, config.respectGitIgnore, !projectConfig.testDir && !config.testDir);\n this.ignoreSnapshots = takeFirst(configCLIOverrides.ignoreSnapshots, projectConfig.ignoreSnapshots, config.ignoreSnapshots, false);\n this.workers = projectConfig.workers ? resolveWorkers(projectConfig.workers) : undefined;\n if (configCLIOverrides.debug && this.workers)\n this.workers = 1;\n }\n}\n\nexport function takeFirst<T>(...args: (T | undefined)[]): T {\n for (const arg of args) {\n if (arg !== undefined)\n return arg;\n }\n return undefined as any as T;\n}\n\nfunction pathResolve(baseDir: string, relative: string | undefined): string | undefined {\n if (!relative)\n return undefined;\n return path.resolve(baseDir, relative);\n}\n\nfunction resolveReporters(reporters: Config['reporter'], rootDir: string): ReporterDescription[] | undefined {\n return toReporters(reporters as any)?.map(([id, arg]) => {\n if (builtInReporters.includes(id as any))\n return [id, arg];\n return [require.resolve(id, { paths: [rootDir] }), arg];\n });\n}\n\nfunction resolveWorkers(workers: string | number): number {\n if (typeof workers === 'string') {\n if (workers.endsWith('%')) {\n const cpus = os.cpus().length;\n return Math.max(1, Math.floor(cpus * (parseInt(workers, 10) / 100)));\n }\n const parsedWorkers = parseInt(workers, 10);\n if (isNaN(parsedWorkers))\n throw new Error(`Workers ${workers} must be a number or percentage.`);\n return parsedWorkers;\n }\n return workers;\n}\n\nfunction resolveProjectDependencies(projects: FullProjectInternal[]) {\n const teardownSet = new Set<FullProjectInternal>();\n for (const project of projects) {\n for (const dependencyName of project.project.dependencies) {\n const dependencies = projects.filter(p => p.project.name === dependencyName);\n if (!dependencies.length)\n throw new Error(`Project '${project.project.name}' depends on unknown project '${dependencyName}'`);\n if (dependencies.length > 1)\n throw new Error(`Project dependencies should have unique names, reading ${dependencyName}`);\n project.deps.push(...dependencies);\n }\n if (project.project.teardown) {\n const teardowns = projects.filter(p => p.project.name === project.project.teardown);\n if (!teardowns.length)\n throw new Error(`Project '${project.project.name}' has unknown teardown project '${project.project.teardown}'`);\n if (teardowns.length > 1)\n throw new Error(`Project teardowns should have unique names, reading ${project.project.teardown}`);\n const teardown = teardowns[0];\n project.teardown = teardown;\n teardownSet.add(teardown);\n }\n }\n for (const teardown of teardownSet) {\n if (teardown.deps.length)\n throw new Error(`Teardown project ${teardown.project.name} must not have dependencies`);\n }\n for (const project of projects) {\n for (const dep of project.deps) {\n if (teardownSet.has(dep))\n throw new Error(`Project ${project.project.name} must not depend on a teardown project ${dep.project.name}`);\n }\n }\n}\n\nexport function toReporters(reporters: BuiltInReporter | ReporterDescription[] | undefined): ReporterDescription[] | undefined {\n if (!reporters)\n return;\n if (typeof reporters === 'string')\n return [[reporters]];\n return reporters;\n}\n\nexport const builtInReporters = ['list', 'line', 'dot', 'json', 'junit', 'null', 'github', 'html', 'blob'] as const;\nexport type BuiltInReporter = typeof builtInReporters[number];\n\nexport type ContextReuseMode = 'none' | 'when-possible';\n\nfunction resolveScript(id: string | undefined, rootDir: string): string | undefined {\n if (!id)\n return undefined;\n const localPath = path.resolve(rootDir, id);\n if (fs.existsSync(localPath))\n return localPath;\n return require.resolve(id, { paths: [rootDir] });\n}\n\nexport const defaultGrep = /.*/;\nexport const defaultReporter = process.env.CI ? 'dot' : 'list';\n\nconst configInternalSymbol = Symbol('configInternalSymbol');\n\nexport function getProjectId(project: FullProject): string {\n return (project as any).__projectId!;\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["path", "os", "fs"]
7
+ }