79 lines
4.4 KiB
JavaScript
79 lines
4.4 KiB
JavaScript
// End-to-end check of the tasks list, unlinked mentions, saved searches and quick capture. Run with `bun run e2e tasks`.
|
|
const { app, BrowserWindow, ipcMain } = require('electron');
|
|
const path = require('path');
|
|
const os = require('os');
|
|
const fs = require('fs');
|
|
|
|
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'ink-e2e-tasks-'));
|
|
const vault = path.join(tmp, 'Vault');
|
|
fs.mkdirSync(vault, { recursive: true });
|
|
fs.writeFileSync(path.join(vault, 'Plan.md'), '# Plan\n\n- [ ] Write the spec #work 📅 2020-01-01\n- [x] Old thing\n');
|
|
fs.writeFileSync(path.join(vault, 'Roadmap.md'), 'The roadmap page\n');
|
|
fs.writeFileSync(path.join(vault, 'Notes.md'), 'Remember the roadmap for next year.\n');
|
|
app.setPath('userData', tmp);
|
|
fs.writeFileSync(path.join(tmp, 'settings.json'), JSON.stringify({ vault, lastPage: 'Roadmap', theme: 'dark', bounds: { width: 1100, height: 760 } }));
|
|
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);
|
|
};
|
|
const read = (f) => fs.readFileSync(path.join(vault, f), 'utf8');
|
|
|
|
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} })()`);
|
|
try {
|
|
await sleep(2200);
|
|
|
|
// unlinked mentions on Roadmap
|
|
check('Roadmap lists Notes as an unlinked mention', (await js(`return document.querySelector('.unlinked .sec-toggle')?.textContent.includes('Mentioned without a link')`)) === true);
|
|
await js(`document.querySelector('.unlinked .sec-toggle').click()`);
|
|
await sleep(300);
|
|
await js(`document.querySelector('.unlinked .bl-loose .btn').click()`);
|
|
await sleep(1000);
|
|
check('"Link it" turns the mention into a link', read('Notes.md').includes('[[Roadmap|roadmap]]'), read('Notes.md'));
|
|
|
|
// tasks dialog
|
|
await js(`document.querySelector('.sidebar button[aria-label="Tasks"]').click()`);
|
|
await sleep(700);
|
|
check('the tasks dialog lists the open task', (await js(`return [...document.querySelectorAll('.tk-t')].map((e) => e.textContent)`)).join('|') === 'Write the spec #work');
|
|
check('...as overdue', (await js(`return !!document.querySelector('.tk-due.over')`)) === true);
|
|
await js(`document.querySelector('.tk input').click()`);
|
|
await sleep(800);
|
|
check('ticking a task writes it to the file', read('Plan.md').includes('- [x] Write the spec'), read('Plan.md'));
|
|
await js(`document.querySelector('.tasks-panel .btn-icon').click()`);
|
|
await sleep(500);
|
|
|
|
// saved searches
|
|
await js(`document.querySelector('.sidebar button[aria-label="Search"]').click()`);
|
|
await sleep(400);
|
|
await js(`const i = document.querySelector('.pal-top input'); i.value = 'tag:work'; i.dispatchEvent(new Event('input', { bubbles: true }))`);
|
|
await sleep(400);
|
|
await js(`[...document.querySelectorAll('.pi')].find((b) => b.textContent.includes('Save this search')).click()`);
|
|
await sleep(700);
|
|
check('a search can be saved to the sidebar', (await js(`return [...document.querySelectorAll('.sidebar .fav .name')].map((e) => e.textContent).includes('tag:work')`)) === true);
|
|
|
|
// quick capture: the window's handler queues it, the page adds it to today's note
|
|
const ok = await ipcMain._invokeHandlers.get('capture:save')({}, 'a quick thought', 'daily');
|
|
await sleep(1500);
|
|
const d = new Date();
|
|
const z = (n) => String(n).padStart(2, '0');
|
|
const day = `${d.getFullYear()}-${z(d.getMonth() + 1)}-${z(d.getDate())}`;
|
|
check('a capture lands in today\'s note', ok === true && fs.existsSync(path.join(vault, 'Daily', day + '.md')) && read(path.join('Daily', day + '.md')).includes('- a quick thought'));
|
|
await ipcMain._invokeHandlers.get('capture:save')({}, 'second', 'inbox');
|
|
await sleep(1500);
|
|
check('...or in Inbox', fs.existsSync(path.join(vault, 'Inbox.md')) && read('Inbox.md').includes('- second'));
|
|
} catch (err) {
|
|
check('harness', false, err.stack);
|
|
}
|
|
fs.rmSync(tmp, { recursive: true, force: true });
|
|
console.log(failures.length ? `\n${failures.length} check(s) failed` : '\ntasks e2e passed!');
|
|
app.exit(failures.length ? 1 : 0);
|
|
});
|