From 1833e839ddd17d32372d95745fc8e8078ce94faf Mon Sep 17 00:00:00 2001 From: mwakizaka <21286384+mwakizaka@users.noreply.github.com> Date: Fri, 24 Nov 2023 21:29:17 +0900 Subject: [PATCH] feat: add skipSyncUiTranslation option (#404) --- lib/simulator-xcode-9.js | 4 ++ test/functional/simulator-e2e-specs.js | 4 +- test/unit/simulator-specs.js | 94 ++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 2 deletions(-) diff --git a/lib/simulator-xcode-9.js b/lib/simulator-xcode-9.js index d3dbb7a..042014c 100644 --- a/lib/simulator-xcode-9.js +++ b/lib/simulator-xcode-9.js @@ -498,6 +498,8 @@ class SimulatorXcode9 extends SimulatorXcode8 { /** * @typedef {Object} LanguageOptions * @property {string} name The name of the language, for example `de` or `zh-Hant-CN` + * @property {boolean} [skipSyncUiDialogTranslation] no Simulator services will be reset if this option is set to true. + * See https://github.com/appium/appium/issues/19440 for more details */ /** @@ -600,6 +602,8 @@ class SimulatorXcode9 extends SimulatorXcode8 { `The 'AppleLanguages' preference is already set to '${globalPrefs.AppleLanguages}'. ` + `Skipping services reset` ); + } else if (language?.skipSyncUiDialogTranslation) { + log.info('Skipping services reset as requested. This might leave some system UI alerts untranslated'); } else { log.info( `Will restart the following services in order to sync UI dialogs translation: ` + diff --git a/test/functional/simulator-e2e-specs.js b/test/functional/simulator-e2e-specs.js index a8ca44e..99e08f2 100644 --- a/test/functional/simulator-e2e-specs.js +++ b/test/functional/simulator-e2e-specs.js @@ -278,7 +278,7 @@ describe('advanced features', function () { return this.skip(); } - await sim.configureLocalization({ + (await sim.configureLocalization({ language: { name: 'en' }, @@ -290,7 +290,7 @@ describe('advanced features', function () { name: 'en_US', layout: 'QWERTY', } - }); + })).should.be.true; }); }); diff --git a/test/unit/simulator-specs.js b/test/unit/simulator-specs.js index 7835d4e..9740fed 100644 --- a/test/unit/simulator-specs.js +++ b/test/unit/simulator-specs.js @@ -145,4 +145,98 @@ launchd_s 35621 mwakizaka 16u unix 0x7b7dbedd6d62e84f 0t0 /private/ teenProcess.exec.callCount.should.equal(1); }); }); + + describe('configureLocalization', function () { + let sim; + let spawnProcessSpy; + beforeEach(async function () { + const xcodeVersion = {major: 9, versionString: '9.0.0'}; + xcodeMock.expects('getVersion').atLeast(1).returns(B.resolve(xcodeVersion)); + sim = await getSimulator(UDID); + spawnProcessSpy = sinon.stub(sim.simctl, 'spawnProcess'); + }); + afterEach(function () { + spawnProcessSpy.reset(); + }); + + describe('locale', function () { + it('should configure locale', async function () { + const options = {locale: {name: 'en_US', calendar: 'gregorian'}}; + (await sim.configureLocalization(options)).should.be.true; + spawnProcessSpy.firstCall.args[0].should.eql( + ['defaults', 'write', '.GlobalPreferences.plist', 'AppleLocale', 'en_US@calendar=gregorian'] + ); + spawnProcessSpy.callCount.should.eql(1); + }); + }); + + describe('keyboard', function () { + it('should configure keyboard', async function () { + const options = {keyboard: {name: 'en_US', layout: 'QWERTY'}}; + (await sim.configureLocalization(options)).should.be.true; + spawnProcessSpy.firstCall.args[0].should.eql( + ['defaults', 'write', '.GlobalPreferences.plist', 'AppleKeyboards', 'en_US@sw=QWERTY'] + ); + spawnProcessSpy.secondCall.args[0].should.eql( + ['defaults', 'write', 'com.apple.Preferences', 'KeyboardsCurrentAndNext', 'en_US@sw=QWERTY'] + ); + spawnProcessSpy.thirdCall.args[0].should.eql( + ['defaults', 'write', 'com.apple.Preferences', 'KeyboardLastUsed', 'en_US@sw=QWERTY'] + ); + spawnProcessSpy.getCall(3).args[0].should.eql( + ['defaults', 'write', 'com.apple.Preferences', 'KeyboardLastUsedForLanguage', 'en_USen_US@sw=QWERTY'] + ); + spawnProcessSpy.callCount.should.eql(4); + }); + }); + + describe('language', function () { + let getDirStub; + const stdout = JSON.stringify({AppleLanguages: ['en']}); + beforeEach(function () { + getDirStub = sinon.stub(sim, 'getDir').callsFake(() => ('')); + sinon.stub(teenProcess, 'exec').callsFake(() => ({ stdout })); + }); + afterEach(function () { + getDirStub.reset(); + teenProcess.exec.restore(); + }); + + it('should configure language and restart services', async function () { + const options = {language: {name: 'ja'}}; + (await sim.configureLocalization(options)).should.be.true; + spawnProcessSpy.firstCall.args[0].should.eql( + ['defaults', 'write', '.GlobalPreferences.plist', 'AppleLanguages', 'ja'] + ); + spawnProcessSpy.secondCall.args[0].should.eql( + ['launchctl', 'stop', 'com.apple.SpringBoard'] + ); + spawnProcessSpy.thirdCall.args[0].should.eql( + ['launchctl', 'stop', 'com.apple.locationd'] + ); + spawnProcessSpy.getCall(3).args[0].should.eql( + ['launchctl', 'stop', 'com.apple.tccd'] + ); + spawnProcessSpy.callCount.should.eql(4); + }); + + it('should confirm skip restarting services if already applied', async function () { + const options = {language: {name: 'en'}}; + (await sim.configureLocalization(options)).should.be.true; + spawnProcessSpy.firstCall.args[0].should.eql( + ['defaults', 'write', '.GlobalPreferences.plist', 'AppleLanguages', 'en'] + ); + spawnProcessSpy.callCount.should.eql(1); + }); + + it('should confirm skip restarting services if skipSyncUiDialogTranslation is true', async function () { + const options = {language: {name: 'ja', skipSyncUiDialogTranslation: true}}; + (await sim.configureLocalization(options)).should.be.true; + spawnProcessSpy.firstCall.args[0].should.eql( + ['defaults', 'write', '.GlobalPreferences.plist', 'AppleLanguages', 'ja'] + ); + spawnProcessSpy.callCount.should.eql(1); + }); + }); + }); });