From 37f4bc1fc9eb7a1a9a838bf655cc9e15ec30777b Mon Sep 17 00:00:00 2001 From: CMK Date: Wed, 2 Mar 2022 19:44:48 +0800 Subject: [PATCH] feat: add UITests for snapshots --- AppStoreSnapshotTestPlan.xctestplan | 27 ++++ Mastodon.xcodeproj/project.pbxproj | 6 + .../xcschemes/Mastodon - Release.xcscheme | 10 -- .../xcshareddata/xcschemes/Mastodon.xcscheme | 3 + .../xcschemes/xcschememanagement.plist | 13 +- MastodonUITests/MastodonUISnapshotTests.swift | 136 ++++++++++++++++++ 6 files changed, 181 insertions(+), 14 deletions(-) create mode 100644 AppStoreSnapshotTestPlan.xctestplan create mode 100644 MastodonUITests/MastodonUISnapshotTests.swift diff --git a/AppStoreSnapshotTestPlan.xctestplan b/AppStoreSnapshotTestPlan.xctestplan new file mode 100644 index 00000000..ebe40293 --- /dev/null +++ b/AppStoreSnapshotTestPlan.xctestplan @@ -0,0 +1,27 @@ +{ + "configurations" : [ + { + "id" : "E27ADCCD-D2DF-4255-81D1-21CFC3C33254", + "name" : "Configuration 1", + "options" : { + + } + } + ], + "defaultOptions" : { + "testTimeoutsEnabled" : true + }, + "testTargets" : [ + { + "selectedTests" : [ + "MastodonUISnapshotTests\/testSnapshot()" + ], + "target" : { + "containerPath" : "container:Mastodon.xcodeproj", + "identifier" : "DB427DF225BAA00100D1B89D", + "name" : "MastodonUITests" + } + } + ], + "version" : 1 +} diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 689f7de3..ed8a4f2b 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -244,6 +244,7 @@ DB45FB0F25CA87D0005A8AC7 /* AuthenticationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB45FB0E25CA87D0005A8AC7 /* AuthenticationService.swift */; }; DB45FB1D25CA9D23005A8AC7 /* APIService+HomeTimeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB45FB1C25CA9D23005A8AC7 /* APIService+HomeTimeline.swift */; }; DB47229725F9EFAD00DA7F53 /* NSManagedObjectContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB47229625F9EFAD00DA7F53 /* NSManagedObjectContext.swift */; }; + DB47AB6227CF752B00CD73C7 /* MastodonUISnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB47AB6127CF752B00CD73C7 /* MastodonUISnapshotTests.swift */; }; DB482A3F261331E8008AE74C /* UserTimelineViewModel+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB482A3E261331E8008AE74C /* UserTimelineViewModel+State.swift */; }; DB482A4B261340A7008AE74C /* APIService+UserTimeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB482A4A261340A7008AE74C /* APIService+UserTimeline.swift */; }; DB4924E226312AB200E9DB22 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4924E126312AB200E9DB22 /* NotificationService.swift */; }; @@ -969,6 +970,8 @@ DB45FB0E25CA87D0005A8AC7 /* AuthenticationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationService.swift; sourceTree = ""; }; DB45FB1C25CA9D23005A8AC7 /* APIService+HomeTimeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+HomeTimeline.swift"; sourceTree = ""; }; DB47229625F9EFAD00DA7F53 /* NSManagedObjectContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSManagedObjectContext.swift; sourceTree = ""; }; + DB47AB6127CF752B00CD73C7 /* MastodonUISnapshotTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonUISnapshotTests.swift; sourceTree = ""; }; + DB47AB6327CF858400CD73C7 /* AppStoreSnapshotTestPlan.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = AppStoreSnapshotTestPlan.xctestplan; sourceTree = ""; }; DB482A3E261331E8008AE74C /* UserTimelineViewModel+State.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserTimelineViewModel+State.swift"; sourceTree = ""; }; DB482A4A261340A7008AE74C /* APIService+UserTimeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+UserTimeline.swift"; sourceTree = ""; }; DB4924E126312AB200E9DB22 /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = ""; }; @@ -2079,6 +2082,7 @@ children = ( DBF53F5F25C14E88008AAC7B /* Mastodon.xctestplan */, DBF53F6025C14E9D008AAC7B /* MastodonSDK.xctestplan */, + DB47AB6327CF858400CD73C7 /* AppStoreSnapshotTestPlan.xctestplan */, DB3D0FED25BAA42200EAA174 /* MastodonSDK */, DB427DD425BAA00100D1B89D /* Mastodon */, DB427DEB25BAA00100D1B89D /* MastodonTests */, @@ -2145,6 +2149,7 @@ isa = PBXGroup; children = ( DB427DF725BAA00100D1B89D /* MastodonUITests.swift */, + DB47AB6127CF752B00CD73C7 /* MastodonUISnapshotTests.swift */, DB427DF925BAA00100D1B89D /* Info.plist */, ); path = MastodonUITests; @@ -4273,6 +4278,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + DB47AB6227CF752B00CD73C7 /* MastodonUISnapshotTests.swift in Sources */, DB427DF825BAA00100D1B89D /* MastodonUITests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Mastodon.xcodeproj/xcshareddata/xcschemes/Mastodon - Release.xcscheme b/Mastodon.xcodeproj/xcshareddata/xcschemes/Mastodon - Release.xcscheme index 15ecdcbe..d5959cea 100644 --- a/Mastodon.xcodeproj/xcshareddata/xcschemes/Mastodon - Release.xcscheme +++ b/Mastodon.xcodeproj/xcshareddata/xcschemes/Mastodon - Release.xcscheme @@ -48,16 +48,6 @@ ReferencedContainer = "container:Mastodon.xcodeproj"> - - - - + + AppShared.xcscheme_^#shared#^_ orderHint - 29 + 21 CoreDataStack.xcscheme_^#shared#^_ @@ -24,6 +24,11 @@ orderHint 1 + Mastodon - Snapshot.xcscheme_^#shared#^_ + + orderHint + 2 + Mastodon - ar.xcscheme_^#shared#^_ orderHint @@ -97,7 +102,7 @@ MastodonIntent.xcscheme_^#shared#^_ orderHint - 30 + 23 MastodonIntents.xcscheme_^#shared#^_ @@ -112,12 +117,12 @@ NotificationService.xcscheme_^#shared#^_ orderHint - 2 + 3 ShareActionExtension.xcscheme_^#shared#^_ orderHint - 28 + 24 SuppressBuildableAutocreation diff --git a/MastodonUITests/MastodonUISnapshotTests.swift b/MastodonUITests/MastodonUISnapshotTests.swift new file mode 100644 index 00000000..632beb4d --- /dev/null +++ b/MastodonUITests/MastodonUISnapshotTests.swift @@ -0,0 +1,136 @@ +// +// MastodonUISnapshotTests.swift +// MastodonUITests +// +// Created by MainasuK on 2022-3-2. +// + +import XCTest + +extension UInt64 { + static let second: UInt64 = 1_000_000_000 +} + +@MainActor +class MastodonUISnapshotTests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + override class func tearDown() { + super.tearDown() + let app = XCUIApplication() + print(app.debugDescription) + } + +} + +extension MastodonUISnapshotTests { + + func testSmoke() async throws { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + // Any test you write for XCTest can be annotated as throws and async. + // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error. + // Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards. + + + } + +} + +extension MastodonUISnapshotTests { + + func testSnapshot() async throws { + let app = XCUIApplication() + app.launch() + + try await snapshotHome() + try await snapshotSearch() + try await snapshotProfile() + + } + + func snapshotHome() async throws { + let app = XCUIApplication() + app.launch() + + func tapTab() { + XCTAssert(app.tabBars.buttons["Home"].exists) + app.tabBars.buttons["Home"].tap() + } + + tapTab() + try await Task.sleep(nanoseconds: .second * 3) + takeSnapshot(name: "Home - 1") + + tapTab() + try await Task.sleep(nanoseconds: .second * 3) + takeSnapshot(name: "Home - 2") + + tapTab() + try await Task.sleep(nanoseconds: .second * 3) + takeSnapshot(name: "Home - 3") + } + + func snapshotSearch() async throws { + let app = XCUIApplication() + app.launch() + + func tapTab() { + XCTAssert(app.tabBars.buttons["Search"].exists) + app.tabBars.buttons["Search"].tap() + } + + tapTab() + try await Task.sleep(nanoseconds: .second * 3) + takeSnapshot(name: "Search - 1") + + tapTab() + try await Task.sleep(nanoseconds: .second * 3) + takeSnapshot(name: "Search - 2") + + tapTab() + try await Task.sleep(nanoseconds: .second * 3) + takeSnapshot(name: "Search - 3") + } + + func snapshotProfile() async throws { + let app = XCUIApplication() + app.launch() + + // Go to Search tab + XCTAssert(app.tabBars.buttons["Search"].exists) + app.tabBars.buttons["Search"].tap() + + // Tap and search user + let searchField = app.navigationBars.searchFields.firstMatch + XCTAssert(searchField.waitForExistence(timeout: 5)) + searchField.tap() + searchField.typeText("@dentaku@fnordon.de") + + // Tap the cell and display user profile + let cell = app.tables.cells.firstMatch + XCTAssert(cell.waitForExistence(timeout: 5)) + cell.tap() + + try await Task.sleep(nanoseconds: .second * 5) + + takeSnapshot(name: "Profile") + } + +} + +extension MastodonUISnapshotTests { + func takeSnapshot(name: String) { + let snapshot = XCUIScreen.main.screenshot() + let attachment = XCTAttachment(screenshot: snapshot) + attachment.lifetime = .keepAlways + add(attachment) + } +}