简体   繁体   English

从Selenium Webdriver中的Javascript函数返回值

[英]Return value from Javascript function in Selenium webdriver

How do i return an array from a javascript function using selenium webdriver ? 如何使用Selenium Webdriver从javascript函数返回数组? the code which i have tried is - 我尝试过的代码是-

System.setProperty("webdriver.chrome.driver", "D:/chromedriver_win32/chromedriver.exe");
    wd=new ChromeDriver();
    wd.navigate().to("http://www.makemytrip.com");
    wd.manage().window().maximize();
    Thread.sleep(5000);
    wd.findElement(By.id("from_typeahead1")).click();
    WebElement span= wd.findElement(By.xpath(".//*[@id='one_round_default']/div/div[1]/div/div[1]/span/span/div[1]/span"));

    JavascriptExecutor jse = (JavascriptExecutor)wd;
    jse.executeScript("window.showList = function(){"+
            "var source=[];"+
            "var inputs = arguments[0].getElementsByTagName('div');"+
            "for(var i = 0; i < inputs.length; i++) {"+
                "source.push(inputs[i])"+
            "}"+
            "return source;"+
            "};",span);

    /*List<?> al =  (List<?>) jse.executeScript(
            "var source = [];"+
            "var inputs = arguments[0].getElementsByTagName('div');"+
            "for(var i = 0; i < inputs.length; i++) {"+
               "source.push(inputs[i])"+      
            "}"+
            "return source;"                 
            ,span);*/

    List<?> al =  (List<?>) jse.executeScript("showList();");
    for(Object web:al){
        System.out.println(((WebElement) web).getText());
    }

I am getting an exception stating - "org.openqa.selenium.WebDriverException: unknown error: Cannot read property 'getElementsByTagName' of undefined." 我收到一个异常声明-“ org.openqa.selenium.WebDriverException:未知错误:无法读取未定义的属性'getElementsByTagName'。”

Incidently when i try this code it works perfectly - 顺便说一句,当我尝试此代码时,它可以完美运行-

System.setProperty("webdriver.chrome.driver", "D:/chromedriver_win32/chromedriver.exe");
    wd=new ChromeDriver();
    wd.navigate().to("http://www.makemytrip.com");
    wd.manage().window().maximize();
    Thread.sleep(5000);
    wd.findElement(By.id("from_typeahead1")).click();
    WebElement span= wd.findElement(By.xpath(".//*[@id='one_round_default']/div/div[1]/div/div[1]/span/span/div[1]/span"));

    List<?> al =  (List<?>) jse.executeScript(
            "var source = [];"+
            "var inputs = arguments[0].getElementsByTagName('div');"+
            "for(var i = 0; i < inputs.length; i++) {"+
               "source.push(inputs[i])"+      
            "}"+
            "return source;"                 
            ,span);

    for(Object web:al){
        System.out.println(((WebElement) web).getText());
    }

But i want to first create a function which returns me the array and then call the function whenever i want. 但是我想先创建一个返回数组的函数,然后在需要时调用该函数。 How to achieve that? 如何实现呢? Also if possible how do i use an external .js file to do the same logic and use it in my script? 另外,如果可能的话,如何使用外部.js文件执行相同的逻辑并在脚本中使用它? Any help will be greatly appreciated. 任何帮助将不胜感激。 Thanks in advance ! 提前致谢 !

As you have found out the executeScript method creates a function using the first argument and pass the remaining arguments to it. 如您executeScript方法使用第一个参数创建函数,并将其余参数传递给该函数。

To break out of the scope of this function, simply define something in the global object or manipulate the DOM. 要突破此功能的范围,只需在全局对象中定义某些内容或操纵DOM。

For example, call the jse.executeScript("window.showList = function(){... from your first code snippet somewhere in your test but do not pass it the span argument. This defines the showList function in the global scope. 例如,从测试中某个地方的第一个代码段调用jse.executeScript("window.showList = function(){... ,但不要将span参数传递给它。这将在全局范围内定义showList函数。

Later you can simply do jse.executeScript("return showList.apply(null, arguments)", span) to call it. 稍后,您可以简单地执行jse.executeScript("return showList.apply(null, arguments)", span)来调用它。

Similarly, you can include an external script using the snippet 同样,您可以使用代码段添加外部脚本

driver.executeScript("var s = document.createElement('script'); s.type = 'text/javascript'; s.src = arguments[0]; document.body.appendChild(s);", scriptUrl);

(or simply hard-code the url). (或简单地对网址进行硬编码)。

For both cases, remember to only run the definition/include call once to avoid redefining things. 对于这两种情况,请记住只运行一次definition / include调用,以避免重新定义内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM