【问题标题】:sendKeys() not inserting the full value using WebDriverWait through Selenium and JavasendKeys() 未通过 Selenium 和 Java 使用 WebDriverWait 插入完整值
【发布时间】:2019-08-26 09:19:15
【问题描述】:

sendKeys() 没有将完整的字符串插入文本字段。我正在尝试插入电子邮件 ID。

String name = "New Apollo33";
fluent_wait.until(ExpectedConditions.presenceOfElementLocated(By.id("businessname"))).sendKeys(name);

String email = "apollo33@mailinator.com";
fluent_wait.until(ExpectedConditions.presenceOfElementLocated(By.id("businessemail"))).sendKeys(email);

它正在插入名称,但没有完全插入电子邮件 ID。

【问题讨论】:

  • 您应该考虑将其分解为至少两个步骤,也许更多。使用流畅的等待,创建 WebElement,清除文本,发送文本。您没有清除任何预先存在的文本。这不是问题,但是将其他三个步骤合二为一并不总是最好的主意。
  • 另外,存在只是意味着元素在 DOM 中,而不是可见等。

标签: java selenium selenium-webdriver webdriver webdriverwait


【解决方案1】:

我经常发现 sendKeys() 移动太快或输入不完整的字符串。 您需要将其包装在一个 while 循环中,延迟非常小:

while(element.text != input) {
    element.sendKeys(Keys.chord(Keys.CONTROL, "a"), input); //or whatever
    Thread.sleep(100) //100ms not 100sec
}

我知道 thread.sleep 非常不受欢迎,但是 waitFor() 会花费同样长的时间

element.clear()

也可以,但同时使用 clear() 或 Ctrl+a + 输入是多余的

【讨论】:

  • 正如 OP 所指出的,部分文本正在制作,而不是全部,而且他没有事先清除文本(你也不是)。这可能会继续污染文本并陷入无限循环。
  • 这仍然很容易陷入无限循环。你没有退出while。最好一次发送一个字符,在字符之间稍作停顿,然后在最后断言字符串是否完整。
  • im 是为了快速阅读,而不是一次遍历一个字符的字符串。无论是否笨拙,这种方法都会让用户再次移动。如果我们被困在一个循环中,我们等待的时间还不够长。如果 OP 想要一个可靠的方法,他们应该自己覆盖 sendkeys。
【解决方案2】:

我在输入预先格式化的电话号码字段时自动化我的一个测试用例时遇到了类似的问题。这是我为确保脚本能够在文本框中输入文本所做的操作:

  • 手动检查文本框是否接受脚本尝试输入的文本长度。检查两次永远不会有什么坏处:)。
  • 使用 sendKeys 输入值并从 DOM 中获取元素的值。
  • 当 DOM 中文本框元素的值与您尝试输入的文本不相等时,请重试。
  • 确保在 while 循环中设置退出条件,以便有退出测试的方法。

你的实现可以是这样的:

Wait<WebDriver> fluent_wait = new FluentWait<WebDriver>(driver)
                           .withTimeout(60, SECONDS)
                           .pollingEvery(2, SECONDS) 
                           .ignoring(NoSuchElementException.class);

WebElement emailElement= fluent_wait.until(new Function<WebDriver, WebElement>() {

     public WebElement apply(WebDriver driver) {
     return driver.findElement(By.id("businessemail"));
}
});
String emailText = "apollo33@mailinator.com";
long startTime = System.currentTimeMillis(); // This is to run the while loop for a specified amount of time and use it as an exit condition for the while loop.

//the below condition assumes that the text box sets some kind of attribute in the DOM element once the user enters the value in the text box.
while(!emailElement.getAttribute("value").equals(emailText)&&System.currentTimeMillis() - startTime) < 2000){
     emailElement.clear();
     emailElement.sendKeys(emailText);
}
//if the above doesn't work, add the below as a fall back:
if(!emailElement.getAttribute("value").equals(emailText)){
    emailElement.clear();
    for(char ch: emailText.toCharArray()){
        emailElement.sendKeys(String.valueOf(ch));
        try{
           Thread.sleep(15); //making the thread sleep for 15 milliseconds, taking a performance hit to make the sendKeys work.
        }catch(InterruptedException e){
        }
    }
}

只有当 while 循环无法在 2 秒内设置文本框中的文本时,才会执行带有 Thread.sleep 的回退条件。如果 2 秒/2000 毫秒不够,您可以增加时间。 thread.sleep 在每个字符迭代之间只有 15 毫秒的微小命中。我们将其合并到我们的框架中,以涵盖使用不同前端技术开发的各种文本框。这对我们这个组织来说很好,所以希望它也对你有用。

上面的关键是不要被 selenium 提供的预定义实用程序所困扰,相反,您应该使用 Java 提供的 DOM 值和选项。希望您能够尽快找到解决问题的方法。 祝你好运!

【讨论】:

    【解决方案3】:

    作为拇指规则,在尝试发送字符序列而不是调用presenceOfElementLocated()时,始终调用elementToBeClickable(),您可以使用以下解决方案:

    fluent_wait.until(ExpectedConditions.elementToBeClickable(By.id("businessname"))).sendKeys("New Apollo33");
    fluent_wait.until(ExpectedConditions.elementToBeClickable(By.id("businessemail"))).sendKeys("apollo33@mailinator.com");
    

    【讨论】:

      【解决方案4】:

      我遇到了同样的问题。 sendKeys-Keys.chord 没有插入完整值(速度太快以至于浏览器甚至“有时”都没有时间编写它)

      之前:(不能 100% 工作)

      action.sendKeys(Keys.chord("string")).perform();
      

      编写“字符串”时速度太快了。有时(例如从 1/5 到 1/10 次)它在我发送到的网站上看起来不完整。这很令人沮丧..

      我尝试应用的解决方案为我工作了几天,但最终发生了同样的情况(1/20,但失败了)我尝试的解决方案只是添加一个 sendKeys-Keys.chord 之后的 1.5seg 的“线程休眠”(可能网站需要更多时间来写):

      之后:(不能 100% 工作 - 我也尝试了这个可能的解决方案,它失败的次数更少,但仍然失败 1/20)

      action.sendKeys(Keys.chord("string")).perform();
      Thread.sleep(1500);
      

      最终解决方案:(100% 有效)

      添加一个执行/检查 sendKeys-Keys.chord 是否与浏览器 (WebDriver) 上实际写入的内容匹配的 do-while,如果不匹配,它将再次写入(您现在可以减少来自 Thread.sleep 的延迟)

      WebDriverWait wait = new WebDriverWait(driver,40);
      Actions action = new Actions(driver);
      
        String TextSentenceORWordToIntroduce = "Dinosaur";
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("xpath_to_element"))).click();
        Thread.sleep(200);
        action.sendKeys(Keys.chord(TextSentenceORWordToIntroduce)).perform();
        Thread.sleep(500);
        String comprovation = driver.findElement(By.xpath("xpath_to_element")).getAttribute("value"); // or rarely ")).getText();"
      
      if (!comprovation.contentEquals(TextSentenceORWordToIntroduce)) { // if not then ALL WORKS FINE ;) and won't enter the Do-while
          driver.findElement(By.xpath("xpath_to_element")).click();
          do {
              Thread.sleep(200);
              action.sendKeys(Keys.HOME).perform();
              Thread.sleep(200);
              action.keyDown(Keys.SHIFT).perform();
              Thread.sleep(200);
              action.sendKeys(Keys.END).perform();
              Thread.sleep(200);
              action.keyUp(Keys.SHIFT).perform();
              Thread.sleep(200);
              action.sendKeys(Keys.chord(TextSentenceORWordToIntroduce)).perform();
              Thread.sleep(500);
              comprovation = driver.findElement(By.xpath("xpath_to_element")).getAttribute("value"); // or rarely ")).getText();"
          } while (!comprovation.contentEquals(TextSentenceORWordToIntroduce));
      }
      

      希望这个解决方案可以帮助遇到同样问题的人^^

      干杯!

      【讨论】:

        猜你喜欢
        • 2016-05-15
        • 2020-11-26
        • 1970-01-01
        • 2019-09-20
        • 2021-05-03
        • 1970-01-01
        • 2019-08-02
        • 1970-01-01
        相关资源
        最近更新 更多