// storebound console fill, mode (c): a session cookie (no Expires / Max-Age) survives closing and relaunching // storebound's own persistent profile (--restore-last-session plus a graceful close). Launched with the browser kind the // product uses for that profile (cli/shots/browser.ts, kind "visible"): real Google Chrome, else Playwright's full // Chromium, headless here so no window appears. Never the headless shell: it does not restore the last session, so the // cookie is always lost there. Skips (with the reason) only when neither is installed. Slow (two real Chrome launches // and graceful closes per store), so tools/ci-plan.ts lists it as HEAVY (the dedicated browser shard). import { afterAll, beforeAll, describe, expect, test } from 'bun:test'; import { mkdtempSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { type ConsoleBrowser, openConsoleBrowser } from '../cli/console/session'; import { installedBrowsers } from '../cli/shots/browser'; import { capped, CLOSE_TIMEOUT_MS, LAUNCH_TIMEOUT_MS, persistentBrowser } from './helpers/browser'; const real = await persistentBrowser(); if (!real.label) console.warn(`console-persist tests skipped: ${real.skipWhy}`); const TEST_MS = 2 * LAUNCH_TIMEOUT_MS + 30_000; // two launches (each capped) plus the test itself let server: ReturnType | null = null; let base = ''; beforeAll(() => { server = Bun.serve({ hostname: '127.0.0.1', port: 0, fetch: req => { const path = new URL(req.url).pathname; if (path === '/session-set') return new Response('

set

', { headers: { 'content-type': 'text/html', 'set-cookie': 'sbsession=example; Path=/; HttpOnly' } }); if (path === '/session-echo') return new Response(`

${/(?:^|; )sbsession=example(?:;|$)/.test(req.headers.get('cookie') ?? '') ? 'kept' : 'lost'}

`, { headers: { 'content-type': 'text/html' } }); return new Response('not found', { status: 404 }); } }); base = `http://127.0.0.1:${server.port}/`; }); afterAll(() => { server?.stop(true); }); describe.skipIf(!real.label)(`storebound's own profile (${real.label ?? 'no real Chrome'})`, () => { for (const store of ['apple', 'play'] as const) { test.concurrent(`${store}: a session cookie survives closing and relaunching storebound's own profile`, async () => { const dir = mkdtempSync(join(tmpdir(), `storebound-profile-${store}-`)); const root = join(import.meta.dir, '..'); const { chromium } = await import('playwright'); // the resolver's own choice, without a STOREBOUND_CHROME from the environment const installed = installedBrowsers(chromium, { ...process.env, STOREBOUND_CHROME: undefined }); const opts = { store, profileDir: dir, fresh: true, headless: true, say: () => {}, launchTimeoutMs: LAUNCH_TIMEOUT_MS, launchDeps: { installed } }; let b: ConsoleBrowser | null = null; try { b = await openConsoleBrowser(root, opts); await b.page.goto(base + 'session-set'); await b.close(); // graceful: Chrome writes its cookie store await b.closed; b = await openConsoleBrowser(root, opts); expect(b.pages()).toHaveLength(1); // the restored tab was closed again await b.page.goto(base + 'session-echo'); expect(await b.page.textContent('#c')).toBe('kept'); await b.close(); await b.closed; } finally { // a failed assertion must not leave this Chrome running into the next test if (b && !b.isClosed()) await capped(b.context.close(), CLOSE_TIMEOUT_MS); rmSync(dir, { recursive: true, force: true }); } }, TEST_MS); } });