Skip to content

Commit 9206d63

Browse files
madeyeclaude
andcommitted
Add UI tests, fastlane, and screenshot automation
- Add ScreenshotTests for capturing App Store screenshots across tabs - Add fastlane config for uploading metadata and screenshots to ASC - Add screenshot capture script for multiple device simulators - Gitignore review_information (contains personal contact details) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent ae6a309 commit 9206d63

18 files changed

+598
-1
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@ Pods/
3333
*.cer
3434

3535
# Fastlane
36-
fastlane/.env.default
36+
fastlane/.env*
3737
fastlane/report.xml
3838
fastlane/README.md
39+
fastlane/metadata/review_information/
3940

4041
# App Store Connect keys
4142
*.p8
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright (c) 2026 Max Lv <max.c.lv@gmail.com>
2+
//
3+
// Licensed under the MIT License. See LICENSE file in the project root for details.
4+
5+
import XCTest
6+
7+
final class ScreenshotTests: XCTestCase {
8+
9+
private var app: XCUIApplication!
10+
11+
override func setUpWithError() throws {
12+
continueAfterFailure = false
13+
app = XCUIApplication()
14+
app.launch()
15+
}
16+
17+
/// Tap a tab by its label text. Handles both iPhone (bottom tab bar) and iPad (top tab bar) layouts.
18+
private func selectTab(_ label: String) {
19+
// iPhone: standard tab bar at the bottom
20+
let tabButton = app.tabBars.buttons[label]
21+
if tabButton.waitForExistence(timeout: 2) {
22+
tabButton.tap()
23+
return
24+
}
25+
26+
// iPad (iOS 18+): tabs render in a top bar as plain buttons, match by label
27+
let predicate = NSPredicate(format: "label == %@", label)
28+
let button = app.buttons.matching(predicate).firstMatch
29+
if button.waitForExistence(timeout: 3) {
30+
button.tap()
31+
return
32+
}
33+
34+
XCTFail("Tab '\(label)' not found in tab bar or top bar")
35+
}
36+
37+
func testCaptureScreenshots() throws {
38+
let tabs: [(name: String, label: String)] = [
39+
("01_Home", "Home"),
40+
("02_Config", "Config"),
41+
("03_Data", "Data"),
42+
("04_Settings", "Settings"),
43+
]
44+
45+
for tab in tabs {
46+
selectTab(tab.label)
47+
48+
// Allow UI to settle
49+
Thread.sleep(forTimeInterval: 1)
50+
51+
let screenshot = app.windows.firstMatch.screenshot()
52+
let attachment = XCTAttachment(screenshot: screenshot)
53+
attachment.name = tab.name
54+
attachment.lifetime = .keepAlways
55+
add(attachment)
56+
}
57+
}
58+
}

Gemfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
source "https://rubygems.org"
2+
3+
gem "fastlane"

0 commit comments

Comments
 (0)