60 lines
3.6 KiB
TypeScript
60 lines
3.6 KiB
TypeScript
// 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: a shard of its own.
|
|
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<typeof Bun.serve> | 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('<p>set</p>', { headers: { 'content-type': 'text/html', 'set-cookie': 'sbsession=example; Path=/; HttpOnly' } });
|
|
if (path === '/session-echo') return new Response(`<p id="c">${/(?:^|; )sbsession=example(?:;|$)/.test(req.headers.get('cookie') ?? '') ? 'kept' : 'lost'}</p>`, { 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);
|
|
}
|
|
});
|