Skip to content

fix(uiautomator2-server): strip trailing escaped newline in SendKeysToElement - #53

Open
hoanle0126 wants to merge 1 commit into
appium:mainfrom
hoanle0126:fix/send-keys-escaped-newline-686
Open

hoanle0126 wants to merge 1 commit into
appium:mainfrom
hoanle0126:fix/send-keys-escaped-newline-686

Conversation

@hoanle0126

Copy link
Copy Markdown

Moved from appium/appium-uiautomator2-server#800 for appium/appium-uiautomator2-server#686.

Cause

In SendKeysToElement.setText, text.endsWith("\\n") checks for a trailing literal two-character sequence \n ('\\' followed by 'n'). However, text.replaceFirst("\\n$", "") passes \n$ as a regular expression to String.replaceFirst, which matches an actual LF character (0x0A) rather than the literal \n sequence. As a result, the trailing \n characters remain in text when element.setText(text) is called, while pressEnter is also set to true.

Using text.replaceFirst("\\\\n$", "") escapes the backslash for the regex engine so the trailing literal \n sequence matched by text.endsWith("\\n") is stripped before element.setText(text) and getUiDevice().pressEnter() are executed.

Before / After Reproduction (appium/appium-uiautomator2-server#686 via Java client)

  • Environment: Appium 2 with uiautomator2 driver, Java client (io.appium:java-client), target EditText element.
  • Java client call:
    WebElement input = driver.findElement(AppiumBy.id("io.appium.android.apis:id/edit"));
    input.sendKeys("aa\\n");
  • Before this change:
    • text.endsWith("\\n") evaluates to true (pressEnter = true).
    • text.replaceFirst("\\n$", "") does not match literal \n, leaving text as "aa\\n".
    • element.setText("aa\\n") sets the literal text aa\n into the EditText field, and getUiDevice().pressEnter() is then invoked on top of that.
  • After this change:
    • text.replaceFirst("\\\\n$", "") strips the trailing literal \n, leaving text as "aa".
    • element.setText("aa") sets aa into the EditText field, and getUiDevice().pressEnter() sends the Enter key event.
  • Actual LF ("aa\n") and append paths (replace=false or replace=null):
    • When model.text ends with an actual LF ("aa\n"), text.endsWith("\\n") is false, so text is passed unchanged ("aa\n") to element.setText without triggering an extra getUiDevice().pressEnter().
    • When model.replace is false or omitted (null), text has its trailing "\\n" stripped first ("aa"), is appended to currentText ("existing_aa"), written via element.setText("existing_aa"), and followed by getUiDevice().pressEnter().

Unit Test Verification (Before vs. After)

Test command:

npm run test:android --workspace appium-uiautomator2-server
# (runs ./gradlew :vendor-xpath2:jar && ./gradlew testServerDebugUnitTest)
  • Before fix (text.replaceFirst("\\n$", "")):

    JUnit version 4.13.2
    ..E.E.E.E.
    There were 4 failures:
    1) shouldStripTrailingEscapedNewlineWhenAppendingWithReplaceOmitted(io.appium.uiautomator2.handler.SendKeysToElementTests)
    org.junit.ComparisonFailure: expected:<existing_aa[]> but was:<existing_aa[\n]>
    2) shouldStripTrailingEscapedNewlineAndPressEnter(io.appium.uiautomator2.handler.SendKeysToElementTests)
    org.junit.ComparisonFailure: expected:<aa[]> but was:<aa[\n]>
    3) shouldOnlyStripTrailingEscapedNewlineWhenMultiplePresent(io.appium.uiautomator2.handler.SendKeysToElementTests)
    org.junit.ComparisonFailure: expected:<aa\nbb[]> but was:<aa\nbb[\n]>
    4) shouldStripTrailingEscapedNewlineWhenAppendingWithReplaceFalse(io.appium.uiautomator2.handler.SendKeysToElementTests)
    org.junit.ComparisonFailure: expected:<existing_aa[]> but was:<existing_aa[\n]>
    
    FAILURES!!!
    Tests run: 6,  Failures: 4
    
  • After fix (text.replaceFirst("\\\\n$", "")):

    JUnit version 4.13.2
    ......
    OK (6 tests)
    

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working package:uiautomator2-server

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant