-
-
Notifications
You must be signed in to change notification settings - Fork 12
Open
Description
This is much faster
private def asJsString(text: String): String = {
val sb = new StringBuilder
sb.append("'")
text.foreach {
case '\'' => sb.append("\\'")
case '\\' => sb.append("\\\\")
case '\n' => sb.append("\\n")
case '\r' => sb.append("\\r")
case '\t' => sb.append("\\t")
case c => sb append c
}
sb.append("'")
sb.toString()
}
implicit class WebElementLocalExt(private val self: WebElement) extends AnyVal {
private def currentValue(): String =
self.getAttribute("value")
def quickSetTextIfNeeded(text: String)(implicit d: WebDriver): Unit =
if (text != currentValue())
quickSetText(text)
def quickSetText(text0: String)(implicit d: WebDriver): Unit =
if (text0.isEmpty)
self.clear()
else {
// React will only ingest the new value when it receives an event - just modifying the dom via JS will go
// ignored by React. Therefore we set all but the last character using JS then use a real event for the last
// char. This also has the nice effect of supporting a carriage-return at the end of the text argument to trigger
// form submission.
val text = text0.replace("\r", "")
val n = text.reverseIterator.takeWhile(_ == '\n').size + 1
val loc = self.getLocation
val x = s"${loc.x}-window.scrollX+1"
val y = s"${loc.y}-window.scrollY+1"
val init = text.dropRight(n)
val last = text.takeRight(n)
val (lastText, lastOther) = if (last.endsWith("\n")) (last.dropRight(1), "\n") else (last, "")
val cmd = s"document.elementFromPoint($x,$y).value=${asJsString(init)}"
// println(s"${asJsString(init)} | ${asJsString(lastText)} | ${asJsString(lastOther)}")
// println(cmd)
// Step 1: Fast!
if (currentValue() !=* init) {
d.executeJsOrThrow(cmd)
assert(currentValue() ==* init) // Without this, the value here can be overwritten by the steps below
}
// Step 2: Send 1 textual char without \n so that the app processes the expected event
self.sendKeys(Keys.END + lastText)
assert(currentValue() ==* (init + lastText))
// Step 3: Send the non-text key
// This needs to be separate from the previous step else ~2% of the time, the update is missed
if (lastOther.nonEmpty)
self.sendKeys(lastOther)
}
Metadata
Metadata
Assignees
Labels
No labels