171 lines
5.2 KiB
JavaScript
171 lines
5.2 KiB
JavaScript
'use strict';
|
|
// Each scene leaves the app looking the way the website screenshot should, then calls shot(name).
|
|
// Scenes run in order in one session; each one starts by getting back to a known state.
|
|
|
|
// Cosmetic: show the default notes location instead of the temp folder this run uses.
|
|
const tidyPath = (js) => js(`
|
|
for (const el of document.querySelectorAll('.ws-path, .mono')) {
|
|
if (/^\\/tmp\\/ink-shots-[^/]+\\/Notes$/.test(el.textContent.trim())) { el.textContent = '~/Notes'; el.title = '~/Notes'; }
|
|
}`);
|
|
|
|
const reset = async ({ key, sleep, js }) => {
|
|
await tidyPath(js);
|
|
for (let i = 0; i < 3; i++) await key('Escape');
|
|
await js(`document.activeElement?.blur?.()`);
|
|
await sleep(150);
|
|
};
|
|
|
|
// Open a page the way a user would: Ctrl+K, type its name, Enter.
|
|
const openFromSidebar = async ({ key, type, sleep }, text) => {
|
|
await key('K', ['control']);
|
|
await sleep(400);
|
|
await type(text, 30);
|
|
await sleep(700);
|
|
await key('Return');
|
|
await sleep(1000);
|
|
return true;
|
|
};
|
|
|
|
// The element that actually scrolls the page.
|
|
const scrollPage = (js, y) => js(`
|
|
const c = [...document.querySelectorAll('*')].filter((e) => { const s = getComputedStyle(e); return /(auto|scroll)/.test(s.overflowY) && e.scrollHeight > e.clientHeight + 20 && e.clientWidth > 600; })
|
|
.sort((a, b) => b.clientWidth * b.clientHeight - a.clientWidth * a.clientHeight)[0];
|
|
if (c) { c.scrollTop = ${y}; return c.className; } return null;`);
|
|
|
|
module.exports = {
|
|
async editor(ctx) {
|
|
const { js, sleep, shot } = ctx;
|
|
await tidyPath(js);
|
|
await reset(ctx);
|
|
await openFromSidebar(ctx, 'Roadmap');
|
|
await scrollPage(js, 120);
|
|
await sleep(300);
|
|
await shot('editor');
|
|
},
|
|
|
|
async 'slash-menu'(ctx) {
|
|
const { js, type, sleep, shot, key } = ctx;
|
|
await reset(ctx);
|
|
await openFromSidebar(ctx, 'Launch plan');
|
|
await scrollPage(js, 170);
|
|
await sleep(300);
|
|
await js(`document.querySelector('.tail').click()`);
|
|
await sleep(400);
|
|
await type('/');
|
|
await sleep(500);
|
|
await shot('slash-menu');
|
|
await key('Escape');
|
|
},
|
|
|
|
async linking(ctx) {
|
|
const { js, sleep, shot } = ctx;
|
|
await reset(ctx);
|
|
await openFromSidebar(ctx, 'Reading list');
|
|
await scrollPage(js, 2000);
|
|
await sleep(600);
|
|
await shot('linking');
|
|
},
|
|
|
|
async canvas(ctx) {
|
|
const { sleep, shot, key } = ctx;
|
|
await reset(ctx);
|
|
await openFromSidebar(ctx, 'Project map');
|
|
await sleep(1200);
|
|
await key('1', ['shift']);
|
|
await sleep(900);
|
|
await shot('canvas');
|
|
},
|
|
|
|
async board(ctx) {
|
|
const { sleep, shot } = ctx;
|
|
await reset(ctx);
|
|
await openFromSidebar(ctx, 'Sprint board');
|
|
await sleep(900);
|
|
await scrollPage(ctx.js, 200);
|
|
await sleep(400);
|
|
await shot('board');
|
|
},
|
|
|
|
async graph(ctx) {
|
|
const { js, sleep, shot, key } = ctx;
|
|
await reset(ctx);
|
|
await js(`[...document.querySelectorAll('.sidebar .qa')].find((b) => b.textContent.includes('Graph view')).click()`);
|
|
await sleep(3500);
|
|
await js(`document.querySelector('.graph-top [aria-label="Graph settings"]')?.click()`);
|
|
await sleep(900);
|
|
await shot('graph');
|
|
await key('Escape');
|
|
},
|
|
|
|
async palette(ctx) {
|
|
const { sleep, shot, key, type } = ctx;
|
|
await reset(ctx);
|
|
await openFromSidebar(ctx, 'Roadmap');
|
|
await key('K', ['control']);
|
|
await sleep(500);
|
|
await type('tag:work road');
|
|
await sleep(700);
|
|
await shot('palette');
|
|
await key('Escape');
|
|
},
|
|
|
|
async settings(ctx) {
|
|
const { js, sleep, shot, key } = ctx;
|
|
await reset(ctx);
|
|
await openFromSidebar(ctx, 'Roadmap');
|
|
await key(',', ['control']);
|
|
await sleep(900);
|
|
await tidyPath(js);
|
|
await sleep(200);
|
|
await shot('settings');
|
|
await key('Escape');
|
|
},
|
|
|
|
async history(ctx) {
|
|
const { js, sleep, shot, key } = ctx;
|
|
await reset(ctx);
|
|
await openFromSidebar(ctx, 'Roadmap');
|
|
await js(`document.querySelector('[aria-label="Page options"]')?.click()`);
|
|
await sleep(500);
|
|
await js(`[...document.querySelectorAll('[role="menuitem"]')].find((m) => m.textContent.includes('Version history'))?.click()`);
|
|
await sleep(1200);
|
|
await shot('history');
|
|
await key('Escape');
|
|
},
|
|
|
|
async databases(ctx) {
|
|
const { js, sleep, shot } = ctx;
|
|
await reset(ctx);
|
|
await openFromSidebar(ctx, 'Feature tracker');
|
|
await sleep(1200);
|
|
await scrollPage(js, 230);
|
|
await sleep(400);
|
|
await shot('databases');
|
|
},
|
|
|
|
async 'database-board'(ctx) {
|
|
const { js, sleep, shot } = ctx;
|
|
await reset(ctx);
|
|
await openFromSidebar(ctx, 'Feature tracker');
|
|
await sleep(800);
|
|
await js(`[...document.querySelectorAll('button, [role="tab"]')].find((b) => b.textContent.trim() === 'Board')?.click()`);
|
|
await sleep(1000);
|
|
await scrollPage(js, 230);
|
|
await sleep(400);
|
|
await shot('database-board');
|
|
},
|
|
|
|
// The settings dialog on the color theme and accent pickers. Run once per palette by run.sh.
|
|
async themes(ctx) {
|
|
const { js, sleep, shot, key } = ctx;
|
|
await reset(ctx);
|
|
await openFromSidebar(ctx, 'Roadmap');
|
|
await key(',', ['control']);
|
|
await sleep(900);
|
|
await js(`document.querySelector('[aria-label="Color theme"]')?.scrollIntoView({ block: 'center' })`);
|
|
await sleep(500);
|
|
await shot('themes');
|
|
await key('Escape');
|
|
},
|
|
};
|