Skip to content

Commit

Permalink
Uitests/add registration tests (#935)
Browse files Browse the repository at this point in the history
* Add registration test

#SQA-809

* Add pageobject and UI tests for login, logout, register

#SQA-809

* Brunch update

* Autocorrect changes

#SQA-809

* Fix flaky tests

#SQA-809

* Final fix flaky tests

#SQA-809

* Fix email typing

#SQA-809

* Merge DEV into branch and minor fix

#SQA-809

* Clean up

* Revert change WorkspaceSettings.xcsettings

* Revert change .swiftlint.yml

* Revert change lint.sh

Co-authored-by: AKholin <ckub.ckub@gmail.com>
Co-authored-by: Ivan Magda <ivan.magda@stepik.org>
  • Loading branch information
3 people authored Apr 16, 2021
1 parent ba55fe1 commit de3dd89
Show file tree
Hide file tree
Showing 4 changed files with 265 additions and 24 deletions.
2 changes: 1 addition & 1 deletion Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,6 @@ SPEC CHECKSUMS:
VK-ios-sdk: 5bcf00a2014a7323f98db9328b603d4f96635caa
YandexMobileMetrica: bf9b2bceb40811ab29c3d0f660ef13d381d8dd93

PODFILE CHECKSUM: 3a196057dfca021d67e83c7668a0252603a0db46
PODFILE CHECKSUM: 3bb9bc441fd56cfb8f0d5d519ae99d2e89bac500

COCOAPODS: 1.10.1
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>
</plist>
125 changes: 115 additions & 10 deletions StepicUITests/Sources/Common.swift
Original file line number Diff line number Diff line change
@@ -1,18 +1,109 @@
import Foundation
import UIKit
import XCTest

private var currentUserName: String?
var currentUserName = "test"
var currentUserEmail = "test"
let kCurrentUserPassword = "512"

enum Common {
static func userName() -> String {
if let currentUserName = currentUserName {
return currentUserName
@discardableResult
static func registerNewUserIfNeeded() -> Bool {
if currentUserEmail.contains("ios_autotest") {
return false
}
// register new user
return currentUserName ?? "test"
// Register new user
let timestamp = Int64(Date().timeIntervalSince1970)

let app = XCUIApplication()
app.launch()

app.tabBars["Tab Bar"].buttons["Profile"].tap()

if !app.buttons["Sign In"].staticTexts["Sign In"].waitForExistence(timeout: 5) {
XCTFail("No Sign In button in profile tab")
} else {
app.buttons["Sign In"].staticTexts["Sign In"].tap()
app.buttons["Sign Up"].tap()

app.textFields["Name"].tap()
app.textFields["Name"].typeText("ios_autotest_\(timestamp)")

app.textFields["Email"].tap()
sleep(2)
self.pasteTextFieldText(
app: app,
element: app.textFields["Email"],
value: "ios_autotest_\(timestamp)@stepik.org"
)

app.secureTextFields["Password"].tap()
sleep(2)
self.pasteTextFieldText(
app: app,
element: app.secureTextFields["Password"],
value: kCurrentUserPassword
)

app.buttons["Register"].tap()

if self.isUserLoggedIn(app: app) {
currentUserName = "ios_autotest_\(timestamp)"
currentUserEmail = "ios_autotest_\(timestamp)@stepik.org"
} else {
XCTFail("User setup failed")
}
}

self.logOut(app: app)
app.terminate()

return true
}

static func deleteMyApp() {
static func isUserLoggedIn(app: XCUIApplication) -> Bool {
app.tabBars["Tab Bar"].buttons["Profile"].tap()
if app.buttons["Sign In"].staticTexts["Sign In"].waitForExistence(timeout: 10) {
return false
}
return true
}

static func logOut(app: XCUIApplication) {
if app.tabBars["Tab Bar"].buttons["Profile"].waitForExistence(timeout: 10) {
app.tabBars["Tab Bar"].buttons["Profile"].tap()
}

app.navigationBars["Profile"].buttons["settings"].tap()
app.swipeUp()
app.tables.staticTexts["Log Out"].tap()
app.alerts["Log Out"].scrollViews.otherElements.buttons["Log Out"].tap()

if !app.buttons["Sign In"].staticTexts["Sign In"].waitForExistence(timeout: 10) {
XCTFail("Logout failed")
}
}

static func logIn(app: XCUIApplication) {
app.tabBars["Tab Bar"].buttons["Profile"].tap()
app.buttons["Sign In"].staticTexts["Sign In"].tap()
app.buttons["Sign In with e-mail"].tap()

app.textFields["Email"].tap()
app.textFields["Email"].typeText(currentUserEmail)

sleep(5)

app.secureTextFields["Password"].tap()
self.pasteTextFieldText(
app: app,
element: app.secureTextFields["Password"],
value: kCurrentUserPassword
)

app.buttons["Log in"].tap()
}

static func deleteApplication() {
let appName = "Stepik"

// Put the app in the background
Expand All @@ -27,12 +118,26 @@ enum Common {
springboard.collectionViews.buttons["Remove App"].tap()
}

if springboard.alerts["Remove “\(appName)”?"].scrollViews.otherElements.buttons["Delete App"].waitForExistence(timeout: 5) {
if springboard.alerts["Remove “\(appName)”?"]
.scrollViews.otherElements.buttons["Delete App"].waitForExistence(timeout: 5) {
springboard.alerts["Remove “\(appName)”?"].scrollViews.otherElements.buttons["Delete App"].tap()
}

if springboard.alerts["Delete “\(appName)”?"].scrollViews.otherElements.buttons["Delete"].waitForExistence(timeout: 5) {
if springboard.alerts["Delete “\(appName)”?"]
.scrollViews.otherElements.buttons["Delete"].waitForExistence(timeout: 5) {
springboard.alerts["Delete “\(appName)”?"].scrollViews.otherElements.buttons["Delete"].tap()
}
}

static func pasteTextFieldText(app: XCUIApplication, element: XCUIElement, value: String, clearText: Bool = false) {
// Get the password into the pasteboard buffer
UIPasteboard.general.string = value
// Bring up the popup menu on the password field
if clearText {
element.buttons["Clear text"].tap()
}
element.doubleTap()
// Tap the Paste button to input the password
app.menuItems["Paste"].tap()
}
}
160 changes: 148 additions & 12 deletions StepicUITests/Sources/StepicUITests.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import XCTest

/* WARNING!
This tests needs make sure 'Hardware -> Keyboard -> Connect hardware keyboard' is off IN SIMULATOR.
Use "defaults write com.apple.iphonesimulator ConnectHardwareKeyboard -bool false" in CI
*/

class StepicUITests: XCTestCase {
override func setUp() {
super.setUp()
Expand Down Expand Up @@ -32,7 +37,7 @@ class StepicUITests: XCTestCase {
return false
}
// We need clean installation for this test
Common.deleteMyApp()
Common.deleteApplication()

let app = XCUIApplication()
app.launch()
Expand Down Expand Up @@ -62,7 +67,7 @@ class StepicUITests: XCTestCase {
return false
}
// We need clean installation for this test
Common.deleteMyApp()
Common.deleteApplication()

let app = XCUIApplication()
app.launch()
Expand Down Expand Up @@ -95,7 +100,7 @@ class StepicUITests: XCTestCase {
return false
}
// We need clean installation for this test
Common.deleteMyApp()
Common.deleteApplication()

let app = XCUIApplication()
app.launch()
Expand Down Expand Up @@ -124,7 +129,7 @@ class StepicUITests: XCTestCase {
app.terminate()
app.launch()

// Check for language change button abstance
// Check for language change button existence
if app.scrollViews.otherElements.staticTexts["En"].waitForExistence(timeout: 5) {
XCTFail("Language switcher still exists after restart")
}
Expand All @@ -134,21 +139,37 @@ class StepicUITests: XCTestCase {
}

func testUnregisteredUserAllUI() throws {
// Adding Notification alert interruption
self.addUIInterruptionMonitor(withDescription: "“Stepik” Would Like to Send You Notifications") { alert in
let alertButton = alert.buttons["Allow"]
if alertButton.exists {
alertButton.tap()
return true
}
return false
}
// We need clean installation for this test
Common.deleteApplication()
let app = XCUIApplication()
app.launch()
// Closing splash with cross
app.navigationBars["Stepic.OnboardingView"].children(matching: .button).element.tap()

// Check all Catalog sections
let scrollViewsQuery = app.scrollViews
let elementsQuery = scrollViewsQuery.otherElements

app.tabBars["Tab Bar"].buttons["Catalog"].tap()
XCTAssertTrue(
elementsQuery.staticTexts["Editors' choice"].waitForExistence(timeout: 5),
"No Editors choice section"
)
XCTAssertTrue(elementsQuery.staticTexts["Stepik trends"].exists, "No Stepik trends section")

app.swipeUp()
XCTAssertTrue(elementsQuery.staticTexts["Top categories"].exists, "No Top categories section")
XCTAssertTrue(elementsQuery.staticTexts["Best authors"].exists, "No Best authors section")

app.swipeUp()
XCTAssertTrue(elementsQuery.staticTexts["Popular courses"].exists, "No Popular courses section")

Expand Down Expand Up @@ -176,12 +197,127 @@ class StepicUITests: XCTestCase {
app.terminate()
}

// func testLaunchPerformance() throws {
// if #available(macOS 10.15, iOS 13.0, tvOS 13.0, *) {
// // This measures how long it takes to launch your application.
// measure(metrics: [XCTApplicationLaunchMetric()]) {
// XCUIApplication().launch()
// }
// }
// }
func testUserCanRegister() throws {
// Adding Notification alert interruption
self.addUIInterruptionMonitor(withDescription: "“Stepik” Would Like to Send You Notifications") { alert in
let alertButton = alert.buttons["Allow"]
if alertButton.exists {
alertButton.tap()
return true
}
return false
}
// We need clean installation for this test
Common.deleteApplication()
let timestamp = Int64(Date().timeIntervalSince1970)
let app = XCUIApplication()
app.launch()
// Closing splash with cross
app.navigationBars["Stepic.OnboardingView"].children(matching: .button).element.tap()
// Register new user
app.tabBars["Tab Bar"].buttons["Profile"].tap()
if !app.buttons["Sign In"].staticTexts["Sign In"].waitForExistence(timeout: 10) {
XCTFail("No Sign In button in profile tab")
} else {
app.buttons["Sign In"].staticTexts["Sign In"].tap()
app.buttons["Sign Up"].tap()

app.textFields["Name"].tap()
app.textFields["Name"].typeText("ios_autotest_\(timestamp)")

app.textFields["Email"].tap()
sleep(2)
Common.pasteTextFieldText(
app: app,
element: app.textFields["Email"],
value: "ios_autotest_\(timestamp)@stepik.org"
)

app.secureTextFields["Password"].tap()
sleep(2)
Common.pasteTextFieldText(
app: app,
element: app.secureTextFields["Password"],
value: kCurrentUserPassword
)

app.buttons["Register"].tap()
}
// Check user profile loaded
app.tabBars["Tab Bar"].buttons["Profile"].tap()
let elementsQuery = app.scrollViews.otherElements
if elementsQuery.staticTexts["ios_autotest_\(timestamp)"].waitForExistence(timeout: 5) {
XCTAssertTrue(elementsQuery.staticTexts["Activity"].exists, "No Activity section")
XCTAssertTrue(elementsQuery.staticTexts["Achievements"].exists, "No Achievements section")
}
app.terminate()
}

func testUserCanLogIn() throws {
let app = XCUIApplication()
app.launch()

if Common.isUserLoggedIn(app: app) {
Common.logOut(app: app)
}

Common.registerNewUserIfNeeded()

app.launch()
app.tabBars["Tab Bar"].buttons["Profile"].tap()
app.buttons["Sign In"].staticTexts["Sign In"].tap()
app.buttons["Sign In with e-mail"].tap()

app.textFields["Email"].tap()
sleep(2)
Common.pasteTextFieldText(
app: app,
element: app.textFields["Email"],
value: currentUserEmail
)

app.secureTextFields["Password"].tap()
sleep(2)
Common.pasteTextFieldText(
app: app,
element: app.secureTextFields["Password"],
value: kCurrentUserPassword
)

app.buttons["Log in"].tap()
// Check user profile loaded
if app.tabBars["Tab Bar"].buttons["Profile"].waitForExistence(timeout: 5) {
app.tabBars["Tab Bar"].buttons["Profile"].tap()
}

let elementsQuery = app.scrollViews.otherElements

if elementsQuery.staticTexts[currentUserName].waitForExistence(timeout: 5) {
XCTAssertTrue(elementsQuery.staticTexts["Activity"].exists, "No Activity section")
XCTAssertTrue(elementsQuery.staticTexts["Achievements"].exists, "No Achievements section")
} else {
XCTFail("User could not login")
}

app.terminate()
}

func testUserCanLogout() throws {
let app = XCUIApplication()
app.launch()

if !Common.isUserLoggedIn(app: app) {
Common.registerNewUserIfNeeded()
app.launch()
Common.logIn(app: app)
}

Common.logOut(app: app)

if Common.isUserLoggedIn(app: app) {
XCTFail("User was not logged out")
}

app.terminate()
}
}

0 comments on commit de3dd89

Please sign in to comment.