4

I'm trying to localize my UITests to work with other languages (currently using Snapshot to automate screenshots so that's why I need this to work).

My main problem right now is with a Done button in IQKeyboardManager.

In English I have the following code and it works fine:

app.toolbars.buttons["Done"].tap()

to tap the done button after entering text.

In Spanish that button is called "OK". Looks like it's getting that from some default UIKit localized string or something like that.

I tried adding a .strings file in my UITest es.lproj folder and put "UIBarButtonSystemItem.Done" = "OK"; in it.

I also changed it to be:

app.toolbars.buttons[NSLocalizedString("UIBarButtonSystemItem.Done", bundle: Bundle.main, value: "Done", comment: "")].tap()

and that didn't work. Always used "Done".

It always gives the error:

No matches found for "Done" Button.

I also tried:

app.toolbars.buttons[NSLocalizedString("UIBarButtonSystemItem.Done", comment: "")].tap()

and that resulted in an error:

No matches found for "UIBarButtonSystemItem.Done" Button.

So it looks like my .strings file isn't working for my UITests. Any ideas of how to get it working?

Tamás Sengel
  • 55,884
  • 29
  • 169
  • 223
Charlie Fish
  • 18,491
  • 19
  • 86
  • 179
  • If the string file is located in the UI Testing target's bundle then I don't think you can access it using Bundle.main. See https://stackoverflow.com/questions/1879247/why-cant-code-inside-unit-tests-find-bundle-resources or https://stackoverflow.com/questions/33609325/xcode-7-uitests-with-localized-ui – Titouan de Bailleul Jul 07 '17 at 04:20
  • @TitouandeBailleul Ok that seems to be working better. But for some reason it's using my Spanish .strings file now for everything. Even when it's in English. Normally in my main project I use the key to be the English version and the Spanish and other versions are in .strings files. But for some reason it's using the Spanish .strings file even in English. Any ideas? – Charlie Fish Jul 07 '17 at 21:46

2 Answers2

3

I created this small project that supports English and Spanish. The tests can also be run using the two different languages by switching it in the scheme's configuration

enter image description here

This is how the test is build

func testExample() {
    let greeting = localizedString(key: "Greetings.Hello")
    XCTAssert(XCUIApplication().staticTexts[greeting].exists, "Expected \"\(greeting)\" label to exist")
}

It uses the following function to get the translations

func localizedString(key:String) -> String {
    let bundle = Bundle(for: LocalizationUITests.self)
    let deviceLanguage = Locale.preferredLanguages[0]
    let localizationBundle = Bundle(path: bundle.path(forResource: deviceLanguage, ofType: "lproj")!)
    let result = NSLocalizedString(key, bundle:localizationBundle!, comment: "") //
    return result
}

Here's the project that where you can see it work: https://github.com/TitouanVanBelle/LocalizationUITests

Titouan de Bailleul
  • 12,920
  • 11
  • 66
  • 121
  • Just cloned your project. I just converted it to use Fastlane's Snapshot (which is what I'm using). And it looks like it's still failing. That really makes me think it's some type of issue with how Snapshot is setting the localization. – Charlie Fish Jul 10 '17 at 06:16
  • Can you share a fork of this project with snapshot as well as the tests/commands you're trying to run with the expected results? – Titouan de Bailleul Jul 10 '17 at 06:23
  • https://github.com/fishcharlie/LocalizationUITests, when running `fastlane snapshot` after navigating to the project in Terminal the Spanish version fails `XCTAssertTrue failed - Expected "Hello" label to exist`. English works fine. So that makes me think Snapshot's method isn't really changing the language correctly or something. – Charlie Fish Jul 10 '17 at 06:26
  • Also, I'm still running Xcode 8.3.3 so I had to revert the project to that. Since Xcode 9 doesn't support SKError I'm kinda holding off moving to Xcode 9 till that gets fixed. – Charlie Fish Jul 10 '17 at 06:27
  • Any thoughts on this? – Charlie Fish Jul 26 '17 at 05:12
1

Just for the reference and easy lookup:

It is indeed because you cannot access your main bundle from your UITests target.

let testBundle = Bundle(for: type(of: self ))
let lookup = NSLocalizedString("UIBarButtonSystemItem.Done", bundle: testBundle, value: "Done", comment: "")
app.toolbars.buttons[lookup].tap()
NSMutableString
  • 10,493
  • 1
  • 21
  • 27