Selenium拖放JQuery元素

时间:2017-07-13 14:55:45

标签: java jquery selenium drag-and-drop

我正在尝试使用Selenium的Action类将JQuery嵌套可排序列表中的源元素拖放到另一个元素。我使用了标准的dragAndDrop方法,并将其分解为clickAndHold,moveToElement和release,但这两种方法都不起作用。我甚至尝试使用源元素内部子进行拖动,但结果是一样的。

当我运行脚本时,测试会返回,因此我知道元素正在被找到并且选择器是有效的。 Selenium认为拖放操作有效,但是当我观察测试时,我看不到任何动作。我已经向一些开发人员确认,我确实将目标锁定在与DOM有关的正确源元素上。

编辑:我在执行操作之前尝试过使用build()方法,甚至通过暂停线程来减慢测试速度,但结果是一样的。

编辑2:我还添加了需要放入源的目标。我还应该提到源元素(在拖动事件上)创建了一个sortable-ghost对象,当用户手动将其拖入目标元素时,该对​​象将被复制到目标元素容器中。

这是我想要拖动的目标容器。

<div class="schedDayItem anytimeSection" data-bind="nestedSortable: { 
    foreach: AutoEvents, options: { animation: 600, group: 
   'autoevents', scroll: true, onStart: EnableDragging, onEnd: 
    DisableDragging } }" style="min-height: 60px; position: relative;
    cursor: pointer;"></div>

这是我要拖动的元素的父级。它是JQuery嵌套的可排序列表:

<div class="listDayItem anytimeSection" style="font-size: 14px;" 
    data-bind="nestedSortable: { foreach: EventList, options: { animation:
    600, group: { name: 'draggbleevents', pull: 'clone', put: false }, 
    onEnd: $root.GetBaseEvents, sort: false } }">

这是我想要移动的源元素,嵌套的sortables直接子:

<div class="draggableEventItem pointer" style="margin: 3px 0; border-
    radius: 3px;">

为了完整性,我要移动源元素的内部子元素:

<div id="container" data-bind="class: EventType, style: { backgroundColor: 
    EventBackground }" style="background-color: white; border: 1px solid 
    #AAA; padding: 4px 0; border-radius: 3px;" class="border-left-red">

以下是我在代码中尝试做的事情:

    Actions action = new Actions(driver);
    //eventAlert is the element I am trying to move.
    //eventName is a string I am using to find the right element in the JQuery List.  One of the source elements inner children provide this string.

    List<WebElement>list = driver.findElements(eventAlert);
    for(WebElement we : list){
        if(we.getText().contains(eventName)){
            action.dragAndDrop(we, driver.findElement(eventElementTarget)).perform();
            break;
        }
    }

2 个答案:

答案 0 :(得分:0)

尝试在perform()方法之前使用build()方法

action.dragAndDrop(we, driver.findElement(eventElementTarget)).build().perform();

我尝试了以下测试来获取一个jquery示例,该示例将一个元素拖放到另一个元素,不确定这会有所帮助:

@Test
public void testDropAndDrag() throws InterruptedException {
    driver.get("http://www.elated.com/res/File/articles/development/javascript/jquery/drag-and-drop-with-jquery-your-essential-guide/card-game.html");
    Actions act = new Actions(driver);
    WebElement card1 = driver.findElement(By.id("card1"));
    WebElement card1Drop = driver.findElement(By.className("ui-droppable"));
    act.dragAndDrop(card1,card1Drop).perform();
    Thread.sleep(5000);
}

<强>更新 我能够使用此站点上的示例重现您遇到的情况:http://jqueryui.com/sortable/#connect-lists

如果你看看源代码,我就抓住了id来获取

  • 元素的列表,这些元素会起作用,但是在循环中它会运行但不会做任何事情。必须是在jquery中获取元素列表的东西。

    我更改了列表以取代所有

  • 元素,并且它有效。这是更新的测试示例:

    @Test
    public void testDropAndDrag() throws InterruptedException {
        driver.manage().window().maximize();
        driver.get("http://jqueryui.com/sortable/#connect-lists");
    
        Actions act = new Actions(driver);
        WebElement iframeElement = driver.findElement(By.cssSelector("iframe.demo-frame"));
        driver.switchTo().frame(iframeElement);
        List<WebElement> list1 = driver.findElements(By.cssSelector("ul > li.ui-state-default"));
        WebElement list2 = driver.findElement(By.id("sortable2"));
        for(WebElement item : list1){
            System.out.println(item.getText());
            if(item.getText().equals("Item 1")){
                System.out.println(item.getText());
                act.dragAndDrop(item,list2).perform();
                break;
            }
        }
        Thread.sleep(1000);
    }
    
  • 答案 1 :(得分:0)

    虽然我无法弄清楚如何让dragAndDrop方法在这个特定问题中运行,但我确实通过在Javascript中使用推送操作找到了解决方法。我将继续尝试,看看嵌套的可排序jQuery列表是否存在错误,但目前这种解决方法是可靠的。

    下面我按照之前的方式创建一个列表,但这次使用计数器作为迭代设备。我正在搜索AutoSequenceItems并将它们推送到我的目标容器的事件列表。这种方法需要知道网站的实际Javascript,但如果与开发人员一起工作,在大多数情况下它不应该成为问题。这只是一个可能的解决方法的示例,其他人在其站点中不会有AutoSequenceItems等。

        List<WebElement>list = driver.findElements(eventListItem);
        int counter = 0;
        for(WebElement we : list){
            if(we.getText().contains(eventName)){
                js.executeScript("return AutonEdit.Main.AutoSequenceItems()[0]"
                        + ".AutoEvents.push(AutoEdit.Main.EventList()[" + counter +"]);");
                break;
            }
            counter++;
        }