【问题标题】:How to send text within a webtable cell using Selenium and Java如何使用 Selenium 和 Java 在 webtable 单元格中发送文本
【发布时间】:2020-06-09 23:41:31
【问题描述】:

我正在尝试将值“100”发送到表的位置(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");
            }
        }
    }
} 

【问题讨论】:

    标签: java selenium xpath webdriver webdriverwait


    【解决方案1】:

    你的循环逻辑是正确的,但是你的代码产生了这个错误:

    org.openqa.selenium.InvalidElementStateException: invalid element state

    您需要先click,然后再对该元素执行下一步操作才能成为可编辑元素,并且您必须使用Actions 类与之交互:

    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)")
    

    【讨论】:

    • 您好,谢谢您的回答。它对我有用。代码 [List inputTable = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//*[@id='var_a_EXL']//tbody//tr"))); ] 对我来说是 neu,但我现在会尝试理解和学习它:)
    【解决方案2】:

    您没有提到您面临的错误。提及该错误将有助于我们构建一个更规范的答案。当您尝试在 &lt;td&gt; 元素上调用 clear() 时,您可能正面临 InvalidElementStateException

    但是,要将字符串 100 发送到表的位置(行:2,z 列),您需要为elementToBeClickable() 诱导WebDriverWait,您可以使用以下@987654322 @:

    • 使用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");
      
    • 浏览器快照:


    行号和列号作为变量

    rowcolumn 数字视为变量:

    • 代码块:

      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");
      

    【讨论】:

    • 是的,我使用过(TypeScript 和 Protractor),我可以理解。但在 Java 中,这对我来说还是新的。感谢您的帮助。我要学习它:)
    【解决方案3】:

    +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));
                    }
    
                }
            }
    
        }
    

    【讨论】:

    • 感谢您的回答。它不适用于以下代码: js.executeScript("arguments[0].innerText = '300'", columns.get(i));但解决方案很有趣。我会针对我的情况进行分析
    • 天哪,我刚刚尝试了这段代码,它的工作完美无瑕,你遇到了什么错误?这是我的完整代码link
    • 您好,我的作用域是向表格的位置(x 行,y 列)发送一个值(例如:100)。但是使用您的代码,我成为位置的实际文本(第 x 行,第 y 列)
    • 公平地说,我已经更新了代码并调出了外部位置的变量,所以你现在可以在任何地方更新
    • 啊,好的。它工作正常。使用您的解决方案,我想我可以创建一个小函数来定位表的任何节点,然后在 Main 中我可以用它做任何事情。很好。非常感谢:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-13
    • 2023-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-02
    • 1970-01-01
    相关资源
    最近更新 更多