Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: use activateApp from adb #964

Merged
merged 4 commits into from
Nov 9, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
56 changes: 3 additions & 53 deletions lib/commands/app-management.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import B from 'bluebird';

const APP_EXTENSIONS = ['.apk', '.apks'];
const RESOLVER_ACTIVITY_NAME = 'android/com.android.internal.app.ResolverActivity';

Check warning on line 9 in lib/commands/app-management.js

View workflow job for this annotation

GitHub Actions / test (22)

'RESOLVER_ACTIVITY_NAME' is assigned a value but never used

Check warning on line 9 in lib/commands/app-management.js

View workflow job for this annotation

GitHub Actions / test (20)

'RESOLVER_ACTIVITY_NAME' is assigned a value but never used

Check warning on line 9 in lib/commands/app-management.js

View workflow job for this annotation

GitHub Actions / test (18)

'RESOLVER_ACTIVITY_NAME' is assigned a value but never used

Check warning on line 9 in lib/commands/app-management.js

View workflow job for this annotation

GitHub Actions / test (22)

'RESOLVER_ACTIVITY_NAME' is assigned a value but never used

Check warning on line 9 in lib/commands/app-management.js

View workflow job for this annotation

GitHub Actions / test (20)

'RESOLVER_ACTIVITY_NAME' is assigned a value but never used

Check warning on line 9 in lib/commands/app-management.js

View workflow job for this annotation

GitHub Actions / test (18)

'RESOLVER_ACTIVITY_NAME' is assigned a value but never used
const PACKAGE_INSTALL_TIMEOUT_MS = 90000;
// These constants are in sync with
// https://developer.apple.com/documentation/xctest/xcuiapplicationstate/xcuiapplicationstaterunningbackground?language=objc
Expand Down Expand Up @@ -84,57 +84,7 @@
* @returns {Promise<void>}
*/
export async function activateApp(appId) {
this.log.debug(`Activating '${appId}'`);
const apiLevel = await this.adb.getApiLevel();
// Fallback to Monkey in older APIs
if (apiLevel < 24) {
// The monkey command could raise an issue as https://stackoverflow.com/questions/44860475/how-to-use-the-monkey-command-with-an-android-system-that-doesnt-have-physical
// but '--pct-syskeys 0' could cause another background process issue. https://github.com/appium/appium/issues/16941#issuecomment-1129837285
const cmd = ['monkey', '-p', appId, '-c', 'android.intent.category.LAUNCHER', '1'];
let output = '';
try {
output = await this.adb.shell(cmd);
this.log.debug(`Command stdout: ${output}`);
} catch (e) {
this.log.errorAndThrow(
`Cannot activate '${appId}'. Original error: ${/** @type {Error} */ (e).message}`,
);
}
if (output.includes('monkey aborted')) {
this.log.errorAndThrow(`Cannot activate '${appId}'. Are you sure it is installed?`);
}
return;
}

let activityName = await this.adb.resolveLaunchableActivity(appId);
if (activityName === RESOLVER_ACTIVITY_NAME) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also remove the unused constant

// https://github.com/appium/appium/issues/17128
this.log.debug(
`The launchable activity name of '${appId}' was resolved to '${activityName}'. ` +
`Switching the resolver to not use cmd`,
);
activityName = await this.adb.resolveLaunchableActivity(appId, {preferCmd: false});
}

const stdout = await this.adb.shell([
'am',
apiLevel < 26 ? 'start' : 'start-activity',
'-a',
'android.intent.action.MAIN',
'-c',
'android.intent.category.LAUNCHER',
// FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
// https://developer.android.com/reference/android/content/Intent#FLAG_ACTIVITY_NEW_TASK
// https://developer.android.com/reference/android/content/Intent#FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
'-f',
'0x10200000',
'-n',
activityName,
]);
this.log.debug(stdout);
if (/^error:/im.test(stdout)) {
throw new Error(`Cannot activate '${appId}'. Original error: ${stdout}`);
}
return await this.adb.activateApp(appId);
}

/**
Expand All @@ -144,7 +94,7 @@
*/
export async function mobileActivateApp(opts) {
const {appId} = requireArgs('appId', opts);
return await this.activateApp(appId);
return await this.adb.activateApp(appId);
}

/**
Expand Down Expand Up @@ -332,7 +282,7 @@
} else {
try {
this.log.debug(`Activating app '${appPackage}' in order to restore it`);
await this.activateApp(/** @type {string} */ (appPackage));
await this.adb.activateApp(/** @type {string} */ (appPackage));
return true;
} catch (ign) {}
args =
Expand Down
12 changes: 6 additions & 6 deletions test/unit/commands/app-management-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,12 @@ describe('App Management', function () {
sandbox.stub(driver.adb, 'getFocusedPackageAndActivity').returns({appPackage, appActivity});
sandbox.stub(B, 'delay');
sandbox.stub(driver.adb, 'startApp');
sandbox.stub(driver, 'activateApp');
sandbox.stub(driver.adb, 'activateApp');
await driver.background(10);
driver.adb.getFocusedPackageAndActivity.calledOnce.should.be.true;
driver.adb.goToHome.calledOnce.should.be.true;
B.delay.calledWithExactly(10000).should.be.true;
driver.activateApp.calledWithExactly(appPackage).should.be.true;
driver.adb.activateApp.calledWithExactly(appPackage).should.be.true;
driver.adb.startApp.notCalled.should.be.true;
});
it('should bring app to background and back if started after session init', async function () {
Expand Down Expand Up @@ -154,13 +154,13 @@ describe('App Management', function () {
sandbox.stub(driver.adb, 'getFocusedPackageAndActivity').returns({appPackage, appActivity});
sandbox.stub(B, 'delay');
sandbox.stub(driver.adb, 'startApp');
sandbox.stub(driver, 'activateApp');
sandbox.stub(driver.adb, 'activateApp');
await driver.background(10);
driver.adb.getFocusedPackageAndActivity.calledOnce.should.be.true;
driver.adb.goToHome.calledOnce.should.be.true;
B.delay.calledWithExactly(10000).should.be.true;
driver.adb.startApp.calledWithExactly(params).should.be.true;
driver.activateApp.notCalled.should.be.true;
driver.adb.activateApp.notCalled.should.be.true;
});
it('should bring app to background and back if waiting for other pkg / activity', async function () {
//eslint-disable-line
Expand All @@ -185,12 +185,12 @@ describe('App Management', function () {
.returns({appPackage: appWaitPackage, appActivity: appWaitActivity});
sandbox.stub(B, 'delay');
sandbox.stub(driver.adb, 'startApp');
sandbox.stub(driver, 'activateApp');
sandbox.stub(driver.adb, 'activateApp');
await driver.background(10);
driver.adb.getFocusedPackageAndActivity.calledOnce.should.be.true;
driver.adb.goToHome.calledOnce.should.be.true;
B.delay.calledWithExactly(10000).should.be.true;
driver.activateApp.calledWithExactly(appWaitPackage).should.be.true;
driver.adb.activateApp.calledWithExactly(appWaitPackage).should.be.true;
driver.adb.startApp.notCalled.should.be.true;
});
it('should not bring app back if seconds are negative', async function () {
Expand Down
Loading