import { test, expect } from '@playwright/test'; import { MOCK_FS_INIT_SCRIPT } from './fixtures/mock-fs-api.js'; import * as path from 'path'; const HTML_PATH = path.resolve('transmittal/dist/transmittal.html'); // Covers the transmittal validation module (transmittal/js/validation.js), // which had no in-browser coverage: // - the live #tracking-number aria-invalid binding (whitespace / underscore) // - validateBeforePublish(): the publish-time gate that rejects a tracking // number or a per-file tracking number / revision containing spaces or // underscores. test.describe('Transmittal – validation', () => { test.beforeEach(async ({ page }) => { await page.addInitScript(MOCK_FS_INIT_SCRIPT); await page.goto(`file://${HTML_PATH}`, { waitUntil: 'networkidle' }); await page.waitForSelector('#tracking-number'); }); test('tracking-number field flags whitespace and underscores live', async ({ page }) => { const input = page.locator('#tracking-number'); await input.fill('123456-EL-TRX-0001'); await expect(input).toHaveAttribute('aria-invalid', 'false'); await input.fill('123456 EL TRX'); // space await expect(input).toHaveAttribute('aria-invalid', 'true'); await expect(input).toHaveClass(/border-red-500/); await input.fill('123456_EL_TRX'); // underscore await expect(input).toHaveAttribute('aria-invalid', 'true'); await input.fill('123456-EL-TRX-0002'); // clean again — clears the flag await expect(input).toHaveAttribute('aria-invalid', 'false'); await expect(input).not.toHaveClass(/border-red-500/); }); test('validateBeforePublish passes for a clean transmittal', async ({ page }) => { const result = await page.evaluate(() => { const app = window.transmittalApp; app.dom.qs('#tracking-number').value = '123456-EL-TRX-0001'; app.data.files = [{ trackingNumber: '123456-EL-SPC-2623', revision: 'A', status: 'IFC', extension: 'pdf', title: 'Spec', name: 'x', path: '', size: 0, fileSize: 0, sha256: '', }]; return app.modules.validation.validateBeforePublish(); }); expect(result.ok).toBe(true); expect(result.message).toBe(''); }); test('validateBeforePublish rejects a tracking number with spaces/underscores and focuses it', async ({ page }) => { const result = await page.evaluate(() => { const app = window.transmittalApp; app.dom.qs('#tracking-number').value = 'BAD NUMBER_01'; app.data.files = []; const r = app.modules.validation.validateBeforePublish(); return { ok: r.ok, message: r.message, focusId: r.focusEl ? r.focusEl.id : null }; }); expect(result.ok).toBe(false); expect(result.message).toContain('spaces or underscores'); expect(result.focusId).toBe('tracking-number'); // gate points the user at the bad field }); test('validateBeforePublish flags per-file bad tracking numbers and revisions by row', async ({ page }) => { const result = await page.evaluate(() => { const app = window.transmittalApp; app.dom.qs('#tracking-number').value = '123456-EL-TRX-0001'; // header is clean app.data.files = [ { trackingNumber: '123456 EL SPC', revision: 'A' }, // row 1: space in tracking { trackingNumber: '123456-EL-DRW', revision: 'B 1' }, // row 2: space in revision ]; return app.modules.validation.validateBeforePublish(); }); expect(result.ok).toBe(false); expect(result.message).toContain('Row 1'); expect(result.message).toContain('Row 2'); expect(result.message).toMatch(/tracking number must not contain spaces or underscores/i); expect(result.message).toMatch(/revision must not contain spaces/i); }); });