我的Selenium测试看起来像这样:客户选择一种金融产品,填写一些必要的数据,并在打印预览中显示条款/协议文件(根据当地法律的要求)。在打印/关闭打印预览对话框后,客户输入更多数据并继续进行操作,选择一些选项,最后获得合同的另一个打印预览。之后,他确认合同和流程已完成。我针对Chrome 75版进行了测试。
到目前为止,我已经尝试了两种方法: 1.使用Selenium切换到打印预览,通过DOM导航到“取消”按钮,然后单击它。但是,由于对话框使用的是影子DOM,因此非常难看,难以维护,并且在Chrome更新后经常会中断。 2.使用awt的Robot类进行了尝试,它在本地运行时效果很好,但在Selenium网格上运行时却失败了,因为Chrome窗口未聚焦并且不接收键盘事件。
处理关闭打印对话框的方法的当前状态:
public void closePrintPreview() {
WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(driver -> driver.getWindowHandles().size() > 1);
driver.switchTo().window(driver.getWindowHandles().toArray()[1].toString());
wait.until(d -> {
if (d.getWindowHandles().size() > 1) {
d.switchTo().window(driver.getWindowHandles().toArray()[1].toString());
try {
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_ESCAPE);
robot.keyRelease(KeyEvent.VK_ESCAPE);
} catch (AWTException e) {
throw new RuntimeException(e);
}
return false;
}
return true;
});
driver.switchTo().window(driver.getWindowHandles().toArray()[0].toString());
}
所以我的问题是,是否有一种更简单的方法可以在打印打印预览中获得“取消”按钮,或者是否可以通过某种方式强制将Chrome窗口聚焦,以便它可以接收来自机器人的关键事件?
答案 0 :(得分:1)
这是python中的解决方案。
您可以将其更新为在Java中工作。
Python:
def cancelPrintPreview():
# get the current time and add 180 seconds to wait for the print preview cancel button
endTime = time.time() + 180
# switch to print preview window
driver.switch_to.window(driver.window_handles[-1])
while True:
try:
# get the cancel button
cancelButton = driver.execute_script(
"return document.querySelector('print-preview-app').shadowRoot.querySelector('#sidebar').shadowRoot.querySelector('print-preview-header#header').shadowRoot.querySelector('paper-button.cancel-button')")
if cancelButton:
# click on cancel
cancelButton.click()
# switch back to main window
driver.switch_to.window(driver.window_handles[0])
return True
except:
pass
time.sleep(1)
if time.time() > endTime:
driver.switch_to.window(driver.window_handles[0])
break
Java:
public void closePrintPreview() {
String jsCancel = "return document.querySelector('print-preview-app')" +
".shadowRoot.querySelector('#sidebar')" +
".shadowRoot.querySelector('print-preview-header#header')" +
".shadowRoot.querySelector('paper-button.cancel-button')";
WebDriverWait wait = new WebDriverWait(driver, 5);
JavascriptExecutor jse = (JavascriptExecutor) driver;
WebElement cancelButton;
wait.until(driver -> driver.getWindowHandles().size() > 1);
driver.switchTo().window(driver.getWindowHandles().toArray(new String[0])[1]);
while (driver.getWindowHandles().size() > 1) {
driver.switchTo().window(driver.getWindowHandles().toArray(new String[0])[1]);
cancelButton = (WebElement) jse.executeScript(jsCancel);
cancelButton.click();
}
driver.switchTo().window(driver.getWindowHandles().toArray(new String[0])[0]);
}
您可以查看我的答案here,以获得有关使用阴影根元素的更多信息。
答案 1 :(得分:0)
这是基于@supputuri的答案的Java实现:
public void closePrintPreview() {
String jsCancel = "return document.querySelector('print-preview-app')" +
".shadowRoot.querySelector('#sidebar')" +
".shadowRoot.querySelector('print-preview-header#header')" +
".shadowRoot.querySelector('paper-button.cancel-button')";
WebDriverWait wait = new WebDriverWait(driver, 5);
JavascriptExecutor jse = (JavascriptExecutor) driver;
WebElement cancelButton;
wait.until(driver -> driver.getWindowHandles().size() > 1);
driver.switchTo().window(driver.getWindowHandles().toArray(new String[0])[1]);
while (driver.getWindowHandles().size() > 1) {
driver.switchTo().window(driver.getWindowHandles().toArray(new String[0])[1]);
cancelButton = (WebElement) jse.executeScript(jsCancel);
cancelButton.click();
}
driver.switchTo().window(driver.getWindowHandles().toArray(new String[0])[0]);
}