feat: add public entry page for KAN-50
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
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:4192';
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
page.setDefaultTimeout(10000);
|
||||
const errors = [];
|
||||
page.on('pageerror', (error) => errors.push(error.message));
|
||||
|
||||
const focusWithTab = async (link) => {
|
||||
await page.locator('body').focus();
|
||||
for (let step = 0; step < 12; 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('Primary welcome 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, action] of [
|
||||
['/', 'Sign in to KanbanGit'],
|
||||
['/?auth=1', 'Open dashboard'],
|
||||
]) {
|
||||
await page.goto(base + path);
|
||||
await page
|
||||
.getByRole('heading', {
|
||||
name: 'Plan the work. Keep Git context close.',
|
||||
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,
|
||||
`${path} overflows at ${width}px in ${theme} mode`,
|
||||
);
|
||||
const clippedElements = await page
|
||||
.locator(
|
||||
'header a, main h1, main p, main section, main article, main li, footer p',
|
||||
)
|
||||
.evaluateAll((elements) =>
|
||||
elements
|
||||
.filter((element) => {
|
||||
const bounds = element.getBoundingClientRect();
|
||||
return (
|
||||
bounds.width > 0 &&
|
||||
(bounds.left < -0.5 ||
|
||||
bounds.right > window.innerWidth + 0.5)
|
||||
);
|
||||
})
|
||||
.map((element) => element.outerHTML.slice(0, 120)),
|
||||
);
|
||||
assert.deepEqual(
|
||||
clippedElements,
|
||||
[],
|
||||
`${path} clips content at ${width}px in ${theme} mode`,
|
||||
);
|
||||
assert.equal(await page.locator('main h1').count(), 1);
|
||||
const primaryAction = page
|
||||
.locator('main')
|
||||
.getByRole('link', { name: action, exact: true });
|
||||
assert.ok(
|
||||
(await primaryAction.evaluate(
|
||||
(element) => element.getBoundingClientRect().height,
|
||||
)) >= 44,
|
||||
);
|
||||
await page.screenshot({
|
||||
path: `/private/tmp/kan50-welcome-${path.includes('auth') ? 'authenticated' : 'guest'}-${width}-${theme}.png`,
|
||||
fullPage: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await page.setViewportSize({ width: 390, height: 1000 });
|
||||
await page.goto(`${base}/`);
|
||||
const signIn = page
|
||||
.locator('main')
|
||||
.getByRole('link', { name: 'Sign in to KanbanGit', exact: true });
|
||||
await focusWithTab(signIn);
|
||||
await page.keyboard.press('Enter');
|
||||
await page.waitForURL('**/login');
|
||||
await page
|
||||
.getByRole('heading', { name: 'Destination reached', exact: true })
|
||||
.waitFor();
|
||||
|
||||
await page.goto(`${base}/?auth=1`);
|
||||
const dashboard = page
|
||||
.locator('main')
|
||||
.getByRole('link', { name: 'Open dashboard', exact: true });
|
||||
await focusWithTab(dashboard);
|
||||
await page.keyboard.press('Enter');
|
||||
await page.waitForURL('**/dashboard');
|
||||
await page
|
||||
.getByRole('heading', { name: 'Destination reached', exact: true })
|
||||
.waitFor();
|
||||
|
||||
assert.deepEqual(errors, []);
|
||||
console.log(
|
||||
'Welcome browser checks passed: keyboard, guest and authenticated actions, 320/390/1440px and both themes.',
|
||||
);
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
Reference in New Issue
Block a user