Files
bindery/tests/js/polling-flows.test.mjs
T
tim 2f4271314b Add the web interface
Plain HTML, CSS and JavaScript modules, with no build step. Hash routes
and relative URLs make it work under any path. The job list is polled:
every 2 seconds while a job runs, and less often otherwise.
2026-09-27 23:38:28 +02:00

61 lines
2.0 KiB
JavaScript

import assert from 'node:assert/strict';
import { test } from 'node:test';
import { install, server, settle } from './flow-helpers.mjs';
const ui = install();
const { startPolling, stopPolling, watchJobs } = await import('../../bindery/static/js/jobs.js');
test('polling adapts to work and visibility, retries failures, and stops after an in-flight request', async (t) => {
t.mock.timers.enable({ apis: ['setTimeout'] });
const api = server(t);
const rendered = [];
const unsubscribe = watchJobs({ render: (jobs) => rendered.push(jobs) });
t.after(() => { unsubscribe(); stopPolling(); });
let jobs = [];
api.on('GET', 'jobs', () => jobs);
startPolling();
await settle();
t.mock.timers.tick(9999);
assert.equal(api.requests.length, 1);
jobs = [{ id: 'job', status: 'running' }];
t.mock.timers.tick(1);
await settle();
assert.equal(api.requests.length, 2);
t.mock.timers.tick(1999);
assert.equal(api.requests.length, 2);
t.mock.timers.tick(1);
await settle();
assert.equal(api.requests.length, 3);
document.hidden = true;
ui.documentEvents.visibilitychange();
assert.equal(api.requests.length, 3);
t.mock.timers.tick(2000);
await settle();
t.mock.timers.tick(59999);
assert.equal(api.requests.length, 4);
t.mock.timers.tick(1);
await settle();
assert.equal(api.requests.length, 5);
document.hidden = false;
api.on('GET', 'jobs', () => { throw new Error('Connection lost'); });
const previous = rendered.length;
ui.documentEvents.visibilitychange();
await settle();
assert.equal(rendered.length, previous);
jobs = [{ id: 'job', status: 'done' }];
api.on('GET', 'jobs', () => jobs);
t.mock.timers.tick(2000);
await settle();
assert.deepEqual(rendered.at(-1), jobs);
let resolve;
api.on('GET', 'jobs', () => new Promise((done) => { resolve = done; }));
t.mock.timers.tick(10000);
stopPolling();
resolve([]);
await settle();
const total = api.requests.length;
t.mock.timers.tick(60000);
await settle();
assert.equal(api.requests.length, total);
});