diff --git a/www/tools/service-portal-browser.mjs b/www/tools/service-portal-browser.mjs
index 599573e..34b27d4 100644
--- a/www/tools/service-portal-browser.mjs
+++ b/www/tools/service-portal-browser.mjs
@@ -71,8 +71,9 @@ try {
const staffCode = randomBytes(24).toString('hex');
const managementCode = randomBytes(24).toString('hex');
const styledFixture = ' Operations Monthly Lineup Report - PMSynthetic Directory
Operational reports
Role Contact Fixture role Fixture email Management Templates
Other Staff Resources
Staff fixture only
Synthetic resourceStaff fixture only
Synthetic resourceManagement fixture only
' + styledFixture, managementCode), ] }; const guard = async (context, inject = false) => { @@ -331,9 +332,9 @@ try { assert.equal(await p.locator('[data-portal-content] img, [data-portal-content] script').count(), 0); assert.equal(await p.evaluate(() => document.activeElement?.hasAttribute('data-portal-content')), true); assert.equal(await input.inputValue(), ''); - const checkPresentation = async () => { + const checkPresentation = async (staff = false) => { const content = p.locator('[data-portal-content]'); - assert.equal(await content.locator('.portal-resource-button').count(), 3); + assert.equal(await content.locator('.portal-resource-button').count(), staff ? 8 : 3); assert.equal(await content.locator('[style], [onclick], .arbitrary-legacy-class, .unrecognized-report-legacy, iframe, form, input').count(), 0); assert.equal(await content.locator('a[href^="javascript:"]').count(), 0); assert.equal(await content.locator('th[scope="col"]').count(), 2); @@ -350,7 +351,16 @@ try { assert.equal(await button.evaluate(e => getComputedStyle(e).outlineStyle), 'solid'); assert.equal(await button.evaluate(e => getComputedStyle(e).outlineWidth), '3px'); }; - await checkPresentation(); + await checkPresentation(true); + const staffContent = p.locator('[data-portal-content]'); + const grid = staffContent.locator('ul.portal-template-grid'); + assert.equal(await grid.count(), 1); + assert.equal(await grid.locator('li').count(), 3); + assert.equal(await grid.locator('a.portal-resource-button').count(), 3); + const columns = await grid.evaluate((element) => getComputedStyle(element).gridTemplateColumns.split(/\s+/).length); + assert.equal(columns, width >= 768 ? 2 : 1, 'staff templates follow responsive column count'); + assert.equal(await staffContent.getByRole('link', { name: 'General staff resource' }).getAttribute('class'), 'portal-resource-button'); + assert.equal(await staffContent.getByRole('link', { name: 'Staff email' }).getAttribute('class'), 'portal-contact-link'); assert.ok(await p.evaluate(() => document.documentElement.scrollWidth <= innerWidth + 1)); await p.screenshot({ path: path.join(output, 'portal-synthetic-' + width + '.png'), fullPage: true }); evidence.screenshots.push('portal-synthetic-' + width + '.png'); @@ -360,6 +370,7 @@ try { assert.match(await p.locator('[data-portal-content]').textContent(), /Synthetic Management/); assert.doesNotMatch(await p.locator('[data-portal-content]').textContent(), /Staff fixture/); await checkPresentation(); + assert.equal(await p.locator('[data-portal-content] ul.portal-template-grid').count(), 0, 'management view retains original layout'); await p.screenshot({ path: path.join(output, 'portal-management-synthetic-' + width + '.png'), fullPage: true }); evidence.screenshots.push('portal-management-synthetic-' + width + '.png'); evidence.checks++; await ctx.close();