Open Deeplink in iOS Programmatically, For Test Automation say

Sandeep Dinesh
2 min readJun 18, 2021

--

The first thing I noticed about opening deep links in my product documentation was to use an ADB command to open the deeplink and for iOS open a Safari instance on your Device/ emulator and type in the deeplink in the address and press Enter.

As a career-long test automation enthusiast, My thoughts were — Now I need to open two instances of Appium, one for Safari and one for our native app, and somehow play around both the instances. Somewhere I heard use Slack to trigger the deeplink, which still made me feel, the same two instance model. Looks Tough!

Well, it turns out we a solution and this is what we need to do. TL, DR:

  1. Identify the UUID of your device/ simulator using
xcrun simctl list devices

2. Run the openurl command

xcrun simctl openurl [booted | <Your device/ Simulator UUID>] '<Deeplink URL>'For e.g.
xcrun simctl openurl booted 'http://maps.apple.com?q=Townsville'
xcrun simctl openurl 81DD15309-E59D-4C37-9F35-66EEDC67C702 'http://maps.apple.com?q=Townsville'

This would internally kickoff a Safari instance on your iOS device/ simulator, and since it identifies this to pick up Apple Maps (in this example, or to your App), the control moves to the target app (Apple Maps in this example, your app with the correct deeplink)

Incase you have only one instance of Device/ Simualtor booted, you can use the booted option, else use the targeted device’s UUID

How to deal with Appium for Deeplinks

{ 
platform: 'iOS',
waitForTimeout: 300000,
desiredCapabilities: {
deviceName: '<DEVICE_NAME>',
platformVersion: '<PLATFORM_VERSION>',
app: path.join(
__dirname,
'<APP_LOCATION>'
),
udid: '<DEVICE_UUID>',
xcodeOrgId: '<APPLE_DEVELOPER_SIGNATURE_ORG>',
xcodeSigningId: 'iPhone Developer',
automationName: 'XCUITest',
noReset: true,
fullReset: false,
},
}

Your desired capabilities should look something like above, specifically your parameters noReset and fullReset, otherwise the deeplink navigation data would be reset by the Appium for the next test run.

Important note: parameters like <DEVICE_NAME>, <PLATFORM_VERSION>, <APP_LOCATION>, <DEVICE_UUID>and <APPLE_DEVELOPER_SIGNATURE_ORG> need to updated to your particular instace.

You can read more about setting iOS Appium testing in Github Actions and CircleCI by referring to my earlier posts on the topic!

Final Cut

const MapDetailPage = require('../page_objects').screens.map.MapDetailPage;
const MapPermissionPage = require('../page_objects').screens.map.MapPermissionPage;
var spawn = require('child_process').spawn;
const LOCATION = 'Townsville Queensland, Australia'
/**@type MapDetailPage */
let mapDetailPage;
Feature('MAP').tag('Feature=MAP');
Before(async function () {

spawn('xcrun', ['xctrace', 'simctl', 'openurl', 'http://maps.apple.com?q=Townsville'], {
stdio: ['ignore', out, err],
detached: true
}).unref();

const mapPermissionPage = new MapPermissionPage();
await mapPermissionPage.heading.seeElement();
await mapPermissionPage.allowWhileUsingTheAppButton.tap();
//Initialize MapDetailPage Page
mapDetailPage = new MapDetailPage();
await mapDetailPage.heading.seeElement();
});
Scenario('Deeplink Test', async () => {
await mapDetailPage.search(LOCATION);
await mapDetailPage.searchResult.success.seeElement();
})
.tag('FUNCTIONAL')
.tag('APP-LOADING')
.tag('MAP')
.tag('POSITIVE')
.tag('RELEASE');

Happy Test Automation!

--

--