有一些麻烦理解为什么CSS选择器中的:contains()pseudo class按照其方式工作?

StackOverflow https://stackoverflow.com/questions/9334539

我正在使用硒和黄瓜的CSS选择器。当定位器不起作用时,我会使用Chrome Developer工具的控制台对其进行测试。我一直遇到一种我不理解的行为(就像为什么要做它在做什么,而不是我需要做的事情...)。请查看这些定位者:

  1. div.view_header ~ div input.my_button

  2. div:contains(My Header Title) ~ div input.my_button

  3. div:contains(My Header Title) ~ div div div input.my_button

在我的dom中,匹配每个定位器的第一部分的元素是相同的...

<div class="view_header foo">    My Header Title  </div>

问题是,上面只有1&#3的定位器实际上才能匹配任何内容。有人知道为什么这是真的。我意识到这一点 div:contains(foo) 不仅将匹配实际包含foo的DIV,而且还匹配所有父级Divs,而且在我看来,其余的定位器元素应该对其进行整理,以便它可以工作。

我只是在寻找任何洞察力,并可能提出建议,以确保“ my_button'我点击的“ my_button”是“我的标题”下的一个,而不是页面上其他地方的“ my_button”(也是唯一的简单简单区分它们的方法是通过它们所处的标题),同时消除定位器中看似过量的DOM结构,从而使其更有可能重复使用。

<head>
<body class="bp">
  <div style="left: -100em; position: absolute; width: 100em;"></div>
  <input class="refresh_marker" type="text" value="no" style="display:none">
  <div class="container">
    <div id="nav_bar">
    <div id="user_bar">
    <div id="wrapper" style="border-radius: 10px 10px 10px 10px;">
      <div class="content">
        <div class="page_title"> Title </div>
        <div></div>
        <a class="change_tracker_link"> &nbsp; </a>
        <div class="breadcrumb_trail">
        <style type="text/css">
        <div id="dialog_no_new_assoc" class="hide" title="No Associations Selected"></div>
        <div class="organizer_widget root_organizer" title="WorkflowItem" style="">
          <input id="data_classifier" type="hidden" value="Workflow::WorkflowItem">
          <input id="data_id" type="hidden" value="34">
          <input id="data_getter" type="hidden">
          <input id="collection_vertex_id" type="hidden" value="4cb1ecc300fa5f77844b1e87431d0a25390c1c77">
          <input id="view-name" type="hidden" value="EnterPaperInformation">
          <div class="object organizer">
            <div class="clear"></div>
            <div class="interior">
              <form method="POST" enctype="multipart/form-data">
                <input type="hidden" value="4cb1ecc300fa5f77844b1e87431d0a25390c1c77" name="vertex_id">
                <input type="submit" value="Save" style="display: none;" name="submit_form">
                <div class="organizer_header view_header"> My Header Title </div>
                <div class="organizer_widget" title="Citation" style="">
                  <input id="data_classifier" type="hidden" value="Bibliography::Citation">
                  <input id="data_id" type="hidden" value="10">
                  <input id="data_getter" type="hidden" value="citation">
                  <input id="collection_vertex_id" type="hidden" value="5376dcc81102a5d76bf829513b096be8f67e560d">
                  <input id="view-name" type="hidden" value="CitationEntrySummary">
                  <div id="citation" class="object organizer">
                    <div class="clear"></div>
                    <div class="interior">
                      <div id="Citation___id_widget" class="widget_row numeric">
                      <div id="Citation___title_widget" class="widget_row string">
                      <div id="Citation___abbreviated_title_widget" class="widget_row string">
                      <div id="Citation___authors_display_string_widget" class="widget_row string">
                      <div id="Citation___language_widget" class="widget_row choice">
                      <div id="Citation___link_widget" class="widget_row link">
                      <input type="hidden" value="Bibliography::JournalArticle___10" name="check_5376dcc81102a5d76bf829513b096be8f67e560d[]">
                      <input id="ba_citation" class="my_button" type="button" value="Break Associations" name="break_assoc_5376dcc81102a5d76bf829513b096be8f67e560d">
                      <div class="clear"></div>
                      <input type="hidden" value="5376dcc81102a5d76bf829513b096be8f67e560d" name="vertices[]">
                    </div>
                  ...
有帮助吗?

解决方案

当我发现自己遇到这种麻烦时,我通常要做的就是看规格。

您可能知道, 没有 :contains() 在当前规格中 因此,您依靠特定浏览器/解析器的无证件,未指定的功能。它 应该 工作,但事实并非如此 - 显然,实施尚未完成。现在伪级消失了。

你能去 XPATH 反而?通过内部硒方法或 JavaScript. 。此XPath与您的CSS选择器编号2相同:

//div[contains(text(),'My Header Title')]/following-sibling::div//input[contains(@class,'my_button')]

编辑

在您的评论向我表明我们谈论的是Selenium RC,因此,我更深入地挖了。

我以您的榜样为例,将其从隐藏和(看似)不必要的元素中剥离,并留下了:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <script src="sizzle.js" type="text/javascript"></script>
</head>

<body class="bp">
  <div class="container">
    <div id="nav_bar">
    <div id="user_bar">
    <div id="wrapper" style="border-radius: 10px 10px 10px 10px;">
      <div class="content">
        <div class="breadcrumb_trail">
        <div class="organizer_widget root_organizer" title="WorkflowItem" style="">
          <div class="object organizer">
            <div class="interior">
              <form method="POST" enctype="multipart/form-data">
                <div class="organizer_header view_header">    My Header Title  </div>
                <div class="organizer_widget" title="Citation" style="">
                  <div id="citation" class="object organizer">
                    <div class="clear"></div>
                    <div class="interior">
                      <div id="Citation___id_widget" class="widget_row numeric">
                      <div id="Citation___title_widget" class="widget_row string">
                      <div id="Citation___abbreviated_title_widget" class="widget_row string">
                      <div id="Citation___authors_display_string_widget" class="widget_row string">
                      <div id="Citation___language_widget" class="widget_row choice">
                      <div id="Citation___link_widget" class="widget_row link">
                      <input id="ba_citation" class="my_button" type="button" value="Break Associations" name="break_assoc_5376dcc81102a5d76bf829513b096be8f67e560d" />
                      <div class="clear"></div>
                      </div></div></div></div></div></div>
                    </div>
                  </div>
                </div>
              </form>
            </div>
          </div>
        </div>
        </div>
      </div>
    </div>
    </div>
    </div>
  </div>
</body>

</html>

我下载了 最新的嘶嘶声 我得到了 Selenium在当前版本中实际使用的Sizzle版本.

事实证明,这两个是非常不同的。

例如 contains 当前嘶嘶声的实施:

return ~( elem.textContent || elem.innerText || getText( elem ) ).indexOf( match[3] );

和实施硒用途:

return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;

我在测试文档上尝试了两个实现,可以在此处看到结果(单击以放大):

当前的嘶嘶声 - 完美匹配Current Sizzle Results

硒的嘶嘶声 - 匹配4分之一Selenium's Sizzle Results


结果说明了一切。硒使用旧版本的嘶嘶声,在处理方面不完美 :contains() 伪级。当前的Sizzle版本不会遭受该错误的影响,并且能够很好地找到所有元素。

现在,您可以做任何事情:

  1. 提交硒错误。
  2. 使用XPath作为解决方法。
  3. 切换 sizzle.js 在您的硒包中归档。

其他提示

#Selenium #Webdriver handle only HTML elements but with using java script executor It's possible to handle #pseudo elements in selenium #webdriver. 

Ex: :after , :before etc

String script = "return window.getComputedStyle(document.querySelector('Enter root classname here'),':after / :before').getPropertyValue('content')";
Thread.sleep(3000);
JavascriptExecutor js = (JavascriptExecutor) driver;
String content = (String) js.executeScript(script);
System.out.println(content);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top