如何使用Selenium WebDriver处理Windows文件上传?

时间:2012-06-29 05:55:55

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

我在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");

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

Screenshot

我正在寻找上述方案的解决方案。

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

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

15 个答案:

答案 0 :(得分:42)

// 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没有允许您使用浏览器对话框(或Flash对象)的API。

因此,在您点击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。

答案 1 :(得分:10)

以下代码适用于我:

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"));

答案 2 :(得分:2)

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

    [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}");
        }
    }

答案 3 :(得分:1)

将System.Windows.Forms二进制文件导入测试解决方案,并在单击UI上的“上传”按钮时调用以下两个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}");

答案 4 :(得分:1)

以下代码适用于我:

// 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();

答案 5 :(得分:1)

有一种更简单的方法可以解决这个问题,那就是Slanec描述的内容。当您使用英语键盘时,Hes解决方案可以正常工作,如果不是,您将很难尝试使用英语键盘#34; map"特殊字符的关键。

您可以使用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 :(得分:1)

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

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

以下是运行此vbs文件的硒代码行,

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

答案 7 :(得分:0)

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

此外,如果您无法“点击”该元素,我的解决方法通常是这样做:

element.SendKeys(Keys.Enter);

希望这会有所帮助(尽管这是一个老帖子)

答案 8 :(得分:0)

你已经为整个绝对路径设置了双斜杠\\来实现这一点 示例: - 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();

答案 9 :(得分:0)

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

然后

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,您将看到您选择的文件,并跳过了文件浏览器窗口

答案 10 :(得分:0)

使用AutoIt脚本处理Selenium Webdriver中的文件上载。它适用于上述情况。

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

请使用以下链接获取进一步的帮助: http://www.guru99.com/use-autoit-selenium.html

答案 11 :(得分:0)

找到元素(必须是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");

答案 12 :(得分:0)

        webDriver.FindElement(By.CssSelector("--cssSelector--")).Click();
        webDriver.SwitchTo().ActiveElement().SendKeys(fileName);

对我来说效果很好。采用另一种方法,由Matt在C#.net上面提供的答案也适用于上传框的类名#32770。

答案 13 :(得分:-1)

以下一个为我工作

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

答案 14 :(得分:-1)

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

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