UITest in Xcode 7: How to test keyboard layout (keyboardType) - ios

I am currently exploring the new UITest library in Xcode, and I want to test if the keyboard that pops up upon clicking inside a UITextView has the proper type (in this case it should be .PhonePad).
I don't think this is feasible with the default XCUIElement and XCUIElementAttributes (which are still a bit blurry to me concerning their actual meaning), and I don't really understand how and what I am supposed to extend in order to be able to test this.
Any help would be greatly appreciated ! :)

Below code I am using for testing the Phone number and password validation check.
let app = XCUIApplication()
let tablesQuery = app.tables
tablesQuery.cells.containingType(.StaticText, identifier:"Login Using").buttons["Icon mail"].tap()
tablesQuery.textFields["Phone Number"].tap()
tablesQuery.cells.containingType(.SecureTextField, identifier:"Password").childrenMatchingType(.TextField).element.typeText("ooo")
tablesQuery.staticTexts["Login Using"].swipeUp()
tablesQuery.secureTextFields["Password"].tap()
tablesQuery.cells.containingType(.Button, identifier:"Login").childrenMatchingType(.SecureTextField).element.typeText("eeee")
tablesQuery.buttons["Login"].tap()
app.alerts["Error"].collectionViews.buttons["OK"].pressForDuration(1.1);
I hope this will be useful for you.

Related

why my print result of from one swift file does not appear in xcode debug area

xcode debug area
hi,
i am a new beginner in iOS development. i am trying to learn someone code to build an app.
here is the screenshot of my problem : https://i.stack.imgur.com/4QX5P.png
i am trying to print("helloo") and print("your requestID is : ") but it doesnt appear in my debug area, that code is written in my ViewController.swift file
the debug area just print out the networking result from VenuesTableViewController.swift file (from another swift file)
what went wrong in here ? thanks in advance :)
Based on your code, it's very strange that your printing "helloo" doesn't appear on your debug area since it is declared on the viewDidLoad of your ViewController. Did you really use this ViewController ?
The second print "Your request id..." can or not be print based on your previous guard statements : guard let dictionnarayJSON...guard let meta...guard let requestID. A guard statement allows you to control the flow of your code. If what you test is correct it can continue to proceed your code. If not you put return so the flow of your code is stopped.
So, if one of your 3 guard statements fails, you can't reach your printing statement print(Your requet id...)
I recommend you to see Apple documentation : Control Flow

Localized Strings are always in English in UITests (Snapshot)

I'm pretty new to Fastlane and love the idea of Snapshot, but I got a little problem.
When I'm trying to create a new set of screenshots I'm facing the problem that the UITests don't use the correct localized Strings to fetch the UI elements.
My current state is based on this Stack entries: XCode 7 UITests with localized UI
The localization method:
func localizedString(_ key: String) -> String {
let uiTestBundle = Bundle(for: MyUITests.self)
return NSLocalizedString(key, bundle: uiTestBundle, comment: "")
}
Trying to perform a tap that way:
app.navigationBars[localizedString("key_1")].buttons[localizedString("key_2")].tap()
The error I get is the following:
No matches found for "Rolling stone" NavigationBar
Rolling stone is the Base/English Localization of the key, but there should be a German one. So for any reason the UITest always picks the English Localization.
Does anybody have an idea how to troubleshoot this? I checked the SnapshotHelper and it passes a "de-DE" as the language, so that's not the point.
But I just can't find the Bug :(
Localization
This link here should be sufficient enough to solve your problem. You simple pick the correct language option during the test tab under edit scheme option.

Can not access the programatically added UIView in XCTest

Below is my recorded XCTest
let app = XCUIApplication()
let tablesQuery = app.tables
tablesQuery.staticTexts["Video"].tap()
tablesQuery.staticTexts["\tWindowed"].tap()
app.buttons["Launch"].tap()
app.buttons["Popout Video"].tap()
app.children(matching: .window).element(boundBy: 0).children(matching: .other).element(boundBy: 1).tap()
When I am trying to run the test the last part that is:
app.children(matching: .window).element(boundBy: 0).children(matching: .other).element(boundBy: 1).tap()
is not accessible. It does not throw any error but the last line of code is not executed.
I have tried solving the issue by referring to the following stackoverflow question :
Xcode UI Tests can't find views that are added programatically
Also , I have referred to the following Apple Documentations: https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/iPhoneAccessibility/Making_Application_Accessible/Making_Application_Accessible.html#//apple_ref/doc/uid/TP40008785-CH102-SW2
https://developer.apple.com/reference/uikit/uiview
But all these doesn't seem to solve the issue. Any help will be greatly appreciated.
The line in question is very brittle. It's possible that your app's views are not always available in the same order every time the app launches, depending on race conditions, so what was recorded in your recording session does not necessarily work for all launches of the app. You'll probably find that the code is actually running, but isn't tapping the element you expected.
To make your code less brittle, add an accessibility identifier to the UIView in your app code, and use the otherElements query to find the UIView.
// app code
let view: UIView!
view.accessibilityIdentifier = "myAccessibilityIdentifier"
// UI test code
app.otherElements["myAccessibilityIdentifier"].tap()

How to test right-to-left language in iOS XCTest unit tests?

Is there a way to switch an XCTest unit test into the right-to-left mode to test Arabic version of the app where sentences are written from right to left of the screen? My app code logic behaves differently based on language direction. I would like to verify this functionality in a unit test. What I need to do is to switch the app into the right-to-left language mode from an XCTest unit test case.
One can run the app in the right-to-left mode by changing the Scheme's Application language settings to Right-to-left Pseudolanguage. Is there a way to do similar thing in a unit test?
My imperfect solution
I ended up changing semanticContentAttribute of a view under test to .ForceRightToLeft. It does what I need to do. It does not feel like a very clean approach though. Firstly, it only works in iOS 9. Secondly, it looks like I am tinkering with my app views on a low level from the unit test. Instead, I would prefer to switch the whole app's language to right-to-left if it is possible.
class MyTests: XCTestCase {
func testRightToLeft() {
if #available(iOS 9.0, *) {
let view = UIView()
view.semanticContentAttribute = .ForceRightToLeft
// Test code involving the view
}
}
}
There's no easy way to do this right now with testing/UI testing besides passing in environment flags or setting the semanticContentAttribute as you are doing now. Filing a bug to Apple is highly recommended.
You can also change the device language & region in the scheme. This means you'll need separate schemes for the various LTR/RTL tests you want to run:
Xcode even provides pseudo-languages for extra-long string & RTL testing.
You can detect the writing direction via
let writingDirection = UIApplication.sharedApplication().userInterfaceLayoutDirection
switch writingDirection {
case .LeftToRight:
//
case .RightToLeft:
//
default:
break // what now? You are obviously using iOS 11's topToBottom direction…
}
To set different languages and locales on startup this might be a proper solution.
What you are looking for is Automated UI-Testing
This example JavaScript code changes the device orientation for example:
var target = UIATarget.localTarget();
var app = target.frontMostApp();
//set orientation to landscape left
target.setDeviceOrientation(UIA_DEVICE_ORIENTATION_LANDSCAPELEFT);
UIALogger.logMessage("Current orientation now " + app.interfaceOrientation());
//reset orientation to portrait
target.setDeviceOrientation(UIA_DEVICE_ORIENTATION_PORTRAIT);
UIALogger.logMessage("Current orientation now " + app.interfaceOrientation());
For testing, if your layout has changed to RTL or LTR you could try to access specific UI Elements and check their content against an expected content. So here is another example to check the contents of a TableViewCell from the official docs:
The crux of testing is being able to verify that each test has been performed and that it has either passed or failed. This code example runs the test testName to determine whether a valid element recipe element whose name starts with “Tarte” exists in the recipe table view. First, a local variable is used to specify the cell criteria:
var cell = UIATarget.localTarget().frontMostApp().mainWindow() \
.tableViews()[0].cells().firstWithPredicate("name beginswith 'Tarte'");
Next, the script uses the isValid method to test whether a valid element matching those criteria exists in the recipe table view.
if (cell.isValid()) {
UIALogger.logPass(testName);
} else {
UIALogger.logFail(testName);
}
If a valid cell is found, the code logs a pass message for the testName test; if not, it logs a failure message.
Notice that this test specifies firstWithPredicate and "name
beginsWith 'Tarte'". These criteria yield a reference to the cell for
“Tarte aux Fraises,” which works for the default data already in the
Recipes sample app. If, however, a user adds a recipe for “Tarte aux
Framboises,” this example may or may not give the desired results.
If you want to test a specific scheme:
Executing an Automation Instrument Script in Xcode
After you have created your customized Automation template, you can execute your test script from Xcode by following these steps:
Open your project in Xcode.
From the Scheme pop-up menu (in the workspace window toolbar), select Edit Scheme for a scheme with which you would like to use your script.
Select Profile from the left column of the scheme editing dialog.
Choose your application from the Executable pop-up menu.
Choose your customized Automation Instrument template from the Instrument pop-up menu.
Click OK to approve your changes and dismiss the scheme editor dialog.
Choose Product > Profile.
Instruments launches and executes your test script.

Unable to get UIAutomation iOS UILabel value

I am trying to get the value "HELLO" of the UILabel shown in the iPad simulator.
I have enabled accessibility and have set the label as "Label Access".
But when I call target.logElementTree(), both the name and value are set to "LabelAccess" and as far as the apple docs say, the value field should contain the string that is set (in this case "Hello").
Does anybody know a fix for this?
PS: I am using the latest iOS SDK and Xcode.
Apple Stack Exchange
I think you encountered a UIAutomation bug that exists since forever.
Easiest way to get around this bug is to set the accessibilityValue to your text in code.
Something like this.
NSString *valueString = [NSString stringWithFormat:#"%d", value];
self.label.text = valueString;
self.label.accessibilityValue = valueString;
Helps those people that use Voice Over too ;-)
thanks for the workaround. Doesn't look like this bug has been fixed.
Came across this while writing Appium test for the iOS app. The element found by the driver somehow only contains accessibilityLabel and accessibilityIdentifier but not the actual text that's shown on the screen.
<XCUIElementTypeStaticText type="XCUIElementTypeStaticText" value=<accessibilityLabel> name=<accessibilityIdentifier> label=<accessibilityLabel> .../>
Has someone found if this issue has been logged with apple?
EDIT: Refer to this answer and the comment underneath. https://stackoverflow.com/a/11411803/4725937
Basically need to use [accessibilityValue]: https://developer.apple.com/documentation/uikit/uiaccessibilityelement/1619583-accessibilityvalue for accessible components for the display text to show up as XCUIElementTypeStaticText.value in the page source.
For eg:
someUILabel.accessibiityLabel = "This is used for voice-over"
someUILabel.accessibilityValue = "This is displayed text"

Resources