使用Selenium和C#进行draggable = true时,拖放操作无法使用操作

时间:2019-12-06 00:27:57

标签: c# selenium drag-and-drop action draggable

enter image description here

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

我尝试了在不同讨论中提出的不同解决方案,但没有一个对我有用

我的代码

moveForward(15);

这就是我识别元素的方式

moveForward(length);

相同的代码可在我们应用程序的另一个ui上工作。

我现在已经像下面那样更改了代码,现在我得到了过时的元素异常-由于我需要动态地标识此元素,因此无法使用此处https://www.softwaretestingmaterial.com/stale-element-reference-exception-selenium-webdriver/#How-To-Overcome-Stale-Element-Reference-Exception-in-Selenium

提到的POM解决方案
_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]"));

2 个答案:

答案 0 :(得分:0)

在单击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();

答案 1 :(得分:0)

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


可拖动

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

  • true:可以拖动元素。
  • false:无法拖动该元素。
  

注意:此属性是枚举值,而不是布尔值。 truefalse的值是强制性的,而<img draggable>之类的速记则被禁止。正确的用法是<img draggable="false">

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


原生HTML5拖放

Eric Bidelman在文章Native HTML5 Drag and Drop中提到,使对象可拖动很简单,因为您只需要在要设置的元素上设置 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>

要使其他类型的内容可拖动,您可以利用HTML5 DnD API。但是,使用CSS3可以使标记看起来更像列,并添加光标可以为用户提供视觉指示器,表明某些东西是可移动的,但是大多数浏览器会为要拖动的内容创建鬼像,而可拖动不会做任何事情< / strong>。某些浏览器,尤其是FF,在拖动操作中将需要一些data be sent

此外,文章Remy Sharp中的Dragging Anything提到:

HTML 5规范说,它应该简单到将以下属性添加到相关元素的标记中一样简单

draggable="true"

但是,这不适用于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);
  });
}
  

在这里您可以找到drag and drop anythingsource code)的工作演示


此用例

实时HTML可以帮助我们更好地分析问题。但是,您可以尝试使用以下任一链接方法作为解决方案:

  • 使用ClickAndHold()MoveToElement()Release()

    new Actions(Driver.WebDriver).ClickAndHold(parentRow).MoveToElement(childRow ).Release(target).Build().Perform();
    
  • 使用DragAndDrop()

    new Actions(Driver.WebDriver).DragAndDrop(parentRow, childRow).Build().Perform();
    
  

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