繁体   English   中英

找不到包含一些文本的元素

[英]Can't find element contains some text

有一点页面:

 <label> <input type="checkbox"> </input> " some text" </label>

我需要找到一个包含“一些文本”的元素。 如果我使用

WebElement().ByXPath("//div/label[contains(text(),'some text')]");

但这并没有给出结果。 找不到元素。

但是!! 如果我尝试为这样的元素获取属性(InnerHTML、GetText、innerText)

    WebElement.ByXPath("//div/label").GetAttribute("InnerHTML"/"innerText");
   WebElement.ByXPath("//div/label").Text; 

有正确的结果 (WebElement.ByXPath("//div/label").Text=="some text")!

对于此 XPath 元素:

WebElement().ByXPath("//div/label[contains(@innerHtml,'some text')]");
WebElement().ByXPath("//div/label[contains(@innerText,'some text')]");

它也不起作用。

为什么这是可能的? 为什么我无法通过页面上的唯一文本找到元素?

您的 xpath 似乎正确,但不查看您的页面我无法判断。 您的示例适用于此 stackoverflow 页面:

//p[contains(text(), 'Why is this possible?')]

我知道这是有效的,因为我使用 FireFox 的 FirePath 扩展对其进行了测试。 尝试使用它来测试它: https : //addons.mozilla.org/en-US/firefox/addon/firepath/

可能是因为在元素显示之前页面没有完全加载,在构建 selenium 测试时你会遇到不是错误的错误,只是浏览器和速度不一致。 您可以通过构建稳定的代码来为无法找到的项目做好准备。

等待功能有帮助

public IWebElement WaitForElement(By element)
    {
            return new WebDriverWait(this.browser,
                TimeSpan.FromSeconds(10)).
                Until(ExpectedConditions.
                ElementIsVisible(element));
    }

如果您认为需要,您还可以通过允许您的程序刷新页面并在失败时再次尝试测试来准备,双重检查的方法。

对于我总是使用的 xpath,如果它们没有名称或 ID

By.Xpath("//*[contains(text(), 'Some Text')]");

我不确定是什么导致了这个问题,但我同意有时会有一个。 我建议您尝试以下操作:

//div//label[contains(node(),'some text')]

或者,正如redp建议的那样,您可以使用*但请确保正确指定父元素,以防您的页面有多个具有相同文本的标签:

//div//*[contains(node(),'some text')]

如果没记错的话,您可以使用contains(.,'some text')插入contains(node(),'some text)' 此外,请考虑在检查器工具中仔细检查您的元素,注意查看“属性”选项卡。 而且,请记住,您可以在Inspector 中使用搜索找到您的元素,这将为您节省大量时间。

如果这对您有帮助,请更新我。

那应该在“一些文本”周围有一个跨度标签。 这只是糟糕的 html 标记。

您还可以使用:

//label/text()[last()]
//label/text()[2]

html 确实不是很好的实践,但它无处不在,人们必须处理它。 我认为这里有帮助的是normalize-space() 在具有该 html 的页面上的 chrome 控制台中尝试此操作:

$x(`//label[contains(normalize-space(), "some text")]`);

我认为上面的代码分解为:

  1. 查找所有label节点
  2. 对于每个节点
    1. 获取该节点及其后代节点内的所有text节点
    2. 结合他们的文字
    3. 从每个文本节点中的文本中删除多余的空格
    4. 如果我想要的确切字符串(“一些文本”)在那里,则将该label添加到要返回的节点列表中。
  3. 返回包含该文本的所有节点的列表(如果不匹配则返回空列表)

为了更复杂一点,如果我想找到作为具有“某些文本”的text节点的直接父节点的节点,我可以这样做:

$x(`//label//text()[contains(normalize-space(), "some text")]/..`);

不过,这变得很棘手。 对于包含给定字符串的每个text节点,它都会获得直接父节点。 它适用于此,因为“一些文本”都在一个text节点中。 在其他情况下,它可能会绊倒某人。 例如,看看这个 html:

<label>
  <span> text </span>
  some other text
</label>

作为人类,我可以阅读“给其他文字发短信”,所以我似乎应该能够找到“给其他文字发短信”的父级。 如果我使用第一种方法查找其中包含“text some”的label ,则此代码会发现该label很好:

$x(`//label[contains(normalize-space(), "text some")]`);

那是因为所有文本节点的组合中确实包含“text some”。 不过,我不能使用第二种方法。 例如,在该 html 上使用此代码只会给我一个空列表:

$x(`//label//text()[contains(normalize-space(), "text some")]/..`);

那是因为当 xpath 在每个单独的text节点中查找时,它们中没有一个包含“text some”。 如果我仔细想想,“给一些人发短信”实际上并没有一个直系父母。 它有两个直系父母。 xpath 选择不给父母,而不是给他们两个。 似乎很公平。

我还没有找到对normalize-space()任何很好的解释,我不知道为什么它结合了其所有后代节点的文本。 至于为什么text()不起作用,我从 2014 年找到了这个答案:

text()child::text()缩写,它选择作为标签元素的直接子元素的文本节点。 -- https://stackoverflow.com/a/26823289/14144258

可能还是对的。

另外,我知道这是一个老问题,但是我在尝试对自己的代码进行故障排除时遇到了同样的问题,并且花了很长时间才找到解决方案。

暂无
暂无

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

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