@rstest/browser 0.11.4 → 0.11.5
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/browser-container/container-static/js/506.b2f920fa67.js +194 -0
- package/dist/browser-container/container-static/js/index.d27fd63f5e.js +1 -0
- package/dist/browser-container/container-static/js/lib-react.e24a1d366b.js +2 -0
- package/dist/browser-container/index.html +1 -1
- package/dist/index.js +76 -124
- package/dist/protocol.d.ts +5 -0
- package/package.json +4 -4
- package/src/client/entry.ts +3 -0
- package/src/hostController.ts +155 -195
- package/src/protocol.ts +6 -0
- package/dist/browser-container/container-static/js/243.a8eed2b9e7.js +0 -27406
- package/dist/browser-container/container-static/js/243.a8eed2b9e7.js.LICENSE.txt +0 -1
- package/dist/browser-container/container-static/js/index.84aaafaf21.js +0 -3058
- package/dist/browser-container/container-static/js/lib-react.62b27a21db.js +0 -8454
- package/dist/browser-container/container-static/js/lib-react.62b27a21db.js.LICENSE.txt +0 -1
package/dist/index.js
CHANGED
|
@@ -3549,6 +3549,30 @@ const createBrowserRuntime = async ({ context, projectEntries: initialProjectEnt
|
|
|
3549
3549
|
return false;
|
|
3550
3550
|
}
|
|
3551
3551
|
};
|
|
3552
|
+
const serveContainerRoute = async (req, res, next)=>{
|
|
3553
|
+
if (!req.url) return void next();
|
|
3554
|
+
const url = new URL(req.url, 'http://localhost');
|
|
3555
|
+
if ('/' === url.pathname) {
|
|
3556
|
+
if (await respondWithDevServerHtml(url, res)) return;
|
|
3557
|
+
const html = injectedContainerHtml || containerHtmlTemplate?.replace(OPTIONS_PLACEHOLDER, 'null');
|
|
3558
|
+
if (html) {
|
|
3559
|
+
res.setHeader('Content-Type', 'text/html');
|
|
3560
|
+
res.end(html);
|
|
3561
|
+
return;
|
|
3562
|
+
}
|
|
3563
|
+
res.statusCode = 502;
|
|
3564
|
+
res.end('Container UI is not available.');
|
|
3565
|
+
return;
|
|
3566
|
+
}
|
|
3567
|
+
if (url.pathname.startsWith('/container-static/')) {
|
|
3568
|
+
if (await proxyDevServerAsset(req, res)) return;
|
|
3569
|
+
if (serveContainer) return void serveContainer(req, res, next);
|
|
3570
|
+
res.statusCode = 502;
|
|
3571
|
+
res.end('Container assets are not available.');
|
|
3572
|
+
return;
|
|
3573
|
+
}
|
|
3574
|
+
next();
|
|
3575
|
+
};
|
|
3552
3576
|
const buildProjectServer = async (project, isContainerServer)=>{
|
|
3553
3577
|
const manifestPath = join(tempDir, toSafeVarName(project.environmentName), VIRTUAL_MANIFEST_FILENAME);
|
|
3554
3578
|
const entry = getProjectEntry(project);
|
|
@@ -3585,7 +3609,10 @@ const createBrowserRuntime = async ({ context, projectEntries: initialProjectEnt
|
|
|
3585
3609
|
server: {
|
|
3586
3610
|
printUrls: false,
|
|
3587
3611
|
port: project.normalizedConfig.browser.port ?? (isContainerServer ? 4000 : 0),
|
|
3588
|
-
strictPort: project.normalizedConfig.browser.strictPort
|
|
3612
|
+
strictPort: project.normalizedConfig.browser.strictPort,
|
|
3613
|
+
setup: isContainerServer ? ({ server })=>{
|
|
3614
|
+
server.middlewares.use(serveContainerRoute);
|
|
3615
|
+
} : void 0
|
|
3589
3616
|
},
|
|
3590
3617
|
dev: createBrowserRsbuildDevConfig(enableHmr),
|
|
3591
3618
|
environments: {
|
|
@@ -3800,27 +3827,6 @@ const createBrowserRuntime = async ({ context, projectEntries: initialProjectEnt
|
|
|
3800
3827
|
}
|
|
3801
3828
|
return;
|
|
3802
3829
|
}
|
|
3803
|
-
if (isContainerServer) {
|
|
3804
|
-
if ('/' === url.pathname) {
|
|
3805
|
-
if (await respondWithDevServerHtml(url, res)) return;
|
|
3806
|
-
const html = injectedContainerHtml || containerHtmlTemplate?.replace(OPTIONS_PLACEHOLDER, 'null');
|
|
3807
|
-
if (html) {
|
|
3808
|
-
res.setHeader('Content-Type', 'text/html');
|
|
3809
|
-
res.end(html);
|
|
3810
|
-
return;
|
|
3811
|
-
}
|
|
3812
|
-
res.statusCode = 502;
|
|
3813
|
-
res.end('Container UI is not available.');
|
|
3814
|
-
return;
|
|
3815
|
-
}
|
|
3816
|
-
if (url.pathname.startsWith('/container-static/')) {
|
|
3817
|
-
if (await proxyDevServerAsset(req, res)) return;
|
|
3818
|
-
if (serveContainer) return void serveContainer(req, res, next);
|
|
3819
|
-
res.statusCode = 502;
|
|
3820
|
-
res.end('Container assets are not available.');
|
|
3821
|
-
return;
|
|
3822
|
-
}
|
|
3823
|
-
}
|
|
3824
3830
|
if ('/runner.html' === url.pathname) {
|
|
3825
3831
|
res.setHeader('Content-Type', 'text/html');
|
|
3826
3832
|
res.end(htmlTemplate);
|
|
@@ -3906,10 +3912,11 @@ async function resolveProjectEntries(context, shardedEntries, browserProjects) {
|
|
|
3906
3912
|
return collectProjectEntries(context, browserProjects);
|
|
3907
3913
|
}
|
|
3908
3914
|
const runBrowserController = async (context, options)=>{
|
|
3909
|
-
const {
|
|
3915
|
+
const { allowEmptyRun = false, filesOnly = false, onTraceEvents, env } = options ?? {};
|
|
3910
3916
|
const buildStart = Date.now();
|
|
3911
3917
|
const isWatchMode = 'watch' === context.command;
|
|
3912
3918
|
const phaseTrackers = onTraceEvents ? new Map() : void 0;
|
|
3919
|
+
const trackerKey = (project, testPath)=>`${project}\u0000${testPath}`;
|
|
3913
3920
|
const browserProjects = options?.projects ?? getBrowserProjects(context);
|
|
3914
3921
|
const useHeadlessDirect = browserProjects.every((project)=>project.normalizedConfig.browser.headless);
|
|
3915
3922
|
const browserSourceMapCache = new Map();
|
|
@@ -3989,27 +3996,15 @@ const runBrowserController = async (context, options)=>{
|
|
|
3989
3996
|
};
|
|
3990
3997
|
const coverageConfig = browserProjects.find((project)=>project.normalizedConfig.coverage?.enabled)?.normalizedConfig.coverage;
|
|
3991
3998
|
const coverageProvider = coverageConfig?.enabled ? await createCoverageProvider(coverageConfig, context.rootPath) : null;
|
|
3992
|
-
const notifyTestRunEnd = async ({ duration,
|
|
3999
|
+
const notifyTestRunEnd = async ({ duration, coverage })=>{
|
|
3993
4000
|
if (!isWatchMode) return;
|
|
3994
|
-
let mergedCoverage;
|
|
3995
|
-
if (coverageProvider) {
|
|
3996
|
-
const coverageMap = coverageProvider.createCoverageMap();
|
|
3997
|
-
let hasCoverage = false;
|
|
3998
|
-
for (const result of context.reporterResults.results)if (result.coverage) {
|
|
3999
|
-
coverageMap.merge(result.coverage);
|
|
4000
|
-
hasCoverage = true;
|
|
4001
|
-
}
|
|
4002
|
-
if (hasCoverage) mergedCoverage = coverageMap.toJSON();
|
|
4003
|
-
}
|
|
4004
4001
|
for (const reporter of context.reporters)await reporter.onTestRunEnd?.({
|
|
4005
4002
|
results: context.reporterResults.results,
|
|
4006
|
-
coverage
|
|
4003
|
+
coverage,
|
|
4007
4004
|
testResults: context.reporterResults.testResults,
|
|
4008
4005
|
duration,
|
|
4009
4006
|
snapshotSummary: context.snapshotManager.summary,
|
|
4010
|
-
getSourcemap: getBrowserSourcemap
|
|
4011
|
-
unhandledErrors,
|
|
4012
|
-
filterRerunTestPaths
|
|
4007
|
+
getSourcemap: getBrowserSourcemap
|
|
4013
4008
|
});
|
|
4014
4009
|
};
|
|
4015
4010
|
const containerDevServerEnv = process.env.RSTEST_CONTAINER_DEV_SERVER;
|
|
@@ -4032,7 +4027,6 @@ const runBrowserController = async (context, options)=>{
|
|
|
4032
4027
|
}
|
|
4033
4028
|
let projectEntries = await resolveProjectEntries(context, options?.shardedEntries, browserProjects);
|
|
4034
4029
|
let totalTests = projectEntries.reduce((total, item)=>total + item.testFiles.length, 0);
|
|
4035
|
-
const shouldKeepWatchingWithEmptySet = isWatchMode && allowEmptyWatchRun;
|
|
4036
4030
|
const shouldInitializeEmptyBrowserHooks = 0 === totalTests && hasUserRstestConfigPlugins(browserProjects);
|
|
4037
4031
|
const createEmptyRunResult = ()=>{
|
|
4038
4032
|
const elapsed = Math.max(0, Date.now() - buildStart);
|
|
@@ -4052,7 +4046,7 @@ const runBrowserController = async (context, options)=>{
|
|
|
4052
4046
|
const reportEmptyTestSet = ()=>{
|
|
4053
4047
|
const code = context.normalizedConfig.passWithNoTests ? 0 : 1;
|
|
4054
4048
|
if (isWatchMode || !allowEmptyRun) {
|
|
4055
|
-
const message =
|
|
4049
|
+
const message = getNoTestFilesMessage({
|
|
4056
4050
|
context,
|
|
4057
4051
|
code,
|
|
4058
4052
|
defaultMessage: `No test files found, exiting with code ${code}.`
|
|
@@ -4062,11 +4056,11 @@ const runBrowserController = async (context, options)=>{
|
|
|
4062
4056
|
if (context.relatedFilters?.length) logger.log(color.gray('related: '), context.relatedFilters.join(color.gray(', ')));
|
|
4063
4057
|
else if (context.fileFilters?.length) logger.log(color.gray('filter: '), context.fileFilters.join(color.gray(', ')));
|
|
4064
4058
|
}
|
|
4065
|
-
if (isWatchMode && 0 !== code && !
|
|
4066
|
-
return !shouldKeepWatchingWithEmptySet;
|
|
4059
|
+
if (isWatchMode && 0 !== code && !allowEmptyRun) ensureProcessExitCode(code);
|
|
4067
4060
|
};
|
|
4068
4061
|
if (0 === totalTests && !shouldInitializeEmptyBrowserHooks) {
|
|
4069
|
-
|
|
4062
|
+
reportEmptyTestSet();
|
|
4063
|
+
return allowEmptyRun ? createEmptyRunResult() : void 0;
|
|
4070
4064
|
}
|
|
4071
4065
|
if (!filesOnly) await notifyTestRunStart();
|
|
4072
4066
|
const enableCliShortcuts = isWatchMode && isTTY('stdin');
|
|
@@ -4131,13 +4125,12 @@ const runBrowserController = async (context, options)=>{
|
|
|
4131
4125
|
} : void 0;
|
|
4132
4126
|
const finalizeWatchRerun = async ({ rerunTestPaths, testTime, unhandledErrors })=>{
|
|
4133
4127
|
const rerunPathSet = new Set(rerunTestPaths);
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
if (coverageMap && coverageMap.files().length > 0) sessionCoverage = coverageMap.toJSON();
|
|
4128
|
+
const rerunResults = context.reporterResults.results.filter((result)=>rerunPathSet.has(result.testPath));
|
|
4129
|
+
let rerunCoverage;
|
|
4130
|
+
const coverageMap = buildBrowserCoverageMap(rerunResults, coverageProvider);
|
|
4131
|
+
if (coverageMap && coverageMap.files().length > 0) rerunCoverage = coverageMap.toJSON();
|
|
4139
4132
|
const outcome = {
|
|
4140
|
-
results:
|
|
4133
|
+
results: rerunResults,
|
|
4141
4134
|
testResults: context.reporterResults.testResults.filter((result)=>rerunPathSet.has(result.testPath)),
|
|
4142
4135
|
errors: unhandledErrors ?? [],
|
|
4143
4136
|
testPaths: rerunTestPaths,
|
|
@@ -4145,8 +4138,8 @@ const runBrowserController = async (context, options)=>{
|
|
|
4145
4138
|
buildTime: drainPendingBuildTime(watchState),
|
|
4146
4139
|
testTime
|
|
4147
4140
|
},
|
|
4148
|
-
coverage:
|
|
4149
|
-
map:
|
|
4141
|
+
coverage: rerunCoverage ? {
|
|
4142
|
+
map: rerunCoverage
|
|
4150
4143
|
} : void 0,
|
|
4151
4144
|
resolveSourcemap: resolveBrowserSourcemap
|
|
4152
4145
|
};
|
|
@@ -4176,7 +4169,8 @@ const runBrowserController = async (context, options)=>{
|
|
|
4176
4169
|
resolveSourcemap: resolveBrowserSourcemap,
|
|
4177
4170
|
close: ()=>destroyBrowserRuntime(runtime)
|
|
4178
4171
|
};
|
|
4179
|
-
if (0 === totalTests
|
|
4172
|
+
if (0 === totalTests) {
|
|
4173
|
+
reportEmptyTestSet();
|
|
4180
4174
|
await destroyBrowserRuntime(runtime);
|
|
4181
4175
|
return allowEmptyRun ? createEmptyRunResult() : void 0;
|
|
4182
4176
|
}
|
|
@@ -4260,19 +4254,17 @@ const runBrowserController = async (context, options)=>{
|
|
|
4260
4254
|
project.name,
|
|
4261
4255
|
createRunnerEventSink(context, project.normalizedConfig)
|
|
4262
4256
|
]));
|
|
4263
|
-
const
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
const projectName = projectNameByTestPath.get(testPath);
|
|
4268
|
-
return projectName ? sinkForProjectName(projectName) : firstBrowserSink;
|
|
4257
|
+
const sinkForProjectName = (projectName)=>{
|
|
4258
|
+
const sink = runnerSinks.get(projectName);
|
|
4259
|
+
if (!sink) throw new Error(`No runner event sink for project "${projectName}"`);
|
|
4260
|
+
return sink;
|
|
4269
4261
|
};
|
|
4270
4262
|
const silentConsoleController = createSilentConsoleController({
|
|
4271
4263
|
runtimeConfig: {
|
|
4272
4264
|
silent: context.normalizedConfig.silent,
|
|
4273
4265
|
disableConsoleIntercept: context.normalizedConfig.disableConsoleIntercept
|
|
4274
4266
|
},
|
|
4275
|
-
emitInterceptedLog: (log)=>
|
|
4267
|
+
emitInterceptedLog: (log)=>sinkForProjectName(log.project).onConsoleLog(log),
|
|
4276
4268
|
writeOriginalLog: ()=>{}
|
|
4277
4269
|
});
|
|
4278
4270
|
const snapshotRpcMethods = {
|
|
@@ -4300,7 +4292,6 @@ const runBrowserController = async (context, options)=>{
|
|
|
4300
4292
|
}
|
|
4301
4293
|
};
|
|
4302
4294
|
const handleTestFileStart = async (payload)=>{
|
|
4303
|
-
projectNameByTestPath.set(payload.testPath, payload.projectName);
|
|
4304
4295
|
if (phaseTrackers) {
|
|
4305
4296
|
const tracker = new PhaseTracker({
|
|
4306
4297
|
trace: {
|
|
@@ -4310,25 +4301,26 @@ const runBrowserController = async (context, options)=>{
|
|
|
4310
4301
|
pid: nextBrowserFilePid++
|
|
4311
4302
|
});
|
|
4312
4303
|
tracker.transition('prepare');
|
|
4313
|
-
phaseTrackers.set(payload.testPath, tracker);
|
|
4304
|
+
phaseTrackers.set(trackerKey(payload.projectName, payload.testPath), tracker);
|
|
4314
4305
|
}
|
|
4315
4306
|
await sinkForProjectName(payload.projectName).onTestFileStart({
|
|
4316
4307
|
testId: getFileTaskId(payload.testPath),
|
|
4317
4308
|
testPath: payload.testPath,
|
|
4309
|
+
project: payload.projectName,
|
|
4318
4310
|
tests: []
|
|
4319
4311
|
});
|
|
4320
4312
|
};
|
|
4321
4313
|
const handleTestFileReady = async (payload)=>{
|
|
4322
|
-
phaseTrackers?.get(payload.testPath)?.transition('tests');
|
|
4323
|
-
await
|
|
4314
|
+
phaseTrackers?.get(trackerKey(payload.project, payload.testPath))?.transition('tests');
|
|
4315
|
+
await sinkForProjectName(payload.project).onTestFileReady(payload);
|
|
4324
4316
|
};
|
|
4325
4317
|
const handleTestSuiteStart = async (payload)=>{
|
|
4326
|
-
phaseTrackers?.get(payload.testPath)?.recordSuiteStart(payload);
|
|
4327
|
-
await
|
|
4318
|
+
phaseTrackers?.get(trackerKey(payload.project, payload.testPath))?.recordSuiteStart(payload);
|
|
4319
|
+
await sinkForProjectName(payload.project).onTestSuiteStart(payload);
|
|
4328
4320
|
};
|
|
4329
4321
|
const handleTestSuiteResult = async (payload)=>{
|
|
4330
|
-
phaseTrackers?.get(payload.testPath)?.recordSuiteResult(payload);
|
|
4331
|
-
await
|
|
4322
|
+
phaseTrackers?.get(trackerKey(payload.project, payload.testPath))?.recordSuiteResult(payload);
|
|
4323
|
+
await sinkForProjectName(payload.project).onTestSuiteResult(payload);
|
|
4332
4324
|
if ('passed-only' === context.normalizedConfig.silent) silentConsoleController.flushBufferedLogsForTask({
|
|
4333
4325
|
taskId: payload.testId,
|
|
4334
4326
|
status: payload.status,
|
|
@@ -4338,13 +4330,13 @@ const runBrowserController = async (context, options)=>{
|
|
|
4338
4330
|
});
|
|
4339
4331
|
};
|
|
4340
4332
|
const handleTestCaseStart = async (payload)=>{
|
|
4341
|
-
phaseTrackers?.get(payload.testPath)?.recordCaseStart(payload);
|
|
4342
|
-
|
|
4333
|
+
phaseTrackers?.get(trackerKey(payload.project, payload.testPath))?.recordCaseStart(payload);
|
|
4334
|
+
sinkForProjectName(payload.project).onTestCaseStart(payload);
|
|
4343
4335
|
};
|
|
4344
4336
|
const handleTestCaseResult = async (payload)=>{
|
|
4345
4337
|
caseResults.push(payload);
|
|
4346
|
-
phaseTrackers?.get(payload.testPath)?.recordCaseResult(payload);
|
|
4347
|
-
await
|
|
4338
|
+
phaseTrackers?.get(trackerKey(payload.project, payload.testPath))?.recordCaseResult(payload);
|
|
4339
|
+
await sinkForProjectName(payload.project).onTestCaseResult(payload);
|
|
4348
4340
|
if ('passed-only' === context.normalizedConfig.silent) silentConsoleController.flushBufferedLogsForTask({
|
|
4349
4341
|
taskId: payload.testId,
|
|
4350
4342
|
status: payload.status,
|
|
@@ -4359,12 +4351,13 @@ const runBrowserController = async (context, options)=>{
|
|
|
4359
4351
|
payload
|
|
4360
4352
|
], payload.results);
|
|
4361
4353
|
if (phaseTrackers) {
|
|
4362
|
-
const
|
|
4354
|
+
const key = trackerKey(payload.project, payload.testPath);
|
|
4355
|
+
const tracker = phaseTrackers.get(key);
|
|
4363
4356
|
if (tracker) {
|
|
4364
4357
|
tracker.end();
|
|
4365
4358
|
const events = tracker.getTraceEvents();
|
|
4366
4359
|
if (events) onTraceEvents?.(events);
|
|
4367
|
-
phaseTrackers.delete(
|
|
4360
|
+
phaseTrackers.delete(key);
|
|
4368
4361
|
}
|
|
4369
4362
|
}
|
|
4370
4363
|
if ('passed-only' === context.normalizedConfig.silent) silentConsoleController.flushBufferedLogsForTask({
|
|
@@ -4374,7 +4367,7 @@ const runBrowserController = async (context, options)=>{
|
|
|
4374
4367
|
taskType: 'file',
|
|
4375
4368
|
testPath: payload.testPath
|
|
4376
4369
|
});
|
|
4377
|
-
await
|
|
4370
|
+
await sinkForProjectName(payload.project).onTestFileResult(payload);
|
|
4378
4371
|
if (isWatchMode && 'fail' === payload.status) ensureProcessExitCode(1);
|
|
4379
4372
|
};
|
|
4380
4373
|
const handleLog = async (payload)=>{
|
|
@@ -4386,6 +4379,7 @@ const runBrowserController = async (context, options)=>{
|
|
|
4386
4379
|
taskParentNames: payload.taskParentNames,
|
|
4387
4380
|
taskType: payload.taskType,
|
|
4388
4381
|
testPath: payload.testPath,
|
|
4382
|
+
project: payload.projectName,
|
|
4389
4383
|
type: payload.type,
|
|
4390
4384
|
trace: payload.trace
|
|
4391
4385
|
};
|
|
@@ -4686,54 +4680,6 @@ const runBrowserController = async (context, options)=>{
|
|
|
4686
4680
|
}
|
|
4687
4681
|
});
|
|
4688
4682
|
awaitHeadlessRerunIdle = ()=>latestRerunScheduler.whenIdle();
|
|
4689
|
-
if (0 === allTestFiles.length) {
|
|
4690
|
-
const duration = {
|
|
4691
|
-
totalTime: buildTime,
|
|
4692
|
-
buildTime,
|
|
4693
|
-
testTime: 0
|
|
4694
|
-
};
|
|
4695
|
-
const result = {
|
|
4696
|
-
results: reporterResults,
|
|
4697
|
-
testResults: caseResults,
|
|
4698
|
-
duration,
|
|
4699
|
-
hasFailure: false,
|
|
4700
|
-
getSourcemap: getBrowserSourcemap,
|
|
4701
|
-
resolveSourcemap: resolveBrowserSourcemap,
|
|
4702
|
-
close: isWatchMode ? void 0 : async ()=>{
|
|
4703
|
-
sessionRegistry.clear();
|
|
4704
|
-
await destroyBrowserRuntime(runtime);
|
|
4705
|
-
},
|
|
4706
|
-
watch: watchHandles
|
|
4707
|
-
};
|
|
4708
|
-
if (isWatchMode) await notifyTestRunEnd({
|
|
4709
|
-
duration
|
|
4710
|
-
});
|
|
4711
|
-
if (isWatchMode) {
|
|
4712
|
-
triggerRerun = async ()=>{
|
|
4713
|
-
const newProjectEntries = await collectProjectEntries(context);
|
|
4714
|
-
const rerunPlan = planWatchRerun({
|
|
4715
|
-
projectEntries: newProjectEntries,
|
|
4716
|
-
previousTestFiles: watchState.lastTestFiles,
|
|
4717
|
-
affectedTestFiles: drainPendingAffectedTestFiles(watchState)
|
|
4718
|
-
});
|
|
4719
|
-
if (rerunPlan.filesChanged) {
|
|
4720
|
-
watchState.lastTestFiles = rerunPlan.currentTestFiles;
|
|
4721
|
-
if (0 === rerunPlan.currentTestFiles.length) {
|
|
4722
|
-
logger.log(color.cyan('No browser test files remain after update.\n'));
|
|
4723
|
-
logWatchReadyMessage(context, enableCliShortcuts);
|
|
4724
|
-
return;
|
|
4725
|
-
}
|
|
4726
|
-
logger.log(color.cyan(`Test file set changed, re-running ${rerunPlan.currentTestFiles.length} file(s)...\n`));
|
|
4727
|
-
await latestRerunScheduler.enqueueLatest(rerunPlan.currentTestFiles);
|
|
4728
|
-
return;
|
|
4729
|
-
}
|
|
4730
|
-
logWatchReadyMessage(context, enableCliShortcuts);
|
|
4731
|
-
};
|
|
4732
|
-
watchState.hooksEnabled = true;
|
|
4733
|
-
logWatchReadyMessage(context, enableCliShortcuts);
|
|
4734
|
-
}
|
|
4735
|
-
return result;
|
|
4736
|
-
}
|
|
4737
4683
|
const testStart = Date.now();
|
|
4738
4684
|
await runFilesWithPool(allTestFiles);
|
|
4739
4685
|
const testTime = Date.now() - testStart;
|
|
@@ -4779,6 +4725,7 @@ const runBrowserController = async (context, options)=>{
|
|
|
4779
4725
|
context.updateReporterResultState(reporterResults, caseResults);
|
|
4780
4726
|
const isFailure = reporterResults.some((result)=>'fail' === result.status);
|
|
4781
4727
|
if (isWatchMode && isFailure) ensureProcessExitCode(1);
|
|
4728
|
+
const cycleCoverageMap = isWatchMode && coverageProvider ? buildBrowserCoverageMap(reporterResults, coverageProvider) : void 0;
|
|
4782
4729
|
const result = {
|
|
4783
4730
|
results: reporterResults,
|
|
4784
4731
|
testResults: caseResults,
|
|
@@ -4787,11 +4734,13 @@ const runBrowserController = async (context, options)=>{
|
|
|
4787
4734
|
getSourcemap: getBrowserSourcemap,
|
|
4788
4735
|
resolveSourcemap: resolveBrowserSourcemap,
|
|
4789
4736
|
close: closeHeadlessRuntime,
|
|
4737
|
+
coverage: cycleCoverageMap,
|
|
4790
4738
|
watch: watchHandles
|
|
4791
4739
|
};
|
|
4792
4740
|
if (isWatchMode) try {
|
|
4793
4741
|
await notifyTestRunEnd({
|
|
4794
|
-
duration
|
|
4742
|
+
duration,
|
|
4743
|
+
coverage: cycleCoverageMap?.files().length ? cycleCoverageMap.toJSON() : void 0
|
|
4795
4744
|
});
|
|
4796
4745
|
} finally{
|
|
4797
4746
|
await closeHeadlessRuntime?.();
|
|
@@ -5084,6 +5033,7 @@ const runBrowserController = async (context, options)=>{
|
|
|
5084
5033
|
context.updateReporterResultState(reporterResults, caseResults);
|
|
5085
5034
|
const isFailure = reporterResults.some((result)=>'fail' === result.status);
|
|
5086
5035
|
if (isWatchMode && isFailure) ensureProcessExitCode(1);
|
|
5036
|
+
const cycleCoverageMap = isWatchMode && coverageProvider ? buildBrowserCoverageMap(reporterResults, coverageProvider) : void 0;
|
|
5087
5037
|
const result = {
|
|
5088
5038
|
results: reporterResults,
|
|
5089
5039
|
testResults: caseResults,
|
|
@@ -5092,11 +5042,13 @@ const runBrowserController = async (context, options)=>{
|
|
|
5092
5042
|
getSourcemap: getBrowserSourcemap,
|
|
5093
5043
|
resolveSourcemap: resolveBrowserSourcemap,
|
|
5094
5044
|
close: closeContainerRuntime,
|
|
5045
|
+
coverage: cycleCoverageMap,
|
|
5095
5046
|
watch: watchHandles
|
|
5096
5047
|
};
|
|
5097
5048
|
if (isWatchMode) try {
|
|
5098
5049
|
await notifyTestRunEnd({
|
|
5099
|
-
duration
|
|
5050
|
+
duration,
|
|
5051
|
+
coverage: cycleCoverageMap?.files().length ? cycleCoverageMap.toJSON() : void 0
|
|
5100
5052
|
});
|
|
5101
5053
|
} finally{
|
|
5102
5054
|
await closeContainerRuntime?.();
|
package/dist/protocol.d.ts
CHANGED
|
@@ -45,6 +45,11 @@ export type BrowserProjectRuntime = {
|
|
|
45
45
|
*/ export type BrowserLogPayload = {
|
|
46
46
|
level: 'log' | 'warn' | 'error' | 'info' | 'debug';
|
|
47
47
|
content: string;
|
|
48
|
+
/**
|
|
49
|
+
* Owning project, resolved by the client from its manifest. The host must
|
|
50
|
+
* not re-derive it from `testPath` — concurrent projects can run the same
|
|
51
|
+
* file, so a path-keyed lookup can attribute the log to the wrong project.
|
|
52
|
+
*/ projectName: string;
|
|
48
53
|
taskId?: string;
|
|
49
54
|
taskName?: string;
|
|
50
55
|
taskParentNames?: string[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rstest/browser",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.5",
|
|
4
4
|
"description": "Browser mode support for Rstest testing framework.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"rstest",
|
|
@@ -55,14 +55,14 @@
|
|
|
55
55
|
"@vitest/snapshot": "^4.1.10",
|
|
56
56
|
"birpc": "^4.0.0",
|
|
57
57
|
"picomatch": "^4.0.5",
|
|
58
|
-
"playwright": "^1.
|
|
58
|
+
"playwright": "^1.62.0",
|
|
59
59
|
"@rstest/browser-ui": "0.0.0",
|
|
60
|
-
"@rstest/core": "0.11.
|
|
60
|
+
"@rstest/core": "0.11.5",
|
|
61
61
|
"@rstest/tsconfig": "0.0.1"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
64
|
"playwright": "^1.49.1",
|
|
65
|
-
"@rstest/core": "^0.11.
|
|
65
|
+
"@rstest/core": "^0.11.5"
|
|
66
66
|
},
|
|
67
67
|
"peerDependenciesMeta": {
|
|
68
68
|
"playwright": {
|
package/src/client/entry.ts
CHANGED
|
@@ -142,6 +142,7 @@ const getFileTaskId = (testPath: string): string => {
|
|
|
142
142
|
* Returns a restore function to revert console to original.
|
|
143
143
|
*/
|
|
144
144
|
const interceptConsole = (
|
|
145
|
+
projectName: string,
|
|
145
146
|
getCurrentTask: () => CurrentTaskInfo | undefined,
|
|
146
147
|
printConsoleTrace: boolean,
|
|
147
148
|
): (() => void) => {
|
|
@@ -176,6 +177,7 @@ const interceptConsole = (
|
|
|
176
177
|
payload: {
|
|
177
178
|
level,
|
|
178
179
|
content,
|
|
180
|
+
projectName,
|
|
179
181
|
taskId: currentTask?.taskId,
|
|
180
182
|
taskName: currentTask?.taskName,
|
|
181
183
|
taskParentNames: currentTask?.taskParentNames,
|
|
@@ -605,6 +607,7 @@ const run = async () => {
|
|
|
605
607
|
// Intercept console methods to forward logs to host
|
|
606
608
|
const restoreConsole = shouldInterceptConsole
|
|
607
609
|
? interceptConsole(
|
|
610
|
+
projectRuntime.name,
|
|
608
611
|
() => taskContext.getCurrent() ?? taskStack[taskStack.length - 1],
|
|
609
612
|
runtimeConfig.disableConsoleIntercept
|
|
610
613
|
? false
|