Skip to content

Commit

Permalink
Add e2e test over the url-launchArgs combo case
Browse files Browse the repository at this point in the history
  • Loading branch information
d4vidi committed Dec 20, 2023
1 parent b716d27 commit 0097fb7
Show file tree
Hide file tree
Showing 9 changed files with 258 additions and 96 deletions.
20 changes: 20 additions & 0 deletions detox/test/e2e/15.urls-and-launchArgs.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const { urlDriver } = require('./drivers/url-driver');
const { launchArgsDriver } = require('./drivers/launch-args-driver');

describe('Launch arguments while handing launch URLs', () => {
it('should pass user args in normally', async () => {
const userArgs = {
how: 'about some',
pie: '3.14',
};
const detoxLaunchArgs = urlDriver.withDetoxArgs.andUserArgs(userArgs);

await device.launchApp({ newInstance: true, ...detoxLaunchArgs });
await urlDriver.navToUrlScreen();
await urlDriver.assertUrl(detoxLaunchArgs.url);

await device.reloadReactNative();
await launchArgsDriver.navToLaunchArgsScreen();
await launchArgsDriver.assertLaunchArgs(userArgs);
});
});
29 changes: 12 additions & 17 deletions detox/test/e2e/15.urls.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const { urlDriver } = require('./drivers/url-driver');

describe('Open URLs', () => {
afterAll(async () => {
await device.launchApp({
Expand All @@ -7,38 +9,31 @@ describe('Open URLs', () => {
});
});

const withDefaultArgs = () => ({
url: 'detoxtesturlscheme://such-string?arg1=first&arg2=second',
launchArgs: undefined,
});

const withSingleInstanceActivityArgs = () => ({
url: 'detoxtesturlscheme.singleinstance://such-string',
launchArgs: { detoxAndroidSingleInstanceActivity: true },
});

describe.each([
['(default)', withDefaultArgs()],
[':android: (single activity)', withSingleInstanceActivityArgs()],
['(default)', urlDriver.withDetoxArgs.default()],
[':android: (single activity)', urlDriver.withDetoxArgs.forSingleInstanceActivityLaunch()],
])('%s', (_platform, {url, launchArgs}) => {
it(`device.launchApp() with a URL and a fresh app should launch app and trigger handling open url handling in app`, async () => {
await device.launchApp({newInstance: true, url, launchArgs});
await expect(element(by.text(url))).toBeVisible();
await urlDriver.navToUrlScreen();
await urlDriver.assertUrl(url);
});

it(`device.openURL() should trigger open url handling in app when app is in foreground`, async () => {
await device.launchApp({newInstance: true, launchArgs});
await expect(element(by.text(url))).not.toBeVisible();
await urlDriver.navToUrlScreen();
await urlDriver.assertNoUrl(url);
await device.openURL({url});
await expect(element(by.text(url))).toBeVisible();
await urlDriver.assertUrl(url);
});

it(`device.launchApp() with a URL should trigger url handling when app is in background`, async () => {
await device.launchApp({newInstance: true, launchArgs});
await expect(element(by.text(url))).not.toBeVisible();
await urlDriver.navToUrlScreen();
await urlDriver.assertNoUrl(url);
await device.sendToHome();
await device.launchApp({newInstance: false, url});
await expect(element(by.text(url))).toBeVisible();
await urlDriver.assertUrl(url);
});
});
});
60 changes: 20 additions & 40 deletions detox/test/e2e/22.launch-args.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* global by, device, element */
const _ = require('lodash');
const { launchArgsDriver: driver } = require('./drivers/launch-args-driver');

// Note: Android-only as, according to Leo, on iOS there's no added value here compared to
// existing tests that check deep-link URLs. Combined with the fact that we do not yet
Expand All @@ -13,26 +14,27 @@ describe(':android: Launch arguments', () => {

beforeEach(async () => {
await device.selectApp('exampleWithArgs');
assertPreconfiguredValues(device.appLaunchArgs.get(), defaultArgs);
driver.assertPreconfiguredValues(device.appLaunchArgs.get(), defaultArgs);
});

it('should preserve a shared arg in spite of app reselection', async () => {
const override = { ama: 'zed' };

try {
assertPreconfiguredValues(device.appLaunchArgs.get(), defaultArgs);
assertPreconfiguredValues(device.appLaunchArgs.shared.get(), {});
driver.assertPreconfiguredValues(device.appLaunchArgs.get(), defaultArgs);
driver.assertPreconfiguredValues(device.appLaunchArgs.shared.get(), {});
device.appLaunchArgs.shared.modify(override);

assertPreconfiguredValues(device.appLaunchArgs.get(), { ...defaultArgs, ...override });
assertPreconfiguredValues(device.appLaunchArgs.shared.get(), override);
driver.assertPreconfiguredValues(device.appLaunchArgs.get(), { ...defaultArgs, ...override });
driver.assertPreconfiguredValues(device.appLaunchArgs.shared.get(), override);

await device.selectApp('example');
assertPreconfiguredValues(device.appLaunchArgs.get(), override);
assertPreconfiguredValues(device.appLaunchArgs.shared.get(), override);
driver.assertPreconfiguredValues(device.appLaunchArgs.get(), override);
driver.assertPreconfiguredValues(device.appLaunchArgs.shared.get(), override);

await device.launchApp({ newInstance: true });
await assertLaunchArgs(override);
await driver.navToLaunchArgsScreen();
await driver.assertLaunchArgs(override);
} finally {
device.appLaunchArgs.shared.reset();
}
Expand All @@ -46,7 +48,8 @@ describe(':android: Launch arguments', () => {
};

await device.launchApp({ newInstance: true, launchArgs });
await assertLaunchArgs(launchArgs);
await driver.navToLaunchArgsScreen();
await driver.assertLaunchArgs(launchArgs);
});

it('should handle complex args when used on-site', async () => {
Expand All @@ -61,7 +64,8 @@ describe(':android: Launch arguments', () => {
};

await device.launchApp({ newInstance: true, launchArgs });
await assertLaunchArgs({
await driver.navToLaunchArgsScreen();
await driver.assertLaunchArgs({
complex: JSON.stringify(launchArgs.complex),
complexlist: JSON.stringify(launchArgs.complexlist),
});
Expand All @@ -75,7 +79,8 @@ describe(':android: Launch arguments', () => {
});

await device.launchApp({ newInstance: true });
await assertLaunchArgs({
await driver.navToLaunchArgsScreen();
await driver.assertLaunchArgs({
'goo': 'gle!',
'ama': 'zon',
'micro': 'soft',
Expand All @@ -93,7 +98,8 @@ describe(':android: Launch arguments', () => {
});

await device.launchApp({ newInstance: true, launchArgs });
await assertLaunchArgs({ anArg: 'aValue!' });
await driver.navToLaunchArgsScreen();
await driver.assertLaunchArgs({ anArg: 'aValue!' });
});

// Ref: https://developer.android.com/studio/test/command-line#AMOptionsSyntax
Expand All @@ -106,33 +112,7 @@ describe(':android: Launch arguments', () => {
};

await device.launchApp({ newInstance: true, launchArgs });
await assertLaunchArgs({ hello: 'world' }, ['debug', 'log', 'size']);
await driver.navToLaunchArgsScreen();
await driver.assertLaunchArgs({ hello: 'world' }, ['debug', 'log', 'size']);
});

async function assertLaunchArgs(expected, notExpected) {
await element(by.text('Launch Args')).tap();

if (expected) {
for (const [key, value] of Object.entries(expected)) {
await expect(element(by.id(`launchArg-${key}.name`))).toBeVisible();
await expect(element(by.id(`launchArg-${key}.value`))).toHaveText(`${value}`);
}
}

if (notExpected) {
for (const key of notExpected) {
await expect(element(by.id(`launchArg-${key}.name`))).not.toBeVisible();
}
}
}

function assertPreconfiguredValues(initArgs, expectedInitArgs) {
if (!_.isEqual(initArgs, expectedInitArgs)) {
throw new Error(
`Precondition failure: Preconfigured launch arguments (in detox.config.js) do not match the expected value.\n` +
`Expected: ${JSON.stringify(expectedInitArgs)}\n` +
`Received: ${JSON.stringify(initArgs)}`
);
}
}
});
33 changes: 33 additions & 0 deletions detox/test/e2e/drivers/launch-args-driver.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const _ = require("lodash");
const driver = {
navToLaunchArgsScreen: () => element(by.text('Launch Args')).tap(),

assertPreconfiguredValues: (initArgs, expectedInitArgs) => {
if (!_.isEqual(initArgs, expectedInitArgs)) {
throw new Error(
`Precondition failure: Preconfigured launch arguments (in detox.config.js) do not match the expected value.\n` +
`Expected: ${JSON.stringify(expectedInitArgs)}\n` +
`Received: ${JSON.stringify(initArgs)}`
);
}
},

assertLaunchArgs: async (expected, notExpected) => {
if (expected) {
for (const [key, value] of Object.entries(expected)) {
await expect(element(by.id(`launchArg-${key}.name`))).toBeVisible();
await expect(element(by.id(`launchArg-${key}.value`))).toHaveText(`${value}`);
}
}

if (notExpected) {
for (const key of notExpected) {
await expect(element(by.id(`launchArg-${key}.name`))).not.toBeVisible();
}
}
}
}

module.exports = {
launchArgsDriver: driver,
};
26 changes: 26 additions & 0 deletions detox/test/e2e/drivers/url-driver.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const driver = {
withDetoxArgs: {
default: () => ({
url: 'detoxtesturlscheme://such-string?arg1=first&arg2=second',
launchArgs: undefined,
}),

andUserArgs: (launchArgs) => ({
url: 'detoxtesturlscheme',
launchArgs,
}),

forSingleInstanceActivityLaunch: () => ({
url: 'detoxtesturlscheme.singleinstance://such-string',
launchArgs: { detoxAndroidSingleInstanceActivity: true },
}),
},

navToUrlScreen: () => element(by.text('Init URL')).tap(),
assertUrl: (url) => expect(element(by.text(url))).toBeVisible(),
assertNoUrl: (url) => expect(element(by.text(url))).not.toBeVisible(),
};

module.exports = {
urlDriver: driver,
};
81 changes: 81 additions & 0 deletions detox/test/e2e/seeing-eye.query
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
with events as (
select
date_trunc('day',date_created) date_created
,detox_version
,flavour
,platform
,case when app_names in ('legacy', 'spaces', 'places') then 'spaces' else app_names end as app_names
,case
when actual_module_name = 'wix-inbox-mobile' then concat(actual_module_name,'-',a.build_conf_name)
when module_name = 'wix-inbox-mobile' then concat(module_name,'-',a.build_conf_name)
when triggering_module = 'wix-inbox-mobile' then concat(triggering_module,'-',a.build_conf_name)
when date_created >= date '2023-02-14' then actual_module_name
when triggering_module is not null then triggering_module
else module_name end as module
,max(num_passed_tests) num_tests
,max(num_failed_tests) num_failed_tests
,max(num_tests) overall_num_tests
,max(num_skipped_tests) num_skipped_tests
from events.dbo.sites_11 a
where
evid = 98801
and a.date_created >= current_date -interval '12' month
and flavour in ('production','dev')
and (triggering_module is null or build_conf_name = 'OneApp+08')
group by 1,2,3,4,5,6
)
,dates as (
select date_created
from (
select sequence(current_date - interval '12' month,current_date,interval '1' day)dates
) cross join unnest(dates) as x(date_created)
)
,agg as (
select date_created
,num_tests
,num_failed_tests
,overall_num_tests
,num_skipped_tests
,flavour
,platform
,concat(module,'-',app_names) module_app
from events a
where (a.module not like '%+%' or a.module like '%smoke_%')
and (a.num_tests > 2 or a.module like '%smoke_%')
and a.module <> 'detox-wix-preset'
and a.module <> 'MRE'
and a.module <> 'Wix+One+App+Parallel'
and a.module not like '%-tmp%'
and a.module <> 'shono'
and a.module not like 'shono%'
and a.module <> 'Wix One App Engine Parallel'
and a.module not like 'Wix One App Engine Parallel%'
and a.module not like 'Wix One App Parallel%'
and a.module <> 'Wix One App Parallel'
and a.module not like 'mre%'
and a.module not like 'wix-one-pikachu%'
and a.module <> 'wix-stores-marchant-app'
and a.date_created < date_trunc('day', current_date)
group by 1,2,3,4,5,6,7,8
)
,crossing as (
select a.date_created
,flavour
,platform
,module_app
from dates a
cross join agg b
group by 1,2,3,4
)

select a.date_created date_created
,coalesce(num_tests, 0) num_tests
,coalesce(num_failed_tests, 0) num_failed_tests
,coalesce(overall_num_tests, 0) overall_num_tests
,coalesce(num_skipped_tests, 0) num_skipped_tests
,a.flavour flavour
,a.platform platform
,a.module_app module_app
from crossing a
left join agg b on b.date_created = a.date_created and a.module_app = b.module_app and a.flavour = b.flavour and a.platform = b.platform
where a.date_created < date_trunc('day', current_date);
45 changes: 45 additions & 0 deletions detox/test/src/Screens/LaunchUrlScreen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React, { Component } from 'react';
import {
Linking,
Text,
View,
} from 'react-native';

export default class LaunchUrlScreen extends Component {

constructor(props) {
super(props);

Linking.addEventListener('url', (params) => this._handleOpenURL(params));

this.state = {
url: undefined,
}
}

async componentDidMount() {
const url = await Linking.getInitialURL();
this.setState({
url,
});
}

renderText(text) {
return (
<View style={{flex: 1, paddingTop: 20, justifyContent: 'center', alignItems: 'center'}}>
<Text style={{fontSize: 25}}>
{text}
</Text>
</View>
);
}

render() {
return this.renderText(this.state.url);
}

_handleOpenURL(params) {
console.log('App@handleOpenURL:', params);
this.setState({url: params.url});
}
}
Loading

0 comments on commit 0097fb7

Please sign in to comment.