正如标题所述,page.click()的大多数情况下都可以工作。然而,有时,它点击而页面没有对操作做出React。有两种详细的情况:
- page.click()不工作并抛出错误。在这种情况下,我可以回退以正确评估单击。
- page.click()确实工作,它不会抛出错误。页面对单击没有React。在这种情况下,我不知道如何回退到另一个单击方法。
有一个轻微的机会,评估点击不工作,以及。因此,我认为最好的解决方案是回落到对方时,未能点击。这是我的代码:
async clickElement(
page: Page,
projectName: string,
title: string,
selector: string,
timeout = 1000,
preventNavigation = false
): Promise<boolean> {
Logger.log(selector, 'CSSClickStrategy.clickElement');
// Ensure the selector is present before proceeding
// it could be a navigation before awaiting the selector
await Promise.race([
page.waitForSelector(selector, { timeout, visible: true }),
page.waitForNavigation({ timeout }),
]);
//TODO: how to determine to switch between the two click methods
// Add navigation prevention if required
if (preventNavigation) {
this.preventNavigationOnElement(page, selector);
return this.evaluateClick(page, projectName, title, selector);
} else {
// const result = await this.normalClick(page, projectName, title, selector);
const result = await this.evaluateClick(
page,
projectName,
title,
selector
);
if (!result) {
// return await this.evaluateClick(page, projectName, title, selector);
return await this.normalClick(page, projectName, title, selector);
} else {
return result;
}
}
}
private async preventNavigationOnElement(page: Page, selector: string) {
await page.evaluate((sel) => {
const element = document.querySelector(sel);
if (element) {
element.addEventListener('click', (e) => e.preventDefault());
}
}, selector);
}
private async evaluateClick(
page: Page,
projectName: string,
title: string,
selector: string,
timeout = 10000
): Promise<boolean> {
try {
await Promise.race([
page.evaluate((sel) => {
const element = document.querySelector(sel) as HTMLElement;
element?.click();
}, selector),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout exceeded')), timeout)
),
]);
Logger.log(
`Clicked using page.evaluate for selector: ${selector}`,
'CSSClickStrategy.clickElement'
);
return true;
} catch (error) {
Logger.error(error.message, 'CSSClickStrategy.evaluateClick');
return false;
}
}
private async normalClick(
page: Page,
projectName: string,
title: string,
selector: string,
timeout = 10000
): Promise<boolean> {
try {
await Promise.race([
page.click(selector, { delay: 100 }),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout exceeded')), timeout)
),
]);
Logger.log(
`Clicked using page.click for selector: ${selector}`,
'CSSClickStrategy.clickElement'
);
return true;
} catch (error) {
Logger.error(error.message, 'CSSClickStrategy.clickElement');
return false;
}
}
字符串
任何帮助都非常感谢。
1条答案
按热度按时间ia2d9nvy1#
我已经找到了一种基于某些条件的相互退回的方法。例如,我发现大多数时候评估点击都可以工作,但在第三方电子商务支付网关上不行。因此,我page.click在支付页面上使用www.example.com()。否则,默认使用评估点击。另一个发现是,在隐身上下文下有一个标签,evaluate单击不能正常工作。下面是我的解决方案代码,基于条件,并在遇到错误时相互回退:
字符串
以下是我的启动设置以供参考:
型