【问题标题】:How to handle windows file upload using Selenium WebDriver?如何使用 Selenium WebDriver 处理 Windows 文件上传?
【发布时间】:2012-06-30 16:29:01
【问题描述】:

我在 Stack Overflow 上看到了很多关于使用 Selenium WebDriver 上传文件的问题和解决方案。但是它们都不适用于以下场景。

有人给出了如下解决方案

// assuming driver is a healthy WebDriver instance
WebElement fileInput = driver.findElement(By.name("uploadfile"));
fileInput.sendKeys("C:/path/to/file.jpg");

但我还是找不到窗口句柄。我该如何处理?

我正在为上述情况寻找解决方案。

请在以下任何网站上查看。

http://www.uploadify.com/demos/
http://www.zamzar.com/

【问题讨论】:

  • 那么你尝试过你写的吗?如果你做了你写了什么,错误是什么?
  • 这是处理 winwods 弹出窗口的假设
  • 我只是想问一下,您是否尝试过这种方法?
  • 您找到元素 ID 并将密钥(“路径/到/文件”)发送到该 Web 元素了吗?
  • 我们可以发送密钥,因为我们正在将它发送到 web 元素“uploadfile”。请注意,没有为要显示的弹出窗口执行click 操作。你会知道如果你会尝试。 :)

标签: java selenium file-upload selenium-webdriver webdriver


【解决方案1】:
// assuming driver is a healthy WebDriver instance
WebElement fileInput = driver.findElement(By.name("uploadfile"));
fileInput.sendKeys("C:/path/to/file.jpg");

嘿,那是我从某个地方传来的 :)。


如果是 Zamzar 网络,它应该可以完美运行。您不要点击该元素。您只需输入路径即可。具体来说,这应该是完全可以的:

driver.findElement(By.id("inputFile")).sendKeys("C:/path/to/file.jpg");

对于 Uploadify 网络,您处于困境中,因为上传的东西不是input,而是一个 Flash 对象。没有用于 WebDriver 的 API 可让您使用浏览器对话框(或 Flash 对象)。

因此,在您单击 Flash 元素后,会弹出一个您无法控制的窗口。在我所知道的浏览器和操作系统中,您几乎可以假设在打开窗口后,光标位于File name 输入中。请确保这个假设在您的情况下也是正确的。

如果没有,您可以尝试通过按 Alt + N 来跳转到它,至少在 Windows 上...

如果是,您可以使用Robot 类“盲目地”输入路径。在你的情况下,这将是一种方式:

driver.findElement(By.id("SWFUpload_0")).click();
Robot r = new Robot();
r.keyPress(KeyEvent.VK_C);        // C
r.keyRelease(KeyEvent.VK_C);
r.keyPress(KeyEvent.VK_COLON);    // : (colon)
r.keyRelease(KeyEvent.VK_COLON);
r.keyPress(KeyEvent.VK_SLASH);    // / (slash)
r.keyRelease(KeyEvent.VK_SLASH);
// etc. for the whole file path

r.keyPress(KeyEvent.VK_ENTER);    // confirm by pressing Enter in the end
r.keyRelease(KeyEvent.VK_ENTER);

这很糟糕,但它应该可以工作。请注意,您可能需要这些:How can I make Robot type a `:`?Convert String to KeyEvents(另外还有新的闪亮的 KeyEvent#getExtendedKeyCodeForChar(),它可以做类似的工作,但只能从 JDK7 获得)。


对于 Flash,我知道的唯一替代方法(来自 this discussion)是使用暗技术:

首先,你修改你的 Flash 应用程序的源代码,暴露 使用 ActionScript 的 ExternalInterface API 的内部方法。 一旦公开,这些方法将可以被浏览器中的 JavaScript 调用。

其次,既然 JavaScript 可以在您的 Flash 应用程序中调用内部方法, 您使用 WebDriver 在网页中进行 JavaScript 调用,这将 然后调用你的 Flash 应用程序。

flash-selenium 项目的文档中进一步解释了该技术。 (http://code.google.com/p/flash-selenium/),但该技术背后的想法 也适用于 WebDriver。

【讨论】:

  • “不工作”是什么意思?为什么,在哪里,有什么错误信息?
  • 无法进入文件上传窗口的文件路径
  • 我也添加了一个黑魔法解决方案。反正你还是不够具体。请根据您的尝试以及失败的方式或原因编辑您的问题。
  • 是的。两者都为我工作。 Robot 解决方案显然依赖于键盘布局,但我认为这可以通过某种方式避免。
  • 旁注:也可以通过 SendKeys 上传多个文件 - 请参阅 stackoverflow.com/questions/23955430/…
【解决方案2】:

以下代码对我有用:

public void test() {
    WebDriver driver = new FirefoxDriver();
    driver.get("http://www.freepdfconvert.com/pdf-word");
    driver.findElement(By.id("clientUpload")).click();
    driver.switchTo()
            .activeElement()
            .sendKeys(
                    "/home/likewise-open/GLOBAL/123/Documents/filename.txt");
    driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
    driver.findElement(By.id("convertButton"));

【讨论】:

  • 这应该是答案。 sendKeys() 根本不会产生任何结果,但这一个效果很好。我在 Ubuntu 上使用 GhostDriver。
【解决方案3】:

使用 C# 和 Selenium 此处的代码适用于我,注意您将需要使用参数在 FindWindow 调用中为您的特定服务器换出“localhost”如果它不是 localhost 并跟踪哪个是最新的对话框,如果有多个对话框挂起,则打开,但这应该让你开始:

    using System.Threading;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    using OpenQA.Selenium;

    [DllImport("user32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool SetForegroundWindow(IntPtr hWnd);

    [DllImport("user32.dll", EntryPoint = "FindWindow")]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    public static void UploadFile(this IWebDriver webDriver, string fileName)
    {
        webDriver.FindElement(By.Id("SWFUpload_0")).Click();
        var dialogHWnd = FindWindow(null, "Select file(s) to upload by localhost");
        var setFocus = SetForegroundWindow(dialogHWnd);
        if (setFocus)
        {
            Thread.Sleep(500);
            SendKeys.SendWait(fileName);
            SendKeys.SendWait("{ENTER}");
        }
    }

【讨论】:

  • 太棒了!! ,这对我来说是最好的,代码完美运行。Tkanks 为你服务@Matt
【解决方案4】:

我使用 vbsscript 文件在 shell 脚本中使用了 sendkeys。下面是vbs文件中的代码,

Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.SendKeys "C:\Demo.txt"
WshShell.SendKeys "{ENTER}"

下面是运行这个 vbs 文件的 selenium 代码行,

driver.findElement(By.id("uploadname1")).click();
Thread.sleep(1000);
Runtime.getRuntime().exec( "wscript C:/script.vbs" );

【讨论】:

  • 最简单的解决方案之一。如果我们可以参数化文件名,那就太好了。?
【解决方案5】:

有一种比 Slanec 描述的更简单的方法来解决这个问题。当您使用英文键盘时,他的解决方案有效,否则您将很难尝试“映射”特殊字符的键。

您可以使用Toolkit 将字符串复制到剪贴板然后粘贴,而不是robot.keyPressrobot.keyRelease

    StringSelection s = new StringSelection("Path to the file");
    Toolkit.getDefaultToolkit().getSystemClipboard().setContents(s, null);
    Robot robot = new Robot();
    robot.keyPress(java.awt.event.KeyEvent.VK_ENTER);
    robot.keyRelease(java.awt.event.KeyEvent.VK_ENTER);
    robot.keyPress(java.awt.event.KeyEvent.VK_CONTROL);
    robot.keyPress(java.awt.event.KeyEvent.VK_V);
    robot.keyRelease(java.awt.event.KeyEvent.VK_CONTROL);
    Thread.sleep(3000);
    robot.keyPress(java.awt.event.KeyEvent.VK_ENTER);

【讨论】:

    【解决方案6】:

    查找元素(必须是具有 type="file" 属性的输入元素)并发送文件的路径。

    WebElement fileInput = driver.findElement(By.id("uploadFile"));
    fileInput.sendKeys("/path/to/file.jpg");
    

    注意:如果您使用的是 RemoteWebDriver,您还必须设置文件检测器。默认为UselessFileDetector

    WebElement fileInput = driver.findElement(By.id("uploadFile"));
    driver.setFileDetector(new LocalFileDetector());
    fileInput.sendKeys("/path/to/file.jpg");
    

    【讨论】:

    • 很好,file 属性是关键。
    【解决方案7】:

    将 System.Windows.Forms 二进制文件导入到测试解决方案中,并在点击 UI 上的 Upload 按钮时调用以下两个 LOC。

            // Send the file path and enter file path and wait.
            System.Windows.Forms.SendKeys.SendWait("complete path of the file");
            System.Windows.Forms.SendKeys.SendWait("{ENTER}");
    

    【讨论】:

      【解决方案8】:

      另一种解决方案是编写一个脚本来自动执行“打开文件”对话框。见AutoIt

      另外,如果你不能“点击”元素,我的解决方法通常是这样做:

      element.SendKeys(Keys.Enter);
      

      希望这会有所帮助(即使这是一篇旧帖子)

      【讨论】:

        【解决方案9】:

        以下代码对我有用:

        // wait for the window to appear
        WebDriverWait wait = new WebDriverWait(driver, 10);
        wait.until(ExpectedConditions.alertIsPresent());
        
        // switch to the file upload window
        Alert alert = driver.switchTo().alert();
        
        // enter the filename
        alert.sendKeys(fileName);
        
        // hit enter
        Robot r = new Robot();
        r.keyPress(KeyEvent.VK_ENTER);
        r.keyRelease(KeyEvent.VK_ENTER);
        
        // switch back
        driver.switchTo().activeElement();
        

        【讨论】:

        • 那是什么“机器人”?
        • @Jcyrss 它是java.awt.Robot
        【解决方案10】:

        您已将双斜杠 \\ 用于整个绝对路径以实现此目的 示例:- D:\\images\\Lighthouse.jpg

        步骤 - 使用 sendkeys 作为具有浏览选项的按钮(将打开的按钮 你的窗口框来选择文件) - 现在点击要上传文件的按钮

        driver.findElement(By.xpath("//input[@id='files']")).sendKeys("D:\\images\\Lighthouse.jpg");  
        Thread.sleep(5000);
        driver.findElement(By.xpath("//button[@id='Upload']")).click();
        

        【讨论】:

          【解决方案11】:

          首先将文件添加到你的项目资源目录

          然后

          public YourPage uploadFileBtnSendKeys() {
              final ClassLoader classLoader = getClass().getClassLoader();
              final File file = new File(classLoader.getResource("yourFile.whatever").getPath());
              uploadFileBtn.sendKeys(file.getPath());
              return this;
          }
          

          Walla,您将看到您选择的文件,并跳过了文件资源管理器窗口

          【讨论】:

            【解决方案12】:

            在 Selenium Webdriver 中使用 AutoIt 脚本处理文件上传。对于上述情况,它工作正常。

            Runtime.getRuntime().exec("E:\\AutoIT\\FileUpload.exe");
            

            请使用以下链接获取更多帮助: http://www.guru99.com/use-autoit-selenium.html

            【讨论】:

              【解决方案13】:
                      webDriver.FindElement(By.CssSelector("--cssSelector--")).Click();
                      webDriver.SwitchTo().ActiveElement().SendKeys(fileName);
              

              对我来说效果很好。采用 Matt 在 C# .net 中在上述答案中提供的另一种方法也可以使用类名 #32770 用于上传框。

              【讨论】:

                【解决方案14】:

                下面的对我有用

                webDriver.findElement(By.xpath("//input[@type='file' and @name='importFile']")).sendKeys("C:/path/to/file.jpg");
                

                【讨论】:

                  【解决方案15】:

                  将路径中的反斜杠加倍,如下所示:

                  driver.findElement(browsebutton).sendKeys("C:\\Users\\Desktop\\Training\\Training.jpg");
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2017-11-24
                    • 2021-07-12
                    • 1970-01-01
                    • 2015-12-23
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多