From 7d8dba7fb8b4e1a131a2a123021e96ec44a58506 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Sun, 7 Jan 2024 18:48:11 -0800 Subject: [PATCH 1/7] fix: io.appium.settings starts every new session --- lib/helpers/android.ts | 136 +++++++++++++++++++++-------------------- 1 file changed, 71 insertions(+), 65 deletions(-) diff --git a/lib/helpers/android.ts b/lib/helpers/android.ts index 5aa4a10b..98b04657 100644 --- a/lib/helpers/android.ts +++ b/lib/helpers/android.ts @@ -76,7 +76,7 @@ function ensureNetworkSpeed(adb: ADB, networkSpeed: string) { } logger.warn( `Wrong network speed param '${networkSpeed}', using default: ${adb.NETWORK_SPEED.FULL}. ` + - `Supported values: ${_.values(adb.NETWORK_SPEED)}` + `Supported values: ${_.values(adb.NETWORK_SPEED)}`, ); return adb.NETWORK_SPEED.FULL; } @@ -139,15 +139,15 @@ interface AndroidHelpers { validatePackageActivityNames(opts: Opts): void; getLaunchInfo( adb: ADB, - opts: Opts + opts: Opts, ): Promise; resetApp( adb: ADB, - opts: SetRequired + opts: SetRequired, ): Promise; installApk( adb: ADB, - opts: SetRequired + opts: SetRequired, ): Promise; /** @@ -158,7 +158,7 @@ interface AndroidHelpers { installOtherApks( apks: string[], adb: ADB, - opts: SetRequired + opts: SetRequired, ): Promise; /** @@ -213,12 +213,12 @@ interface AndroidHelpers { pushStrings( language: string | undefined, adb: ADB, - opts: AndroidDriverOpts + opts: AndroidDriverOpts, ): Promise; unlock( driver: D, adb: ADB, - capabilities: Caps + capabilities: Caps, ): Promise; verifyUnlock(adb: ADB, timeoutMs?: number | null): Promise; initDevice(adb: ADB, opts: AndroidDriverOpts): Promise; @@ -228,7 +228,7 @@ interface AndroidHelpers { getChromePkg(browser: string): ValueOf; removeAllSessionWebSocketHandlers( server?: AppiumServer, - sessionId?: string | null + sessionId?: string | null, ): Promise; parseArray(cap: string | string[]): string[]; @@ -447,7 +447,7 @@ const AndroidHelpers: AndroidHelpers = { logger.errorAndThrow( `Unable to find an active device or emulator ` + `with OS ${opts.platformVersion}. The following are available: ` + - availDevices.join(', ') + availDevices.join(', '), ); throw new Error(); // unreachable; for TS } @@ -489,12 +489,12 @@ const AndroidHelpers: AndroidHelpers = { } logger.warn( - `Capability '${key}' is expected to only include latin letters, digits, underscore, dot, comma and asterisk characters.` + `Capability '${key}' is expected to only include latin letters, digits, underscore, dot, comma and asterisk characters.`, ); logger.warn( `Current value '${name}' has non-matching character at index ${match.index}: '${String( - name - ).substring(0, match.index + 1)}'` + name, + ).substring(0, match.index + 1)}'`, ); } }, @@ -557,7 +557,7 @@ const AndroidHelpers: AndroidHelpers = { const output = await adb.clear(appPackage); if (_.isString(output) && output.toLowerCase().includes('failed')) { throw new Error( - `Cannot clear the application data of '${appPackage}'. Original error: ${output}` + `Cannot clear the application data of '${appPackage}'. Original error: ${output}`, ); } // executing `shell pm clear` resets previously assigned application permissions as well @@ -566,12 +566,12 @@ const AndroidHelpers: AndroidHelpers = { await adb.grantAllPermissions(appPackage); } catch (error) { logger.error( - `Unable to grant permissions requested. Original error: ${(error as Error).message}` + `Unable to grant permissions requested. Original error: ${(error as Error).message}`, ); } } logger.debug( - `Performed fast reset on the installed '${appPackage}' application (stop and clear)` + `Performed fast reset on the installed '${appPackage}' application (stop and clear)`, ); return; } @@ -580,7 +580,7 @@ const AndroidHelpers: AndroidHelpers = { if (!app) { throw new Error( `Either provide 'app' option to install '${appPackage}' or ` + - `consider setting 'noReset' to 'true' if '${appPackage}' is supposed to be preinstalled.` + `consider setting 'noReset' to 'true' if '${appPackage}' is supposed to be preinstalled.`, ); } @@ -648,7 +648,7 @@ const AndroidHelpers: AndroidHelpers = { timeout: androidInstallTimeout, allowTestPackages, }); - }) + }), ); }, @@ -673,7 +673,7 @@ const AndroidHelpers: AndroidHelpers = { return _.difference(appPackagesArray, filterPackages); } catch (err) { logger.warn( - `Unable to get packages with 'adb shell pm list packages -3': ${(err as Error).message}` + `Unable to get packages with 'adb shell pm list packages -3': ${(err as Error).message}`, ); return []; } @@ -769,8 +769,8 @@ const AndroidHelpers: AndroidHelpers = { try { await adb.shell(['appops', 'set', pkgId, 'android:mock_location', 'deny']); } catch (ign) {} - })() - ) + })(), + ), ); } catch (err) { logger.warn(`Unable to reset mock location: ${(err as Error).message}`); @@ -785,7 +785,7 @@ const AndroidHelpers: AndroidHelpers = { HELPER_APP_INSTALL_RETRY_DELAY_MS, async function retryInstallHelperApp() { await adb.installOrUpgrade(apkPath, packageId, {grantPermissions: true}); - } + }, ); }, @@ -803,7 +803,7 @@ const AndroidHelpers: AndroidHelpers = { `Ignored error while installing '${settingsApkPath}': ` + `'${(err as Error).message}'. Features that rely on this helper ` + 'require the apk such as toggle WiFi and getting location ' + - 'will raise an error if you try to use them.' + 'will raise an error if you try to use them.', ); } @@ -812,40 +812,45 @@ const AndroidHelpers: AndroidHelpers = { if (await adb.processExists(SETTINGS_HELPER_PKG_ID)) { logger.debug( `${SETTINGS_HELPER_PKG_ID} is already running. ` + - `There is no need to reset its permissions.` + `There is no need to reset its permissions.`, ); - return; - } - - const apiLevel = await adb.getApiLevel(); - if (apiLevel >= 29) { - // https://github.com/appium/io.appium.settings#internal-audio--video-recording - try { - await adb.shell(['appops', 'set', SETTINGS_HELPER_PKG_ID, 'PROJECT_MEDIA', 'allow']); - } catch (err) { - logger.debug((err as Error).message); + } else { + const apiLevel = await adb.getApiLevel(); + if (apiLevel >= 29) { + // https://github.com/appium/io.appium.settings#internal-audio--video-recording + try { + await adb.shell(['appops', 'set', SETTINGS_HELPER_PKG_ID, 'PROJECT_MEDIA', 'allow']); + } catch (err) { + logger.debug((err as Error).message); + } + try { + await adb.shell([ + 'cmd', + 'notification', + 'allow_listener', + SETTING_NOTIFICATIONS_LISTENER_SERVICE, + ]); + } catch (err) { + logger.debug((err as Error).message); + } } - try { - await adb.shell([ - 'cmd', - 'notification', - 'allow_listener', - SETTING_NOTIFICATIONS_LISTENER_SERVICE, - ]); - } catch (err) { - logger.debug((err as Error).message); + if (apiLevel <= 23) { + // Android 6- devices should have granted permissions + // https://github.com/appium/appium/pull/11640#issuecomment-438260477 + const perms = ['SET_ANIMATION_SCALE', 'CHANGE_CONFIGURATION', 'ACCESS_FINE_LOCATION']; + logger.info(`Granting permissions ${perms} to '${SETTINGS_HELPER_PKG_ID}'`); + await adb.grantPermissions( + SETTINGS_HELPER_PKG_ID, + perms.map((x) => `android.permission.${x}`), + ); } } - if (apiLevel <= 23) { - // Android 6- devices should have granted permissions - // https://github.com/appium/appium/pull/11640#issuecomment-438260477 - const perms = ['SET_ANIMATION_SCALE', 'CHANGE_CONFIGURATION', 'ACCESS_FINE_LOCATION']; - logger.info(`Granting permissions ${perms} to '${SETTINGS_HELPER_PKG_ID}'`); - await adb.grantPermissions( - SETTINGS_HELPER_PKG_ID, - perms.map((x) => `android.permission.${x}`) - ); - } + + // Some commands by adb such as 'adb shell cmd notification' + // could launch the app process but it was not started via activity. + // It could cause wrong io.appium.settings process launches, + // thus it is safe to start the app process forcefully every session start + // to ensure the settings app process starts. // launch io.appium.settings app due to settings failing to be set // if the app is not launched prior to start the session on android 7+ @@ -853,6 +858,7 @@ const AndroidHelpers: AndroidHelpers = { try { await adb.requireRunningSettingsApp({ timeout: AndroidHelpers.isEmulator(adb, opts) ? 30000 : 5000, + forceStartSettingsApp: true, }); } catch (err) { logger.debug(err); @@ -877,7 +883,7 @@ const AndroidHelpers: AndroidHelpers = { logger.info( `Failed to pull an apk from '${opts.appPackage}' to '${opts.tmpDir}'. Original error: ${ (err as Error).message - }` + }`, ); } @@ -892,13 +898,13 @@ const AndroidHelpers: AndroidHelpers = { const {apkStrings, localPath} = await adb.extractStringsFromApk( app!, language ?? null, - stringsTmpDir + stringsTmpDir, ); await adb.push(localPath, remoteDir); return apkStrings; } catch (err) { logger.warn( - `Could not get strings, continuing anyway. Original error: ${(err as Error).message}` + `Could not get strings, continuing anyway. Original error: ${(err as Error).message}`, ); await adb.shell(['echo', `'{}' > ${remoteFile}`]); } finally { @@ -917,7 +923,7 @@ const AndroidHelpers: AndroidHelpers = { if (!capabilities.unlockType && !capabilities.unlockKey) { logger.info( `Neither 'unlockType' nor 'unlockKey' capability is provided. ` + - `Assuming the device is locked with a simple lock screen.` + `Assuming the device is locked with a simple lock screen.`, ); await adb.dismissKeyguard(); return; @@ -996,7 +1002,7 @@ const AndroidHelpers: AndroidHelpers = { unicodeKeyboard || hideKeyboard || disableWindowAnimation || - !skipUnlock + !skipUnlock, ); await AndroidHelpers.pushSettingsApp(adb, shouldThrowError, opts); } @@ -1031,7 +1037,7 @@ const AndroidHelpers: AndroidHelpers = { if (unicodeKeyboard) { logger.warn( `The 'unicodeKeyboard' capability has been deprecated and will be removed. ` + - `Set the 'hideKeyboard' capability to 'true' in order to make the on-screen keyboard invisible.` + `Set the 'hideKeyboard' capability to 'true' in order to make the on-screen keyboard invisible.`, ); return await AndroidHelpers.initUnicodeKeyboard(adb); } @@ -1096,12 +1102,12 @@ const AndroidHelpers: AndroidHelpers = { if (caps.app) { // warn if the capabilities have both `app` and `browser, although this is common with selenium grid logger.warn( - `The desired capabilities should generally not include both an 'app' and a 'browserName'` + `The desired capabilities should generally not include both an 'app' and a 'browserName'`, ); } if (caps.appPackage) { logger.errorAndThrow( - `The desired should not include both of an 'appPackage' and a 'browserName'` + `The desired should not include both of an 'appPackage' and a 'browserName'`, ); } } @@ -1111,7 +1117,7 @@ const AndroidHelpers: AndroidHelpers = { AndroidHelpers.parseArray(caps.uninstallOtherPackages); } catch (e) { logger.errorAndThrow( - `Could not parse "uninstallOtherPackages" capability: ${(e as Error).message}` + `Could not parse "uninstallOtherPackages" capability: ${(e as Error).message}`, ); } } @@ -1123,12 +1129,12 @@ const AndroidHelpers: AndroidHelpers = { const {browserName} = caps; logger.info(`The current session is considered browser-based`); logger.info( - `Supported browser names: ${JSON.stringify(_.keys(CHROME_BROWSER_PACKAGE_ACTIVITY))}` + `Supported browser names: ${JSON.stringify(_.keys(CHROME_BROWSER_PACKAGE_ACTIVITY))}`, ); if (caps.appPackage || caps.appActivity) { logger.info( `Not overriding appPackage/appActivity capability values for '${browserName}' ` + - 'because some of them have been already provided' + 'because some of them have been already provided', ); return caps; } @@ -1138,12 +1144,12 @@ const AndroidHelpers: AndroidHelpers = { caps.appActivity = activity; logger.info( `appPackage/appActivity capabilities have been automatically set to ${pkg}/${activity} ` + - `for '${browserName}'` + `for '${browserName}'`, ); logger.info( `Consider changing the browserName to the one from the list of supported browser names ` + `or provide custom appPackage/appActivity capability values if the automatically assigned ones do ` + - `not make sense` + `not make sense`, ); return caps; }, From 8596281d7de69f8deddaa2fc3a85dbf1ae41dd4f Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Sun, 7 Jan 2024 18:49:51 -0800 Subject: [PATCH 2/7] chore: revert auto lint fixes --- lib/helpers/android.ts | 74 +++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/lib/helpers/android.ts b/lib/helpers/android.ts index 98b04657..5988a2f9 100644 --- a/lib/helpers/android.ts +++ b/lib/helpers/android.ts @@ -76,7 +76,7 @@ function ensureNetworkSpeed(adb: ADB, networkSpeed: string) { } logger.warn( `Wrong network speed param '${networkSpeed}', using default: ${adb.NETWORK_SPEED.FULL}. ` + - `Supported values: ${_.values(adb.NETWORK_SPEED)}`, + `Supported values: ${_.values(adb.NETWORK_SPEED)}` ); return adb.NETWORK_SPEED.FULL; } @@ -139,15 +139,15 @@ interface AndroidHelpers { validatePackageActivityNames(opts: Opts): void; getLaunchInfo( adb: ADB, - opts: Opts, + opts: Opts ): Promise; resetApp( adb: ADB, - opts: SetRequired, + opts: SetRequired ): Promise; installApk( adb: ADB, - opts: SetRequired, + opts: SetRequired ): Promise; /** @@ -158,7 +158,7 @@ interface AndroidHelpers { installOtherApks( apks: string[], adb: ADB, - opts: SetRequired, + opts: SetRequired ): Promise; /** @@ -213,12 +213,12 @@ interface AndroidHelpers { pushStrings( language: string | undefined, adb: ADB, - opts: AndroidDriverOpts, + opts: AndroidDriverOpts ): Promise; unlock( driver: D, adb: ADB, - capabilities: Caps, + capabilities: Caps ): Promise; verifyUnlock(adb: ADB, timeoutMs?: number | null): Promise; initDevice(adb: ADB, opts: AndroidDriverOpts): Promise; @@ -228,7 +228,7 @@ interface AndroidHelpers { getChromePkg(browser: string): ValueOf; removeAllSessionWebSocketHandlers( server?: AppiumServer, - sessionId?: string | null, + sessionId?: string | null ): Promise; parseArray(cap: string | string[]): string[]; @@ -447,7 +447,7 @@ const AndroidHelpers: AndroidHelpers = { logger.errorAndThrow( `Unable to find an active device or emulator ` + `with OS ${opts.platformVersion}. The following are available: ` + - availDevices.join(', '), + availDevices.join(', ') ); throw new Error(); // unreachable; for TS } @@ -489,12 +489,12 @@ const AndroidHelpers: AndroidHelpers = { } logger.warn( - `Capability '${key}' is expected to only include latin letters, digits, underscore, dot, comma and asterisk characters.`, + `Capability '${key}' is expected to only include latin letters, digits, underscore, dot, comma and asterisk characters.` ); logger.warn( `Current value '${name}' has non-matching character at index ${match.index}: '${String( - name, - ).substring(0, match.index + 1)}'`, + name + ).substring(0, match.index + 1)}'` ); } }, @@ -557,7 +557,7 @@ const AndroidHelpers: AndroidHelpers = { const output = await adb.clear(appPackage); if (_.isString(output) && output.toLowerCase().includes('failed')) { throw new Error( - `Cannot clear the application data of '${appPackage}'. Original error: ${output}`, + `Cannot clear the application data of '${appPackage}'. Original error: ${output}` ); } // executing `shell pm clear` resets previously assigned application permissions as well @@ -566,12 +566,12 @@ const AndroidHelpers: AndroidHelpers = { await adb.grantAllPermissions(appPackage); } catch (error) { logger.error( - `Unable to grant permissions requested. Original error: ${(error as Error).message}`, + `Unable to grant permissions requested. Original error: ${(error as Error).message}` ); } } logger.debug( - `Performed fast reset on the installed '${appPackage}' application (stop and clear)`, + `Performed fast reset on the installed '${appPackage}' application (stop and clear)` ); return; } @@ -580,7 +580,7 @@ const AndroidHelpers: AndroidHelpers = { if (!app) { throw new Error( `Either provide 'app' option to install '${appPackage}' or ` + - `consider setting 'noReset' to 'true' if '${appPackage}' is supposed to be preinstalled.`, + `consider setting 'noReset' to 'true' if '${appPackage}' is supposed to be preinstalled.` ); } @@ -648,7 +648,7 @@ const AndroidHelpers: AndroidHelpers = { timeout: androidInstallTimeout, allowTestPackages, }); - }), + }) ); }, @@ -673,7 +673,7 @@ const AndroidHelpers: AndroidHelpers = { return _.difference(appPackagesArray, filterPackages); } catch (err) { logger.warn( - `Unable to get packages with 'adb shell pm list packages -3': ${(err as Error).message}`, + `Unable to get packages with 'adb shell pm list packages -3': ${(err as Error).message}` ); return []; } @@ -769,8 +769,8 @@ const AndroidHelpers: AndroidHelpers = { try { await adb.shell(['appops', 'set', pkgId, 'android:mock_location', 'deny']); } catch (ign) {} - })(), - ), + })() + ) ); } catch (err) { logger.warn(`Unable to reset mock location: ${(err as Error).message}`); @@ -785,7 +785,7 @@ const AndroidHelpers: AndroidHelpers = { HELPER_APP_INSTALL_RETRY_DELAY_MS, async function retryInstallHelperApp() { await adb.installOrUpgrade(apkPath, packageId, {grantPermissions: true}); - }, + } ); }, @@ -803,7 +803,7 @@ const AndroidHelpers: AndroidHelpers = { `Ignored error while installing '${settingsApkPath}': ` + `'${(err as Error).message}'. Features that rely on this helper ` + 'require the apk such as toggle WiFi and getting location ' + - 'will raise an error if you try to use them.', + 'will raise an error if you try to use them.' ); } @@ -812,7 +812,7 @@ const AndroidHelpers: AndroidHelpers = { if (await adb.processExists(SETTINGS_HELPER_PKG_ID)) { logger.debug( `${SETTINGS_HELPER_PKG_ID} is already running. ` + - `There is no need to reset its permissions.`, + `There is no need to reset its permissions.` ); } else { const apiLevel = await adb.getApiLevel(); @@ -841,7 +841,7 @@ const AndroidHelpers: AndroidHelpers = { logger.info(`Granting permissions ${perms} to '${SETTINGS_HELPER_PKG_ID}'`); await adb.grantPermissions( SETTINGS_HELPER_PKG_ID, - perms.map((x) => `android.permission.${x}`), + perms.map((x) => `android.permission.${x}`) ); } } @@ -883,7 +883,7 @@ const AndroidHelpers: AndroidHelpers = { logger.info( `Failed to pull an apk from '${opts.appPackage}' to '${opts.tmpDir}'. Original error: ${ (err as Error).message - }`, + }` ); } @@ -898,13 +898,13 @@ const AndroidHelpers: AndroidHelpers = { const {apkStrings, localPath} = await adb.extractStringsFromApk( app!, language ?? null, - stringsTmpDir, + stringsTmpDir ); await adb.push(localPath, remoteDir); return apkStrings; } catch (err) { logger.warn( - `Could not get strings, continuing anyway. Original error: ${(err as Error).message}`, + `Could not get strings, continuing anyway. Original error: ${(err as Error).message}` ); await adb.shell(['echo', `'{}' > ${remoteFile}`]); } finally { @@ -923,7 +923,7 @@ const AndroidHelpers: AndroidHelpers = { if (!capabilities.unlockType && !capabilities.unlockKey) { logger.info( `Neither 'unlockType' nor 'unlockKey' capability is provided. ` + - `Assuming the device is locked with a simple lock screen.`, + `Assuming the device is locked with a simple lock screen.` ); await adb.dismissKeyguard(); return; @@ -1002,7 +1002,7 @@ const AndroidHelpers: AndroidHelpers = { unicodeKeyboard || hideKeyboard || disableWindowAnimation || - !skipUnlock, + !skipUnlock ); await AndroidHelpers.pushSettingsApp(adb, shouldThrowError, opts); } @@ -1037,7 +1037,7 @@ const AndroidHelpers: AndroidHelpers = { if (unicodeKeyboard) { logger.warn( `The 'unicodeKeyboard' capability has been deprecated and will be removed. ` + - `Set the 'hideKeyboard' capability to 'true' in order to make the on-screen keyboard invisible.`, + `Set the 'hideKeyboard' capability to 'true' in order to make the on-screen keyboard invisible.` ); return await AndroidHelpers.initUnicodeKeyboard(adb); } @@ -1102,12 +1102,12 @@ const AndroidHelpers: AndroidHelpers = { if (caps.app) { // warn if the capabilities have both `app` and `browser, although this is common with selenium grid logger.warn( - `The desired capabilities should generally not include both an 'app' and a 'browserName'`, + `The desired capabilities should generally not include both an 'app' and a 'browserName'` ); } if (caps.appPackage) { logger.errorAndThrow( - `The desired should not include both of an 'appPackage' and a 'browserName'`, + `The desired should not include both of an 'appPackage' and a 'browserName'` ); } } @@ -1117,7 +1117,7 @@ const AndroidHelpers: AndroidHelpers = { AndroidHelpers.parseArray(caps.uninstallOtherPackages); } catch (e) { logger.errorAndThrow( - `Could not parse "uninstallOtherPackages" capability: ${(e as Error).message}`, + `Could not parse "uninstallOtherPackages" capability: ${(e as Error).message}` ); } } @@ -1129,12 +1129,12 @@ const AndroidHelpers: AndroidHelpers = { const {browserName} = caps; logger.info(`The current session is considered browser-based`); logger.info( - `Supported browser names: ${JSON.stringify(_.keys(CHROME_BROWSER_PACKAGE_ACTIVITY))}`, + `Supported browser names: ${JSON.stringify(_.keys(CHROME_BROWSER_PACKAGE_ACTIVITY))}` ); if (caps.appPackage || caps.appActivity) { logger.info( `Not overriding appPackage/appActivity capability values for '${browserName}' ` + - 'because some of them have been already provided', + 'because some of them have been already provided' ); return caps; } @@ -1144,12 +1144,12 @@ const AndroidHelpers: AndroidHelpers = { caps.appActivity = activity; logger.info( `appPackage/appActivity capabilities have been automatically set to ${pkg}/${activity} ` + - `for '${browserName}'`, + `for '${browserName}'` ); logger.info( `Consider changing the browserName to the one from the list of supported browser names ` + `or provide custom appPackage/appActivity capability values if the automatically assigned ones do ` + - `not make sense`, + `not make sense` ); return caps; }, From cb9948bbaed3f417edf9518c2ba6c100e5737e5b Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Mon, 8 Jan 2024 13:57:27 -0800 Subject: [PATCH 3/7] Update android.ts --- lib/helpers/android.ts | 66 +++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 36 deletions(-) diff --git a/lib/helpers/android.ts b/lib/helpers/android.ts index 5988a2f9..5e9ca84f 100644 --- a/lib/helpers/android.ts +++ b/lib/helpers/android.ts @@ -809,48 +809,43 @@ const AndroidHelpers: AndroidHelpers = { // Reinstall would stop the settings helper process anyway, so // there is no need to continue if the application is still running - if (await adb.processExists(SETTINGS_HELPER_PKG_ID)) { + if (await adb.hasRunningSettingsAppForegroundService()) { logger.debug( `${SETTINGS_HELPER_PKG_ID} is already running. ` + `There is no need to reset its permissions.` ); - } else { - const apiLevel = await adb.getApiLevel(); - if (apiLevel >= 29) { - // https://github.com/appium/io.appium.settings#internal-audio--video-recording - try { - await adb.shell(['appops', 'set', SETTINGS_HELPER_PKG_ID, 'PROJECT_MEDIA', 'allow']); - } catch (err) { - logger.debug((err as Error).message); - } - try { - await adb.shell([ - 'cmd', - 'notification', - 'allow_listener', - SETTING_NOTIFICATIONS_LISTENER_SERVICE, - ]); - } catch (err) { - logger.debug((err as Error).message); - } + return; + } + + const apiLevel = await adb.getApiLevel(); + if (apiLevel >= 29) { + // https://github.com/appium/io.appium.settings#internal-audio--video-recording + try { + await adb.shell(['appops', 'set', SETTINGS_HELPER_PKG_ID, 'PROJECT_MEDIA', 'allow']); + } catch (err) { + logger.debug((err as Error).message); } - if (apiLevel <= 23) { - // Android 6- devices should have granted permissions - // https://github.com/appium/appium/pull/11640#issuecomment-438260477 - const perms = ['SET_ANIMATION_SCALE', 'CHANGE_CONFIGURATION', 'ACCESS_FINE_LOCATION']; - logger.info(`Granting permissions ${perms} to '${SETTINGS_HELPER_PKG_ID}'`); - await adb.grantPermissions( - SETTINGS_HELPER_PKG_ID, - perms.map((x) => `android.permission.${x}`) - ); + try { + await adb.shell([ + 'cmd', + 'notification', + 'allow_listener', + SETTING_NOTIFICATIONS_LISTENER_SERVICE, + ]); + } catch (err) { + logger.debug((err as Error).message); } } - - // Some commands by adb such as 'adb shell cmd notification' - // could launch the app process but it was not started via activity. - // It could cause wrong io.appium.settings process launches, - // thus it is safe to start the app process forcefully every session start - // to ensure the settings app process starts. + if (apiLevel <= 23) { + // Android 6- devices should have granted permissions + // https://github.com/appium/appium/pull/11640#issuecomment-438260477 + const perms = ['SET_ANIMATION_SCALE', 'CHANGE_CONFIGURATION', 'ACCESS_FINE_LOCATION']; + logger.info(`Granting permissions ${perms} to '${SETTINGS_HELPER_PKG_ID}'`); + await adb.grantPermissions( + SETTINGS_HELPER_PKG_ID, + perms.map((x) => `android.permission.${x}`) + ); + } // launch io.appium.settings app due to settings failing to be set // if the app is not launched prior to start the session on android 7+ @@ -858,7 +853,6 @@ const AndroidHelpers: AndroidHelpers = { try { await adb.requireRunningSettingsApp({ timeout: AndroidHelpers.isEmulator(adb, opts) ? 30000 : 5000, - forceStartSettingsApp: true, }); } catch (err) { logger.debug(err); From 2ba1787f203e836aee64b39a92eeba82d4c87ba5 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Tue, 9 Jan 2024 11:39:34 -0800 Subject: [PATCH 4/7] chore: bump appium-adb --- lib/helpers/android.ts | 76 +++++++++++++++++++++--------------------- package.json | 2 +- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/lib/helpers/android.ts b/lib/helpers/android.ts index 5e9ca84f..e490beff 100644 --- a/lib/helpers/android.ts +++ b/lib/helpers/android.ts @@ -76,7 +76,7 @@ function ensureNetworkSpeed(adb: ADB, networkSpeed: string) { } logger.warn( `Wrong network speed param '${networkSpeed}', using default: ${adb.NETWORK_SPEED.FULL}. ` + - `Supported values: ${_.values(adb.NETWORK_SPEED)}` + `Supported values: ${_.values(adb.NETWORK_SPEED)}`, ); return adb.NETWORK_SPEED.FULL; } @@ -139,15 +139,15 @@ interface AndroidHelpers { validatePackageActivityNames(opts: Opts): void; getLaunchInfo( adb: ADB, - opts: Opts + opts: Opts, ): Promise; resetApp( adb: ADB, - opts: SetRequired + opts: SetRequired, ): Promise; installApk( adb: ADB, - opts: SetRequired + opts: SetRequired, ): Promise; /** @@ -158,7 +158,7 @@ interface AndroidHelpers { installOtherApks( apks: string[], adb: ADB, - opts: SetRequired + opts: SetRequired, ): Promise; /** @@ -213,12 +213,12 @@ interface AndroidHelpers { pushStrings( language: string | undefined, adb: ADB, - opts: AndroidDriverOpts + opts: AndroidDriverOpts, ): Promise; unlock( driver: D, adb: ADB, - capabilities: Caps + capabilities: Caps, ): Promise; verifyUnlock(adb: ADB, timeoutMs?: number | null): Promise; initDevice(adb: ADB, opts: AndroidDriverOpts): Promise; @@ -228,7 +228,7 @@ interface AndroidHelpers { getChromePkg(browser: string): ValueOf; removeAllSessionWebSocketHandlers( server?: AppiumServer, - sessionId?: string | null + sessionId?: string | null, ): Promise; parseArray(cap: string | string[]): string[]; @@ -447,7 +447,7 @@ const AndroidHelpers: AndroidHelpers = { logger.errorAndThrow( `Unable to find an active device or emulator ` + `with OS ${opts.platformVersion}. The following are available: ` + - availDevices.join(', ') + availDevices.join(', '), ); throw new Error(); // unreachable; for TS } @@ -489,12 +489,12 @@ const AndroidHelpers: AndroidHelpers = { } logger.warn( - `Capability '${key}' is expected to only include latin letters, digits, underscore, dot, comma and asterisk characters.` + `Capability '${key}' is expected to only include latin letters, digits, underscore, dot, comma and asterisk characters.`, ); logger.warn( `Current value '${name}' has non-matching character at index ${match.index}: '${String( - name - ).substring(0, match.index + 1)}'` + name, + ).substring(0, match.index + 1)}'`, ); } }, @@ -557,7 +557,7 @@ const AndroidHelpers: AndroidHelpers = { const output = await adb.clear(appPackage); if (_.isString(output) && output.toLowerCase().includes('failed')) { throw new Error( - `Cannot clear the application data of '${appPackage}'. Original error: ${output}` + `Cannot clear the application data of '${appPackage}'. Original error: ${output}`, ); } // executing `shell pm clear` resets previously assigned application permissions as well @@ -566,12 +566,12 @@ const AndroidHelpers: AndroidHelpers = { await adb.grantAllPermissions(appPackage); } catch (error) { logger.error( - `Unable to grant permissions requested. Original error: ${(error as Error).message}` + `Unable to grant permissions requested. Original error: ${(error as Error).message}`, ); } } logger.debug( - `Performed fast reset on the installed '${appPackage}' application (stop and clear)` + `Performed fast reset on the installed '${appPackage}' application (stop and clear)`, ); return; } @@ -580,7 +580,7 @@ const AndroidHelpers: AndroidHelpers = { if (!app) { throw new Error( `Either provide 'app' option to install '${appPackage}' or ` + - `consider setting 'noReset' to 'true' if '${appPackage}' is supposed to be preinstalled.` + `consider setting 'noReset' to 'true' if '${appPackage}' is supposed to be preinstalled.`, ); } @@ -648,7 +648,7 @@ const AndroidHelpers: AndroidHelpers = { timeout: androidInstallTimeout, allowTestPackages, }); - }) + }), ); }, @@ -673,7 +673,7 @@ const AndroidHelpers: AndroidHelpers = { return _.difference(appPackagesArray, filterPackages); } catch (err) { logger.warn( - `Unable to get packages with 'adb shell pm list packages -3': ${(err as Error).message}` + `Unable to get packages with 'adb shell pm list packages -3': ${(err as Error).message}`, ); return []; } @@ -769,8 +769,8 @@ const AndroidHelpers: AndroidHelpers = { try { await adb.shell(['appops', 'set', pkgId, 'android:mock_location', 'deny']); } catch (ign) {} - })() - ) + })(), + ), ); } catch (err) { logger.warn(`Unable to reset mock location: ${(err as Error).message}`); @@ -785,7 +785,7 @@ const AndroidHelpers: AndroidHelpers = { HELPER_APP_INSTALL_RETRY_DELAY_MS, async function retryInstallHelperApp() { await adb.installOrUpgrade(apkPath, packageId, {grantPermissions: true}); - } + }, ); }, @@ -803,16 +803,16 @@ const AndroidHelpers: AndroidHelpers = { `Ignored error while installing '${settingsApkPath}': ` + `'${(err as Error).message}'. Features that rely on this helper ` + 'require the apk such as toggle WiFi and getting location ' + - 'will raise an error if you try to use them.' + 'will raise an error if you try to use them.', ); } // Reinstall would stop the settings helper process anyway, so // there is no need to continue if the application is still running - if (await adb.hasRunningSettingsAppForegroundService()) { + if (await adb.isSettingsAppServiceRunningInForeground()) { logger.debug( `${SETTINGS_HELPER_PKG_ID} is already running. ` + - `There is no need to reset its permissions.` + `There is no need to reset its permissions.`, ); return; } @@ -843,7 +843,7 @@ const AndroidHelpers: AndroidHelpers = { logger.info(`Granting permissions ${perms} to '${SETTINGS_HELPER_PKG_ID}'`); await adb.grantPermissions( SETTINGS_HELPER_PKG_ID, - perms.map((x) => `android.permission.${x}`) + perms.map((x) => `android.permission.${x}`), ); } @@ -877,7 +877,7 @@ const AndroidHelpers: AndroidHelpers = { logger.info( `Failed to pull an apk from '${opts.appPackage}' to '${opts.tmpDir}'. Original error: ${ (err as Error).message - }` + }`, ); } @@ -892,13 +892,13 @@ const AndroidHelpers: AndroidHelpers = { const {apkStrings, localPath} = await adb.extractStringsFromApk( app!, language ?? null, - stringsTmpDir + stringsTmpDir, ); await adb.push(localPath, remoteDir); return apkStrings; } catch (err) { logger.warn( - `Could not get strings, continuing anyway. Original error: ${(err as Error).message}` + `Could not get strings, continuing anyway. Original error: ${(err as Error).message}`, ); await adb.shell(['echo', `'{}' > ${remoteFile}`]); } finally { @@ -917,7 +917,7 @@ const AndroidHelpers: AndroidHelpers = { if (!capabilities.unlockType && !capabilities.unlockKey) { logger.info( `Neither 'unlockType' nor 'unlockKey' capability is provided. ` + - `Assuming the device is locked with a simple lock screen.` + `Assuming the device is locked with a simple lock screen.`, ); await adb.dismissKeyguard(); return; @@ -996,7 +996,7 @@ const AndroidHelpers: AndroidHelpers = { unicodeKeyboard || hideKeyboard || disableWindowAnimation || - !skipUnlock + !skipUnlock, ); await AndroidHelpers.pushSettingsApp(adb, shouldThrowError, opts); } @@ -1031,7 +1031,7 @@ const AndroidHelpers: AndroidHelpers = { if (unicodeKeyboard) { logger.warn( `The 'unicodeKeyboard' capability has been deprecated and will be removed. ` + - `Set the 'hideKeyboard' capability to 'true' in order to make the on-screen keyboard invisible.` + `Set the 'hideKeyboard' capability to 'true' in order to make the on-screen keyboard invisible.`, ); return await AndroidHelpers.initUnicodeKeyboard(adb); } @@ -1096,12 +1096,12 @@ const AndroidHelpers: AndroidHelpers = { if (caps.app) { // warn if the capabilities have both `app` and `browser, although this is common with selenium grid logger.warn( - `The desired capabilities should generally not include both an 'app' and a 'browserName'` + `The desired capabilities should generally not include both an 'app' and a 'browserName'`, ); } if (caps.appPackage) { logger.errorAndThrow( - `The desired should not include both of an 'appPackage' and a 'browserName'` + `The desired should not include both of an 'appPackage' and a 'browserName'`, ); } } @@ -1111,7 +1111,7 @@ const AndroidHelpers: AndroidHelpers = { AndroidHelpers.parseArray(caps.uninstallOtherPackages); } catch (e) { logger.errorAndThrow( - `Could not parse "uninstallOtherPackages" capability: ${(e as Error).message}` + `Could not parse "uninstallOtherPackages" capability: ${(e as Error).message}`, ); } } @@ -1123,12 +1123,12 @@ const AndroidHelpers: AndroidHelpers = { const {browserName} = caps; logger.info(`The current session is considered browser-based`); logger.info( - `Supported browser names: ${JSON.stringify(_.keys(CHROME_BROWSER_PACKAGE_ACTIVITY))}` + `Supported browser names: ${JSON.stringify(_.keys(CHROME_BROWSER_PACKAGE_ACTIVITY))}`, ); if (caps.appPackage || caps.appActivity) { logger.info( `Not overriding appPackage/appActivity capability values for '${browserName}' ` + - 'because some of them have been already provided' + 'because some of them have been already provided', ); return caps; } @@ -1138,12 +1138,12 @@ const AndroidHelpers: AndroidHelpers = { caps.appActivity = activity; logger.info( `appPackage/appActivity capabilities have been automatically set to ${pkg}/${activity} ` + - `for '${browserName}'` + `for '${browserName}'`, ); logger.info( `Consider changing the browserName to the one from the list of supported browser names ` + `or provide custom appPackage/appActivity capability values if the automatically assigned ones do ` + - `not make sense` + `not make sense`, ); return caps; }, diff --git a/package.json b/package.json index 17c76d5e..ca27fd1b 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "dependencies": { "@appium/support": "^4.2.0", "@colors/colors": "^1.6.0", - "appium-adb": "^11.0.1", + "appium-adb": "^11.1.0", "appium-chromedriver": "^5.5.1", "asyncbox": "^3.0.0", "axios": "^1.x", From ba81f874eec8bb08f8501a2bb544bf83c8b5ce03 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Tue, 9 Jan 2024 11:41:16 -0800 Subject: [PATCH 5/7] fix: revert lint fixes to reduce diff --- lib/helpers/android.ts | 74 +++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/lib/helpers/android.ts b/lib/helpers/android.ts index e490beff..28572390 100644 --- a/lib/helpers/android.ts +++ b/lib/helpers/android.ts @@ -76,7 +76,7 @@ function ensureNetworkSpeed(adb: ADB, networkSpeed: string) { } logger.warn( `Wrong network speed param '${networkSpeed}', using default: ${adb.NETWORK_SPEED.FULL}. ` + - `Supported values: ${_.values(adb.NETWORK_SPEED)}`, + `Supported values: ${_.values(adb.NETWORK_SPEED)}` ); return adb.NETWORK_SPEED.FULL; } @@ -139,15 +139,15 @@ interface AndroidHelpers { validatePackageActivityNames(opts: Opts): void; getLaunchInfo( adb: ADB, - opts: Opts, + opts: Opts ): Promise; resetApp( adb: ADB, - opts: SetRequired, + opts: SetRequired ): Promise; installApk( adb: ADB, - opts: SetRequired, + opts: SetRequired ): Promise; /** @@ -158,7 +158,7 @@ interface AndroidHelpers { installOtherApks( apks: string[], adb: ADB, - opts: SetRequired, + opts: SetRequired ): Promise; /** @@ -213,12 +213,12 @@ interface AndroidHelpers { pushStrings( language: string | undefined, adb: ADB, - opts: AndroidDriverOpts, + opts: AndroidDriverOpts ): Promise; unlock( driver: D, adb: ADB, - capabilities: Caps, + capabilities: Caps ): Promise; verifyUnlock(adb: ADB, timeoutMs?: number | null): Promise; initDevice(adb: ADB, opts: AndroidDriverOpts): Promise; @@ -228,7 +228,7 @@ interface AndroidHelpers { getChromePkg(browser: string): ValueOf; removeAllSessionWebSocketHandlers( server?: AppiumServer, - sessionId?: string | null, + sessionId?: string | null ): Promise; parseArray(cap: string | string[]): string[]; @@ -447,7 +447,7 @@ const AndroidHelpers: AndroidHelpers = { logger.errorAndThrow( `Unable to find an active device or emulator ` + `with OS ${opts.platformVersion}. The following are available: ` + - availDevices.join(', '), + availDevices.join(', ') ); throw new Error(); // unreachable; for TS } @@ -489,12 +489,12 @@ const AndroidHelpers: AndroidHelpers = { } logger.warn( - `Capability '${key}' is expected to only include latin letters, digits, underscore, dot, comma and asterisk characters.`, + `Capability '${key}' is expected to only include latin letters, digits, underscore, dot, comma and asterisk characters.` ); logger.warn( `Current value '${name}' has non-matching character at index ${match.index}: '${String( - name, - ).substring(0, match.index + 1)}'`, + name + ).substring(0, match.index + 1)}'` ); } }, @@ -557,7 +557,7 @@ const AndroidHelpers: AndroidHelpers = { const output = await adb.clear(appPackage); if (_.isString(output) && output.toLowerCase().includes('failed')) { throw new Error( - `Cannot clear the application data of '${appPackage}'. Original error: ${output}`, + `Cannot clear the application data of '${appPackage}'. Original error: ${output}` ); } // executing `shell pm clear` resets previously assigned application permissions as well @@ -566,12 +566,12 @@ const AndroidHelpers: AndroidHelpers = { await adb.grantAllPermissions(appPackage); } catch (error) { logger.error( - `Unable to grant permissions requested. Original error: ${(error as Error).message}`, + `Unable to grant permissions requested. Original error: ${(error as Error).message}` ); } } logger.debug( - `Performed fast reset on the installed '${appPackage}' application (stop and clear)`, + `Performed fast reset on the installed '${appPackage}' application (stop and clear)` ); return; } @@ -580,7 +580,7 @@ const AndroidHelpers: AndroidHelpers = { if (!app) { throw new Error( `Either provide 'app' option to install '${appPackage}' or ` + - `consider setting 'noReset' to 'true' if '${appPackage}' is supposed to be preinstalled.`, + `consider setting 'noReset' to 'true' if '${appPackage}' is supposed to be preinstalled.` ); } @@ -648,7 +648,7 @@ const AndroidHelpers: AndroidHelpers = { timeout: androidInstallTimeout, allowTestPackages, }); - }), + }) ); }, @@ -673,7 +673,7 @@ const AndroidHelpers: AndroidHelpers = { return _.difference(appPackagesArray, filterPackages); } catch (err) { logger.warn( - `Unable to get packages with 'adb shell pm list packages -3': ${(err as Error).message}`, + `Unable to get packages with 'adb shell pm list packages -3': ${(err as Error).message}` ); return []; } @@ -769,8 +769,8 @@ const AndroidHelpers: AndroidHelpers = { try { await adb.shell(['appops', 'set', pkgId, 'android:mock_location', 'deny']); } catch (ign) {} - })(), - ), + })() + ) ); } catch (err) { logger.warn(`Unable to reset mock location: ${(err as Error).message}`); @@ -785,7 +785,7 @@ const AndroidHelpers: AndroidHelpers = { HELPER_APP_INSTALL_RETRY_DELAY_MS, async function retryInstallHelperApp() { await adb.installOrUpgrade(apkPath, packageId, {grantPermissions: true}); - }, + } ); }, @@ -803,7 +803,7 @@ const AndroidHelpers: AndroidHelpers = { `Ignored error while installing '${settingsApkPath}': ` + `'${(err as Error).message}'. Features that rely on this helper ` + 'require the apk such as toggle WiFi and getting location ' + - 'will raise an error if you try to use them.', + 'will raise an error if you try to use them.' ); } @@ -812,7 +812,7 @@ const AndroidHelpers: AndroidHelpers = { if (await adb.isSettingsAppServiceRunningInForeground()) { logger.debug( `${SETTINGS_HELPER_PKG_ID} is already running. ` + - `There is no need to reset its permissions.`, + `There is no need to reset its permissions.` ); return; } @@ -843,7 +843,7 @@ const AndroidHelpers: AndroidHelpers = { logger.info(`Granting permissions ${perms} to '${SETTINGS_HELPER_PKG_ID}'`); await adb.grantPermissions( SETTINGS_HELPER_PKG_ID, - perms.map((x) => `android.permission.${x}`), + perms.map((x) => `android.permission.${x}`) ); } @@ -877,7 +877,7 @@ const AndroidHelpers: AndroidHelpers = { logger.info( `Failed to pull an apk from '${opts.appPackage}' to '${opts.tmpDir}'. Original error: ${ (err as Error).message - }`, + }` ); } @@ -892,13 +892,13 @@ const AndroidHelpers: AndroidHelpers = { const {apkStrings, localPath} = await adb.extractStringsFromApk( app!, language ?? null, - stringsTmpDir, + stringsTmpDir ); await adb.push(localPath, remoteDir); return apkStrings; } catch (err) { logger.warn( - `Could not get strings, continuing anyway. Original error: ${(err as Error).message}`, + `Could not get strings, continuing anyway. Original error: ${(err as Error).message}` ); await adb.shell(['echo', `'{}' > ${remoteFile}`]); } finally { @@ -917,7 +917,7 @@ const AndroidHelpers: AndroidHelpers = { if (!capabilities.unlockType && !capabilities.unlockKey) { logger.info( `Neither 'unlockType' nor 'unlockKey' capability is provided. ` + - `Assuming the device is locked with a simple lock screen.`, + `Assuming the device is locked with a simple lock screen.` ); await adb.dismissKeyguard(); return; @@ -996,7 +996,7 @@ const AndroidHelpers: AndroidHelpers = { unicodeKeyboard || hideKeyboard || disableWindowAnimation || - !skipUnlock, + !skipUnlock ); await AndroidHelpers.pushSettingsApp(adb, shouldThrowError, opts); } @@ -1031,7 +1031,7 @@ const AndroidHelpers: AndroidHelpers = { if (unicodeKeyboard) { logger.warn( `The 'unicodeKeyboard' capability has been deprecated and will be removed. ` + - `Set the 'hideKeyboard' capability to 'true' in order to make the on-screen keyboard invisible.`, + `Set the 'hideKeyboard' capability to 'true' in order to make the on-screen keyboard invisible.` ); return await AndroidHelpers.initUnicodeKeyboard(adb); } @@ -1096,12 +1096,12 @@ const AndroidHelpers: AndroidHelpers = { if (caps.app) { // warn if the capabilities have both `app` and `browser, although this is common with selenium grid logger.warn( - `The desired capabilities should generally not include both an 'app' and a 'browserName'`, + `The desired capabilities should generally not include both an 'app' and a 'browserName'` ); } if (caps.appPackage) { logger.errorAndThrow( - `The desired should not include both of an 'appPackage' and a 'browserName'`, + `The desired should not include both of an 'appPackage' and a 'browserName'` ); } } @@ -1111,7 +1111,7 @@ const AndroidHelpers: AndroidHelpers = { AndroidHelpers.parseArray(caps.uninstallOtherPackages); } catch (e) { logger.errorAndThrow( - `Could not parse "uninstallOtherPackages" capability: ${(e as Error).message}`, + `Could not parse "uninstallOtherPackages" capability: ${(e as Error).message}` ); } } @@ -1123,12 +1123,12 @@ const AndroidHelpers: AndroidHelpers = { const {browserName} = caps; logger.info(`The current session is considered browser-based`); logger.info( - `Supported browser names: ${JSON.stringify(_.keys(CHROME_BROWSER_PACKAGE_ACTIVITY))}`, + `Supported browser names: ${JSON.stringify(_.keys(CHROME_BROWSER_PACKAGE_ACTIVITY))}` ); if (caps.appPackage || caps.appActivity) { logger.info( `Not overriding appPackage/appActivity capability values for '${browserName}' ` + - 'because some of them have been already provided', + 'because some of them have been already provided' ); return caps; } @@ -1138,12 +1138,12 @@ const AndroidHelpers: AndroidHelpers = { caps.appActivity = activity; logger.info( `appPackage/appActivity capabilities have been automatically set to ${pkg}/${activity} ` + - `for '${browserName}'`, + `for '${browserName}'` ); logger.info( `Consider changing the browserName to the one from the list of supported browser names ` + `or provide custom appPackage/appActivity capability values if the automatically assigned ones do ` + - `not make sense`, + `not make sense` ); return caps; }, From 983caf27e6986805ab442a993c8664e45ea59a15 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Tue, 9 Jan 2024 11:57:43 -0800 Subject: [PATCH 6/7] test: update test --- test/unit/android-helper-specs.js | 39 ++++++++++++++----------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/test/unit/android-helper-specs.js b/test/unit/android-helper-specs.js index 9ae1290d..1e77f0db 100644 --- a/test/unit/android-helper-specs.js +++ b/test/unit/android-helper-specs.js @@ -118,7 +118,7 @@ describe('Android Helpers', function () { it('should fail if avd name is not specified', async function () { await helpers.prepareEmulator(adb, {}).should.eventually.be.rejected; }); - }) + }), ); describe( 'prepareAvdArgs', @@ -143,7 +143,7 @@ describe('Android Helpers', function () { let args = prepareAvdArgs(adb, {isHeadless: true, avdArgs}); args.should.eql(['-no-window']); }); - }) + }), ); describe('ensureNetworkSpeed', function () { it('should return value if network speed is valid', function () { @@ -206,7 +206,7 @@ describe('Android Helpers', function () { .should.be.rejectedWith(Error, `Failed to set language: fr and country: FR`); mocks.adb.verify(); }); - }) + }), ); describe('getDeviceInfoFromCaps', function () { @@ -493,9 +493,9 @@ describe('Android Helpers', function () { }; (await helpers.getLaunchInfo(adb, inOpts)).should.deep.equal(outOpts); mocks.adb.verify(); - } + }, ); - }) + }), ); describe( 'resetApp', @@ -535,7 +535,7 @@ describe('Android Helpers', function () { await helpers.resetApp(adb, {app: localApkPath, appPackage: pkg, fastReset: true}); mocks.adb.verify(); }); - }) + }), ); describe( @@ -590,7 +590,7 @@ describe('Android Helpers', function () { mocks.adb.verify(); mocks.helpers.verify(); }); - }) + }), ); describe( 'installOtherApks', @@ -628,14 +628,14 @@ describe('Android Helpers', function () { await helpers.installOtherApks([fakeApk, otherFakeApk], adb, opts); mocks.adb.verify(); }); - }) + }), ); describe( 'pushSettingsApp', withMocks({adb}, (mocks) => { it('should skip granting permissions if the app is already running on over API level 23+ devices', async function () { mocks.adb.expects('installOrUpgrade').once().returns(true); - mocks.adb.expects('processExists').withExactArgs('io.appium.settings').once().returns(true); + mocks.adb.expects('isSettingsAppServiceRunningInForeground').once().returns(true); mocks.adb.expects('getApiLevel').never(); mocks.adb.expects('grantPermissions').never(); await helpers.pushSettingsApp(adb); @@ -643,7 +643,7 @@ describe('Android Helpers', function () { }); it('should not skip granting permissions if the app is already running on under API level 22 devices', async function () { mocks.adb.expects('installOrUpgrade').once().returns(true); - mocks.adb.expects('processExists').once().returns(true); + mocks.adb.expects('isSettingsAppServiceRunningInForeground').once().returns(true); mocks.adb.expects('getApiLevel').never(); mocks.adb.expects('grantPermissions').never(); await helpers.pushSettingsApp(adb); @@ -651,7 +651,7 @@ describe('Android Helpers', function () { }); it('should launch settings app if it isnt running on over API level 24 devices', async function () { mocks.adb.expects('installOrUpgrade').once().returns(true); - mocks.adb.expects('processExists').once().returns(false); + mocks.adb.expects('isSettingsAppServiceRunningInForeground').once().returns(false); mocks.adb.expects('getApiLevel').once().returns(24); mocks.adb.expects('requireRunningSettingsApp').once(); await helpers.pushSettingsApp(adb); @@ -659,7 +659,7 @@ describe('Android Helpers', function () { }); it('should launch settings app if it isnt running on under API level 23 devices', async function () { mocks.adb.expects('installOrUpgrade').once().returns(true); - mocks.adb.expects('processExists').once().returns(false); + mocks.adb.expects('isSettingsAppServiceRunningInForeground').once().returns(false); mocks.adb.expects('getApiLevel').once().returns(23); mocks.adb .expects('grantPermissions') @@ -674,7 +674,7 @@ describe('Android Helpers', function () { await helpers.pushSettingsApp(adb); mocks.adb.verify(); }); - }) + }), ); describe( 'setMockLocationApp', @@ -701,7 +701,7 @@ describe('Android Helpers', function () { await helpers.setMockLocationApp(adb, 'io.appium.settings'); mocks.adb.verify(); }); - }) + }), ); describe( 'pushStrings', @@ -751,7 +751,7 @@ describe('Android Helpers', function () { mocks.adb.verify(); mocks.fs.verify(); }); - }) + }), ); describe( 'unlock', @@ -848,7 +848,7 @@ describe('Android Helpers', function () { .should.be.rejectedWith('Fingerprint'); mocks.helpers.verify(); }); - }) + }), ); describe( 'initDevice', @@ -910,10 +910,7 @@ describe('Android Helpers', function () { mocks.helpers.expects('pushSettingsApp').once(); mocks.helpers.expects('ensureDeviceLocale').never(); mocks.helpers.expects('setMockLocationApp').once(); - mocks.helpers - .expects('hideKeyboard') - .withExactArgs(adb) - .once(); + mocks.helpers.expects('hideKeyboard').withExactArgs(adb).once(); await helpers.initDevice(adb, opts); mocks.helpers.verify(); mocks.adb.verify(); @@ -969,7 +966,7 @@ describe('Android Helpers', function () { mocks.helpers.verify(); mocks.adb.verify(); }); - }) + }), ); describe('removeNullProperties', function () { it('should ignore null properties', function () { From 2b4a79e5fcd1b4dcaf36cc7031633f22ff7d8103 Mon Sep 17 00:00:00 2001 From: Kazuaki Matsuo Date: Tue, 9 Jan 2024 11:58:00 -0800 Subject: [PATCH 7/7] test: update test --- test/unit/android-helper-specs.js | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/test/unit/android-helper-specs.js b/test/unit/android-helper-specs.js index 1e77f0db..00f79b8f 100644 --- a/test/unit/android-helper-specs.js +++ b/test/unit/android-helper-specs.js @@ -118,7 +118,7 @@ describe('Android Helpers', function () { it('should fail if avd name is not specified', async function () { await helpers.prepareEmulator(adb, {}).should.eventually.be.rejected; }); - }), + }) ); describe( 'prepareAvdArgs', @@ -143,7 +143,7 @@ describe('Android Helpers', function () { let args = prepareAvdArgs(adb, {isHeadless: true, avdArgs}); args.should.eql(['-no-window']); }); - }), + }) ); describe('ensureNetworkSpeed', function () { it('should return value if network speed is valid', function () { @@ -206,7 +206,7 @@ describe('Android Helpers', function () { .should.be.rejectedWith(Error, `Failed to set language: fr and country: FR`); mocks.adb.verify(); }); - }), + }) ); describe('getDeviceInfoFromCaps', function () { @@ -493,9 +493,9 @@ describe('Android Helpers', function () { }; (await helpers.getLaunchInfo(adb, inOpts)).should.deep.equal(outOpts); mocks.adb.verify(); - }, + } ); - }), + }) ); describe( 'resetApp', @@ -535,7 +535,7 @@ describe('Android Helpers', function () { await helpers.resetApp(adb, {app: localApkPath, appPackage: pkg, fastReset: true}); mocks.adb.verify(); }); - }), + }) ); describe( @@ -590,7 +590,7 @@ describe('Android Helpers', function () { mocks.adb.verify(); mocks.helpers.verify(); }); - }), + }) ); describe( 'installOtherApks', @@ -628,7 +628,7 @@ describe('Android Helpers', function () { await helpers.installOtherApks([fakeApk, otherFakeApk], adb, opts); mocks.adb.verify(); }); - }), + }) ); describe( 'pushSettingsApp', @@ -674,7 +674,7 @@ describe('Android Helpers', function () { await helpers.pushSettingsApp(adb); mocks.adb.verify(); }); - }), + }) ); describe( 'setMockLocationApp', @@ -701,7 +701,7 @@ describe('Android Helpers', function () { await helpers.setMockLocationApp(adb, 'io.appium.settings'); mocks.adb.verify(); }); - }), + }) ); describe( 'pushStrings', @@ -751,7 +751,7 @@ describe('Android Helpers', function () { mocks.adb.verify(); mocks.fs.verify(); }); - }), + }) ); describe( 'unlock', @@ -848,7 +848,7 @@ describe('Android Helpers', function () { .should.be.rejectedWith('Fingerprint'); mocks.helpers.verify(); }); - }), + }) ); describe( 'initDevice', @@ -910,7 +910,10 @@ describe('Android Helpers', function () { mocks.helpers.expects('pushSettingsApp').once(); mocks.helpers.expects('ensureDeviceLocale').never(); mocks.helpers.expects('setMockLocationApp').once(); - mocks.helpers.expects('hideKeyboard').withExactArgs(adb).once(); + mocks.helpers + .expects('hideKeyboard') + .withExactArgs(adb) + .once(); await helpers.initDevice(adb, opts); mocks.helpers.verify(); mocks.adb.verify(); @@ -966,7 +969,7 @@ describe('Android Helpers', function () { mocks.helpers.verify(); mocks.adb.verify(); }); - }), + }) ); describe('removeNullProperties', function () { it('should ignore null properties', function () {