Selenium Webdriver:如何从表列表 (Java) 中单击特定行的隐藏元素?
Selenium Webdriver: How to click on a hidden element of a specific row from a tablelist (Java)?
我对 java 和 selenium 很陌生,希望尽可能清楚。
测试场景:
添加类别(例如:TestCategoryName)、验证类别的创建、删除类别、验证类别的删除。
工作原理: 创建类别后,创建的类别将显示在 table 末尾的附加行中。 table 显然包含所有创建的类别,但 table 的每一行包含三个元素:
- 创建的类别名称
- 在创建的类别名称下方,有两个隐藏元素:“编辑”和“删除”选项。这两个选项仅在用户将鼠标移动到包含一个类别的特定行时可见,例如“类别名称”。
PS:我不能点击类别名称,否则我会访问另一个页面。
我的难点:我只需要删除一个类别,也就是最后创建的类别(例如table的最后一行)。但是,即使“删除”选项(=“Löschen”)可以“看到”,也不会被点击。
似乎我只能找到 table 的所有“Löschen”选项(“删除”选项),但我无法单击该特定类别“TestCategoryName”的那个特定“Löschen”。
前面描述的 table 的代码本身如下所示:
<tbody id="the-list" data-wp-lists="list:tag">
<tr id="tag-1">_</tr
<tr id="tag-1">_</tr
<tr id="tag-1">_</tr
<tr id="tag-1">_</tr
<tr id="tag-1">_</tr
<tr id="tag-1">_</tr
<tr id="tag-1">_</tr
<tr id="tag-1">
<th scope="row" class="check-column">_</th>
<td data-colname="Name" class="name column-name has-row-actions column-primary">
<strong>
<a href="#/projects/active?category=172" class="row-title">TestCategoryName</a>
</strong>
<div class="row-actions">
<span class="edit">
<a href="#">Bearbeiten</a>
" |
<a href="#">Löschen</a>
</span>
</div>
</td>
- 类别列在 table 中,没有真实 ID,可以通过类别名称识别它们。
- 选项“编辑”(“Bearbeiten”)和“删除”(“Löschen”)没有直接“链接”到类别名称。
调试时,无论我编写什么代码(我尝试使用 size()、equals、loops 和互联网上提供的其他解决方案...),我的测试总是在尝试“单击”时抛出异常“删除”选项:
这里是要点击特定类别的“删除”选项的方法草稿之一(当然不行):
/**
* Deletes the created category.
*
* @param categoryName
*/
public void deleteNewCategory(String categoryName) {
System.out.println("--- Delete Created Category ---");
// int rowCount = driver.findElements(By.xpath(CATEGORY_LIST_FIELD)).size();
// int rowNumber = driver.findElements(By.xpath(String.format(CATEGORY_LIST_NAME, categoryName))).size();
WebElement element1 = driver.findElement(By.xpath(String.format(CATEGORY_LIST_NAME, categoryName)));
WebElement element2 = driver.findElement(By.xpath(CATEGORY_DELETE_OPTION));
Actions builder = new Actions(driver);
builder.moveToElement(element1).moveToElement(element2).pause(1000).click().build().perform();
driver.switchTo().alert().accept();
}
这是 Xpath(“删除”选项的 Xpath 可能不够具体,可能需要特定的 //tr):
private static final String CATEGORIES_LIST_CONTAINER = "//tbody[contains(@id, 'the-list')]";
private static final String CATEGORY_LIST_FIELD = CATEGORIES_LIST_CONTAINER + "//tr";
private static final String CATEGORY_LIST_NAME = CATEGORIES_LIST_CONTAINER + "//a[contains(text(), '%s')]";
private static final String CATEGORY_DELETE_OPTION = "//a[@innertext='Löschen']";
这是我调试的 invokeMethod:
/**
* @see org.junit.platform.commons.support.ReflectionSupport#invokeMethod(Method, Object, Object...)
*/
public static Object invokeMethod(Method method, Object target, Object... args) {
Preconditions.notNull(method, "Method must not be null");
Preconditions.condition((target != null || isStatic(method)),
() -> String.format("Cannot invoke non-static method [%s] on a null target.", method.toGenericString()));
try {
return makeAccessible(method).invoke(target, args);
}
catch (Throwable t) {
throw ExceptionUtils.throwAsUncheckedException(getUnderlyingCause(t));
}
尝试下面的 xpath-
//a[text()='TestCategoryName']/parent::*/following-sibling::div/span[@class='edit']//a[text()='Löschen']
我对 java 和 selenium 很陌生,希望尽可能清楚。
测试场景: 添加类别(例如:TestCategoryName)、验证类别的创建、删除类别、验证类别的删除。
工作原理: 创建类别后,创建的类别将显示在 table 末尾的附加行中。 table 显然包含所有创建的类别,但 table 的每一行包含三个元素:
- 创建的类别名称
- 在创建的类别名称下方,有两个隐藏元素:“编辑”和“删除”选项。这两个选项仅在用户将鼠标移动到包含一个类别的特定行时可见,例如“类别名称”。
PS:我不能点击类别名称,否则我会访问另一个页面。
我的难点:我只需要删除一个类别,也就是最后创建的类别(例如table的最后一行)。但是,即使“删除”选项(=“Löschen”)可以“看到”,也不会被点击。 似乎我只能找到 table 的所有“Löschen”选项(“删除”选项),但我无法单击该特定类别“TestCategoryName”的那个特定“Löschen”。
前面描述的 table 的代码本身如下所示:
<tbody id="the-list" data-wp-lists="list:tag">
<tr id="tag-1">_</tr
<tr id="tag-1">_</tr
<tr id="tag-1">_</tr
<tr id="tag-1">_</tr
<tr id="tag-1">_</tr
<tr id="tag-1">_</tr
<tr id="tag-1">_</tr
<tr id="tag-1">
<th scope="row" class="check-column">_</th>
<td data-colname="Name" class="name column-name has-row-actions column-primary">
<strong>
<a href="#/projects/active?category=172" class="row-title">TestCategoryName</a>
</strong>
<div class="row-actions">
<span class="edit">
<a href="#">Bearbeiten</a>
" |
<a href="#">Löschen</a>
</span>
</div>
</td>
- 类别列在 table 中,没有真实 ID,可以通过类别名称识别它们。
- 选项“编辑”(“Bearbeiten”)和“删除”(“Löschen”)没有直接“链接”到类别名称。
调试时,无论我编写什么代码(我尝试使用 size()、equals、loops 和互联网上提供的其他解决方案...),我的测试总是在尝试“单击”时抛出异常“删除”选项:
这里是要点击特定类别的“删除”选项的方法草稿之一(当然不行):
/**
* Deletes the created category.
*
* @param categoryName
*/
public void deleteNewCategory(String categoryName) {
System.out.println("--- Delete Created Category ---");
// int rowCount = driver.findElements(By.xpath(CATEGORY_LIST_FIELD)).size();
// int rowNumber = driver.findElements(By.xpath(String.format(CATEGORY_LIST_NAME, categoryName))).size();
WebElement element1 = driver.findElement(By.xpath(String.format(CATEGORY_LIST_NAME, categoryName)));
WebElement element2 = driver.findElement(By.xpath(CATEGORY_DELETE_OPTION));
Actions builder = new Actions(driver);
builder.moveToElement(element1).moveToElement(element2).pause(1000).click().build().perform();
driver.switchTo().alert().accept();
}
这是 Xpath(“删除”选项的 Xpath 可能不够具体,可能需要特定的 //tr):
private static final String CATEGORIES_LIST_CONTAINER = "//tbody[contains(@id, 'the-list')]";
private static final String CATEGORY_LIST_FIELD = CATEGORIES_LIST_CONTAINER + "//tr";
private static final String CATEGORY_LIST_NAME = CATEGORIES_LIST_CONTAINER + "//a[contains(text(), '%s')]";
private static final String CATEGORY_DELETE_OPTION = "//a[@innertext='Löschen']";
这是我调试的 invokeMethod:
/**
* @see org.junit.platform.commons.support.ReflectionSupport#invokeMethod(Method, Object, Object...)
*/
public static Object invokeMethod(Method method, Object target, Object... args) {
Preconditions.notNull(method, "Method must not be null");
Preconditions.condition((target != null || isStatic(method)),
() -> String.format("Cannot invoke non-static method [%s] on a null target.", method.toGenericString()));
try {
return makeAccessible(method).invoke(target, args);
}
catch (Throwable t) {
throw ExceptionUtils.throwAsUncheckedException(getUnderlyingCause(t));
}
尝试下面的 xpath-
//a[text()='TestCategoryName']/parent::*/following-sibling::div/span[@class='edit']//a[text()='Löschen']