109 lines
3.7 KiB
JavaScript
109 lines
3.7 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import process from 'node:process';
|
|
|
|
const playwright = await import(process.env.PLAYWRIGHT_MODULE ?? 'playwright');
|
|
const { chromium } = playwright.default ?? playwright;
|
|
const browser = await chromium.launch({ channel: 'chrome', headless: true });
|
|
const base = 'http://127.0.0.1:4180';
|
|
const context = await browser.newContext({
|
|
viewport: { width: 1440, height: 1000 },
|
|
});
|
|
const page = await context.newPage();
|
|
page.setDefaultTimeout(10000);
|
|
const errors = [];
|
|
page.on('pageerror', (error) => errors.push(error.message));
|
|
const content = () => page.locator('#main-content');
|
|
const focusWithTab = async (link) => {
|
|
await content().focus();
|
|
for (let step = 0; step < 40; step++) {
|
|
await page.keyboard.press('Tab');
|
|
if (
|
|
await link.evaluate((element) => element === document.activeElement)
|
|
) {
|
|
assert.equal(
|
|
await link.evaluate((element) =>
|
|
element.matches(':focus-visible'),
|
|
),
|
|
true,
|
|
);
|
|
return;
|
|
}
|
|
}
|
|
assert.fail('Dashboard action was not reachable by keyboard');
|
|
};
|
|
|
|
try {
|
|
for (const width of [1440, 390, 320]) {
|
|
await page.setViewportSize({ width, height: 1000 });
|
|
for (const theme of ['light', 'dark']) {
|
|
await page.emulateMedia({
|
|
colorScheme: theme,
|
|
reducedMotion: 'reduce',
|
|
});
|
|
for (const [path, state] of [
|
|
['/dashboard', 'filled'],
|
|
['/dashboard?empty', 'empty'],
|
|
]) {
|
|
await page.goto(base + path);
|
|
await page
|
|
.getByRole('heading', {
|
|
name: 'Welcome back, Alex Morgan',
|
|
exact: true,
|
|
level: 1,
|
|
})
|
|
.waitFor();
|
|
await page.evaluate(() => document.fonts.ready);
|
|
assert.equal(
|
|
await page
|
|
.locator('html')
|
|
.evaluate((element) =>
|
|
element.classList.contains('dark'),
|
|
),
|
|
theme === 'dark',
|
|
);
|
|
assert.equal(
|
|
await page.evaluate(
|
|
() =>
|
|
document.documentElement.scrollWidth <=
|
|
window.innerWidth,
|
|
),
|
|
true,
|
|
`${state} dashboard overflows at ${width} in ${theme}`,
|
|
);
|
|
await page.screenshot({
|
|
path: `/private/tmp/kan25-dashboard-${state}-${width}-${theme}.png`,
|
|
fullPage: true,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
await page.setViewportSize({ width: 390, height: 1000 });
|
|
await page.goto(`${base}/dashboard`);
|
|
const ticket = content().getByRole('link', {
|
|
name: 'Open ENG-42: Ship the dashboard with real assigned work',
|
|
exact: true,
|
|
});
|
|
await focusWithTab(ticket);
|
|
await page.keyboard.press('Enter');
|
|
await page.waitForURL('**/projects/7/tickets/42');
|
|
await page
|
|
.getByRole('heading', { name: 'Destination reached', exact: true })
|
|
.waitFor();
|
|
|
|
await page.goto(`${base}/dashboard?empty`);
|
|
const projects = content().getByRole('link', {
|
|
name: 'Browse projects',
|
|
exact: true,
|
|
});
|
|
await focusWithTab(projects);
|
|
await page.keyboard.press('Enter');
|
|
await page.waitForURL('**/projects');
|
|
assert.deepEqual(errors, []);
|
|
console.log(
|
|
'Dashboard browser checks passed: keyboard, empty and filled states, 320/390/1440px and both themes.',
|
|
);
|
|
} finally {
|
|
await browser.close();
|
|
}
|