Skip to content

Sign a Simulator into WordPress.com from a launch-argument token - #25801

Open
jkmassel wants to merge 13 commits into
trunkfrom
jkmassel/sim-wpcom-token-signin
Open

Sign a Simulator into WordPress.com from a launch-argument token#25801
jkmassel wants to merge 13 commits into
trunkfrom
jkmassel/sim-wpcom-token-signin

Conversation

@jkmassel

@jkmassel jkmassel commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds make sim-login (wrapping Scripts/sim-signin.sh) to sign a booted Simulator into WordPress.com in one command — no taps.
  • Introduces the -wpcom-token launch argument that finishes WordPress.com sign-in automatically; the legacy -ui-test-wpcom-token still works.
  • Reads the token from WPCOM_TOKEN or ~/.wpcom-token (never the command line), so it stays out of shell history.

Background

trunk already reads a -ui-test-wpcom-token launch argument inside WordPressDotComAuthenticator.attemptSignIn — but only after the user taps "Continue with WordPress.com" on the login screen. Signing a Simulator in therefore still needed a manual tap. This is the launch-argument approach, chosen over device-to-device session transfer (#25795).

Changes

1. make sim-login / Scripts/sim-signin.sh

make sim-login                # Jetpack, the booted simulator
make sim-login APP=wordpress  # WordPress instead
make sim-login RESET=1        # reinstall the app first, for a clean slate
make sim-login DEVICE=<udid>  # target a specific simulator

The script targets the booted simulator (prompting to choose when several are booted), maps --app to the bundle id (com.automattic.jetpack / org.wordpress), and launches it with -wpcom-token so the app signs in from the login screen with no taps.

The token never appears on the command line. It resolves from WPCOM_TOKEN, then ~/.wpcom-token, then a hidden prompt (which offers to save it, mode 600). A token passed as an argument would be saved to shell history, so there is deliberately no --wpcom-token flag.

--reset uninstalls and reinstalls the app instead of running the in-app -ui-test-reset-everything wipe. Reinstalling clears the whole data container — caches and cookies, not just Core Data and UserDefaults — and simctl install is synchronous, so nothing races an async wipe on a fixed sleep. The app must already be installed.

2. The -wpcom-token launch argument

WordPressDotComAuthenticator.launchArgumentToken resolves the token from -wpcom-token, falling back to the legacy -ui-test-wpcom-token. Both the automatic sign-in and the existing attemptSignIn path read through it, so anything still passing the old argument keeps working.

3. Automatic sign-in

WordPressAppDelegate.autoSignInWPComAccountFromLaunchArgumentIfNeeded() mirrors the existing autoSignInUITestSite() hook and is called from RootViewCoordinator.showSignInUI(). It runs the real signIn(context: .default) flow, then swaps the window root with windowManager.showUI() — posting WPSigninDidFinishNotification alone creates the account but leaves the app on the login screen.

It attempts at most once per process, and only when no account is signed in. Without the once-per-process guard, signing out returns to the login screen where the still-present token would immediately sign the account back in — a logout could never reach a logged-out state.

Test plan

Verified at the script level with a stubbed xcrun (the command sequence, not a real sign-in), on macOS's system bash 3.2:

  • --reset issues get_app_containeruninstallinstall <staged .app>launch -wpcom-token, in that order, and the staged copy is removed on exit.
  • A --wpcom-token <token> flag and a positional token are both rejected (error: unknown argument); the token resolves from WPCOM_TOKEN / ~/.wpcom-token.
  • --reset with the app not installed fails with a clear "build and install it first" error.

On a booted Simulator (reviewer):

  • Build and install the app, then make sim-login → the app signs in and lands on the site with no taps.
  • Launching with the legacy -ui-test-wpcom-token <token> still signs in.
  • make sim-login RESET=1 against a signed-in app → the app is reinstalled, then signed in.
  • Sign out after a token launch → the app stays on the login screen and does not auto sign back in.
  • make sim-login APP=wordpress targets org.wordpress.

Related

@dangermattic

Copy link
Copy Markdown
Collaborator
1 Message
📖 This PR is still a Draft: some checks will be skipped.

Generated by 🚫 Danger

@wpmobilebot

wpmobilebot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor
App Icon📲 You can test the changes from this Pull Request in WordPress by scanning the QR code below to install the corresponding build.
App NameWordPress
ConfigurationRelease-Alpha
Build Number33358
VersionPR #25801
Bundle IDorg.wordpress.alpha
Commit6a719d5
Installation URL10nmn546bf0r8
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.

@wpmobilebot

wpmobilebot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor
App Icon📲 You can test the changes from this Pull Request in Jetpack by scanning the QR code below to install the corresponding build.
App NameJetpack
ConfigurationRelease-Alpha
Build Number33358
VersionPR #25801
Bundle IDcom.jetpack.alpha
Commit6a719d5
Installation URL2t4ba39snumv0
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.

@wpmobilebot

wpmobilebot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

🤖 Build Failure Analysis

This build has failures. Claude has analyzed them - check the build annotations for details.

jkmassel added 5 commits July 22, 2026 13:11
Add `Scripts/sim-signin.sh`, a one-command wrapper around `xcrun simctl
launch` that signs a Simulator into WordPress.com with a bearer token, and
make the existing `-ui-test-wpcom-token` launch argument finish sign-in
automatically instead of requiring a tap on "Continue with WordPress.com".

`autoSignInUITestWPComAccountIfNeeded()` mirrors the existing
`autoSignInUITestSite()` hook: it runs from `showSignInUI()`, no-ops unless
the token argument is present and no account is signed in, then runs the
real sign-in flow and swaps the window root with `windowManager.showUI()`.
Add a named `-t, --wpcom-token <token>` option alongside the positional
form, and reject a missing option value instead of shifting past the end.
Introduce `WordPressDotComAuthenticator.launchArgumentToken`, which reads
the new `-wpcom-token` launch argument and falls back to the legacy
`-ui-test-wpcom-token`. Route both read sites — `attemptSignIn` and
`autoSignInUITestWPComAccountIfNeeded()` — through it, and switch the helper
script to pass `-wpcom-token`.
The launch argument is `-wpcom-token`, not UI-test-scoped, so
`autoSignInUITestWPComAccountIfNeeded()` was misleading. Rename it to
`autoSignInWPComAccountFromLaunchArgumentIfNeeded()`.
So the token can be set once instead of pasted every launch, sim-signin.sh
falls back to the WPCOM_TOKEN environment variable, then a ~/.wpcom-token
file, when neither --wpcom-token nor a positional token is given.
Precedence: flag > env var > file.
@jkmassel
jkmassel force-pushed the jkmassel/sim-wpcom-token-signin branch from 5b8b264 to 976ef69 Compare July 22, 2026 19:11
jkmassel added 8 commits July 22, 2026 13:20
Wraps `Scripts/sim-signin.sh` behind `make sim-login`, forwarding optional
`DEVICE`, `APP`, and `RESET=1` variables plus an `ARGS` passthrough. The
token still resolves from `--wpcom-token`, `WPCOM_TOKEN`, or `~/.wpcom-token`.
When --device is omitted, sim-signin.sh now resolves the target from the
booted simulators: it uses the only one if a single device is booted, and
otherwise lists them and prompts for a choice. Errors clearly when none are
booted or no selection is made. An explicit --device still bypasses this.
If no token is found via --wpcom-token, WPCOM_TOKEN, or ~/.wpcom-token,
sim-signin.sh now prompts for one instead of erroring out. Input is read
hidden (it's a secret), whitespace-trimmed, and confirmed by length;
cancelling with an empty entry still exits with the usage error.
After the interactive prompt accepts a token, ask whether to persist it to
~/.wpcom-token so later runs pick it up automatically. Defaults to no, and
writes owner-only (umask 077 + chmod 600) since it's a secret.
Lead the simulator sign-in doc with `make sim-login` as the quickest path,
and name the command inline in AGENTS.md so agents can sign a Simulator in
without opening the doc first.
Signing out returns to the login screen, where `showSignInUI()` runs the
auto sign-in again. With the `-wpcom-token` argument still present and the
account now gone, both guards passed and it signed straight back in — a
logout could never reach a logged-out state.

Gate the auto sign-in on a per-process flag so it attempts at most once.
A token passed on the command line is saved to shell history, so drop the
`--wpcom-token` flag and the positional form. The token now comes only from
`WPCOM_TOKEN`, `~/.wpcom-token`, or a hidden prompt.

While here, two more fixes from review:

- `--reset` now uninstalls and reinstalls the app rather than running the
  in-app `-ui-test-reset-everything` wipe. Reinstalling clears the whole
  data container (caches and cookies too) and is synchronous, so it drops
  the `sleep 2` that could race the wipe.
- The booted-simulator scan no longer aborts under `set -e` when a line has
  no UUID; `|| true` lets the skip logic run as intended.
@jkmassel
jkmassel requested a review from crazytonyli July 22, 2026 21:29
@jkmassel jkmassel added [Type] Tooling Testing Unit and UI Tests and Tooling labels Jul 22, 2026
@jkmassel jkmassel added this to the 27.2 milestone Jul 22, 2026
@jkmassel
jkmassel marked this pull request as ready for review July 22, 2026 21:31
// login screen. Swap the window root to the signed-in app (no epilogue, so no taps).
windowManager.showUI()
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I intentionally kept the sign in flow manual, mainly because I want to avoid introducing another code path to the sign in flow, like this function here. The current auto-sign flow only changes where to get the token/credentials (web or env var).

If we want to fully automated sign in, do you think we can move the logic to the view controller that shows the buttons? Something like:

func viewDidAppear() {
  if autoSignWPCom {
    continueWithWPComButtonAction()
  }
}

For self-hosted site auto-sign in, we can do similar, something like

.onAppear {
  self.siteAddress = siteUrlEnvVar()
  continueButtonAction()
}

With this direction, the sign in code path stays the same, manually or fully automated.


BTW, the autoSignInUITestSite is a left-over dead code and should be deleted.

Comment thread AGENTS.md
- Add every unit test target to `WordPressUnitTests.xctestplan`.
- Run the full suite with `xcodebuild -workspace WordPress.xcworkspace -scheme WordPress -testPlan WordPressUnitTests test`. Do not use `swift test`.
- To verify changes end-to-end on an iOS simulator, follow @docs/simulator-sign-in.md to sign in to the app.
- To sign a Simulator into WordPress.com, run `make sim-login` (it targets the running simulator; the WordPress.com token comes from `~/.wpcom-token` or `WPCOM_TOKEN`, and it prompts if none is set). See @docs/simulator-sign-in.md for options and self-hosted sign-in.

@crazytonyli crazytonyli Jul 22, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it targets the running simulator

There may be multiple running simulators. Or, maybe I want a new one.

the WordPress.com token comes from ~/.wpcom-token or WPCOM_TOKEN

I feel like this belongs to personal configuration. What do you think?


Overall, I feel like the new script adds too many restrictions to what the agent can do intuitively. Currently, I can say "Create a new simulator, sign in to the test account (WP.com or a self-hosted site), perform this end-to-end verification on the Jetpack app", and the agent has enough info (from the AGENTS.md and the sign in doc) to help with that. With this new change, the agent can't get how to do that from the prompts themselves. I have not tried the new script, but I suspect the agent would read the makefile and the new script to understand what it does and then perform the actions.

The new script wraps an oneline simctl command, which AI agents should be able to see in the docs/simulator-sign-in.md. Maybe it solves other problems that I don't see?

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

Labels

Testing Unit and UI Tests and Tooling [Type] Tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants