【问题标题】:Using a css selector to grab a deeply nested button使用 CSS 选择器获取深度嵌套的按钮
【发布时间】:2018-03-30 11:59:06
【问题描述】:

我目前正在对一个无法轻松识别标签的应用程序进行一些 E2E 测试。我需要单击一个深度嵌套的按钮,这些按钮有时与其他按钮具有完全相同的名称和属性。

HTML 代码如下所示:

<div class='.ui .row'>
  <div class='.ui .fluid'>
    <div class='.content'>
      <div>
        <div class='.field'>
          <button>Button</button>
        </div>
      </div>
    </div>
    <div class='.content'>
      <div>
        <div>Some other stuff</div>
        <div class='.field'>
           <button>Button</button>
        </div>
      </div>
    </div>
  </div>
</div>

因为我们有两个同名,所以我不能只使用browser.click('button*=Button')。我目前解决它的方式是这样的:

browser.click('div &gt; div &gt; div &gt; div &gt; div &gt; button')

当第二个按钮时,我必须做这样的事情:

browser.click('div &gt; div &gt; div:nth-child(2) &gt; div &gt; div:nth-child(2) &gt; button')

尽管它有效,但我有一些问题: - 它看起来不漂亮,对于可能刚刚拿起此代码的人来说不容易阅读 - 它会随着应用程序的最细微更改而过时,即使它与按钮无关

我的问题是在这些情况下是否有更好的选择这些按钮。

【问题讨论】:

  • 元素上根本就没有属性吗?
  • 是的,但这只是文件周围有很多重复的东西的类(想想引导类)
  • 我假设您无权访问标记进行更改?
  • 你们也可以提供课程吗?或任何类型的属性?

标签: html css selenium-webdriver css-selectors webdriver-io


【解决方案1】:

如果您的标记保持相似,您可以利用第二个按钮嵌套在一个 div 中,该 div 是另一个 div 的 sibling。示例:

/* style the first button */
button {
  color: red;
}

/* style the second button */
div + div button {
  color: blue;
}
<div>
  <div>
    <div>
      <div>
        <div>
          <button>Button</button>
        </div>
      </div>
    </div>
    <div>
      <div>
        <div>Some other stuff</div>
        <div>
           <button>Button</button>
        </div>
      </div>
    </div>
  </div>
</div>

【讨论】:

    【解决方案2】:

    我会使用 XPath

    //div[.='Some other stuff']/following::button
    

    第二个按钮前面有一个DIV 标签,“其他一些东西”。您可以使用它来区分这两个按钮。

    【讨论】:

      【解决方案3】:

      对于最容易阅读的格式,Selenium 文档提到如果浏览器不支持查询,它会回退到使用 Sizzle,因此您应该能够使用:contains(),这将允许您通过它们包含的文本,例如:

      button:contains("Button")`
      

      等等

      对于 WebdriverIO,syntax 似乎略有不同,用于使用此功能:

      browser.getTagName('button=Button'); // captures: "<button>Button</button>"
      


      WebdriverIO documentation

      Selenium documentation

      Sizzle documentation for :contains()

      【讨论】:

      • 我看到一些答案提到:contains() 应该可以工作,但我从未见过它实际工作,我已经尝试了几次。你使用成功了吗?你能举个例子吗?
      • 非常依赖环境。有些环境可以开箱即用,有些需要在使用前进行配置。但是,对于这个问题,OP 正在使用 claims 开箱即用的 WebdriverIO。
      【解决方案4】:

      我肯定也会使用 Xpath :)

      为什么不使用索引?

      第一个:

      //button[1]
      

      最后一个:

      //button[last()]
      

      【讨论】:

        【解决方案5】:

        有很多方法可以访问元素:

        一些例子:

        // to access the first button 
        $$('button')[0].click();
        
        // to access the second button 
        $$('button')[1].click();
        

        注意:如果您在该页面中只有两个按钮,则可以使用上述。如果您有更多按钮,那么理想情况下不应该使用它

        或者如果你想链接这里提到的选择器http://webdriver.io/api/utility/$.html

        let buttonContainer = $('.fluid');
        buttonContainer.$$('button')[0].click();
        buttonContainer.$$('button')[1].click();
        

        或者如果你想按照 div .content 访问那么

        $('.fluid div.content:nth-child(1) >button').click();
        $('.fluid div.content:nth-child(2) >button').click();
        

        您可以根据自己的方便如何访问DOM 元素。

        【讨论】:

          猜你喜欢
          • 2011-08-04
          • 2019-07-28
          • 1970-01-01
          • 2018-09-06
          • 2011-08-11
          • 2020-06-29
          • 2018-09-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多