当前位置: 首页 > 知识库问答 >
问题:

不一致错误:元素未附加到页面文档

傅越
2023-03-14

我知道这是一个重复的问题,但我没有得到解决方案,因此再问一次。

我正在使用selenium C#,并在同一页面上的同一个操作中得到上述错误。我的测试在本地机器上运行良好,但当我通过TFS在服务器上执行时,相同的测试不一致。

我在测试中做了一些更改,因为它在单击操作后重新加载DOM,现在我在本地机器上重新加载对象后检查它是否正常工作,但在服务器上不一致。如果选中了复选框,我需要取消选中。我在包含此复选框的表上使用“/*[@type='checkbox']”获取复选框组(CB)。

但这产生了同样的错误,所以我改变了我的方法,后来从与复选框相邻的文本中删除了单个复选框,但这种方式不一致,并且在我的本地机器上工作,但在服务器上不工作。

不确定这是怎么发生的。我需要在多个测试中执行这个操作,所以我编写了一个公共函数来取消选中CB

以下是要单击复选框的超文本标记语言

    <tr>	<td>
            <input id="ContentPlaceHolder1_cblModules_0" type="checkbox" name="ctl00$ContentPlaceHolder1$cblModules$0" checked="checked" onclick="javascript:setTimeout('__doPostBack(\'ctl00$ContentPlaceHolder1$cblModules$0\',\'\')', 0)" value="0"><label for="ContentPlaceHolder1_cblModules_0">Collector</label>
            </td>
    </tr>
    <tr>	<td>
            <input id="ContentPlaceHolder1_cblModules_1" type="checkbox" name="ctl00$ContentPlaceHolder1$cblModules$1" onclick="javascript:setTimeout('__doPostBack(\'ctl00$ContentPlaceHolder1$cblModules$1\',\'\')', 0)" value="1">
            <label for="ContentPlaceHolder1_cblModules_1">Maintenance</label>
            </td>
    </tr>
    <tr>	<td>
            <input id="ContentPlaceHolder1_cblModules_2" type="checkbox" name="ctl00$ContentPlaceHolder1$cblModules$2" onclick="javascript:setTimeout('__doPostBack(\'ctl00$ContentPlaceHolder1$cblModules$2\',\'\')', 0)" value="2">
            <label for="ContentPlaceHolder1_cblModules_2">Manager</label>
            </td>
</tr>

我尝试的第一种方法

string checkboxList = ".//*[@id='ContentPlaceHolder1_cblModules' and @class = 'checkBoxList']";
IWebElement e1 = SeeElement.GetElement(driver,checkboxList);// internal function to get element
string CBchecked =".//*[@type='checkbox']";
IReadOnlyCollection<IWebElement> ele1 = e1.FindElements(By.XPath(CBchecked));
foreach (IWebElement e in ele1)
                {
                    string isChecked = e.GetAttribute("checked");
                    if (isChecked != null)
                    {
                        e.Click();                            
                    }
                }

这里我得到了同样的错误,所以我改变了方法

 List<string> checkedItems = new List<string>();
 string checkboxList = ".//*[@id='ContentPlaceHolder1_cblModules' and @class = 'checkBoxList']";
 string CBchecked = checkboxList+"//input[@type='checkbox']/following-sibling::label";
IReadOnlyCollection<IWebElement> ele1 = driver.FindElements(By.XPath(CBchecked));
        foreach (IWebElement e in ele1){ checkedItems.Add(e.Text); }
        foreach (string s in checkedItems)
        {
            string xPath;
            xPath = "//*[text()='" + s + "']/preceding-sibling::input[@type='checkbox']";
            IWebElement e;
            e = driver.FindElement(By.XPath(xPath));
            string isChecked = e.GetAttribute("checked");
            if (isChecked != null)
            {
                e.Click();
            }
        }

这在我的本地机器上工作正常,但在服务器上不工作。在一些随机运行中,它在一个测试中执行,而在另一个测试中失败。

不知道为什么会这样。

谢谢,艾美

共有1个答案

韩彬
2023-03-14

这是自动化测试中的一个众所周知的错误,过时的元素异常,您不应该在循环中使用对象的列表/数组/集合来更改页面。

当页面更改时,您当前的所有对象都不会绑定到对象页面,因为它们不是同一个对象。

每次单击之前都需要找到元素。

你应该用do whileif搭配,应该看起来像(我没有用过c#所以你可能需要做一些改变)

do
   string checked = driver.FindElement(By.XPath(xPath_for_checked));

   if (checked != null)
       {
            checked .Click();
       }

while (checked != null)

选择器应该是:

xpath://输入[包含(@id,'ContentPlaceHolder')][@checked]

CSS:输入[id*=ContentPlaceHolder][选中]

 类似资料:
  • 我正在尝试访问一系列的网页和递归。访问一个页面,然后返回,然后移动到下一个页面,依此类推。用我的代码,我可以访问第一页,然后返回到上一页,但我不能访问下一页,并得到一个陈旧的元素引用错误。我通读了关于这个错误的答案,但仍然不知道我的代码在哪里更改了状态... 下面是我的代码

  • 我在Minim Developer上发现了一种奇怪的行为;当我在控制台中运行以下代码时: Minium能够填写“描述”字段 但是,当我尝试在步骤定义中运行相同的代码时,出现以下错误: org . Mozilla . JavaScript . Wrapped exception:Wrapped org . open QA . selenium . staleelementreferenceexcep

  • 我正在使用C#和Selenium Chromedriver来做一个测试项目,以抓取谷歌地图。 在到达第二个循环之前,它运行良好: 返回: OpenQA. Selenium.过时元素引用:元素未附加到页面文档 这是我所有的代码: 任何帮助将不胜感激!

  • 我正在网页上做分页。其中20个帐户已经加载到页面上,在再次单击该按钮后,又加载了20个帐户。第三次点击后,按钮从网页上消失,所有帐户都已加载。但我得到以下错误: “org.openqa.selenium.staleElementReferenceException:过时元素引用:元素未附加到页面文档”

  • 我得到了这个错误,当我试图点击一个下拉ID: 我想用这个代码: 有没有什么方法可以防止无限循环,或者更好的方法在我得到这个异常后点击id?

  • 我正在构建一个刮网站的c#应用程序。我认为这个问题是因为页面在一次又一次提交表单后被重新加载而导致的。我必须从选择列表中选择一个选项,然后按回车键,等待页面重新加载新结果。但是重新加载后会导致此错误; 我的代码是这样的; 我也尝试过类似的东西; 时间不多了,我有个例外,时间不多了。