Skip to content

Commit

Permalink
add script param in setDeviceSysLocaleViaSettingApp, setDeviceLanguag…
Browse files Browse the repository at this point in the history
…eCountry and ensureCurrentLocale (#372)

* add script param in setDeviceSysLocaleViaSettingApp

* make e2e test runnable

* define null if arg has no script

* revert default api level and avd name

* use npm run mocha than mocha directly

* add script in setDeviceLanguageCountry

* add script in ensureCurrentLocale

* use a ternary operator

* add a debug log to show current locale is equal to requested one
  • Loading branch information
KazuCocoa authored Nov 5, 2018
1 parent 90a84cc commit 679bc5c
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 19 deletions.
8 changes: 4 additions & 4 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
"use strict";

let gulp = require('gulp'),
boilerplate = require('appium-gulp-plugins').boilerplate.use(gulp);
const gulp = require('gulp');
const boilerplate = require('appium-gulp-plugins').boilerplate.use(gulp);

boilerplate({
build: 'appium-adb',
jscs: false,
e2eTest: { android: true }
e2eTest: { android: true },
eslint: true,
});
16 changes: 13 additions & 3 deletions lib/tools/adb-commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -836,12 +836,22 @@ methods.isAnimationOn = async function () {
*
* @param {string} language - Language. e.g. en, ja
* @param {string} country - Country. e.g. US, JP
* @param {?string} script - Script. e.g. Hans in `zh-Hans-CN`
*/
methods.setDeviceSysLocaleViaSettingApp = async function (language, country) {
await this.shell(['am', 'broadcast', '-a', LOCALE_SETTING_ACTION,
methods.setDeviceSysLocaleViaSettingApp = async function (language, country, script = null) {
const params = [
'am', 'broadcast',
'-a', LOCALE_SETTING_ACTION,
'-n', LOCALE_SETTING_RECEIVER,
'--es', 'lang', language.toLowerCase(),
'--es', 'country', country.toUpperCase()]);
'--es', 'country', country.toUpperCase()
];

if (script) {
params.push('--es', 'script', script);
}

await this.shell(params);
};

/**
Expand Down
21 changes: 15 additions & 6 deletions lib/tools/apk-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -711,10 +711,11 @@ apkUtilsMethods.setDeviceLocale = async function (locale) {
*
* @param {string} language - Language. The language field is case insensitive, but Locale always canonicalizes to lower case.
* @param {string} country - Country. The language field is case insensitive, but Locale always canonicalizes to lower case.
* @param {?string} script - Script. The script field is case insensitive but Locale always canonicalizes to title case.
*
* @return {boolean} If current locale is language and country as arguments, return true.
*/
apkUtilsMethods.ensureCurrentLocale = async function (language, country) {
apkUtilsMethods.ensureCurrentLocale = async function (language, country, script = null) {
const hasLanguage = _.isString(language);
const hasCountry = _.isString(country);

Expand Down Expand Up @@ -750,7 +751,11 @@ apkUtilsMethods.ensureCurrentLocale = async function (language, country) {
}
} else {
const curLocale = (await this.getDeviceLocale()).toLowerCase();
if (`${language}-${country}` === curLocale) {
// zh-hans-cn : zh-cn
const localeCode = script ? `${language}-${script.toLowerCase()}-${country}` : `${language}-${country}`;

if (localeCode === curLocale) {
log.debug(`Requested locale is equal to current locale: '${curLocale}'`);
return true;
}
}
Expand All @@ -772,8 +777,10 @@ apkUtilsMethods.ensureCurrentLocale = async function (language, country) {
* format: [a-zA-Z]{2,8}. e.g. en, ja : https://developer.android.com/reference/java/util/Locale.html
* @param {string} country - Country. The country (region) field is case insensitive, but Locale always canonicalizes to upper case.
* format: [a-zA-Z]{2} | [0-9]{3}. e.g. US, JP : https://developer.android.com/reference/java/util/Locale.html
* @param {?string} script - Script. The script field is case insensitive but Locale always canonicalizes to title case.
* format: [a-zA-Z]{4}. e.g. Hans in zh-Hans-CN : https://developer.android.com/reference/java/util/Locale.html
*/
apkUtilsMethods.setDeviceLanguageCountry = async function (language, country) {
apkUtilsMethods.setDeviceLanguageCountry = async function (language, country, script = null) {
let hasLanguage = language && _.isString(language);
let hasCountry = country && _.isString(country);
if (!hasLanguage && !hasCountry) {
Expand Down Expand Up @@ -823,9 +830,11 @@ apkUtilsMethods.setDeviceLanguageCountry = async function (language, country) {
return;
}

log.debug(`Current locale: '${curLocale}'; requested locale: '${language}-${country}'`);
if (`${language}-${country}`.toLowerCase() !== curLocale.toLowerCase()) {
await this.setDeviceSysLocaleViaSettingApp(language, country);
// zh-Hans-CN : zh-CN
const localeCode = script ? `${language}-${script}-${country}` : `${language}-${country}`;
log.debug(`Current locale: '${curLocale}'; requested locale: '${localeCode}'`);
if (localeCode.toLowerCase() !== curLocale.toLowerCase()) {
await this.setDeviceSysLocaleViaSettingApp(language, country, script);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"watch": "gulp watch",
"build": "gulp transpile",
"mocha": "mocha",
"e2e-test": "gulp e2e-test",
"e2e-test": "gulp transpile && npm run mocha -- -t 600000 --recursive build/test/functional/",
"coverage": "gulp coveralls",
"precommit-msg": "echo 'Pre-commit checks...' && exit 0",
"precommit-test": "REPORTER=dot gulp once",
Expand Down
Binary file modified test/fixtures/selendroid-test-app.apk
Binary file not shown.
9 changes: 9 additions & 0 deletions test/functional/adb-commands-e2e-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ let expect = chai.expect;
const IME = 'com.example.android.softkeyboard/.SoftKeyboard',
defaultIMEs = [
'com.android.inputmethod.latin/.LatinIME',
'com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME',
'io.appium.android.ime/.UnicodeIME',
],
contactManagerPath = path.resolve(rootDir, 'test',
Expand Down Expand Up @@ -105,6 +106,7 @@ describe('adb commands', function () {
it('should get device locale', async function () {
if (parseInt(apiLevel, 10) < 23) return this.skip(); // eslint-disable-line curly

await adb.setDeviceSysLocaleViaSettingApp('en', 'US');
['us', 'en', 'ca_en', 'en-US'].should.contain(await adb.getDeviceLocale());
});
it('should forward the port', async function () {
Expand Down Expand Up @@ -156,10 +158,14 @@ describe('adb commands', function () {
(await adb.isWifiOn()).should.be.false;
});
it('should be able to turn off animation @skip-ci', async function () {
await adb.grantPermission('io.appium.settings', 'android.permission.SET_ANIMATION_SCALE');

await adb.setAnimationState(false);
(await adb.isAnimationOn()).should.be.false;
});
it('should be able to turn on animation @skip-ci', async function () {
await adb.grantPermission('io.appium.settings', 'android.permission.SET_ANIMATION_SCALE');

await adb.setAnimationState(true);
(await adb.isAnimationOn()).should.be.true;
});
Expand All @@ -171,6 +177,9 @@ describe('adb commands', function () {
await adb.setDeviceSysLocaleViaSettingApp('fr', 'fr');
(await adb.getDeviceSysLocale()).should.equal('fr-FR');

await adb.setDeviceSysLocaleViaSettingApp('zh', 'CN', 'Hans');
(await adb.getDeviceSysLocale()).should.equal('zh-Hans-CN');

await adb.setDeviceSysLocaleViaSettingApp('en', 'us');
(await adb.getDeviceSysLocale()).should.equal('en-US');
});
Expand Down
3 changes: 3 additions & 0 deletions test/functional/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ const API_LEVEL_MAP = {
'6': '23',
'7': '24',
'7.1': '25',
'8.0': '26',
'8.1': '27',
'9.0': '28',
};

const avdName = process.env.ANDROID_AVD || 'NEXUS_S_18_X86';
Expand Down
17 changes: 13 additions & 4 deletions test/unit/adb-commands-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -516,13 +516,22 @@ describe('adb commands', withMocks({adb, logcat, teen_process, net}, function (m
});
});
describe('setDeviceSysLocaleViaSettingApp', function () {
const adbArgs = ['am', 'broadcast', '-a', 'io.appium.settings.locale',
'-n', 'io.appium.settings/.receivers.LocaleSettingReceiver',
'--es', 'lang', 'en', '--es', 'country', 'US'];
it('should call shell with locale settings', async function () {
it('should call shell with locale settings without script', async function () {
const adbArgs = ['am', 'broadcast', '-a', 'io.appium.settings.locale',
'-n', 'io.appium.settings/.receivers.LocaleSettingReceiver',
'--es', 'lang', 'en', '--es', 'country', 'US'];

mocks.adb.expects("shell").once().withExactArgs(adbArgs);
await adb.setDeviceSysLocaleViaSettingApp('en', 'US');
});

it('should call shell with locale settings with script', async function () {
const adbArgs = ['am', 'broadcast', '-a', 'io.appium.settings.locale',
'-n', 'io.appium.settings/.receivers.LocaleSettingReceiver',
'--es', 'lang', 'zh', '--es', 'country', 'CN', '--es', 'script', 'Hans'];
mocks.adb.expects("shell").once().withExactArgs(adbArgs);
await adb.setDeviceSysLocaleViaSettingApp('zh', 'CN', 'Hans');
});
});
describe('setGeoLocation', function () {
const location = {
Expand Down
22 changes: 21 additions & 1 deletion test/unit/apk-utils-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,16 @@ describe('Apk-utils', withMocks({adb, fs, teen_process}, function (mocks) {
mocks.adb.expects("getDeviceLocale").withExactArgs().once().returns("");
(await adb.ensureCurrentLocale('en', 'us')).should.be.false;
});
it('should return true when API 23 with script', async function () {
mocks.adb.expects("getApiLevel").withExactArgs().once().returns(23);
mocks.adb.expects("getDeviceLocale").withExactArgs().once().returns("zh-Hans-CN");
(await adb.ensureCurrentLocale('zh', 'CN', 'Hans')).should.be.true;
});
it('should return false when API 23 with script', async function () {
mocks.adb.expects("getApiLevel").withExactArgs().once().returns(23);
mocks.adb.expects("getDeviceLocale").withExactArgs().once().returns("");
(await adb.ensureCurrentLocale('zh', 'CN', 'Hans')).should.be.false;
});
});
describe('setDeviceLocale', function () {
it('should not call setDeviceLanguageCountry because of empty', async function () {
Expand Down Expand Up @@ -758,11 +768,21 @@ describe('Apk-utils', withMocks({adb, fs, teen_process}, function (mocks) {
.once().returns(24);
mocks.adb.expects("getDeviceLocale").withExactArgs()
.once().returns('fr-FR');
mocks.adb.expects("setDeviceSysLocaleViaSettingApp").withExactArgs(language, country)
mocks.adb.expects("setDeviceSysLocaleViaSettingApp").withExactArgs(language, country, null)
.once().returns("");
mocks.adb.expects('reboot').never();
await adb.setDeviceLanguageCountry(language, country);
});
it('should call set locale with script via setting app when API 24+', async function () {
mocks.adb.expects("getApiLevel").withExactArgs()
.once().returns(24);
mocks.adb.expects("getDeviceLocale").withExactArgs()
.once().returns('fr-FR');
mocks.adb.expects("setDeviceSysLocaleViaSettingApp").withExactArgs('zh', 'CN', 'Hans')
.once().returns("");
mocks.adb.expects('reboot').never();
await adb.setDeviceLanguageCountry('zh', 'CN', 'Hans');
});
it('should not set language and country if it does not change when API 24+', async function () {
mocks.adb.expects("getApiLevel").withExactArgs()
.once().returns(24);
Expand Down

0 comments on commit 679bc5c

Please sign in to comment.