硒未检索元素的当前文本值

时间:2018-07-11 16:17:50

标签: c# selenium selenium-webdriver

我正在使用Selenium和ChromeDriver用C#编写测试应用程序。我有一个网页,该网页使用AJAX加载了多个表的内容,而我的测试希望看到特定的字符串加载到这些表之一的某处。当我使用相同的参数手动执行测试时,可以在屏幕上看到字符串,但是Selenium看不到。

该测试等待jQuery启动然后完成,然后查询表的文本值以查看是否有任何内容与测试字符串匹配。这是问题所在:当它通过innerHTML,innerText,textContent和value属性或元素的.Text属性查询表的文本值时,看不到通过AJAX加载的文本。它看到原始表只是标题。因此,看起来Selenium未能从页面中获取最新的值,Selenium未能在获取AJAX之前就完成了操作,或者其他错误。我该如何调试或更正确地编写查询?

为了进行初步的调试工作,我首先验证了已选择了正确的表,并且jQuery实际上已经开始并完成了,然后像这样设置日志记录,所有这些行在初始时都产生类似的输出表的仅标头版本:

log.Trace(".Text: {0}", selectedElement.Text);
log.Trace("attr innerHTML: {0}", selectedElement.GetAttribute("innerHTML"));
log.Trace("attr innerText: {0}", selectedElement.GetAttribute("innerText"));
log.Trace("attr textContent: {0}", selectedElement.GetAttribute("textContent"));
log.Trace("attr value: {0}", selectedElement.GetAttribute("value"));

此代码等待jQuery启动,然后通过此完成(与实际实现相比,它与对象的ToString进行了比较,略有简化,并且可以在其他地方很好地使用):

string js = "return !!window.jQuery && window.jQuery.active == 0";
waiter.Until(_ => ((IJavaScriptExecutor)_).ExecuteScript(js)
    .ToString().Trim().ToUpper().Equals("FALSE"));
waiter.Until(_ => ((IJavaScriptExecutor)_).ExecuteScript(js)
    .ToString().Trim().ToUpper().Equals("TRUE"));

我现在唯一能想到的是,该特定表的AJAX可能尚未处理,但jQuery完成后又回来了吗?这种可能性没有多大意义,但我不知道如何进行测试以确保确定。

我宁愿不修改站点本身,而是尽可能将所有与测试相关的部分保留在C#测试套件中。

edit:我可以通过检查Chrome中的元素来看到这些值-Inspector中的textContent属性是正确的-但Selenium根本不会用我当前的代码来识别它。我很容易选择表本身,因为Selenium每次都会获取其唯一的标题文本。既然有人问过了,这里是该表的经过净化的版本,它已深深地埋在页面中,并且具有一个唯一的ID,我将使用该ID沿着By.CssSelector(“#thetable”)的行进行选择。 :

<table id='thetable'>
  <colgroup> ... 5x <col> tags ... </colgroup>
  <thead>
    <tr> ... 5x <th> tags ... </tr>
    <tr> ... 5x <th> tags ... </tr>
    <tr><th colspan='5'...> ...</tr>
  </thead>
  <tbody>
    <tr> ... 5x <td> tags, one of which includes the text I look for ... </tr>
    ...
  </tbody>
</table>

前面提到的table元素本身的属性和属性只给我thead部分的文本。

2 个答案:

答案 0 :(得分:0)

如果您正在等待特定的文本,建议您等待文本而不是等待Javascript执行。

请参见下面的代码:

public void TestWaitForText()
{
    IWait<IWebDriver> wait = new DefaultWait<IWebDriver>(driver);
    wait.Timeout = TimeSpan.FromSeconds(10);
    wait.PollingInterval = TimeSpan.FromMilliseconds(300);
    wait.Until(d => isAnyTextAppeared(d));
}

private Boolean isAnyTextAppeared(IWebDriver d)
{
    List<string> textList = new List<string>() { "foo", "bar" };
    foreach(var txt in textList)
    {
        var elems = d.FindElements(By.XPath("//tbody/tr/td[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'" + txt +"')]"));
        if (elems.Count > 0)
        {
            log.Trace(".Text: {0}", elems[0].Text);
            return true;
        }                    
    }
    return false;
}

答案 1 :(得分:0)

我设法解决了问题。

问题是,当您在 arraylist.add(new songs(ID[0], ...)); // didnt paste other variables 元素上查询那些文本属性时,它们会深入到table元素中,然后在返回到thead元素之前返回。这是我们网站上使用JS控制台可验证的浏览器。我不确定为什么会这样,也不确定我没有时间搜索这些信息,但是目前是这样。 (2018年7月7日,Chrome 67)

没有任何等待改变的行为。

解决方案是使用附加了tbody的选择器,例如tbody而不是.thetable tbody,现在选择正确的文本。