@gate-forge/pack-playwright 0.7.1 → 0.8.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 (202) hide show
  1. package/README.md +31 -0
  2. package/dist/constants.d.ts +13 -140
  3. package/dist/constants.d.ts.map +1 -1
  4. package/dist/constants.js +13 -148
  5. package/dist/constants.js.map +1 -1
  6. package/dist/cypress/plugin.d.ts +53 -0
  7. package/dist/cypress/plugin.d.ts.map +1 -0
  8. package/dist/cypress/plugin.js +369 -0
  9. package/dist/cypress/plugin.js.map +1 -0
  10. package/dist/cypress/spec-scan.d.ts +39 -0
  11. package/dist/cypress/spec-scan.d.ts.map +1 -0
  12. package/dist/cypress/spec-scan.js +301 -0
  13. package/dist/cypress/spec-scan.js.map +1 -0
  14. package/dist/diagnosis.d.ts +39 -0
  15. package/dist/diagnosis.d.ts.map +1 -0
  16. package/dist/diagnosis.js +63 -0
  17. package/dist/diagnosis.js.map +1 -0
  18. package/dist/discovery/adapter-projection.d.ts +13 -0
  19. package/dist/discovery/adapter-projection.d.ts.map +1 -0
  20. package/dist/discovery/adapter-projection.js +84 -0
  21. package/dist/discovery/adapter-projection.js.map +1 -0
  22. package/dist/discovery/config-locations.d.ts +5 -0
  23. package/dist/discovery/config-locations.d.ts.map +1 -0
  24. package/dist/discovery/config-locations.js +19 -0
  25. package/dist/discovery/config-locations.js.map +1 -0
  26. package/dist/discovery/cypress-runner-adapter.d.ts +112 -0
  27. package/dist/discovery/cypress-runner-adapter.d.ts.map +1 -0
  28. package/dist/discovery/cypress-runner-adapter.js +501 -0
  29. package/dist/discovery/cypress-runner-adapter.js.map +1 -0
  30. package/dist/discovery/discover.d.ts +53 -1
  31. package/dist/discovery/discover.d.ts.map +1 -1
  32. package/dist/discovery/discover.js +100 -3
  33. package/dist/discovery/discover.js.map +1 -1
  34. package/dist/discovery/git-ignore.d.ts +13 -0
  35. package/dist/discovery/git-ignore.d.ts.map +1 -0
  36. package/dist/discovery/git-ignore.js +62 -0
  37. package/dist/discovery/git-ignore.js.map +1 -0
  38. package/dist/discovery/index.d.ts +9 -0
  39. package/dist/discovery/index.d.ts.map +1 -1
  40. package/dist/discovery/index.js +9 -0
  41. package/dist/discovery/index.js.map +1 -1
  42. package/dist/discovery/playwright-runner-adapter.d.ts +108 -0
  43. package/dist/discovery/playwright-runner-adapter.d.ts.map +1 -0
  44. package/dist/discovery/playwright-runner-adapter.js +185 -0
  45. package/dist/discovery/playwright-runner-adapter.js.map +1 -0
  46. package/dist/discovery/prepare-barrier.d.ts +522 -0
  47. package/dist/discovery/prepare-barrier.d.ts.map +1 -0
  48. package/dist/discovery/prepare-barrier.js +739 -0
  49. package/dist/discovery/prepare-barrier.js.map +1 -0
  50. package/dist/discovery/pytest-adapter.d.ts.map +1 -1
  51. package/dist/discovery/pytest-adapter.js +6 -2
  52. package/dist/discovery/pytest-adapter.js.map +1 -1
  53. package/dist/discovery/pytest-runner-adapter.d.ts +124 -0
  54. package/dist/discovery/pytest-runner-adapter.d.ts.map +1 -0
  55. package/dist/discovery/pytest-runner-adapter.js +454 -0
  56. package/dist/discovery/pytest-runner-adapter.js.map +1 -0
  57. package/dist/discovery/reconcile.d.ts +80 -11
  58. package/dist/discovery/reconcile.d.ts.map +1 -1
  59. package/dist/discovery/reconcile.js +395 -78
  60. package/dist/discovery/reconcile.js.map +1 -1
  61. package/dist/discovery/runner-env.d.ts +88 -2
  62. package/dist/discovery/runner-env.d.ts.map +1 -1
  63. package/dist/discovery/runner-env.js +142 -4
  64. package/dist/discovery/runner-env.js.map +1 -1
  65. package/dist/discovery/static-discovery.d.ts +38 -3
  66. package/dist/discovery/static-discovery.d.ts.map +1 -1
  67. package/dist/discovery/static-discovery.js +454 -15
  68. package/dist/discovery/static-discovery.js.map +1 -1
  69. package/dist/discovery/supervised-run.d.ts +199 -10
  70. package/dist/discovery/supervised-run.d.ts.map +1 -1
  71. package/dist/discovery/supervised-run.js +350 -39
  72. package/dist/discovery/supervised-run.js.map +1 -1
  73. package/dist/discovery/trusted-config.d.ts +180 -6
  74. package/dist/discovery/trusted-config.d.ts.map +1 -1
  75. package/dist/discovery/trusted-config.js +279 -10
  76. package/dist/discovery/trusted-config.js.map +1 -1
  77. package/dist/discovery/vitest-runner-adapter.d.ts +172 -0
  78. package/dist/discovery/vitest-runner-adapter.d.ts.map +1 -0
  79. package/dist/discovery/vitest-runner-adapter.js +607 -0
  80. package/dist/discovery/vitest-runner-adapter.js.map +1 -0
  81. package/dist/fixture/consumer-runner.d.ts +4 -0
  82. package/dist/fixture/consumer-runner.d.ts.map +1 -0
  83. package/dist/fixture/consumer-runner.js +38 -0
  84. package/dist/fixture/consumer-runner.js.map +1 -0
  85. package/dist/fixture/evidence.d.ts +27 -0
  86. package/dist/fixture/evidence.d.ts.map +1 -1
  87. package/dist/fixture/evidence.js +12 -0
  88. package/dist/fixture/evidence.js.map +1 -1
  89. package/dist/fixture/fixture.d.ts +2 -1
  90. package/dist/fixture/fixture.d.ts.map +1 -1
  91. package/dist/fixture/fixture.js +1 -17
  92. package/dist/fixture/fixture.js.map +1 -1
  93. package/dist/fixture/witness-client.d.ts +6 -174
  94. package/dist/fixture/witness-client.d.ts.map +1 -1
  95. package/dist/fixture/witness-client.js +6 -267
  96. package/dist/fixture/witness-client.js.map +1 -1
  97. package/dist/index.d.ts +9 -6
  98. package/dist/index.d.ts.map +1 -1
  99. package/dist/index.js +5 -4
  100. package/dist/index.js.map +1 -1
  101. package/dist/json.d.ts +6 -12
  102. package/dist/json.d.ts.map +1 -1
  103. package/dist/json.js +6 -17
  104. package/dist/json.js.map +1 -1
  105. package/dist/reporter/project-graph-reporter.d.ts +92 -0
  106. package/dist/reporter/project-graph-reporter.d.ts.map +1 -0
  107. package/dist/reporter/project-graph-reporter.js +92 -0
  108. package/dist/reporter/project-graph-reporter.js.map +1 -0
  109. package/dist/reporter/reporter.cjs.map +1 -1
  110. package/dist/reporter/reporter.d.ts +93 -4
  111. package/dist/reporter/reporter.d.ts.map +1 -1
  112. package/dist/reporter/reporter.js +174 -18
  113. package/dist/reporter/reporter.js.map +1 -1
  114. package/dist/runner-claims.d.ts +13 -0
  115. package/dist/runner-claims.d.ts.map +1 -0
  116. package/dist/runner-claims.js +46 -0
  117. package/dist/runner-claims.js.map +1 -0
  118. package/dist/runner-resolution.d.ts +3 -0
  119. package/dist/runner-resolution.d.ts.map +1 -0
  120. package/dist/runner-resolution.js +14 -0
  121. package/dist/runner-resolution.js.map +1 -0
  122. package/dist/supervisor/client.d.ts +23 -1
  123. package/dist/supervisor/client.d.ts.map +1 -1
  124. package/dist/supervisor/client.js +49 -0
  125. package/dist/supervisor/client.js.map +1 -1
  126. package/dist/supervisor/drain.d.ts +65 -0
  127. package/dist/supervisor/drain.d.ts.map +1 -1
  128. package/dist/supervisor/drain.js +353 -9
  129. package/dist/supervisor/drain.js.map +1 -1
  130. package/dist/supervisor/index.d.ts +7 -3
  131. package/dist/supervisor/index.d.ts.map +1 -1
  132. package/dist/supervisor/index.js +7 -3
  133. package/dist/supervisor/index.js.map +1 -1
  134. package/dist/supervisor/spool.d.ts +65 -2
  135. package/dist/supervisor/spool.d.ts.map +1 -1
  136. package/dist/supervisor/spool.js +47 -0
  137. package/dist/supervisor/spool.js.map +1 -1
  138. package/dist/surface.d.ts +6 -207
  139. package/dist/surface.d.ts.map +1 -1
  140. package/dist/surface.js +6 -264
  141. package/dist/surface.js.map +1 -1
  142. package/dist/vitest/index.d.ts +23 -0
  143. package/dist/vitest/index.d.ts.map +1 -0
  144. package/dist/vitest/index.js +356 -0
  145. package/dist/vitest/index.js.map +1 -0
  146. package/dist/vitest/reporter.d.ts +83 -0
  147. package/dist/vitest/reporter.d.ts.map +1 -0
  148. package/dist/vitest/reporter.js +211 -0
  149. package/dist/vitest/reporter.js.map +1 -0
  150. package/dist/vitest/worker-slot.d.ts +36 -0
  151. package/dist/vitest/worker-slot.d.ts.map +1 -0
  152. package/dist/vitest/worker-slot.js +51 -0
  153. package/dist/vitest/worker-slot.js.map +1 -0
  154. package/dist/witness/adapter-registry.d.ts +6 -50
  155. package/dist/witness/adapter-registry.d.ts.map +1 -1
  156. package/dist/witness/adapter-registry.js +6 -257
  157. package/dist/witness/adapter-registry.js.map +1 -1
  158. package/dist/witness/behavior-request.d.ts +6 -76
  159. package/dist/witness/behavior-request.d.ts.map +1 -1
  160. package/dist/witness/behavior-request.js +6 -273
  161. package/dist/witness/behavior-request.js.map +1 -1
  162. package/dist/witness/behavior.d.ts +6 -48
  163. package/dist/witness/behavior.d.ts.map +1 -1
  164. package/dist/witness/behavior.js +6 -114
  165. package/dist/witness/behavior.js.map +1 -1
  166. package/dist/witness/bin.d.ts +6 -17
  167. package/dist/witness/bin.d.ts.map +1 -1
  168. package/dist/witness/bin.js +6 -168
  169. package/dist/witness/bin.js.map +1 -1
  170. package/dist/witness/browser.d.ts +14 -206
  171. package/dist/witness/browser.d.ts.map +1 -1
  172. package/dist/witness/browser.js +15 -654
  173. package/dist/witness/browser.js.map +1 -1
  174. package/dist/witness/classifications.d.ts +6 -38
  175. package/dist/witness/classifications.d.ts.map +1 -1
  176. package/dist/witness/classifications.js +6 -83
  177. package/dist/witness/classifications.js.map +1 -1
  178. package/dist/witness/env-attestation.d.ts +6 -94
  179. package/dist/witness/env-attestation.d.ts.map +1 -1
  180. package/dist/witness/env-attestation.js +6 -198
  181. package/dist/witness/env-attestation.js.map +1 -1
  182. package/dist/witness/fixture-provider.d.ts +6 -82
  183. package/dist/witness/fixture-provider.d.ts.map +1 -1
  184. package/dist/witness/fixture-provider.js +6 -105
  185. package/dist/witness/fixture-provider.js.map +1 -1
  186. package/dist/witness/loopback-pins.d.ts +6 -75
  187. package/dist/witness/loopback-pins.d.ts.map +1 -1
  188. package/dist/witness/loopback-pins.js +6 -240
  189. package/dist/witness/loopback-pins.js.map +1 -1
  190. package/dist/witness/server.d.ts +8 -26
  191. package/dist/witness/server.d.ts.map +1 -1
  192. package/dist/witness/server.js +24 -3761
  193. package/dist/witness/server.js.map +1 -1
  194. package/dist/witness/types.d.ts +6 -882
  195. package/dist/witness/types.d.ts.map +1 -1
  196. package/dist/witness/types.js +9 -1
  197. package/dist/witness/types.js.map +1 -1
  198. package/examples/overlay-proof.spec.js +75 -0
  199. package/package.json +8 -2
  200. package/python/__pycache__/gateforge_persistence_intents.cpython-312.pyc +0 -0
  201. package/python/__pycache__/gateforge_persistence_intents.cpython-314.pyc +0 -0
  202. package/python/gateforge_pytest_plugin.py +462 -0
@@ -13,7 +13,23 @@
13
13
  * (from the planned expected set), or the runner default when the
14
14
  * caller selected nothing;
15
15
  * - projects: bare names carried as data (identity only — per-project
16
- * code options are NOT honored);
16
+ * code options are NOT honored), each with the files the plan
17
+ * attributed to it, the dependency EDGES the enumeration captured
18
+ * (names only), and the `use.storageState` PATH the enumeration
19
+ * captured for that project. The edges are what makes a `setup`-project
20
+ * config order correctly: Playwright runs a dependency project's tests
21
+ * before the dependent project, which is the only way the dependent
22
+ * test can read the artifact the setup test produced — and the state
23
+ * is what hands that project the session the setup test saved, while
24
+ * the setup project itself keeps running unauthenticated;
25
+ * - storage states: a declared path is resolved from the NATIVE CONFIG
26
+ * DIRECTORY the runner child runs from (so the dependent project reads
27
+ * the very file its own setup project wrote from that same cwd) and is
28
+ * honored only while it lands INSIDE the candidate root, which stays
29
+ * the containment boundary for a nested project too; an
30
+ * operator-provided whole-run state still outranks every project
31
+ * declaration and keeps its own candidate-root meaning (see
32
+ * {@link resolveProjectStorageState});
17
33
  * - reporter: the engine's own reporter entry forced by absolute path
18
34
  * with run-state paths as CONSTRUCTOR OPTIONS (never env — worker
19
35
  * processes must not learn the spool/outcomes locations);
@@ -36,8 +52,21 @@
36
52
  *
37
53
  * Compatibility limits (honest, not transparent):
38
54
  * - consumer `globalSetup`/`globalTeardown` are NOT executed;
39
- * - consumer reporters, `webServer`, per-project `use` options,
40
- * `testDir`/`testIgnore` scoping, and sharding are NOT honored;
55
+ * - consumer reporters, `webServer`, per-project `use` options other
56
+ * than the captured `storageState` PATH, `testDir`/`testIgnore`
57
+ * scoping, and sharding are NOT honored;
58
+ * - consumer `testMatch` scoping is NOT honored as CONSUMER CODE. What IS
59
+ * honored is the SUPERVISOR'S OWN per-project file selection
60
+ * (`projectScopes`): project identity is the join key the whole pipeline
61
+ * speaks — catalog rows, the registered expected set, session opens, and
62
+ * the execution trace — so file scoping must be per project too. A single
63
+ * global `testMatch` collects every selected file under EVERY project,
64
+ * which is how a `setup`-dependency config (`{ name: 'setup', testMatch:
65
+ * /.*\.setup\.ts/ }` plus a dependent project) ran the whole suite once
66
+ * per project: identities the registered expected set never bound, so
67
+ * their sessions were refused and they lost every piece of evidence.
68
+ * - per-project `teardown` is NOT honored; only `dependencies` is, as
69
+ * ordering data (names only).
41
70
  * - tests must be self-contained (app provided externally via the
42
71
  * app-base env, as the fixture already requires).
43
72
  */
@@ -55,11 +84,44 @@ export interface TrustedReporterOptions {
55
84
  outcomesPath: string;
56
85
  /** Absolute obligations document path (reporter ledger; empty when none). */
57
86
  obligationsPath: string;
87
+ /**
88
+ * Absolute CANDIDATE ROOT the reporter anchors every file identity
89
+ * to. Handed as trusted CONSTRUCTOR DATA (never worker env): the
90
+ * runner child runs from the native config directory, while every
91
+ * identity the supervisor registered is repo-relative — the reporter
92
+ * must therefore relativize against the root, not against the cwd it
93
+ * happens to run in.
94
+ */
95
+ candidateRoot: string;
96
+ /**
97
+ * ABSOLUTE path of the engine's own generated preparation-freeze
98
+ * controller spec, when this run armed the global native freeze.
99
+ *
100
+ * The controller is a real Playwright test inside the runner, so the
101
+ * reporter would otherwise report it as a native case: it would append
102
+ * a lifecycle event (opening a witness session for a test the
103
+ * registered expected set never contained), record an outcome row (so
104
+ * the run's native count carries a non-native case), and collect its
105
+ * claims. The exclusion is therefore by ABSOLUTE FILE IDENTITY — the
106
+ * exact control bytes the trusted CLI pinned — never by title, never
107
+ * by a project-name prefix, and never by anything the candidate
108
+ * controls.
109
+ */
110
+ controlSpecPath?: string;
58
111
  }
59
112
  /** Inputs for one trusted config synthesis. */
60
113
  export interface TrustedConfigInput {
61
- /** Absolute repo root (the runner's testDir). */
114
+ /** Absolute repo root (the runner's testDir, and the identity root). */
62
115
  cwd: string;
116
+ /**
117
+ * Absolute native config directory — the directory the runner child
118
+ * runs from (the same one `listNativePlaywrightTests` enumerates
119
+ * from). Relative per-project {@link ProjectScope.storageState}
120
+ * declarations resolve from here, because that is the cwd the
121
+ * project's own setup test wrote the file from. Undefined = the repo
122
+ * root, which is exactly the config directory of a root-level config.
123
+ */
124
+ nativeConfigDir?: string;
63
125
  /** Absolute run-state dir (receives the synthesized config). */
64
126
  stateDir: string;
65
127
  /** The run identity. */
@@ -68,15 +130,126 @@ export interface TrustedConfigInput {
68
130
  reporterEntry: string;
69
131
  /** Trusted operator-provided app proxy URL for relative browser navigation. */
70
132
  appBaseUrl?: string;
71
- /** Operator-provided browser storage state, embedded only in trusted config. */
133
+ /**
134
+ * Operator-provided browser storage state, embedded only in trusted
135
+ * config. This is the WHOLE-RUN state: when it is set it applies to
136
+ * every project and outranks each project's declared
137
+ * {@link ProjectScope.storageState}, exactly as it always has. A
138
+ * relative value keeps its CANDIDATE-ROOT meaning — it is resolved
139
+ * against {@link TrustedConfigInput.cwd} here, so moving the native
140
+ * child's cwd can never re-point an operator's path.
141
+ */
72
142
  storageState?: string;
73
143
  /** Exact repo-relative posix test files to run (undefined = default). */
74
144
  testFiles?: readonly string[];
75
145
  /** Bare project names to run (undefined = no project filter). */
76
146
  projects?: readonly string[];
147
+ /**
148
+ * The supervisor's OWN per-project file selection: each named project
149
+ * carries exactly the files the plan attributed to it. A project with no
150
+ * files is omitted (it would execute nothing). Files no project scope
151
+ * claims (a project-less plan row) stay in the global `testMatch`, so
152
+ * they still run. Empty = one global `testMatch` over `testFiles`, which
153
+ * is byte-identical to the pre-scope behavior for a single-project run.
154
+ */
155
+ projectScopes?: readonly ProjectScope[];
156
+ /**
157
+ * ABSOLUTE path of the generated preparation-freeze controller spec,
158
+ * when this run armed the global native freeze. It crosses to the
159
+ * engine reporter as TRUSTED CONSTRUCTOR DATA (never env, never a
160
+ * candidate-relative path) so the reporter can exclude exactly that one
161
+ * file from its outcome rows, claims and lifecycle events. Unarmed, the
162
+ * field is absent and the reporter records every test, exactly as
163
+ * before.
164
+ */
165
+ controlSpecPath?: string;
77
166
  /** Per-test timeout ms (default 60_000). */
78
167
  testTimeoutMs?: number;
79
168
  }
169
+ /** One named project and the repo-relative files the plan attributed to it. */
170
+ export interface ProjectScope {
171
+ /** The project name — identity only; no consumer code options. */
172
+ name: string;
173
+ /** Repo-relative posix test files this project runs. */
174
+ files: readonly string[];
175
+ /**
176
+ * Project names this project depends on, as the runner resolved them
177
+ * (names only — never the consumer's per-project options). The
178
+ * synthesized config emits them so Playwright runs a `setup` project's
179
+ * tests BEFORE the dependent project that reads their artifact; an
180
+ * edge naming a project the synthesized config omits is dropped,
181
+ * because Playwright refuses to load such a config at all.
182
+ */
183
+ dependencies?: readonly string[];
184
+ /**
185
+ * The `use.storageState` PATH this project declared, as the runner
186
+ * resolved it (data, never consumer code). The synthesized config
187
+ * hands it to THIS project only, which is what lets a `setup` project
188
+ * sign in and save `playwright/.auth/user.json` for the dependent
189
+ * project that reads it while the setup project itself stays logged
190
+ * out. Relative paths resolve against the RUNNER's cwd — the native
191
+ * config directory the child runs from — exactly like the setup
192
+ * test's own relative write, which is the very cwd that write is
193
+ * resolved from. Containment stays the WHOLE candidate root, so a
194
+ * valid `../shared/state.json` that lands back inside the candidate
195
+ * is honored while anything reaching outside it is refused (see
196
+ * {@link resolveProjectStorageState}).
197
+ *
198
+ * An operator-provided whole-run state (GATEFORGE_SESSION_STATE)
199
+ * outranks every project declaration, so this field is not emitted at
200
+ * all in that case.
201
+ */
202
+ storageState?: string;
203
+ /**
204
+ * This project's OWN `testDir` (absolute), when it collects files from
205
+ * somewhere other than the config's `testDir`. Only the engine's freeze
206
+ * controller uses it: its spec is GENERATED code in a private per-run
207
+ * directory OUTSIDE the repository, which the config's own repo-root
208
+ * `testDir` never covers and the consumer's own configuration can
209
+ * never collect. A consumer project never gets one — the files it runs
210
+ * are always repo-relative to the identity root.
211
+ */
212
+ testDir?: string;
213
+ }
214
+ /** Thrown when a project-declared browser state may not be read. */
215
+ export declare class ProjectStorageStateError extends Error {
216
+ constructor(message: string);
217
+ }
218
+ /**
219
+ * Resolves one project-declared `use.storageState` and refuses anything
220
+ * a supervised run must not read.
221
+ *
222
+ * A relative path is resolved against the NATIVE CONFIG DIRECTORY —
223
+ * the directory the runner child runs from, exactly the directory
224
+ * `listNativePlaywrightTests` enumerated the suite from: the worker
225
+ * reads the file relative to the process it runs in, which is that very
226
+ * cwd, which is also where the project's own setup test wrote it from.
227
+ * The file itself need not exist yet — the setup project writes it
228
+ * during this run.
229
+ *
230
+ * Containment is the WHOLE CANDIDATE ROOT, not the config directory,
231
+ * and it is PHYSICAL rather than lexical: a symlink inside the
232
+ * candidate that points outside it is refused too, so the check follows
233
+ * the real filesystem from the nearest existing ancestor. A nested
234
+ * project's `../shared/state.json` therefore stays valid whenever it
235
+ * lands back inside the candidate.
236
+ *
237
+ * @param value: the `use.storageState` string the runner resolved.
238
+ * @param root: the candidate root (the containment boundary).
239
+ * @param project: the declaring project, named in the error.
240
+ * @param baseDir: the directory a relative declaration resolves from —
241
+ * the native config directory the runner child runs from.
242
+ *
243
+ * @returns
244
+ * string: the absolute path the declared state resolves to.
245
+ *
246
+ * @throws
247
+ * ProjectStorageStateError: when the value is empty, names a URL, or
248
+ * resolves outside the candidate root either directly or through a
249
+ * link. A requested state is never silently dropped — that would
250
+ * degrade into a logged-out run that looks green.
251
+ */
252
+ export declare function resolveProjectStorageState(value: string, root: string, project: string, baseDir: string): string;
80
253
  /**
81
254
  * Resolves the engine reporter entry the trusted config forces: the
82
255
  * pack's own BUILT reporter (the same class the consumer config would
@@ -94,7 +267,8 @@ export declare function trustedReporterEntry(fromModule?: string): string;
94
267
  * Synthesizes the trusted Playwright config into the run-state dir.
95
268
  *
96
269
  * Args:
97
- * input: repo root, run state, reporter entry, file/project selection.
270
+ * input: repo root, native config directory, run state, reporter
271
+ * entry, file/project selection, and the operator's whole-run state.
98
272
  *
99
273
  * Returns:
100
274
  * { configPath, reporterOptions }: absolute config path for
@@ -1 +1 @@
1
- {"version":3,"file":"trusted-config.d.ts","sourceRoot":"","sources":["../../src/discovery/trusted-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAMH,4EAA4E;AAC5E,eAAO,MAAM,mBAAmB,kCAAkC,CAAC;AAEnE,4EAA4E;AAC5E,eAAO,MAAM,6BAA6B,kCAAkC,CAAC;AAE7E,8EAA8E;AAC9E,MAAM,WAAW,sBAAsB;IACrC,yEAAyE;IACzE,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,YAAY,EAAE,MAAM,CAAC;IACrB,6EAA6E;IAC7E,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,+CAA+C;AAC/C,MAAM,WAAW,kBAAkB;IACjC,iDAAiD;IACjD,GAAG,EAAE,MAAM,CAAC;IACZ,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,aAAa,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,iEAAiE;IACjE,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,4CAA4C;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,GAAE,MAAwB,GAAG,MAAM,CAKjF;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,kBAAkB,GAAG;IAClE,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,sBAAsB,CAAC;CACzC,CA8CA"}
1
+ {"version":3,"file":"trusted-config.d.ts","sourceRoot":"","sources":["../../src/discovery/trusted-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AAQH,4EAA4E;AAC5E,eAAO,MAAM,mBAAmB,kCAAkC,CAAC;AAEnE,4EAA4E;AAC5E,eAAO,MAAM,6BAA6B,kCAAkC,CAAC;AAE7E,8EAA8E;AAC9E,MAAM,WAAW,sBAAsB;IACrC,yEAAyE;IACzE,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,YAAY,EAAE,MAAM,CAAC;IACrB,6EAA6E;IAC7E,eAAe,EAAE,MAAM,CAAC;IACxB;;;;;;;OAOG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;;;;;;;;;;;;OAaG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,+CAA+C;AAC/C,MAAM,WAAW,kBAAkB;IACjC,wEAAwE;IACxE,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,aAAa,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yEAAyE;IACzE,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,iEAAiE;IACjE,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IACxC;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,4CAA4C;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,+EAA+E;AAC/E,MAAM,WAAW,YAAY;IAC3B,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC;;;;;;;;;;;;;;;;;OAiBG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,oEAAoE;AACpE,qBAAa,wBAAyB,SAAQ,KAAK;gBACrC,OAAO,EAAE,MAAM;CAI5B;AAoBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAiDhH;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,GAAE,MAAwB,GAAG,MAAM,CAKjF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,kBAAkB,GAAG;IAClE,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,sBAAsB,CAAC;CACzC,CA+KA"}
@@ -13,7 +13,23 @@
13
13
  * (from the planned expected set), or the runner default when the
14
14
  * caller selected nothing;
15
15
  * - projects: bare names carried as data (identity only — per-project
16
- * code options are NOT honored);
16
+ * code options are NOT honored), each with the files the plan
17
+ * attributed to it, the dependency EDGES the enumeration captured
18
+ * (names only), and the `use.storageState` PATH the enumeration
19
+ * captured for that project. The edges are what makes a `setup`-project
20
+ * config order correctly: Playwright runs a dependency project's tests
21
+ * before the dependent project, which is the only way the dependent
22
+ * test can read the artifact the setup test produced — and the state
23
+ * is what hands that project the session the setup test saved, while
24
+ * the setup project itself keeps running unauthenticated;
25
+ * - storage states: a declared path is resolved from the NATIVE CONFIG
26
+ * DIRECTORY the runner child runs from (so the dependent project reads
27
+ * the very file its own setup project wrote from that same cwd) and is
28
+ * honored only while it lands INSIDE the candidate root, which stays
29
+ * the containment boundary for a nested project too; an
30
+ * operator-provided whole-run state still outranks every project
31
+ * declaration and keeps its own candidate-root meaning (see
32
+ * {@link resolveProjectStorageState});
17
33
  * - reporter: the engine's own reporter entry forced by absolute path
18
34
  * with run-state paths as CONSTRUCTOR OPTIONS (never env — worker
19
35
  * processes must not learn the spool/outcomes locations);
@@ -36,18 +52,143 @@
36
52
  *
37
53
  * Compatibility limits (honest, not transparent):
38
54
  * - consumer `globalSetup`/`globalTeardown` are NOT executed;
39
- * - consumer reporters, `webServer`, per-project `use` options,
40
- * `testDir`/`testIgnore` scoping, and sharding are NOT honored;
55
+ * - consumer reporters, `webServer`, per-project `use` options other
56
+ * than the captured `storageState` PATH, `testDir`/`testIgnore`
57
+ * scoping, and sharding are NOT honored;
58
+ * - consumer `testMatch` scoping is NOT honored as CONSUMER CODE. What IS
59
+ * honored is the SUPERVISOR'S OWN per-project file selection
60
+ * (`projectScopes`): project identity is the join key the whole pipeline
61
+ * speaks — catalog rows, the registered expected set, session opens, and
62
+ * the execution trace — so file scoping must be per project too. A single
63
+ * global `testMatch` collects every selected file under EVERY project,
64
+ * which is how a `setup`-dependency config (`{ name: 'setup', testMatch:
65
+ * /.*\.setup\.ts/ }` plus a dependent project) ran the whole suite once
66
+ * per project: identities the registered expected set never bound, so
67
+ * their sessions were refused and they lost every piece of evidence.
68
+ * - per-project `teardown` is NOT honored; only `dependencies` is, as
69
+ * ordering data (names only).
41
70
  * - tests must be self-contained (app provided externally via the
42
71
  * app-base env, as the fixture already requires).
43
72
  */
44
- import { mkdirSync, writeFileSync } from 'node:fs';
45
- import { join } from 'node:path';
73
+ import { lstatSync, mkdirSync, realpathSync, writeFileSync } from 'node:fs';
74
+ import { dirname, join, relative, resolve, sep } from 'node:path';
46
75
  import { fileURLToPath } from 'node:url';
76
+ import { FREEZE_CONTROLLER_PROJECT } from './prepare-barrier.js';
47
77
  /** File name of the synthesized trusted config inside the run-state dir. */
48
78
  export const TRUSTED_CONFIG_FILE = 'trusted.playwright.config.mjs';
49
79
  /** File name of the forced reporter options (diagnostic mirror of argv). */
50
80
  export const TRUSTED_REPORTER_OPTIONS_FILE = 'trusted-reporter-options.json';
81
+ /** Thrown when a project-declared browser state may not be read. */
82
+ export class ProjectStorageStateError extends Error {
83
+ constructor(message) {
84
+ super(message);
85
+ this.name = 'ProjectStorageStateError';
86
+ }
87
+ }
88
+ /** A declared state that names a URL scheme rather than a file path. */
89
+ const URL_LIKE = /^[a-zA-Z][a-zA-Z\d+.-]*:/;
90
+ /**
91
+ * True when a path exists as a directory entry — a file, a directory, or
92
+ * a symlink of its own, including one that leads nowhere. Deliberately
93
+ * not `existsSync`, which follows links and would report a dangling one
94
+ * as absent.
95
+ */
96
+ function isDirectoryEntry(path) {
97
+ try {
98
+ lstatSync(path);
99
+ return true;
100
+ }
101
+ catch {
102
+ return false;
103
+ }
104
+ }
105
+ /**
106
+ * Resolves one project-declared `use.storageState` and refuses anything
107
+ * a supervised run must not read.
108
+ *
109
+ * A relative path is resolved against the NATIVE CONFIG DIRECTORY —
110
+ * the directory the runner child runs from, exactly the directory
111
+ * `listNativePlaywrightTests` enumerated the suite from: the worker
112
+ * reads the file relative to the process it runs in, which is that very
113
+ * cwd, which is also where the project's own setup test wrote it from.
114
+ * The file itself need not exist yet — the setup project writes it
115
+ * during this run.
116
+ *
117
+ * Containment is the WHOLE CANDIDATE ROOT, not the config directory,
118
+ * and it is PHYSICAL rather than lexical: a symlink inside the
119
+ * candidate that points outside it is refused too, so the check follows
120
+ * the real filesystem from the nearest existing ancestor. A nested
121
+ * project's `../shared/state.json` therefore stays valid whenever it
122
+ * lands back inside the candidate.
123
+ *
124
+ * @param value: the `use.storageState` string the runner resolved.
125
+ * @param root: the candidate root (the containment boundary).
126
+ * @param project: the declaring project, named in the error.
127
+ * @param baseDir: the directory a relative declaration resolves from —
128
+ * the native config directory the runner child runs from.
129
+ *
130
+ * @returns
131
+ * string: the absolute path the declared state resolves to.
132
+ *
133
+ * @throws
134
+ * ProjectStorageStateError: when the value is empty, names a URL, or
135
+ * resolves outside the candidate root either directly or through a
136
+ * link. A requested state is never silently dropped — that would
137
+ * degrade into a logged-out run that looks green.
138
+ */
139
+ export function resolveProjectStorageState(value, root, project, baseDir) {
140
+ const base = resolve(root);
141
+ const from = resolve(base, baseDir);
142
+ const refuse = (why) => {
143
+ throw new ProjectStorageStateError(`project '${project}' declares use.storageState '${value}', which ${why}. A supervised run reads a ` +
144
+ `browser state only from inside the candidate (root '${base}'), resolving relative paths from the ` +
145
+ `project's config directory '${from}': point the project at a path under the candidate — the ` +
146
+ `standard pattern writes 'playwright/.auth/user.json' from its own setup project — or set ` +
147
+ `GATEFORGE_SESSION_STATE to a whole-run state instead.`);
148
+ };
149
+ if (value.length === 0)
150
+ return refuse('is empty');
151
+ if (URL_LIKE.test(value))
152
+ return refuse('is a URL, not a file path');
153
+ const resolvedPath = resolve(from, value);
154
+ if (resolvedPath !== base && !resolvedPath.startsWith(base + sep)) {
155
+ return refuse(`resolves outside the candidate root ('${resolvedPath}')`);
156
+ }
157
+ // A path that only LOOKS contained is not contained: a symlink inside
158
+ // the candidate can point anywhere on the host, and the worker would
159
+ // follow it. So the check follows the real filesystem from the nearest
160
+ // existing ancestor — the state file itself need not exist yet, the
161
+ // setup project writes it during this run — and compares against the
162
+ // real candidate root. Ancestor lookup uses lstat, NOT existsSync: a
163
+ // link that leads nowhere must be FOUND here and refused below, never
164
+ // stepped over as if it were absent.
165
+ let probe = resolvedPath;
166
+ while (!isDirectoryEntry(probe)) {
167
+ const parent = dirname(probe);
168
+ if (parent === probe)
169
+ return refuse('names no path this host can resolve');
170
+ probe = parent;
171
+ }
172
+ let realBase;
173
+ try {
174
+ realBase = realpathSync(base);
175
+ }
176
+ catch {
177
+ return refuse('cannot be resolved against this host\'s filesystem');
178
+ }
179
+ let realProbe;
180
+ try {
181
+ realProbe = realpathSync(probe);
182
+ }
183
+ catch {
184
+ return refuse('is a link this host cannot resolve');
185
+ }
186
+ const physical = resolve(realProbe, relative(probe, resolvedPath));
187
+ if (physical !== realBase && !physical.startsWith(realBase + sep)) {
188
+ return refuse(`reaches outside the candidate through a link ('${physical}')`);
189
+ }
190
+ return resolvedPath;
191
+ }
51
192
  /**
52
193
  * Resolves the engine reporter entry the trusted config forces: the
53
194
  * pack's own BUILT reporter (the same class the consumer config would
@@ -70,7 +211,8 @@ export function trustedReporterEntry(fromModule = import.meta.url) {
70
211
  * Synthesizes the trusted Playwright config into the run-state dir.
71
212
  *
72
213
  * Args:
73
- * input: repo root, run state, reporter entry, file/project selection.
214
+ * input: repo root, native config directory, run state, reporter
215
+ * entry, file/project selection, and the operator's whole-run state.
74
216
  *
75
217
  * Returns:
76
218
  * { configPath, reporterOptions }: absolute config path for
@@ -82,9 +224,123 @@ export function synthesizeTrustedConfig(input) {
82
224
  runId: input.runId,
83
225
  outcomesPath: join(input.stateDir, 'runner-outcomes.json'),
84
226
  obligationsPath: join(input.stateDir, 'obligations.json'),
227
+ candidateRoot: input.cwd,
228
+ // The engine's own freeze controller is excluded by ABSOLUTE FILE
229
+ // IDENTITY, handed here as trusted constructor data. Unarmed, the
230
+ // field is absent and the reporter records every test as before.
231
+ ...(input.controlSpecPath !== undefined ? { controlSpecPath: input.controlSpecPath } : {}),
85
232
  };
86
233
  const testFiles = [...new Set(input.testFiles ?? [])].sort();
87
234
  const projects = [...new Set(input.projects ?? [])].sort();
235
+ // An operator's whole-run state is resolved HERE, against the candidate
236
+ // root, and emitted absolute: a relative operator path keeps the
237
+ // candidate-root meaning it always had, whatever cwd the native child
238
+ // runs from. (An absolute value passes through unchanged — the
239
+ // operator's own path, never re-anchored.)
240
+ const operatorState = input.storageState === undefined ? undefined : resolve(input.cwd, input.storageState);
241
+ // Every project-declared storage state is resolved and checked BEFORE
242
+ // anything is written: a state a supervised run may not read refuses
243
+ // the run outright, because silently dropping it would leave the
244
+ // project logged out and still call the run green. Relative
245
+ // declarations resolve from the NATIVE CONFIG DIRECTORY (the child's
246
+ // cwd, where the setup test wrote the file), while containment stays
247
+ // the whole candidate root. Under an operator's whole-run state the
248
+ // declarations are not used at all, so they are neither read nor
249
+ // checked — precedence means the losing value never reaches the
250
+ // filesystem.
251
+ if (operatorState === undefined) {
252
+ for (const scope of input.projectScopes ?? []) {
253
+ if (scope.storageState !== undefined) {
254
+ resolveProjectStorageState(scope.storageState, input.cwd, scope.name, input.nativeConfigDir ?? input.cwd);
255
+ }
256
+ }
257
+ }
258
+ // Per-project file selection. Each project carries exactly the files the
259
+ // plan attributed to it, so a project-scoped consumer config (the standard
260
+ // `setup`-project auth pattern) does not have every selected file collected
261
+ // under every project. Files no project scope claims stay in the global
262
+ // `testMatch` — a project-less plan row must still execute. Scoping only
263
+ // changes what runs when TWO or more projects share the config: with one
264
+ // project the global `testMatch` selects the identical set, so a
265
+ // single-project run keeps exactly the old one-global-`testMatch` config.
266
+ // A project's declared state travels with it — except under an
267
+ // operator-provided WHOLE-RUN state, which has always outranked
268
+ // everything the config declared and keeps doing so: that state is
269
+ // emitted once as the global `use`, and no per-project state is emitted
270
+ // beside it. A project that declares nothing keeps no `use` at all and
271
+ // therefore runs logged out, which is exactly what the `setup` project
272
+ // of the standard pattern needs.
273
+ const scopedProjects = (input.projectScopes ?? [])
274
+ .map((scope) => ({
275
+ name: scope.name,
276
+ files: [...new Set(scope.files)].sort(),
277
+ // Carried through so the synthesized project can actually collect
278
+ // from it; a dropped field would make the engine's freeze controller
279
+ // look for its spec under the repo root and find nothing.
280
+ ...(scope.testDir === undefined ? {} : { testDir: scope.testDir }),
281
+ dependencies: scope.dependencies ?? [],
282
+ ...(operatorState === undefined && scope.storageState !== undefined
283
+ ? { storageState: scope.storageState }
284
+ : {}),
285
+ }))
286
+ .filter((scope) => scope.name.length > 0 && scope.files.length > 0)
287
+ .sort((left, right) => (left.name < right.name ? -1 : left.name > right.name ? 1 : 0));
288
+ const projectScopes = scopedProjects.length >= 2 ? scopedProjects : [];
289
+ // One surviving scope runs its files under that project alone — a named
290
+ // project that owns no file must not collect them a second time. Its
291
+ // declared state still rides along: that path emits no per-project
292
+ // `testMatch`, and dropping the state with it would log out the very
293
+ // project a narrowed run kept.
294
+ const loneScope = scopedProjects.length === 1 ? scopedProjects[0] : undefined;
295
+ const plainProjects = loneScope !== undefined ? [loneScope.name] : projects;
296
+ const scopedFiles = new Set(projectScopes.flatMap((scope) => scope.files));
297
+ const unscopedFiles = testFiles.filter((file) => !scopedFiles.has(file));
298
+ // Dependency edges are carried as the runner resolved them (names
299
+ // only) and filtered to the projects this config actually defines:
300
+ // Playwright REFUSES to load a config whose `dependencies` names a
301
+ // project it does not declare, so a dangling edge would fail the whole
302
+ // run instead of merely losing an ordering. An edge to a project with
303
+ // no files is dropped with it, for the same reason. Projects with no
304
+ // edges at all emit no `dependencies` key, so a single-project run
305
+ // stays byte-identical.
306
+ const scopedNames = new Set(projectScopes.map((scope) => scope.name));
307
+ // Whether this config carries the engine's preparation-freeze
308
+ // controller. Its presence is what makes the dependency emission below
309
+ // order-aware; every config without it emits exactly what it always did.
310
+ const freezeArmed = projectScopes.some((scope) => scope.name === FREEZE_CONTROLLER_PROJECT);
311
+ const synthesizedProjects = projectScopes.map((scope) => {
312
+ const captured = [
313
+ ...new Set(scope.dependencies.filter((name) => scopedNames.has(name) && name !== scope.name)),
314
+ ].sort();
315
+ // ARMED (the global preparation freeze is in this config): the
316
+ // controller is emitted FIRST, explicitly, and the project's own
317
+ // captured edges follow in their existing sorted order. Sorting the
318
+ // whole array instead would silently move the controller behind any
319
+ // prerequisite that sorts before it, and the extra-environment union
320
+ // the native scheduler builds over `project.deps` is positional with
321
+ // later entries winning — so where the controller lands decides which
322
+ // environment a body actually starts with. UNARMED keeps the exact
323
+ // pre-existing emission, so every run without the barrier stays
324
+ // byte-identical.
325
+ const edges = freezeArmed
326
+ ? captured.includes(FREEZE_CONTROLLER_PROJECT)
327
+ ? [FREEZE_CONTROLLER_PROJECT, ...captured.filter((name) => name !== FREEZE_CONTROLLER_PROJECT)]
328
+ : captured
329
+ : captured;
330
+ return {
331
+ name: scope.name,
332
+ testMatch: scope.files,
333
+ // A project with its OWN `testDir` (the engine's freeze controller)
334
+ // collects from there; every consumer project stays on the config's
335
+ // repo-root `testDir`, exactly as before.
336
+ ...(scope.testDir === undefined ? {} : { testDir: scope.testDir }),
337
+ ...(edges.length > 0 ? { dependencies: edges } : {}),
338
+ // The declared state, for THIS project only. It rides in `use`
339
+ // rather than at the top level so the `setup` project that writes
340
+ // the file keeps running with no session at all.
341
+ ...(scope.storageState === undefined ? {} : { use: { storageState: scope.storageState } }),
342
+ };
343
+ });
88
344
  const lines = [
89
345
  '// GENERATED by gateforge trusted supervision — do not edit. The',
90
346
  '// consumer config file is NEVER loaded for supervised runs: it is',
@@ -92,8 +348,21 @@ export function synthesizeTrustedConfig(input) {
92
348
  '// spool and outcomes document this reporter writes.',
93
349
  'export default {',
94
350
  ` testDir: ${JSON.stringify(input.cwd)},`,
95
- ...(testFiles.length > 0 ? [` testMatch: ${JSON.stringify(testFiles)},`] : []),
96
- ...(projects.length > 0 ? [` projects: ${JSON.stringify(projects.map((name) => ({ name })))},`] : []),
351
+ ...(unscopedFiles.length > 0 ? [` testMatch: ${JSON.stringify(unscopedFiles)},`] : []),
352
+ ...(projectScopes.length > 0
353
+ ? [
354
+ ` projects: ${JSON.stringify(synthesizedProjects)},`,
355
+ ]
356
+ : plainProjects.length > 0
357
+ ? [
358
+ ` projects: ${JSON.stringify(plainProjects.map((name) => ({
359
+ name,
360
+ ...(loneScope?.name === name && loneScope.storageState !== undefined
361
+ ? { use: { storageState: loneScope.storageState } }
362
+ : {}),
363
+ })))},`,
364
+ ]
365
+ : []),
97
366
  ' workers: 1,',
98
367
  ' fullyParallel: false,',
99
368
  ' retries: 0,',
@@ -107,7 +376,7 @@ export function synthesizeTrustedConfig(input) {
107
376
  headless: true,
108
377
  trace: 'off',
109
378
  ...(input.appBaseUrl !== undefined ? { baseURL: input.appBaseUrl } : {}),
110
- ...(input.storageState !== undefined ? { storageState: input.storageState } : {}),
379
+ ...(operatorState !== undefined ? { storageState: operatorState } : {}),
111
380
  })},`,
112
381
  ` outputDir: ${JSON.stringify(join(input.stateDir, 'playwright-artifacts'))},`,
113
382
  '};',
@@ -116,7 +385,7 @@ export function synthesizeTrustedConfig(input) {
116
385
  mkdirSync(input.stateDir, { recursive: true });
117
386
  const configPath = join(input.stateDir, TRUSTED_CONFIG_FILE);
118
387
  writeFileSync(configPath, `${lines.join('\n')}`, 'utf8');
119
- writeFileSync(join(input.stateDir, TRUSTED_REPORTER_OPTIONS_FILE), `${JSON.stringify({ configPath, reporterEntry: input.reporterEntry, reporterOptions, testFiles, projects }, null, 2)}\n`, 'utf8');
388
+ writeFileSync(join(input.stateDir, TRUSTED_REPORTER_OPTIONS_FILE), `${JSON.stringify({ configPath, reporterEntry: input.reporterEntry, reporterOptions, testFiles, projects, projectScopes }, null, 2)}\n`, 'utf8');
120
389
  return { configPath, reporterOptions };
121
390
  }
122
391
  //# sourceMappingURL=trusted-config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"trusted-config.js","sourceRoot":"","sources":["../../src/discovery/trusted-config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"trusted-config.js","sourceRoot":"","sources":["../../src/discovery/trusted-config.ts"],"names":[],"mappings":"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"}