C# 使用Selenium和C在draggable=true时使用操作拖放不工作#

C# 使用Selenium和C在draggable=true时使用操作拖放不工作#,c#,selenium,drag-and-drop,action,draggable,C#,Selenium,Drag And Drop,Action,Draggable,元素被正确识别,我可以看到鼠标在这两个元素之间移动,但并没有发生拖放。 单击并按住时,Ui未显示任何突出显示。 也没有错误 我在不同的讨论中尝试了不同的解决方案,但没有一个适合我 我的代码 _actions = new Actions(Driver.WebDriver); var dragAndDrop = _actions.ClickAndHold(parentRow) .MoveToElement(child

元素被正确识别,我可以看到鼠标在这两个元素之间移动,但并没有发生拖放。 单击并按住时,Ui未显示任何突出显示。 也没有错误

我在不同的讨论中尝试了不同的解决方案,但没有一个适合我

我的代码

_actions = new Actions(Driver.WebDriver);
        var dragAndDrop = _actions.ClickAndHold(parentRow)
                                  .MoveToElement(childRow )
                                  .Release(target)
                                  .Build();
        dragAndDrop.Perform();
        Driver.Wait();
这就是我识别元素的方式

 var childList =Driver.WebDriver.FindElements(By.ClassName("itl-treeNode-title"));
     var parentRow = childList.FirstOrDefault(x => x.Text.Equals(parentSrc)).FindElement(By.XPath("following-sibling::*[1]"));
     var childRow = childList.FirstOrDefault(x => x.Text.Equals(childSrc)).FindElement(By.XPath("following-sibling::*[1]"));
同样的代码在我们应用程序的另一个ui上工作

我现在已经像下面那样修改了我的代码,现在我遇到了陈旧的元素异常——因为我需要动态地识别这个元素,所以我不能使用这里提到的POM解决方案

例外情况

OpenQA.Selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document
  (Session info: chrome=77.0.3865.120)
   at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse)
   at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.Remote.RemoteWebDriver.PerformActions(IList`1 actionSequenceList)
   at OpenQA.Selenium.Interactions.Actions.Perform()

单击childRow后,再次构建webelement以避免过时的元素引用异常,下面是示例代码

var childList = Driver.WebDriver.FindElements(By.ClassName("itl-treeNode-title"));
var parent = childList.FirstOrDefault(x => x.Text.Equals(parentSrc)).FindElement(By.XPath("parent::*"));
var parentRow = parent.FindElement(By.ClassName("itl-treenode-content-cover"));
var child = childList.FirstOrDefault(x => x.Text.Equals(childSrc)).FindElement(By.XPath("parent::*"));
var childRow = child.FindElement(By.ClassName("itl-treenode-content-cover"));    
childRow.Click();
childRow = child.FindElement(By.ClassName("itl-treenode-content-cover"));    
new Actions(Driver.WebDriver).ClickAndHold(childRow)
           .MoveToElement(parent)
           .Release(parent)
           .Build()
           .Perform();
Driver.Wait();

根据HTML,您已共享要包含属性的WebElement
draggable=true


拖动 是一个属性,指示是否可以使用本机浏览器行为或HTML拖放API拖动元素<代码>可拖动可以具有以下值:

  • true:可以拖动元素
  • false:无法拖动元素
注意:此属性是枚举属性,而不是布尔属性。
true
false
的值是强制性的,并且禁止使用类似
的速记。正确的用法是

如果未设置此属性,则其默认值为
auto
,这意味着拖动行为是默认的浏览器行为:只能拖动文本选择、图像和链接。对于其他元素,必须将事件设置为拖放才能工作


原生HTML5拖放 在前面提到的文章中,使对象可拖动很简单,因为您只需要在要使其可移动的元素上设置
draggable=true
属性。例如:

<div id="cols">
  <div class="col" draggable="true"><header>X</header></div>
  <div class="col" draggable="true"><header>Y</header></div>
  <div class="col" draggable="true"><header>Z</header></div>
</div>
然而,这并不完全适用于Safari或Firefox。对于Safari,您需要向元素添加以下样式:

[draggable=true] {
  -khtml-user-drag: element;
}
这将在Safari中开始工作,当您拖动它时,它将使用dataTransfer对象设置一个默认的空值。但是,Firefox不允许您拖动该元素,除非您手动设置一些数据


解决方案 为了解决这个问题,我们需要一个dragstart事件处理程序,我们将为它提供一些数据以供拖动:

var dragItems = document.querySelectorAll('[draggable=true]');

for (var i = 0; i < dragItems.length; i++) {
  addEvent(dragItems[i], 'dragstart', function (event) {
    // store the ID of the element, and collect it on the drop later on
    event.dataTransfer.setData('Text', this.id);
  });
}
  • 使用:

  • 注意:诱导WebDriverWait以确保要拖动的元素可单击


    我已将我的新代码和异常详细信息添加到原始描述中。现在我得到了一个陈旧的元素异常。@user8710571,您在哪一行得到异常?dragAndDrop.Perform()@用户8710571,我已经更新了答案,尝试一下。我已经在原始描述中添加了我的新代码和异常详细信息。请您帮助我,谢谢。现在我得到了一个陈旧的元素异常
    [draggable=true] {
      -khtml-user-drag: element;
    }
    
    var dragItems = document.querySelectorAll('[draggable=true]');
    
    for (var i = 0; i < dragItems.length; i++) {
      addEvent(dragItems[i], 'dragstart', function (event) {
        // store the ID of the element, and collect it on the drop later on
        event.dataTransfer.setData('Text', this.id);
      });
    }
    
    new Actions(Driver.WebDriver).ClickAndHold(parentRow).MoveToElement(childRow ).Release(target).Build().Perform();
    
    new Actions(Driver.WebDriver).DragAndDrop(parentRow, childRow).Build().Perform();