Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Localization UI Tests #1051

Merged

Conversation

aa-stripe
Copy link
Contributor

Summary

Create a UI test that visits all the screens in the UI Examples app, and takes a screenshot of each one. These screenshots can then be gathered from DerivedData (or saved in a custom location using xcodebuild, to aid with localization QA, or even general QA)
Added a new UI Tests target to the UI Examples scheme.

Motivation

Automate Localization QA, and be able to scale the process as we add more languages.

Testing

Ran the UI tests with Cmd+u with the UI Examples scheme selected
Also ran on the command line with this xcodebuild invocation. This is the invocation that we should use in CI too:
xcodebuild clean test -workspace "Stripe.xcworkspace" -scheme "UI Examples" -configuration "Debug" -sdk "iphonesimulator" -destination "platform=iOS Simulator,name=iPhone 8 Plus,OS=11.2" -resultBundlePath "<result directory here>" -testLanguage "<language>" -testRegion "<region>"

A note for adding this to CI - we should put this in a for loop that goes through all the languages/regions, and then upload all the screenshots as artifacts in the CI run. A rough idea is:

for locale in [("de", "DE"), ("en", "US"), ("fr", "FR"), ... ]:
    language, region = locale
    output_dir = "{}_{}_{}".format(OUTPUT_PATH, language, region)
    run_command('xcodebuild clean test -workspace "Stripe.xcworkspace" -scheme "UI Examples" -configuration "Debug" -sdk "iphonesimulator" -destination "platform=iOS Simulator,name=iPhone 8 Plus,OS=11.2" -resultBundlePath "{}" -testLanguage "{}" -testRegion "{}"'.format(output_dir, language, region))

@csabol-stripe
Copy link
Contributor

note there are known issues running this with 11.2 simulator (see: http://www.openradar.me/39348762 https://openradar.appspot.com/26320475). Running on 11.4 fixed for me

@csabol-stripe
Copy link
Contributor

UI strings not covered by this scheme/script:
STPAddCardViewController:
- "Use shipping"
- "Use delivery"
- "Scan card"
- "OK"
STPPaymentMethodsViewController
- "Loading..."
STPShippingAddressViewController
- "Use Billing"
- "Invalid Shipping Address"
- "OK"
- "Delivery"
- "Contact"
- "Delivery Address"
STPPaymentCardTextField
- "ZIP"
- "Postal"
STPAddressFieldTableViewCell
(all of these except the last two might be actually covered when specififying a different region, I only ran en_US to test)
- "Province"
- "County"
- "State / Province / Region"
- "Postal code"
- "Country"
- "Email"
- "Phone"
STPPaymentMethodTableViewCell
- "%@ Ending In %@" (format string)
STPShippingMethodTableViewCell
- "Free"

@aa-stripe let me know how you would like to proceed. I think our options include adding some additional interactions to the script to hit some of these, creating a new scheme that explicitly hits all of these, add test schemes to Standard/Custom Integration targets to try to hit these, something else?

@aa-stripe
Copy link
Contributor Author

Per offline discussion, @csabol-stripe to take the action of adding the remaining screens/strings not covered by my test to the example app. I will provide any support as necessary.

@aa-stripe aa-stripe removed their assignment Dec 5, 2018
@csabol-stripe
Copy link
Contributor

Adding @danj-stripe as a reviewer. This patch is getting quite large as I'm also incorporating updated translations from QA (since they are based on and need another round trip of screenshots). Once I get the all clear from loc qa I can try to at least separate this out into a strings update patch and ui-testing/screenshot generating patch

Copy link
Contributor

@danj-stripe danj-stripe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couple questions/nits

#statements
IFS=",";
set -- $i;
xcodebuild clean test -workspace "${script_dir}/../Stripe.xcworkspace" -scheme "LocalizationTester" -configuration "Debug" -sdk "iphonesimulator" -destination "platform=iOS Simulator,name=iPhone 6s,OS=11.4" -resultBundlePath "$HOME/Desktop/loc_qa/$1_$2" -testLanguage $1 -testRegion $2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's probably better to keep this inside the repository, instead of putting it on the desktop. Maybe in the build/ directory

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense!

if ([source isKindOfClass:[STPToken class]] && ((STPToken *)source).card != nil) {
[_mockCustomer.mockSources addObject:((STPToken *)source).card];
}
completion(nil);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 of the methods that end up calling completion make sure it's not nil first, but this & selectDefaultCustomerSource don't. Should they?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup, thanks

XCUIApplication *app = [[XCUIApplication alloc] init];
XCUIElementQuery *tablesQuery = app.tables;

#pragma mark -
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding of #pragma mark is that it puts things into the jump bar, and that's the way I've always seen it used. All of these plain separators look strange. IMO you should include some text if you're going to use it (like the comments that you have on the next lines)

screen shot 2019-02-08 at 10 36 06 am

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blegh yeah, I'll add text

}

- (void)_waitForElementToAppear:(XCUIElement *)element {
XCTAssert([element waitForExistenceWithTimeout:5], "An exepected element did not appear on screen: \(element)");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

afaik this only works in swift, but I'm pretty sure the string can be a format string.

Suggested change
XCTAssert([element waitForExistenceWithTimeout:5], "An exepected element did not appear on screen: \(element)");
XCTAssert([element waitForExistenceWithTimeout:5], "An expected element did not appear on screen: %@", element);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copy-pasta :P

[super tearDown];
}

- (void)testExample {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this file be deleted? Or is it going to have some content later?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be deleted. Thanks

@@ -48,6 +48,8 @@ @interface STPAddCardViewController ()<
UITableViewDelegate,
UITableViewDataSource>

@property (nonatomic) BOOL alwaysShowScanCardButton;
@property (nonatomic) BOOL alwaysEnableDoneButton;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My objc is rusty, but do you need these duplicated here if they're declared in the private header?

Maybe the private header needs to be imported?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused about why this is needed as well, but _alwaysShowScanCardButton is not a valid ivar without it. Also matches the pattern of the other properties declared in the private header

@csabol-stripe csabol-stripe removed their assignment Feb 8, 2019
Copy link
Collaborator

@yuki-stripe yuki-stripe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last 3 commits look good!

@stripe-ci stripe-ci assigned aa-stripe and unassigned danj-stripe Mar 19, 2019
@csabol-stripe csabol-stripe merged commit 1c5505f into stripe:master Mar 19, 2019
@csabol-stripe csabol-stripe deleted the aa-stripe/add-localization-tests branch March 19, 2019 17:09
@aa-stripe
Copy link
Contributor Author

@csabol-stripe @danj-stripe @yuki-stripe thank you so much for taking this to the finish line!

yuki-stripe pushed a commit that referenced this pull request May 3, 2022
- Refactors the `containerView` from
  `DocumentScanningView` into
  `CameraPreviewContainerView` so it can be
  shared between document and selfie
- Adds a new `SelfieScanningView` to display a
  camera preview or scanned image
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants