1271d48e9f
Créer un portefeuille, en obtenir le .ngw, traverser le broker : ce n'est pas du ressort du polyfill. C'est un besoin commun au polyfill et à toute application NextGraph — et surtout, ça SURVIT à la migration, alors que le polyfill est fait pour disparaître. L'y laisser, c'était le faire mourir avec lui ou rendre le polyfill indéracinable. Le paquet n'importe rien du polyfill — vérifié mécaniquement — et déclare Playwright et @ng-org/web en pairs, le consommateur devant maîtriser les versions. Sa surface : attentes bornées, mesure, navigateur, profils, portefeuille, traversée du broker, rapport d'exécution, et reconnaissance des modes de panne connus. La preuve qu'il est utilisable de l'extérieur : le polyfill le CONSOMME, sans garder de copie. Restent chez lui les parcours, la barrière et les identités virtuelles, qui lui sont propres. Le verrou entre exécutions disparaît, remplacé par un profil par exécution. Il ne traitait qu'un symptôme — un répertoire partagé que la création de portefeuille effaçait. Avec un profil par exécution il n'y a plus rien à sérialiser, les exécutions concurrentes deviennent indépendantes, et la collision entre deux dépôts s'évanouit au lieu d'être exportée. Six exécutions : aucun répertoire ni Chromium orphelin. Et la connaissance descriptive est séparée du pilotage : URL, sélecteurs et inventaire ordonné des écrans sont des données, passées DANS la page pour la reconnaissance — donc un échec nomme le même écran que celui sur lequel on dispatchait. Un échec de navigateur est désormais nommé comme tel — « the actors browser STOPPED ANSWERING » — au lieu de sortir sous le nom de l'opération innocente qui se trouvait en vol.
74 lines
3.0 KiB
TypeScript
74 lines
3.0 KiB
TypeScript
/**
|
|
* What is POLYFILL-SPECIFIC in these suites' setup: the harness page and the wallet this
|
|
* repository's runs use.
|
|
*
|
|
* Everything generic — the wallet lifecycle, the broker crossing, profiles, bounds, the report
|
|
* shape, the recognition of the known failure modes — lives in `ng-e2e-helpers`, which knows
|
|
* nothing about this package and must keep knowing nothing about it: the polyfill is designed
|
|
* to DISAPPEAR at migration, and that machinery talks about NextGraph itself, so it outlives
|
|
* it. What is left here is the two things that genuinely belong to the polyfill: the page that
|
|
* exposes its surface to a browser (`polyfill-entry.ts`), and the name of the wallet its runs
|
|
* mint.
|
|
*/
|
|
|
|
import { execSync } from "node:child_process";
|
|
import * as fs from "node:fs";
|
|
import * as path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import {
|
|
mintWalletProfile,
|
|
serveOnEphemeralPort,
|
|
type RunProfile,
|
|
type WalletCredentials,
|
|
} from "ng-e2e-helpers";
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
|
/**
|
|
* The wallet every suite in this package mints for its own run.
|
|
*
|
|
* A NAME, not an identity that survives: each run gets a profile of its own and mints this
|
|
* wallet into it, so two runs sharing the name share nothing else. See `ng-e2e-helpers`'
|
|
* `profiles.ts` for why one physical user per run is the rule, and why it is now a property of
|
|
* the directory rather than something a lock had to enforce.
|
|
*/
|
|
export const WALLET: WalletCredentials = {
|
|
name: "ng-eventually-e2e",
|
|
password: "ng-eventually-e2e",
|
|
};
|
|
|
|
/** This run's physical user, in a profile of its own. */
|
|
export function mintBatchWallet(suite: string): Promise<RunProfile> {
|
|
return mintWalletProfile(suite, WALLET);
|
|
}
|
|
|
|
/** `bun build` is a local bundle; a minute is already ten times what it takes. */
|
|
const BUILD_MS = 60_000;
|
|
|
|
const ENTRY = path.resolve(__dirname, "polyfill-entry.ts");
|
|
const BUNDLE_OUT = path.resolve(__dirname, ".dist", "polyfill-entry.js");
|
|
|
|
export function buildBundle(): void {
|
|
fs.mkdirSync(path.dirname(BUNDLE_OUT), { recursive: true });
|
|
execSync(`bun build ${ENTRY} --outfile ${BUNDLE_OUT} --bundle --format=esm`, {
|
|
stdio: "pipe",
|
|
cwd: path.resolve(__dirname, ".."),
|
|
timeout: BUILD_MS,
|
|
});
|
|
}
|
|
|
|
/** Serve the harness page — the polyfill's surface, reachable from Playwright as `window.__sdk`. */
|
|
export function serveHarness(): Promise<{ url: string; close: () => void }> {
|
|
const bundle = fs.readFileSync(BUNDLE_OUT, "utf-8");
|
|
const html = `<!DOCTYPE html><html><head><meta charset="utf-8"><title>ng-eventually polyfill e2e</title></head><body><div id="root"></div><script type="module" src="/polyfill-entry.js"></script></body></html>`;
|
|
return serveOnEphemeralPort((req, res) => {
|
|
if (req.url === "/polyfill-entry.js") {
|
|
res.writeHead(200, { "Content-Type": "application/javascript; charset=utf-8" });
|
|
res.end(bundle);
|
|
} else {
|
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
res.end(html);
|
|
}
|
|
});
|
|
}
|