Skip to content

Commit 42b0b06

Browse files
authored
pythongh-133131: Discover an appropriate iOS simulator rather than hard-coding iPhone SE 3rd gen (python#133132)
Determines a candidate simulator at runtime rather than hardcoding iPhone SE.
1 parent c46635a commit 42b0b06

File tree

2 files changed

+41
-3
lines changed

2 files changed

+41
-3
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The iOS testbed will now select the most recently released "SE-class" device
2+
for testing if a device isn't explicitly specified.

iOS/testbed/__main__.py

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,36 @@ async def async_check_output(*args, **kwargs):
123123
)
124124

125125

126+
# Select a simulator device to use.
127+
async def select_simulator_device():
128+
# List the testing simulators, in JSON format
129+
raw_json = await async_check_output(
130+
"xcrun", "simctl", "--set", "testing", "list", "-j"
131+
)
132+
json_data = json.loads(raw_json)
133+
134+
# Any device will do; we'll look for "SE" devices - but the name isn't
135+
# consistent over time. Older Xcode versions will use "iPhone SE (Nth
136+
# generation)"; As of 2025, they've started using "iPhone 16e".
137+
#
138+
# When Xcode is updated after a new release, new devices will be available
139+
# and old ones will be dropped from the set available on the latest iOS
140+
# version. Select the one with the highest minimum runtime version - this
141+
# is an indicator of the "newest" released device, which should always be
142+
# supported on the "most recent" iOS version.
143+
se_simulators = sorted(
144+
(devicetype["minRuntimeVersion"], devicetype["name"])
145+
for devicetype in json_data["devicetypes"]
146+
if devicetype["productFamily"] == "iPhone"
147+
and (
148+
("iPhone " in devicetype["name"] and devicetype["name"].endswith("e"))
149+
or "iPhone SE " in devicetype["name"]
150+
)
151+
)
152+
153+
return se_simulators[-1][1]
154+
155+
126156
# Return a list of UDIDs associated with booted simulators
127157
async def list_devices():
128158
try:
@@ -371,12 +401,16 @@ def update_plist(testbed_path, args):
371401
plistlib.dump(info, f)
372402

373403

374-
async def run_testbed(simulator: str, args: list[str], verbose: bool=False):
404+
async def run_testbed(simulator: str | None, args: list[str], verbose: bool=False):
375405
location = Path(__file__).parent
376406
print("Updating plist...", end="", flush=True)
377407
update_plist(location, args)
378408
print(" done.", flush=True)
379409

410+
if simulator is None:
411+
simulator = await select_simulator_device()
412+
print(f"Running test on {simulator}", flush=True)
413+
380414
# We need to get an exclusive lock on simulator creation, to avoid issues
381415
# with multiple simulators starting and being unable to tell which
382416
# simulator is due to which testbed instance. See
@@ -453,8 +487,10 @@ def main():
453487
)
454488
run.add_argument(
455489
"--simulator",
456-
default="iPhone SE (3rd Generation)",
457-
help="The name of the simulator to use (default: 'iPhone SE (3rd Generation)')",
490+
help=(
491+
"The name of the simulator to use (eg: 'iPhone 16e'). Defaults to ",
492+
"the most recently released 'entry level' iPhone device."
493+
)
458494
)
459495
run.add_argument(
460496
"-v", "--verbose",

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy