Files
gstack/test/qa-bugs-fixture.test.ts
T
Garry Tan dcaea52800 v1.91.7.0 feat: add functional QA and pre-publication docs checks (#2983)
* feat: add surface-aware exploratory QA and ship documentation gates

* test: preserve delegated QA setup authority after main integration

* fix(qa): clarify exploration order and preserve report artifacts

* test(qa): follow the shared setup reference directly

* refactor(ship): make verification and recovery routes explicit

* test(ship): align evidence and review guards with explicit routes

* fix(workflows): clarify ship recovery and functional QA evidence

* fix(workflows): clarify approval recovery and full QA coverage

* refactor(workflows): order review transactions and clarify ship state

* fix(ship): clarify final verification and fail closed at publication

* fix(evals): attribute native atomic documentation writes

* fix(ship): clarify recovery and documentation lifecycle guidance

* fix(test): preserve observed native placeholder styling in CI

* fix(codex): report watchdog timeouts without a process-exit race

* Checkpoint functional QA implementation and workflow validation repairs

* Fix documentation and shared-review fixture contracts

* docs: clarify judge reuse and evaluation supervision

* test: align review evidence and selected case contracts

* test: verify append-only documentation checkpoints and recovery

* fix: qualify QA workflows and CI validation repairs

* fix: launch shared-libs fixture scripts on Windows

* fix: qualify QA deadlines, fixture isolation, and shard cleanup

* fix: preserve qualified QA and cancellation repairs

* fix: enforce functional fixture authority and share strict event decoding

* fix: retain free-test evidence and explain recovery

* fix: reject malformed native evidence after decoder consolidation

* test: use reliable capture for telemetry privacy filters

* test: refresh measured quick coverage and document validation costs

* Fix native fixture receipts and preserve VM validation evidence

* Align negative judge controls with upstream clarity policy

* Fix report-only QA preparation and public evidence handling

* Clarify QA-only preparation and current-report preservation

* Stream Ship quality judgments with an explicit 64k response contract

* Validate compact judge reasoning locally with supported wire schema

* Align functional QA fixture instructions with evidence acceptance

* Bind native browser diagnostics to execution evidence and align review verdicts

* Preserve native diagnostic line boundaries

* Serialize functional QA evidence from native captures

* Keep large QA evidence fixture payload out of Windows argv
2026-09-29 06:07:35 -07:00

60 lines
3.7 KiB
TypeScript

import { expect, test } from 'bun:test';
import * as fs from 'node:fs';
import * as os from 'node:os';
import * as path from 'node:path';
import { E2E_TOUCHFILES, selectTests } from './helpers/touchfiles';
const ROOT = path.resolve(import.meta.dir, '..');
const source = fs.readFileSync(path.join(ROOT, 'test/skill-e2e-qa-bugs.test.ts'), 'utf8');
const setup = source.match(/^function browserSetupSection\(\): string \{[\s\S]*?^\}/m)?.[0];
const runner = source.match(/^ async function runPlantedBugEval\([\s\S]*?^ \}/m)?.[0];
const registrations = [...source.matchAll(/^ testConcurrentIfSelected\('qa-b[678]-[^']+', async \(\) => \{[\s\S]*?^ \}, CAPTURE_LONG_MS\);/gm)].map(match => match[0]);
if (!setup || !runner || registrations.length !== 3) throw new Error('Missing actual planted-browser fixture functions or registrations');
const script = new Bun.Transpiler({ loader: 'ts' }).transformSync([setup, runner, ...registrations].join('\n'));
const asset = fs.readFileSync(path.join(ROOT, 'qa/sections/browser-setup.md'), 'utf8');
const ids = ['qa-b6-static', 'qa-b7-spa', 'qa-b8-checkout'];
test('planted-browser fixture regression selects its three actual consumers', () => {
expect(selectTests(['test/qa-bugs-fixture.test.ts'], E2E_TOUCHFILES).selected?.sort()).toEqual(ids);
});
for (const id of ids) test.each(['complete section', 'additional trailing policy', 'missing section'])(`${id} retains the carved browser setup: %s`, async scenario => {
const owned = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'qa-bugs-fixture-')));
const section = scenario === 'additional trailing policy' ? asset + '\n## Additional policy\nPreserve this final policy.\n' : asset;
const calls: unknown[] = [];
const callbacks = new Map<string, () => Promise<void>>();
const stopped = new Error('Stopped at the offline actor boundary');
try {
fs.mkdirSync(path.join(owned, 'qa/sections'), { recursive: true });
fs.writeFileSync(path.join(owned, 'qa/SKILL.md'), '# QA entrypoint\nRead the carved sections.\n');
if (scenario !== 'missing section') fs.writeFileSync(path.join(owned, 'qa/sections/browser-setup.md'), section);
new Function('fs', 'path', 'os', 'ROOT', 'setupBrowseShims', 'testServer', 'browseBin',
'runSkillTest', 'runId', 'CAPTURE_MS', 'CAPTURE_LONG_MS', 'testConcurrentIfSelected', script)(
fs, path, { ...os, tmpdir: () => owned }, owned, () => {}, { url: 'http://fixture.invalid' }, '/unused/browse',
async (options: { workingDirectory: string; prompt: string; testName: string }) => {
calls.push(options);
const actual = fs.readFileSync(path.join(options.workingDirectory, 'BROWSER-SETUP.md'), 'utf8');
expect(actual).toBe(section);
expect(actual.indexOf('## Browser access decision')).toBeLessThan(actual.indexOf('## BROWSER SETUP'));
expect(actual).toContain('Unknown caller: use report-only authority');
expect(actual).toContain('## Browser fallback');
expect(actual).toContain('Invocation does not authorize external mutations');
expect(options.testName).toBe(id);
expect(options.prompt).toContain('read BROWSER-SETUP.md in this directory and follow it exactly');
throw stopped;
}, 'offline-fixture', 300000, 600000,
(name: string, callback: () => Promise<void>) => callbacks.set(name, callback),
);
expect([...callbacks.keys()]).toEqual(ids);
if (scenario === 'missing section') {
await expect(callbacks.get(id)!()).rejects.toThrow('ENOENT');
expect(calls).toHaveLength(0);
} else {
await expect(callbacks.get(id)!()).rejects.toBe(stopped);
expect(calls).toHaveLength(1);
}
} finally {
fs.rmSync(owned, { recursive: true, force: true });
}
});