supapup
Version:
⚡ Lightning-fast MCP browser dev tool. Navigate → Get instant structured data. No screenshots needed! Puppeteer: 📸 → CSS selectors → JS eval. Supapup: semantic IDs ready to use. 10x faster, 90% fewer tokens.
66 lines (65 loc) • 2.12 kB
JavaScript
/**
* Navigation and redirect monitoring
*/
export class NavigationMonitor {
/**
* Check if a navigation/redirect occurred
*/
static async checkForNavigation(page, originalUrl) {
const currentUrl = page.url();
const navigated = currentUrl !== originalUrl;
if (!navigated) {
return { navigated: false };
}
// Check for common captcha/sorry pages
const pageContent = await page.content();
const title = await page.title();
const captchaIndicators = [
'sorry/index',
'recaptcha',
'captcha',
'unusual traffic',
'automated requests',
'not a robot',
'verify you\'re human'
];
const isCaptcha = captchaIndicators.some(indicator => currentUrl.toLowerCase().includes(indicator) ||
pageContent.toLowerCase().includes(indicator) ||
title.toLowerCase().includes(indicator));
return {
navigated: true,
newUrl: currentUrl,
isRedirect: true,
isCaptcha
};
}
/**
* Wait for navigation with timeout
*/
static async waitForPossibleNavigation(page, action, options = {}) {
const { timeout = 5000, waitUntil = 'domcontentloaded' } = options;
try {
// Execute action and wait for navigation in parallel
const [actionResult, navigationResult] = await Promise.all([
action(),
// Wrap navigation promise to prevent listener leaks
new Promise((resolve) => {
page.waitForNavigation({ timeout, waitUntil })
.then(() => resolve(true))
.catch(() => resolve(null));
})
]);
return {
actionResult,
navigated: !!navigationResult
};
}
catch (error) {
return {
actionResult: null,
navigated: false,
error
};
}
}
}