Selenium如何批量许多isElementDisplayed调用?

硒有一个方便的机制,可以非常有效地从DOM中提取数十个或数百个元素,并且只需一次快速往返:

buttons = driver.find_elements_by_css_selector('button')

结果buttons可以是几十或几百个元素的列表,没有任何问题。

但是如果你想用is_displayed()过滤元素(或者像Java调用它, isElementDisplayed ), isElementDisplayed事情就会慢慢爬行,因为每次调用该方法都需要往返于浏览器。 即使在我最快的开发机器上,每个这样的调用都需要大约0.1s,这意味着跨100个元素的以下过滤需要10秒(!):

[b.is_displayed() for b in buttons]

如果您想要查找带有特定文本的按钮,则会发生同样的问题,因为每次查找.text属性实际上都会调用一个具有自己往返浏览器的属性:

[('Subscribe' in b.text) for b in buttons]

这使得编写健壮的Selenium测试变得很困难,这些测试关注了真正用户面对DOM的两件事情:一个元素是否可见,以及它包含哪些文本。 虽然完全远离可见性和文本内容(比如说,唯一的ID或类的组合或文档位置),将会使我们的测试运行得更快,但它会在我们的Selenium测试和它正在查找的按钮之间创建一条看不见的链接让我们的测试着眼于用户体验以及用户可以在屏幕上看到和阅读的内容。

我的问题:

  • 有什么办法可以在元素初始获取期间将is_displayed()text测试应用于浏览器上的元素?

  • 或者有没有办法做一批批的is_displayed()调用,询问很多元素而不是一个?

  • 或者是从Python测试到Firefox下的Selenium的0.1秒往返时间,这完全不合理,而且对其他人来说运行速度更快,这就是为什么这些常见操作的明显批处理版本不存在?

  • 我曾经想过,我可以转向从Python(Java名称: executeScript() )运行execute_script() ,并从我的JavaScript代码中以某种方式执行Selenium的逻辑,该逻辑隐藏在“这个元素可见”的复杂思想背后。 不幸的是, executeScript()似乎不能让脚本访问Selenium本身发现的任何util函数,因此要访问is-visible函数,我们必须将jQuery或随机Selenium代码片段放入页面中,否则缺乏它们,干扰了测试的整个概念:它测试页面原样而不改变它的JS配置文件仅仅是为了运行我们的测试。

    感谢您的任何想法! 我很惊讶Selenium希望调用者能够执行executeScript()以重建像is_displayed()这样的功能,正如代码所暗示的那样,Selenium的一个主要特性就是它需要很多工作才能获得正确的人们会想要从可能的所有代码中访问,以避免重新发明这样一个重要的轮子。


    根据我对selenium python绑定源代码的理解,没有选项可以批量发送命令,如isElementDisplayedexecute()方法负责通过JSON有线协议传输命令,但一次只能处理一个命令。

    仅供参考,这里是w3c webdriver规范的底层isDisplayed()算法。 而且,我认为,这是Chrome Webdriver自己实施的。

    作为解决方法并依靠此解决方案,我们可以执行javascript(未测试):

    script = """
    function isHidden(el) {
        var style = window.getComputedStyle(el);
        return (style.display === 'none')
    }
    
    var result = [];
    for (var i = 0; i < arguments.length; i++) {
        result.push(isHidden(arguments[i]));
    }
    return result;
    """
    
    driver.execute_script(script, *buttons)
    

    请注意,这只是一种解决方法,严格地说,它甚至不接近Webdriver真正确定可见性的方式。

    说到检查按钮元素的text值,除了采用类似的execute_script()方法之外,一种可能的解决方法是使用XPath表达式并验证文本:

    buttons = driver.find_elements_by_xpath('//button[contains(., "some text")]')
    
    链接地址: http://www.djcxy.com/p/83579.html

    上一篇: How can Selenium batch many isElementDisplayed calls?

    下一篇: Listen to element visibility in Angular 2