Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,30 @@ beforeEach(() => {
);
});

test('opens Simulator.app with the device UDID when it exists', async () => {
test('opens Simulator.app with the device UDID when it is not already booted', async () => {
(fs.existsSync as jest.Mock).mockImplementation((target) =>
String(target).endsWith('Simulator.app'),
);

await runOnSimulator(xcodeProject, 'ios', 'Debug', 'TestApp', args, {
...simulator,
state: 'Shutdown',
});

expect(child_process.execFileSync).toHaveBeenCalledWith('open', [
`${developerDir}/Applications/Simulator.app`,
'--args',
'-CurrentDeviceUDID',
simulator.udid,
]);
});

test('opens Simulator.app without -CurrentDeviceUDID when the device is already booted', async () => {
(fs.existsSync as jest.Mock).mockImplementation((target) =>
String(target).endsWith('Simulator.app'),
);

// `simulator` is already in the `Booted` state.
await runOnSimulator(
xcodeProject,
'ios',
Expand All @@ -51,12 +70,16 @@ test('opens Simulator.app with the device UDID when it exists', async () => {
simulator,
);

// Bring the already-running Simulator.app to the foreground without re-issuing
// a boot for the booted device, which would otherwise trigger the
// "Unable to boot device in current state: Booted" modal alert.
expect(child_process.execFileSync).toHaveBeenCalledWith('open', [
`${developerDir}/Applications/Simulator.app`,
'--args',
'-CurrentDeviceUDID',
simulator.udid,
]);
expect(child_process.execFileSync).not.toHaveBeenCalledWith(
'open',
expect.arrayContaining(['-CurrentDeviceUDID']),
);
});

test('falls back to DeviceHub via devices:// deep link when Simulator.app is absent', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,13 @@ export async function runOnSimulator(
* that the Simulator.app is running.
*
* We also pass it `-CurrentDeviceUDID` so that when we launch it for the first time,
* it will not boot the "default" device, but the one we set. If the app is already running,
* this flag has no effect.
* it will not boot the "default" device, but the one we set.
*
* We only pass that flag when the target device is not already booted. Passing
* `-CurrentDeviceUDID` for an already-booted device makes Simulator.app re-issue a
* boot request, which CoreSimulator rejects with "Unable to boot device in current
* state: Booted" and surfaces as a modal alert on every subsequent run. When the
* device is already booted we just bring the running Simulator.app to the foreground.
*/
const activeDeveloperDir = child_process
.execFileSync('xcode-select', ['-p'], {encoding: 'utf8'})
Expand All @@ -51,12 +56,12 @@ export async function runOnSimulator(
);

if (fs.existsSync(simulatorApp)) {
child_process.execFileSync('open', [
simulatorApp,
'--args',
'-CurrentDeviceUDID',
simulator.udid,
]);
child_process.execFileSync(
'open',
simulator.state === 'Booted'
? [simulatorApp]
: [simulatorApp, '--args', '-CurrentDeviceUDID', simulator.udid],
);
} else if (fs.existsSync(deviceHubApp)) {
child_process.execFileSync('open', [
`devices://device/open?id=${simulator.udid}`,
Expand Down
Loading