Files
KanbanGit/native/tests/navigation-browser.mjs
Twyco 1cf7524a7b
CI/CD / preconditions (pull_request) Successful in 1s
Native JavaScript checks / Native launcher and release tests (pull_request) Successful in 1m13s
macOS checks / Native Rust tests and unsigned build (pull_request) Successful in 1m44s
CI/CD / test_and_check_app (pull_request) Successful in 7m4s
CI/CD / Publish immutable image (pull_request) Skipped
fix(KAN-71): use interactive WebKit navigation gestures
2026-09-29 08:02:10 +02:00

95 lines
3.7 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 script = await readFile(
new URL('../ui/workspace-navigation.js', import.meta.url),
'utf8',
);
const server = createServer((request, response) => {
response.setHeader('Content-Type', 'text/html');
response.end(`<!doctype html><html><head><meta name="viewport" content="width=device-width,initial-scale=1"><style>
body { margin: 0; } #board { overflow-x: auto; width: 300px; height: 100px; }
#board > div { width: 1500px; height: 100px; } dialog { max-height: 200px; overflow-y: auto; }
</style></head><body><p id="page">${request.url}</p><input id="draft" value="retained"><div id="board"><div>Board columns</div></div>
<dialog><button id="close">Close</button><div style="height:1000px">Long dialog</div></dialog><div id="long"></div></body></html>`);
});
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({ viewport: { width: 390, height: 844 } });
await page.addInitScript(script);
const root = `http://127.0.0.1:${server.address().port}`;
try {
await page.goto(root);
assert.equal(
await page.evaluate(() => typeof window.__kanbanNavigation),
'undefined',
);
await page.goto(`${root}/full-page`);
await page.goBack();
await page.waitForURL(`${root}/`);
await page.goForward();
await page.waitForURL(`${root}/full-page`);
await page.locator('#draft').fill('unsaved draft');
assert.equal(await page.locator('#draft').inputValue(), 'unsaved draft');
assert.equal(
await page.evaluate(
() =>
getComputedStyle(document.documentElement).overscrollBehaviorY,
),
'none',
);
assert.equal(
await page.evaluate(
() =>
getComputedStyle(document.documentElement).overscrollBehaviorX,
),
'auto',
);
assert.equal(
await page.evaluate(() => document.documentElement.scrollHeight),
844,
);
await page.mouse.move(380, 400);
await page.mouse.wheel(0, -1000);
await page.waitForTimeout(200);
assert.equal(await page.evaluate(() => scrollY), 0);
await page
.locator('#long')
.evaluate((element) => (element.style.height = '3000px'));
await page.mouse.wheel(0, 1000);
await page.waitForFunction(() => scrollY > 0);
await page.evaluate(() =>
scrollTo(0, document.documentElement.scrollHeight),
);
await page.mouse.wheel(0, 5000);
await page.waitForTimeout(200);
assert.equal(
await page.evaluate(() => scrollY + innerHeight),
await page.evaluate(() => document.documentElement.scrollHeight),
);
await page.evaluate(() => scrollTo(0, 0));
await page.locator('#board').hover();
await page.mouse.wheel(500, 0);
await page.waitForFunction(
() => document.querySelector('#board').scrollLeft > 0,
);
assert.equal(new URL(page.url()).pathname, '/full-page');
await page.locator('dialog').evaluate((dialog) => dialog.showModal());
await page.locator('dialog').hover();
await page.mouse.wheel(0, 500);
await page.waitForFunction(
() => document.querySelector('dialog').scrollTop > 0,
);
console.log(
'PASS: browser-owned history, editable input, short/long scroll bounds, horizontal board and dialog scrolling',
);
} finally {
await browser.close();
await new Promise((resolve) => server.close(resolve));
}