feat(e2e-helpers): fabriquer un portefeuille, pour un test comme pour un déploiement
Trois appelants veulent la même chose — un portefeuille neuf, ses octets et son mot de passe : la suite du polyfill à son démarrage, la suite d'une application au sien, et un humain une fois pour provisionner un déploiement. Rien ne produisait ce fichier ; il fallait aller le chercher à la main sur nextgraph.eu. Mêmes entrées, mêmes sorties, mais des appelants de nature différente : une suite ne va pas lancer un sous-processus et analyser sa sortie, et un humain ne va pas écrire un fichier jetable pour appeler une fonction. Donc une fonction, et un script mince par-dessus. mintWalletBytes(password, name) rend les OCTETS, pas un chemin. C'est une correction de ce qui existait : exportWalletFile imposait le disque à tout le monde, et la suite applicative écrivait un fichier temporaire pour le relire aussitôt en mémoire, puis devait le nettoyer. Elle ne le fait plus — serveApp prend les octets. Qui veut un fichier l'écrit ; personne n'y est forcé. Le script exige --password et refuse d'en inventer un, et refuse d'écraser un .ngw existant sans --force, vérifié AVANT de fabriquer quoi que ce soit. Exécuté pour de vrai : 800 octets, et le mot de passe imprimé est celui passé en entrée. C'est le seul des trois cas qu'aucune suite n'exerce, donc le seul qui pouvait être livré cassé sans que rien ne le dise. Ce qui ne change pas : les suites fabriquent un portefeuille par exécution et n'en héritent jamais ; le provisionnement veut l'inverse, durable et conservé. Ils partagent la fabrication et l'export, ils divergent sur la durée de vie. Les identifiants en dur deviennent un paramètre — les suites passent toujours les leurs, le script prend ceux qu'on lui donne, et il n'existe aucun mot de passe par défaut.
This commit is contained in:
@@ -45,7 +45,7 @@ import {
|
||||
declareSuite,
|
||||
emptyProfileContext,
|
||||
enclosingBound,
|
||||
exportWalletFile,
|
||||
exportWalletBytes,
|
||||
firstLine,
|
||||
frameTrouble,
|
||||
importWalletFile,
|
||||
@@ -330,7 +330,7 @@ function buildApp(): void {
|
||||
* download of a file NOBODY served looked like a perfectly good download. The check that
|
||||
* the link resolves could not have failed.
|
||||
*/
|
||||
function serveApp(walletFile: Buffer, walletPassword: string): Promise<{ url: string; close: () => void }> {
|
||||
function serveApp(walletFile: Uint8Array, walletPassword: string): Promise<{ url: string; close: () => void }> {
|
||||
const bundle = fs.readFileSync(BUNDLE_OUT, "utf-8");
|
||||
const page = fs.readFileSync(path.join(APP_DIR, "index.html"), "utf-8");
|
||||
const moduleTag = '<script type="module" src="/app.js"></script>';
|
||||
@@ -690,11 +690,13 @@ async function main(): Promise<void> {
|
||||
const t = Date.now().toString(36);
|
||||
const ALICE = `alice-${t}`;
|
||||
const BOB = `bob-${t}`;
|
||||
// The wallet the barrier hands out, and the newcomer's download of it. Both under a
|
||||
// temp dir, removed at the end: a wallet file is an identity, and one must never be
|
||||
// committed — `*.ngw` is gitignored besides, which is the belt to this brace.
|
||||
// Where the visitors' DOWNLOADS land — the `.ngw` each one pulls off the barrier and hands
|
||||
// to the wallet application, which takes a path and nothing else. Under a temp dir, removed
|
||||
// at the end: a wallet file is an identity, and one must never be committed — `*.ngw` is
|
||||
// gitignored besides, which is the belt to this brace.
|
||||
//
|
||||
// The wallet this suite SERVES is not here: it never becomes a file at all (see below).
|
||||
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "ng-eventually-notebook-"));
|
||||
const sharedWalletFile = path.join(tmpDir, "shared-wallet.ngw");
|
||||
|
||||
let ctx: BrowserContext | null = null;
|
||||
let closeServer: (() => void) | null = null;
|
||||
@@ -710,21 +712,24 @@ async function main(): Promise<void> {
|
||||
// mechanism is a suspicion, not a finding: closing a broker page may end the session
|
||||
// its profile-mates are using. Cheap to avoid, so avoided — the actors inherit
|
||||
// nothing. Sequential contexts over the one profile dir; never two at once.
|
||||
// Bytes straight into the server that hands them out. They used to go through a temp
|
||||
// `.ngw` that was written, read straight back and deleted at the end — a file nobody
|
||||
// wanted, three steps to get back what the export already had in hand.
|
||||
console.log("[e2e/app] exporting the wallet the barrier hands out...");
|
||||
const exportCtx = await launchWatchedContext("wallet-export", wallet.dir);
|
||||
let walletSize = 0;
|
||||
let walletBytes: Uint8Array = new Uint8Array(0);
|
||||
try {
|
||||
walletSize = await exportWalletFile(exportCtx, sharedWalletFile, WALLET.password);
|
||||
walletBytes = await exportWalletBytes(exportCtx, WALLET.password);
|
||||
} finally {
|
||||
await closeContext("wallet-export", exportCtx);
|
||||
}
|
||||
|
||||
ctx = await launchWatchedContext("actors", wallet.dir);
|
||||
actorsBrowser = ctx;
|
||||
const served = await serveApp(fs.readFileSync(sharedWalletFile), WALLET.password);
|
||||
const served = await serveApp(walletBytes, WALLET.password);
|
||||
closeServer = served.close;
|
||||
const url = served.url;
|
||||
console.log(`[e2e/app] application served at ${url} (shared wallet: ${walletSize} bytes)`);
|
||||
console.log(`[e2e/app] application served at ${url} (shared wallet: ${walletBytes.length} bytes)`);
|
||||
|
||||
// The actors sign in inside a JOURNEY, not at the suite's top level. Up here a failed
|
||||
// sign-in threw past every journey into `main`'s own catch, which prints "fatal" and
|
||||
|
||||
Reference in New Issue
Block a user