chore: update the snapshot documents and UITests
This commit is contained in:
parent
e82b97619e
commit
12349105e7
|
@ -9,12 +9,19 @@
|
|||
}
|
||||
],
|
||||
"defaultOptions" : {
|
||||
"defaultTestExecutionTimeAllowance" : 1800,
|
||||
"testTimeoutsEnabled" : true
|
||||
},
|
||||
"testTargets" : [
|
||||
{
|
||||
"selectedTests" : [
|
||||
"MastodonUISnapshotTests\/testSmoke()"
|
||||
"MastodonUISnapshotTests\/testSmoke()",
|
||||
"MastodonUISnapshotTests\/testSnapshotCompose()",
|
||||
"MastodonUISnapshotTests\/testSnapshotHome()",
|
||||
"MastodonUISnapshotTests\/testSnapshotProfile()",
|
||||
"MastodonUISnapshotTests\/testSnapshotSearch()",
|
||||
"MastodonUISnapshotTests\/testSnapshotServerRules()",
|
||||
"MastodonUISnapshotTests\/testSnapshotThread()"
|
||||
],
|
||||
"target" : {
|
||||
"containerPath" : "container:Mastodon.xcodeproj",
|
||||
|
|
|
@ -8,12 +8,13 @@ The app use the Xcode UITest generate snapshots attachments. Then use the `xcpar
|
|||
# install xcparse from Homebrew
|
||||
brew install chargepoint/xcparse/xcparse
|
||||
```
|
||||
## Take Snapshots
|
||||
We use `xcodebuild` CLI tool to trigger UITest. To change device for snapshot.
|
||||
## How it works
|
||||
We use `xcodebuild` CLI tool to trigger UITest.
|
||||
|
||||
Replace the `name` in `-destinatio` option to change device. For example:
|
||||
Set the `name` in `-destinatio` option to add device for snapshot. For example:
|
||||
`-destination 'platform=iOS Simulator,name=iPad Pro (12.9-inch) (5th generation)' \`
|
||||
|
||||
You can list the avaiable simulator:
|
||||
```zsh
|
||||
# list the destinations
|
||||
xcodebuild \
|
||||
|
@ -22,16 +23,27 @@ xcodebuild \
|
|||
-derivedDataPath '~/Downloads/MastodonBuild/Derived' \
|
||||
-workspace Mastodon.xcworkspace \
|
||||
-scheme 'Mastodon - Snapshot'
|
||||
|
||||
# output
|
||||
Available destinations for the "Mastodon - Snapshot" scheme:
|
||||
{ platform:iOS Simulator, id:7F6D7727-AD49-4B79-B6F5-AEC538925576, OS:15.2, name:iPad (9th generation) }
|
||||
{ platform:iOS Simulator, id:BEB9533C-F786-40E6-8C38-248F6A11FC37, OS:15.2, name:iPad Air (4th generation) }
|
||||
…
|
||||
```
|
||||
|
||||
#### Auto-Login before make snapshots
|
||||
#### Note:
|
||||
Multiple lines for destination will dispatches the parallel snapshot jobs.
|
||||
|
||||
|
||||
## Login before make snapshots
|
||||
This script trigger the `MastodonUITests/MastodonUISnapshotTests/testSignInAccount` test case to sign-in the account. The test case may wait for 2FA code or email code. Please input it if needed. Also, you can skip this and sign-in the test account manually.
|
||||
|
||||
Replace the `<Email>` and `<Password>` for test account.
|
||||
```zsh
|
||||
# build and run test case for auto sign-in
|
||||
TEST_RUNNER_email='<Email>' \
|
||||
TEST_RUNNER_password='<Password>' \
|
||||
TEST_RUNNER_login_domain='<Domain>' \
|
||||
TEST_RUNNER_login_email='<Email>' \
|
||||
TEST_RUNNER_login_password='<Password>' \
|
||||
xcodebuild \
|
||||
test \
|
||||
-derivedDataPath '~/Downloads/MastodonBuild/Derived' \
|
||||
|
@ -48,16 +60,31 @@ TEST_RUNNER_email='<Email>' \
|
|||
Note:
|
||||
UITest may running silent. Open the Simulator.app to make the device display.
|
||||
|
||||
#### Take and extract snapshots
|
||||
## Take and extract snapshots
|
||||
|
||||
### 1. Setup status bar
|
||||
```zsh
|
||||
# boot devices
|
||||
xcrun simctl boot 'iPhone 8 Plus'
|
||||
xcrun simctl boot 'iPhone 13 Pro Max'
|
||||
xcrun simctl boot 'iPad Pro (12.9-inch) (5th generation)'
|
||||
|
||||
# setup magic status bar
|
||||
xcrun simctl status_bar 'iPhone 13 Pro Max' override --time "9:41" --batteryState charged --batteryLevel 100
|
||||
xcrun simctl status_bar 'iPhone 8 Plus' override --time "9:41" --batteryState charged --batteryLevel 100
|
||||
xcrun simctl status_bar 'iPad Pro (12.9-inch) (5th generation)' override --time "9:41" --batteryState charged --batteryLevel 100
|
||||
```
|
||||
|
||||
### 2. Take snapshots
|
||||
The `TEST_RUNNER_` prefix will sets env value into test runner.
|
||||
|
||||
```zsh
|
||||
# take snapshots
|
||||
TEST_RUNNER_domain='<domain.com>' \
|
||||
TEST_RUNNER_username_snapshot='username@domain.com' \
|
||||
TEST_RUNNER_login_domain='<domain.com>' \
|
||||
TEST_RUNNER_login_email='<email>' \
|
||||
TEST_RUNNER_login_password='<email>' \
|
||||
TEST_RUNNER_thread_id='<thread_id>' \
|
||||
TEST_RUNNER_profile_id='<profile_id>' \
|
||||
xcodebuild \
|
||||
test \
|
||||
-derivedDataPath '~/Downloads/MastodonBuild/Derived' \
|
||||
|
@ -67,8 +94,9 @@ TEST_RUNNER_domain='<domain.com>' \
|
|||
-destination 'platform=iOS Simulator,name=iPhone 13 Pro Max' \
|
||||
-destination 'platform=iOS Simulator,name=iPhone 8 Plus' \
|
||||
-destination 'platform=iOS Simulator,name=iPad Pro (12.9-inch) (5th generation)' \
|
||||
-testPlan 'AppStoreSnapshotTestPlan' \
|
||||
-only-testing:MastodonUITests/MastodonUISnapshotTests/testSnapshot
|
||||
-test-iterations 3 \
|
||||
-retry-tests-on-failure \
|
||||
-testPlan 'AppStoreSnapshotTestPlan'
|
||||
|
||||
# output:
|
||||
Test session results, code coverage, and logs:
|
||||
|
@ -77,6 +105,18 @@ Test session results, code coverage, and logs:
|
|||
** TEST SUCCEEDED **
|
||||
```
|
||||
|
||||
#### Note:
|
||||
Add `-only-testing:MastodonUITests/MastodonUISnapshotTests/testSnapshot…` to run specific test case.
|
||||
|
||||
| Task | key | value |
|
||||
| ------------------- | -------------- | ----------------------------------------------------- |
|
||||
| testSignInAccount | login_domain | The server domain for user login |
|
||||
| testSignInAccount | login_email | The user email for login |
|
||||
| testSignInAccount | login_password | The user password for login |
|
||||
| testSnapshotThread | thread_id | The ID for post which used for thread scene snapshot |
|
||||
| testSnapshotProfile | profile_id | The ID for user which used for profile scene snapshot |
|
||||
|
||||
### 3. Extract snapshots
|
||||
Use `xcparse screenshots <path_for_xcresult> <path_for_destination>` extracts snapshots.
|
||||
|
||||
```zsh
|
||||
|
@ -86,4 +126,11 @@ xcparse screenshots '<path_for_xcresult>' ~/Downloads/MastodonBuild/Screenshots/
|
|||
# output
|
||||
100% [============]
|
||||
🎊 Export complete! 🎊
|
||||
|
||||
# group
|
||||
mkdir 'iPhone 8 Plus' 'iPhone 13 Pro Max' 'iPad Pro (12.9-inch) (5th generation)'
|
||||
find . -name "*iPad*" -type file -print0 | xargs -0 -I {} mv {} './iPad Pro (12.9-inch) (5th generation)'
|
||||
find . -name "*iPhone 8*" -type file -print0 | xargs -0 -I {} mv {} './iPhone 8 Plus'
|
||||
find . -name "*iPhone 13*" -type file -print0 | xargs -0 -I {} mv {} './iPhone 13 Pro Max'
|
||||
|
||||
```
|
||||
|
|
|
@ -700,6 +700,8 @@
|
|||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
0655B257371274BEB7EB1C19 /* Pods-Mastodon.release snapshot.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.release snapshot.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.release snapshot.xcconfig"; sourceTree = "<group>"; };
|
||||
0827D1674B2523503E8605F6 /* Pods-Mastodon-MastodonUITests.release snapshot.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-MastodonUITests.release snapshot.xcconfig"; path = "Target Support Files/Pods-Mastodon-MastodonUITests/Pods-Mastodon-MastodonUITests.release snapshot.xcconfig"; sourceTree = "<group>"; };
|
||||
0F1E2D0A2615C39400C38565 /* DoubleTitleLabelNavigationBarTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoubleTitleLabelNavigationBarTitleView.swift; sourceTree = "<group>"; };
|
||||
0F2021FA2613262F000C64BF /* HashtagTimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagTimelineViewController.swift; sourceTree = "<group>"; };
|
||||
0F202200261326E6000C64BF /* HashtagTimelineViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagTimelineViewModel.swift; sourceTree = "<group>"; };
|
||||
|
@ -719,6 +721,7 @@
|
|||
159AC43EFE0A1F95FCB358A4 /* Pods-MastodonIntent.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonIntent.release.xcconfig"; path = "Target Support Files/Pods-MastodonIntent/Pods-MastodonIntent.release.xcconfig"; sourceTree = "<group>"; };
|
||||
164F0EBB267D4FE400249499 /* BoopSound.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = BoopSound.caf; sourceTree = "<group>"; };
|
||||
1D6D967E77A5357E2C6110D9 /* Pods-Mastodon.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.asdk - debug.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.asdk - debug.xcconfig"; sourceTree = "<group>"; };
|
||||
2C12EB4B3699D5D597027962 /* Pods-MastodonIntent.release snapshot.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonIntent.release snapshot.xcconfig"; path = "Target Support Files/Pods-MastodonIntent/Pods-MastodonIntent.release snapshot.xcconfig"; sourceTree = "<group>"; };
|
||||
2D198642261BF09500F0B013 /* SearchResultItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultItem.swift; sourceTree = "<group>"; };
|
||||
2D198648261C0B8500F0B013 /* SearchResultSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultSection.swift; sourceTree = "<group>"; };
|
||||
2D206B8525F5FB0900143C56 /* Double.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Double.swift; sourceTree = "<group>"; };
|
||||
|
@ -783,6 +786,7 @@
|
|||
374AA339A20E0FAC75BCDA6D /* Pods_NotificationService.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_NotificationService.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
3B7FD8F28DDA8FBCE5562B78 /* Pods-NotificationService.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationService.asdk - debug.xcconfig"; path = "Target Support Files/Pods-NotificationService/Pods-NotificationService.asdk - debug.xcconfig"; sourceTree = "<group>"; };
|
||||
3C030226D3C73DCC23D67452 /* Pods_Mastodon_MastodonUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Mastodon_MastodonUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
3E08A432F40BA7B9CAA9DB68 /* Pods-AppShared.release snapshot.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppShared.release snapshot.xcconfig"; path = "Target Support Files/Pods-AppShared/Pods-AppShared.release snapshot.xcconfig"; sourceTree = "<group>"; };
|
||||
452147B2903DF38070FE56A2 /* Pods_MastodonTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MastodonTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
459EA4F43058CAB47719E963 /* Pods-Mastodon-MastodonUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-MastodonUITests.debug.xcconfig"; path = "Target Support Files/Pods-Mastodon-MastodonUITests/Pods-Mastodon-MastodonUITests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
46DAB0EBDDFB678347CD96FF /* Pods-MastodonTests.asdk - release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonTests.asdk - release.xcconfig"; path = "Target Support Files/Pods-MastodonTests/Pods-MastodonTests.asdk - release.xcconfig"; sourceTree = "<group>"; };
|
||||
|
@ -814,6 +818,8 @@
|
|||
819CEC9DCAD8E8E7BD85A7BB /* Pods-Mastodon.asdk.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.asdk.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.asdk.xcconfig"; sourceTree = "<group>"; };
|
||||
861BE60ED27430771CFD578D /* Pods-MastodonIntent.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonIntent.debug.xcconfig"; path = "Target Support Files/Pods-MastodonIntent/Pods-MastodonIntent.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
8850E70A1D5FF51432E43653 /* Pods-Mastodon-MastodonUITests.asdk - release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-MastodonUITests.asdk - release.xcconfig"; path = "Target Support Files/Pods-Mastodon-MastodonUITests/Pods-Mastodon-MastodonUITests.asdk - release.xcconfig"; sourceTree = "<group>"; };
|
||||
8ADD558BE5B8255E5764A54F /* Pods-NotificationService.release snapshot.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationService.release snapshot.xcconfig"; path = "Target Support Files/Pods-NotificationService/Pods-NotificationService.release snapshot.xcconfig"; sourceTree = "<group>"; };
|
||||
8E79CCBE51FBC3F7FE8CF49F /* Pods-MastodonTests.release snapshot.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonTests.release snapshot.xcconfig"; path = "Target Support Files/Pods-MastodonTests/Pods-MastodonTests.release snapshot.xcconfig"; sourceTree = "<group>"; };
|
||||
8ED8C4B1F1BA2DCFF2926BB1 /* Pods-Mastodon-NotificationService.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-NotificationService.debug.xcconfig"; path = "Target Support Files/Pods-Mastodon-NotificationService/Pods-Mastodon-NotificationService.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
9553C689FFA9EBC880CAB78D /* Pods-NotificationService.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationService.debug.xcconfig"; path = "Target Support Files/Pods-NotificationService/Pods-NotificationService.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
95AD0663479892A2109EEFD0 /* Pods-ShareActionExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShareActionExtension.release.xcconfig"; path = "Target Support Files/Pods-ShareActionExtension/Pods-ShareActionExtension.release.xcconfig"; sourceTree = "<group>"; };
|
||||
|
@ -1340,6 +1346,7 @@
|
|||
ECA373ABA86BE3C2D7ED878E /* Pods-AppShared.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppShared.release.xcconfig"; path = "Target Support Files/Pods-AppShared/Pods-AppShared.release.xcconfig"; sourceTree = "<group>"; };
|
||||
EE13214BC0246BE5210CCC10 /* Pods-AppShared.asdk.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppShared.asdk.xcconfig"; path = "Target Support Files/Pods-AppShared/Pods-AppShared.asdk.xcconfig"; sourceTree = "<group>"; };
|
||||
F31E7502A7E3945B98C6CBAF /* Pods-NotificationService.asdk.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationService.asdk.xcconfig"; path = "Target Support Files/Pods-NotificationService/Pods-NotificationService.asdk.xcconfig"; sourceTree = "<group>"; };
|
||||
F43DF6E8AB8C87914A64FC48 /* Pods-ShareActionExtension.release snapshot.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShareActionExtension.release snapshot.xcconfig"; path = "Target Support Files/Pods-ShareActionExtension/Pods-ShareActionExtension.release snapshot.xcconfig"; sourceTree = "<group>"; };
|
||||
F4A2A2D7000E477CA459ADA9 /* Pods_AppShared.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AppShared.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F4C94BD75C96D0EFF5F6D961 /* Pods_MastodonIntent.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MastodonIntent.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F920AD4EC23B0D00F5CCA58E /* Pods-MastodonIntent.asdk - release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonIntent.asdk - release.xcconfig"; path = "Target Support Files/Pods-MastodonIntent/Pods-MastodonIntent.asdk - release.xcconfig"; sourceTree = "<group>"; };
|
||||
|
@ -1541,6 +1548,13 @@
|
|||
C3789232A52F43529CA67E95 /* Pods-MastodonIntent.asdk - debug.xcconfig */,
|
||||
F920AD4EC23B0D00F5CCA58E /* Pods-MastodonIntent.asdk - release.xcconfig */,
|
||||
159AC43EFE0A1F95FCB358A4 /* Pods-MastodonIntent.release.xcconfig */,
|
||||
3E08A432F40BA7B9CAA9DB68 /* Pods-AppShared.release snapshot.xcconfig */,
|
||||
0655B257371274BEB7EB1C19 /* Pods-Mastodon.release snapshot.xcconfig */,
|
||||
0827D1674B2523503E8605F6 /* Pods-Mastodon-MastodonUITests.release snapshot.xcconfig */,
|
||||
2C12EB4B3699D5D597027962 /* Pods-MastodonIntent.release snapshot.xcconfig */,
|
||||
8E79CCBE51FBC3F7FE8CF49F /* Pods-MastodonTests.release snapshot.xcconfig */,
|
||||
8ADD558BE5B8255E5764A54F /* Pods-NotificationService.release snapshot.xcconfig */,
|
||||
F43DF6E8AB8C87914A64FC48 /* Pods-ShareActionExtension.release snapshot.xcconfig */,
|
||||
);
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
|
@ -3430,22 +3444,22 @@
|
|||
);
|
||||
mainGroup = DB427DC925BAA00100D1B89D;
|
||||
packageReferences = (
|
||||
DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage" */,
|
||||
DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage.git" */,
|
||||
2D61336725C18A4F00CAE157 /* XCRemoteSwiftPackageReference "AlamofireNetworkActivityIndicator" */,
|
||||
DB0140BB25C40D7500F9F3CF /* XCRemoteSwiftPackageReference "CommonOSLog" */,
|
||||
2D5981B825E4D7F8000FB903 /* XCRemoteSwiftPackageReference "ThirdPartyMailer" */,
|
||||
2D939AC625EE14620076FA61 /* XCRemoteSwiftPackageReference "TOCropViewController" */,
|
||||
2D5981B825E4D7F8000FB903 /* XCRemoteSwiftPackageReference "ThirdPartyMailer.git" */,
|
||||
2D939AC625EE14620076FA61 /* XCRemoteSwiftPackageReference "TOCropViewController.git" */,
|
||||
DB9A487C2603456B008B817C /* XCRemoteSwiftPackageReference "UITextView-Placeholder" */,
|
||||
DBB525062611EAC0002F1F29 /* XCRemoteSwiftPackageReference "Tabman" */,
|
||||
DB6804722637CC1200430867 /* XCRemoteSwiftPackageReference "KeychainAccess" */,
|
||||
DBAC6481267D0B21007FE9FD /* XCRemoteSwiftPackageReference "DifferenceKit" */,
|
||||
DBAC649C267DFE43007FE9FD /* XCRemoteSwiftPackageReference "DiffableDataSources" */,
|
||||
DBAC649F267E6D01007FE9FD /* XCRemoteSwiftPackageReference "Fuzi" */,
|
||||
DBF7A0FA26830C33004176A2 /* XCRemoteSwiftPackageReference "FPSIndicator" */,
|
||||
DB0E2D2C26833FF600865C3C /* XCRemoteSwiftPackageReference "Nuke-FLAnimatedImage-Plugin" */,
|
||||
DB01E23126A98F0900C3965B /* XCRemoteSwiftPackageReference "MetaTextKit" */,
|
||||
DB552D4D26BBD10C00E481F6 /* XCRemoteSwiftPackageReference "swift-collections" */,
|
||||
DBA5A52D26F07ED800CACBAA /* XCRemoteSwiftPackageReference "PanModal" */,
|
||||
DB6804722637CC1200430867 /* XCRemoteSwiftPackageReference "KeychainAccess.git" */,
|
||||
DBAC6481267D0B21007FE9FD /* XCRemoteSwiftPackageReference "DifferenceKit.git" */,
|
||||
DBAC649C267DFE43007FE9FD /* XCRemoteSwiftPackageReference "DiffableDataSources.git" */,
|
||||
DBAC649F267E6D01007FE9FD /* XCRemoteSwiftPackageReference "Fuzi.git" */,
|
||||
DBF7A0FA26830C33004176A2 /* XCRemoteSwiftPackageReference "FPSIndicator.git" */,
|
||||
DB0E2D2C26833FF600865C3C /* XCRemoteSwiftPackageReference "Nuke-FLAnimatedImage-Plugin.git" */,
|
||||
DB01E23126A98F0900C3965B /* XCRemoteSwiftPackageReference "MetaTextKit.git" */,
|
||||
DB552D4D26BBD10C00E481F6 /* XCRemoteSwiftPackageReference "swift-collections.git" */,
|
||||
DBA5A52D26F07ED800CACBAA /* XCRemoteSwiftPackageReference "PanModal.git" */,
|
||||
);
|
||||
productRefGroup = DB427DD325BAA00100D1B89D /* Products */;
|
||||
projectDirPath = "";
|
||||
|
@ -4925,6 +4939,237 @@
|
|||
};
|
||||
name = Release;
|
||||
};
|
||||
DBEB19E127E4658E00B0E80E /* Release Snapshot */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
INTENTS_CODEGEN_LANGUAGE = Swift;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = SNAPSHOT;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = "Release Snapshot";
|
||||
};
|
||||
DBEB19E227E4658E00B0E80E /* Release Snapshot */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 0655B257371274BEB7EB1C19 /* Pods-Mastodon.release snapshot.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 108;
|
||||
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = Mastodon/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.7;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Mastodon/Vender/Mastodon-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = "Release Snapshot";
|
||||
};
|
||||
DBEB19E327E4658E00B0E80E /* Release Snapshot */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 8E79CCBE51FBC3F7FE8CF49F /* Pods-MastodonTests.release snapshot.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = MastodonTests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.MastodonTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Mastodon.app/Mastodon";
|
||||
};
|
||||
name = "Release Snapshot";
|
||||
};
|
||||
DBEB19E427E4658E00B0E80E /* Release Snapshot */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 0827D1674B2523503E8605F6 /* Pods-Mastodon-MastodonUITests.release snapshot.xcconfig */;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = MastodonUITests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.MastodonUITests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TEST_TARGET_NAME = Mastodon;
|
||||
};
|
||||
name = "Release Snapshot";
|
||||
};
|
||||
DBEB19E527E4658E00B0E80E /* Release Snapshot */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 3E08A432F40BA7B9CAA9DB68 /* Pods-AppShared.release snapshot.xcconfig */;
|
||||
buildSettings = {
|
||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 108;
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 108;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INFOPLIST_FILE = AppShared/Info.plist;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@loader_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.AppShared;
|
||||
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
};
|
||||
name = "Release Snapshot";
|
||||
};
|
||||
DBEB19E627E4658E00B0E80E /* Release Snapshot */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 8ADD558BE5B8255E5764A54F /* Pods-NotificationService.release snapshot.xcconfig */;
|
||||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 108;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.7;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.NotificationService;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = "Release Snapshot";
|
||||
};
|
||||
DBEB19E727E4658E00B0E80E /* Release Snapshot */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = F43DF6E8AB8C87914A64FC48 /* Pods-ShareActionExtension.release snapshot.xcconfig */;
|
||||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 108;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = ShareActionExtension/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.7;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.ShareActionExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "APP_EXTENSION $(inherited)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = "Release Snapshot";
|
||||
};
|
||||
DBEB19E827E4658E00B0E80E /* Release Snapshot */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 2C12EB4B3699D5D597027962 /* Pods-MastodonIntent.release snapshot.xcconfig */;
|
||||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 108;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = MastodonIntent/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.7;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.MastodonIntent;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "APP_EXTENSION $(inherited)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = "Release Snapshot";
|
||||
};
|
||||
DBF8AE1C263293E400C9C23C /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 9553C689FFA9EBC880CAB78D /* Pods-NotificationService.debug.xcconfig */;
|
||||
|
@ -4981,6 +5226,7 @@
|
|||
buildConfigurations = (
|
||||
DB427DFA25BAA00100D1B89D /* Debug */,
|
||||
DB427DFB25BAA00100D1B89D /* Release */,
|
||||
DBEB19E127E4658E00B0E80E /* Release Snapshot */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
|
@ -4990,6 +5236,7 @@
|
|||
buildConfigurations = (
|
||||
DB427DFD25BAA00100D1B89D /* Debug */,
|
||||
DB427DFE25BAA00100D1B89D /* Release */,
|
||||
DBEB19E227E4658E00B0E80E /* Release Snapshot */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
|
@ -4999,6 +5246,7 @@
|
|||
buildConfigurations = (
|
||||
DB427E0025BAA00100D1B89D /* Debug */,
|
||||
DB427E0125BAA00100D1B89D /* Release */,
|
||||
DBEB19E327E4658E00B0E80E /* Release Snapshot */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
|
@ -5008,6 +5256,7 @@
|
|||
buildConfigurations = (
|
||||
DB427E0325BAA00100D1B89D /* Debug */,
|
||||
DB427E0425BAA00100D1B89D /* Release */,
|
||||
DBEB19E427E4658E00B0E80E /* Release Snapshot */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
|
@ -5017,6 +5266,7 @@
|
|||
buildConfigurations = (
|
||||
DB6804892637CD4C00430867 /* Debug */,
|
||||
DB68048A2637CD4C00430867 /* Release */,
|
||||
DBEB19E527E4658E00B0E80E /* Release Snapshot */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
|
@ -5026,6 +5276,7 @@
|
|||
buildConfigurations = (
|
||||
DB8FABD026AEC7B2008E5AF4 /* Debug */,
|
||||
DB8FABD326AEC7B2008E5AF4 /* Release */,
|
||||
DBEB19E827E4658E00B0E80E /* Release Snapshot */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
|
@ -5035,6 +5286,7 @@
|
|||
buildConfigurations = (
|
||||
DBC6461D26A170AB00B0E31B /* Debug */,
|
||||
DBC6462026A170AB00B0E31B /* Release */,
|
||||
DBEB19E727E4658E00B0E80E /* Release Snapshot */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
|
@ -5044,6 +5296,7 @@
|
|||
buildConfigurations = (
|
||||
DBF8AE1C263293E400C9C23C /* Debug */,
|
||||
DBF8AE1D263293E400C9C23C /* Release */,
|
||||
DBEB19E627E4658E00B0E80E /* Release Snapshot */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
|
@ -5051,7 +5304,7 @@
|
|||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
2D5981B825E4D7F8000FB903 /* XCRemoteSwiftPackageReference "ThirdPartyMailer" */ = {
|
||||
2D5981B825E4D7F8000FB903 /* XCRemoteSwiftPackageReference "ThirdPartyMailer.git" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/vtourraine/ThirdPartyMailer.git";
|
||||
requirement = {
|
||||
|
@ -5067,7 +5320,7 @@
|
|||
minimumVersion = 3.1.0;
|
||||
};
|
||||
};
|
||||
2D939AC625EE14620076FA61 /* XCRemoteSwiftPackageReference "TOCropViewController" */ = {
|
||||
2D939AC625EE14620076FA61 /* XCRemoteSwiftPackageReference "TOCropViewController.git" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/TimOliver/TOCropViewController.git";
|
||||
requirement = {
|
||||
|
@ -5083,7 +5336,7 @@
|
|||
minimumVersion = 0.1.1;
|
||||
};
|
||||
};
|
||||
DB01E23126A98F0900C3965B /* XCRemoteSwiftPackageReference "MetaTextKit" */ = {
|
||||
DB01E23126A98F0900C3965B /* XCRemoteSwiftPackageReference "MetaTextKit.git" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/TwidereProject/MetaTextKit.git";
|
||||
requirement = {
|
||||
|
@ -5091,7 +5344,7 @@
|
|||
version = 2.2.1;
|
||||
};
|
||||
};
|
||||
DB0E2D2C26833FF600865C3C /* XCRemoteSwiftPackageReference "Nuke-FLAnimatedImage-Plugin" */ = {
|
||||
DB0E2D2C26833FF600865C3C /* XCRemoteSwiftPackageReference "Nuke-FLAnimatedImage-Plugin.git" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/kean/Nuke-FLAnimatedImage-Plugin.git";
|
||||
requirement = {
|
||||
|
@ -5099,7 +5352,7 @@
|
|||
minimumVersion = 8.0.0;
|
||||
};
|
||||
};
|
||||
DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage" */ = {
|
||||
DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage.git" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/Alamofire/AlamofireImage.git";
|
||||
requirement = {
|
||||
|
@ -5107,7 +5360,7 @@
|
|||
minimumVersion = 4.1.0;
|
||||
};
|
||||
};
|
||||
DB552D4D26BBD10C00E481F6 /* XCRemoteSwiftPackageReference "swift-collections" */ = {
|
||||
DB552D4D26BBD10C00E481F6 /* XCRemoteSwiftPackageReference "swift-collections.git" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/apple/swift-collections.git";
|
||||
requirement = {
|
||||
|
@ -5115,7 +5368,7 @@
|
|||
minimumVersion = 0.0.5;
|
||||
};
|
||||
};
|
||||
DB6804722637CC1200430867 /* XCRemoteSwiftPackageReference "KeychainAccess" */ = {
|
||||
DB6804722637CC1200430867 /* XCRemoteSwiftPackageReference "KeychainAccess.git" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/kishikawakatsumi/KeychainAccess.git";
|
||||
requirement = {
|
||||
|
@ -5131,7 +5384,7 @@
|
|||
minimumVersion = 1.4.1;
|
||||
};
|
||||
};
|
||||
DBA5A52D26F07ED800CACBAA /* XCRemoteSwiftPackageReference "PanModal" */ = {
|
||||
DBA5A52D26F07ED800CACBAA /* XCRemoteSwiftPackageReference "PanModal.git" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/slackhq/PanModal.git";
|
||||
requirement = {
|
||||
|
@ -5139,7 +5392,7 @@
|
|||
minimumVersion = 1.2.7;
|
||||
};
|
||||
};
|
||||
DBAC6481267D0B21007FE9FD /* XCRemoteSwiftPackageReference "DifferenceKit" */ = {
|
||||
DBAC6481267D0B21007FE9FD /* XCRemoteSwiftPackageReference "DifferenceKit.git" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/ra1028/DifferenceKit.git";
|
||||
requirement = {
|
||||
|
@ -5147,7 +5400,7 @@
|
|||
version = 1.2.0;
|
||||
};
|
||||
};
|
||||
DBAC649C267DFE43007FE9FD /* XCRemoteSwiftPackageReference "DiffableDataSources" */ = {
|
||||
DBAC649C267DFE43007FE9FD /* XCRemoteSwiftPackageReference "DiffableDataSources.git" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/MainasuK/DiffableDataSources.git";
|
||||
requirement = {
|
||||
|
@ -5155,7 +5408,7 @@
|
|||
kind = branch;
|
||||
};
|
||||
};
|
||||
DBAC649F267E6D01007FE9FD /* XCRemoteSwiftPackageReference "Fuzi" */ = {
|
||||
DBAC649F267E6D01007FE9FD /* XCRemoteSwiftPackageReference "Fuzi.git" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/cezheng/Fuzi.git";
|
||||
requirement = {
|
||||
|
@ -5171,7 +5424,7 @@
|
|||
minimumVersion = 2.11.0;
|
||||
};
|
||||
};
|
||||
DBF7A0FA26830C33004176A2 /* XCRemoteSwiftPackageReference "FPSIndicator" */ = {
|
||||
DBF7A0FA26830C33004176A2 /* XCRemoteSwiftPackageReference "FPSIndicator.git" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/MainasuK/FPSIndicator.git";
|
||||
requirement = {
|
||||
|
@ -5184,7 +5437,7 @@
|
|||
/* Begin XCSwiftPackageProductDependency section */
|
||||
2D5981B925E4D7F8000FB903 /* ThirdPartyMailer */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 2D5981B825E4D7F8000FB903 /* XCRemoteSwiftPackageReference "ThirdPartyMailer" */;
|
||||
package = 2D5981B825E4D7F8000FB903 /* XCRemoteSwiftPackageReference "ThirdPartyMailer.git" */;
|
||||
productName = ThirdPartyMailer;
|
||||
};
|
||||
2D61336825C18A4F00CAE157 /* AlamofireNetworkActivityIndicator */ = {
|
||||
|
@ -5194,7 +5447,7 @@
|
|||
};
|
||||
2D939AC725EE14620076FA61 /* CropViewController */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 2D939AC625EE14620076FA61 /* XCRemoteSwiftPackageReference "TOCropViewController" */;
|
||||
package = 2D939AC625EE14620076FA61 /* XCRemoteSwiftPackageReference "TOCropViewController.git" */;
|
||||
productName = CropViewController;
|
||||
};
|
||||
5D526FE125BE9AC400460CB9 /* MastodonSDK */ = {
|
||||
|
@ -5213,17 +5466,17 @@
|
|||
};
|
||||
DB01E23226A98F0900C3965B /* MastodonMeta */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = DB01E23126A98F0900C3965B /* XCRemoteSwiftPackageReference "MetaTextKit" */;
|
||||
package = DB01E23126A98F0900C3965B /* XCRemoteSwiftPackageReference "MetaTextKit.git" */;
|
||||
productName = MastodonMeta;
|
||||
};
|
||||
DB01E23426A98F0900C3965B /* MetaTextKit */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = DB01E23126A98F0900C3965B /* XCRemoteSwiftPackageReference "MetaTextKit" */;
|
||||
package = DB01E23126A98F0900C3965B /* XCRemoteSwiftPackageReference "MetaTextKit.git" */;
|
||||
productName = MetaTextKit;
|
||||
};
|
||||
DB0C946426A6FD4D0088FB11 /* AlamofireImage */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage" */;
|
||||
package = DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage.git" */;
|
||||
productName = AlamofireImage;
|
||||
};
|
||||
DB179266278D5A4A00B71DEB /* MastodonSDK */ = {
|
||||
|
@ -5232,22 +5485,22 @@
|
|||
};
|
||||
DB3D0FF225BAA61700EAA174 /* AlamofireImage */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage" */;
|
||||
package = DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage.git" */;
|
||||
productName = AlamofireImage;
|
||||
};
|
||||
DB552D4E26BBD10C00E481F6 /* OrderedCollections */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = DB552D4D26BBD10C00E481F6 /* XCRemoteSwiftPackageReference "swift-collections" */;
|
||||
package = DB552D4D26BBD10C00E481F6 /* XCRemoteSwiftPackageReference "swift-collections.git" */;
|
||||
productName = OrderedCollections;
|
||||
};
|
||||
DB68050F2637D0F800430867 /* KeychainAccess */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = DB6804722637CC1200430867 /* XCRemoteSwiftPackageReference "KeychainAccess" */;
|
||||
package = DB6804722637CC1200430867 /* XCRemoteSwiftPackageReference "KeychainAccess.git" */;
|
||||
productName = KeychainAccess;
|
||||
};
|
||||
DB6D9F41263527CE008423CD /* AlamofireImage */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage" */;
|
||||
package = DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage.git" */;
|
||||
productName = AlamofireImage;
|
||||
};
|
||||
DB9A487D2603456B008B817C /* UITextView+Placeholder */ = {
|
||||
|
@ -5257,22 +5510,22 @@
|
|||
};
|
||||
DBA5A52E26F07ED800CACBAA /* PanModal */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = DBA5A52D26F07ED800CACBAA /* XCRemoteSwiftPackageReference "PanModal" */;
|
||||
package = DBA5A52D26F07ED800CACBAA /* XCRemoteSwiftPackageReference "PanModal.git" */;
|
||||
productName = PanModal;
|
||||
};
|
||||
DBAC6482267D0B21007FE9FD /* DifferenceKit */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = DBAC6481267D0B21007FE9FD /* XCRemoteSwiftPackageReference "DifferenceKit" */;
|
||||
package = DBAC6481267D0B21007FE9FD /* XCRemoteSwiftPackageReference "DifferenceKit.git" */;
|
||||
productName = DifferenceKit;
|
||||
};
|
||||
DBAC649D267DFE43007FE9FD /* DiffableDataSources */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = DBAC649C267DFE43007FE9FD /* XCRemoteSwiftPackageReference "DiffableDataSources" */;
|
||||
package = DBAC649C267DFE43007FE9FD /* XCRemoteSwiftPackageReference "DiffableDataSources.git" */;
|
||||
productName = DiffableDataSources;
|
||||
};
|
||||
DBAC64A0267E6D02007FE9FD /* Fuzi */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = DBAC649F267E6D01007FE9FD /* XCRemoteSwiftPackageReference "Fuzi" */;
|
||||
package = DBAC649F267E6D01007FE9FD /* XCRemoteSwiftPackageReference "Fuzi.git" */;
|
||||
productName = Fuzi;
|
||||
};
|
||||
DBB525072611EAC0002F1F29 /* Tabman */ = {
|
||||
|
@ -5300,7 +5553,7 @@
|
|||
};
|
||||
DBF7A0FB26830C33004176A2 /* FPSIndicator */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = DBF7A0FA26830C33004176A2 /* XCRemoteSwiftPackageReference "FPSIndicator" */;
|
||||
package = DBF7A0FA26830C33004176A2 /* XCRemoteSwiftPackageReference "FPSIndicator.git" */;
|
||||
productName = FPSIndicator;
|
||||
};
|
||||
/* End XCSwiftPackageProductDependency section */
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Release"
|
||||
buildConfiguration = "Release Snapshot"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
|
@ -63,7 +63,7 @@
|
|||
</TestPlans>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Release"
|
||||
buildConfiguration = "Release Snapshot"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
disableMainThreadChecker = "YES"
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<key>isShown</key>
|
||||
<true/>
|
||||
<key>orderHint</key>
|
||||
<integer>16</integer>
|
||||
<integer>15</integer>
|
||||
</dict>
|
||||
<key>CoreDataStack.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
|
@ -104,7 +104,7 @@
|
|||
<key>MastodonIntent.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>32</integer>
|
||||
<integer>37</integer>
|
||||
</dict>
|
||||
<key>MastodonIntents.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
|
@ -119,12 +119,12 @@
|
|||
<key>NotificationService.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>33</integer>
|
||||
<integer>36</integer>
|
||||
</dict>
|
||||
<key>ShareActionExtension.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>31</integer>
|
||||
<integer>38</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "IMG_1010.jpg",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 2.4 MiB |
|
@ -381,7 +381,7 @@ extension ComposeViewController {
|
|||
// bind publish bar button state
|
||||
viewModel.$isPublishBarButtonItemEnabled
|
||||
.receive(on: DispatchQueue.main)
|
||||
.assign(to: \.isEnabled, on: publishBarButtonItem)
|
||||
.assign(to: \.isEnabled, on: publishButton)
|
||||
.store(in: &disposeBag)
|
||||
|
||||
// bind media button toolbar state
|
||||
|
@ -915,14 +915,25 @@ extension ComposeViewController: UITextViewDelegate {
|
|||
// MARK: - ComposeToolbarViewDelegate
|
||||
extension ComposeViewController: ComposeToolbarViewDelegate {
|
||||
|
||||
func composeToolbarView(_ composeToolbarView: ComposeToolbarView, cameraButtonDidPressed sender: Any, mediaSelectionType type: ComposeToolbarView.MediaSelectionType) {
|
||||
func composeToolbarView(_ composeToolbarView: ComposeToolbarView, mediaButtonDidPressed sender: Any, mediaSelectionType type: ComposeToolbarView.MediaSelectionType) {
|
||||
switch type {
|
||||
case .photoLibrary:
|
||||
present(photoLibraryPicker, animated: true, completion: nil)
|
||||
case .camera:
|
||||
present(imagePickerController, animated: true, completion: nil)
|
||||
case .browse:
|
||||
#if SNAPSHOT
|
||||
guard let image = UIImage(named: "Athens") else { return }
|
||||
|
||||
let attachmentService = MastodonAttachmentService(
|
||||
context: context,
|
||||
image: image,
|
||||
initialAuthenticationBox: viewModel.authenticationBox
|
||||
)
|
||||
viewModel.attachmentServices = viewModel.attachmentServices + [attachmentService]
|
||||
#else
|
||||
present(documentPickerController, animated: true, completion: nil)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import MastodonAsset
|
|||
import MastodonLocalization
|
||||
|
||||
protocol ComposeToolbarViewDelegate: AnyObject {
|
||||
func composeToolbarView(_ composeToolbarView: ComposeToolbarView, cameraButtonDidPressed sender: Any, mediaSelectionType type: ComposeToolbarView.MediaSelectionType)
|
||||
func composeToolbarView(_ composeToolbarView: ComposeToolbarView, mediaButtonDidPressed sender: Any, mediaSelectionType type: ComposeToolbarView.MediaSelectionType)
|
||||
func composeToolbarView(_ composeToolbarView: ComposeToolbarView, pollButtonDidPressed sender: Any)
|
||||
func composeToolbarView(_ composeToolbarView: ComposeToolbarView, emojiButtonDidPressed sender: Any)
|
||||
func composeToolbarView(_ composeToolbarView: ComposeToolbarView, contentWarningButtonDidPressed sender: Any)
|
||||
|
@ -304,21 +304,21 @@ extension ComposeToolbarView {
|
|||
let photoLibraryAction = UIAction(title: L10n.Scene.Compose.MediaSelection.photoLibrary, image: UIImage(systemName: "rectangle.on.rectangle"), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off) { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: mediaSelectionType: .photoLibrary", ((#file as NSString).lastPathComponent), #line, #function)
|
||||
self.delegate?.composeToolbarView(self, cameraButtonDidPressed: self.mediaButton, mediaSelectionType: .photoLibrary)
|
||||
self.delegate?.composeToolbarView(self, mediaButtonDidPressed: self.mediaButton, mediaSelectionType: .photoLibrary)
|
||||
}
|
||||
children.append(photoLibraryAction)
|
||||
if UIImagePickerController.isSourceTypeAvailable(.camera) {
|
||||
let cameraAction = UIAction(title: L10n.Scene.Compose.MediaSelection.camera, image: UIImage(systemName: "camera"), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off, handler: { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: mediaSelectionType: .camera", ((#file as NSString).lastPathComponent), #line, #function)
|
||||
self.delegate?.composeToolbarView(self, cameraButtonDidPressed: self.mediaButton, mediaSelectionType: .camera)
|
||||
self.delegate?.composeToolbarView(self, mediaButtonDidPressed: self.mediaButton, mediaSelectionType: .camera)
|
||||
})
|
||||
children.append(cameraAction)
|
||||
}
|
||||
let browseAction = UIAction(title: L10n.Scene.Compose.MediaSelection.browse, image: UIImage(systemName: "ellipsis"), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off) { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: mediaSelectionType: .browse", ((#file as NSString).lastPathComponent), #line, #function)
|
||||
self.delegate?.composeToolbarView(self, cameraButtonDidPressed: self.mediaButton, mediaSelectionType: .browse)
|
||||
self.delegate?.composeToolbarView(self, mediaButtonDidPressed: self.mediaButton, mediaSelectionType: .browse)
|
||||
}
|
||||
children.append(browseAction)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
//
|
||||
|
||||
|
||||
#if DEBUG
|
||||
#if DEBUG || SNAPSHOT
|
||||
import os.log
|
||||
import UIKit
|
||||
import CoreData
|
||||
|
|
|
@ -127,6 +127,11 @@ extension HomeTimelineViewController {
|
|||
settingBarButtonItem.action = #selector(HomeTimelineViewController.settingBarButtonItemPressed(_:))
|
||||
#endif
|
||||
|
||||
#if SNAPSHOT
|
||||
titleView.logoButton.menu = self.debugMenu
|
||||
titleView.button.menu = self.debugMenu
|
||||
#endif
|
||||
|
||||
viewModel.$displayComposeBarButtonItem
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak self] displayComposeBarButtonItem in
|
||||
|
|
|
@ -65,6 +65,9 @@ extension HomeTimelineNavigationBarTitleView {
|
|||
configure(state: .logo)
|
||||
logoButton.addTarget(self, action: #selector(HomeTimelineNavigationBarTitleView.logoButtonDidPressed(_:)), for: .touchUpInside)
|
||||
button.addTarget(self, action: #selector(HomeTimelineNavigationBarTitleView.buttonDidPressed(_:)), for: .touchUpInside)
|
||||
|
||||
logoButton.accessibilityIdentifier = "TitleButton"
|
||||
button.accessibilityIdentifier = "TitleButton"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ final class MastodonConfirmEmailViewModel {
|
|||
self.updateCredentialQuery = updateCredentialQuery
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
#if DEBUG || SNAPSHOT
|
||||
init() {
|
||||
self.context = AppContext.shared
|
||||
self.email = "example.com"
|
||||
|
|
|
@ -12,6 +12,8 @@ final class CachedProfileViewModel: ProfileViewModel {
|
|||
|
||||
init(context: AppContext, mastodonUser: MastodonUser) {
|
||||
super.init(context: context, optionalMastodonUser: mastodonUser)
|
||||
|
||||
logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): [Profile] user[\(mastodonUser.id)] profile: \(mastodonUser.acctWithDomain)")
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -59,6 +59,14 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||
sceneCoordinator.setup()
|
||||
sceneCoordinator.setupOnboardingIfNeeds(animated: false)
|
||||
window.makeKeyAndVisible()
|
||||
|
||||
#if SNAPSHOT
|
||||
// speedup animation
|
||||
// window.layer.speed = 999
|
||||
|
||||
// disable animation
|
||||
UIView.setAnimationsEnabled(false)
|
||||
#endif
|
||||
|
||||
if let shortcutItem = connectionOptions.shortcutItem {
|
||||
// Save it off for later when we become active.
|
||||
|
@ -67,7 +75,15 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||
|
||||
UserDefaults.shared.observe(\.customUserInterfaceStyle, options: [.initial, .new]) { [weak self] defaults, _ in
|
||||
guard let self = self else { return }
|
||||
#if SNAPSHOT
|
||||
// toggle Dark Mode
|
||||
// https://stackoverflow.com/questions/32988241/how-to-access-launchenvironment-and-launcharguments-set-in-xcuiapplication-runn
|
||||
if ProcessInfo.processInfo.arguments.contains("UIUserInterfaceStyleForceDark") {
|
||||
self.window?.overrideUserInterfaceStyle = .dark
|
||||
}
|
||||
#else
|
||||
self.window?.overrideUserInterfaceStyle = defaults.customUserInterfaceStyle
|
||||
#endif
|
||||
}
|
||||
.store(in: &observations)
|
||||
|
||||
|
|
|
@ -45,6 +45,19 @@ extension MastodonUISnapshotTests {
|
|||
|
||||
extension MastodonUISnapshotTests {
|
||||
|
||||
func takeSnapshot(name: String) {
|
||||
let snapshot = XCUIScreen.main.screenshot()
|
||||
let attachment = XCTAttachment(
|
||||
uniformTypeIdentifier: "public.png",
|
||||
name: "\(name).\(UIDevice.current.name).png",
|
||||
payload: snapshot.pngRepresentation,
|
||||
userInfo: nil
|
||||
)
|
||||
attachment.lifetime = .keepAlways
|
||||
add(attachment)
|
||||
}
|
||||
|
||||
// make tab display by tap it
|
||||
private func tapTab(app: XCUIApplication, tab: String) {
|
||||
let searchTab = app.tabBars.buttons[tab]
|
||||
if searchTab.exists { searchTab.tap() }
|
||||
|
@ -52,159 +65,223 @@ extension MastodonUISnapshotTests {
|
|||
let searchCell = app.collectionViews.cells[tab]
|
||||
if searchCell.exists { searchCell.tap() }
|
||||
}
|
||||
|
||||
private func showTitleButtonMenu(app: XCUIApplication) async throws {
|
||||
let titleButton = app.navigationBars.buttons["TitleButton"].firstMatch
|
||||
XCTAssert(titleButton.waitForExistence(timeout: 5))
|
||||
titleButton.press(forDuration: 1.0)
|
||||
try await Task.sleep(nanoseconds: .second * 1)
|
||||
}
|
||||
|
||||
func testSnapshot() async throws {
|
||||
let app = XCUIApplication()
|
||||
app.launch()
|
||||
private func snapshot(
|
||||
name: String,
|
||||
count: Int = 3,
|
||||
task: (_ app: XCUIApplication) async throws -> Void
|
||||
) async rethrows {
|
||||
var app = XCUIApplication()
|
||||
|
||||
try await testSnapshotHome()
|
||||
try await testSnapshotSearch()
|
||||
try await testSnapshotNotification()
|
||||
try await testSnapshotProfile()
|
||||
try await testSnapshotCompose()
|
||||
}
|
||||
|
||||
func testSnapshotHome() async throws {
|
||||
let app = XCUIApplication()
|
||||
app.launch()
|
||||
|
||||
tapTab(app: app, tab: "Home")
|
||||
try await Task.sleep(nanoseconds: .second * 3)
|
||||
takeSnapshot(name: "Home - 1")
|
||||
|
||||
tapTab(app: app, tab: "Home")
|
||||
try await Task.sleep(nanoseconds: .second * 3)
|
||||
takeSnapshot(name: "Home - 2")
|
||||
|
||||
tapTab(app: app, tab: "Home")
|
||||
try await Task.sleep(nanoseconds: .second * 3)
|
||||
takeSnapshot(name: "Home - 3")
|
||||
}
|
||||
|
||||
func testSnapshotSearch() async throws {
|
||||
let app = XCUIApplication()
|
||||
app.launch()
|
||||
|
||||
tapTab(app: app, tab: "Search")
|
||||
try await Task.sleep(nanoseconds: .second * 3)
|
||||
takeSnapshot(name: "Search - 1")
|
||||
|
||||
tapTab(app: app, tab: "Search")
|
||||
try await Task.sleep(nanoseconds: .second * 3)
|
||||
takeSnapshot(name: "Search - 2")
|
||||
|
||||
tapTab(app: app, tab: "Search")
|
||||
try await Task.sleep(nanoseconds: .second * 3)
|
||||
takeSnapshot(name: "Search - 3")
|
||||
}
|
||||
|
||||
func testSnapshotNotification() async throws {
|
||||
let app = XCUIApplication()
|
||||
app.launch()
|
||||
|
||||
tapTab(app: app, tab: "Notification")
|
||||
try await Task.sleep(nanoseconds: .second * 3)
|
||||
takeSnapshot(name: "Notification - 1")
|
||||
|
||||
tapTab(app: app, tab: "Notification")
|
||||
try await Task.sleep(nanoseconds: .second * 3)
|
||||
takeSnapshot(name: "Notification - 2")
|
||||
|
||||
tapTab(app: app, tab: "Notification")
|
||||
try await Task.sleep(nanoseconds: .second * 3)
|
||||
takeSnapshot(name: "Notification - 3")
|
||||
}
|
||||
|
||||
func testSnapshotProfile() async throws {
|
||||
let username = ProcessInfo.processInfo.environment["username_snapshot"] ?? "Gargron"
|
||||
|
||||
let app = XCUIApplication()
|
||||
app.launch()
|
||||
|
||||
// Go to Search tab
|
||||
tapTab(app: app, tab: "Search")
|
||||
|
||||
// Tap and search user
|
||||
let searchField = app.navigationBars.searchFields.firstMatch
|
||||
XCTAssert(searchField.waitForExistence(timeout: 5))
|
||||
searchField.tap()
|
||||
searchField.typeText(username)
|
||||
|
||||
// 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")
|
||||
}
|
||||
|
||||
func testSnapshotCompose() async throws {
|
||||
let app = XCUIApplication()
|
||||
app.launch()
|
||||
|
||||
// open Compose scene
|
||||
let composeBarButtonItem = app.navigationBars.buttons["Compose"].firstMatch
|
||||
let composeCollectionViewCell = app.collectionViews.cells["Compose"]
|
||||
if composeBarButtonItem.waitForExistence(timeout: 5) {
|
||||
composeBarButtonItem.tap()
|
||||
} else if composeCollectionViewCell.waitForExistence(timeout: 5) {
|
||||
composeCollectionViewCell.tap()
|
||||
} else {
|
||||
XCTFail()
|
||||
// pass -1 to debug test case
|
||||
guard count >= 0 else {
|
||||
app.launch()
|
||||
try await task(app)
|
||||
takeSnapshot(name: name)
|
||||
return
|
||||
}
|
||||
|
||||
// type text
|
||||
let textView = app.textViews.firstMatch
|
||||
XCTAssert(textView.waitForExistence(timeout: 5))
|
||||
textView.tap()
|
||||
textView.typeText("Look at that view! #Athens ")
|
||||
|
||||
// tap Add Attachment toolbar button
|
||||
let addAttachmentButton = app.buttons["Add Attachment"].firstMatch
|
||||
XCTAssert(addAttachmentButton.waitForExistence(timeout: 5))
|
||||
addAttachmentButton.tap()
|
||||
// Light Mode
|
||||
for index in 0..<count {
|
||||
app.launch()
|
||||
try await task(app)
|
||||
|
||||
let name = "\(name).light.\(index+1)"
|
||||
takeSnapshot(name: name)
|
||||
}
|
||||
|
||||
// tap Photo Library menu action
|
||||
let photoLibraryButton = app.buttons["Photo Library"].firstMatch
|
||||
XCTAssert(photoLibraryButton.waitForExistence(timeout: 5))
|
||||
photoLibraryButton.tap()
|
||||
|
||||
// select the first photo
|
||||
let photo = app.images.containing(NSPredicate(format: "label BEGINSWITH 'Photo'")).element(boundBy: 0).firstMatch
|
||||
XCTAssert(photo.waitForExistence(timeout: 5))
|
||||
photo.tap()
|
||||
|
||||
// tap Add barButtonItem
|
||||
let addBarButtonItem = app.navigationBars.buttons["Add"].firstMatch
|
||||
XCTAssert(addBarButtonItem.waitForExistence(timeout: 5))
|
||||
addBarButtonItem.tap()
|
||||
|
||||
try await Task.sleep(nanoseconds: .second * 10)
|
||||
takeSnapshot(name: "Compose - 1")
|
||||
|
||||
try await Task.sleep(nanoseconds: .second * 10)
|
||||
takeSnapshot(name: "Compose - 2")
|
||||
|
||||
try await Task.sleep(nanoseconds: .second * 10)
|
||||
takeSnapshot(name: "Compose - 3")
|
||||
// Dark Mode
|
||||
app = XCUIApplication()
|
||||
app.launchArguments.append("UIUserInterfaceStyleForceDark")
|
||||
for index in 0..<count {
|
||||
app.launch()
|
||||
try await task(app)
|
||||
|
||||
let name = "\(name).dark.\(index+1)"
|
||||
takeSnapshot(name: name)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Home
|
||||
extension MastodonUISnapshotTests {
|
||||
|
||||
func testSnapshotHome() async throws {
|
||||
try await snapshot(name: "Home") { app in
|
||||
tapTab(app: app, tab: "Home")
|
||||
try await Task.sleep(nanoseconds: .second * 3)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Thread
|
||||
extension MastodonUISnapshotTests {
|
||||
|
||||
func testSnapshotThread() async throws {
|
||||
try await snapshot(name: "Thread") { app in
|
||||
let threadID = ProcessInfo.processInfo.environment["thread_id"]!
|
||||
try await coordinateToThread(app: app, id: threadID)
|
||||
try await Task.sleep(nanoseconds: .second * 5)
|
||||
}
|
||||
}
|
||||
|
||||
// use debug entry goto thread scene by thread ID
|
||||
// assert the thread ID is valid for current sign in user server
|
||||
private func coordinateToThread(app: XCUIApplication, id: String) async throws {
|
||||
try await Task.sleep(nanoseconds: .second * 1)
|
||||
|
||||
try await showTitleButtonMenu(app: app)
|
||||
|
||||
let showMenu = app.collectionViews.buttons["Show…"].firstMatch
|
||||
XCTAssert(showMenu.waitForExistence(timeout: 3))
|
||||
showMenu.tap()
|
||||
try await Task.sleep(nanoseconds: .second * 1)
|
||||
|
||||
let threadAction = app.collectionViews.buttons["Thread"].firstMatch
|
||||
XCTAssert(threadAction.waitForExistence(timeout: 3))
|
||||
threadAction.tap()
|
||||
try await Task.sleep(nanoseconds: .second * 1)
|
||||
|
||||
let textField = app.alerts.textFields.firstMatch
|
||||
XCTAssert(textField.waitForExistence(timeout: 3))
|
||||
textField.typeText(id)
|
||||
try await Task.sleep(nanoseconds: .second * 1)
|
||||
|
||||
let showAction = app.alerts.buttons["Show"].firstMatch
|
||||
XCTAssert(showAction.waitForExistence(timeout: 3))
|
||||
showAction.tap()
|
||||
try await Task.sleep(nanoseconds: .second * 1)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Profile
|
||||
extension MastodonUISnapshotTests {
|
||||
|
||||
func testSnapshotProfile() async throws {
|
||||
try await snapshot(name: "Profile") { app in
|
||||
let profileID = ProcessInfo.processInfo.environment["profile_id"]!
|
||||
try await coordinateToProfile(app: app, id: profileID)
|
||||
try await Task.sleep(nanoseconds: .second * 5)
|
||||
}
|
||||
}
|
||||
|
||||
// use debug entry goto thread scene by profile ID
|
||||
// assert the profile ID is valid for current sign in user server
|
||||
private func coordinateToProfile(app: XCUIApplication, id: String) async throws {
|
||||
try await Task.sleep(nanoseconds: .second * 1)
|
||||
|
||||
try await showTitleButtonMenu(app: app)
|
||||
|
||||
let showMenu = app.collectionViews.buttons["Show…"].firstMatch
|
||||
XCTAssert(showMenu.waitForExistence(timeout: 3))
|
||||
showMenu.tap()
|
||||
try await Task.sleep(nanoseconds: .second * 1)
|
||||
|
||||
let profileAction = app.collectionViews.buttons["Profile"].firstMatch
|
||||
XCTAssert(profileAction.waitForExistence(timeout: 3))
|
||||
profileAction.tap()
|
||||
try await Task.sleep(nanoseconds: .second * 1)
|
||||
|
||||
let textField = app.alerts.textFields.firstMatch
|
||||
XCTAssert(textField.waitForExistence(timeout: 3))
|
||||
textField.typeText(id)
|
||||
try await Task.sleep(nanoseconds: .second * 1)
|
||||
|
||||
let showAction = app.alerts.buttons["Show"].firstMatch
|
||||
XCTAssert(showAction.waitForExistence(timeout: 3))
|
||||
showAction.tap()
|
||||
try await Task.sleep(nanoseconds: .second * 1)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Server Rules
|
||||
extension MastodonUISnapshotTests {
|
||||
|
||||
func testSnapshotServerRules() async throws {
|
||||
try await snapshot(name: "ServerRules") { app in
|
||||
let domain = "mastodon.social"
|
||||
try await coordinateToOnboarding(app: app, page: .serverRules(domain: domain))
|
||||
try await Task.sleep(nanoseconds: .second * 3)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Search
|
||||
extension MastodonUISnapshotTests {
|
||||
|
||||
func testSnapshotSearch() async throws {
|
||||
try await snapshot(name: "ServerRules") { app in
|
||||
tapTab(app: app, tab: "Search")
|
||||
try await Task.sleep(nanoseconds: .second * 3)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Compose
|
||||
extension MastodonUISnapshotTests {
|
||||
|
||||
func testSnapshotCompose() async throws {
|
||||
try await snapshot(name: "Compose") { app in
|
||||
// open Compose scene
|
||||
let composeBarButtonItem = app.navigationBars.buttons["Compose"].firstMatch
|
||||
let composeCollectionViewCell = app.collectionViews.cells["Compose"]
|
||||
if composeBarButtonItem.waitForExistence(timeout: 5) {
|
||||
composeBarButtonItem.tap()
|
||||
} else if composeCollectionViewCell.waitForExistence(timeout: 5) {
|
||||
composeCollectionViewCell.tap()
|
||||
} else {
|
||||
XCTFail()
|
||||
}
|
||||
|
||||
// type text
|
||||
let textView = app.textViews.firstMatch
|
||||
XCTAssert(textView.waitForExistence(timeout: 5))
|
||||
textView.tap()
|
||||
textView.typeText("Look at that view! #Athens ")
|
||||
|
||||
// tap Add Attachment toolbar button
|
||||
let addAttachmentButton = app.buttons["Add Attachment"].firstMatch
|
||||
XCTAssert(addAttachmentButton.waitForExistence(timeout: 5))
|
||||
addAttachmentButton.tap()
|
||||
|
||||
// tap Browse menu action to add stub image
|
||||
let browseButton = app.buttons["Browse"].firstMatch
|
||||
XCTAssert(browseButton.waitForExistence(timeout: 5))
|
||||
browseButton.tap()
|
||||
|
||||
try await Task.sleep(nanoseconds: .second * 10)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: Sign in
|
||||
extension MastodonUISnapshotTests {
|
||||
|
||||
// Please check the Documentation/Snapshot.md and run this test case in the command line
|
||||
func testSignInAccount() async throws {
|
||||
guard let domain = ProcessInfo.processInfo.environment["domain"] else {
|
||||
fatalError("env 'domain' missing")
|
||||
guard let domain = ProcessInfo.processInfo.environment["login_domain"] else {
|
||||
fatalError("env 'login_domain' missing")
|
||||
}
|
||||
guard let email = ProcessInfo.processInfo.environment["email"] else {
|
||||
fatalError("env 'email' missing")
|
||||
guard let email = ProcessInfo.processInfo.environment["login_email"] else {
|
||||
fatalError("env 'login_email' missing")
|
||||
}
|
||||
guard let password = ProcessInfo.processInfo.environment["password"] else {
|
||||
fatalError("env 'password' missing")
|
||||
guard let password = ProcessInfo.processInfo.environment["login_password"] else {
|
||||
fatalError("env 'login_password' missing")
|
||||
}
|
||||
try await signInApplication(
|
||||
domain: domain,
|
||||
|
@ -221,62 +298,7 @@ extension MastodonUISnapshotTests {
|
|||
let app = XCUIApplication()
|
||||
app.launch()
|
||||
|
||||
// check in Onboarding or not
|
||||
let loginButton = app.buttons["Log In"].firstMatch
|
||||
let loginButtonExists = loginButton.waitForExistence(timeout: 5)
|
||||
|
||||
// goto Onboarding scene if already sign-in
|
||||
if !loginButtonExists {
|
||||
let profileTabBarButton = app.tabBars.buttons["Profile"]
|
||||
XCTAssert(profileTabBarButton.waitForExistence(timeout: 3))
|
||||
profileTabBarButton.press(forDuration: 2)
|
||||
|
||||
let addAccountCell = app.cells.containing(.staticText, identifier: "Add Account").firstMatch
|
||||
XCTAssert(addAccountCell.waitForExistence(timeout: 3))
|
||||
addAccountCell.tap()
|
||||
}
|
||||
|
||||
// Tap login button
|
||||
XCTAssert(loginButtonExists)
|
||||
loginButton.tap()
|
||||
|
||||
// type domain
|
||||
let domainTextField = app.textFields.firstMatch
|
||||
XCTAssert(domainTextField.waitForExistence(timeout: 5))
|
||||
domainTextField.tap()
|
||||
// Skip system keyboard swipe input guide
|
||||
skipKeyboardSwipeInputGuide(app: app)
|
||||
domainTextField.typeText(domain)
|
||||
XCUIApplication().keyboards.buttons["Done"].firstMatch.tap()
|
||||
|
||||
// wait searching
|
||||
try await Task.sleep(nanoseconds: .second * 3)
|
||||
|
||||
// tap server
|
||||
let cell = app.cells.containing(.staticText, identifier: domain).firstMatch
|
||||
XCTAssert(cell.waitForExistence(timeout: 5))
|
||||
cell.tap()
|
||||
|
||||
// add system alert monitor
|
||||
// A. The monitor not works
|
||||
// addUIInterruptionMonitor(withDescription: "Authentication Alert") { alert in
|
||||
// alert.buttons["Continue"].firstMatch.tap()
|
||||
// return true
|
||||
// }
|
||||
|
||||
// tap next button
|
||||
let nextButton = app.buttons.matching(NSPredicate(format: "enabled == true")).matching(identifier: "Next").firstMatch
|
||||
XCTAssert(nextButton.waitForExistence(timeout: 3))
|
||||
nextButton.tap()
|
||||
|
||||
// wait authentication alert display
|
||||
try await Task.sleep(nanoseconds: .second * 3)
|
||||
|
||||
// B. Workaround
|
||||
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
|
||||
let continueButton = springboard.buttons["Continue"].firstMatch
|
||||
XCTAssert(continueButton.waitForExistence(timeout: 3))
|
||||
continueButton.tap()
|
||||
try await coordinateToOnboarding(app: app, page: .login(domain: domain))
|
||||
|
||||
// wait OAuth webpage display
|
||||
try await Task.sleep(nanoseconds: .second * 10)
|
||||
|
@ -331,24 +353,102 @@ extension MastodonUISnapshotTests {
|
|||
print("OAuth finish")
|
||||
}
|
||||
|
||||
private func skipKeyboardSwipeInputGuide(app: XCUIApplication) {
|
||||
enum OnboardingPage {
|
||||
case welcome
|
||||
case login(domain: String)
|
||||
case serverRules(domain: String)
|
||||
}
|
||||
|
||||
private func coordinateToOnboarding(app: XCUIApplication, page: OnboardingPage) async throws {
|
||||
// check in Onboarding or not
|
||||
let loginButton = app.buttons["Log In"].firstMatch
|
||||
try await Task.sleep(nanoseconds: .second * 3)
|
||||
let loginButtonExists = loginButton.exists
|
||||
|
||||
// goto Onboarding scene if already sign-in
|
||||
if !loginButtonExists {
|
||||
try await showTitleButtonMenu(app: app)
|
||||
|
||||
let showMenu = app.collectionViews.buttons["Show…"].firstMatch
|
||||
XCTAssert(showMenu.waitForExistence(timeout: 3))
|
||||
showMenu.tap()
|
||||
try await Task.sleep(nanoseconds: .second * 1)
|
||||
|
||||
let welcomeAction = app.collectionViews.buttons["Welcome"].firstMatch
|
||||
XCTAssert(welcomeAction.waitForExistence(timeout: 3))
|
||||
welcomeAction.tap()
|
||||
try await Task.sleep(nanoseconds: .second * 1)
|
||||
}
|
||||
|
||||
func type(domain: String) async throws {
|
||||
// type domain
|
||||
let domainTextField = app.textFields.firstMatch
|
||||
XCTAssert(domainTextField.waitForExistence(timeout: 5))
|
||||
domainTextField.tap()
|
||||
|
||||
// Skip system keyboard swipe input guide
|
||||
try await skipKeyboardSwipeInputGuide(app: app)
|
||||
domainTextField.typeText(domain)
|
||||
XCUIApplication().keyboards.buttons["Done"].firstMatch.tap()
|
||||
}
|
||||
|
||||
switch page {
|
||||
case .welcome:
|
||||
break
|
||||
case .login(let domain):
|
||||
// Tap login button
|
||||
XCTAssert(loginButtonExists)
|
||||
loginButton.tap()
|
||||
// type domain
|
||||
try await type(domain: domain)
|
||||
// add system alert monitor
|
||||
// A. The monitor not works
|
||||
// addUIInterruptionMonitor(withDescription: "Authentication Alert") { alert in
|
||||
// alert.buttons["Continue"].firstMatch.tap()
|
||||
// return true
|
||||
// }
|
||||
// tap next
|
||||
try await selectServerAndContinue(app: app, domain: domain)
|
||||
// wait authentication alert display
|
||||
try await Task.sleep(nanoseconds: .second * 3)
|
||||
// B. Workaround
|
||||
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
|
||||
let continueButton = springboard.buttons["Continue"].firstMatch
|
||||
XCTAssert(continueButton.waitForExistence(timeout: 3))
|
||||
continueButton.tap()
|
||||
case .serverRules(let domain):
|
||||
// Tap sign up button
|
||||
let signUpButton = app.buttons["Get Started"].firstMatch
|
||||
XCTAssert(signUpButton.waitForExistence(timeout: 3))
|
||||
signUpButton.tap()
|
||||
// type domain
|
||||
try await type(domain: domain)
|
||||
// tap next
|
||||
try await selectServerAndContinue(app: app, domain: domain)
|
||||
}
|
||||
}
|
||||
|
||||
private func selectServerAndContinue(app: XCUIApplication, domain: String) async throws {
|
||||
// wait searching
|
||||
try await Task.sleep(nanoseconds: .second * 3)
|
||||
|
||||
// tap server
|
||||
let cell = app.cells.containing(.staticText, identifier: domain).firstMatch
|
||||
XCTAssert(cell.waitForExistence(timeout: 5))
|
||||
cell.tap()
|
||||
|
||||
// tap next button
|
||||
let nextButton = app.buttons.matching(NSPredicate(format: "enabled == true")).matching(identifier: "Next").firstMatch
|
||||
XCTAssert(nextButton.waitForExistence(timeout: 3))
|
||||
nextButton.tap()
|
||||
}
|
||||
|
||||
private func skipKeyboardSwipeInputGuide(app: XCUIApplication) async throws {
|
||||
let swipeInputLabel = app.staticTexts["Speed up your typing by sliding your finger across the letters to compose a word."].firstMatch
|
||||
guard swipeInputLabel.waitForExistence(timeout: 3) else { return }
|
||||
try await Task.sleep(nanoseconds: .second * 3)
|
||||
guard swipeInputLabel.exists else { return }
|
||||
let continueButton = app.buttons["Continue"]
|
||||
continueButton.tap()
|
||||
}
|
||||
}
|
||||
|
||||
extension MastodonUISnapshotTests {
|
||||
func takeSnapshot(name: String) {
|
||||
let snapshot = XCUIScreen.main.screenshot()
|
||||
let attachment = XCTAttachment(
|
||||
uniformTypeIdentifier: "public.png",
|
||||
name: "Screenshot-\(name)-\(UIDevice.current.name).png",
|
||||
payload: snapshot.pngRepresentation,
|
||||
userInfo: nil
|
||||
)
|
||||
attachment.lifetime = .keepAlways
|
||||
add(attachment)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
2
Podfile
2
Podfile
|
@ -16,7 +16,7 @@ target 'Mastodon' do
|
|||
pod 'Sourcery', '~> 1.6.1'
|
||||
|
||||
# DEBUG
|
||||
pod 'FLEX', '~> 4.4.0', :configurations => ['Debug']
|
||||
pod 'FLEX', '~> 4.4.0', :configurations => ['Debug', "Release Snapshot"]
|
||||
|
||||
target 'MastodonTests' do
|
||||
inherit! :search_paths
|
||||
|
|
|
@ -40,6 +40,6 @@ SPEC CHECKSUMS:
|
|||
SwiftGen: 67860cc7c3cfc2ed25b9b74cfd55495fc89f9108
|
||||
"UITextField+Shake": 298ac5a0f239d731bdab999b19b628c956ca0ac3
|
||||
|
||||
PODFILE CHECKSUM: 1426a4b78d8d711a5ae7600b9deea8986ddfdf7d
|
||||
PODFILE CHECKSUM: c471d1f9c923dc63bf8684415c79b85adb2ac36b
|
||||
|
||||
COCOAPODS: 1.11.2
|
||||
|
|
Loading…
Reference in New Issue