mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-04 02:04:06 +00:00
84 lines
2.5 KiB
TypeScript
84 lines
2.5 KiB
TypeScript
/**
|
|
* Covers only the polling contract of `BrowserHarness`, which every page
|
|
* harness inherits: a silent `null` where a predicate actually threw sends the
|
|
* caller hunting a phantom timeout. Lives in the browser project because the
|
|
* base class imports `vitest/browser`.
|
|
*/
|
|
import { describe, expect, it } from "vitest";
|
|
|
|
import { BrowserHarness } from "./browser-harness";
|
|
|
|
const QUIET_MS = 50;
|
|
|
|
/** Exposes the protected waiting helpers; no fixture or DOM is involved. */
|
|
class WaitingHarness extends BrowserHarness<null> {
|
|
constructor() {
|
|
super(null);
|
|
}
|
|
|
|
probe<T>(fn: () => T | null | undefined | false): Promise<T> {
|
|
return this.waitFor(fn, 200, "probe", 10);
|
|
}
|
|
|
|
probeOrNull<T>(fn: () => T | null | undefined | false): Promise<T | null> {
|
|
return this.waitForOrNull(fn, 200, "probe");
|
|
}
|
|
|
|
probeStable<T>(read: () => T): Promise<T> {
|
|
return this.waitForStable(read, QUIET_MS, 1000, "probe");
|
|
}
|
|
}
|
|
|
|
describe("BrowserHarness waiting helpers", () => {
|
|
it("resolves to null when the predicate only ever stays falsy", async () => {
|
|
const harness = new WaitingHarness();
|
|
|
|
await expect(harness.probeOrNull<string>(() => null)).resolves.toBeNull();
|
|
});
|
|
|
|
it("rejects with the predicate's error when it throws and then goes falsy", async () => {
|
|
const harness = new WaitingHarness();
|
|
const boom = new Error("predicate blew up");
|
|
let calls = 0;
|
|
|
|
// `vi.waitFor` polls past a throw and rejects with the *last* error, so the
|
|
// falsy polls would otherwise bury `boom` under the timeout sentinel.
|
|
await expect(
|
|
harness.probeOrNull<string>(() => {
|
|
calls += 1;
|
|
if (calls === 1) throw boom;
|
|
return null;
|
|
}),
|
|
).rejects.toBe(boom);
|
|
});
|
|
|
|
it("still polls through a transient throw", async () => {
|
|
const harness = new WaitingHarness();
|
|
let calls = 0;
|
|
|
|
await expect(
|
|
harness.probe(() => {
|
|
calls += 1;
|
|
if (calls === 1) throw new Error("transient");
|
|
return "ready";
|
|
}),
|
|
).resolves.toBe("ready");
|
|
});
|
|
|
|
it("resolves with a value only once it has held for the quiet window", async () => {
|
|
const harness = new WaitingHarness();
|
|
let reads = 0;
|
|
let settledAt = 0;
|
|
|
|
// Changes on each of the first reads, then holds at 4.
|
|
const settled = await harness.probeStable(() => {
|
|
reads += 1;
|
|
if (reads === 4) settledAt = performance.now();
|
|
return Math.min(reads, 4);
|
|
});
|
|
|
|
expect(settled).toBe(4);
|
|
expect(performance.now() - settledAt).toBeGreaterThanOrEqual(QUIET_MS);
|
|
});
|
|
});
|