在 selenium 节点(网格环境)上上传文件,其中上传按钮不是 input(type='file')

Upload File on selenium node (grid environment) , where in upload button is not of input(type='file')

我有一个页面,导入按钮看起来像这样。

Dom 上面导入按钮的结构如下

<button ngf-select="" ng-model="$parent.enduserMashups.files" class="btn btn-default text-center ng-pristine ng-untouched ng-valid ng-empty">
    <i class="icon-import-data"></i>
    <span>Import</span></button>

我已经编写了如下的 selenium 上传实用程序,它在非网格环境(本地机器)的情况下工作正常

public void uploadFile(String filePath)
    {
    // Setting up clipBoard location
    StringSelection ss = new StringSelection(filePath);
    Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, null);

    // Using Robot class to upload file
    Robot robot;
    try
    {
        robot = new Robot();
        try
        {
            Thread.sleep(1000);
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        // Press Enter
         robot.keyPress(KeyEvent.VK_ENTER);

        // Release Enter
         robot.keyRelease(KeyEvent.VK_ENTER);

          // Press CTRL+V
         robot.keyPress(KeyEvent.VK_CONTROL);
         robot.keyPress(KeyEvent.VK_V);

        // Release CTRL+V
         robot.keyRelease(KeyEvent.VK_CONTROL);
         robot.keyRelease(KeyEvent.VK_V);
         try
            {
                Thread.sleep(1000);
            } catch (InterruptedException e)
            {
                e.printStackTrace();
            };

        // Press Enter 
         robot.keyPress(KeyEvent.VK_ENTER);
         robot.keyRelease(KeyEvent.VK_ENTER);


    } catch (AWTException e)
    {
        e.printStackTrace();
    }

}

如果 运行 上面的代码是在 selenium 网格节点环境中,'import' 按钮在节点浏览器实例上被点击并且在这里它没有找到文件(很明显),因为它被保存在测试用例为 运行 的另一台机器上。 谷歌搜索了很多,我发现了一些解决方案,其中指出在有按钮的情况下,我们可以使用 webdriver.sendKeys(file) 方法,该方法直接将文件发送到 selenium 节点,但这仅适用于标签。

没有元素怎么办?

以下是解决问题的方法。

  1. 您需要构建一个自定义 servlet,该 servlet 定义了 POST/GET 方法并且可用于触发文件上传。 (有关示例,请参见 here)。您还需要确保此 servlet 将 return 返回文件被接受后保存位置的绝对文件路径。
  2. 您现在将新构建的自定义 servlet 注入网格节点(请参阅 here 了解如何操作)
  3. 与 (1) 和 (2) 类似,您使用 GET/POST 操作构建另一个 servlet,调用该操作时可以在内部调用您的 uploadFile() 方法。 [您基本上会传递通过调用 (1) 中解释的 servlet 获得的文件路径
  4. 您参考了我的 this 博客 post 以了解如何找出网格将您的测试路由到哪里,并使用我已经解释过的机制检索您的 IP 和端口您的测试路由到的节点。
  5. 使用从 (4) 中获取的 IP 和端口号,您首先调用上传文件 servlet,首先将您的文件上传到节点所在的远程计算机 运行 并取回保存文件的绝对文件来自 servlet 的路径。
  6. 您现在通过从 (5) 传递绝对文件路径来调用包含 uploadFile() 方法并由 ROBOT API 驱动的其他 servlet,并让它在远程主机上使用 ROBOT 执行上传操作。

这应该可以解决问题。