test(determinism): deterministic waits + stableShot screenshots; drop blind sleeps/ifs/retries
Make the Playwright e2e + kicad suites deterministic so screenshot flake stops tracing to timing races. - Blind page.waitForTimeout -> condition waits (expect.poll, web-first assertions, waitUntil) + readiness helpers (waitForWxApp, waitForCanvasApp). Remaining sleeps are documented interaction dwells (annotated). - Defensive "if element exists" branches -> loud asserts; label-fallback chains -> normalized clickMenuItemByText. First-run wizard for/if loops removed by seeding calculator/gerbview/pcbnew HTMLs. - Screenshots: new stableShot(page, name) settles the render in-page (canvas hash over rAF) then writes a raw PNG to test-results/ for the existing offline gate (tools/screenshots vs baseline-screenshots). Replaces toHaveScreenshot, which did inline compare + its own baselines and had decoupled the specs from the real gate. scale:'css' pinned. - retries: 0 in both configs. - Guard: tests/tools/lint-determinism.ts (npm run lint:determinism) bans blind sleeps / toHaveScreenshot / inline retries / swallowed catches in specs; documented exceptions carry a marker. Rules in tests/TESTING.md. Assertions, coverage, and renders unchanged (semantic-equivalence reviewed; captures pixel-identical modulo inherent timer/timestamp/3d-raytrace variance). Both suites green at retries:0 (e2e 340, kicad 92); ~35-61% faster. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BVX1pHMvRPYHdp6ZfEawrk
This commit is contained in:
parent
d9264549bf
commit
4c3a4cacd4
102 changed files with 2867 additions and 3407 deletions
|
|
@ -1,5 +1,5 @@
|
|||
import { test, expect } from './utils/fixtures';
|
||||
import { clickByLabel } from './utils/element-tracker';
|
||||
import { clickByLabel, waitForWxApp, stableShot } from './utils/element-tracker';
|
||||
|
||||
/**
|
||||
* wxPrinting Tests
|
||||
|
|
@ -23,39 +23,29 @@ import { clickByLabel } from './utils/element-tracker';
|
|||
test.describe('wxPrinting Tests', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/standalone/print/print_test.html');
|
||||
// Wait for app to initialize
|
||||
await page.waitForFunction(() => {
|
||||
return document.querySelector('canvas') !== null;
|
||||
}, { timeout: 30000 });
|
||||
await page.waitForTimeout(1000);
|
||||
// Deterministic app-readiness: canvas visible + element registry populated
|
||||
await waitForWxApp(page);
|
||||
});
|
||||
|
||||
test('Print test app loads successfully', async ({ page, testLogger }) => {
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
const hasStartupLog = testLogger.consoleLogs.some(log =>
|
||||
log.includes('PRINT_TEST') && log.includes('started successfully')
|
||||
);
|
||||
|
||||
await page.screenshot({ path: 'test-results/print-01-loaded.png' });
|
||||
await stableShot(page, 'print-01-loaded.png');
|
||||
|
||||
expect(testLogger.errors.filter(e => !e.includes('favicon'))).toHaveLength(0);
|
||||
});
|
||||
|
||||
test('Document preview panel renders', async ({ page }) => {
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// Take screenshot to verify preview panel shows document content
|
||||
await page.screenshot({ path: 'test-results/print-02-preview-panel.png' });
|
||||
await stableShot(page, 'print-02-preview-panel.png');
|
||||
|
||||
// Visual verification - preview panel should show shapes and text
|
||||
});
|
||||
|
||||
test('Browser Print button triggers window.print()', async ({ page, testLogger }) => {
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Mock window.print to track calls
|
||||
let printCalled = false;
|
||||
await page.evaluate(() => {
|
||||
(window as any).originalPrint = window.print;
|
||||
(window as any).printWasCalled = false;
|
||||
|
|
@ -67,35 +57,29 @@ test.describe('wxPrinting Tests', () => {
|
|||
|
||||
// Click Browser Print button using element registry
|
||||
await clickByLabel(page, 'Browser Print');
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await page.screenshot({ path: 'test-results/print-03-browser-print-clicked.png' });
|
||||
// Either the browser-print log appears or window.print was called
|
||||
await expect.poll(async () => {
|
||||
const printWasCalled = await page.evaluate(() => (window as any).printWasCalled);
|
||||
const hasBrowserPrintLog = testLogger.consoleLogs.some(log =>
|
||||
log.includes('window.print') || log.includes('browser print')
|
||||
);
|
||||
return hasBrowserPrintLog || printWasCalled;
|
||||
}, { message: 'Browser Print should trigger window.print() or log it' }).toBe(true);
|
||||
|
||||
// Check if Browser Print triggered window.print
|
||||
const hasBrowserPrintLog = testLogger.consoleLogs.some(log =>
|
||||
log.includes('window.print') || log.includes('browser print')
|
||||
);
|
||||
|
||||
// Also check our mock
|
||||
const printWasCalled = await page.evaluate(() => (window as any).printWasCalled);
|
||||
await stableShot(page, 'print-03-browser-print-clicked.png');
|
||||
|
||||
// Restore original print function
|
||||
await page.evaluate(() => {
|
||||
window.print = (window as any).originalPrint;
|
||||
});
|
||||
|
||||
// Either the log message appears or window.print was called
|
||||
expect(hasBrowserPrintLog || printWasCalled).toBe(true);
|
||||
});
|
||||
|
||||
test('Print Preview button works', async ({ page, testLogger }) => {
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Click Print Preview button using element registry
|
||||
await clickByLabel(page, 'Print Preview');
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await page.screenshot({ path: 'test-results/print-04-preview-clicked.png' });
|
||||
await stableShot(page, 'print-04-preview-clicked.png');
|
||||
|
||||
// Check for print preview events
|
||||
const hasPreviewLog = testLogger.consoleLogs.some(log =>
|
||||
|
|
@ -107,13 +91,10 @@ test.describe('wxPrinting Tests', () => {
|
|||
});
|
||||
|
||||
test('Page Setup button works', async ({ page, testLogger }) => {
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Click Page Setup button using element registry
|
||||
await clickByLabel(page, 'Page Setup');
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await page.screenshot({ path: 'test-results/print-05-page-setup-clicked.png' });
|
||||
await stableShot(page, 'print-05-page-setup-clicked.png');
|
||||
|
||||
// Check for page setup events
|
||||
const hasPageSetupLog = testLogger.consoleLogs.some(log =>
|
||||
|
|
@ -122,13 +103,10 @@ test.describe('wxPrinting Tests', () => {
|
|||
});
|
||||
|
||||
test('Print button works', async ({ page, testLogger }) => {
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Click Print... button using element registry
|
||||
await clickByLabel(page, 'Print...');
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await page.screenshot({ path: 'test-results/print-06-print-clicked.png' });
|
||||
await stableShot(page, 'print-06-print-clicked.png');
|
||||
|
||||
// Check for print dialog events
|
||||
const hasPrintLog = testLogger.consoleLogs.some(log =>
|
||||
|
|
@ -137,26 +115,19 @@ test.describe('wxPrinting Tests', () => {
|
|||
});
|
||||
|
||||
test('Printout callbacks are triggered', async ({ page, testLogger }) => {
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Try to trigger print preview to see callbacks
|
||||
await clickByLabel(page, 'Print Preview');
|
||||
await page.waitForTimeout(1500);
|
||||
|
||||
await page.screenshot({ path: 'test-results/print-07-callbacks.png' });
|
||||
|
||||
// Look for printout callback messages
|
||||
const callbacks = testLogger.consoleLogs.filter(log =>
|
||||
log.includes('PRINTOUT_CALLBACK')
|
||||
);
|
||||
|
||||
// Verify printout callbacks were triggered
|
||||
expect(callbacks.length).toBeGreaterThan(0);
|
||||
await expect.poll(() =>
|
||||
testLogger.consoleLogs.filter(log => log.includes('PRINTOUT_CALLBACK')).length,
|
||||
{ message: 'Print Preview should trigger PRINTOUT_CALLBACK logs' }
|
||||
).toBeGreaterThan(0);
|
||||
|
||||
await stableShot(page, 'print-07-callbacks.png');
|
||||
});
|
||||
|
||||
test('No JavaScript errors during print operations', async ({ page, testLogger }) => {
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Button labels to click
|
||||
const buttonLabels = ['Print Preview', 'Print...', 'Browser Print', 'Page Setup'];
|
||||
|
||||
|
|
@ -169,10 +140,10 @@ test.describe('wxPrinting Tests', () => {
|
|||
// Click each button using element registry
|
||||
for (const label of buttonLabels) {
|
||||
await clickByLabel(page, label);
|
||||
await page.waitForTimeout(500);
|
||||
await page.waitForTimeout(500); // eslint-disable-line -- documented interaction dwell: let each button's dialog/preview settle before clicking the next; no single uniform per-button observable to poll
|
||||
}
|
||||
|
||||
await page.screenshot({ path: 'test-results/print-08-all-buttons.png' });
|
||||
await stableShot(page, 'print-08-all-buttons.png');
|
||||
|
||||
// Restore window.print
|
||||
await page.evaluate(() => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue