test(smoke): cover loadBrowser's failure branches; fix a stale helper comment
Two findings from Copilot's suppressed block. 1. The launch-failure message is #2086's acceptance criterion — a missing browser must name THAT engine and its own install command — and it had no test. The smokes cannot supply one: install-smoke-browser fetches the binary first, so a passing smoke says nothing about what a failing one prints, and that message is the deliverable. loadBrowser now takes an injectable loadPlaywright purely to open that seam. The test asserts per engine that the message leads with that engine, names --with-deps <that engine> and no other, and preserves the underlying cause. Verified by mutation: hard-coding 'chromium' in the message fails it. It also pins the two branches apart — an unresolvable package must say > @modelcontextprotocol/inspector@2.3.0 postinstall > node scripts/install-clients.mjs [install-clients] Installing dependencies for clients/web... up to date, audited 583 packages in 614ms 198 packages are looking for funding run `npm fund` for details found 0 vulnerabilities [install-clients] Installing dependencies for clients/cli... up to date, audited 237 packages in 496ms 69 packages are looking for funding run `npm fund` for details found 0 vulnerabilities [install-clients] Installing dependencies for clients/tui... up to date, audited 314 packages in 518ms 102 packages are looking for funding run `npm fund` for details found 0 vulnerabilities [install-clients] Installing dependencies for clients/launcher... up to date, audited 160 packages in 449ms 50 packages are looking for funding run `npm fund` for details found 0 vulnerabilities up to date, audited 281 packages in 3s 108 packages are looking for funding run `npm fund` for details found 0 vulnerabilities and must NOT say , which fetches binaries and cannot fix a missing package. The unsupported-engine test now also asserts loadPlaywright was never called, pinning the ORDER rather than only the message: validating first is what makes the error name the real mistake. 2. prod-web-server.mjs's header still described the prefix this PR removed. Corrected, keeping why deriving paths from import.meta.url is still right, and adding the elicitation smoke to the list of callers it had also outgrown. Addresses the suppressed comments on Copilot's review of #2133. Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
25eb2fb3bf
commit
4ab0139de9
1 changed files with 134 additions and 26 deletions
|
|
@ -112,30 +112,55 @@ export function resolveBrowserName(env = process.env) {
|
|||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the Playwright package from the web client's install.
|
||||
*
|
||||
* Separate from `loadBrowser` so it can be substituted in tests — see the
|
||||
* `loadPlaywright` option there for why that seam has to exist.
|
||||
*/
|
||||
export function requirePlaywright(repoRoot) {
|
||||
const requireFromWeb = createRequire(
|
||||
join(repoRoot, "clients", "web", "package.json"),
|
||||
);
|
||||
return requireFromWeb("playwright");
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch a headless browser of `browserName`, resolved from the web client's
|
||||
* install.
|
||||
*
|
||||
* The launch-failure message names the engine that failed and the
|
||||
* `playwright install` invocation that fixes it — naming "chromium" while
|
||||
* WebKit was the thing missing sends the reader off to install a browser they
|
||||
* already have.
|
||||
* Both failure branches produce a message that names the actual remedy, and they
|
||||
* are different remedies — which is the whole reason they are separate branches:
|
||||
*
|
||||
* - **not resolvable** means the Playwright *npm package* is missing, fixed by
|
||||
* `npm install` at the repo root. `playwright install` (which fetches
|
||||
* browser binaries) would not help and is the wrong thing to suggest.
|
||||
* - **launch rejected** means the package is there but that engine's *binary*
|
||||
* is not, fixed by `playwright install --with-deps <that engine>`. Naming
|
||||
* "chromium" while WebKit was the missing one sends the reader off to
|
||||
* install a browser they already have — the reason the engine is
|
||||
* interpolated rather than hard-coded (#2086's acceptance criterion).
|
||||
*
|
||||
* `loadPlaywright` is injectable purely so those branches can be unit-tested.
|
||||
* They are unreachable from the smokes by construction: `install-smoke-browser`
|
||||
* runs first and fetches the binary, so a passing smoke proves nothing about the
|
||||
* message a failing one would print — and that message IS the deliverable here,
|
||||
* since its whole job is to be read by someone whose setup is broken.
|
||||
*/
|
||||
export async function loadBrowser(repoRoot, browserName = DEFAULT_BROWSER) {
|
||||
export async function loadBrowser(
|
||||
repoRoot,
|
||||
browserName = DEFAULT_BROWSER,
|
||||
{ loadPlaywright = requirePlaywright } = {},
|
||||
) {
|
||||
if (!SUPPORTED_BROWSERS.includes(browserName)) {
|
||||
throw new Error(
|
||||
`unsupported browser "${browserName}" — expected one of ${SUPPORTED_BROWSERS.join(", ")}`,
|
||||
);
|
||||
}
|
||||
const requireFromWeb = createRequire(
|
||||
join(repoRoot, "clients", "web", "package.json"),
|
||||
);
|
||||
let playwright;
|
||||
try {
|
||||
playwright = requireFromWeb("playwright");
|
||||
playwright = loadPlaywright(repoRoot);
|
||||
} catch (err) {
|
||||
// Not resolvable means devDependencies are missing — fixed by `npm install`
|
||||
// at the repo root, NOT by `playwright install` (which fetches binaries).
|
||||
throw new Error(
|
||||
`could not resolve the Playwright package from clients/web — run \`npm install\` at the repo root (${err instanceof Error ? err.message : String(err)})`,
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue