(templateName)
| 440 | } |
| 441 | |
| 442 | async function ensureTemplateSimulator(templateName) { |
| 443 | const inventory = await simulatorInventory(); |
| 444 | const exact = inventory.devices.find( |
| 445 | (device) => device.name === templateName && device.isAvailable !== false, |
| 446 | ); |
| 447 | if (exact) { |
| 448 | return exact; |
| 449 | } |
| 450 | const runtime = |
| 451 | inventory.runtimes.find( |
| 452 | (candidate) => candidate.isAvailable && candidate.platform === "iOS", |
| 453 | ) || inventory.runtimes.find((candidate) => candidate.isAvailable); |
| 454 | if (!runtime) { |
| 455 | throw new Error("No available iOS simulator runtime was found."); |
| 456 | } |
| 457 | const deviceType = |
| 458 | inventory.deviceTypes.find( |
| 459 | (candidate) => candidate.name === templateName, |
| 460 | ) || |
| 461 | inventory.deviceTypes.find((candidate) => |
| 462 | candidate.name.includes("iPhone 17 Pro"), |
| 463 | ) || |
| 464 | inventory.deviceTypes.find((candidate) => |
| 465 | candidate.name.includes("iPhone"), |
| 466 | ); |
| 467 | if (!deviceType) { |
| 468 | throw new Error(`No simulator device type was found for ${templateName}.`); |
| 469 | } |
| 470 | const udid = ( |
| 471 | await execText("xcrun", [ |
| 472 | "simctl", |
| 473 | "create", |
| 474 | templateName, |
| 475 | deviceType.identifier, |
| 476 | runtime.identifier, |
| 477 | ]) |
| 478 | ).trim(); |
| 479 | return { |
| 480 | isAvailable: true, |
| 481 | name: templateName, |
| 482 | runtimeName: runtime.name, |
| 483 | udid, |
| 484 | }; |
| 485 | } |
| 486 | |
| 487 | async function simulatorInventory() { |
| 488 | const [devicesJson, deviceTypesJson, runtimesJson] = await Promise.all([ |
no test coverage detected