diff --git a/detox/ios/Detox/DetoxManager.m b/detox/ios/Detox/DetoxManager.m index cccc249192..44b84b9cb4 100644 --- a/detox/ios/Detox/DetoxManager.m +++ b/detox/ios/Detox/DetoxManager.m @@ -117,7 +117,7 @@ - (void) websocketDidReceiveAction:(NSString *)type withParams:(NSDictionary *)p } else if([type isEqualToString:@"openURL"]) { - NSURL* URLToOpen = [NSURL fileURLWithPath:params[@"url"]]; + NSURL* URLToOpen = [NSURL URLWithString:params[@"url"]]; NSParameterAssert(URLToOpen != nil); diff --git a/detox/src/client/Client.js b/detox/src/client/Client.js index cdcc5c2374..6617453130 100644 --- a/detox/src/client/Client.js +++ b/detox/src/client/Client.js @@ -37,6 +37,10 @@ class Client { await this.sendAction(new actions.CurrentStatus()); } + async openURL(params) { + await this.sendAction(new actions.openURL(params)); + } + async execute(invocation) { if (typeof invocation === 'function') { invocation = invocation(); diff --git a/detox/src/client/actions/actions.js b/detox/src/client/actions/actions.js index 0b6814d52a..f4b41f791c 100644 --- a/detox/src/client/actions/actions.js +++ b/detox/src/client/actions/actions.js @@ -89,6 +89,16 @@ class SendUserNotification extends Action { } } +class openURL extends Action { + constructor(params) { + super('openURL', params); + } + + async handle(response) { + this.expectResponseOfType(response, 'openURLDone'); + } +} + class CurrentStatus extends Action { constructor(params) { super('currentStatus', params); @@ -111,6 +121,7 @@ module.exports = { Invoke, ReloadReactNative, Cleanup, + openURL, SendUserNotification, CurrentStatus }; diff --git a/detox/src/devices/Device.js b/detox/src/devices/Device.js index 5e1208559c..4edf3ca427 100644 --- a/detox/src/devices/Device.js +++ b/detox/src/devices/Device.js @@ -37,6 +37,9 @@ class Device { let additionalLaunchArgs; if (params.url) { additionalLaunchArgs = {'detoxURLOverride': params.url}; + if(params.sourceApp) { + additionalLaunchArgs['detoxSourceAppOverride'] = params.sourceApp; + } } else if (params.userNotification) { additionalLaunchArgs = {'detoxUserNotificationDataURL': this.deviceDriver.createPushNotificationJson(params.userNotification)}; } @@ -67,8 +70,12 @@ class Device { await this.deviceDriver.reloadReactNative(); } - async openURL(url) { - await this.deviceDriver.openURL(this._deviceId, url); + async openURL(params) { + if(typeof params !== 'object' || !params.url) { + throw new Error(`openURL must be called with JSON params, and a value for 'url' key must be provided. example: await device.openURL({url: "url", sourceApp: "sourceAppBundleID"}`); + } + + await this.deviceDriver.openURL(this._deviceId, params); } async shutdown() { diff --git a/detox/src/devices/DeviceDriverBase.js b/detox/src/devices/DeviceDriverBase.js index 355a098fb2..5dae4918d5 100644 --- a/detox/src/devices/DeviceDriverBase.js +++ b/detox/src/devices/DeviceDriverBase.js @@ -31,7 +31,7 @@ class DeviceDriverBase { return await Promise.resolve(''); } - async openURL() { + async openURL(params) { return await Promise.resolve(''); } diff --git a/detox/src/devices/IosDriver.js b/detox/src/devices/IosDriver.js index 6431dea199..cd1b39f528 100644 --- a/detox/src/devices/IosDriver.js +++ b/detox/src/devices/IosDriver.js @@ -41,6 +41,10 @@ class IosDriver extends DeviceDriverBase { await super.sendUserNotification({detoxUserNotificationDataURL: notificationFilePath}); } + async openURL(deviceId, params) { + this.client.openURL(params); + } + async setURLBlacklist(urlList) { await this.client.execute(GREYConfiguration.setURLBlacklist(urlList)); } diff --git a/detox/src/devices/SimulatorDriver.js b/detox/src/devices/SimulatorDriver.js index dc28c1c318..427ba3dd70 100644 --- a/detox/src/devices/SimulatorDriver.js +++ b/detox/src/devices/SimulatorDriver.js @@ -34,10 +34,6 @@ class SimulatorDriver extends IosDriver { await this._fbsimctl.terminate(deviceId, bundleId); } - async openURL(deviceId, url) { - await this._fbsimctl.open(deviceId, url); - } - async shutdown(deviceId) { await this._fbsimctl.shutdown(deviceId); } diff --git a/detox/test/e2e/n-deep-links.js b/detox/test/e2e/n-deep-links.js index ced3f7d42d..c0a26d2a3e 100644 --- a/detox/test/e2e/n-deep-links.js +++ b/detox/test/e2e/n-deep-links.js @@ -6,10 +6,16 @@ describe.only('Deep Links', () => { await expect(element(by.label(url))).toBeVisible(); }); - it('device.openURL(url) should', async () => { + it('device.openURL({url: url}) should', async () => { const url = 'detoxtesturlscheme://such-string'; await device.relaunchApp(); - await device.openURL(url); + + await device.openURL({url: url}); await expect(element(by.label(url))).toBeVisible(); }); }); + + +async function timeout(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} \ No newline at end of file diff --git a/detox/test/index.ios.js b/detox/test/index.ios.js index 34c8577092..cac2f08db7 100644 --- a/detox/test/index.ios.js +++ b/detox/test/index.ios.js @@ -55,7 +55,7 @@ class example extends Component { componentWillMount() { PushNotificationIOS.addEventListener('notification', (notification) => this._onNotification(notification)); PushNotificationIOS.addEventListener('localNotification', (notification) => this._onNotification(notification)); - Linking.addEventListener('url', (url) => this._handleOpenURL(url)); + Linking.addEventListener('url', (params) => this._handleOpenURL(params)); } render() { @@ -98,8 +98,8 @@ class example extends Component { this.setState({notification: notification.getAlert()}); } - _handleOpenURL(url) { - this.setState({url: url}); + _handleOpenURL(params) { + this.setState({url: params.url}); } }