Locating element in Xcode UI Test without accessiblity id - swift

Recently I started learning XCode UI Test to write functional automation tests using UI testing feature of Xcode.
I need to read a text value of native app element. I can get the element with the help of text of element but the problem is I can not use the text as it is dynamic it will be changed after some time or next launch of app.
I am familiar with using WebDriver and Appium where I can tackle this with writing parent - child xpath.
Can anyone suggest a solution to this problem? Please post a sample code snippet as well with your solution as I am new to apple technology / swift.
Appreciate your help.

In your app's code, add an accessibility identifier to the element you want to inspect, then use that identifier to find the element in your UI test code.
// app code
let myLabel = UILabel()
myLabel.accessibilityIdentifier = "myDescriptionLabel"
// add other label configuration...
// UI test code
let app = XCUIApplication()
let descriptionLabel = app.staticTexts["myDescriptionLabel"]
let description = descriptionLabel.value as String

Related

What is the standard way to create a checkbox programmatically in Swift 4.0 using Cocoa?

I've been asked to update an existing macOS program, and have been given an Xcode project written in Swift 4.0. The program uses Cocoa to generate the interface programmatically.
I haven't used Swift (or Xcode) before and am unfamiliar with Cocoa, so I'm trying to pick it up as I go, but I was able to add a button to the interface with the following code:
public lazy var phaseInvertButton: NSButton = {
let button = NSButton()
self.addSubview(button)
return button
}()
However, when I tried to add a checkbox using the same code and an additional line,
button.setButtonType(NSSwitchButton), I got an error:
'NSSwitchButton' is unavailable in Swift.
I also tried creating it with
public lazy var phaseInvertButton: NSSwitchButton, but got the same error. According to the Cocoa documentation, NSSwitchButton is a subtype of NSButton, but I can't seem to get it working in Swift.
Can anyone enlighten me as to how I should create a checkbox programmatically in this context?
You can use:
let button = NSButton(checkboxWithTitle:"Title" target:nil action:nil)
If you want to stick with setting the button type of an NSButton, the type you want is .switch:
button.setButtonType(.switch)

Xcode 8: UI Testing, Neither element not any descendant has keyboard focus

I've recently started to use UI testing within Xcode. I was able to record the test and play it back and it worked perfectly fine. I recently changed the accessibility labels for textFields to make the test look cleaner by giving it a better name.
However, now when I record the UI test and play it back again to test it, I get an error "Neither element not any descendant has keyboard focus.". I've attempted to uncheck hardware keyboard as mentioned in other posts, but that doesn't work for me.
//test login with username and empty password
let app = XCUIApplication()
let elementsQuery = app.scrollViews.otherElements
let emailtextfieldElement = elementsQuery.otherElements["emailTextField"]
let passwordtextfieldElement = elementsQuery.otherElements["passwordTextField"]
emailtextfieldElement.tap()
passwordtextfieldElement.tap()
emailtextfieldElement.tap()
app.typeText("wayne#test.com")
passwordtextfieldElement.tap()
app.buttons["Login - signInButton"].tap()
Anybody know the fix for this?
Use typeText on emailtextfieldElement instead of app.
let emailtextfieldElement = elementsQuery.otherElements["emailTextField"]
emailtextfieldElement.tap()
emailtextfieldElement.typeText("wayne#test.com")

Fails a simple test case using KIF

I try to use KIF in swift project. I run test case on iPhone simulator. Probably I did not set up correctly KIF because use it first time. I used this manual
Test fails in this simple code
func testSelectingOrganizerRole() {
tester().tapView(withAccessibilityLabel: "ORGANIZE")
}
with reason:
A button with Accessibility label "ORGANIZE" exists on initial ViewConroller of storyboard.
Why don't you switch to the UI tests framework available since Xcode 7? A quick intro:
UI testing gives you the ability to find and interact with the UI of your app in order to validate the properties and state of the UI elements.
UI testing includes UI recording, which gives you the ability to generate code that exercises your app's UI the same way you do, and which you can expand upon to implement UI tests. This is a great way to quickly get started writing UI tests.
Using this framework, your simple test would look like this:
let app = XCUIApplication()
app.launch()
app["ORGANIZE"].tap()

Programmatically minimize all windows or besides my Cocoa application?

I haven't been able to find anything about this in Swift. Is there a way to programmatically make my application minimize all other windows open in the background, or even just minimize Safari? I basically want my application to run against the desktop, without any clutter in the background. Is there a way to programmatically do this for a Cocoa app? I'm pretty new to swift, so any help would be appreciated.
You can use api on NSWorkspace which allows you to hide all visible app in the background.
You can find more about NSWorkspace here: link
Hides all applications other than the sender. This method must be called from your app’s main thread.
NSWorkspace.shared().hideOtherApplications()
If you only want to hide Safari,
let appPath = NSWorkspace.shared().fullPath(forApplication: "Safari")
let identifier = Bundle.init(path: appPath!)?.bundleIdentifier
if let bundleID = identifier {
let runningApps = NSRunningApplication.runningApplications(withBundleIdentifier:bundleID )
if !runningApps.isEmpty {
runningApps.first?.hide()
}
}

Paste from the clipboard in iOS

So I have 2 apps. One is a sensors app (built with XCode) that records data (text) with hardware wireless sensors. The other is a checklist/reference manual (built with Titaniam Appcelerator). Using custom URL schemes, they can instantiate each other.
What I am trying to do is paste any text data the sensors app copies to the clipboard into a text field in the reference manual app. I have a UIWebview showing html pages (the checklist) with a text box displayed now. To demo the capability, I have to touch the field and select paste. I was thinking that javascript might work, but all my research poo poo's that idea. Any thoughts about how to grab the text that is on the clipboard and display it programmatically in the reference manual app without having to touch the field and select paste?
Should I even be looking at the clipboard or should I be looking into modifying the custom URL scheme to pass data that way instead?
To get the text from the clipboard:
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
NSString *string = pasteboard.string;
if (string) {
// Do something
}
For more funcional communication between apps, take a look at URL Schemes.
So, I figured out a way to pass the data in the url with this tutorial. At the bottom it describes how to pass data after you set up the URL id for each app. Hope this helps someone.
Pasting in Swift
Get the pasteboard string with UIPasteboard.generalPasteboard().string.
The string is optional, so it must be unwrapped before being used.
if let pasteboardString = UIPasteboard.generalPasteboard().string {
// use the string, for example:
myTextView.insertText(pasteboardString)
}
Note
The original question is asking for something more complex than this. However, most people come here based on the question title rather than question content, so that I what I am answering here.