Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Selenium:从文件系统拖放到WebDriver?_C#_Selenium_Ui Automation - Fatal编程技术网

C# Selenium:从文件系统拖放到WebDriver?

C# Selenium:从文件系统拖放到WebDriver?,c#,selenium,ui-automation,C#,Selenium,Ui Automation,我必须测试一个web应用程序,它包含一个用于从本地文件系统上载文件的拖放区域。我的测试环境基于C# 对于自动化测试,我使用了Selenium,但无法从文件系统中拖动文件。上传区域是一个div标签(无input标签)。那么最好的方法是什么呢?AutoIt(是否可以插入web浏览器)?Sikuli?单独使用硒是可能的,但这并不简单。它需要在页面中插入一个新的INPUT元素,以便通过SendKeys接收文件。然后,脚本需要通过将dragenter、dragover、drop事件发送到目标区域来模拟拖放

我必须测试一个web应用程序,它包含一个用于从本地文件系统上载文件的拖放区域。我的测试环境基于C#


对于自动化测试,我使用了Selenium,但无法从文件系统中拖动文件。上传区域是一个
div
标签(无
input
标签)。那么最好的方法是什么呢?AutoIt(是否可以插入web浏览器)?Sikuli?

单独使用硒是可能的,但这并不简单。它需要在页面中插入一个新的
INPUT
元素,以便通过
SendKeys
接收文件。然后,脚本需要通过将
dragenter
dragover
drop
事件发送到目标区域来模拟拖放

static void Main(字符串[]args)
{
var驱动程序=新的ChromeDriver();
驱动程序Url=”https://react-dropzone.js.org/";
IWebElement droparea=driver.FindElementByCssSelector(“[data preview='Basic example'][style]”);
DropFile(droparea,@“C:\Users\florent\Desktop\capture.png”);
driver.Quit();
}

const string JS_DROP_FILE=“for(var b=arguments[0],k=arguments[1],l=arguments[2],c=b.ownerDocument,m=0;){var e=b.getBoundingClientRect(),g=e.left+(k | e.width/2),h=e.top+(l | e.height/2),f=c.elementFromPoint(g,h);if(f&&b.contains(f))break;if(1前面的答案是正确的,并且与Chrome驱动程序完美配合,但是Mozilla Gecko驱动程序可能有问题,它抛出
org.openqa.selenium.ElementNotVisibleException

为了避免这种情况,请删除
input.style.display='none';


如果需要使其消失,可以使用
input.style.opacity=0;

如果使用Selenide:

    public static void dragAndDropFileUpload(File file, SelenideElement target) throws IOException {

    String inputId = "seleniumDragAndDropInput";

    // Create the FileList
    executeJavaScript(inputId + "_files = [];");
        executeJavaScript(inputId + "_files.push(new File([new Blob(['" + file.getAbsolutePath() + "'], {type: '" + Files.probeContentType(file.toPath()) + "'})], '" + file.getName() + "'));");


    String targetId = target.getAttribute("id");

    // Add an id if the target doesn't have one
    if (targetId == null || targetId.isEmpty()) {
        targetId = "seleniumDragAndDropInput_target";
        executeJavaScript("sId=function(e, i){e.id = i;};sId(arguments[0], arguments[1]);", target, targetId);
    }

    // Add the item function the the FileList
    // Create the drop event and dispatch it on the target
    String initEventJS = inputId + "_files.item = function (i) {return this[i];};"
            + "var eve=document.createEvent(\"HTMLEvents\");"
            + "eve.initEvent(\"drop\", true, true);"
            + "eve.dataTransfer = {files:seleniumDragAndDropInput_files};"
            + "eve.preventDefault = function () {};"
            + "eve.type = \"drop\";"
            + "document.getElementById('" + targetId + "').dispatchEvent(eve);";

    executeJavaScript(initEventJS);

    if (targetId == "seleniumDragAndDropInput_target") {
        executeJavaScript("document.getElementById('seleniumDragAndDropInput_target').id = null");
    }
}

您可以使用JSExecutor执行此操作:

public void dropFile(File filePath, WebElement target, int offsetX, int offsetY) {
        if (!filePath.exists())
            throw new WebDriverException("File not found: " + filePath.toString());

        JavascriptExecutor jse = (JavascriptExecutor) driver;

        String JS_DROP_FILE =
                "var target = arguments[0]," +
                        "    offsetX = arguments[1]," +
                        "    offsetY = arguments[2]," +
                        "    document = target.ownerDocument || document," +
                        "    window = document.defaultView || window;" +
                        "" +
                        "var input = document.createElement('INPUT');" +
                        "input.type = 'file';" +
                        "input.style.display = 'none';" +
                        "input.onchange = function () {" +
                        "  var rect = target.getBoundingClientRect()," +
                        "      x = rect.left + (offsetX || (rect.width >> 1))," +
                        "      y = rect.top + (offsetY || (rect.height >> 1))," +
                        "      dataTransfer = { files: this.files };" +
                        "" +
                        "  ['dragenter', 'dragover', 'drop'].forEach(function (name) {" +
                        "    var evt = document.createEvent('MouseEvent');" +
                        "    evt.initMouseEvent(name, !0, !0, window, 0, 0, 0, x, y, !1, !1, !1, !1, 0, null);" +
                        "    evt.dataTransfer = dataTransfer;" +
                        "    target.dispatchEvent(evt);" +
                        "  });" +
                        "" +
                        "  setTimeout(function () { document.body.removeChild(input); }, 25);" +
                        "};" +
                        "document.body.appendChild(input);" +
                        "return input;";

        WebElement input = (WebElement) jse.executeScript(JS_DROP_FILE, target, offsetX, offsetY);
        input.sendKeys(filePath.getAbsoluteFile().toString());
        wait.until(ExpectedConditions.stalenessOf(input));
    }

Florent B的回答出于某种原因对我不起作用-AutoIt起了作用。你能解释一下JavaScript代码中发生了什么吗?你添加输入,在这个输入路径中设置到文件,然后触发/模拟“dragenter”、“Dragver”、“drop”事件,对吗?最后应该发生什么?我已经尝试过这个代码,但它对我不起作用。我看不出来hat输入被注入页面,输入值包含文件路径,但drop area没有发生任何变化。@Alex.K,很难说为什么一个简单的“不起作用”"因为该页面可以以多种方式处理删除。请注意,它不应该再与Firefox一起使用,因为输入需要很难处理。您应该就您的问题发布一个问题。@Alex.K,试试这个版本:@Alex.K.,没有可复制的示例就不能说。稍后我将看到如何使用最新的API更新用于数据传输的代码。可能是您没有选择具有预期偏移量的正确元素。@FlorentB。我尝试了“react dropzone.js.org”的新代码,但没有看到,该文件列在“Dropped files”中。我手动执行了该操作,然后可以看到我的文件列在“Dropped files”中。现在我没有任何JavaScript错误,但它不起作用(通过Selenium拖放).有什么想法吗?我应该补充一点,这是针对Java的,但大部分只是包装JS。只要用您自己的JS executor实现替换“executeJs”。