Selenium:element.clear()在sendKeys()之前触发javascript
我有一个应该包含日期的输入字段 假设表单在字段内加载了一个值,例如“2015/04/28”。我正在使用webdriver选择使用的元素,然后我执行以下操作:Selenium:element.clear()在sendKeys()之前触发javascript,java,selenium,webdriver,Java,Selenium,Webdriver,我有一个应该包含日期的输入字段 假设表单在字段内加载了一个值,例如“2015/04/28”。我正在使用webdriver选择使用的元素,然后我执行以下操作: element.clear(); element.sendKeys("2015/04/29"); 不幸的是,当我清除该元素时,它会触发一些javascript加载模板“yyy/MM/dd”并将其放入字段中,因此当sendKeys()出现时,最终结果是“yyy/MM/dd2015/04/29” 手动执行这些步骤时不会发生这种情况,如果转到字
element.clear();
element.sendKeys("2015/04/29");
不幸的是,当我清除该元素时,它会触发一些javascript加载模板“yyy/MM/dd”并将其放入字段中,因此当sendKeys()出现时,最终结果是“yyy/MM/dd2015/04/29”
手动执行这些步骤时不会发生这种情况,如果转到字段并选择其中的所有内容并将其删除,则在切换到其他元素之前不会加载模板
因此,javascript似乎不仅仅是通过更改字段触发的,而是与焦点丢失之类的东西相结合的。我尝试了多种方法来关注输入元素:
new Actions(driver).moveToElement(element).perform();
new Actions(driver).moveToElement(element).click().perform();
element.click()
element.sendKeys("") // before the other sendKeys
然而,当我使用webdriver时,同样的事情不断发生。
所以有两个问题:
- 通常,您如何处理由您执行的操作触发但可能会影响您正在执行的操作的异步javascript调用?等等
- 在这个特定的问题中,它似乎是焦点驱动的,在clear()和sendKeys()之间是否有某种方式使字段失去焦点
element.clear()
,它必须触发这三个选项中的一个,因为在清除之后,代码将插入模板数据
当我到达element.sendKeys()时,损坏已经完成
因此,在clear()和sendKeys()之间,网站上会调用“更改”、“模糊”或“聚焦”,对我来说,最合理的解释是该字段不知何故失去了焦点。几周前我自己也遇到过类似的问题。问题是我只是偶尔遇到这个问题。解决方法是将进程封闭在while循环中,在发送sendkeys()后检索日期。然后将检索到的日期与正则表达式进行比较,如果日期与正则表达式不匹配,则再次重复clear()->sendKeys()操作
为了回答您的第一个问题,我使用了一个自定义方法,该方法等待活动请求数==0。我不确定你的第二个问题 您可以尝试通过发送退格来清除输入
public static void clearWithBackspace(WebElement input) {
while(input.getAttribute("value").length() > 0) {
input.sendKeys(Keys.BACK_SPACE);
}
}
(或者是一些变体,其中在单个sendKeys
调用中发送正确数量的返回空间,后跟所需的文本。)
或者,使用由执行的JavaScript设置输入值
通常如何处理异步javascript调用
我等着。或者是一些估计的数量,或者如果我想说得具体一些:执行我自己的脚本并等待完成。这是因为JavaScript的事件循环只有在其他一切都已完成时才会执行脚本。大概是这样的:
public static void waitForScriptExecution() {
executeJs("var sc = document.createElement('script'); sc.innerHTML = 'window.allDone = true;'; document.body.appendChild(sc);");
int maxWait = 6000;
int waitTimeSoFar = 0;
int waitIntervalMs = 500;
do {
if (executeJs("return window.allDone").equals("true")) {
break;
}
waitFor(waitIntervalMs, MILLISECONDS);
waitTimeSoFar = waitTimeSoFar + waitIntervalMs;
} while (waitTimeSoFar < maxWait);
if (waitTimeSoFar >= maxWait) {
// TODO handle timeout
}
}
public static String executeJs(String script) {
JavascriptExecutor js = (JavascriptExecutor) driver;
Object result = js.executeScript(script);
return result != null ? result.toString() : null;
}
public static void waitFor(long count, TimeUnit timeUnit) {
try {
Thread.sleep(timeUnit.toMillis(count));
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
publicstaticvoid waitForScriptExecution(){
executeJs(“var sc=document.createElement('script');sc.innerHTML='window.allDone=true;';document.body.appendChild(sc);”;
int maxWait=6000;
int waitTimeSoFar=0;
国际等待间隔=500;
做{
if(executeJs(“return window.allDone”).equals(“true”)){
打破
}
waitFor(waitIntervalMs,毫秒);
waitTimeSoFar=waitTimeSoFar+waitIntervalMs;
}while(waitTimeSoFar=maxWait){
//TODO句柄超时
}
}
公共静态字符串executeJs(字符串脚本){
JavascriptExecutor js=(JavascriptExecutor)驱动程序;
Object result=js.executeScript(脚本);
返回结果!=null?result.toString():null;
}
公共静态void waitFor(长计数,时间单位时间单位){
试一试{
Thread.sleep(timeUnit.toMillis(count));
}捕捉(中断异常e){
抛出新的运行时异常(e);
}
}
看看这个,可能会有帮助。
与ekuusela的建议类似,
但您可以尝试Ctrl+A,然后键入
在此添加示例以确保完整性
element.sendKeys(Keys.chord(Keys.CONTROL, "a"), value));
element.sendKeys(Keys.chord(Keys.END, Keys.BACKSPACE, Keys.BACKSPACE, ... (enough backspaces to erase the field)), value)).
问题实际上是描述了链接到不幸设置为“WorkingAsIntended”的
基本上:clear()
触发change
事件
我的解决方案(基于上述帖子中的答案)是:
然后执行元素。sendKeys()
Actions navigator = new Actions(driver);
navigator.click(element)
.sendKeys(Keys.END)
.keyDown(Keys.SHIFT)
.sendKeys(Keys.HOME)
.keyUp(Keys.SHIFT)
.sendKeys(Keys.BACK_SPACE)
.perform();