UNPKG

@labnex/cli

Version:

CLI for Labnex, an AI-Powered Testing Automation Platform

138 lines 7.12 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.handleNavigate = handleNavigate; async function handleNavigate(page, currentFrame, // Though navigate resets to page, keep for consistency addLog, url) { if (!page) throw new Error('Page not available'); let newCurrentFrame = page; // Initialize with page // Navigation always happens on the main page, so reset context first newCurrentFrame = page; if (!url) throw new Error('Navigation URL not provided'); // Validate URL try { const parsedUrl = new URL(url); if (!['http:', 'https:'].includes(parsedUrl.protocol)) { throw new Error('Invalid URL protocol. Only http and https are allowed.'); } } catch (e) { throw new Error(`Invalid URL for navigation: ${url}. ${e.message}`); } if (/\/login\/the$/i.test(url)) { const fixed = url.replace(/\/login\/the$/i, '/login'); addLog(`[AutoRedirect] Detected likely typo in URL, rewriting ${url}${fixed}`); url = fixed; } addLog(`Navigating to ${url}`); const navigationOptions = { waitUntil: 'domcontentloaded', timeout: 60000 // Default timeout }; if (url.includes('w3schools.com/jsref/tryit.asp') || url.includes('w3schools.com/code/tryit.asp')) { addLog('[W3Schools Tryit Specific] Using "networkidle0" event and extended timeout for tryit page.'); navigationOptions.waitUntil = 'networkidle0'; navigationOptions.timeout = 120000; // Extended timeout for networkidle0 to 120 seconds } // Add more detailed error listeners for navigation const pageErrorHandler = (error) => addLog(`[Navigation Page Error] ${error.message}`); const requestFailedHandler = (request) => { if (request.failure() && request.failure().errorText !== 'net::ERR_ABORTED') { addLog(`[Navigation Request Failed] URL: ${request.url()}, Error: ${request.failure().errorText}`); } }; if (page) { page.on('pageerror', pageErrorHandler); page.on('requestfailed', requestFailedHandler); } try { const response = await page.goto(url, navigationOptions); if (response && response.status() === 404 && /\/login\/[^\/]+$/i.test(url)) { const correctedUrl = url.replace(/\/login\/[^\/]+$/i, '/login'); if (correctedUrl !== url) { addLog(`[AutoRedirect] Original URL returned 404. Retrying with ${correctedUrl}`); await page.goto(correctedUrl, navigationOptions); } } addLog(`Navigation to ${url} complete (${navigationOptions.waitUntil} event fired).`); // Post-navigation check for tryit.asp pages to ensure page is responsive if (url.includes('w3schools.com/jsref/tryit.asp') || url.includes('w3schools.com/code/tryit.asp')) { addLog('[W3Schools Tryit Specific] Performing post-navigation responsiveness check...'); try { await page.evaluate(() => 1 === 1); // Simple evaluation to check if page context is alive addLog('[W3Schools Tryit Specific] Page is responsive after navigation.'); // Attempt to close login/signup prompt specifically for tryit pages const closeLoginPromptSelector = '#mypagediv > .fa-times'; const loginPromptCloseButton = await page.$(closeLoginPromptSelector); if (loginPromptCloseButton) { const isVisible = await loginPromptCloseButton.isIntersectingViewport(); if (isVisible) { addLog(`[W3Schools Tryit Specific] Found login/signup prompt close button: ${closeLoginPromptSelector}. Clicking it.`); await loginPromptCloseButton.click(); await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for it to disappear addLog('[W3Schools Tryit Specific] Clicked login/signup prompt close button.'); } else { addLog(`[W3Schools Tryit Specific] Login/signup prompt close button ${closeLoginPromptSelector} found but not visible.`); } } else { addLog('[W3Schools Tryit Specific] Login/signup prompt close button not found.'); } } catch (evalError) { addLog(`[W3Schools Tryit Specific] Page responsiveness check failed or login prompt closure error: ${evalError.message}`); // Potentially re-throw or handle as a navigation failure if this is critical } } } catch (e) { addLog(`Error during page.goto or post-navigation checks: ${e.message}`); throw e; // Re-throw the error after logging } finally { if (page) { page.off('pageerror', pageErrorHandler); page.off('requestfailed', requestFailedHandler); } } addLog(`Navigation to ${url} complete (${navigationOptions.waitUntil} event fired). Attempting to dismiss potential cookie/consent banners.`); // Attempt to find and click common consent buttons const consentSelectors = [ 'div#snigel-cmp-framework button.accept-choices-button', // More specific Snigel v2 button '#snigel-cmp-widget #snigel-cmp-framework button.snigel-cmp-button.snigel-cmp-accept-all', // Cookie consent (seen 2024) '#accept-choices', // Another cookie consent button 'button[aria-label="Close Welcome Banner"]', // Welcome banner 'button[data-testid="dialog-close"]', // Common test id for close buttons 'button[aria-label="dismiss cookie message"]' // Another common aria label ]; let clickedConsentButton = false; for (const selector of consentSelectors) { try { const button = await page.waitForSelector(selector, { visible: true, timeout: 2000 }); if (button) { addLog(`Found potential consent button with selector: "${selector}". Attempting to click.`); await button.click({ delay: 100 }); await button.dispose(); addLog(`Clicked consent button. Waiting a moment for banner to disappear...`); await new Promise(resolve => setTimeout(resolve, 1500)); clickedConsentButton = true; break; } } catch (error) { // Not logging every miss to avoid spam } } if (clickedConsentButton) { addLog('A consent button was clicked. Page should be clearer now.'); } else { addLog('No common consent buttons found or clicked. Continuing...'); } addLog('Adding a short delay for page stabilization after navigation and consent checks.'); await new Promise(resolve => setTimeout(resolve, 1500)); // 1.5-second delay return newCurrentFrame; // Return the page as the new current context } //# sourceMappingURL=handleNavigate.js.map