Selenium:打开扩展程序的弹出窗口

时间:2018-04-20 13:58:28

标签: java selenium selenium-webdriver google-chrome-extension selenium-chromedriver

我正在尝试使用Selenium为我的扩展程序编写E2E测试。对于我的测试,我需要打开扩展程序的弹出页面 - 就好像用户点击了扩展程序的徽标(位于浏览器的右下角)。

我已经设法使用扩展程序启动ChromeDriver:

ChromeOptions options = new ChromeOptions();
options.addExtensions(new File("...\\dist.crx"));

这样打开浏览器(网络驱动程序),并根据需要安装它。但问题是,我不知何故需要打开弹出页面。

所以我想到了一个很好的解决方案,遗憾的是没有工作: 我设置了一个键盘快捷键来打开扩展程序(使用Google' s Command API)。问题是 - 它只能手动

手动选择的快捷方式(Ctrl + Shift + Y)根据需要打开扩展名。但是当使用Selenium将这些密钥发送到浏览器时,没有任何反应*

Actions actions = new Actions(webDriver);
actions.sendKeys(Keys.chord(Keys.CONTROL, Keys.SHIFT, "Y")).perform();

因此,如果这不起作用,我使用Java的机器人点击扩展名的图标,给它x,y偏移坐标。这个解决方案正在运行,但它非常难看并且不好,因为它不能在不同的屏幕上正确点击。我试图找到一个可以在所有屏幕尺寸上运行的全局解决方案。

提前致谢。

*当我以这种方式发送密钥时,其他操作对我来说效果很好(例如Control + A标记全部) - 所以我猜测问题不在于我发送密钥的方式。

澄清:我想在弹出页面(和后台脚本)与DOM本身(内容脚本)之间测试交互。这意味着我需要打开两个弹出页面,对其执行一些操作,然后在" real"上进行断言。网页的DOM。因此,只在全屏幕上打开弹出页面并不能让我能够编写我想要的所有E2E测试。

2 个答案:

答案 0 :(得分:1)

我解决这个问题的方法是直接打开页面。

换句话说,Chrome扩展程序中的所有页面都只是打包在包中的HTML页面。因此,您可以使用特制的URL直接打开它们。

第一步是找出您的包裹ID。它是一个独特的32个字符的字符串。此值派生自用于对包进行签名的密钥,因此它应该相当一致。找到这个值的最快方法是:

  1. 在安装了扩展程序的情况下打开Chrome
  2. 转到分机列表(菜单>更多工具>扩展程序)
  3. 在顶部确保"开发者模式"选中复选框
  4. 在列表中找到您的扩展程序,会有一个名为" ID的条目:"
  5. 复制此值
  6. 例如,云端硬盘的应用启动器是" ID:lmjegmlicamnimmfhcmpkclmigmmcbeh "

    了解此值意味着您现在可以访问包中的任何页面。

    String EXTENSION_PROTOCOL = "chrome-extension";
    String EXTENSION_ID = "lmjegmlicamnimmfhcmpkclmigmmcbeh";
    indexPage = EXTENSION_PROTOCOL + "://" + EXTENSION_ID + "/index.html";
    optionsPage = EXTENSION_PROTOCOL + "://" + EXTENSION_ID + "/options/options.html";
    
    driver.get(indexPage);
    

    这有一些缺点:

    • 它不会测试按钮本身
    • 页面始终全屏显示,因此您可能会遇到一些布局问题

    如果您可以解决这些问题,至少可以测试Chrome扩展程序的大部分功能。

答案 1 :(得分:1)

好的,我设法让这个工作。 我使用Java的机器人发送我设置的所需密钥来打开扩展(Control + Shift + Y),它工作,弹出窗口打开。 sendKeys没有工作,因为Selenium禁用了发送触发浏览器功能的键的功能,所以我认为这是一个不错的黑客。

import java.awt.*;
import java.awt.event.KeyEvent;

private void openExtension() throws AWTException {
    Robot robot = new Robot();

    robot.keyPress(KeyEvent.VK_CONTROL);
    robot.keyPress(KeyEvent.VK_SHIFT);
    robot.keyPress(KeyEvent.VK_Y);
}

编辑:当然,按下后释放这些键是个好主意(否则它们会保持按下状态)。所以最终的解决方案看起来像是:

    public void openExtension() {
    robotKeyPress(KeyEvent.VK_CONTROL, KeyEvent.VK_SHIFT, KeyEvent.VK_Y);
    robotKeyRelease(KeyEvent.VK_CONTROL, KeyEvent.VK_SHIFT, KeyEvent.VK_Y);
}

private void robotKeyPress(int... keys) {
    for (int k : keys) {
        robot.keyPress(k);
    }
}

private void robotKeyRelease(int... keys) {
    for (int k : keys) {
        robot.keyRelease(k);
    }
}