fix(apple): prefer the last booted simulator over the first available one - #2848
Open
ahmdshrif wants to merge 1 commit into
Open
fix(apple): prefer the last booted simulator over the first available one#2848ahmdshrif wants to merge 1 commit into
ahmdshrif wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
findMatchingSimulatordocuments this priority when no simulator is requested:The "last booted" tier never applies. In default mode (
run-ioswith no--simulator/--udid), the first available simulator in the list setsmatchon the very same iteration that could have recorded the fallback:For the first available device,
fallbackMatchis only assigned when that same device also carrieslastBootedAt— andmatchis then assigned to it anyway. For every later device both guards are dead becausematchis already truthy. Soreturn match ?? fallbackMatch ?? nullcan never returnfallbackMatchin default mode: the result is always the first available simulator, whichever simulator the developer actually used last.That is the behaviour #1701 set out to change ("Sometimes, it's better to have the last booted simulator as a fallback, instead of the first available simulator"). #1709 then moved the assignment from
matchto a separatefallbackMatchso that an explicitly requested simulator wins (#1707), but the!matchguard against the first-available assignment stayed, which leaves the feature unreachable.In practice
npx react-native run-iosboots whateverxcrun simctl listhappens to return first for the newest runtime rather than the simulator you were last working on.A second, smaller effect of the same shared
matchvariable: when several simulators have been booted before, the one that is picked depends on list order rather than on which was booted most recently, and the tracked value is overwritten on each iteration despite the comment saying "first".Fix
Split the single
matchaccumulator into the three tiers the docblock describes, so each is recorded independently:match— an exact--simulatorname match (unchanged),lastBootedMatch— the available simulator with the newestlastBootedAt,firstAvailableMatch— the first available simulator, only tracked in default mode.return match ?? lastBootedMatch ?? firstAvailableMatch ?? null.Scope notes — this deliberately keeps the existing behaviour of every other path:
Bootedsimulator still short-circuits and wins over everything;--simulator <name>still wins over the last booted one (fix: pick selected simulator when defined instead of last booted #1709);--udidstill returns the exact match ornull;--simulator <name>matches nothing, the previously-booted fallback is still returned rather thannull, sogetDestinationSimulator's error message andgetFallbackSimulator's behaviour are untouched;firstAvailableMatchis only tracked when no name was requested, so no path that returnsnulltoday starts returning a simulator.Unparseable
lastBootedAtvalues are still accepted as a fallback candidate (they just lose to any parseable one), so a malformedsimctlvalue cannot turn a previously working selection intonull.Test Plan
Four tests added to
packages/cli-platform-apple/src/tools/__tests__/findMatchingSimulator.test.ts.Before the fix (tests applied, source unchanged) — 2 failed, 21 passed:
After the fix — 23 passed, with all 21 pre-existing tests passing unchanged, including
should return the defined simulator in list even if another device is booted,should return picked simulator instead of last booted simulator in list, and the UDID and version-filter cases.The other two new tests pass both before and after and are there as guards for the behaviour that must not change:
should prefer a currently booted simulator over the last booted oneshould keep falling back to a previously booted simulator when the requested name is not availablePackage and repo-wide:
Verification is unit tests only — I have not linked this into a local
react-nativecheckout, so the third checklist box is left unchecked. The change is confined to the selection logic infindMatchingSimulator; the fixtures in the test file are realxcrun simctl list --json devicesshapes, including both theavailability: '(available)'and the newerisAvailable: trueforms.Checklist
react-nativecheckout (instructions) — not done; verified with unit tests only.