ZDDC/tests/archive.spec.js
ZDDC ea385b5366 Initial commit
ZDDC — Zero Day Document Control. A file-naming convention plus five
single-file HTML tools (archive, transmittal, classifier, mdedit,
landing) and an optional Go HTTP server (zddc-server) with ACL and a
virtual archive index. Self-contained, offline-capable, dependency-free.

See README.md for an overview, AGENTS.md and ARCHITECTURE.md for the
build/release/architecture detail, bootstrap/README.md for the
two-level deployment install pattern, and zddc/README.md for the
HTTP server.
2026-04-27 11:05:47 -05:00

113 lines
5.5 KiB
JavaScript

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('archive/dist/archive.html');
test.describe('Archive Browser', () => {
test.beforeEach(async ({ page }) => {
await page.addInitScript(MOCK_FS_INIT_SCRIPT);
});
test('loads without errors', async ({ page }) => {
await page.goto(`file://${HTML_PATH}`, { waitUntil: 'domcontentloaded' });
await page.waitForSelector('#appContainer', { timeout: 15000 });
// Page title contains "Archive"
await expect(page).toHaveTitle(/Archive/i);
// No-directory message is shown before any directory is opened
await expect(page.locator('#noDirectoryMessage')).toBeVisible();
// The open-directory button is present
await expect(page.locator('#addDirectoryBtn')).toBeVisible();
});
test('scans a mock directory tree and displays files', async ({ page }) => {
await page.goto(`file://${HTML_PATH}`, { waitUntil: 'domcontentloaded' });
await page.waitForSelector('#addDirectoryBtn', { timeout: 15000 });
// Log to see if the scan is working
page.on('console', msg => {
console.log('Browser console:', msg.text());
});
page.on('pageerror', err => {
console.log('Page error:', err.message);
});
// The archive expects a two-level structure: root → transmittal-folder → files.
// Flat files at the root are not counted — they must be inside subdirectories.
await page.evaluate(() => {
window.__setMockDirectoryTree('test-project', {
'2025-01-15_123456-EM-TRN-0001 (IFC) - First Transmittal': {
'123456-EL-SPC-2623_A (IFC) - Specification.pdf': '%PDF',
'123456-EL-DRW-0001_B (IFR) - Drawing.dwg': 'DWG',
},
'2025-02-10_123456-EM-TRN-0002 (IFC) - Second Transmittal': {
'789012-ME-CAL-0001_A (IFA) - Calculation.pdf': '%PDF',
},
});
console.log('Mock directory set up');
});
await page.locator('#addDirectoryBtn').click();
// Wait for scanning to complete
await page.waitForTimeout(2000);
// Log state for debugging
await page.evaluate(() => {
console.log('After scanning:');
console.log(' window.app exists:', typeof window.app !== 'undefined');
if (typeof window.app !== 'undefined') {
console.log(' window.app type:', typeof window.app);
console.log(' window.app constructor:', window.app.constructor.name);
console.log(' window.app.directories:', Array.isArray(window.app.directories) ? window.app.directories.length : window.app.directories);
console.log(' window.app.files:', Array.isArray(window.app.files) ? window.app.files.length : window.app.files);
console.log(' window.app.filteredFiles:', Array.isArray(window.app.filteredFiles) ? window.app.filteredFiles.length : window.app.filteredFiles);
console.log(' window.app modules:', Object.keys(window.app || {}).filter(k => k.startsWith('modules')));
} else {
console.log(' window.app is undefined!');
}
});
// Select all grouping folders so files are included in the file list
await page.evaluate(() => {
const cb = document.getElementById('selectAllGroupingCheckbox');
if (cb && !cb.checked) cb.click();
});
await page.waitForTimeout(500);
// The files table should have at least one data row
const rowCount = await page.locator('#filesTableBody tr').count();
expect(rowCount).toBeGreaterThanOrEqual(1);
// Status bar should show files were found (any non-empty text is fine)
const fileCountText = await page.locator('#fileCount').textContent();
expect(fileCountText).toBeTruthy();
});
test('parser module uses shared zddc helpers (not its own wrappers)', async ({ page }) => {
await page.goto(`file://${HTML_PATH}`, { waitUntil: 'domcontentloaded' });
await page.waitForSelector('#appContainer', { timeout: 15000 });
const probe = await page.evaluate(() => ({
// archive's parser module should NOT re-export wrappers we removed
hasParseFileNameWrapper: typeof window.app.modules.parser?.parseFileName === 'function',
hasParseRevisionWrapper: typeof window.app.modules.parser?.parseRevision === 'function',
// but should still expose archive-specific helpers
hasIsTransmittalFolder: typeof window.app.modules.parser?.isTransmittalFolder === 'function',
hasGroupFiles: typeof window.app.modules.parser?.groupFilesByTrackingNumber === 'function',
// and isTransmittalFolder should agree with shared zddc.parseFolder
validFolder: window.app.modules.parser.isTransmittalFolder('2025-10-31_123456-EM-SUB-0001 (IFR) - General Arrangement'),
invalidFolder: window.app.modules.parser.isTransmittalFolder('not-a-zddc-folder'),
}));
expect(probe.hasParseFileNameWrapper).toBe(false);
expect(probe.hasParseRevisionWrapper).toBe(false);
expect(probe.hasIsTransmittalFolder).toBe(true);
expect(probe.hasGroupFiles).toBe(true);
expect(probe.validFolder).toBe(true);
expect(probe.invalidFolder).toBe(false);
});
});