import { fileURLToPath } from 'node:url'; import { es } from '@impuestos/i18n'; import { expect, test, type Page } from '@playwright/test'; /** * SPEC.md section 13: a scan taken with no network is queued and syncs when there is one. * * Serial and desktop only, like the other ingestion paths: it adds a document to the shared * demo account. */ test.describe.configure({ mode: 'serial' }); const fixture = (name: string) => fileURLToPath(new URL(`../fixtures/${name}.png`, import.meta.url)); async function signIn(page: Page): Promise { await page.goto('/es/login'); await page.getByLabel(es['auth.register.email']).fill('maria@demo.local'); await page.getByLabel(es['auth.login.password']).fill('demo-maria-1'); await page.getByRole('button', { name: es['auth.login.submit'] }).click(); await expect(page).not.toHaveURL(/\/login$/, { timeout: 20_000 }); } test.describe('offline capture', () => { test.beforeEach(() => { test.skip(test.info().project.name !== 'desktop', 'adds a document to shared seed data'); }); test('queues a scan with no network and sends it when there is one', async ({ page, context }) => { await signIn(page); await page.goto('/es/escanear'); // The scanner has to be up before the network goes: it is a client screen either way, // but waiting on it avoids racing the first paint. await expect(page.locator('input[type="file"]')).toBeAttached(); await context.setOffline(true); await page.locator('input[type="file"]').setInputFiles(fixture('factura-qr-farmacia')); // Nothing is lost and the reader is told so, on the screen and in the shell. await expect(page.getByText(es['offline.queued']).first()).toBeVisible({ timeout: 20_000 }); await context.setOffline(false); // The chip clears itself once the capture has gone. await expect(page.getByText(es['offline.queued'])).toHaveCount(0, { timeout: 30_000 }); // And the document is really there, whether this run was the first to scan it or not. await page.goto('/es/comprobantes'); await expect(page.getByText('FARMACIA', { exact: false }).first()).toBeVisible({ timeout: 20_000, }); }); });