Add screenshotting

This commit is contained in:
Lei Nelissen
2022-06-15 11:45:38 +02:00
parent a402757c96
commit c19b9d8920
41 changed files with 736 additions and 192 deletions

View File

@@ -7,7 +7,6 @@
objects = {
/* Begin PBXBuildFile section */
00E356F31AD99517003FC87E /* FintunesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* FintunesTests.m */; };
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
@@ -15,6 +14,8 @@
38B3606A2D29107567360ACF /* libPods-Fintunes-FintunesTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8EBC468D2DE6EB8FF02B72B7 /* libPods-Fintunes-FintunesTests.a */; };
4C04FC6E055249ABB204D3BC /* Inter-VariableFont_slnt,wght.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 4B4A0465FF364579B28CF5D7 /* Inter-VariableFont_slnt,wght.ttf */; };
4FA1B23D2550A94C007A035E /* File.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FA1B23C2550A94C007A035E /* File.swift */; };
AB393FCA2857CC8400773469 /* SnapshotHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB393FC92857CC8400773469 /* SnapshotHelper.swift */; };
AB4A8DFE2857C8DA005A1ED0 /* FintunesUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB4A8DFD2857C8DA005A1ED0 /* FintunesUITests.swift */; };
D7439709FB704B4FE23C538F /* libPods-Fintunes.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 12335560B9820FD5AD98AB8F /* libPods-Fintunes.a */; };
/* End PBXBuildFile section */
@@ -26,12 +27,17 @@
remoteGlobalIDString = 13B07F861A680F5B00A75B9A;
remoteInfo = Fintunes;
};
AB4A8E012857C8DA005A1ED0 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 13B07F861A680F5B00A75B9A;
remoteInfo = Fintunes;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
00E356EE1AD99517003FC87E /* FintunesTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FintunesTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
00E356F21AD99517003FC87E /* FintunesTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FintunesTests.m; sourceTree = "<group>"; };
0973197F4BDB99413C326AD0 /* Pods-Fintunes.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Fintunes.release.xcconfig"; path = "Target Support Files/Pods-Fintunes/Pods-Fintunes.release.xcconfig"; sourceTree = "<group>"; };
12335560B9820FD5AD98AB8F /* libPods-Fintunes.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Fintunes.a"; sourceTree = BUILT_PRODUCTS_DIR; };
13B07F961A680F5B00A75B9A /* Fintunes.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Fintunes.app; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -47,6 +53,9 @@
5370B45C5DDCD952C6569B8D /* Pods-Fintunes.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Fintunes.debug.xcconfig"; path = "Target Support Files/Pods-Fintunes/Pods-Fintunes.debug.xcconfig"; sourceTree = "<group>"; };
7D43C7610851B9666193E3F6 /* libPods-Fintunes-tvOSTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Fintunes-tvOSTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
8EBC468D2DE6EB8FF02B72B7 /* libPods-Fintunes-FintunesTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Fintunes-FintunesTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
AB393FC92857CC8400773469 /* SnapshotHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SnapshotHelper.swift; sourceTree = "<group>"; };
AB4A8DFB2857C8DA005A1ED0 /* FintunesUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FintunesUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
AB4A8DFD2857C8DA005A1ED0 /* FintunesUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FintunesUITests.swift; sourceTree = "<group>"; };
AFAE700A256C6B0ED0D20FE3 /* Pods-Fintunes-FintunesTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Fintunes-FintunesTests.release.xcconfig"; path = "Target Support Files/Pods-Fintunes-FintunesTests/Pods-Fintunes-FintunesTests.release.xcconfig"; sourceTree = "<group>"; };
B20CBCFF11E124551F286B84 /* Pods-Fintunes-FintunesTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Fintunes-FintunesTests.debug.xcconfig"; path = "Target Support Files/Pods-Fintunes-FintunesTests/Pods-Fintunes-FintunesTests.debug.xcconfig"; sourceTree = "<group>"; };
E35451F7979C52C1692C4C9F /* libPods-Fintunes-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Fintunes-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -71,26 +80,16 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
AB4A8DF82857C8DA005A1ED0 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
00E356EF1AD99517003FC87E /* FintunesTests */ = {
isa = PBXGroup;
children = (
00E356F21AD99517003FC87E /* FintunesTests.m */,
00E356F01AD99517003FC87E /* Supporting Files */,
);
path = FintunesTests;
sourceTree = "<group>";
};
00E356F01AD99517003FC87E /* Supporting Files */ = {
isa = PBXGroup;
children = (
00E356F11AD99517003FC87E /* Info.plist */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
13B07FAE1A68108700A75B9A /* Fintunes */ = {
isa = PBXGroup;
children = (
@@ -142,7 +141,7 @@
children = (
13B07FAE1A68108700A75B9A /* Fintunes */,
832341AE1AAA6A7D00B99B32 /* Libraries */,
00E356EF1AD99517003FC87E /* FintunesTests */,
AB4A8DFC2857C8DA005A1ED0 /* FintunesUITests */,
83CBBA001A601CBA00E9B192 /* Products */,
2D16E6871FA4F8E400B85C8A /* Frameworks */,
46001D7383D71A837AAF6E07 /* Pods */,
@@ -158,10 +157,20 @@
children = (
13B07F961A680F5B00A75B9A /* Fintunes.app */,
00E356EE1AD99517003FC87E /* FintunesTests.xctest */,
AB4A8DFB2857C8DA005A1ED0 /* FintunesUITests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
AB4A8DFC2857C8DA005A1ED0 /* FintunesUITests */ = {
isa = PBXGroup;
children = (
AB4A8DFD2857C8DA005A1ED0 /* FintunesUITests.swift */,
AB393FC92857CC8400773469 /* SnapshotHelper.swift */,
);
path = FintunesUITests;
sourceTree = "<group>";
};
CFCEB457E84E4C5195253CD7 /* Resources */ = {
isa = PBXGroup;
children = (
@@ -216,12 +225,31 @@
productReference = 13B07F961A680F5B00A75B9A /* Fintunes.app */;
productType = "com.apple.product-type.application";
};
AB4A8DFA2857C8DA005A1ED0 /* FintunesUITests */ = {
isa = PBXNativeTarget;
buildConfigurationList = AB4A8E052857C8DB005A1ED0 /* Build configuration list for PBXNativeTarget "FintunesUITests" */;
buildPhases = (
AB4A8DF72857C8DA005A1ED0 /* Sources */,
AB4A8DF82857C8DA005A1ED0 /* Frameworks */,
AB4A8DF92857C8DA005A1ED0 /* Resources */,
);
buildRules = (
);
dependencies = (
AB4A8E022857C8DA005A1ED0 /* PBXTargetDependency */,
);
name = FintunesUITests;
productName = FintunesUITests;
productReference = AB4A8DFB2857C8DA005A1ED0 /* FintunesUITests.xctest */;
productType = "com.apple.product-type.bundle.ui-testing";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
83CBB9F71A601CBA00E9B192 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1340;
LastUpgradeCheck = 1130;
TargetAttributes = {
00E356ED1AD99517003FC87E = {
@@ -235,6 +263,12 @@
LastSwiftMigration = 1210;
ProvisioningStyle = Automatic;
};
AB4A8DFA2857C8DA005A1ED0 = {
CreatedOnToolsVersion = 13.4.1;
DevelopmentTeam = 238P3C58WC;
ProvisioningStyle = Automatic;
TestTargetID = 13B07F861A680F5B00A75B9A;
};
};
};
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "Fintunes" */;
@@ -252,6 +286,7 @@
targets = (
13B07F861A680F5B00A75B9A /* Fintunes */,
00E356ED1AD99517003FC87E /* FintunesTests */,
AB4A8DFA2857C8DA005A1ED0 /* FintunesUITests */,
);
};
/* End PBXProject section */
@@ -274,6 +309,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
AB4A8DF92857C8DA005A1ED0 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
@@ -444,7 +486,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
00E356F31AD99517003FC87E /* FintunesTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -458,6 +499,15 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
AB4A8DF72857C8DA005A1ED0 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
AB4A8DFE2857C8DA005A1ED0 /* FintunesUITests.swift in Sources */,
AB393FCA2857CC8400773469 /* SnapshotHelper.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
@@ -466,6 +516,11 @@
target = 13B07F861A680F5B00A75B9A /* Fintunes */;
targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */;
};
AB4A8E022857C8DA005A1ED0 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 13B07F861A680F5B00A75B9A /* Fintunes */;
targetProxy = AB4A8E012857C8DA005A1ED0 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
@@ -547,7 +602,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 39;
CURRENT_PROJECT_VERSION = 6;
DEVELOPMENT_TEAM = 238P3C58WC;
ENABLE_BITCODE = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
@@ -560,6 +615,7 @@
"$(SDKROOT)/usr/lib/swift",
"$(inherited)",
);
MARKETING_VERSION = 2.0.0;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
@@ -583,7 +639,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 39;
CURRENT_PROJECT_VERSION = 6;
DEVELOPMENT_TEAM = 238P3C58WC;
INFOPLIST_FILE = Fintunes/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
@@ -591,6 +647,7 @@
"$(SDKROOT)/usr/lib/swift",
"$(inherited)",
);
MARKETING_VERSION = 2.0.0;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
@@ -725,6 +782,69 @@
};
name = Release;
};
AB4A8E032857C8DB005A1ED0 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 6;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = 238P3C58WC;
GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.5;
MARKETING_VERSION = 1.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = nl.moeilijkedingen.FintunesUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "915c5213-22f6-4f9d-8065-2a06300f9bfb";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_TARGET_NAME = Fintunes;
};
name = Debug;
};
AB4A8E042857C8DB005A1ED0 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 6;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = 238P3C58WC;
GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.5;
MARKETING_VERSION = 1.0;
MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = nl.moeilijkedingen.FintunesUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "915c5213-22f6-4f9d-8065-2a06300f9bfb";
SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_TARGET_NAME = Fintunes;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -755,6 +875,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
AB4A8E052857C8DB005A1ED0 /* Build configuration list for PBXNativeTarget "FintunesUITests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
AB4A8E032857C8DB005A1ED0 /* Debug */,
AB4A8E042857C8DB005A1ED0 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;

View File

@@ -20,6 +20,20 @@
ReferencedContainer = "container:Fintunes.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "AB4A8DFA2857C8DA005A1ED0"
BuildableName = "FintunesUITests.xctest"
BlueprintName = "FintunesUITests"
ReferencedContainer = "container:Fintunes.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
@@ -32,9 +46,9 @@
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00E356ED1AD99517003FC87E"
BuildableName = "FintunesTests.xctest"
BlueprintName = "FintunesTests"
BlueprintIdentifier = "AB4A8DFA2857C8DA005A1ED0"
BuildableName = "FintunesUITests.xctest"
BlueprintName = "FintunesUITests"
ReferencedContainer = "container:Fintunes.xcodeproj">
</BuildableReference>
</TestableReference>

View File

@@ -17,11 +17,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.2.7</string>
<string>2.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>39</string>
<string>6</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>

View File

@@ -1,65 +0,0 @@
#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
#import <React/RCTLog.h>
#import <React/RCTRootView.h>
#define TIMEOUT_SECONDS 600
#define TEXT_TO_LOOK_FOR @"Welcome to React"
@interface FintunesTests : XCTestCase
@end
@implementation FintunesTests
- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test
{
if (test(view)) {
return YES;
}
for (UIView *subview in [view subviews]) {
if ([self findSubviewInView:subview matching:test]) {
return YES;
}
}
return NO;
}
- (void)testRendersWelcomeScreen
{
UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController];
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
BOOL foundElement = NO;
__block NSString *redboxError = nil;
#ifdef DEBUG
RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
if (level >= RCTLogLevelError) {
redboxError = message;
}
});
#endif
while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) {
[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
[[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) {
if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) {
return YES;
}
return NO;
}];
}
#ifdef DEBUG
RCTSetLogFunction(RCTDefaultLogFunction);
#endif
XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
}
@end

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.2.7</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>39</string>
</dict>
</plist>

View File

@@ -0,0 +1,61 @@
//
// FintunesUITests.swift
// FintunesUITests
//
// Created by Lei Nelissen on 13/06/2022.
//
import XCTest
class FintunesUITests: XCTestCase {
override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
// In UI tests it is usually best to stop immediately when a failure occurs.
continueAfterFailure = false
// In UI tests its important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
}
override func tearDownWithError() throws {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
func testExample() throws {
// UI tests must launch the application that they test.
let app = XCUIApplication()
setupSnapshot(app)
app.launch()
// Use XCTAssert and related functions to verify your tests produce the correct results.
snapshot("04RecentAlbums");
app.otherElements["all-albums"].tap();
snapshot("05AlbumsScreen");
app.buttons["search-tab"].tap();
app.textFields["search-input"].tap();
app.textFields["search-input"].typeText("bicep");
snapshot("03SearchScreen");
if app.otherElements["search-result-157a37e93a7aec945f8ea3107abb458a"].waitForExistence(timeout: 5) {
app.otherElements["search-result-157a37e93a7aec945f8ea3107abb458a"].tap();
app.otherElements["search-result-157a37e93a7aec945f8ea3107abb458a"].tap();
snapshot("02AlbumScreen");
}
if app.otherElements["play-album"].waitForExistence(timeout: 5) {
app.otherElements["play-album"].tap();
}
if app.otherElements["open-player-modal"].waitForExistence(timeout: 5) {
app.otherElements["open-player-modal"].tap();
snapshot("01PlayModal");
}
}
// func testLaunchPerformance() throws {
// if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
// // This measures how long it takes to launch your application.
// measure(metrics: [XCTApplicationLaunchMetric()]) {
// XCUIApplication().launch()
// }
// }
// }
}

View File

@@ -0,0 +1,309 @@
//
// SnapshotHelper.swift
// Example
//
// Created by Felix Krause on 10/8/15.
//
// -----------------------------------------------------
// IMPORTANT: When modifying this file, make sure to
// increment the version number at the very
// bottom of the file to notify users about
// the new SnapshotHelper.swift
// -----------------------------------------------------
import Foundation
import XCTest
var deviceLanguage = ""
var locale = ""
func setupSnapshot(_ app: XCUIApplication, waitForAnimations: Bool = true) {
Snapshot.setupSnapshot(app, waitForAnimations: waitForAnimations)
}
func snapshot(_ name: String, waitForLoadingIndicator: Bool) {
if waitForLoadingIndicator {
Snapshot.snapshot(name)
} else {
Snapshot.snapshot(name, timeWaitingForIdle: 0)
}
}
/// - Parameters:
/// - name: The name of the snapshot
/// - timeout: Amount of seconds to wait until the network loading indicator disappears. Pass `0` if you don't want to wait.
func snapshot(_ name: String, timeWaitingForIdle timeout: TimeInterval = 20) {
Snapshot.snapshot(name, timeWaitingForIdle: timeout)
}
enum SnapshotError: Error, CustomDebugStringConvertible {
case cannotFindSimulatorHomeDirectory
case cannotRunOnPhysicalDevice
var debugDescription: String {
switch self {
case .cannotFindSimulatorHomeDirectory:
return "Couldn't find simulator home location. Please, check SIMULATOR_HOST_HOME env variable."
case .cannotRunOnPhysicalDevice:
return "Can't use Snapshot on a physical device."
}
}
}
@objcMembers
open class Snapshot: NSObject {
static var app: XCUIApplication?
static var waitForAnimations = true
static var cacheDirectory: URL?
static var screenshotsDirectory: URL? {
return cacheDirectory?.appendingPathComponent("screenshots", isDirectory: true)
}
open class func setupSnapshot(_ app: XCUIApplication, waitForAnimations: Bool = true) {
Snapshot.app = app
Snapshot.waitForAnimations = waitForAnimations
do {
let cacheDir = try getCacheDirectory()
Snapshot.cacheDirectory = cacheDir
setLanguage(app)
setLocale(app)
setLaunchArguments(app)
} catch let error {
NSLog(error.localizedDescription)
}
}
class func setLanguage(_ app: XCUIApplication) {
guard let cacheDirectory = self.cacheDirectory else {
NSLog("CacheDirectory is not set - probably running on a physical device?")
return
}
let path = cacheDirectory.appendingPathComponent("language.txt")
do {
let trimCharacterSet = CharacterSet.whitespacesAndNewlines
deviceLanguage = try String(contentsOf: path, encoding: .utf8).trimmingCharacters(in: trimCharacterSet)
app.launchArguments += ["-AppleLanguages", "(\(deviceLanguage))"]
} catch {
NSLog("Couldn't detect/set language...")
}
}
class func setLocale(_ app: XCUIApplication) {
guard let cacheDirectory = self.cacheDirectory else {
NSLog("CacheDirectory is not set - probably running on a physical device?")
return
}
let path = cacheDirectory.appendingPathComponent("locale.txt")
do {
let trimCharacterSet = CharacterSet.whitespacesAndNewlines
locale = try String(contentsOf: path, encoding: .utf8).trimmingCharacters(in: trimCharacterSet)
} catch {
NSLog("Couldn't detect/set locale...")
}
if locale.isEmpty && !deviceLanguage.isEmpty {
locale = Locale(identifier: deviceLanguage).identifier
}
if !locale.isEmpty {
app.launchArguments += ["-AppleLocale", "\"\(locale)\""]
}
}
class func setLaunchArguments(_ app: XCUIApplication) {
guard let cacheDirectory = self.cacheDirectory else {
NSLog("CacheDirectory is not set - probably running on a physical device?")
return
}
let path = cacheDirectory.appendingPathComponent("snapshot-launch_arguments.txt")
app.launchArguments += ["-FASTLANE_SNAPSHOT", "YES", "-ui_testing"]
do {
let launchArguments = try String(contentsOf: path, encoding: String.Encoding.utf8)
let regex = try NSRegularExpression(pattern: "(\\\".+?\\\"|\\S+)", options: [])
let matches = regex.matches(in: launchArguments, options: [], range: NSRange(location: 0, length: launchArguments.count))
let results = matches.map { result -> String in
(launchArguments as NSString).substring(with: result.range)
}
app.launchArguments += results
} catch {
NSLog("Couldn't detect/set launch_arguments...")
}
}
open class func snapshot(_ name: String, timeWaitingForIdle timeout: TimeInterval = 20) {
if timeout > 0 {
waitForLoadingIndicatorToDisappear(within: timeout)
}
NSLog("snapshot: \(name)") // more information about this, check out https://docs.fastlane.tools/actions/snapshot/#how-does-it-work
if Snapshot.waitForAnimations {
sleep(1) // Waiting for the animation to be finished (kind of)
}
#if os(OSX)
guard let app = self.app else {
NSLog("XCUIApplication is not set. Please call setupSnapshot(app) before snapshot().")
return
}
app.typeKey(XCUIKeyboardKeySecondaryFn, modifierFlags: [])
#else
guard self.app != nil else {
NSLog("XCUIApplication is not set. Please call setupSnapshot(app) before snapshot().")
return
}
let screenshot = XCUIScreen.main.screenshot()
#if os(iOS) && !targetEnvironment(macCatalyst)
let image = XCUIDevice.shared.orientation.isLandscape ? fixLandscapeOrientation(image: screenshot.image) : screenshot.image
#else
let image = screenshot.image
#endif
guard var simulator = ProcessInfo().environment["SIMULATOR_DEVICE_NAME"], let screenshotsDir = screenshotsDirectory else { return }
do {
// The simulator name contains "Clone X of " inside the screenshot file when running parallelized UI Tests on concurrent devices
let regex = try NSRegularExpression(pattern: "Clone [0-9]+ of ")
let range = NSRange(location: 0, length: simulator.count)
simulator = regex.stringByReplacingMatches(in: simulator, range: range, withTemplate: "")
let path = screenshotsDir.appendingPathComponent("\(simulator)-\(name).png")
#if swift(<5.0)
UIImagePNGRepresentation(image)?.write(to: path, options: .atomic)
#else
try image.pngData()?.write(to: path, options: .atomic)
#endif
} catch let error {
NSLog("Problem writing screenshot: \(name) to \(screenshotsDir)/\(simulator)-\(name).png")
NSLog(error.localizedDescription)
}
#endif
}
class func fixLandscapeOrientation(image: UIImage) -> UIImage {
#if os(watchOS)
return image
#else
if #available(iOS 10.0, *) {
let format = UIGraphicsImageRendererFormat()
format.scale = image.scale
let renderer = UIGraphicsImageRenderer(size: image.size, format: format)
return renderer.image { context in
image.draw(in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
}
} else {
return image
}
#endif
}
class func waitForLoadingIndicatorToDisappear(within timeout: TimeInterval) {
#if os(tvOS)
return
#endif
guard let app = self.app else {
NSLog("XCUIApplication is not set. Please call setupSnapshot(app) before snapshot().")
return
}
let networkLoadingIndicator = app.otherElements.deviceStatusBars.networkLoadingIndicators.element
let networkLoadingIndicatorDisappeared = XCTNSPredicateExpectation(predicate: NSPredicate(format: "exists == false"), object: networkLoadingIndicator)
_ = XCTWaiter.wait(for: [networkLoadingIndicatorDisappeared], timeout: timeout)
}
class func getCacheDirectory() throws -> URL {
let cachePath = "Library/Caches/tools.fastlane"
// on OSX config is stored in /Users/<username>/Library
// and on iOS/tvOS/WatchOS it's in simulator's home dir
#if os(OSX)
let homeDir = URL(fileURLWithPath: NSHomeDirectory())
return homeDir.appendingPathComponent(cachePath)
#elseif arch(i386) || arch(x86_64) || arch(arm64)
guard let simulatorHostHome = ProcessInfo().environment["SIMULATOR_HOST_HOME"] else {
throw SnapshotError.cannotFindSimulatorHomeDirectory
}
let homeDir = URL(fileURLWithPath: simulatorHostHome)
return homeDir.appendingPathComponent(cachePath)
#else
throw SnapshotError.cannotRunOnPhysicalDevice
#endif
}
}
private extension XCUIElementAttributes {
var isNetworkLoadingIndicator: Bool {
if hasAllowListedIdentifier { return false }
let hasOldLoadingIndicatorSize = frame.size == CGSize(width: 10, height: 20)
let hasNewLoadingIndicatorSize = frame.size.width.isBetween(46, and: 47) && frame.size.height.isBetween(2, and: 3)
return hasOldLoadingIndicatorSize || hasNewLoadingIndicatorSize
}
var hasAllowListedIdentifier: Bool {
let allowListedIdentifiers = ["GeofenceLocationTrackingOn", "StandardLocationTrackingOn"]
return allowListedIdentifiers.contains(identifier)
}
func isStatusBar(_ deviceWidth: CGFloat) -> Bool {
if elementType == .statusBar { return true }
guard frame.origin == .zero else { return false }
let oldStatusBarSize = CGSize(width: deviceWidth, height: 20)
let newStatusBarSize = CGSize(width: deviceWidth, height: 44)
return [oldStatusBarSize, newStatusBarSize].contains(frame.size)
}
}
private extension XCUIElementQuery {
var networkLoadingIndicators: XCUIElementQuery {
let isNetworkLoadingIndicator = NSPredicate { (evaluatedObject, _) in
guard let element = evaluatedObject as? XCUIElementAttributes else { return false }
return element.isNetworkLoadingIndicator
}
return self.containing(isNetworkLoadingIndicator)
}
var deviceStatusBars: XCUIElementQuery {
guard let app = Snapshot.app else {
fatalError("XCUIApplication is not set. Please call setupSnapshot(app) before snapshot().")
}
let deviceWidth = app.windows.firstMatch.frame.width
let isStatusBar = NSPredicate { (evaluatedObject, _) in
guard let element = evaluatedObject as? XCUIElementAttributes else { return false }
return element.isStatusBar(deviceWidth)
}
return self.containing(isStatusBar)
}
}
private extension CGFloat {
func isBetween(_ numberA: CGFloat, and numberB: CGFloat) -> Bool {
return numberA...numberB ~= self
}
}
// Please don't remove the lines below
// They are used to detect outdated configuration files
// SnapshotHelperVersion [1.28]