我知道这是一个重复的问题,但我没有得到它的解决方案,因此再次询问它。
我正在使用selenium C#并在同一页面上以相同的操作获得上述错误以进行几次测试。 我的测试在我的本地机器上正常工作,但是当我通过TFS在服务器上执行时,相同的测试不一致。
我在测试中进行了更改,因为它在单击操作后重新加载DOM,现在我在本地计算机上重新加载其工作正常后检查对象但在服务器上不一致。 如果选中它们,我需要取消选中复选框。 我正在使用" .// * [@ type ='复选框']"来获取复选框(CB)。在包含此CB的表上。
但是这产生了同样的错误,所以我改变了我的方法,后来又从复选框旁边的文本中设置了单独的复选框,但是这种方式不一致,并且正在我的本地机器上工作但不在服务器上。
不确定这是怎么回事。 我需要在多个测试中执行此操作,因此我编写了一个常用函数来取消选中CB
以下是要点击的复选框的HTML
<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>
&#13;
我的第一个方法我试过
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();
}
}
这在我的本地计算机上工作正常,但不能在服务器上运行。 并且在一些随机运行中,它在一次测试中执行而在其他测试中失败。
不确定为什么会这样。
感谢, amey
答案 0 :(得分:2)
这是自动化测试中的众所周知的错误,陈旧元素异常,您不应该在可以更改页面的循环中使用列表/数组/对象集合。
当页面改变时,所有当前对象都没有绑定到对象页面,因为它不是同一个对象。
每次点击之前都需要找到该元素。
你应该使用带有do-while
的{{1}},看起来应该是这样的(我还没有使用过c#,所以你可能需要做一些更改)
if
,选择器应为:
xpath:do
string checked = driver.FindElement(By.XPath(xPath_for_checked));
if (checked != null)
{
checked .Click();
}
while (checked != null)
css://input[contains(@id, 'ContentPlaceHolder')][@checked]