514 lines
24 KiB
JavaScript
514 lines
24 KiB
JavaScript
// End-to-end cascade behaviour for the archive browser.
|
||
//
|
||
// Pins the contract for how the three filter layers compose:
|
||
// 1. Folder-type bar (enabledFolderTypes ⊂ {issued, received, mdl, incoming})
|
||
// 2. Selected parties (selectedGroupingFolders, name-keyed)
|
||
// 3. Selected projects (visibleProjects, in multi-project mode)
|
||
//
|
||
// Specifically targets the symptom "I select various third-party folders and
|
||
// the Issued/Received/MDL/Incoming badges, and sometimes files that should be
|
||
// there aren't shown". Each test asserts both the file table and the
|
||
// transmittal folder list, since the user reported both can drop entries.
|
||
|
||
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');
|
||
|
||
// All four folder types enabled — used at the start of each test so default
|
||
// (issued+received only) isn't quietly hiding things.
|
||
async function enableAllFolderTypes(page) {
|
||
await page.evaluate(() => {
|
||
window.app.enabledFolderTypes = new Set(['issued', 'received', 'mdl', 'incoming']);
|
||
});
|
||
}
|
||
|
||
async function selectAllParties(page) {
|
||
await page.evaluate(() => {
|
||
const cb = document.getElementById('selectAllGroupingCheckbox');
|
||
if (cb && !cb.checked) cb.click();
|
||
});
|
||
await page.waitForTimeout(200);
|
||
}
|
||
|
||
// Returns the names of files currently visible in the table (parsed from the
|
||
// row labels). Folder-type changes flow through applyFilters → filteredFiles
|
||
// → updateFileTable, so reading filteredFiles directly is the closest signal.
|
||
async function visibleFileNames(page) {
|
||
return page.evaluate(() => window.app.filteredFiles.map(f => f.name));
|
||
}
|
||
|
||
// Returns the visible-transmittal-folder paths (the ones that pass the
|
||
// grouping/folder-type cascade — what the left panel actually renders).
|
||
async function visibleTransmittalPaths(page) {
|
||
return page.evaluate(() => {
|
||
const items = document.querySelectorAll('#transmittalFoldersList .folder-item');
|
||
return Array.from(items).map(el => el.getAttribute('data-path'));
|
||
});
|
||
}
|
||
|
||
test.describe('Archive cascade: folder-type × parties × outstanding', () => {
|
||
test.beforeEach(async ({ page }) => {
|
||
await page.addInitScript(MOCK_FS_INIT_SCRIPT);
|
||
});
|
||
|
||
test('all four folder-type badges hide their subtrees and only their subtrees', async ({ page }) => {
|
||
await page.goto(`file://${HTML_PATH}`, { waitUntil: 'domcontentloaded' });
|
||
await page.waitForSelector('#addDirectoryBtn', { timeout: 15000 });
|
||
|
||
// Start with all four enabled so the scan picks up MDL/Incoming.
|
||
await enableAllFolderTypes(page);
|
||
|
||
await page.evaluate(() => {
|
||
window.__setMockDirectoryTree('Archive', {
|
||
'BM': {
|
||
'Issued': {
|
||
'2025-01-01_T-ISSUED (IFC) - I': {
|
||
'100-EL-SPC-0001_A (IFC) - SpecIssued.pdf': '%PDF',
|
||
},
|
||
},
|
||
'Received': {
|
||
'2025-01-02_T-RECEIVED (IFC) - R': {
|
||
'100-EL-SPC-0002_A (IFC) - SpecReceived.pdf': '%PDF',
|
||
},
|
||
},
|
||
'MDL': {
|
||
'2025-01-03_T-MDL (IFC) - M': {
|
||
'100-EL-SPC-0003_A (IFC) - SpecMDL.pdf': '%PDF',
|
||
},
|
||
},
|
||
'Incoming': {
|
||
'2025-01-04_T-INCOMING (IFC) - In': {
|
||
'100-EL-SPC-0004_A (IFC) - SpecIncoming.pdf': '%PDF',
|
||
},
|
||
},
|
||
},
|
||
});
|
||
});
|
||
|
||
await page.locator('#addDirectoryBtn').click();
|
||
await page.waitForTimeout(2000);
|
||
|
||
// All four folder types should have surfaced files at scan time.
|
||
const allFour = await visibleFileNames(page);
|
||
for (const expected of ['SpecIssued', 'SpecReceived', 'SpecMDL', 'SpecIncoming']) {
|
||
expect(allFour.some(n => n.includes(expected)), `expected ${expected} present with all four enabled; got ${allFour.join(', ')}`).toBe(true);
|
||
}
|
||
|
||
// Toggle each folder type off and verify its subtree's files disappear,
|
||
// while the other three stay. This is the load-bearing claim.
|
||
const types = [
|
||
{ type: 'issued', expectGone: 'SpecIssued' },
|
||
{ type: 'received', expectGone: 'SpecReceived' },
|
||
{ type: 'mdl', expectGone: 'SpecMDL' },
|
||
{ type: 'incoming', expectGone: 'SpecIncoming' },
|
||
];
|
||
|
||
for (const { type, expectGone } of types) {
|
||
// Disable the type via the canonical app entry point.
|
||
await page.evaluate((t) => window.app.modules.app.toggleFolderType(t), type);
|
||
await page.waitForTimeout(300);
|
||
|
||
const visible = await visibleFileNames(page);
|
||
expect(
|
||
visible.some(n => n.includes(expectGone)),
|
||
`disabling ${type} should hide ${expectGone}; saw: ${visible.join(', ')}`
|
||
).toBe(false);
|
||
|
||
// The other three subtrees keep their files.
|
||
for (const other of types) {
|
||
if (other.type === type) continue;
|
||
expect(
|
||
visible.some(n => n.includes(other.expectGone)),
|
||
`disabling ${type} must not hide ${other.expectGone}; saw: ${visible.join(', ')}`
|
||
).toBe(true);
|
||
}
|
||
|
||
// Re-enable for the next iteration. toggleFolderType triggers a
|
||
// refreshDirectories() because the scan dropped that subtree —
|
||
// we need to wait for the rescan to finish before continuing.
|
||
await page.evaluate((t) => window.app.modules.app.toggleFolderType(t), type);
|
||
await page.waitForTimeout(2000);
|
||
}
|
||
});
|
||
|
||
test('toggling a folder type off then on does not duplicate or lose files', async ({ page }) => {
|
||
await page.goto(`file://${HTML_PATH}`, { waitUntil: 'domcontentloaded' });
|
||
await page.waitForSelector('#addDirectoryBtn', { timeout: 15000 });
|
||
|
||
await enableAllFolderTypes(page);
|
||
|
||
await page.evaluate(() => {
|
||
window.__setMockDirectoryTree('Archive', {
|
||
'BM': {
|
||
'Issued': {
|
||
'2025-01-01_T-ISSUED (IFC) - I': {
|
||
'100-EL-SPC-0001_A (IFC) - I1.pdf': '%PDF',
|
||
'100-EL-SPC-0001_B (IFC) - I2.pdf': '%PDF',
|
||
},
|
||
},
|
||
'Received': {
|
||
'2025-01-02_T-RECEIVED (IFC) - R': {
|
||
'100-EL-SPC-0002_A (IFC) - R1.pdf': '%PDF',
|
||
},
|
||
},
|
||
},
|
||
});
|
||
});
|
||
|
||
await page.locator('#addDirectoryBtn').click();
|
||
await page.waitForTimeout(2000);
|
||
|
||
const baseline = await page.evaluate(() => ({
|
||
files: window.app.files.length,
|
||
txn: window.app.transmittalFolders.length,
|
||
grouping: window.app.groupingFolders.length,
|
||
}));
|
||
expect(baseline.files).toBe(3);
|
||
|
||
// Toggle Issued off → on.
|
||
await page.evaluate(() => window.app.modules.app.toggleFolderType('issued'));
|
||
await page.waitForTimeout(300);
|
||
await page.evaluate(() => window.app.modules.app.toggleFolderType('issued'));
|
||
await page.waitForTimeout(2000);
|
||
|
||
const after = await page.evaluate(() => ({
|
||
files: window.app.files.length,
|
||
txn: window.app.transmittalFolders.length,
|
||
grouping: window.app.groupingFolders.length,
|
||
// Distinct-file-id counts to catch duplication via re-scan.
|
||
distinctIds: new Set(window.app.files.map(f => f.id)).size,
|
||
distinctPaths: new Set(window.app.files.map(f => f.path)).size,
|
||
}));
|
||
|
||
expect(after.files, 'no file duplication after toggle off→on').toBe(baseline.files);
|
||
expect(after.distinctIds, 'each file should still have a unique id').toBe(after.files);
|
||
expect(after.distinctPaths, 'no duplicate file paths').toBe(after.files);
|
||
expect(after.grouping, 'grouping folders not duplicated').toBe(baseline.grouping);
|
||
expect(after.txn, 'transmittal folders not duplicated').toBe(baseline.txn);
|
||
});
|
||
|
||
test('outstanding files: visible under <party>/, <party>/Issued/, <party>/MDL/ matches the folder-type cascade', async ({ page }) => {
|
||
await page.goto(`file://${HTML_PATH}`, { waitUntil: 'domcontentloaded' });
|
||
await page.waitForSelector('#addDirectoryBtn', { timeout: 15000 });
|
||
|
||
await enableAllFolderTypes(page);
|
||
|
||
await page.evaluate(() => {
|
||
window.__setMockDirectoryTree('Archive', {
|
||
'BM': {
|
||
// Loose file directly under party — not under any folder-type marker.
|
||
'100-EL-SPC-LOOSE_A (IFC) - LooseAtParty.pdf': '%PDF',
|
||
'Issued': {
|
||
// Loose file under Issued (no transmittal folder wrapper)
|
||
'100-EL-SPC-LOOSE_A (IFC) - LooseAtIssued.pdf': '%PDF',
|
||
},
|
||
'MDL': {
|
||
'100-EL-SPC-LOOSE_A (IFC) - LooseAtMDL.pdf': '%PDF',
|
||
},
|
||
},
|
||
});
|
||
});
|
||
|
||
await page.locator('#addDirectoryBtn').click();
|
||
await page.waitForTimeout(2000);
|
||
|
||
await selectAllParties(page);
|
||
|
||
// With all folder types enabled, all three loose files should be visible
|
||
// under the Outstanding virtual transmittal.
|
||
const allEnabled = await visibleFileNames(page);
|
||
expect(allEnabled.some(n => n.includes('LooseAtParty'))).toBe(true);
|
||
expect(allEnabled.some(n => n.includes('LooseAtIssued'))).toBe(true);
|
||
expect(allEnabled.some(n => n.includes('LooseAtMDL'))).toBe(true);
|
||
|
||
// Disable MDL — only LooseAtMDL should drop.
|
||
await page.evaluate(() => window.app.modules.app.toggleFolderType('mdl'));
|
||
await page.waitForTimeout(2000);
|
||
|
||
const noMDL = await visibleFileNames(page);
|
||
expect(noMDL.some(n => n.includes('LooseAtParty'))).toBe(true);
|
||
expect(noMDL.some(n => n.includes('LooseAtIssued'))).toBe(true);
|
||
expect(noMDL.some(n => n.includes('LooseAtMDL'))).toBe(false);
|
||
|
||
// Disable Issued too — LooseAtIssued drops, LooseAtParty stays
|
||
// (LooseAtParty's path has no folder-type segment at all).
|
||
await page.evaluate(() => window.app.modules.app.toggleFolderType('issued'));
|
||
await page.waitForTimeout(2000);
|
||
|
||
const noIssuedMDL = await visibleFileNames(page);
|
||
expect(noIssuedMDL.some(n => n.includes('LooseAtParty'))).toBe(true);
|
||
expect(noIssuedMDL.some(n => n.includes('LooseAtIssued'))).toBe(false);
|
||
expect(noIssuedMDL.some(n => n.includes('LooseAtMDL'))).toBe(false);
|
||
});
|
||
|
||
test('same-name party across two projects + folder-type cascade hides both projects symmetrically', async ({ page }) => {
|
||
// BM in ProjectA AND ProjectB, each with Issued and Received subtrees.
|
||
// Disabling Received must hide BOTH projects' Received files;
|
||
// selecting BM (one row in the panel) must surface both projects' Issued.
|
||
await page.goto(`file://${HTML_PATH}`, { waitUntil: 'domcontentloaded' });
|
||
await page.waitForSelector('#addDirectoryBtn', { timeout: 15000 });
|
||
|
||
await enableAllFolderTypes(page);
|
||
|
||
await page.evaluate(() => {
|
||
window.__setMockDirectoryTree('combined-root', {
|
||
'ProjectA': {
|
||
'Archive': {
|
||
'BM': {
|
||
'Issued': {
|
||
'2025-01-01_T-A-I (IFC) - X': {
|
||
'100-EL-SPC-0001_A (IFC) - A_Issued.pdf': '%PDF',
|
||
},
|
||
},
|
||
'Received': {
|
||
'2025-01-02_T-A-R (IFC) - X': {
|
||
'100-EL-SPC-0002_A (IFC) - A_Received.pdf': '%PDF',
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
'ProjectB': {
|
||
'Archive': {
|
||
'BM': {
|
||
'Issued': {
|
||
'2025-02-01_T-B-I (IFC) - X': {
|
||
'200-EL-SPC-0001_A (IFC) - B_Issued.pdf': '%PDF',
|
||
},
|
||
},
|
||
'Received': {
|
||
'2025-02-02_T-B-R (IFC) - X': {
|
||
'200-EL-SPC-0002_A (IFC) - B_Received.pdf': '%PDF',
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
});
|
||
window.app.projectFilter = new Set(['ProjectA', 'ProjectB']);
|
||
window.app.visibleProjects = new Set(['ProjectA', 'ProjectB']);
|
||
window.app.isMultiProject = true;
|
||
});
|
||
|
||
await page.locator('#addDirectoryBtn').click();
|
||
await page.waitForTimeout(2000);
|
||
|
||
// BM should appear once in the parties panel.
|
||
const partyRows = await page.locator('#groupingFoldersList .folder-item-name').allTextContents();
|
||
const bmCount = partyRows.filter(n => n.trim() === 'BM').length;
|
||
expect(bmCount, 'BM merged to one party row across projects').toBe(1);
|
||
|
||
// All four files visible with all four folder types enabled.
|
||
const all = await visibleFileNames(page);
|
||
expect(all.some(n => n.includes('A_Issued'))).toBe(true);
|
||
expect(all.some(n => n.includes('B_Issued'))).toBe(true);
|
||
expect(all.some(n => n.includes('A_Received'))).toBe(true);
|
||
expect(all.some(n => n.includes('B_Received'))).toBe(true);
|
||
|
||
// Disable Received — BOTH projects' Received files hide.
|
||
await page.evaluate(() => window.app.modules.app.toggleFolderType('received'));
|
||
await page.waitForTimeout(2000);
|
||
|
||
const noReceived = await visibleFileNames(page);
|
||
expect(noReceived.some(n => n.includes('A_Issued')), 'ProjectA Issued stays').toBe(true);
|
||
expect(noReceived.some(n => n.includes('B_Issued')), 'ProjectB Issued stays').toBe(true);
|
||
expect(noReceived.some(n => n.includes('A_Received')), 'ProjectA Received hidden').toBe(false);
|
||
expect(noReceived.some(n => n.includes('B_Received')), 'ProjectB Received hidden').toBe(false);
|
||
|
||
// Transmittal folder list also drops both projects' Received transmittals.
|
||
const txnPaths = await visibleTransmittalPaths(page);
|
||
expect(txnPaths.every(p => !p.includes('/Received/')), 'no Received transmittals: ' + txnPaths.join(', ')).toBe(true);
|
||
});
|
||
|
||
test('toggling a party off then on with selectAllTransmittals re-syncs the transmittal selection', async ({ page }) => {
|
||
// Default selectAllTransmittals=true. After deselecting BM, BM's
|
||
// transmittal folders are gone from the list. Reselecting BM should
|
||
// make them visible AND auto-selected (because select-all is still on).
|
||
await page.goto(`file://${HTML_PATH}`, { waitUntil: 'domcontentloaded' });
|
||
await page.waitForSelector('#addDirectoryBtn', { timeout: 15000 });
|
||
|
||
await enableAllFolderTypes(page);
|
||
|
||
await page.evaluate(() => {
|
||
window.__setMockDirectoryTree('Archive', {
|
||
'BM': {
|
||
'Issued': {
|
||
'2025-01-01_T-BM (IFC) - X': {
|
||
'100-EL-SPC-0001_A (IFC) - BM1.pdf': '%PDF',
|
||
},
|
||
},
|
||
},
|
||
'OTHER': {
|
||
'Issued': {
|
||
'2025-01-02_T-OTHER (IFC) - X': {
|
||
'200-EL-SPC-0002_A (IFC) - OTHER1.pdf': '%PDF',
|
||
},
|
||
},
|
||
},
|
||
});
|
||
});
|
||
|
||
await page.locator('#addDirectoryBtn').click();
|
||
await page.waitForTimeout(2000);
|
||
|
||
// Both parties auto-selected, both transmittals auto-selected.
|
||
const initial = await page.evaluate(() => ({
|
||
selectAllTxn: window.app.selectAllTransmittals,
|
||
selectedGrouping: Array.from(window.app.selectedGroupingFolders).sort(),
|
||
selectedTxn: Array.from(window.app.selectedTransmittalFolders).sort(),
|
||
}));
|
||
expect(initial.selectAllTxn).toBe(true);
|
||
expect(initial.selectedGrouping).toEqual(['BM', 'OTHER']);
|
||
expect(initial.selectedTxn.some(p => p.includes('T-BM'))).toBe(true);
|
||
expect(initial.selectedTxn.some(p => p.includes('T-OTHER'))).toBe(true);
|
||
|
||
// Deselect BM via the canonical event handler (mimics user click)
|
||
await page.evaluate(() => {
|
||
window.app.selectAllGroupingFolders = false;
|
||
window.app.selectedGroupingFolders.delete('BM');
|
||
window.app.modules.app.renderGroupingFolders();
|
||
window.app.modules.app.renderTransmittalFolders();
|
||
window.app.modules.filtering.applyFilters();
|
||
});
|
||
await page.waitForTimeout(200);
|
||
|
||
// BM's transmittal is no longer visible AND no longer in the selection set.
|
||
const afterDeselect = await page.evaluate(() => ({
|
||
selectedTxn: Array.from(window.app.selectedTransmittalFolders).sort(),
|
||
visiblePaths: Array.from(document.querySelectorAll('#transmittalFoldersList .folder-item'))
|
||
.map(el => el.getAttribute('data-path')),
|
||
}));
|
||
expect(afterDeselect.selectedTxn.some(p => p.includes('T-BM'))).toBe(false);
|
||
expect(afterDeselect.visiblePaths.some(p => p && p.includes('T-BM'))).toBe(false);
|
||
|
||
// Re-add BM. Because selectAllTransmittals stays true, BM's
|
||
// transmittal should be auto-selected on the re-render.
|
||
await page.evaluate(() => {
|
||
window.app.selectedGroupingFolders.add('BM');
|
||
window.app.modules.app.renderGroupingFolders();
|
||
window.app.modules.app.renderTransmittalFolders();
|
||
window.app.modules.filtering.applyFilters();
|
||
});
|
||
await page.waitForTimeout(200);
|
||
|
||
const afterReselect = await page.evaluate(() => ({
|
||
selectAllTxn: window.app.selectAllTransmittals,
|
||
selectedTxn: Array.from(window.app.selectedTransmittalFolders).sort(),
|
||
visibleFiles: window.app.filteredFiles.map(f => f.name),
|
||
}));
|
||
expect(afterReselect.selectAllTxn).toBe(true);
|
||
expect(
|
||
afterReselect.selectedTxn.some(p => p.includes('T-BM')),
|
||
'BM transmittal should be re-selected via selectAll cascade'
|
||
).toBe(true);
|
||
expect(afterReselect.visibleFiles.some(n => n.includes('BM1'))).toBe(true);
|
||
});
|
||
});
|
||
|
||
test.describe('Archive cascade: nested-party path-segment contract', () => {
|
||
test.beforeEach(async ({ page }) => {
|
||
await page.addInitScript(MOCK_FS_INIT_SCRIPT);
|
||
});
|
||
|
||
// Pin the contract for nested-party paths. With folder-type segment NOT
|
||
// immediately after the party, the current rule (transmittalIsUnderVisibleParty
|
||
// checks only the segment right after the first matched party) means the
|
||
// folder-type cascade can leak. Either the test should fail and we fix
|
||
// the cascade to walk all party matches; or the contract is "the folder
|
||
// type only applies one level under the party". Recording the call here
|
||
// forces us to face the question explicitly when a future change touches
|
||
// the helper.
|
||
test('nested party + deep folder-type marker: the deep folder-type filter applies to the file', async ({ page }) => {
|
||
await page.goto(`file://${HTML_PATH}`, { waitUntil: 'domcontentloaded' });
|
||
await page.waitForSelector('#addDirectoryBtn', { timeout: 15000 });
|
||
|
||
await enableAllFolderTypes(page);
|
||
|
||
await page.evaluate(() => {
|
||
window.__setMockDirectoryTree('Archive', {
|
||
'BM': {
|
||
'sub': {
|
||
'Issued': {
|
||
'2025-01-01_T-NESTED (IFC) - X': {
|
||
'100-EL-SPC-NESTED_A (IFC) - SpecDeepIssued.pdf': '%PDF',
|
||
},
|
||
},
|
||
},
|
||
},
|
||
});
|
||
});
|
||
|
||
await page.locator('#addDirectoryBtn').click();
|
||
await page.waitForTimeout(2000);
|
||
|
||
await selectAllParties(page);
|
||
|
||
// With Issued enabled, the file is visible.
|
||
const visibleAll = await visibleFileNames(page);
|
||
expect(visibleAll.some(n => n.includes('SpecDeepIssued'))).toBe(true);
|
||
|
||
// Turn Issued OFF — the file lives under .../Issued/... so its scan-time
|
||
// listing should be skipped. After the toggle-driven rescan, the file
|
||
// must NOT be visible regardless of how transmittalIsUnderVisibleParty
|
||
// walks segments.
|
||
await page.evaluate(() => window.app.modules.app.toggleFolderType('issued'));
|
||
await page.waitForTimeout(2000);
|
||
|
||
const visibleNoIssued = await visibleFileNames(page);
|
||
expect(
|
||
visibleNoIssued.some(n => n.includes('SpecDeepIssued')),
|
||
'deep Issued subtree must hide when Issued is toggled off'
|
||
).toBe(false);
|
||
});
|
||
});
|
||
|
||
test.describe('Archive cascade: URL state round-trip', () => {
|
||
test.beforeEach(async ({ page }) => {
|
||
await page.addInitScript(MOCK_FS_INIT_SCRIPT);
|
||
});
|
||
|
||
test('non-default folder-type set round-trips through serialize → restore', async ({ page }) => {
|
||
await page.goto(`file://${HTML_PATH}`, { waitUntil: 'domcontentloaded' });
|
||
await page.waitForSelector('#addDirectoryBtn', { timeout: 15000 });
|
||
|
||
const qs = await page.evaluate(() => {
|
||
window.app.enabledFolderTypes = new Set(['issued', 'mdl']); // received off, incoming off, mdl on
|
||
return window.app.modules.urlState.serialize();
|
||
});
|
||
// serialize() returns "?types=..." (leading "?" included) or "" when no
|
||
// diffs from defaults exist. Strip the leading "?" before re-emitting.
|
||
const cleanQs = qs.startsWith('?') ? qs.slice(1) : qs;
|
||
expect(cleanQs).toContain('types=');
|
||
|
||
const round = await page.evaluate((querystring) => {
|
||
// Reset to defaults so restore has work to do.
|
||
window.app.enabledFolderTypes = new Set(['issued', 'received']);
|
||
history.replaceState(null, '', '?' + querystring);
|
||
window.app.modules.urlState.restore();
|
||
return Array.from(window.app.enabledFolderTypes).sort();
|
||
}, cleanQs);
|
||
|
||
expect(round).toEqual(['issued', 'mdl']);
|
||
});
|
||
|
||
// Selected parties are deliberately NOT in URL state today — the natural
|
||
// flow is: pick a directory locally, then narrow with party checkboxes.
|
||
// Pin this in a test so accidentally adding party serialization later
|
||
// doesn't break sharing semantics; remove the test (and the assertion)
|
||
// when/if sharing-with-parties becomes a feature.
|
||
test('selected parties are NOT serialized to URL state (current contract)', async ({ page }) => {
|
||
await page.goto(`file://${HTML_PATH}`, { waitUntil: 'domcontentloaded' });
|
||
await page.waitForSelector('#addDirectoryBtn', { timeout: 15000 });
|
||
|
||
const qs = await page.evaluate(() => {
|
||
window.app.selectAllGroupingFolders = false;
|
||
window.app.selectedGroupingFolders = new Set(['BM', 'OTHER']);
|
||
return window.app.modules.urlState.serialize();
|
||
});
|
||
expect(qs).not.toContain('parties=');
|
||
expect(qs).not.toContain('groups=');
|
||
expect(qs).not.toContain('selected=');
|
||
});
|
||
});
|