如何使用 Selenium 和 Java 在 webtable 单元格中发送文本
How to send text within a webtable cell using Selenium and Java
我正在尝试将值“100”发送到 Table 的位置 (row: 2, column 3)
,此处:
https://keisan.casio.com/exec/system/13800848854767
下面这段代码,你能告诉我,哪里出了问题吗?
代码:
driver.get("https://keisan.casio.com/exec/system/13800848854767");
List<WebElement> inputTable = driver.findElements(By.xpath("//*[@id='var_a_EXL']//tbody//tr"));
System.out.println(inputTable.size());
List<WebElement> columns;
for (int rows = 0; rows < inputTable.size(); rows++) {
if (rows == 2) {
columns = inputTable.get(rows).findElements(By.tagName("td"));
for (int i = 0; i < columns.size(); i++) {
if (i == 3) {
columns.get(i).clear();
columns.get(i).sendKeys("100");
}
}
}
}
你的循环逻辑是正确的,但是你的代码产生了这个错误:
org.openqa.selenium.InvalidElementStateException: invalid element state
您需要先 click
才能对该元素执行下一步操作才能成为可编辑元素,并且您必须使用 Actions
class 与其交互:
driver.get("https://keisan.casio.com/exec/system/13800848854767");
List<WebElement> inputTable = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//*[@id='var_a_EXL']//tbody//tr")));
System.out.println(inputTable.size());
List<WebElement> columns;
for (int rows = 0; rows < inputTable.size(); rows++) {
if (rows == 2) {
columns = inputTable.get(rows).findElements(By.tagName("td"));
for (int i = 0; i < columns.size(); i++) {
if (i == 3) {
WebElement target = columns.get(i);
Actions actions = new Actions(driver);
actions.moveToElement(target)
.click(target)
.sendKeys("100")
.build()
.perform();
}
}
}
}
而且我还在上面的代码中添加了WebDriverWait
。
以下导入:
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
顺便说一句,这个 xpath //*[@id='var_a_EXL']//tbody//tr[3]//td[4]
有一个更简单的方法,而不是使用上面的循环:
driver.get("https://keisan.casio.com/exec/system/13800848854767");
WebElement target = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id='var_a_EXL']//tbody//tr[3]//td[4]")));
Actions actions = new Actions(driver);
actions.moveToElement(target)
.click(target)
.sendKeys("100")
.build()
.perform();
或使用以下 css 选择器更好地定位元素:
By.cssSelector("#var_a_EXL tr:nth-child(3) td:nth-child(4)")
+1 @frianH 的回答,您的代码不起作用的原因是因为 .clear()
仅当元素是文本输入元素时才起作用。文本输入元素是 INPUT 和 TEXTAREA,这不是您的情况
这是使用 JSExecutor 的更简单方法
List<WebElement> inputTable = driver.findElements(By.xpath("//*[@id='var_a_EXL']//tbody//tr"));
System.out.println(inputTable.size());
List<WebElement> columns;
int rowss = 3;
int columnss = 3;
for (int rows = 0; rows < inputTable.size(); rows++) {
if (rows == rowss) {
columns = inputTable.get(rows).findElements(By.tagName("td"));
System.out.println(columns.size());
for (int i = 0; i < columns.size(); i++) {
if (i == columnss) {
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].innerText = '300'", columns.get(i));
}
}
}
}
您没有提到您面临的错误。提及错误会帮助我们构建一个更规范的答案。当您尝试在 <td>
元素上调用 clear()
时,您可能正面临 InvalidElementStateException
。
但是,要将字符串 100 发送到 table 的位置(行:2,列 z),您需要归纳 for the elementToBeClickable()
and you can use the following :
使用 xpath:
driver.get("https://keisan.casio.com/exec/system/13800848854767");
new WebDriverWait(driver, 5).until(ExpectedConditions.elementToBeClickable(By.xpath("//td/span[@id='var_a_EXL_2_3C']"))).click();
new WebDriverWait(driver, 5).until(ExpectedConditions.elementToBeClickable(By.xpath("//td/input[@id='var_a_EXL_2_3_input']"))).sendKeys("100");
浏览器快照:
行号和列号作为变量
考虑 row
和 column
数字作为变量:
代码块:
driver.get("https://keisan.casio.com/exec/system/13800848854767");
int row = 2;
int column = 3;
new WebDriverWait(driver, 5).until(ExpectedConditions.elementToBeClickable(By.xpath("//td/span[contains(@id, '"+String.valueOf(row)+"') and contains(@id, '"+String.valueOf(column)+"')]"))).click();
new WebDriverWait(driver, 5).until(ExpectedConditions.elementToBeClickable(By.xpath("//td/input[contains(@id, '"+String.valueOf(row)+"') and contains(@id, '"+String.valueOf(column)+"')]"))).sendKeys("100");
我正在尝试将值“100”发送到 Table 的位置 (row: 2, column 3)
,此处:
https://keisan.casio.com/exec/system/13800848854767
下面这段代码,你能告诉我,哪里出了问题吗?
代码:
driver.get("https://keisan.casio.com/exec/system/13800848854767");
List<WebElement> inputTable = driver.findElements(By.xpath("//*[@id='var_a_EXL']//tbody//tr"));
System.out.println(inputTable.size());
List<WebElement> columns;
for (int rows = 0; rows < inputTable.size(); rows++) {
if (rows == 2) {
columns = inputTable.get(rows).findElements(By.tagName("td"));
for (int i = 0; i < columns.size(); i++) {
if (i == 3) {
columns.get(i).clear();
columns.get(i).sendKeys("100");
}
}
}
}
你的循环逻辑是正确的,但是你的代码产生了这个错误:
org.openqa.selenium.InvalidElementStateException: invalid element state
您需要先 click
才能对该元素执行下一步操作才能成为可编辑元素,并且您必须使用 Actions
class 与其交互:
driver.get("https://keisan.casio.com/exec/system/13800848854767");
List<WebElement> inputTable = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//*[@id='var_a_EXL']//tbody//tr")));
System.out.println(inputTable.size());
List<WebElement> columns;
for (int rows = 0; rows < inputTable.size(); rows++) {
if (rows == 2) {
columns = inputTable.get(rows).findElements(By.tagName("td"));
for (int i = 0; i < columns.size(); i++) {
if (i == 3) {
WebElement target = columns.get(i);
Actions actions = new Actions(driver);
actions.moveToElement(target)
.click(target)
.sendKeys("100")
.build()
.perform();
}
}
}
}
而且我还在上面的代码中添加了WebDriverWait
。
以下导入:
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
顺便说一句,这个 xpath //*[@id='var_a_EXL']//tbody//tr[3]//td[4]
有一个更简单的方法,而不是使用上面的循环:
driver.get("https://keisan.casio.com/exec/system/13800848854767");
WebElement target = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id='var_a_EXL']//tbody//tr[3]//td[4]")));
Actions actions = new Actions(driver);
actions.moveToElement(target)
.click(target)
.sendKeys("100")
.build()
.perform();
或使用以下 css 选择器更好地定位元素:
By.cssSelector("#var_a_EXL tr:nth-child(3) td:nth-child(4)")
+1 @frianH 的回答,您的代码不起作用的原因是因为 .clear()
仅当元素是文本输入元素时才起作用。文本输入元素是 INPUT 和 TEXTAREA,这不是您的情况
这是使用 JSExecutor 的更简单方法
List<WebElement> inputTable = driver.findElements(By.xpath("//*[@id='var_a_EXL']//tbody//tr"));
System.out.println(inputTable.size());
List<WebElement> columns;
int rowss = 3;
int columnss = 3;
for (int rows = 0; rows < inputTable.size(); rows++) {
if (rows == rowss) {
columns = inputTable.get(rows).findElements(By.tagName("td"));
System.out.println(columns.size());
for (int i = 0; i < columns.size(); i++) {
if (i == columnss) {
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].innerText = '300'", columns.get(i));
}
}
}
}
您没有提到您面临的错误。提及错误会帮助我们构建一个更规范的答案。当您尝试在 <td>
元素上调用 clear()
时,您可能正面临 InvalidElementStateException
。
但是,要将字符串 100 发送到 table 的位置(行:2,列 z),您需要归纳 elementToBeClickable()
and you can use the following
使用 xpath:
driver.get("https://keisan.casio.com/exec/system/13800848854767"); new WebDriverWait(driver, 5).until(ExpectedConditions.elementToBeClickable(By.xpath("//td/span[@id='var_a_EXL_2_3C']"))).click(); new WebDriverWait(driver, 5).until(ExpectedConditions.elementToBeClickable(By.xpath("//td/input[@id='var_a_EXL_2_3_input']"))).sendKeys("100");
浏览器快照:
行号和列号作为变量
考虑 row
和 column
数字作为变量:
代码块:
driver.get("https://keisan.casio.com/exec/system/13800848854767"); int row = 2; int column = 3; new WebDriverWait(driver, 5).until(ExpectedConditions.elementToBeClickable(By.xpath("//td/span[contains(@id, '"+String.valueOf(row)+"') and contains(@id, '"+String.valueOf(column)+"')]"))).click(); new WebDriverWait(driver, 5).until(ExpectedConditions.elementToBeClickable(By.xpath("//td/input[contains(@id, '"+String.valueOf(row)+"') and contains(@id, '"+String.valueOf(column)+"')]"))).sendKeys("100");