fix(browser): capture selected events in popup pages (#600)
Selected page events from popups are retained even when popup lifecycle events are unselected; popup opened/closed events remain selection-controlled.
This commit is contained in:
parent
2919def828
commit
a3bf4a0944
|
|
@ -6,6 +6,42 @@ import { BrowserScenarioSecrets } from "./BrowserScenarioSecrets.js";
|
|||
import { PlaywrightScenarioEvents } from "./PlaywrightScenarioEvents.js";
|
||||
|
||||
describe("PlaywrightScenarioEvents", () => {
|
||||
it("observes requested popup page errors independently of popup lifecycle events", () => {
|
||||
const listeners = new Map<string, (value: unknown) => void>();
|
||||
const popupListeners = new Map<string, (value: unknown) => void>();
|
||||
const page = {
|
||||
on: (name: string, listener: (value: unknown) => void) => {
|
||||
listeners.set(name, listener);
|
||||
},
|
||||
} as unknown as Page;
|
||||
const popup = {
|
||||
url: () => "https://app.example.test/popup",
|
||||
on: (name: string, listener: (value: unknown) => void) => {
|
||||
popupListeners.set(name, listener);
|
||||
},
|
||||
} as unknown as Page;
|
||||
const scenario = browserScenarioSchema.parse({
|
||||
browser: { mode: "launch", executable_path: "/opt/chromium" },
|
||||
start_url: { url: "https://app.example.test/" },
|
||||
actions: [
|
||||
{ step_id: "wait", action: "wait_for_timeout", duration_ms: 1 },
|
||||
],
|
||||
capture: { events: ["page-errors"] },
|
||||
});
|
||||
const secrets = BrowserScenarioSecrets.resolve(scenario, {});
|
||||
if (secrets === undefined) throw new Error("Expected resolved secrets");
|
||||
const events = new PlaywrightScenarioEvents({
|
||||
page,
|
||||
enabled: new Set(["page-errors"]),
|
||||
secrets,
|
||||
});
|
||||
listeners.get("popup")?.(popup);
|
||||
popupListeners.get("pageerror")?.(new Error("popup application failure"));
|
||||
expect(events.result().items).toMatchObject([
|
||||
{ kind: "page-error", message: "popup application failure" },
|
||||
]);
|
||||
});
|
||||
|
||||
it("bounds oversized page errors before validating captured events", () => {
|
||||
const listeners = new Map<string, (value: Error) => void>();
|
||||
const page = {
|
||||
|
|
|
|||
|
|
@ -116,8 +116,10 @@ export class PlaywrightScenarioEvents {
|
|||
}
|
||||
if (this.enabled.has("workers"))
|
||||
page.on("worker", (worker) => this.worker(worker));
|
||||
if (this.enabled.has("popups"))
|
||||
page.on("popup", (popup) => this.popup(popup));
|
||||
// Every selectable event can also be emitted by a child popup page, and a
|
||||
// popup is only reachable through this one subscription, so any selection at
|
||||
// all must observe popups. Lifecycle events stay gated on `popups` below.
|
||||
if (this.enabled.size > 0) page.on("popup", (popup) => this.popup(popup));
|
||||
if (this.enabled.has("downloads"))
|
||||
page.on("download", (download) => this.download(download));
|
||||
}
|
||||
|
|
@ -243,14 +245,16 @@ export class PlaywrightScenarioEvents {
|
|||
url: page.url() === "" ? null : this.safeUrl(page.url()),
|
||||
name: null,
|
||||
};
|
||||
this.push({ kind: "popup-opened", ...opened });
|
||||
page.on("close", () =>
|
||||
this.push({
|
||||
kind: "popup-closed",
|
||||
url: page.url() === "" ? null : this.safeUrl(page.url()),
|
||||
name: null,
|
||||
}),
|
||||
);
|
||||
if (this.enabled.has("popups")) {
|
||||
this.push({ kind: "popup-opened", ...opened });
|
||||
page.on("close", () =>
|
||||
this.push({
|
||||
kind: "popup-closed",
|
||||
url: page.url() === "" ? null : this.safeUrl(page.url()),
|
||||
name: null,
|
||||
}),
|
||||
);
|
||||
}
|
||||
this.observePage(page);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue