我正在尝试解决有关单击下一页上制定的某一行的问题:https://testwisely.com/demo/event-table。我通过阅读《Selenium WebDriver Recipes in C#》一书想到了这个问题。我编写了一个页面对象类,如下所示:
public void ClickTableLink(String issueNumber)
{
ReadOnlyCollection<IWebElement> tableRows =
driver.FindElements(
By.XPath(
".//*[@id='complaintsTable']/tbody/tr[contains (@class, 'gridLayoutEvenRow' ) or contains(@class, 'gridLayoutOddRow')]"));
foreach (IWebElement row in tableRows)
{
try
{
row.FindElement(By.XPath("td[contains(text(), '" + issueNumber + "')]"))
.FindElement(By.XPath("//td/a"))
.Click();
break;
}
catch (NoSuchElementException e)
{
}
}
}
问题是,无论我用什么问题编号调用此方法,单击始终位于第一行的链接上。我做错了什么?
根据您关于使用直接方法与使用表格的评论,您也可以使用字符串替换执行以下操作。
Driver.FindElement(By.XPath(string.Format("//td[contains(text(), '{0}')]//preceding-sibling::td/a", issueNumber))).Click();
因为我喜欢答案的优雅,所以我试图得到@JeffC的答案,但没有成功,可能是因为我对 XPath 表达式的了解不够。经过一些更改后,我设法得到了@Dazed 工作的答案。
public void ClickTableLink(String issueNumber)
{
var table = driver.FindElements(By.TagName("tr"));
foreach (var tr in table)
{
var tds = tr.FindElements(By.TagName("td"));
for (var i = 0; i < tds.Count; i++)
{
if (tds[i].Text.Trim().Contains(issueNumber))
{
tds[i - 3].Click();
break;
}
}
}
}
您基本上可以使用 XPath 通过一行代码来完成此操作。 XPath 将查找包含所需问题编号的 TD,查找父 TR,然后查找 id="applicationDateId" 的子 TD。我会将其包装在一个函数中,以便它可以重用。
static void ClickEvent(string issueNumber)
{
Driver.FindElement(By.XPath("//tr[td[contains(., '" + issueNumber + "')]]/td/a")).Click();
}
你会这样称呼它,
ClickEvent("2898");
你可以试试这个。它将循环并找到问题编号。然后,如果您查看
tds[i - 3].Click();
,它将查看问题编号左侧的 3 列并单击它。您可以使用 + 3 转到 issuesNumber 的右侧。只需根据与 issuesNumber 相关的列来更改该值即可。
public void ClickTableLink(String issueNumber)
{
var table = driver.FindElement(By.Id("complaintsTable"));
foreach (var tr in table.FindElements(By.TagName("tr")))
{
var tds = tr.FindElements(By.TagName("td"));
for (var i = 0; i < tds.Count; i++)
{
if (tds[i].Text.Trim().Contains(issueNumber))
{
tds[i - 3].Click();
break;
}
}
}
}