【问题标题】:Return value from Javascript function in Selenium webdriverSelenium webdriver中Javascript函数的返回值
【发布时间】:2016-03-27 13:05:31
【问题描述】:

如何使用 selenium webdriver 从 javascript 函数返回数组? 我尝试过的代码是-

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());
    }

我收到一个异常说明 - “org.openqa.selenium.WebDriverException:未知错误:无法读取未定义的属性 'getElementsByTagName'。”

顺便说一句,当我尝试这段代码时,它可以完美运行 -

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());
    }

但我想首先创建一个函数,它返回我的数组,然后随时调用该函数。如何做到这一点?另外,如果可能的话,我如何使用外部 .js 文件来执行相同的逻辑并在我的脚本中使用它? 任何帮助将不胜感激。提前致谢 !

【问题讨论】:

    标签: javascript java selenium


    【解决方案1】:

    如您所见,executeScript 方法使用第一个参数创建一个函数,并将其余参数传递给它。

    要突破这个函数的范围,只需在全局对象中定义一些东西或操作 DOM。

    例如,在测试中的某处从您的第一个代码 sn-p 调用 jse.executeScript("window.showList = function(){...,但不要将 span 参数传递给它。这在全局范围内定义了showList 函数。

    稍后您可以简单地通过jse.executeScript("return showList.apply(null, arguments)", span) 调用它。

    同样,您可以使用 sn -p 包含外部脚本

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

    (或者只是硬编码网址)。

    对于这两种情况,请记住只运行一次定义/包含调用以避免重新定义。

    【讨论】:

    • 感谢@billc.cn!您能否向我展示您正在创建的外部 .js 文件的工作示例,然后在脚本中调用它?可能是我做错了什么(我猜是语法错误),它不起作用。
    • 我手头并没有真正的工作示例,但基本上你在外部脚本中定义全局函数并使用executeScript 调用它们,类似于我上面给出的第二个示例。您可以使用浏览器的调试控制台来查找 JS 错误(在测试代码中放置一些断点,以便您有时间与浏览器交互)。如果您无权访问浏览器,则可以获取大多数驱动程序的浏览器控制台日志。只需谷歌浏览器名称+“硒日志”。
    • 好的会试试。再次感谢 !还有一件事 - 我需要将外部 .js 文件放在本地网络服务器中还是可以从本地资源访问它?如果是这样,我如何在“s.src”中分配路径?
    • 最简单的方法是从提供主网站的地方提供服务。如果不可能,您将不得不运行另一个 HTTP 服务器来托管它,因为大多数浏览器拒绝使用file: 协议为使用http: 服务的页面加载资源。作为最后的手段,您可以让您的测试代码读取脚本文件并使用executeScript 将其作为&lt;script&gt; 块插入。但是,在这里转义脚本可能会变得非常棘手。
    • 好的。这就解释了。我试图使用“文件:”协议从本地机器加载 .js 文件,但它抛出了“函数未定义”异常。再次感谢@billc.cn!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-25
    • 2020-12-17
    • 1970-01-01
    • 2016-04-25
    • 1970-01-01
    相关资源
    最近更新 更多