Selenium java中的拖放操作

js4nwp54  于 2023-02-14  发布在  Java
关注(0)|答案(4)|浏览(156)

我尝试将内容拖放到selenium中的search-textbox中,但它执行了拖动操作,但没有将其拖放到www.example.com中search-textbox.so我的问题是如何拖放到textbox中。

driver.get("http://stackoverflow.com/questions/42159265/drag-and-drop-content-into-textbox-by-using-selenium");                 
WebElement from = driver.findElement(By.xpath("//*[@id='qinfo']/tbody/tr[1]/td[2]/p/b"));
Actions builder = new Actions(driver);
        builder.doubleClick(from).perform();
        Thread.sleep(1000);

WebElement to = driver.findElement(By.name("q"));
Action dragAndDrop = builder.clickAndHold(from).moveToElement(to).release(to).build();
        dragAndDrop.perform();
91zkwejq

91zkwejq1#

首先,WebDriver/Selenium DragAndDrop似乎不再工作了,充其量它在工作和不工作之间徘徊,这取决于驱动程序,浏览器和Selenium的发布。我没有发现任何Java变通方案实际上工作。

clickAndHold() moveToElement() release()  // solutions don't work

在浏览了下面提到的站点之后,我制作了一个Java示例。
Elemental Selenium Drag N Drop-用于测试拖放的示例应用rcorreia/drag_and_drop_helper.js- rcorreia的javascript助手代码
RomanIsko/elemental-selenium-tips-csharp实现
通过查看romanisko csharp代码,我知道了如何集成javascript文件。

JSDriver.ExecuteScript(dnd_javascript + "$('#column-a').simulateDragDrop({ dropTarget: '#column-b'});");

从上面我想到了下面的Java解决方案:
DragAndDropJsHelper.java

import java.io.BufferedReader;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Collectors;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

public class DragAndDropJsHelper {
    Logger log = LogManager.getLogger(DragAndDropJsHelper.class.getName());

    String dragndrop_js = null;

    public DragAndDropJsHelper(String jsFile) throws IOException {
        // the javascript file must be read into a single string no line breaks
        try (BufferedReader br = Files.newBufferedReader(Paths.get(getURIFromURL(jsFile)))) {
            dragndrop_js = br
                    .lines()
                    .collect(Collectors.joining(" "));
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }

    // helper method, I'm using maven my js file is in src/test/resources
    @SuppressWarnings("finally")
    private URI getURIFromURL(String fileName) {
        URI uri = null;
        try {
            URL url = this.getClass().getClassLoader().getResource(fileName);
            uri = url.toURI();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } finally {
            return uri;
        }
    }

    /**
     * Solution from elemental-selenium-tips
     * https://github.com/tourdedave/elemental-selenium-tips/blob/master/39-drag-and-drop/csharp/DragAndDrop.cs
     * JSDriver.ExecuteScript(dnd_javascript + "$('#column-a').simulateDragDrop({
     * dropTarget: '#column-b'});");
     * 
     * NOTE: Seems fragile, not sure if this works for XPATH or other src/dst type strings
     * TODO: would be good if it worked with WebElement, or BY
     * 
     * @param driver
     * @param src
     *            - css string for source element
     * @param dst
     *            - css string for destination element
     */
    public void dragDrop(WebDriver driver, String src, String dst) {
        String js = String.format("$('%s').simulateDragDrop({ dropTarget: '%s'});",src,dst);
        JavascriptExecutor jse = (JavascriptExecutor) driver;
        jse.executeScript(dragndrop_js + js);
    }

}

我网站的一部分DragAndDropTest.java

@Test
public void dragAtoBTest() {
    try {
        WebElement weA = driver.findElement(DragNDropPage.COLUMN_A);
        WebElement weB = driver.findElement(DragNDropPage.COLUMN_B);
        DragAndDropJsHelper ddh = new DragAndDropJsHelper("drag_and_drop_helper.js");

        ddh.dragDrop(driver, "#column-a", "#column-b");

        log.info("wait for opacity to change 1, indicating move complete");
        wait.until(ExpectedConditions.attributeToBe(weA, "opacity", "1"));
        assertThat(weA.findElement(page.columnHeader).getText(), containsString("B"));

    } catch (Exception e) {
        e.printStackTrace();
        log.error(e);
        Assert.fail("FAILED validLoginTest");
    }
}

注意:使用drag_and_drop. js需要src和dst是css选择器字符串,我不知道xpath是否可以工作。如果它可以处理WebElement和/或BY作为输入参数,那就更好了。不幸的是,我的javascript不够深,无法进行这样的修改。
另见:
Selenium Actions drag and drop not working on chrome browser
Drag and drop support for an object via Gwen DSL

sirbozc5

sirbozc52#

所以这件事让我疯狂了几天,但我已经找到了答案。
拍了个视频
https://www.youtube.com/watch?v=hOprGzKBD9I&feature=youtu.be
用文字/代码解释需要做什么
1 -您需要导入一个外部JS文件resources/drag_and_drop. js 2 -在您需要运行make之后,创建一个将执行JS的函数
下面是我的-

  • 此方法使用Selenium webdriver实现拖放操作
  • 字符串必须是CSS位置
public void dragIT (String Fromlocator, String ToLocator) 


  String filePath = "resources/drag_and_drop.js";
  StringBuffer buffer = new StringBuffer();

  String line;
  BufferedReader br = new BufferedReader(new FileReader(filePath));
  while((line = br.readLine())!=null)
      buffer.append(line);

  String javaScript = buffer.toString();
  String commandToExecute =  "$('"+Fromlocator+"').simulateDragDrop({ dropTarget: '"+ToLocator+"'});";

  javaScript = javaScript + commandToExecute;
  ((JavascriptExecutor)driver).executeScript(javaScript)   }
mrfwxfqh

mrfwxfqh3#

您可以尝试:

Actions dragAndDrop= new Actions(driver);
dragAndDrop.clickAndHold(DragFrom).moveToElement(DragTo).release().build().perform();
fnvucqvd

fnvucqvd4#

显然,这适用于某些情况(当使用HTML5可拖动属性时)。https://elementalselenium.com/tips/39-drag-and-drop
这是我的解决方案,我修改了javascript文件一点,所以它将使用executeScript可选args,而不使用字符串串联。

var source = arguments[0];
var target = arguments[1];
(function( $ ) {
    $.fn.simulateDragDrop = function(options) {
        return this.each(function() {
            new $.simulateDragDrop(this, options);
        });
    };
    $.simulateDragDrop = function(elem, options) {
        this.options = options;
        this.simulateEvent(elem, options);
    };
    $.extend($.simulateDragDrop.prototype, {
        simulateEvent: function(elem, options) {
            /*Simulating drag start*/
            var type = 'dragstart';
            var event = this.createEvent(type);
            this.dispatchEvent(elem, type, event);

            /*Simulating drop*/
            type = 'drop';
            var dropEvent = this.createEvent(type, {});
            dropEvent.dataTransfer = event.dataTransfer;
            this.dispatchEvent($(options.dropTarget)[0], type, dropEvent);

            /*Simulating drag end*/
            type = 'dragend';
            var dragEndEvent = this.createEvent(type, {});
            dragEndEvent.dataTransfer = event.dataTransfer;
            this.dispatchEvent(elem, type, dragEndEvent);
        },
        createEvent: function(type) {
            var event = document.createEvent("CustomEvent");
            event.initCustomEvent(type, true, true, null);
            event.dataTransfer = {
                data: {
                },
                setData: function(type, val){
                        this.data[type] = val;
                },
                getData: function(type){
                        return this.data[type];
                }
            };
            return event;
        },
        dispatchEvent: function(elem, type, event) {
            if(elem.dispatchEvent) {
                elem.dispatchEvent(event);
            }else if( elem.fireEvent ) {
                elem.fireEvent("on"+type, event);
            }
        }
    });
})(jQuery);
$(source).simulateDragDrop({ dropTarget: target});

有了这个,你现在可以简单地用参数调用它:

摘自Java测试方法:

JavascriptExecutor js = (JavascriptExecutor) getDriver();
String script = Utils.readFileContents("/dragAndDrop.js");

// First Drag & Drop
js. executeScript(script, dndPage.getColumnA(), dndPage.getColumnB());
assertThat(dndPage.getColumnAHeaderText()).isEqualTo("B");
assertThat(dndPage.getColumnBHeaderText()).isEqualTo("A");

希望这能帮到什么人。

相关问题