Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/improsocial/impro
An extensible Bluesky client for web impro.social
Something went wrong. Try again.
JavaScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187import { describe, it, beforeEach, afterEach } from "node:test";import assert from "node:assert/strict";import { startActiveTabMonitor } from "/js/activeTabMonitor.js";import { installFakeBroadcastChannel } from "../testHelpers.js";
const CHANNEL_NAME = "active-tab-monitor";
function macrotask() { return new Promise((resolve) => setTimeout(resolve, 0));}
// One delivery hop each way, plus room for the reply to be handled.async function flushChannel() { await macrotask(); await macrotask(); await macrotask();}
describe("startActiveTabMonitor", () => { let monitors; let peers; let restoreBroadcastChannel; let originalHasFocus;
function simulateTabState({ visible, focused }) { Object.defineProperty(document, "visibilityState", { value: visible ? "visible" : "hidden", configurable: true, }); document.hasFocus = () => focused; }
function startMonitor({ replyTimeoutMs = 100 } = {}) { const monitor = startActiveTabMonitor({ replyTimeoutMs }); monitors.push(monitor); return monitor; }
// Stands in for another tab, so the monitor under test is the only thing // reading this document's focus state. function createPeer({ answersQueries = false, id = null } = {}) { const channel = new BroadcastChannel(CHANNEL_NAME); const received = []; channel.addEventListener("message", (event) => { received.push(event.data); if (answersQueries && event.data?.method === "isTabActive") { channel.postMessage({ id: id ?? event.data.id, result: true }); } }); peers.push(channel); return { channel, received }; }
beforeEach(() => { monitors = []; peers = []; restoreBroadcastChannel = installFakeBroadcastChannel(); originalHasFocus = document.hasFocus; simulateTabState({ visible: true, focused: false }); });
afterEach(() => { for (const monitor of monitors) { monitor.stop(); } for (const peer of peers) { peer.close(); } restoreBroadcastChannel(); document.hasFocus = originalHasFocus; delete document.visibilityState; });
describe("this tab's own focus", () => { it("is active when visible and focused", async () => { const monitor = startMonitor(); simulateTabState({ visible: true, focused: true });
assert.deepEqual(await monitor.isAnyTabActive(), true); });
it("is not active when focused but hidden", async () => { const monitor = startMonitor(); simulateTabState({ visible: false, focused: true });
assert.deepEqual(await monitor.isAnyTabActive(), false); });
it("is not active when visible but unfocused", async () => { const monitor = startMonitor(); simulateTabState({ visible: true, focused: false });
assert.deepEqual(await monitor.isAnyTabActive(), false); }); });
describe("answering other tabs", () => { it("answers a focus query while focused", async () => { startMonitor(); const peer = createPeer(); simulateTabState({ visible: true, focused: true });
peer.channel.postMessage({ method: "isTabActive", id: "req-1" }); await flushChannel();
assert.deepEqual(peer.received, [{ id: "req-1", result: true }]); });
it("stays silent on a focus query while unfocused", async () => { startMonitor(); const peer = createPeer();
peer.channel.postMessage({ method: "isTabActive", id: "req-1" }); await flushChannel();
assert.deepEqual(peer.received, []); });
it("stops answering once stopped", async () => { const monitor = startMonitor(); const peer = createPeer(); simulateTabState({ visible: true, focused: true });
monitor.stop(); peer.channel.postMessage({ method: "isTabActive", id: "req-1" }); await flushChannel();
assert.deepEqual(peer.received, []); }); });
describe("asking other tabs", () => { it("is active when a peer answers", async () => { createPeer({ answersQueries: true }); const monitor = startMonitor();
assert.deepEqual(await monitor.isAnyTabActive(), true); });
it("ignores a response carrying another request's id", async () => { createPeer({ answersQueries: true, id: "someone-else" }); const monitor = startMonitor();
assert.deepEqual(await monitor.isAnyTabActive(), false); });
it("is inactive when a peer stays silent", async () => { createPeer(); const monitor = startMonitor();
assert.deepEqual(await monitor.isAnyTabActive(), false); });
it("is inactive when no other tab is open", async () => { const monitor = startMonitor();
assert.deepEqual(await monitor.isAnyTabActive(), false); });
it("does not ask when this tab is already active", async () => { const peer = createPeer({ answersQueries: true }); const monitor = startMonitor(); simulateTabState({ visible: true, focused: true });
assert.deepEqual(await monitor.isAnyTabActive(), true); await flushChannel();
assert.deepEqual(peer.received, []); });
it("is inactive without BroadcastChannel support", async (t) => { const warn = t.mock.method(console, "warn", () => {}); restoreBroadcastChannel(); const originalChannel = globalThis.BroadcastChannel; delete globalThis.BroadcastChannel; try { const monitor = startActiveTabMonitor(); assert.deepEqual(await monitor.isAnyTabActive(), false); assert.deepEqual(warn.mock.callCount(), 1); } finally { globalThis.BroadcastChannel = originalChannel; restoreBroadcastChannel = installFakeBroadcastChannel(); } }); });});