繁体   English   中英

如何处理 Selenium 中的打印对话框?

[英]How to handle print dialog in Selenium?

我必须处理打印对话框(与在浏览器中单击 ctrl-p 时出现的对话框相同)。 我试过:

Alert printDialog = driver.switchTo().alert();
printDialog.dismiss();

但它没有用。 我也无法抓住它的窗口句柄,因为它不是一个窗口......

是否可以处理这些对象以及如何处理?

不幸的是,WebDriver 无法处理这些(或任何其他浏览器或操作系统对话框)。 此外,它们在浏览器/系统/语言设置中的外观往往不同,因此可能没有明确的答案。 您需要检测并处理每一种可能的情况,以使其在任何地方都能正常工作。 您的选择包括:

  • Robot类,它允许您以编程方式“按下”键盘上的任何内容(或盲目单击),因此通过按EnterEsc来摆脱对话框。 然而,如上所述,任何高级交互都取决于操作系统/语言/打印机。

     // press Escape programatically - the print dialog must have focus, obviously Robot r = new Robot(); r.keyPress(KeyEvent.VK_ESCAPE); r.keyRelease(KeyEvent.VK_ESCAPE);
  • 自动化 它是一个 Windows 程序,可用于处理任何系统级自动化。 与上述相同的依赖关系。

差不多就是这样。 如果您可以避免打印对话框,请尝试截取页面的屏幕截图并使用标准 Java 工具打印它。

一个可以在 Chrome 中使用 Selenium 处理打印对话框。 不确定其他浏览器。

在 ChromeDriver-2.17 中添加了对打印对话框的访问。 可以在这里找到详细信息: https ://bugs.chromium.org/p/chromedriver/issues/detail?id=1087

右键单击“打印对话框”->“检查元素”。 因此,打印对话框的 DOM 将在单独的窗口中打开。 现在您可以为对话框中的任何元素生成定位器并在您的测试中使用它们。

要关闭“打印”对话框,可以执行以下操作:

//Switch to Print dialog
Set<String> windowHandles = driver.getWindowHandles();
if (!windowHandles.isEmpty()) {
    driver.switchTo().window((String) windowHandles.toArray()[windowHandles.size() - 1]);
}
//Now work with the dialog as with an ordinary page:  
driver.findElement(By.className("cancel")).click();

我能够通过添加完全绕过打印对话框的--kiosk-printing来解决这个问题。 我将我的默认打印设置为 pdf,所以我最终在我的下载文件夹中得到了一个 pdf,但至少 selenium 没有挂起。 代码如下所示:

        ChromeOptions cOptions = new ChromeOptions();
        cOptions.addArguments("kiosk-printing");
        RemoteWebDriver driver = new RemoteWebDriver(hostUrl, cOptions);

Slanec 的回答是正确的——WebDriver 没有这方面的本机功能。 我在 Windows 中解决这个问题的方法是使用 System.Windows.Forms.SendKeys 对象:

    SendKeys.SendWait("^p");
    System.Threading.Thread.Sleep(500);
    SendKeys.SendWait("~");

    // give it a minute to spool onto the printer
    System.Threading.Thread.Sleep(5000);

我实际上已经在循环中打印了一堆语句。 奇迹般有效。

出现打印对话框后,您只需关闭浏览器即可。 诚然,这是一个有点过激的措施,但优点是:

  • 很简单
  • 它不需要任何外部工具
  • 它适用于操作系统和浏览器

只需致电:

myWebDriver.quit();

通常,您会运行测试,并照常检查要打印的页面上的元素。 即使打印对话框打开,WebDriver 也可以检查页面元素。

完成后,退出浏览器(并为下一次测试启动一个新浏览器)。


我们已经在一个项目中成功地使用了它。 为了使事情变得更容易,我们编写了一个包装类来跟踪“当前 WebDriver 实例”。 我有方法来检索这个实例(根据需要创建一个)并关闭它。 这样,您始终可以调用getCurrentWebDriver()并获取有效实例(重复使用或新创建的)。

另一种选择是为 Chrome 编辑 Windows 注册表以禁用打印窗口。

--disable-print-preview - 告诉 Chrome 禁用打印预览的标志

  1. 转到注册表编辑器
  2. 导航到“Computer\HKEY_CLASSES_ROOT\ChromeBHTML\shell\open\command”
  3. 将值设置为:"C:\Program Files (x86)\Google\Chrome Beta\Application\chrome.exe" --disable-print-preview

该解决方案适用于我的具体案例。

使用带有 Codeception 的 Selenium 和 Facebook WebDriver,我遇到了同样的问题——测试场景将停止运行,因为打印对话框阻止了与页面的任何交互。

我最终没有在test环境中打开打印对话框(使用 Symfony 和 Twig 的示例):

{# Selenium can't interact with the OS native print dialog. #}
{# Therefore, it's disabled in the test environment. #}
{% if app.environment != 'test' %}
    $(document).ready(function () {
        var orderShouldBePrinted = window.location.href.indexOf(
            'print=true'
        ) !== -1;

        if (orderShouldBePrinted) {
            window.print();
        }
    });
{% endif %}

这具有不停止测试的优点。 但是,它不允许测试打印对话框是否实际出现。

作为冒烟测试,我添加了$I->seeInCurrentUrl('print=true'); (因为此 URL 参数触发window.print() )。

我试图从不允许“全部打印”的网站上的图案列表中打印 100 多页。 所以硒在理论上会自动帮助我。 我想出了一个完全非正统的打印对话框窗口解决方案。

##Python code
import time
import threading
from pynput.mouse import Button, Controller
mouse = Controller()

##selenium starting up website stuff here

def website_print_button():
    browser.find_element_by_id('printButton').click()

def push():
    time.sleep(4)    #4 second delay to give the computer time to open print dialog
    mouse.position = [1131, 733] #where my print button is located
    mouse.click(Button.left, 1)

def letsgo():

    for x in range(printing_amount):
        browser.find_element_by_xpath('/html/body/div[1]/form/table[4]/tbody/tr['+str(x+1)+']/td[1]/a/b').click()
        browser.find_element_by_css_selector('ul.light-green.button').click()
        browser.switch_to.window(browser.window_handles[1])
        t2 = threading.Thread(target=push)
        t2.start()
        t1 = threading.Thread(target=website_print_button)
        t1.start()
        time.sleep(5)
        browser.close()
        browser.switch_to.window(browser.window_handles[0])
        browser.find_element_by_class_name('c').click()

当打印对话窗口打开时,Selenium 通常会卡住等待发生某些事情。 我使用了我最近学到的称为“线程”的东西,这让我在技术上可以同时做两件事。 我会要求点击在 4 秒内启动(推送功能),然后 Selenium 会立即点击网站打印按钮。 当 Selenium 打开打印对话框窗口时,它卡住了等待,但延迟点击仍在运行,并在 selenium 打开打印窗口 4 秒后等待点击。 然后单击将执行,并且 selenium 重新控制,因为打印窗口已得到处理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM