@rpcbase/test 0.385.0 → 0.387.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.
- package/dist/clearDatabase.js +10 -12
- package/dist/clearDatabase.js.map +1 -1
- package/dist/cli.js +439 -556
- package/dist/cli.js.map +1 -1
- package/dist/coverage/collect.js +63 -101
- package/dist/coverage/collect.js.map +1 -1
- package/dist/coverage/config-loader.js +179 -229
- package/dist/coverage/config-loader.js.map +1 -1
- package/dist/coverage/config.js +76 -100
- package/dist/coverage/config.js.map +1 -1
- package/dist/coverage/console-text-report.js +175 -220
- package/dist/coverage/console-text-report.js.map +1 -1
- package/dist/coverage/files.js +44 -57
- package/dist/coverage/files.js.map +1 -1
- package/dist/coverage/fixtures.js +27 -38
- package/dist/coverage/fixtures.js.map +1 -1
- package/dist/coverage/global-setup.js +15 -18
- package/dist/coverage/global-setup.js.map +1 -1
- package/dist/coverage/index.js +38 -55
- package/dist/coverage/index.js.map +1 -1
- package/dist/coverage/report.js +340 -465
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/reporter.js +47 -60
- package/dist/coverage/reporter.js.map +1 -1
- package/dist/coverage/v8-tracker.js +114 -146
- package/dist/coverage/v8-tracker.js.map +1 -1
- package/dist/index.js +46 -75
- package/dist/index.js.map +1 -1
- package/dist/runners/playwright.js +440 -564
- package/dist/runners/playwright.js.map +1 -1
- package/dist/runners/process.js +124 -183
- package/dist/runners/process.js.map +1 -1
- package/dist/runners/vitest.js +123 -170
- package/dist/runners/vitest.js.map +1 -1
- package/dist/serverCoverage.js +28 -42
- package/dist/serverCoverage.js.map +1 -1
- package/dist/vitest.config.js +176 -228
- package/dist/vitest.config.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,615 +1,491 @@
|
|
|
1
|
-
import
|
|
2
|
-
import fs
|
|
1
|
+
import { spawnAndCaptureStdout, spawnWithLogs, withRegisterShim } from "./process.js";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import fsSync from "node:fs";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { createRequire } from "node:module";
|
|
5
6
|
import { fileURLToPath } from "node:url";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
7
|
+
//#region src/runners/playwright.ts
|
|
8
|
+
var require = createRequire(import.meta.url);
|
|
9
|
+
var moduleDir = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
var COMBINED_COVERAGE_ENV_VAR = "RB_TEST_COMBINED_COVERAGE";
|
|
11
|
+
var PLAYWRIGHT_RESULTS_FILE = path.join(process.cwd(), "build", "playwright", "results.json");
|
|
12
|
+
var PLAYWRIGHT_OPTIONS_WITH_REQUIRED_VALUE = /* @__PURE__ */ new Set([
|
|
13
|
+
"--browser",
|
|
14
|
+
"--config",
|
|
15
|
+
"-c",
|
|
16
|
+
"--grep",
|
|
17
|
+
"-g",
|
|
18
|
+
"--grep-invert",
|
|
19
|
+
"--global-timeout",
|
|
20
|
+
"--max-failures",
|
|
21
|
+
"--output",
|
|
22
|
+
"--project",
|
|
23
|
+
"--repeat-each",
|
|
24
|
+
"--reporter",
|
|
25
|
+
"--retries",
|
|
26
|
+
"--shard",
|
|
27
|
+
"--timeout",
|
|
28
|
+
"--trace",
|
|
29
|
+
"--tsconfig",
|
|
30
|
+
"--workers",
|
|
31
|
+
"-j"
|
|
32
|
+
]);
|
|
33
|
+
var PLAYWRIGHT_OPTIONS_WITH_OPTIONAL_VALUE = /* @__PURE__ */ new Set([
|
|
34
|
+
"--only-changed",
|
|
35
|
+
"--update-snapshots",
|
|
36
|
+
"-u"
|
|
37
|
+
]);
|
|
38
|
+
var PLAYWRIGHT_OPTIONS_TO_REMOVE_FOR_WORKER_RETRY = /* @__PURE__ */ new Set([
|
|
39
|
+
"--last-failed",
|
|
40
|
+
"--only-changed",
|
|
41
|
+
"--output",
|
|
42
|
+
"--retries",
|
|
43
|
+
"--pass-with-no-tests",
|
|
44
|
+
"--reporter",
|
|
45
|
+
"--workers",
|
|
46
|
+
"-j"
|
|
47
|
+
]);
|
|
48
|
+
var PLAYWRIGHT_OPTIONS_TO_REMOVE_FOR_INITIAL_FRESH_RUN = /* @__PURE__ */ new Set(["--retries"]);
|
|
49
|
+
var PLAYWRIGHT_RETRY_LOG_LABEL_MAX_LENGTH = 20;
|
|
50
|
+
async function runPlaywright(userArgs, { disableCoverage = false } = {}) {
|
|
51
|
+
const configPath = fsSync.existsSync(path.join(process.cwd(), "playwright.config.ts")) ? path.join(process.cwd(), "playwright.config.ts") : path.join(moduleDir, "..", "playwright.config.ts");
|
|
52
|
+
const hasCustomConfig = userArgs.some((arg) => {
|
|
53
|
+
if (arg === "--config" || arg === "-c") return true;
|
|
54
|
+
return arg.startsWith("--config=");
|
|
55
|
+
});
|
|
56
|
+
ensureJsxRuntimeShim(process.cwd());
|
|
57
|
+
const launcher = resolvePlaywrightLauncher();
|
|
58
|
+
const env = withRegisterShim(process.env);
|
|
59
|
+
env[COMBINED_COVERAGE_ENV_VAR] = "1";
|
|
60
|
+
if (disableCoverage) env.RB_DISABLE_COVERAGE = "1";
|
|
61
|
+
const runtimeSettings = await resolveFreshWorkerRetrySettings({
|
|
62
|
+
launcher,
|
|
63
|
+
configPath,
|
|
64
|
+
hasCustomConfig,
|
|
65
|
+
userArgs,
|
|
66
|
+
env
|
|
67
|
+
});
|
|
68
|
+
const configuredRetries = runtimeSettings.retries;
|
|
69
|
+
const retryConcurrency = Math.max(1, runtimeSettings.workers ?? 1);
|
|
70
|
+
const resultsMtimeBeforeRun = getFileMtimeMs(PLAYWRIGHT_RESULTS_FILE);
|
|
71
|
+
const initialRunArgs = buildPlaywrightInitialFreshWorkerArgs(userArgs);
|
|
72
|
+
const initialPlaywrightArgs = ["test"];
|
|
73
|
+
if (!hasCustomConfig) initialPlaywrightArgs.push("--config", configPath);
|
|
74
|
+
initialPlaywrightArgs.push(...initialRunArgs);
|
|
75
|
+
try {
|
|
76
|
+
await runPlaywrightOnce({
|
|
77
|
+
launcher,
|
|
78
|
+
args: initialPlaywrightArgs,
|
|
79
|
+
env
|
|
80
|
+
});
|
|
81
|
+
return;
|
|
82
|
+
} catch (error) {
|
|
83
|
+
const summary = await readPlaywrightReportSummary(PLAYWRIGHT_RESULTS_FILE, resultsMtimeBeforeRun);
|
|
84
|
+
if (!summary || configuredRetries <= 0 || summary.failedFiles.length === 0) throw error;
|
|
85
|
+
let lastError = error;
|
|
86
|
+
let failedFiles = summary.failedFiles;
|
|
87
|
+
const maxAttempts = configuredRetries;
|
|
88
|
+
for (let attempt = 1; attempt <= maxAttempts && failedFiles.length > 0; attempt += 1) {
|
|
89
|
+
const activeRetryWorkers = Math.max(1, Math.min(retryConcurrency, failedFiles.length));
|
|
90
|
+
console.warn(`[rb-test] Retrying ${failedFiles.length} failed Playwright file(s) with fresh workers (${attempt}/${maxAttempts}, up to ${activeRetryWorkers} in parallel)`);
|
|
91
|
+
const retryResults = await runPlaywrightRetryAttempt({
|
|
92
|
+
launcher,
|
|
93
|
+
userArgs,
|
|
94
|
+
failedFiles,
|
|
95
|
+
retryConcurrency: activeRetryWorkers,
|
|
96
|
+
configPath,
|
|
97
|
+
hasCustomConfig,
|
|
98
|
+
env,
|
|
99
|
+
attempt
|
|
100
|
+
});
|
|
101
|
+
if (retryResults.lastError) lastError = retryResults.lastError;
|
|
102
|
+
failedFiles = retryResults.failedFiles;
|
|
103
|
+
}
|
|
104
|
+
if (failedFiles.length === 0) return;
|
|
105
|
+
throw lastError;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function runPlaywrightOnce({ launcher, args, env, outputMode = "chunk", bufferOutput = false, successMessage, failureMessage, stdoutLinePrefix, stderrLinePrefix }) {
|
|
109
|
+
return spawnWithLogs({
|
|
110
|
+
name: "Playwright",
|
|
111
|
+
launcher,
|
|
112
|
+
args,
|
|
113
|
+
env,
|
|
114
|
+
outputMode,
|
|
115
|
+
bufferOutput,
|
|
116
|
+
successMessage: successMessage === void 0 ? "Playwright suite passed!" : successMessage ?? void 0,
|
|
117
|
+
failureMessage: failureMessage === void 0 ? "Playwright failed" : failureMessage ?? void 0,
|
|
118
|
+
stdoutLinePrefix,
|
|
119
|
+
stderrLinePrefix
|
|
120
|
+
});
|
|
111
121
|
}
|
|
112
122
|
function resolvePlaywrightLauncher() {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
return {
|
|
128
|
-
command: "playwright",
|
|
129
|
-
args: []
|
|
130
|
-
};
|
|
123
|
+
const cliPath = resolveCliPath();
|
|
124
|
+
if (cliPath) return {
|
|
125
|
+
command: process.execPath,
|
|
126
|
+
args: [cliPath]
|
|
127
|
+
};
|
|
128
|
+
const localBin = path.resolve(process.cwd(), "node_modules/.bin/playwright");
|
|
129
|
+
if (fsSync.existsSync(localBin)) return {
|
|
130
|
+
command: localBin,
|
|
131
|
+
args: []
|
|
132
|
+
};
|
|
133
|
+
return {
|
|
134
|
+
command: "playwright",
|
|
135
|
+
args: []
|
|
136
|
+
};
|
|
131
137
|
}
|
|
132
138
|
function resolveCliPath() {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
if (fs.existsSync(cliPath)) {
|
|
141
|
-
return cliPath;
|
|
142
|
-
}
|
|
143
|
-
} catch (_error) {
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
return null;
|
|
139
|
+
const searchRoots = [process.cwd(), moduleDir];
|
|
140
|
+
for (const base of searchRoots) try {
|
|
141
|
+
const pkgPath = require.resolve("@playwright/test/package.json", { paths: [base] });
|
|
142
|
+
const cliPath = path.join(path.dirname(pkgPath), "cli.js");
|
|
143
|
+
if (fsSync.existsSync(cliPath)) return cliPath;
|
|
144
|
+
} catch (_error) {}
|
|
145
|
+
return null;
|
|
147
146
|
}
|
|
148
147
|
function buildPlaywrightWorkerRetryArgs(userArgs, failedFiles, attempt) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
148
|
+
return [
|
|
149
|
+
...removePlaywrightOptions(extractPlaywrightOptionArgs(userArgs), PLAYWRIGHT_OPTIONS_TO_REMOVE_FOR_WORKER_RETRY),
|
|
150
|
+
"--retries=0",
|
|
151
|
+
"--workers=1",
|
|
152
|
+
"--reporter=list",
|
|
153
|
+
"--output",
|
|
154
|
+
buildPlaywrightRetryOutputDir(attempt, failedFiles),
|
|
155
|
+
...failedFiles
|
|
156
|
+
];
|
|
152
157
|
}
|
|
153
158
|
function buildPlaywrightInitialFreshWorkerArgs(userArgs) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
retries: null,
|
|
201
|
-
workers: null
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
return {
|
|
205
|
-
retries: resolvePlaywrightRetriesFromReport(json),
|
|
206
|
-
workers: resolvePlaywrightWorkersFromReport(json)
|
|
207
|
-
};
|
|
208
|
-
} catch (_error) {
|
|
209
|
-
return {
|
|
210
|
-
retries: null,
|
|
211
|
-
workers: null
|
|
212
|
-
};
|
|
213
|
-
}
|
|
159
|
+
const sanitizedOptions = removePlaywrightOptions(extractPlaywrightOptionArgs(userArgs), PLAYWRIGHT_OPTIONS_TO_REMOVE_FOR_INITIAL_FRESH_RUN);
|
|
160
|
+
const positionalArgs = extractPlaywrightPositionalArgs(userArgs);
|
|
161
|
+
return [
|
|
162
|
+
...sanitizedOptions,
|
|
163
|
+
"--retries=0",
|
|
164
|
+
...positionalArgs
|
|
165
|
+
];
|
|
166
|
+
}
|
|
167
|
+
async function resolveFreshWorkerRetrySettings({ launcher, configPath, hasCustomConfig, userArgs, env }) {
|
|
168
|
+
const configuredSettings = await probeConfiguredPlaywrightSettings({
|
|
169
|
+
launcher,
|
|
170
|
+
configPath,
|
|
171
|
+
hasCustomConfig,
|
|
172
|
+
userArgs,
|
|
173
|
+
env
|
|
174
|
+
});
|
|
175
|
+
return {
|
|
176
|
+
retries: configuredSettings.retries ?? 0,
|
|
177
|
+
workers: configuredSettings.workers
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
async function probeConfiguredPlaywrightSettings({ launcher, configPath, hasCustomConfig, userArgs, env }) {
|
|
181
|
+
const probeArgs = ["test"];
|
|
182
|
+
if (!hasCustomConfig) probeArgs.push("--config", configPath);
|
|
183
|
+
probeArgs.push("--list", "--reporter=json", ...extractPlaywrightProjectArgs(userArgs));
|
|
184
|
+
try {
|
|
185
|
+
const json = parseJsonObjectFromText(await spawnAndCaptureStdout({
|
|
186
|
+
name: "Playwright retries probe",
|
|
187
|
+
launcher,
|
|
188
|
+
args: probeArgs,
|
|
189
|
+
env
|
|
190
|
+
}));
|
|
191
|
+
if (!json) return {
|
|
192
|
+
retries: null,
|
|
193
|
+
workers: null
|
|
194
|
+
};
|
|
195
|
+
return {
|
|
196
|
+
retries: resolvePlaywrightRetriesFromReport(json),
|
|
197
|
+
workers: resolvePlaywrightWorkersFromReport(json)
|
|
198
|
+
};
|
|
199
|
+
} catch (_error) {
|
|
200
|
+
return {
|
|
201
|
+
retries: null,
|
|
202
|
+
workers: null
|
|
203
|
+
};
|
|
204
|
+
}
|
|
214
205
|
}
|
|
215
206
|
function extractPlaywrightProjectArgs(userArgs) {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
output.push(arg);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
return output;
|
|
207
|
+
const output = [];
|
|
208
|
+
for (let i = 0; i < userArgs.length; i += 1) {
|
|
209
|
+
const arg = userArgs[i];
|
|
210
|
+
if (arg === "--") break;
|
|
211
|
+
if (arg === "--project") {
|
|
212
|
+
const next = userArgs[i + 1];
|
|
213
|
+
if (next != null) {
|
|
214
|
+
output.push(arg, next);
|
|
215
|
+
i += 1;
|
|
216
|
+
}
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
if (arg.startsWith("--project=")) output.push(arg);
|
|
220
|
+
}
|
|
221
|
+
return output;
|
|
235
222
|
}
|
|
236
223
|
function parseJsonObjectFromText(input) {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
}
|
|
250
|
-
}
|
|
224
|
+
try {
|
|
225
|
+
return JSON.parse(input);
|
|
226
|
+
} catch {
|
|
227
|
+
const start = input.indexOf("{");
|
|
228
|
+
const end = input.lastIndexOf("}");
|
|
229
|
+
if (start === -1 || end === -1 || end <= start) return null;
|
|
230
|
+
try {
|
|
231
|
+
return JSON.parse(input.slice(start, end + 1));
|
|
232
|
+
} catch {
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
251
236
|
}
|
|
252
237
|
function extractPlaywrightPositionalArgs(userArgs) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}
|
|
273
|
-
if (PLAYWRIGHT_OPTIONS_WITH_OPTIONAL_VALUE.has(arg)) {
|
|
274
|
-
const next = userArgs[i + 1];
|
|
275
|
-
if (next !== void 0 && !next.startsWith("-")) {
|
|
276
|
-
i += 1;
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
return output;
|
|
238
|
+
const output = [];
|
|
239
|
+
for (let i = 0; i < userArgs.length; i += 1) {
|
|
240
|
+
const arg = userArgs[i];
|
|
241
|
+
if (arg === "--") break;
|
|
242
|
+
if (!arg.startsWith("-")) {
|
|
243
|
+
output.push(arg);
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
if (arg.includes("=")) continue;
|
|
247
|
+
if (PLAYWRIGHT_OPTIONS_WITH_REQUIRED_VALUE.has(arg)) {
|
|
248
|
+
if (userArgs[i + 1] !== void 0) i += 1;
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
if (PLAYWRIGHT_OPTIONS_WITH_OPTIONAL_VALUE.has(arg)) {
|
|
252
|
+
const next = userArgs[i + 1];
|
|
253
|
+
if (next !== void 0 && !next.startsWith("-")) i += 1;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return output;
|
|
281
257
|
}
|
|
282
258
|
function removePlaywrightOptions(optionArgs, optionsToRemove) {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
const next = optionArgs[i + 1];
|
|
303
|
-
if (next !== void 0 && !next.startsWith("-")) {
|
|
304
|
-
i += 1;
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
return output;
|
|
259
|
+
const output = [];
|
|
260
|
+
for (let i = 0; i < optionArgs.length; i += 1) {
|
|
261
|
+
const arg = optionArgs[i];
|
|
262
|
+
const normalized = arg.split("=")[0];
|
|
263
|
+
if (!arg.startsWith("-") || !optionsToRemove.has(normalized)) {
|
|
264
|
+
output.push(arg);
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
if (arg.includes("=")) continue;
|
|
268
|
+
if (PLAYWRIGHT_OPTIONS_WITH_REQUIRED_VALUE.has(normalized)) {
|
|
269
|
+
if (optionArgs[i + 1] !== void 0) i += 1;
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
if (PLAYWRIGHT_OPTIONS_WITH_OPTIONAL_VALUE.has(normalized)) {
|
|
273
|
+
const next = optionArgs[i + 1];
|
|
274
|
+
if (next !== void 0 && !next.startsWith("-")) i += 1;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return output;
|
|
309
278
|
}
|
|
310
279
|
function extractPlaywrightOptionArgs(userArgs) {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
output.push(next);
|
|
336
|
-
i += 1;
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
return output;
|
|
280
|
+
const output = [];
|
|
281
|
+
for (let i = 0; i < userArgs.length; i += 1) {
|
|
282
|
+
const arg = userArgs[i];
|
|
283
|
+
if (arg === "--") break;
|
|
284
|
+
if (!arg.startsWith("-")) continue;
|
|
285
|
+
output.push(arg);
|
|
286
|
+
if (arg.includes("=")) continue;
|
|
287
|
+
if (PLAYWRIGHT_OPTIONS_WITH_REQUIRED_VALUE.has(arg)) {
|
|
288
|
+
const next = userArgs[i + 1];
|
|
289
|
+
if (next !== void 0) {
|
|
290
|
+
output.push(next);
|
|
291
|
+
i += 1;
|
|
292
|
+
}
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
if (PLAYWRIGHT_OPTIONS_WITH_OPTIONAL_VALUE.has(arg)) {
|
|
296
|
+
const next = userArgs[i + 1];
|
|
297
|
+
if (next !== void 0 && !next.startsWith("-")) {
|
|
298
|
+
output.push(next);
|
|
299
|
+
i += 1;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return output;
|
|
341
304
|
}
|
|
342
305
|
async function readPlaywrightReportSummary(resultsFilePath, newerThanMtimeMs) {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
}
|
|
350
|
-
const data = await readJson(resultsFilePath);
|
|
351
|
-
if (!data || typeof data !== "object") {
|
|
352
|
-
return null;
|
|
353
|
-
}
|
|
354
|
-
return {
|
|
355
|
-
failedFiles: resolveFailedPlaywrightFiles(data)
|
|
356
|
-
};
|
|
306
|
+
const stats = await fs.stat(resultsFilePath).catch(() => null);
|
|
307
|
+
if (!stats) return null;
|
|
308
|
+
if (newerThanMtimeMs != null && stats.mtimeMs <= newerThanMtimeMs) return null;
|
|
309
|
+
const data = await readJson(resultsFilePath);
|
|
310
|
+
if (!data || typeof data !== "object") return null;
|
|
311
|
+
return { failedFiles: resolveFailedPlaywrightFiles(data) };
|
|
357
312
|
}
|
|
358
313
|
function getFileMtimeMs(filePath) {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
314
|
+
try {
|
|
315
|
+
return fsSync.statSync(filePath).mtimeMs;
|
|
316
|
+
} catch {
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
364
319
|
}
|
|
365
320
|
function resolvePlaywrightRetriesFromReport(data) {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
const fallback = Number(data?.config?.retries);
|
|
372
|
-
if (Number.isFinite(fallback)) {
|
|
373
|
-
return Math.max(0, Math.floor(fallback));
|
|
374
|
-
}
|
|
375
|
-
return 0;
|
|
321
|
+
const retriesFromProjects = (Array.isArray(data?.config?.projects) ? data.config.projects : []).map((project) => Number(project?.retries)).filter((value) => Number.isFinite(value)).map((value) => Math.max(0, Math.floor(value)));
|
|
322
|
+
if (retriesFromProjects.length > 0) return Math.max(...retriesFromProjects);
|
|
323
|
+
const fallback = Number(data?.config?.retries);
|
|
324
|
+
if (Number.isFinite(fallback)) return Math.max(0, Math.floor(fallback));
|
|
325
|
+
return 0;
|
|
376
326
|
}
|
|
377
327
|
function resolvePlaywrightWorkersFromReport(data) {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
const workersFromProjects = projects.map((project) => Number(project?.metadata?.actualWorkers ?? project?.workers)).filter((value) => Number.isFinite(value)).map((value) => Math.max(1, Math.floor(value)));
|
|
384
|
-
if (workersFromProjects.length > 0) {
|
|
385
|
-
return Math.max(...workersFromProjects);
|
|
386
|
-
}
|
|
387
|
-
return null;
|
|
328
|
+
const configWorkers = Number(data?.config?.workers);
|
|
329
|
+
if (Number.isFinite(configWorkers)) return Math.max(1, Math.floor(configWorkers));
|
|
330
|
+
const workersFromProjects = (Array.isArray(data?.config?.projects) ? data.config.projects : []).map((project) => Number(project?.metadata?.actualWorkers ?? project?.workers)).filter((value) => Number.isFinite(value)).map((value) => Math.max(1, Math.floor(value)));
|
|
331
|
+
if (workersFromProjects.length > 0) return Math.max(...workersFromProjects);
|
|
332
|
+
return null;
|
|
388
333
|
}
|
|
389
334
|
function resolveFailedPlaywrightFiles(data) {
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
}
|
|
396
|
-
return Array.from(failedFiles).sort();
|
|
335
|
+
const suites = Array.isArray(data?.suites) ? data.suites : [];
|
|
336
|
+
const rootDir = typeof data?.config?.rootDir === "string" ? data.config.rootDir : null;
|
|
337
|
+
const failedFiles = /* @__PURE__ */ new Set();
|
|
338
|
+
for (const suite of suites) collectFailedPlaywrightFiles(suite, failedFiles, rootDir);
|
|
339
|
+
return Array.from(failedFiles).sort();
|
|
397
340
|
}
|
|
398
341
|
function collectFailedPlaywrightFiles(suite, output, rootDir) {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
const innerSuites = Array.isArray(suite?.suites) ? suite.suites : [];
|
|
410
|
-
for (const innerSuite of innerSuites) {
|
|
411
|
-
collectFailedPlaywrightFiles(innerSuite, output, rootDir);
|
|
412
|
-
}
|
|
342
|
+
const specs = Array.isArray(suite?.specs) ? suite.specs : [];
|
|
343
|
+
for (const spec of specs) {
|
|
344
|
+
if (isPlaywrightSpecSuccessful(spec)) continue;
|
|
345
|
+
const file = normalizePlaywrightReportFile(spec?.file ?? suite?.file, rootDir);
|
|
346
|
+
if (file) output.add(file);
|
|
347
|
+
}
|
|
348
|
+
const innerSuites = Array.isArray(suite?.suites) ? suite.suites : [];
|
|
349
|
+
for (const innerSuite of innerSuites) collectFailedPlaywrightFiles(innerSuite, output, rootDir);
|
|
413
350
|
}
|
|
414
351
|
function isPlaywrightSpecSuccessful(spec) {
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
return true;
|
|
426
|
-
}
|
|
427
|
-
const results = Array.isArray(test?.results) ? test.results : [];
|
|
428
|
-
if (results.length === 0) {
|
|
429
|
-
return false;
|
|
430
|
-
}
|
|
431
|
-
return results.every((result) => result?.status === "passed" || result?.status === "skipped");
|
|
432
|
-
});
|
|
352
|
+
if (typeof spec?.ok === "boolean") return spec.ok;
|
|
353
|
+
const tests = Array.isArray(spec?.tests) ? spec.tests : [];
|
|
354
|
+
if (tests.length === 0) return false;
|
|
355
|
+
return tests.every((test) => {
|
|
356
|
+
const testStatus = String(test?.status ?? "");
|
|
357
|
+
if (testStatus === "expected" || testStatus === "skipped" || testStatus === "flaky") return true;
|
|
358
|
+
const results = Array.isArray(test?.results) ? test.results : [];
|
|
359
|
+
if (results.length === 0) return false;
|
|
360
|
+
return results.every((result) => result?.status === "passed" || result?.status === "skipped");
|
|
361
|
+
});
|
|
433
362
|
}
|
|
434
363
|
function normalizePlaywrightReportFile(filePath, rootDir) {
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
} else {
|
|
450
|
-
absolutePath = rootCandidate ?? cwdCandidate;
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
const relative = path.relative(process.cwd(), absolutePath);
|
|
454
|
-
if (relative === "" || !relative.startsWith("..") && !path.isAbsolute(relative)) {
|
|
455
|
-
return toPosixPath(relative || raw);
|
|
456
|
-
}
|
|
457
|
-
return toPosixPath(raw);
|
|
364
|
+
const raw = String(filePath ?? "").trim();
|
|
365
|
+
if (!raw) return null;
|
|
366
|
+
let absolutePath;
|
|
367
|
+
if (path.isAbsolute(raw)) absolutePath = path.normalize(raw);
|
|
368
|
+
else {
|
|
369
|
+
const cwdCandidate = path.resolve(process.cwd(), raw);
|
|
370
|
+
const rootCandidate = rootDir ? path.resolve(rootDir, raw) : null;
|
|
371
|
+
if (rootCandidate && fsSync.existsSync(rootCandidate)) absolutePath = rootCandidate;
|
|
372
|
+
else if (fsSync.existsSync(cwdCandidate)) absolutePath = cwdCandidate;
|
|
373
|
+
else absolutePath = rootCandidate ?? cwdCandidate;
|
|
374
|
+
}
|
|
375
|
+
const relative = path.relative(process.cwd(), absolutePath);
|
|
376
|
+
if (relative === "" || !relative.startsWith("..") && !path.isAbsolute(relative)) return toPosixPath(relative || raw);
|
|
377
|
+
return toPosixPath(raw);
|
|
458
378
|
}
|
|
459
379
|
function toPosixPath(input) {
|
|
460
|
-
|
|
380
|
+
return String(input ?? "").replaceAll("\\", "/").split(path.sep).join("/");
|
|
461
381
|
}
|
|
462
382
|
function buildPlaywrightRetryOutputDir(attempt, failedFiles) {
|
|
463
|
-
|
|
464
|
-
|
|
383
|
+
const slug = failedFiles.map((file) => toPosixPath(file).replace(/[^a-zA-Z0-9._/-]+/g, "-").replace(/\//g, "__")).join("--");
|
|
384
|
+
return toPosixPath(path.join("build", "playwright", "test-results", "rb-retries", `attempt-${attempt}`, slug));
|
|
465
385
|
}
|
|
466
386
|
function createPlaywrightRetryEnv(baseEnv) {
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
387
|
+
return {
|
|
388
|
+
...baseEnv,
|
|
389
|
+
PLAYWRIGHT_FORCE_TTY: "false"
|
|
390
|
+
};
|
|
471
391
|
}
|
|
472
392
|
function truncatePlaywrightRetryLogLabel(label, maxLength = PLAYWRIGHT_RETRY_LOG_LABEL_MAX_LENGTH) {
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
const visibleChars = maxLength - 3;
|
|
480
|
-
const startLength = Math.ceil(visibleChars / 2);
|
|
481
|
-
const endLength = Math.floor(visibleChars / 2);
|
|
482
|
-
return `${label.slice(0, startLength)}...${label.slice(-endLength)}`;
|
|
393
|
+
if (label.length <= maxLength) return label;
|
|
394
|
+
if (maxLength <= 3) return ".".repeat(Math.max(0, maxLength));
|
|
395
|
+
const visibleChars = maxLength - 3;
|
|
396
|
+
const startLength = Math.ceil(visibleChars / 2);
|
|
397
|
+
const endLength = Math.floor(visibleChars / 2);
|
|
398
|
+
return `${label.slice(0, startLength)}...${label.slice(-endLength)}`;
|
|
483
399
|
}
|
|
484
400
|
function getPlaywrightRetryLogName(failedFile) {
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
})
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
}) {
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
launcher,
|
|
547
|
-
args: retryPlaywrightArgs,
|
|
548
|
-
env: retryEnv,
|
|
549
|
-
outputMode: "line",
|
|
550
|
-
bufferOutput: true,
|
|
551
|
-
successMessage: null,
|
|
552
|
-
failureMessage: `${retryLogLabel} Playwright failed`,
|
|
553
|
-
stdoutLinePrefix: formatPlaywrightRetryLinePrefix({
|
|
554
|
-
failedFile,
|
|
555
|
-
stream: "stdout"
|
|
556
|
-
}),
|
|
557
|
-
stderrLinePrefix: formatPlaywrightRetryLinePrefix({
|
|
558
|
-
failedFile,
|
|
559
|
-
stream: "stderr"
|
|
560
|
-
})
|
|
561
|
-
});
|
|
562
|
-
} catch (retryError) {
|
|
563
|
-
lastError = retryError;
|
|
564
|
-
failedAgain.add(failedFile);
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
await Promise.all(Array.from({
|
|
569
|
-
length: Math.max(1, Math.min(retryConcurrency, failedFiles.length))
|
|
570
|
-
}, () => runNext()));
|
|
571
|
-
return {
|
|
572
|
-
failedFiles: failedFiles.filter((failedFile) => failedAgain.has(failedFile)),
|
|
573
|
-
lastError
|
|
574
|
-
};
|
|
401
|
+
const normalizedFile = toPosixPath(failedFile);
|
|
402
|
+
const relativeFile = normalizedFile.startsWith("build/spec/") ? normalizedFile.slice(11) : normalizedFile;
|
|
403
|
+
return relativeFile.replace(/\.(spec|test)\.[^.]+$/i, "").replace(/\.[^.]+$/i, "").trim() || relativeFile || normalizedFile;
|
|
404
|
+
}
|
|
405
|
+
function formatPlaywrightRetryBracketLabel({ failedFile, suffix = "" }) {
|
|
406
|
+
return `[${truncatePlaywrightRetryLogLabel(getPlaywrightRetryLogName(failedFile), Math.max(1, PLAYWRIGHT_RETRY_LOG_LABEL_MAX_LENGTH - suffix.length))}${suffix}]`;
|
|
407
|
+
}
|
|
408
|
+
function formatPlaywrightRetryLogLabel({ failedFile }) {
|
|
409
|
+
return formatPlaywrightRetryBracketLabel({ failedFile });
|
|
410
|
+
}
|
|
411
|
+
function formatPlaywrightRetryLinePrefix({ failedFile, stream }) {
|
|
412
|
+
return stream === "stderr" ? `${formatPlaywrightRetryBracketLabel({
|
|
413
|
+
failedFile,
|
|
414
|
+
suffix: " stderr"
|
|
415
|
+
})} ` : `${formatPlaywrightRetryLogLabel({ failedFile })} `;
|
|
416
|
+
}
|
|
417
|
+
async function runPlaywrightRetryAttempt({ launcher, userArgs, failedFiles, retryConcurrency, configPath, hasCustomConfig, env, attempt }) {
|
|
418
|
+
const failedAgain = /* @__PURE__ */ new Set();
|
|
419
|
+
let lastError = null;
|
|
420
|
+
let nextIndex = 0;
|
|
421
|
+
const retryEnv = createPlaywrightRetryEnv(env);
|
|
422
|
+
async function runNext() {
|
|
423
|
+
while (nextIndex < failedFiles.length) {
|
|
424
|
+
const fileIndex = nextIndex;
|
|
425
|
+
nextIndex += 1;
|
|
426
|
+
const failedFile = failedFiles[fileIndex];
|
|
427
|
+
const retryLogLabel = formatPlaywrightRetryLogLabel({ failedFile });
|
|
428
|
+
const retryArgs = buildPlaywrightWorkerRetryArgs(userArgs, [failedFile], attempt);
|
|
429
|
+
const retryPlaywrightArgs = ["test"];
|
|
430
|
+
if (!hasCustomConfig) retryPlaywrightArgs.push("--config", configPath);
|
|
431
|
+
retryPlaywrightArgs.push(...retryArgs);
|
|
432
|
+
try {
|
|
433
|
+
console.warn(`${retryLogLabel} Starting fresh-worker retry`);
|
|
434
|
+
await runPlaywrightOnce({
|
|
435
|
+
launcher,
|
|
436
|
+
args: retryPlaywrightArgs,
|
|
437
|
+
env: retryEnv,
|
|
438
|
+
outputMode: "line",
|
|
439
|
+
bufferOutput: true,
|
|
440
|
+
successMessage: null,
|
|
441
|
+
failureMessage: `${retryLogLabel} Playwright failed`,
|
|
442
|
+
stdoutLinePrefix: formatPlaywrightRetryLinePrefix({
|
|
443
|
+
failedFile,
|
|
444
|
+
stream: "stdout"
|
|
445
|
+
}),
|
|
446
|
+
stderrLinePrefix: formatPlaywrightRetryLinePrefix({
|
|
447
|
+
failedFile,
|
|
448
|
+
stream: "stderr"
|
|
449
|
+
})
|
|
450
|
+
});
|
|
451
|
+
} catch (retryError) {
|
|
452
|
+
lastError = retryError;
|
|
453
|
+
failedAgain.add(failedFile);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
await Promise.all(Array.from({ length: Math.max(1, Math.min(retryConcurrency, failedFiles.length)) }, () => runNext()));
|
|
458
|
+
return {
|
|
459
|
+
failedFiles: failedFiles.filter((failedFile) => failedAgain.has(failedFile)),
|
|
460
|
+
lastError
|
|
461
|
+
};
|
|
575
462
|
}
|
|
576
463
|
async function readJson(filePath) {
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
464
|
+
try {
|
|
465
|
+
const raw = await fs.readFile(filePath, "utf8");
|
|
466
|
+
return JSON.parse(raw);
|
|
467
|
+
} catch {
|
|
468
|
+
return null;
|
|
469
|
+
}
|
|
583
470
|
}
|
|
584
471
|
function ensureJsxRuntimeShim(projectRoot) {
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
fs.writeFileSync(filePath, content, "utf8");
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
export {
|
|
610
|
-
createPlaywrightRetryEnv,
|
|
611
|
-
formatPlaywrightRetryLinePrefix,
|
|
612
|
-
formatPlaywrightRetryLogLabel,
|
|
613
|
-
runPlaywright
|
|
614
|
-
};
|
|
615
|
-
//# sourceMappingURL=playwright.js.map
|
|
472
|
+
const shimDir = path.join(projectRoot, "node_modules", "playwright");
|
|
473
|
+
fsSync.mkdirSync(shimDir, { recursive: true });
|
|
474
|
+
for (const { file, target } of [{
|
|
475
|
+
file: "jsx-runtime.js",
|
|
476
|
+
target: "react/jsx-runtime"
|
|
477
|
+
}, {
|
|
478
|
+
file: "jsx-dev-runtime.js",
|
|
479
|
+
target: "react/jsx-dev-runtime"
|
|
480
|
+
}]) {
|
|
481
|
+
const filePath = path.join(shimDir, file);
|
|
482
|
+
if (!fsSync.existsSync(filePath)) {
|
|
483
|
+
const content = `export * from "${target}";\nexport { default } from "${target}";\n`;
|
|
484
|
+
fsSync.writeFileSync(filePath, content, "utf8");
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
//#endregion
|
|
489
|
+
export { createPlaywrightRetryEnv, formatPlaywrightRetryLinePrefix, formatPlaywrightRetryLogLabel, runPlaywright };
|
|
490
|
+
|
|
491
|
+
//# sourceMappingURL=playwright.js.map
|