Selenium:element.clear() 在 sendKeys() 之前触发 javascript
Selenium: element.clear() triggers javascript before sendKeys()
我有一个应该包含日期的输入字段。
假设表单加载了字段内的值,例如“2015/04/28”。我正在使用 webdriver select 使用 By 的元素,然后我这样做:
element.clear();
element.sendKeys("2015/04/29");
不幸的是,当我清除元素时,它会触发一些 javascript 加载模板 "yyyy/MM/dd" 并将其放在字段中,因此当 sendKeys() 出现时,最终结果是 "yyyy/MM/dd2015/04/29".
当您手动执行这些步骤时不会发生这种情况,如果您转到该字段并select其中的所有内容并将其删除,它不会加载模板 until 你切换到不同的元素。
所以 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() 之间失去焦点?
更新
详细说明:它是一个 "text" 输入字段,在 "change"、"blur" 和 [=56= 上具有 javascript 方法 运行ning ] 更新字段值。
所以我运行 element.clear()
必须 触发这三个之一,因为在清除代码后插入模板数据。
当我到达 element.sendKeys() 时,损坏已经完成。
所以不知何故,在 clear() 和 sendKeys() 之间,网站上调用了 "change"、"blur" 或 "focus",对我来说最合乎逻辑的解释是字段以某种方式失去焦点。
几周前我自己也遇到过类似的问题。问题是我只是偶尔遇到这个问题。通过将进程封闭在 while 循环中解决它,在发送 sendkeys() 后检索日期。然后将检索到的日期与正则表达式进行比较,如果日期与正则表达式不匹配,那么我再次重复 clear() -> sendKeys() 操作。
为了回答您的第一个问题,我使用了一种自定义方法,该方法等待活动请求数 == 0。不确定您的第二个问题。
您可以尝试通过退格键清除输入。
public static void clearWithBackspace(WebElement input) {
while(input.getAttribute("value").length() > 0) {
input.sendKeys(Keys.BACK_SPACE);
}
}
(或者您在单次 sendKeys
调用中发送正确数量的 BACK_SPACE
后跟您想要的文本的一些变体。)
或者,通过 JavascriptExecutor 执行的 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);
}
}
看看这个,可能会有帮助。
类似于 ekuusela 的建议,
但是你可以试试 Ctrl + A 然后输入。
https://groups.google.com/forum/#!topic/selenium-users/OqRAQmmABJY
为了完整起见,在此处添加示例,
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)).
这个问题实际上描述的是in this post which links to a selenium bug,不幸的是设置为"WorkingAsIntended"。
基本上:clear()
触发了一个 change
事件。
我的解决方案(基于上面post中的一个答案)是:
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();
然后我做 element.sendKeys()
我有一个应该包含日期的输入字段。
假设表单加载了字段内的值,例如“2015/04/28”。我正在使用 webdriver select 使用 By 的元素,然后我这样做:
element.clear();
element.sendKeys("2015/04/29");
不幸的是,当我清除元素时,它会触发一些 javascript 加载模板 "yyyy/MM/dd" 并将其放在字段中,因此当 sendKeys() 出现时,最终结果是 "yyyy/MM/dd2015/04/29".
当您手动执行这些步骤时不会发生这种情况,如果您转到该字段并select其中的所有内容并将其删除,它不会加载模板 until 你切换到不同的元素。
所以 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() 之间失去焦点?
更新
详细说明:它是一个 "text" 输入字段,在 "change"、"blur" 和 [=56= 上具有 javascript 方法 运行ning ] 更新字段值。
所以我运行 element.clear()
必须 触发这三个之一,因为在清除代码后插入模板数据。
当我到达 element.sendKeys() 时,损坏已经完成。
所以不知何故,在 clear() 和 sendKeys() 之间,网站上调用了 "change"、"blur" 或 "focus",对我来说最合乎逻辑的解释是字段以某种方式失去焦点。
几周前我自己也遇到过类似的问题。问题是我只是偶尔遇到这个问题。通过将进程封闭在 while 循环中解决它,在发送 sendkeys() 后检索日期。然后将检索到的日期与正则表达式进行比较,如果日期与正则表达式不匹配,那么我再次重复 clear() -> sendKeys() 操作。
为了回答您的第一个问题,我使用了一种自定义方法,该方法等待活动请求数 == 0。不确定您的第二个问题。
您可以尝试通过退格键清除输入。
public static void clearWithBackspace(WebElement input) {
while(input.getAttribute("value").length() > 0) {
input.sendKeys(Keys.BACK_SPACE);
}
}
(或者您在单次 sendKeys
调用中发送正确数量的 BACK_SPACE
后跟您想要的文本的一些变体。)
或者,通过 JavascriptExecutor 执行的 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);
}
}
看看这个,可能会有帮助。 类似于 ekuusela 的建议, 但是你可以试试 Ctrl + A 然后输入。
https://groups.google.com/forum/#!topic/selenium-users/OqRAQmmABJY
为了完整起见,在此处添加示例,
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)).
这个问题实际上描述的是in this post which links to a selenium bug,不幸的是设置为"WorkingAsIntended"。
基本上:clear()
触发了一个 change
事件。
我的解决方案(基于上面post中的一个答案)是:
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();
然后我做 element.sendKeys()