有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我在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/

共 (4) 个答案

  1. # 1 楼答案

    我使用VBSSCcript文件在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" );
    
  2. # 2 楼答案

    有一种更简单的方法可以解决这个问题,正如斯莱纳克所描述的。当你使用英文键盘时,他的解决方案是有效的,否则你将很难“映射”特殊字符的键

    您可以使用^{}将字符串复制到剪贴板,然后粘贴,而不是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);
    
  3. # 3 楼答案

    使用C#和Selenium这段代码对我来说很有用,注意如果不是本地主机,你需要使用一个参数来替换特定服务器的FindWindow调用中的“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}");
            }
        }
    
  4. # 4 楼答案

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

    嘿,那是我从哪儿来的:)


    对于Zamzarweb,它应该可以完美地工作。你不能点击元素。只需在其中输入路径。具体来说,这应该是绝对可以的:

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

    Uploadify网站的情况下,你陷入了困境,因为上传的东西不是^{,而是一个Flash对象。WebDriver没有API允许您使用浏览器对话框(或Flash对象)

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

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

    如果是,可以使用^{}类“盲目”地在其中键入路径。在你的情况下,这将是:

    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(另外还有新的、闪亮的^{},它做类似的工作,但只能从JDK7获得)


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

    First, you modify the source code of you the flash application, exposing internal methods using the ActionScript's ExternalInterface API. Once exposed, these methods will be callable by JavaScript in the browser.

    Second, now that JavaScript can call internal methods in your flash app, you use WebDriver to make a JavaScript call in the web page, which will then call into your flash app.

    This technique is explained further in the docs of the flash-selenium project. (http://code.google.com/p/flash-selenium/), but the idea behind the technique applies just as well to WebDriver.