Skip to content
Merged
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
10 changes: 9 additions & 1 deletion lib/simulator.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ function compareSims(a, b) {
return a.model < b.model ? -1 : a.model > b.model ? 1 : 0;
}

function getCreateSimulatorHelpText(selectedXcode) {
if (selectedXcode && selectedXcode.version && appc.version.gte(selectedXcode.version, '27.0')) {
return '\n\nPlease open "Device Hub" app and create a new Simulator with your preferred configuration.';
}

return '\n\nPlease open Xcode, navigate to "Window > Devices and Simulators" and create a new Simulator with your preferred configuration.';
}

/**
* Detects iOS simulators.
*
Expand Down Expand Up @@ -770,7 +778,7 @@ function findSimulators(options, callback) {
}

if (!simHandle) {
const helpText = '\n\nPlease open Xcode, navigate to "Window > Devices and Simulators" and create a new Simulator with your preferred configuration.';
const helpText = getCreateSimulatorHelpText(selectedXcode);

// user experience!
if (options.simVersion) {
Expand Down
215 changes: 17 additions & 198 deletions lib/xcode.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,204 +40,6 @@ var cache,
* what Watch Simulator. It's a mystery!
*/
const simulatorDevicePairCompatibility = {
'>=6.2 <7.0': { // Xcode 6.2, 6.3, 6.4
'>=8.2 <9.0': { // iOS 8.2, 8.3, 8.4
'1.x': true // watchOS 1.0
}
},
'7.x': { // Xcode 7.x
'>=8.2 <9.0': { // iOS 8.2, 8.3, 8.4
'1.x': true // watchOS 1.0
},
'>=9.0 <=9.2': { // iOS 9.0, 9.1, 9.2
'>=2.0 <=2.1': true // watchOS 2.0, 2.1
},
'>=9.3 <10': { // iOS 9.3
'2.2': true // watchOS 2.2
}
},
'8.x': { // Xcode 8.x
'>=9.0 <=9.2': { // iOS 9.0, 9.1, 9.2
'>=2.0 <=2.1': true // watchOS 2.0, 2.1
},
'>=9.3 <10': { // iOS 9.x
'2.2': true, // watchOS 2.2
'3.x': true // watchOS 3.x
},
'10.x': { // iOS 10.x
'2.2': true, // watchOS 2.2
'3.x': true // watchOS 3.x
}
},
'9.x': { // Xcode 9.x
'>=9.0 <=9.2': { // iOS 9.0, 9.1, 9.2
'>=2.0 <=2.1': true // watchOS 2.0, 2.1
},
'>=9.3 <10': { // iOS 9.x
'2.2': true, // watchOS 2.2
'3.x': true // watchOS 3.x
},
'10.x': { // iOS 10.x
'2.2': true, // watchOS 2.2
'3.x': true // watchOS 3.x
},
'11.x': { // iOS 11.x
'>=3.2 <4.0': true, // watchOS 3.2
'4.x': true // watchOS 4.x
}
},
'10.x <10.3': { // Xcode 10.0-10.2.1
'8.x': {}, // iOS 8.x
'>=9.0 <=9.2': { // iOS 9.0, 9.1, 9.2
'>=2.0 <=2.1': true // watchOS 2.0, 2.1
},
'>=9.3 <10': { // iOS 9.x
'2.2': true, // watchOS 2.2
'3.x': true // watchOS 3.x
},
'>=10.0 <=10.2': { // iOS 10.0, 10.1, 10.2
'2.2': true, // watchOS 2.2
'3.x': true // watchOS 3.x
},
'>=10.3 <11': { // iOS 10.3
'3.x': true // watchOS 3.x
},
'11.x': { // iOS 11.x
'>=3.2 <4.0': true, // watchOS 3.2
'4.x': true // watchOS 4.x
},
'12.x': { // iOS 12.x
'>=3.2 <4.0': true, // watchOS 3.2
'4.x': true, // watchOS 4.x
'5.x': true // watchOS 5.x
}
},
'>=10.3 <11': {
'>=10.3 <11': { // iOS 10.3
'3.x': true // watchOS 3.x
},
'11.x': { // iOS 11.x
'>=3.2 <4.0': true, // watchOS 3.2
'4.x': true // watchOS 4.x
},
'12.x': { // iOS 12.x
'4.x': true, // watchOS 4.x
'5.x': true // watchOS 5.x
}
},
'11.x': { // Xcode 11.x
'>=10.3 <11': { // iOS 10.3
'2.2': true, // watchOS 2.2
'3.x': true // watchOS 3.x
},
'11.x': { // iOS 11.x
'>=3.2 <4.0': true, // watchOS 3.2
'4.x': true // watchOS 4.x
},
'12.x': { // iOS 12.x
'4.x': true, // watchOS 4.x
'5.x': true, // watchOS 5.x
'6.x': true // watchOS 6.x
},
'13.x': { // iOS 13.x
'4.x': true, // watchOS 4.x
'5.x': true, // watchOS 5.x
'6.x': true // watchOS 6.x
}
},
'12.x': { // Xcode 12.x
'>=10.3 <11': { // iOS 10.x
'2.2': true, // watchOS 2.2
'3.x': true // watchOS 3.x
},
'11.x': { // iOS 11.x
'>=3.2 <4.0': true, // watchOS 3.2
'4.x': true // watchOS 4.x
},
'12.x': { // iOS 12.x
'4.x': true, // watchOS 4.x
'5.x': true, // watchOS 5.x
'6.x': true, // watchOS 6.x
'7.x': true // watchOS 7.x
},
'13.x': { // iOS 13.x
'4.x': true, // watchOS 4.x
'5.x': true, // watchOS 5.x
'6.x': true, // watchOS 6.x
'7.x': true // watchOS 7.x
},
'14.x': { // iOS 14.x
'4.x': true, // watchOS 4.x
'5.x': true, // watchOS 5.x
'6.x': true, // watchOS 6.x
'7.x': true // watchOS 7.x
}
},
'13.x': { // Xcode 13.x
'>=10.3 <11': { // iOS 10.x
'2.2': true, // watchOS 2.2
'3.x': true // watchOS 3.x
},
'11.x': { // iOS 11.x
'>=3.2 <4.0': true, // watchOS 3.2
'4.x': true // watchOS 4.x
},
'12.x': { // iOS 12.x
'4.x': true, // watchOS 4.x
'5.x': true, // watchOS 5.x
'6.x': true, // watchOS 6.x
'7.x': true, // watchOS 7.x
'8.x': true // watchOS 8.x
},
'13.x': { // iOS 13.x
'4.x': true, // watchOS 4.x
'5.x': true, // watchOS 5.x
'6.x': true, // watchOS 6.x
'7.x': true, // watchOS 7.x
'8.x': true // watchOS 8.x
},
'14.x': { // iOS 14.x
'4.x': true, // watchOS 4.x
'5.x': true, // watchOS 5.x
'6.x': true, // watchOS 6.x
'7.x': true, // watchOS 7.x
'8.x': true // watchOS 8.x
},
'15.x': {
'4.x': true, // watchOS 4.x
'5.x': true, // watchOS 5.x
'6.x': true, // watchOS 6.x
'7.x': true, // watchOS 7.x
'8.x': true // watchOS 8.x
}
},
'14.x': { // Xcode 14.x
'12.x': { // iOS 12.x
'7.x': true, // watchOS 7.x
'8.x': true, // watchOS 8.x
'9.x': true // watchOS 9.x
},
'13.x': { // iOS 13.x
'7.x': true, // watchOS 7.x
'8.x': true, // watchOS 8.x
'9.x': true // watchOS 9.x
},
'14.x': { // iOS 14.x
'7.x': true, // watchOS 7.x
'8.x': true, // watchOS 8.x
'9.x': true // watchOS 9.x
},
'15.x': {
'7.x': true, // watchOS 7.x
'8.x': true, // watchOS 8.x
'9.x': true // watchOS 9.x
},
'16.x': {
'7.x': true, // watchOS 7.x
'8.x': true, // watchOS 8.x
'9.x': true // watchOS 9.x
}
},
'15.x': { // Xcode 15.x
'13.x': { // iOS 13.x
'7.x': true, // watchOS 7.x
Expand Down Expand Up @@ -315,6 +117,16 @@ const simulatorDevicePairCompatibility = {
'11.x': true, // watchOS 11.x
'26.x': true, // watchOS 26.x
},
},
'27.x': { // Xcode 27.x
'26.x': { // iOS 26.x
'26.x': true, // watchOS 26.x
'27.x': true, // watchOS 27.x
},
'27.x': { // iOS 27.x
'26.x': true, // watchOS 26.x
'27.x': true, // watchOS 27.x
},
}
};

Expand Down Expand Up @@ -641,6 +453,13 @@ exports.detect = function detect(options, callback) {
}
});

if (!xc.executables.simulator) {
var deviceHub = path.join(dir, '..', 'Applications', 'DeviceHub.app', 'Contents', 'MacOS', 'DeviceHub');
if (fs.existsSync(deviceHub)) {
xc.executables.simulator = deviceHub;
}
}

if (appc.version.gte(xc.version, 9)) {
xc.executables.watchsimulator = xc.executables.simulator;
} else {
Expand Down
4 changes: 2 additions & 2 deletions test/test-ioslib.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ describe('ioslib', function () {
});

it('detect all iOS information', function (done) {
this.timeout(80000);
this.slow(30000);
this.timeout(180000);
this.slow(60000);

ioslib.detect(function (err, results) {
if (err) {
Expand Down
4 changes: 2 additions & 2 deletions test/test-simulator.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,8 @@ describe('simulator', function () {
});

it('detect iOS Simulators', function (done) {
this.timeout(8000);
this.slow(2000);
this.timeout(30000);
this.slow(10000);

ioslib.simulator.detect(function (err, results) {
if (err) {
Expand Down
4 changes: 2 additions & 2 deletions test/test-teams.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ describe('teams', function () {
});

it('detect teams', function (done) {
this.timeout(5000);
this.slow(2000);
this.timeout(30000);
this.slow(10000);

ioslib.teams.detect(function (err, results) {
if (err) {
Expand Down
79 changes: 78 additions & 1 deletion test/test-xcode.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,29 @@
*/

const
execFile = require('child_process').execFile,
fs = require('fs'),
ioslib = require('..');

function skipUnlessSelectedXcode27(ctx, done, callback) {
execFile('xcodebuild', [ '-version' ], function (err, stdout) {
if (err) {
return done(err);
}

if (!/^Xcode 27\./m.test(stdout)) {
return ctx.skip();
}

callback();
});
}

function checkXcode(xcode) {
should(xcode).be.an.Object;
should(xcode).have.keys('xcodeapp', 'path', 'selected', 'version', 'build',
'supported', 'eulaAccepted', 'sdks', 'sims', 'simDeviceTypes',
'simRuntimes', 'watchos', 'tvos', 'teams', 'executables');
'simRuntimes', 'simDevicePairs', 'watchos', 'tvos', 'teams', 'executables');

should(xcode.xcodeapp).be.a.String;
should(xcode.xcodeapp).not.equal('');
Expand Down Expand Up @@ -154,4 +169,66 @@ describe('xcode', function () {
done();
});
});

it('detect should map Xcode 27 simulator device pairs', function (done) {
this.timeout(5000);
this.slow(2000);

skipUnlessSelectedXcode27(this, done, function () {
ioslib.xcode.detect({ bypassCache: true }, function (err, results) {
if (err) {
return done(err);
}

var xcode27 = Object.keys(results.xcode)
.map(function (id) { return results.xcode[id]; })
.filter(function (xc) { return /^27\./.test(xc.version); })
.shift();

if (!xcode27) {
return done();
}

should(xcode27.simDevicePairs).eql({
'26.x': {
'26.x': true,
'27.x': true
},
'27.x': {
'26.x': true,
'27.x': true
}
});
done();
});
});
});

it('detect should use DeviceHub as the Xcode 27 simulator executable', function (done) {
this.timeout(5000);
this.slow(2000);

skipUnlessSelectedXcode27(this, done, function () {
ioslib.xcode.detect({ bypassCache: true }, function (err, results) {
if (err) {
return done(err);
}

var xcode27 = Object.keys(results.xcode)
.map(function (id) { return results.xcode[id]; })
.filter(function (xc) { return /^27\./.test(xc.version); })
.shift();

if (!xcode27) {
return done();
}

var deviceHub = 'DeviceHub.app/Contents/MacOS/DeviceHub';
should(xcode27.executables.simulator).not.equal(null);
should(xcode27.executables.simulator).endWith(deviceHub);
should(xcode27.executables.watchsimulator).equal(xcode27.executables.simulator);
done();
});
});
});
});
Loading