为啥这个 Selenium 的拖放 C# 代码在 Chrome 上不起作用?

Posted

技术标签:

【中文标题】为啥这个 Selenium 的拖放 C# 代码在 Chrome 上不起作用?【英文标题】:Why this Selenium's drag and drop C# code is not working on Chrome?为什么这个 Selenium 的拖放 C# 代码在 Chrome 上不起作用? 【发布时间】:2019-10-29 10:38:16 【问题描述】:

这不起作用(例如:https://www.w3schools.com/html/html5_draganddrop.asp)

var item = WebDriver.FindElement(By.XPath(@"//img[@src='img_w3slogo.gif']"), 30);
var container = WebDriver.FindElement(By.XPath(@"//div[@id='div2']"), 30);

var actions = new OpenQA.Selenium.Interactions.Actions(this.WebDriver);
actions.DragAndDrop(item, container).Build().Perform();

System.Threading.Thread.Sleep(3000);

【问题讨论】:

这是一个 selenium 开发人员解释 HTML5 拖放如何实现/支持的线程。还包含围绕您单击并按住,移动到随机点,然后再次移动到最终目的地的潜在工作。 github.com/SeleniumHQ/selenium-google-code-issue-archive/issues/… @LoffinA 该链接来自 2016 年。为什么 XPATH 中有“@”符号? 以前的开发者已经在 XPATH 的开头有 @ 符号,但是我能够找到元素。 Anf 非常感谢@LoflinA,这真的很有帮助 【参考方案1】:

如果有帮助的话......

        public static void DragAndDrop(IWebElement element1, IWebElement element2)
    
        WaitForElementEnabled(element1);
        WaitForElementEnabled(element2);
        var builder = new Actions(_webDriver);
        var dragAndDrop = builder.ClickAndHold(element1).MoveToElement(element2).Release(element2).Build();
        dragAndDrop.Perform();
    

           public static void WaitForElementEnabled(IWebElement element)
    
        try  _wait.Until(webDriver => element.Enabled); 
        catch (StaleElementReferenceException)  if (!WaitForNotFoundElement_Enabled(element))  LogFunctions.WriteError("Enabled - Stale Element Exception"); TakeScreenshot("elementNotFound"); throw;  
     

【讨论】:

【参考方案2】:

我能够让它工作的唯一方法是使用位于此处的辅助函数:https://gist.github.com/druska/624501b7209a74040175 并执行 javascript(Java 示例):

 String simulateFunction = "function simulateDragDrop(sourceNode, destinationNode) \n" +
"    var EVENT_TYPES = \n" +
"        DRAG_END: 'dragend',\n" +
"        DRAG_START: 'dragstart',\n" +
"        DROP: 'drop'\n" +
"    \n" +
"\n" +
"    function createCustomEvent(type) \n" +
"        var event = new CustomEvent(\"CustomEvent\")\n" +
"        event.initCustomEvent(type, true, true, null)\n" +
"        event.dataTransfer = \n" +
"            data: \n" +
"            ,\n" +
"            setData: function(type, val) \n" +
"                this.data[type] = val\n" +
"            ,\n" +
"            getData: function(type) \n" +
"                return this.data[type]\n" +
"            \n" +
"        \n" +
"        return event\n" +
"    \n" +
"\n" +
"    function dispatchEvent(node, type, event) \n" +
"        if (node.dispatchEvent) \n" +
"            return node.dispatchEvent(event)\n" +
"        \n" +
"        if (node.fireEvent) \n" +
"            return node.fireEvent(\"on\" + type, event)\n" +
"        \n" +
"    \n" +
"\n" +
"    var event = createCustomEvent(EVENT_TYPES.DRAG_START)\n" +
"    dispatchEvent(sourceNode, EVENT_TYPES.DRAG_START, event)\n" +
"\n" +
"    var dropEvent = createCustomEvent(EVENT_TYPES.DROP)\n" +
"    dropEvent.dataTransfer = event.dataTransfer\n" +
"    dispatchEvent(destinationNode, EVENT_TYPES.DROP, dropEvent)\n" +
"\n" +
"    var dragEndEvent = createCustomEvent(EVENT_TYPES.DRAG_END)\n" +
"    dragEndEvent.dataTransfer = event.dataTransfer\n" +
"    dispatchEvent(sourceNode, EVENT_TYPES.DRAG_END, dragEndEvent)\n" +
" var toDrag =document.getElementById('drag1'); var toDrop = document.getElementById('div2');";

  ((JavascriptExecutor)driver).executeScript(simulateFunction + "simulateDragDrop(toDrag, toDrop);");

有没有人在没有 javascript 执行器的情况下得到这个工作?

【讨论】:

谢谢@pcalkins,这就像一个魅力。我将此添加到我的 WebDriver 扩展类中,以便我可以发送元素的选择器查询。

以上是关于为啥这个 Selenium 的拖放 C# 代码在 Chrome 上不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

C# 具有叠加/不透明图像的拖放效果

Python Selenium 拖放

什么是“用鼠标移动东西”中的拖放,而不是数据传输中的拖放?

当 draggable=true 使用 Selenium 和 C# 时,拖放不能使用 Actions

使用 .Net 检测外部应用程序中的拖放操作

简单的拖放代码