Короче говоря, ваша проблема связана с тем, как вы захватываете "столбцы":
IList<IWebElement> columns = _driver.FindElements(By.XPath("//div[@id='data_3']/div/div/div[3]/table/tbody/tr[@class][" + row + "]/td[@class]"));
Я не могу проверить, действительно ли ваш XPath захватывает то, о чем вы думаете, например:
IList<IWebElement> row1 = _driver.FindElements(By.XPath("//*[@id='data_3']/div/div/div[3]/table/tbody/tr [@class][3]/td[@class]"));
Я продолжу с предположением, что ваш XPath делает именно то, для чего предназначен, просто убедитесь, что вы проверяете, что индексируете правильное количество строк и тому подобное. Вы можете сделать свой код немного более разборчивым с некоторыми форматированием строк и простыми функциями:
string xpathTableBase = "//*[@id='data_3']/div/div/div[3]/table/tbody";
// grab all rows
List<IWebElement> tableRows = _driver.FindElements(By.XPath(
$"{xpathTableBase}tr[contains(@class, 'row']"));
// grab the "first" row cells in a list
List<IWebElement> firstRowCells = _driver.FindElements(By.XPath(
$"{xpathTableBase}/tr[@class][3]/td[@class]"));
Возможно, вам будет полезно прочитать некоторые документы: https://www.selenium.dev/selenium/docs/api/dotnet/
Обратите внимание, что вы можете использовать FindElements для объекта, который реализует интерфейс IWebElement
. Если вы захватите каждую из строк таблицы (<tr>
) как IWebElement
, это даст вам доступ к дочерним элементам без создания запутанных циклов.
И только один побочный комментарий, ваш l oop for (int row = 4; row <= rows.Count; row++)
предполагает, что элементы возвращаются в порядке их появления в DOM. В моей практике с Selenium это обычно имеет место, но просто понимаю, что это не гарантируется интерфейсом.
Кажется, что утверждение сравнивает все данные с данными первой строки. Я хочу изменить его так, чтобы формула сравнивалась построчно.
Это сбивает с толку. Вы для l oop итерирует по каждой строке, а затем итерирует по каждой ячейке в этой строке. Затем он сравнивает значение ячейки в столбце j
со значением ячейки в столбце j
первой строки - это именно то поведение, которое вы описываете.
Очистка вашего l oop может помогите понять, что происходит:
// loop through each row in the table, after our "first" row
for (int row = 4; row < tableRows.Count; row++)
{
// grab the cells of the current row
List<IWebElement> cells = tableRows[row].FindElements(By.XPath("//td[@class]"));
// zip the lists to make iterating a little easier
// and prevents indexing issues if the rows don't match in column length
var zippedList = firstRowCells.Zip(cells, (x, y) => (x, y));
foreach((firstCell, cell) in zippedList)
{
Assert.IsTrue(int.Parse(cell.Text) <= int.Parse(firstCell.Text));
}
}
Редактировать:
Если вы говорите, что хотите сравнить СУММУ первого ряда со всеми последующими строками, то вы нужно сделать это в l oop:
// loop through each row in the table, after our "first" row
for (int row = 4; row < tableRows.Count; row++)
{
// grab the cells of the current row
List<IWebElement> cells = tableRows[row].FindElements(By.XPath("//td[@class]"));
int firstRowSum = firstRowCells.Select(x => int.Parse(x.Text)).Sum();
int currentRowSum = cells.Select(x => int.Parse(x.Text)).Sum();
Assert.IsTrue(currentRowSum <= firstRowSum);
}
(отредактированы некоторые опечатки в коде)