Quellcode durchsuchen

Initial UI testing setup

multiple-accounts
Shadowfacts vor 1 Monat
Ursprung
Commit
49f58cf955
Signiert von: Shadowfacts <me@shadowfacts.net> GPG-Schlüssel-ID: 94A5AB95422746E5

+ 6
- 0
.gitmodules Datei anzeigen

@@ -7,3 +7,9 @@
7 7
 [submodule "Gifu"]
8 8
 	path = Gifu
9 9
 	url = git://github.com/kaishin/Gifu.git
10
+[submodule "Embassy"]
11
+	path = Embassy
12
+	url = https://github.com/envoy/Embassy.git
13
+[submodule "Ambassador"]
14
+	path = Ambassador
15
+	url = https://github.com/envoy/Ambassador.git

+ 1
- 0
Ambassador

@@ -0,0 +1 @@
1
+Subproject commit 4fe264af51e0dd7228486c604750909e368241a7

BIN
BlankSlate.xcappdata/AppDataInfo.plist Datei anzeigen


+ 1
- 0
Embassy

@@ -0,0 +1 @@
1
+Subproject commit 189436100c00efbf5fb2653fe7972a9371db0a91

+ 49
- 0
Tusker.xcodeproj/project.pbxproj Datei anzeigen

@@ -114,6 +114,9 @@
114 114
 		D64F80E2215875CC00BEF393 /* XCBActionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64F80E1215875CC00BEF393 /* XCBActionType.swift */; };
115 115
 		D6538945214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6538944214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift */; };
116 116
 		D65A37F321472F300087646E /* SwiftSoup.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6BED16E212663DA00F02DA0 /* SwiftSoup.framework */; };
117
+		D65F613423AEAB6600F3CFD3 /* OnboardingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D65F613323AEAB6600F3CFD3 /* OnboardingTests.swift */; };
118
+		D65F613623AFD65900F3CFD3 /* Ambassador.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D65F613523AFD65900F3CFD3 /* Ambassador.framework */; };
119
+		D65F613823AFD65D00F3CFD3 /* Embassy.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D65F613723AFD65D00F3CFD3 /* Embassy.framework */; };
117 120
 		D663625D2135C74800C9CBA2 /* ConversationMainStatusTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D663625C2135C74800C9CBA2 /* ConversationMainStatusTableViewCell.xib */; };
118 121
 		D663625F2135C75500C9CBA2 /* ConversationMainStatusTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D663625E2135C75500C9CBA2 /* ConversationMainStatusTableViewCell.swift */; };
119 122
 		D663626221360B1900C9CBA2 /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D663626121360B1900C9CBA2 /* Preferences.swift */; };
@@ -391,6 +394,11 @@
391 394
 		D64D0AB02128D9AE005A6F37 /* OnboardingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewController.swift; sourceTree = "<group>"; };
392 395
 		D64F80E1215875CC00BEF393 /* XCBActionType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCBActionType.swift; sourceTree = "<group>"; };
393 396
 		D6538944214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewSwipeActionProvider.swift; sourceTree = "<group>"; };
397
+		D65F612D23AE990C00F3CFD3 /* Embassy.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Embassy.framework; sourceTree = BUILT_PRODUCTS_DIR; };
398
+		D65F613023AE99E000F3CFD3 /* Ambassador.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Ambassador.framework; sourceTree = BUILT_PRODUCTS_DIR; };
399
+		D65F613323AEAB6600F3CFD3 /* OnboardingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingTests.swift; sourceTree = "<group>"; };
400
+		D65F613523AFD65900F3CFD3 /* Ambassador.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Ambassador.framework; sourceTree = BUILT_PRODUCTS_DIR; };
401
+		D65F613723AFD65D00F3CFD3 /* Embassy.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Embassy.framework; sourceTree = BUILT_PRODUCTS_DIR; };
394 402
 		D663625C2135C74800C9CBA2 /* ConversationMainStatusTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ConversationMainStatusTableViewCell.xib; sourceTree = "<group>"; };
395 403
 		D663625E2135C75500C9CBA2 /* ConversationMainStatusTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationMainStatusTableViewCell.swift; sourceTree = "<group>"; };
396 404
 		D663626121360B1900C9CBA2 /* Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = "<group>"; };
@@ -501,6 +509,7 @@
501 509
 		D6F1F84C2193B56E00F5FE67 /* Cache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cache.swift; sourceTree = "<group>"; };
502 510
 		D6F953EB212519E700CF0F2B /* TimelineTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineTableViewController.swift; sourceTree = "<group>"; };
503 511
 		D6F953EF21251A2900CF0F2B /* MastodonController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonController.swift; sourceTree = "<group>"; };
512
+		D6F98BD523AE951F008A4DAC /* Swifter.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Swifter.framework; sourceTree = BUILT_PRODUCTS_DIR; };
504 513
 /* End PBXFileReference section */
505 514
 
506 515
 /* Begin PBXFrameworksBuildPhase section */
@@ -530,6 +539,8 @@
530 539
 			isa = PBXFrameworksBuildPhase;
531 540
 			buildActionMask = 2147483647;
532 541
 			files = (
542
+				D65F613823AFD65D00F3CFD3 /* Embassy.framework in Frameworks */,
543
+				D65F613623AFD65900F3CFD3 /* Ambassador.framework in Frameworks */,
533 544
 				D60A549221ED515800F1F87C /* GMImagePicker.framework in Frameworks */,
534 545
 				D61099C02144B0CC00432DC2 /* Pachyderm.framework in Frameworks */,
535 546
 				D65A37F321472F300087646E /* SwiftSoup.framework in Frameworks */,
@@ -947,6 +958,11 @@
947 958
 		D65A37F221472F300087646E /* Frameworks */ = {
948 959
 			isa = PBXGroup;
949 960
 			children = (
961
+				D65F613723AFD65D00F3CFD3 /* Embassy.framework */,
962
+				D65F613523AFD65900F3CFD3 /* Ambassador.framework */,
963
+				D65F613023AE99E000F3CFD3 /* Ambassador.framework */,
964
+				D65F612D23AE990C00F3CFD3 /* Embassy.framework */,
965
+				D6F98BD523AE951F008A4DAC /* Swifter.framework */,
950 966
 			);
951 967
 			name = Frameworks;
952 968
 			sourceTree = "<group>";
@@ -1259,6 +1275,7 @@
1259 1275
 			isa = PBXGroup;
1260 1276
 			children = (
1261 1277
 				D6D4DDEF212518A200E1C4BB /* TuskerUITests.swift */,
1278
+				D65F613323AEAB6600F3CFD3 /* OnboardingTests.swift */,
1262 1279
 				D6D4DDF1212518A200E1C4BB /* Info.plist */,
1263 1280
 			);
1264 1281
 			path = TuskerUITests;
@@ -1371,6 +1388,7 @@
1371 1388
 				D6D4DDC9212518A000E1C4BB /* Frameworks */,
1372 1389
 				D6D4DDCA212518A000E1C4BB /* Resources */,
1373 1390
 				D6F953E52125197500CF0F2B /* Embed Frameworks */,
1391
+				D65F612C23AE957600F3CFD3 /* Embed debug-only frameworks */,
1374 1392
 			);
1375 1393
 			buildRules = (
1376 1394
 			);
@@ -1415,6 +1433,8 @@
1415 1433
 				D6D4DDED212518A200E1C4BB /* PBXTargetDependency */,
1416 1434
 			);
1417 1435
 			name = TuskerUITests;
1436
+			packageProductDependencies = (
1437
+			);
1418 1438
 			productName = TuskerUITests;
1419 1439
 			productReference = D6D4DDEB212518A200E1C4BB /* TuskerUITests.xctest */;
1420 1440
 			productType = "com.apple.product-type.bundle.ui-testing";
@@ -1472,6 +1492,8 @@
1472 1492
 				ca,
1473 1493
 			);
1474 1494
 			mainGroup = D6D4DDC3212518A000E1C4BB;
1495
+			packageReferences = (
1496
+			);
1475 1497
 			productRefGroup = D6D4DDCD212518A000E1C4BB /* Products */;
1476 1498
 			projectDirPath = "";
1477 1499
 			projectRoot = "";
@@ -1564,6 +1586,31 @@
1564 1586
 		};
1565 1587
 /* End PBXResourcesBuildPhase section */
1566 1588
 
1589
+/* Begin PBXShellScriptBuildPhase section */
1590
+		D65F612C23AE957600F3CFD3 /* Embed debug-only frameworks */ = {
1591
+			isa = PBXShellScriptBuildPhase;
1592
+			buildActionMask = 2147483647;
1593
+			files = (
1594
+			);
1595
+			inputFileListPaths = (
1596
+			);
1597
+			inputPaths = (
1598
+				"${BUILT_PRODUCTS_DIR}/Embassy.framework",
1599
+				"${BUILT_PRODUCTS_DIR}/Ambassador.framework",
1600
+			);
1601
+			name = "Embed debug-only frameworks";
1602
+			outputFileListPaths = (
1603
+			);
1604
+			outputPaths = (
1605
+				"${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/Embassy.framework",
1606
+				"${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/Ambassador.framework",
1607
+			);
1608
+			runOnlyForDeploymentPostprocessing = 0;
1609
+			shellPath = /bin/sh;
1610
+			shellScript = "if [ \"${CONFIGURATION}\" == \"Debug\" ]; then\n    echo \"Embedding ${SCRIPT_INPUT_FILE_0}\"\n    cp -R $SCRIPT_INPUT_FILE_0 $SCRIPT_OUTPUT_FILE_0\n    codesign --force --verbose --sign $EXPANDED_CODE_SIGN_IDENTITY $SCRIPT_OUTPUT_FILE_0\n    \n    echo \"Embedding ${SCRIPT_INPUT_FILE_1}\"\n    cp -R $SCRIPT_INPUT_FILE_1 $SCRIPT_OUTPUT_FILE_1\n    codesign --force --verbose --sign $EXPANDED_CODE_SIGN_IDENTITY $SCRIPT_OUTPUT_FILE_1\nelse\n    echo \"Skipping embedding debug frameworks\"\nfi\n";
1611
+		};
1612
+/* End PBXShellScriptBuildPhase section */
1613
+
1567 1614
 /* Begin PBXSourcesBuildPhase section */
1568 1615
 		D60A548721ED515800F1F87C /* Sources */ = {
1569 1616
 			isa = PBXSourcesBuildPhase;
@@ -1764,6 +1811,7 @@
1764 1811
 			isa = PBXSourcesBuildPhase;
1765 1812
 			buildActionMask = 2147483647;
1766 1813
 			files = (
1814
+				D65F613423AEAB6600F3CFD3 /* OnboardingTests.swift in Sources */,
1767 1815
 				D6D4DDF0212518A200E1C4BB /* TuskerUITests.swift in Sources */,
1768 1816
 			);
1769 1817
 			runOnlyForDeploymentPostprocessing = 0;
@@ -2166,6 +2214,7 @@
2166 2214
 					"$(inherited)",
2167 2215
 					"@executable_path/Frameworks",
2168 2216
 				);
2217
+				OTHER_LDFLAGS = "";
2169 2218
 				PRODUCT_BUNDLE_IDENTIFIER = net.shadowfacts.Tusker;
2170 2219
 				PRODUCT_NAME = "$(TARGET_NAME)";
2171 2220
 				PROVISIONING_PROFILE_SPECIFIER = "";

+ 13
- 14
Tusker.xcodeproj/xcshareddata/xcschemes/Tusker.xcscheme Datei anzeigen

@@ -1,7 +1,7 @@
1 1
 <?xml version="1.0" encoding="UTF-8"?>
2 2
 <Scheme
3 3
    LastUpgradeVersion = "1020"
4
-   version = "1.3">
4
+   version = "1.7">
5 5
    <BuildAction
6 6
       parallelizeBuildables = "YES"
7 7
       buildImplicitDependencies = "YES">
@@ -27,6 +27,15 @@
27 27
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28 28
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29 29
       shouldUseLaunchSchemeArgsEnv = "YES">
30
+      <MacroExpansion>
31
+         <BuildableReference
32
+            BuildableIdentifier = "primary"
33
+            BlueprintIdentifier = "D6D4DDCB212518A000E1C4BB"
34
+            BuildableName = "Tusker.app"
35
+            BlueprintName = "Tusker"
36
+            ReferencedContainer = "container:Tusker.xcodeproj">
37
+         </BuildableReference>
38
+      </MacroExpansion>
30 39
       <Testables>
31 40
          <TestableReference
32 41
             skipped = "NO">
@@ -47,6 +56,9 @@
47 56
                BlueprintName = "TuskerUITests"
48 57
                ReferencedContainer = "container:Tusker.xcodeproj">
49 58
             </BuildableReference>
59
+            <DeviceAppData
60
+               resolvedPath = "../BlankSlate.xcappdata">
61
+            </DeviceAppData>
50 62
          </TestableReference>
51 63
          <TestableReference
52 64
             skipped = "NO">
@@ -59,17 +71,6 @@
59 71
             </BuildableReference>
60 72
          </TestableReference>
61 73
       </Testables>
62
-      <MacroExpansion>
63
-         <BuildableReference
64
-            BuildableIdentifier = "primary"
65
-            BlueprintIdentifier = "D6D4DDCB212518A000E1C4BB"
66
-            BuildableName = "Tusker.app"
67
-            BlueprintName = "Tusker"
68
-            ReferencedContainer = "container:Tusker.xcodeproj">
69
-         </BuildableReference>
70
-      </MacroExpansion>
71
-      <AdditionalOptions>
72
-      </AdditionalOptions>
73 74
    </TestAction>
74 75
    <LaunchAction
75 76
       buildConfiguration = "Debug"
@@ -91,8 +92,6 @@
91 92
             ReferencedContainer = "container:Tusker.xcodeproj">
92 93
          </BuildableReference>
93 94
       </BuildableProductRunnable>
94
-      <AdditionalOptions>
95
-      </AdditionalOptions>
96 95
    </LaunchAction>
97 96
    <ProfileAction
98 97
       buildConfiguration = "Release"

+ 9
- 0
Tusker.xcworkspace/contents.xcworkspacedata Datei anzeigen

@@ -5,6 +5,9 @@
5 5
       location = "container:Tusker.xcodeproj">
6 6
    </FileRef>
7 7
    <FileRef
8
+      location = "group:BlankSlate.xcappdata">
9
+   </FileRef>
10
+   <FileRef
8 11
       location = "group:Cache/Cache.xcodeproj">
9 12
    </FileRef>
10 13
    <FileRef
@@ -13,4 +16,10 @@
13 16
    <FileRef
14 17
       location = "group:Gifu/Gifu.xcodeproj">
15 18
    </FileRef>
19
+   <FileRef
20
+      location = "group:Embassy/Embassy.xcodeproj">
21
+   </FileRef>
22
+   <FileRef
23
+      location = "group:Ambassador/Ambassador.xcodeproj">
24
+   </FileRef>
16 25
 </Workspace>

+ 11
- 0
Tusker/Info.plist Datei anzeigen

@@ -2,6 +2,17 @@
2 2
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3 3
 <plist version="1.0">
4 4
 <dict>
5
+	<key>NSAppTransportSecurity</key>
6
+	<dict>
7
+		<key>NSExceptionDomains</key>
8
+		<dict>
9
+			<key>localhost</key>
10
+			<dict>
11
+				<key>NSExceptionAllowsInsecureHTTPLoads</key>
12
+				<true/>
13
+			</dict>
14
+		</dict>
15
+	</dict>
5 16
 	<key>NSUserActivityTypes</key>
6 17
 	<array>
7 18
 		<string>$(PRODUCT_BUNDLE_IDENTIFIER).activity.show-timeline</string>

+ 9
- 5
Tusker/LocalData.swift Datei anzeigen

@@ -12,7 +12,15 @@ class LocalData {
12 12
     
13 13
     static let shared = LocalData()
14 14
     
15
-    let defaults = UserDefaults()
15
+    let defaults: UserDefaults
16
+    
17
+    private init() {
18
+        if ProcessInfo.processInfo.environment.keys.contains("UI_TESTING") {
19
+            defaults = UserDefaults(suiteName: "\(Bundle.main.bundleIdentifier!).uitesting")!
20
+        } else {
21
+            defaults = UserDefaults()
22
+        }
23
+    }
16 24
     
17 25
     private let onboardingCompleteKey = "onboardingComplete"
18 26
     var onboardingComplete: Bool {
@@ -63,10 +71,6 @@ class LocalData {
63 71
             defaults.set(newValue, forKey: accessTokenKey)
64 72
         }
65 73
     }
66
-    
67
-    private init() {
68
-    }
69
-    
70 74
 }
71 75
 
72 76
 extension Notification.Name {

+ 1
- 8
Tusker/Screens/Onboarding/InstanceSelectorTableViewController.swift Datei anzeigen

@@ -75,14 +75,7 @@ class InstanceSelectorTableViewController: UITableViewController {
75 75
     }
76 76
     
77 77
     private func updateSpecificInstance(domain: String) {
78
-        var components = URLComponents()
79
-        if domain.contains("://") {
80
-            let parts = domain.components(separatedBy: "://")
81
-            components.scheme = parts[0]
82
-            components.host = parts[1]
83
-        } else {
84
-            components.host = domain
85
-        }
78
+        var components = URLComponents(string: domain)!
86 79
         if components.scheme != "https" && components.scheme != "http" {
87 80
             components.scheme = "https"
88 81
         }

+ 5
- 2
Tusker/Views/Instance Cell/InstanceTableViewCell.xib Datei anzeigen

@@ -1,8 +1,8 @@
1 1
 <?xml version="1.0" encoding="UTF-8"?>
2
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14868" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
2
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
3 3
     <device id="retina6_1" orientation="portrait" appearance="light"/>
4 4
     <dependencies>
5
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14824"/>
5
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15703"/>
6 6
         <capability name="Safe area layout guides" minToolsVersion="9.0"/>
7 7
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
8 8
     </dependencies>
@@ -53,6 +53,9 @@
53 53
                                     </stackView>
54 54
                                     <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" text="Instance Description" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aD6-LG-BWG" customClass="ContentLabel" customModule="Tusker" customModuleProvider="target">
55 55
                                         <rect key="frame" x="0.0" y="26.5" width="200" height="20.5"/>
56
+                                        <accessibility key="accessibilityConfiguration">
57
+                                            <accessibilityTraits key="traits" staticText="YES" notEnabled="YES"/>
58
+                                        </accessibility>
56 59
                                         <fontDescription key="fontDescription" type="system" pointSize="17"/>
57 60
                                         <nil key="textColor"/>
58 61
                                         <nil key="highlightedColor"/>

+ 38
- 0
TuskerUITests/OnboardingTests.swift Datei anzeigen

@@ -0,0 +1,38 @@
1
+//
2
+//  OnboardingTests.swift
3
+//  TuskerUITests
4
+//
5
+//  Created by Shadowfacts on 12/21/19.
6
+//  Copyright © 2019 Shadowfacts. All rights reserved.
7
+//
8
+
9
+import XCTest
10
+import Ambassador
11
+
12
+class OnboardingTests: TuskerUITests {
13
+
14
+    override func setUp() {
15
+        super.setUp()
16
+        
17
+        router["/api/v1/instance"] = JSONResponse(handler: { (_) in
18
+            return [
19
+                "description": "An instance description",
20
+                "max_toot_chars": 500,
21
+                "thumbnail": "http://localhost:8080/thumbnail.png",
22
+                "title": "Localhost",
23
+                "uri": "http://localhost:8080",
24
+                "version": "2.7.2",
25
+                "urls": [:]
26
+            ]
27
+        })
28
+    }
29
+    
30
+    func testExample() {
31
+        let searchField = app.searchFields.element
32
+        searchField.tap()
33
+        searchField.typeText("http://localhost:8080")
34
+        XCTAssertTrue(app.staticTexts["localhost"].exists)
35
+        XCTAssertTrue(app.staticTexts["An instance description"].exists)
36
+    }
37
+
38
+}

+ 43
- 15
TuskerUITests/TuskerUITests.swift Datei anzeigen

@@ -7,28 +7,56 @@
7 7
 //
8 8
 
9 9
 import XCTest
10
+import Embassy
11
+import Ambassador
10 12
 
11 13
 class TuskerUITests: XCTestCase {
12
-
14
+    
15
+    var eventLoop: EventLoop!
16
+    var router: Router!
17
+    var server: HTTPServer!
18
+    var eventLoopThreadCondition: NSCondition!
19
+    var eventLoopThread: Thread!
20
+    
21
+    var app: XCUIApplication!
22
+
23
+    private func setupWebServer() {
24
+        eventLoop = try! SelectorEventLoop(selector: try! KqueueSelector())
25
+        router = Router()
26
+        server = DefaultHTTPServer(eventLoop: eventLoop, port: 8080, app: router.app)
27
+        router["/hello"] = JSONResponse(handler: { (_) in
28
+            return ["Hello", "World"]
29
+        })
30
+        try! server.start()
31
+
32
+        eventLoopThreadCondition = NSCondition()
33
+        eventLoopThread = Thread(block: {
34
+            self.eventLoop.runForever()
35
+            self.eventLoopThreadCondition.lock()
36
+            self.eventLoopThreadCondition.signal()
37
+            self.eventLoopThreadCondition.unlock()
38
+        })
39
+        eventLoopThread.start()
40
+    }
41
+    
13 42
     override func setUp() {
14
-        // Put setup code here. This method is called before the invocation of each test method in the class.
15
-
16
-        // In UI tests it is usually best to stop immediately when a failure occurs.
43
+        setupWebServer()
44
+        
17 45
         continueAfterFailure = false
18
-
19
-        // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
20
-        XCUIApplication().launch()
21
-
22
-        // In UI tests it’s 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.
46
+        app = XCUIApplication()
47
+        app.launchEnvironment["UI_TESTING"] = "true"
48
+        app.launch()
23 49
     }
24 50
 
25 51
     override func tearDown() {
26
-        // Put teardown code here. This method is called after the invocation of each test method in the class.
27
-    }
28
-
29
-    func testExample() {
30
-        // Use recording to get started writing UI tests.
31
-        // Use XCTAssert and related functions to verify your tests produce the correct results.
52
+        server.stopAndWait()
53
+        eventLoopThreadCondition.lock()
54
+        eventLoop.stop()
55
+        while eventLoop.running {
56
+            if !eventLoopThreadCondition.wait(until: Date(timeIntervalSinceNow: 10)) {
57
+                fatalError("Join eventLoopThread timeout")
58
+            }
59
+        }
32 60
     }
33 61
 
34 62
 }

Laden…
Abbrechen
Speichern