withChildren
uses tcmts.cli.test.e2e.harness.stopWhenThisEnds, which uses node:child_process
Run fn with a way to keep the processes it starts (servers, watchers), and stop them when it's done, waiting
until they have: a tcm stopped so writes what code it ran as it exits (coverage, which the suite reads once this
test's process ends), and one still writing would be missed, its suite's result cached as though that code
hadn't run. One that doesn't stop in 10 seconds is killed. And if this process ends first, however it ends (a
test that hangs is killed by its suite's time limit, and its finally never runs), they're stopped all the same
(stopWhenThisEnds).
import { stopWhenThisEnds } from "#codebase/tcmts/cli/test/e2e/harness"; import type { ChildProcess } from "node:child_process"; export async function withChildren<T>( fn: (keep: <C extends ChildProcess>(c: C) => C) => Promise<T> | T, ): Promise<T> { const kept: ChildProcess[] = []; try { return await fn((c) => (kept.push(c), stopWhenThisEnds(c), c)); } finally { await Promise.all( kept.map( (c) => new Promise<void>((resolve) => { // (something stopped as a process is, a server in this one: stopped, nothing to wait for) if (typeof c.once !== "function") return (c.kill(), resolve()); if (c.exitCode !== null || c.signalCode !== null) return resolve(); const late = setTimeout(() => c.kill("SIGKILL"), 10_000); c.once("exit", () => (clearTimeout(late), resolve())); c.kill(); }), ), ); } }
uses
used by
- tcmts.cli.test.e2e.builds.testAgentRunsAnOlderBuild
- tcmts.cli.test.e2e.contributions.testContributorsAndPublicRead
- tcmts.cli.test.e2e.contributions.testIllTypedContributionIsRefusedAtMerge
- tcmts.cli.test.e2e.contributions.testPublicServerStartsTheWebUiAhead
- tcmts.cli.test.e2e.contributions.testServeShowsOtherCodebasesForges
- tcmts.cli.test.e2e.contributions.testWebUi
- tcmts.cli.test.e2e.contributions.testWebUiStopsWithTheServer
- tcmts.cli.test.e2e.data.testTablesAndSchedulesByRole
- tcmts.cli.test.e2e.data.testTypedTables
- tcmts.cli.test.e2e.examples.testNotesExample
- tcmts.cli.test.e2e.examples.testPollsExample
- tcmts.cli.test.e2e.examples.testUserinputExample
- tcmts.cli.test.e2e.harness.testServersStopWhenTheirTestDoes
- tcmts.cli.test.e2e.jobs.testBackgroundJobs
- tcmts.cli.test.e2e.libraries.testAnnouncementsAreCheckedBySignature
- tcmts.cli.test.e2e.libraries.testLibrariesFromAnnouncements
- tcmts.cli.test.e2e.libraries.testLibraryAttestations
- tcmts.cli.test.e2e.lsp.testAppsAndDataInEditor
- tcmts.cli.test.e2e.lsp.testChangesInEditor
- tcmts.cli.test.e2e.lsp.testCodeSearchInEditor
- tcmts.cli.test.e2e.lsp.testCodebaseInEditor
- tcmts.cli.test.e2e.lsp.testDebugging
- tcmts.cli.test.e2e.lsp.testLanguageServer
- tcmts.cli.test.e2e.lsp.testPackagesInEditor
- tcmts.cli.test.e2e.lsp.testPages
- tcmts.cli.test.e2e.lsp.testReleasesInEditor
- tcmts.cli.test.e2e.lsp.testScratchQuickFixes
- tcmts.cli.test.e2e.lsp.testVscodeRegistersNoServerCommands
- tcmts.cli.test.e2e.mcp.testASessionWhoseBranchIsGoneGoesOn
- tcmts.cli.test.e2e.mcp.testAgentWorksThroughMcp
- tcmts.cli.test.e2e.mcp.testJobsOutliveTheirServer
- tcmts.cli.test.e2e.mcp.testMcpSessionsAndUpgrades
- tcmts.cli.test.e2e.mcp.testSearchAndFindFollowTheSessionsBranch
- tcmts.cli.test.e2e.mcp.testSessionSaysWhereItsScratchFilesAre
- tcmts.cli.test.e2e.mcp.testSessionsGoOnAfterARestart
- tcmts.cli.test.e2e.mcp.testSessionsLeftBehindAreClearedAway
- tcmts.cli.test.e2e.mcp.testSessionsReadOtherBranches
- tcmts.cli.test.e2e.mcp.testSessionsStartingTogetherKeepTheirBranches
- tcmts.cli.test.e2e.mcp.testSessionsWorkApart
- tcmts.cli.test.e2e.mcp.testSupervisedRestartsKeepTheBranch
- tcmts.cli.test.e2e.mcp.testToolsRunInAWorker
- tcmts.cli.test.e2e.mcp.testUnknownToolOptionsAreRefused
- tcmts.cli.test.e2e.merge.testAMergeNotFinishedIsntPushed
- tcmts.cli.test.e2e.prod.testAppUnderABase
- tcmts.cli.test.e2e.prod.testAssetsKeepTheirUrlsAcrossDeploys
- tcmts.cli.test.e2e.prod.testBuildDuringStart
- tcmts.cli.test.e2e.prod.testBuildStartDeployRollBack
- tcmts.cli.test.e2e.prod.testBuildsOfOneAppAtOnce
- tcmts.cli.test.e2e.prod.testDeployedChunksArriveAsDifferences
- tcmts.cli.test.e2e.prod.testKeptBuildWithoutItsCode
- tcmts.cli.test.e2e.prod.testPagesShellsAreKept
- tcmts.cli.test.e2e.prod.testPushDeploys
- tcmts.cli.test.e2e.prod.testReactCacheLastsARequest
- tcmts.cli.test.e2e.prod.testServerComponentsKeptAndRenderedAhead
- tcmts.cli.test.e2e.prod.testStaticSitesAndPwas
- tcmts.cli.test.e2e.react.testComponentsAreCompiled
- tcmts.cli.test.e2e.react.testLazyChunksLoadWithThePage
- tcmts.cli.test.e2e.react.testPackageComponentsRenderInTheBrowser
- tcmts.cli.test.e2e.react.testPagesKeepAndRenderAhead
- tcmts.cli.test.e2e.react.testReactPlacementStreamingHydration
- tcmts.cli.test.e2e.react.testServerComponentsAreDebuggable
- tcmts.cli.test.e2e.react.testServerFunctionsAsProps
- tcmts.cli.test.e2e.react.testTcmReact
- tcmts.cli.test.e2e.registry.testRegistryShowsAnnouncedLibraries
- tcmts.cli.test.e2e.registry.testRegistrySignInAndStars
- tcmts.cli.test.e2e.releases.testReleasesAnnounced
- tcmts.cli.test.e2e.server.testServerFunctions
- tcmts.cli.test.e2e.suites.testBuildsWaitForASlot
- tcmts.cli.test.e2e.sync.testBigPushesTravelCompressed
- tcmts.cli.test.e2e.sync.testHistoryFromBeforeTheLibrariesTravels
- tcmts.cli.test.e2e.sync.testParallelChecksMatchOneAtATime
- tcmts.cli.test.e2e.sync.testReceivedConstantsArentRun
- tcmts.cli.test.e2e.sync.testReceivedSignaturesFollowRenames
- tcmts.cli.test.e2e.sync.testResultsTravelThroughAServer
- tcmts.cli.test.e2e.sync.testServeRunOn
- tcmts.cli.test.e2e.sync.testServeSite
- tcmts.cli.test.e2e.sync.testServeTlsPinning
- tcmts.cli.test.e2e.watch.testWatcherSaysImportsWithoutWritingThem
- tcmts.cli.test.e2e.watch.testWatcherSeesChangesMadeElsewhere
- tcmts.cli.test.e2e.web.testDevPlacementAndCallsByHash
- tcmts.dev.registryTrial
- tcmts.registry.test.testProfilesAreTheirSignedRecords
- tcmts.registry.test.testRegistryChecksAttestations
- tcmts.registry.test.testRegistryCountsStars
- tcmts.registry.test.testRegistryMirrorsSignedReleases