Skip to content

Instantly share code, notes, and snippets.

@devashish2203
Last active December 12, 2018 01:59
Show Gist options
  • Save devashish2203/f9dc4b3813d8fa8512e4 to your computer and use it in GitHub Desktop.
Save devashish2203/f9dc4b3813d8fa8512e4 to your computer and use it in GitHub Desktop.
Page Object Model for UITests in Swift
//
// BaseScreen.swift
//
//
// This serves as the Superclass of all other Screens that need to be created.
import Foundation
import XCTest
class BaseScreen {
let app = xcApp
let navTabs = NavigationTabs()
var XCTCRef: XCTestCase
init(xctc: XCTestCase) {
XCTCRef = xctc
}
// MARK: Tap on TabBar Buttons
func tapProfileTabandGoToProfileScreen() -> ProfileScreen {
self.navTabs.tapTab("Profile")
return ProfileScreen(xctc: XCTCRef)
}
func tapHomeTabandGoToHomeScreen() -> HomeScreen {
self.navTabs.tapTab("Home")
return HomeScreen(xctc: XCTCRef)
}
}
//
// BaseTest.swift
//
//
import XCTest
class BaseTest: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
// In UI tests it is usually best to stop immediately when a failure occurs.
continueAfterFailure = false
//Set app to launch with default launch arguments.
xcApp.launchArguments = UIFuncLib.defaultLaunchArguments
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
}
//
// ProfileScreen.swift
//
// Created by Devashish Chandra on 10/8/15.
//
import UIKit
import XCTest
class ProfileScreen: BaseScreen {
//Define actions to be done on the screen below. Most of the methods return an object for the resulting screen
//to allow chaining of methods and make test code readable.
// MARK: Using XCTestCase methods in screens
func verifyUserisLoggedOut() -> ProfileScreen {
let labelPredicate = NSPredicate(format: "label==\"\"")
XCTCRef.expectationForPredicate(labelPredicate, evaluatedWithObject: nameLabel, handler: nil)
XCTCRef.waitForExpectationsWithTimeout(10) { (error) -> Void in
if let _ = error {
let message = "Could not logout User \(nameLabel.label)"
print(message)
} else {
print("User logged out successfully")
}
}
XCTAssertTrue(nameLabel.label.isEmpty, "Could not logout user \(nameLabel.label)")
return self
}
// MARK: Elementary Actions
func tapLoginandGoToLoginChoiceScreen() -> LoginChoiceScreen {
app.scrollViews.otherElements.buttons["LoginButtonProfile"].tap()
return LoginChoiceScreen(xctc: XCTCRef)
}
func tapFeedbackandGoToFeedbackScreen() -> FeedbackScreen {
app.scrollViews.otherElements.buttons["FeedbackButton"].tap()
return FeedbackScreen(xctc: XCTCRef)
}
}
//
// SignupTest.swift
//
//
// Test Classes extending from BaseTest
import XCTest
class SignupTest: BaseTest {
override func setUp() {
super.setUp()
// UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
xcApp.launch()
//Select Profile Tab
HomeScreen(xctc: self).tapProfileTabandGoToProfileScreen()
}
override func tearDown() {
// Select Home Tab
HomeScreen(xctc: self).tapHomeTabandGoToHomeScreen()
//Call Teardown of BaseTest
super.tearDown()
}
func testNewUserSignUp() {
let hUser = dataSource.getUserDetails()
HomeScreen(xctc: self).tapProfileTabandGoToProfileScreen()
.tapLoginandGoToLoginChoiceScreen()
.tapSignUpandGoToSignUpScreen()
.registerNewUser(hUser)
.verifySuccessfulSignUpAlert()
LoginChoiceScreen(xctc: self).tapCloseButtonandGoToProfileScreen()
}
}
@Przemyslaw-Wosko
Copy link

nice idea of chaining methods, but how to you handle exceptions from assertions? those are visible only in page object class which is not acceptable for most of people :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment