85 lines
4.9 KiB
JavaScript
85 lines
4.9 KiB
JavaScript
// End-to-end check of column colours on Kanban boards (Markdown boards, not databases).
|
|
const { app, BrowserWindow } = require('electron');
|
|
const path = require('path');
|
|
const os = require('os');
|
|
const fs = require('fs');
|
|
|
|
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'ink-e2e-kcolors-'));
|
|
const vault = path.join(tmp, 'Vault');
|
|
fs.mkdirSync(vault);
|
|
const BOARD = '## To do\n\n- [ ] One\n\n## Doing\n\n- [ ] Two\n\n## Done\n\n- [x] Three\n';
|
|
fs.writeFileSync(path.join(vault, 'Plan.md'), '---\nkanban-plugin: basic\n---\n\n' + BOARD);
|
|
fs.writeFileSync(path.join(vault, 'Other.md'), 'Other.\n');
|
|
app.setPath('userData', tmp);
|
|
fs.writeFileSync(path.join(tmp, 'settings.json'), JSON.stringify({ vault, lastPage: 'Plan', bounds: { width: 1300, height: 800 } }));
|
|
require('../electron/main.cjs');
|
|
|
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
const failures = [];
|
|
const check = (name, ok, extra = '') => {
|
|
console.log(`${ok ? 'PASS' : 'FAIL'} ${name}${extra ? ' — ' + extra : ''}`);
|
|
if (!ok) failures.push(name);
|
|
};
|
|
|
|
app.whenReady().then(async () => {
|
|
let win;
|
|
for (let i = 0; i < 80 && !(win = BrowserWindow.getAllWindows()[0]); i++) await sleep(100);
|
|
const wc = win.webContents;
|
|
if (wc.isLoading()) await new Promise((r) => wc.once('did-finish-load', r));
|
|
const js = (code) => wc.executeJavaScript(`(async () => { ${code} })()`);
|
|
const centerOf = (sel) => js(`const e = ${sel}; if (!e) return null; const r = e.getBoundingClientRect(); return [Math.round(r.x + r.width / 2), Math.round(r.y + r.height / 2)]`);
|
|
const click = async (sel) => {
|
|
const c = await centerOf(sel);
|
|
if (!c) throw new Error('not found: ' + sel);
|
|
wc.sendInputEvent({ type: 'mouseMove', x: c[0], y: c[1] });
|
|
wc.sendInputEvent({ type: 'mouseDown', x: c[0], y: c[1], button: 'left', clickCount: 1 });
|
|
wc.sendInputEvent({ type: 'mouseUp', x: c[0], y: c[1], button: 'left', clickCount: 1 });
|
|
await sleep(450);
|
|
};
|
|
const file = () => fs.readFileSync(path.join(vault, 'Plan.md'), 'utf8');
|
|
const pill = (name) => js(`const h = [...document.querySelectorAll('.khead')].find((x) => x.querySelector('.kh-title')?.textContent.trim() === ${JSON.stringify(name)}); return h ? h.querySelector('.db-opt').style.getPropertyValue('--oc') : null`);
|
|
const menuFor = async (name) => {
|
|
await js(`const h = [...document.querySelectorAll('.khead')].find((x) => x.querySelector('.kh-title')?.textContent.trim() === ${JSON.stringify(name)}); h.querySelector('[aria-label="Column options"]').click()`);
|
|
await sleep(300);
|
|
};
|
|
|
|
try {
|
|
await sleep(1800);
|
|
check('column titles are pills', (await js(`return document.querySelectorAll('.khead .db-opt').length`)) === 3);
|
|
const auto = await pill('Doing');
|
|
check('...with a colour from their name until you pick one', /^#[0-9a-f]{6}$/i.test(auto), auto);
|
|
|
|
await menuFor('Doing');
|
|
await click(`document.querySelector('.kmenu .cv-swatch[data-color="teal"]')`);
|
|
await sleep(1000);
|
|
check('a colour is picked from the column menu', (await pill('Doing')) === '#3aa6c4', await pill('Doing'));
|
|
check('...kept in the page\'s front matter', /ink-colors: .*Doing.*teal/.test(file()), file().slice(0, 120));
|
|
check('...and the board text itself is untouched', file().endsWith(BOARD), JSON.stringify(file().slice(-60)));
|
|
check('...and not listed as a property of the page', !(await js(`return [...document.querySelectorAll('.custom-pk')].some((i) => i.value === 'ink-colors')`)));
|
|
|
|
await js(`window.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape' }))`);
|
|
await js(`document.querySelector('.row[data-id="Other"]').click()`);
|
|
await sleep(900);
|
|
await js(`document.querySelector('.row[data-id="Plan"]').click()`);
|
|
await sleep(1200);
|
|
check('the colour is there when you come back', (await pill('Doing')) === '#3aa6c4', await pill('Doing'));
|
|
|
|
// rename keeps it
|
|
await js(`const h = [...document.querySelectorAll('.khead')].find((x) => x.querySelector('.kh-title')?.textContent.trim() === 'Doing'); h.querySelector('.kh-title').click()`);
|
|
await sleep(300);
|
|
await js(`const i = document.querySelector('.kh-input'); i.value = 'In progress'; i.dispatchEvent(new Event('input', { bubbles: true })); i.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }))`);
|
|
await sleep(1000);
|
|
check('renaming a column keeps its colour', (await pill('In progress')) === '#3aa6c4' && /In progress.*teal/.test(file()) && !/"Doing"/.test(file()), file().slice(0, 140));
|
|
|
|
await menuFor('In progress');
|
|
await click(`document.querySelector('.kmenu .cv-swatch[data-color="auto"]')`);
|
|
await sleep(900);
|
|
check('"Automatic" takes the colour away again', !/ink-colors/.test(file()), file().slice(0, 100));
|
|
} catch (err) {
|
|
check('harness', false, err.stack);
|
|
}
|
|
fs.rmSync(tmp, { recursive: true, force: true });
|
|
console.log(failures.length ? `\n${failures.length} check(s) failed` : '\nkanban colours e2e passed!');
|
|
app.exit(failures.length ? 1 : 0);
|
|
});
|