@coinbase/onchaintestkit
Version:
End-to-end testing toolkit for blockchain applications, powered by Playwright
56 lines (55 loc) • 2.46 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.waitForPage = waitForPage;
const LoadingStateDetector_1 = require("./LoadingStateDetector");
/**
* Generic utility to wait for and configure a page by URL.
*
* Uses a dual strategy to handle the TOCTOU race condition where a page
* opens between the context.pages() check and the waitForEvent listener:
* 1. Check context.pages() for an existing matching page
* 2. If not found, race waitForEvent('page') against polling
*
* @param context - Browser context to search for pages
* @param pageUrl - Partial URL to match (e.g., 'notification.html')
* @param viewport - Optional viewport size
* @returns Promise that resolves to the found and configured page
*/
async function waitForPage(context, pageUrl, viewport) {
const isLiveTargetPage = (page) => !page.isClosed() && page.url().includes(pageUrl);
// Check existing pages first, skipping any that are already closed
let targetPage = context.pages().find(isLiveTargetPage);
if (!targetPage) {
// Race two strategies:
// 1. waitForEvent('page') — catches pages that open after this point
// 2. Polling context.pages() — catches pages that opened during the
// gap between the check above and the event listener setup
targetPage = await Promise.race([
context.waitForEvent("page", {
predicate: (p) => p.url().includes(pageUrl),
}),
new Promise(resolve => {
const poll = () => {
const found = context.pages().find(isLiveTargetPage);
if (found)
resolve(found);
else
setTimeout(poll, 300);
};
setTimeout(poll, 300);
}),
]);
}
await targetPage.waitForLoadState("domcontentloaded");
if (viewport) {
await targetPage.setViewportSize(viewport);
}
// Only run loading detection if the page is still open. Extension popup
// pages (like MetaMask notifications) can close at any time, and running
// expensive selector checks on a closed page wastes time and causes
// cascading "Target page closed" errors on CI.
if (!targetPage.isClosed()) {
await LoadingStateDetector_1.LoadingStateDetector.waitForPageLoadingComplete(targetPage, 10000);
}
return targetPage;
}