Skip to content

iOS: fill() on a React Native secureTextEntry field always fails verification (observed "••••••••"), secret or plain value #872

Closed
callstack/agent-device
#3567

Description

@Athleticsmind

Summary

On an iOS simulator, fill() into a React Native TextInput with secureTextEntry always fails with ENGINE_FAILURE: perform fill failed: text entry verification failed. The runner reads the masked field value back ("••••••••") and compares it with the typed text, so the check can never pass. This happens with a credential password and with a plain string, so it is not specific to secrets. After the failure, the show/hide toggle that overlays the field's right edge has been flipped, which suggests the runner's repair path tapped the field again.

This blocks every password sign-in on iOS devices: fill(credentials.user(...).password) and type_secret cannot succeed.

Environment

  • e2e 0.17.0, @e2e-dev/mobile 0.9.2, agent-device 0.21.20 (also seen on e2e 0.15.1, @e2e-dev/mobile 0.8.1, agent-device 0.21.18)
  • iOS 27.0 simulator (iPhone 18 Pro), Xcode 27.0 (27A266a), macOS 27.0.1
  • React Native 0.86.3, Expo SDK 57, Release build for the simulator

Reproduction

The field is a standard React Native TextInput with secureTextEntry, wrapped together with a show/hide Pressable that sits over the input's right edge:

<View style={{ position: 'relative' }}>
  <TextInput accessibilityLabel="Password" secureTextEntry={!visible} textContentType="none" autoComplete="off" style={{ paddingRight: 48 }} />
  <Pressable accessibilityRole="button" accessibilityLabel={visible ? 'Hide password' : 'Show password'}
    onPress={() => setVisible((v) => !v)} style={{ position: 'absolute', right: 0, top: 0, bottom: 0, width: 48 }} />
</View>

Test:

await expect(screen.getByRole('button', 'Show password')).toBeVisible(); // passes
await screen.getByLabel('Password').fill('not-a-secret-123');            // fails

Result (2 of 2 runs, same for a credential password in 2 of 2 runs):

ENGINE_FAILURE: perform fill failed: text entry verification failed: expected "not-a-secret-123", observed "••••••••"

With a credential password the message reads expected "<secret:...>", which is only the redacted form of the same comparison.

Screen at failure (from failure/screen.txt):

other "Password"
 textbox "Password" [focused]
button "Hide password"

Observations

  • e2e's tree reports the field as a plain textbox, without secure or inputPurpose: 'password', so XCTest does not seem to classify it as secureTextField here.
  • In agent-device's runner, editableTextValue returns nil for .secureTextField, which skips verification. A masked field that XCTest reports as .textField falls through to the observedText == expectedText comparison in verifyTextEntry (RunnerTests+TextTyping.swift), which a masked value can never satisfy. 16 characters typed were read back as 8 bullets, so even a length check would not help.
  • The toggle reads "Show password" before the fill and "Hide password" after it. Something in the fill (the repair or retry after the failed verification, as far as we can tell) tapped inside the field's frame where the toggle overlays it, which also leaves the field showing its text.

Expected

A fill into a masked field either skips the value check (as already done for .secureTextField) or treats a value made only of bullet characters as unverifiable, and never taps outside the field's own text area while repairing.

Possible direction

Treat an observed value that consists only of • (U+2022) as unverifiable (verified: nil) in verifyTextEntry, and/or use the element's secure trait rather than only elementType == .secureTextField.

Activity

  1. added
    agent-deviceRoot cause in agent-device, fixed upstream then bumped here
    on Oct 6, 2026
  2. nyiramisigaroleocadie85-dot commented on Oct 6, 2026

    @nyiramisigaroleocadie85-dot

    This command is a good how to create in web in have raliationship

  3. added
    P2Improvement / follow-up
    bugSomething isn't working
    on Oct 13, 2026
  4. added a commit that references this issue on Oct 13, 2026
    dcaad95
  5. added a commit that references this issue on Oct 13, 2026
    a95d2d5
  6. okwasniewski commented on Oct 22, 2026

    @okwasniewski
    Member

    hey, this should be already fixed in latest release, thanks for reporting!

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Improvement / follow-upagent-deviceRoot cause in agent-device, fixed upstream then bumped herebugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions