Add screenshot generator

This commit is contained in:
世界
2026-01-08 16:13:20 +08:00
parent 264c4eed81
commit 6b589cb771
57 changed files with 1931 additions and 109 deletions
+58
View File
@@ -0,0 +1,58 @@
import Foundation
import XCTest
private var screenshotsDir: URL!
private func resolveScreenshotsDir() -> URL {
let env = ProcessInfo.processInfo.environment
if let override = env["SCREENSHOTS_DIR"], !override.isEmpty {
return URL(fileURLWithPath: override, isDirectory: true)
}
if let override = env["SNAPSHOT_SCREENSHOTS_PATH"], !override.isEmpty {
return URL(fileURLWithPath: override, isDirectory: true)
}
if let simulatorHostHome = env["SIMULATOR_HOST_HOME"] {
return URL(fileURLWithPath: simulatorHostHome)
.appendingPathComponent("Library/Caches/tools.fastlane/screenshots")
}
return URL(fileURLWithPath: NSHomeDirectory())
.appendingPathComponent("Library/Caches/tools.fastlane/screenshots")
}
@MainActor
func setupSnapshot(_ app: XCUIApplication, waitForAnimations _: Bool = true) {
app.launchArguments += ["-FASTLANE_SNAPSHOT", "YES", "-ui_testing"]
screenshotsDir = resolveScreenshotsDir()
try! FileManager.default.createDirectory(at: screenshotsDir, withIntermediateDirectories: true)
}
@MainActor
func snapshot(_ name: String, waitForLoadingIndicator: Bool = true) {
snapshot(name, timeWaitingForIdle: waitForLoadingIndicator ? 1 : 0)
}
@MainActor
func snapshot(_ name: String, timeWaitingForIdle timeout: TimeInterval) {
if timeout > 0 {
sleep(UInt32(timeout))
}
let simulator = ProcessInfo.processInfo.environment["SIMULATOR_DEVICE_NAME"] ?? "AppleTV"
let screenshot = XCUIScreen.main.screenshot()
let path = screenshotsDir.appendingPathComponent("\(simulator)-\(name).png")
try! screenshot.pngRepresentation.write(to: path)
}
func loadScreenshotLanguage() -> (language: String?, locale: String?) {
let dir = resolveScreenshotsDir()
let language = readScreenshotText(dir.appendingPathComponent("language.txt"))
let locale = readScreenshotText(dir.appendingPathComponent("locale.txt"))
return (language, locale)
}
private func readScreenshotText(_ url: URL) -> String? {
guard let text = try? String(contentsOf: url, encoding: .utf8) else {
return nil
}
let trimmed = text.trimmingCharacters(in: .whitespacesAndNewlines)
return trimmed.isEmpty ? nil : trimmed
}
+72
View File
@@ -0,0 +1,72 @@
import XCTest
@MainActor
final class SnapshotTests: XCTestCase {
let app = XCUIApplication()
override func setUpWithError() throws {
continueAfterFailure = false
app.terminate()
configureLanguage()
if let page = screenshotPage() {
app.launchEnvironment["SCREENSHOT_PAGE"] = page
} else {
app.launchEnvironment["SCREENSHOT_PAGE"] = ""
}
setupSnapshot(app)
app.launch()
}
private func configureLanguage() {
let environment = ProcessInfo.processInfo.environment
var language = environment["SCREENSHOT_LANGUAGE"]?
.trimmingCharacters(in: .whitespacesAndNewlines)
var locale = environment["SCREENSHOT_LOCALE"]?
.trimmingCharacters(in: .whitespacesAndNewlines)
if language == nil || language?.isEmpty == true {
let cached = loadScreenshotLanguage()
language = cached.language
if locale == nil || locale?.isEmpty == true {
locale = cached.locale
}
}
guard let language, !language.isEmpty else {
return
}
app.launchArguments += ["-AppleLanguages", "(\(language))"]
app.launchEnvironment["SCREENSHOT_LANGUAGE"] = language
if let locale, !locale.isEmpty {
app.launchArguments += ["-AppleLocale", locale]
app.launchEnvironment["SCREENSHOT_LOCALE"] = locale
}
}
private func screenshotPage() -> String? {
let testName = name
if testName.contains("test01Dashboard") {
return "dashboard"
}
if testName.contains("test02Logs") {
return "logs"
}
if testName.contains("test03Settings") {
return "settings"
}
return nil
}
func test01Dashboard() throws {
sleep(1)
snapshot("01_Dashboard")
}
func test02Logs() throws {
sleep(1)
snapshot("02_Logs")
}
func test03Settings() throws {
sleep(1)
snapshot("03_Settings")
}
}