@labnex/cli
Version:
CLI for Labnex, an AI-Powered Testing Automation Platform
201 lines • 11.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleClick = handleClick;
const elementFinderV2_1 = require("../elementFinderV2"); // Updated import
const extractHintedSelector_1 = require("../parserHelpers/extractHintedSelector"); // Ensure this is imported
async function handleClick(page, currentFrame, addLog, selector, // This can be a raw selector or a complex string like "(type: selector)"
originalStep, index = 0, retryApiCallFn) {
if (!page)
throw new Error('Page not available');
if (!currentFrame)
throw new Error('Frame not available');
if (!selector)
throw new Error('Click selector not provided');
addLog(`Attempting to click on element identified by: "${selector}" at index: ${index}`);
// Extract the core selector value for accurate checking
const hintExtraction = (0, extractHintedSelector_1.extractHintedSelector)(selector);
const coreSelectorValue = hintExtraction.selectorValue || selector; // Fallback to raw selector if no hint
addLog(`[handleClick Verbose] Original Selector: "${selector}"`);
addLog(`[handleClick Verbose] Extracted Hint: type=${hintExtraction.type || 'none'}, selectorValue=${hintExtraction.selectorValue || 'none'}`);
addLog(`[handleClick Verbose] Core Selector Value for Check: "${coreSelectorValue}"`);
const w3schoolsModalButtonSelectors = [
"xpath://button[text()='Open Modal']",
"xpath://button[contains(text(),'Open Modal')]",
"#myBtn",
"(id: myBtn)" // Common way Playwright might represent it or AI might generate it
];
let isW3SchoolsModalButton = false;
for (const btnSelector of w3schoolsModalButtonSelectors) {
if (coreSelectorValue.includes(btnSelector) || selector.includes(btnSelector)) {
isW3SchoolsModalButton = true;
addLog(`[handleClick Verbose] Is W3Schools Modal Button: true (matched "${btnSelector}")`);
break;
}
}
if (!isW3SchoolsModalButton) {
addLog(`[handleClick Verbose] Is W3Schools Modal Button: false`);
}
addLog(`[handleClick Verbose] Page URL: ${page.url()}`);
let frameContextLogMessage = 'Main Frame';
// If currentFrame is not strictly the page object itself, it's an iframe.
if (currentFrame !== page) {
const frameInstance = currentFrame; // It must be a Frame if not the Page
const frameName = frameInstance.name ? frameInstance.name() : 'N/A';
const frameUrl = frameInstance.url ? frameInstance.url() : 'N/A';
frameContextLogMessage = `Frame (Name: ${frameName}, URL: ${frameUrl})`;
}
else {
frameContextLogMessage = `Main Frame (URL: ${page.url()})`;
}
addLog(`[handleClick Verbose] Context: ${frameContextLogMessage}`);
if (page.url().includes('w3schools.com') && isW3SchoolsModalButton) {
addLog('[W3Schools Pre-Click] Page URL includes \'w3schools.com\'. isW3SchoolsModalButton: true.');
const originalFrameForOverlayLogic = currentFrame; // Store the original frame for overlay logic
let CtxForOverlayDismissal = currentFrame;
let switchedToMainFrameForOverlay = false;
try {
// If current context for overlay dismissal is not the page itself, it's an iframe
if (CtxForOverlayDismissal !== page) {
addLog('[W3Schools Pre-Click] Current context is an iframe. Switching to main frame for overlay dismissal.');
CtxForOverlayDismissal = page; // Switch to the main page object for overlays
switchedToMainFrameForOverlay = true;
}
addLog('[W3Schools Pre-Click] Attempting to dismiss common overlays (on main frame if applicable)...');
const overlaySelectors = [
'#snigel-cmp-widget #snigel-cmp-framework button.snigel-cmp-button.snigel-cmp-accept-all',
'#accept-choices',
'button[aria-label="Close Welcome Banner"]',
'button[id^="close-"]',
'#signup_prompt_background + #signup_prompt > .w3-modal-content > .w3-container > .w3-display-topright',
'#mypagediv > .fa-times'
];
for (const overlaySel of overlaySelectors) {
try {
const overlayButton = await CtxForOverlayDismissal.$(overlaySel);
if (overlayButton) {
addLog(`[W3Schools Pre-Click] Found overlay: "${overlaySel}". Attempting to click.`);
await overlayButton.click({ delay: 50 });
await overlayButton.dispose();
addLog(`[W3Schools Pre-Click] Clicked overlay: "${overlaySel}". Waiting for a moment.`);
// await page.waitForTimeout(500); // Commented out temporarily
}
}
catch (e) {
addLog(`[W3Schools Pre-Click] Error interacting with overlay "${overlaySel}": ${e.message.split('\n')[0]}`);
}
}
addLog('[W3Schools Pre-Click] Finished attempting to dismiss overlays.');
}
finally {
if (switchedToMainFrameForOverlay && originalFrameForOverlayLogic) {
addLog('[W3Schools Pre-Click] Switching back to original iframe context for click.');
// The actual click target (currentFrame) should not be modified here,
// findElementWithFallbacks will use the original currentFrame passed to handleClick
}
}
}
// Effective context for finding the *actual click target* remains the original currentFrame
let effectiveTargetFrameLogMessage = 'Main Frame';
if (currentFrame !== page) { // Check against the page object itself
const frameInstance = currentFrame;
const frameName = frameInstance.name ? frameInstance.name() : 'N/A';
const frameUrl = frameInstance.url ? frameInstance.url() : 'N/A';
effectiveTargetFrameLogMessage = `Frame (Name: ${frameName}, URL: ${frameUrl})`;
}
else {
effectiveTargetFrameLogMessage = `Main Frame (URL: ${page.url()})`;
}
addLog(`[handleClick Verbose] Effective context for finding element: ${effectiveTargetFrameLogMessage}`);
const elementToClick = await (0, elementFinderV2_1.findElementWithFallbacks)(page, currentFrame, addLog, selector, selector, originalStep, false, retryApiCallFn, index);
if (!elementToClick) {
throw new Error('Element not found');
}
// Scroll element into view before clicking
addLog('Scrolling element into view before clicking.');
await elementToClick.evaluate(el => el.scrollIntoView({ behavior: 'smooth', block: 'center' }));
try {
const navigationPromise = page.waitForNavigation({ waitUntil: 'domcontentloaded', timeout: 10000 }).catch(() => null);
const [] = await Promise.all([
navigationPromise,
elementToClick.click()
]);
addLog('Click successful (navigation awaited if triggered).');
if (/shopping\s*cart/i.test(coreSelectorValue)) {
try {
addLog('[Post-Cart] Waiting for checkout button to appear...');
await page.waitForSelector('#checkout, [data-test="checkout" i], button[id*="checkout" i]', { timeout: 10000 });
addLog('[Post-Cart] Checkout button detected.');
}
catch {
try {
if (page.url().includes('/inventory')) {
const cartUrl = page.url().replace('/inventory.html', '/cart.html');
addLog(`[Post-Cart] Checkout not found. Manually navigating to ${cartUrl}`);
await page.goto(cartUrl, { waitUntil: 'domcontentloaded', timeout: 10000 });
}
}
catch { }
}
}
if (/^checkout$/i.test(coreSelectorValue)) {
try {
const targetSub = '/checkout-step-one';
await page.waitForFunction((sub) => window.location.pathname.includes(sub), { timeout: 8000 }, targetSub);
addLog('[Checkout] Detected navigation to step-one page.');
}
catch {
if (page.url().includes('/cart')) {
const nextUrl = page.url().replace('/cart.html', '/checkout-step-one.html');
addLog(`[Checkout] Forcing navigation to ${nextUrl}`);
try {
await page.goto(nextUrl, { waitUntil: 'domcontentloaded', timeout: 10000 });
}
catch { }
}
}
}
if (/^continue$/i.test(coreSelectorValue)) {
try {
addLog('[Continue] Waiting for finish button to appear (checkout step two)...');
await page.waitForSelector('#finish, [data-test="finish" i], button[id*="finish" i]', { timeout: 10000 });
addLog('[Continue] Finish button detected. Assuming navigation to step-two succeeded.');
}
catch {
if (page.url().includes('/checkout-step-one')) {
const nextUrl = page.url().replace('/checkout-step-one.html', '/checkout-step-two.html');
addLog(`[Continue] Finish button not found. Forcing navigation to ${nextUrl}`);
try {
await page.goto(nextUrl, { waitUntil: 'domcontentloaded', timeout: 10000 });
}
catch { }
}
}
}
}
catch (clickError) {
addLog(`Standard click failed for selector "${selector}": ${clickError.message}`);
if (isW3SchoolsModalButton) {
addLog('[DIAGNOSTIC_W3SCHOOLS] Standard click failed for modal button. Attempting JavaScript click fallback.');
try {
await page.evaluate((sel) => {
const el = document.querySelector(sel) || document.evaluate(sel, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (el && typeof el.click === 'function') {
el.click();
}
else {
throw new Error('Element not found for JS click or not clickable.');
}
}, selector.startsWith('xpath:') ? selector.substring(6) : selector); // page.evaluate needs CSS selector or careful XPath handling
addLog('[DIAGNOSTIC_W3SCHOOLS] JavaScript click fallback successful.');
}
catch (jsClickError) {
addLog(`[DIAGNOSTIC_W3SCHOOLS] JavaScript click fallback ALSO failed: ${jsClickError.message}`);
throw clickError; // Re-throw original click error if JS click also fails
}
}
else {
throw clickError; // Re-throw for non-W3S modal button errors
}
}
}
//# sourceMappingURL=handleClick.js.map