Skip to content

Commit

Permalink
feat: Add a possibility to set device timezone (#930)
Browse files Browse the repository at this point in the history
  • Loading branch information
mykola-mokhnach authored Apr 9, 2024
1 parent 5523378 commit 4c88cf0
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 14 deletions.
20 changes: 12 additions & 8 deletions lib/commands/device/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
validatePackageActivityNames,
pushSettingsApp,
} from './utils';
import {adjustTimeZone} from '../time';

/**
* @this {AndroidDriver}
Expand Down Expand Up @@ -194,6 +195,7 @@ export async function initDevice() {
skipLogcatCapture,
logcatFormat,
logcatFilterSpecs,
timeZone,
} = this.opts;

if (skipDeviceInitialization) {
Expand Down Expand Up @@ -222,10 +224,9 @@ export async function initDevice() {
}

/** @type {Promise[]} */
const promises = [];

const setupPromises = [];
if (!this.isEmulator()) {
promises.push((async () => {
setupPromises.push((async () => {
if (mockLocationApp || _.isUndefined(mockLocationApp)) {
await setMockLocationApp.bind(this)(mockLocationApp || SETTINGS_HELPER_ID);
} else {
Expand All @@ -234,34 +235,37 @@ export async function initDevice() {
})());
}
if (language && locale) {
promises.push(this.ensureDeviceLocale(language, locale, localeScript));
setupPromises.push(this.ensureDeviceLocale(language, locale, localeScript));
}
if (skipLogcatCapture) {
this.log.info(`'skipLogcatCapture' is set. Skipping starting logcat capture.`);
} else {
promises.push(this.adb.startLogcat({
setupPromises.push(this.adb.startLogcat({
format: logcatFormat,
filterSpecs: logcatFilterSpecs,
}));
}
promises.push((async () => {
setupPromises.push((async () => {
if (hideKeyboard) {
await hideKeyboardCompletely.bind(this)();
} else if (hideKeyboard === false) {
await this.adb.shell(['ime', 'reset']);
}
})());
if (unicodeKeyboard) {
promises.push((async () => {
setupPromises.push((async () => {
this.log.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.`,
);
await initUnicodeKeyboard.bind(this)();
})());
}
if (timeZone) {
setupPromises.push(adjustTimeZone.bind(this)(timeZone));
}

await B.all(promises);
await B.all(setupPromises);
}

/**
Expand Down
28 changes: 25 additions & 3 deletions lib/commands/time.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import moment from 'moment';
import moment from 'moment-timezone';

const MOMENT_FORMAT_ISO8601 = 'YYYY-MM-DDTHH:mm:ssZ';

/**
* @this {import('../driver').AndroidDriver}
* @this {AndroidDriver}
* @param {string} [format=MOMENT_FORMAT_ISO8601]
* @returns {Promise<string>}
*/
Expand All @@ -23,14 +23,36 @@ export async function getDeviceTime(format = MOMENT_FORMAT_ISO8601) {
}

/**
* @this {import('../driver').AndroidDriver}
* @this {AndroidDriver}
* @param {import('./types').DeviceTimeOpts} [opts={}]
* @returns {Promise<string>}
*/
export async function mobileGetDeviceTime(opts = {}) {
return await this.getDeviceTime(opts.format);
}

/**
* @this {AndroidDriver}
* @param {string} zoneName
* @returns {Promise<void>}
*/
export async function adjustTimeZone(zoneName) {
if (!moment.tz.names().includes(zoneName)) {
throw new Error(
`The provided time zone identifier '${zoneName}' is not known. ` +
`Please choose a valid TZ identifier from https://en.wikipedia.org/wiki/List_of_tz_database_time_zones`
);
}
this.log.info(`Setting the device time zone to '${zoneName}'`);
// The magic number '3' depends on the actual ordering of methods in
// the IAlarmManager interface and might be a subject of change between
// different Android API versions.
// See, for example,
// https://cs.android.com/android/platform/superproject/+/master:frameworks/base/apex/jobscheduler/framework/java/android/app/IAlarmManager.aidl;l=1?q=IAlarmManager
await this.adb.shell(['service', 'call', 'alarm', '3', 's16', zoneName]);
}

/**
* @typedef {import('appium-adb').ADB} ADB
* @typedef {import('../driver').AndroidDriver} AndroidDriver
*/
3 changes: 3 additions & 0 deletions lib/constraints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,9 @@ export const ANDROID_DRIVER_CONSTRAINTS = {
appWaitForLaunch: {
isBoolean: true,
},
timeZone: {
isString: true,
},
} as const satisfies Constraints;

export default ANDROID_DRIVER_CONSTRAINTS;
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@
"@types/source-map-support": "^0.5.6",
"@types/teen_process": "^2.0.0",
"@types/ws": "^8.5.4",
"@typescript-eslint/eslint-plugin": "^6.9.0",
"@typescript-eslint/parser": "^6.9.0",
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^7.0.0",
"@xmldom/xmldom": "^0.x",
"android-apidemos": "^4.1.0",
"appium": "^2.0.0-rc.5",
Expand All @@ -111,7 +111,7 @@
"xpath": "^0.x"
},
"peerDependencies": {
"appium": "^2.0.0-beta.40"
"appium": "^2.0.0"
},
"engines": {
"node": ">=14",
Expand Down

0 comments on commit 4c88cf0

Please sign in to comment.