149 lines
4.9 KiB
JavaScript
149 lines
4.9 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import { readFile } from 'node:fs/promises';
|
|
import { createServer } from 'node:http';
|
|
import process from 'node:process';
|
|
|
|
const { chromium } = await import(
|
|
process.env.PLAYWRIGHT_MODULE ?? 'playwright'
|
|
);
|
|
const actions = [];
|
|
const server = createServer(async (request, response) => {
|
|
const url = new URL(request.url, 'http://localhost');
|
|
if (url.pathname.startsWith('/action/')) {
|
|
actions.push(url);
|
|
response.writeHead(204).end();
|
|
return;
|
|
}
|
|
const file = url.pathname === '/' ? 'index.html' : url.pathname.slice(1);
|
|
if (
|
|
![
|
|
'index.html',
|
|
'main.js',
|
|
'server.js',
|
|
'locales/en.js',
|
|
'styles.css',
|
|
'mark.svg',
|
|
].includes(file)
|
|
) {
|
|
response.writeHead(404).end();
|
|
return;
|
|
}
|
|
response.setHeader(
|
|
'Content-Type',
|
|
file.endsWith('.js')
|
|
? 'text/javascript'
|
|
: file.endsWith('.css')
|
|
? 'text/css'
|
|
: file.endsWith('.svg')
|
|
? 'image/svg+xml'
|
|
: 'text/html',
|
|
);
|
|
response.end(await readFile(new URL(`../ui/${file}`, import.meta.url)));
|
|
});
|
|
await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve));
|
|
const browser = await chromium.launch({ channel: 'chrome', headless: true });
|
|
const page = await browser.newPage();
|
|
const state = (phase, ready = false, server = 'https://kanbangit.de/') =>
|
|
page.evaluate(
|
|
({ phase, ready, server }) => {
|
|
window.updateLauncher(
|
|
new URLSearchParams({
|
|
phase,
|
|
ready: String(ready),
|
|
server,
|
|
}).toString(),
|
|
);
|
|
},
|
|
{ phase, ready, server },
|
|
);
|
|
const latestAction = async (name) => {
|
|
await page.waitForTimeout(100);
|
|
assert.equal(actions.at(-1)?.pathname, `/action/${name}`);
|
|
};
|
|
try {
|
|
await page.goto(`http://127.0.0.1:${server.address().port}/`);
|
|
await state('idle');
|
|
for (const width of [320, 390, 1440]) {
|
|
await page.setViewportSize({ width, height: 900 });
|
|
for (const theme of ['light', 'dark', 'system']) {
|
|
await page.getByLabel('Appearance').selectOption(theme);
|
|
assert.equal(
|
|
await page.evaluate(
|
|
() => document.documentElement.scrollWidth <= innerWidth,
|
|
),
|
|
true,
|
|
);
|
|
assert.equal(
|
|
await page
|
|
.getByRole('button', {
|
|
name: 'Open workspace',
|
|
exact: true,
|
|
})
|
|
.isVisible(),
|
|
true,
|
|
);
|
|
}
|
|
}
|
|
await page.getByLabel('Server address').fill('http://example.com/');
|
|
await page.getByLabel('Server address').press('Enter');
|
|
assert.equal(
|
|
await page.getByLabel('Server address').getAttribute('aria-invalid'),
|
|
'true',
|
|
);
|
|
await page.getByLabel('Server address').fill('https://first.example.com/');
|
|
await page.getByLabel('Server address').press('Enter');
|
|
await latestAction('open');
|
|
assert.equal(
|
|
actions.at(-1).searchParams.get('server'),
|
|
'https://first.example.com/',
|
|
);
|
|
await state('connecting', false, 'https://first.example.com/');
|
|
assert.equal(
|
|
await page
|
|
.getByRole('button', { name: 'Open workspace', exact: true })
|
|
.isDisabled(),
|
|
true,
|
|
);
|
|
await state('connectionError', false, 'https://first.example.com/');
|
|
assert.equal(
|
|
await page.getByLabel('Server address').inputValue(),
|
|
'https://first.example.com/',
|
|
);
|
|
await page.getByRole('button', { name: 'Try again', exact: true }).click();
|
|
await latestAction('open');
|
|
await state('connected', true, 'https://first.example.com/');
|
|
await page
|
|
.getByRole('button', { name: 'Return to workspace', exact: true })
|
|
.click();
|
|
await latestAction('resume');
|
|
await page
|
|
.getByLabel('Server address')
|
|
.fill('https://second.example.com/app');
|
|
await page
|
|
.getByRole('button', { name: 'Open workspace', exact: true })
|
|
.click();
|
|
assert.equal(
|
|
await page
|
|
.getByRole('button', { name: 'Switch server', exact: true })
|
|
.isVisible(),
|
|
true,
|
|
);
|
|
await page.getByRole('button', { name: 'Cancel', exact: true }).click();
|
|
await latestAction('resume');
|
|
await page.getByLabel('Server address').press('Enter');
|
|
await page
|
|
.getByRole('button', { name: 'Switch server', exact: true })
|
|
.click();
|
|
await latestAction('open');
|
|
assert.equal(
|
|
actions.at(-1).searchParams.get('server'),
|
|
'https://second.example.com/app/',
|
|
);
|
|
console.log(
|
|
'Launcher browser tests passed: responsive themes, keyboard, validation, offline retry, resume and confirmed switching.',
|
|
);
|
|
} finally {
|
|
await browser.close();
|
|
server.close();
|
|
}
|