Skip to content

Commit e272e42

Browse files
Merge pull request #4 from michallaskowski/make-it-work-in-xcuitest
Make it work in xcuitest
2 parents 9608c2b + 6bb433a commit e272e42

File tree

8 files changed

+269
-6
lines changed

8 files changed

+269
-6
lines changed

.github/workflows/continuous-integration-workflow.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,6 @@ jobs:
5757
- name: Boot simulator
5858
run: xcrun simctl boot "iPhone 8"
5959
- name: Tests
60-
run: ./gradlew library:iosTest
60+
run: ./gradlew library:iosTest
61+
- name: UI tests
62+
run: xcodebuild test -project sample-ios/SampleiOS.xcodeproj -scheme SampleiOS -destination "name=iPhone 8" -testPlan UITest

library/src/iOSMain/kotlin/actual.kt

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,27 @@ actual fun Data.asString(): String {
2121
@Suppress("UNCHECKED_CAST")
2222
actual class HttpServer actual constructor() {
2323
private val httpServer = GCDWebServer()
24+
2425
actual fun start(port: Int) {
25-
httpServer.startWithPort(port.toULong(), null)
26+
memScoped {
27+
val errorRef = alloc<ObjCObjectVar<NSError?>>()
28+
val started = httpServer.startWithOptions(
29+
mapOf(
30+
GCDWebServerOption_BindToLocalhost to true,
31+
GCDWebServerOption_AutomaticallySuspendInBackground to false,
32+
GCDWebServerOption_Port to port.toULong()
33+
),
34+
errorRef.ptr
35+
)
36+
37+
if (errorRef.value != null) {
38+
throw RuntimeException("Failed to start GCDWebServer on port $port, reason:" +
39+
errorRef.value!!.localizedDescription)
40+
}
41+
if (!started) {
42+
throw RuntimeException("Failed to start GCDWebServer on port $port")
43+
}
44+
}
2645
}
2746

2847
actual fun stop() {
@@ -55,7 +74,6 @@ actual class HttpServer actual constructor() {
5574
} else {
5675
gcdResponse = GCDWebServerResponse()
5776
gcdResponse.statusCode = response.status.toLong()
58-
gcdResponse
5977
}
6078

6179
response.headers.forEach {

sample-ios/SampleiOS.xcodeproj/project.pbxproj

Lines changed: 146 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,22 @@
1919
C17E09C624AF756700BB0A33 /* sharedMock.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = C17E09C424AF756700BB0A33 /* sharedMock.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
2020
C1C6B0D724AFABEB0062B742 /* mokttp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1C6B0D624AFABEB0062B742 /* mokttp.framework */; };
2121
C1C6B0D824AFABEB0062B742 /* mokttp.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = C1C6B0D624AFABEB0062B742 /* mokttp.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
22+
C1E5C38424BA2AED0050E663 /* HttpStubTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1E5C38324BA2AED0050E663 /* HttpStubTests.swift */; };
23+
C1E5C38B24BA2C4A0050E663 /* mokttp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1C6B0D624AFABEB0062B742 /* mokttp.framework */; };
24+
C1E5C38E24BA35750050E663 /* mokttp.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = C1C6B0D624AFABEB0062B742 /* mokttp.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
25+
C1E5C38F24BA358D0050E663 /* GCDWebServers.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = C17070A7241709EC00A35D8A /* GCDWebServers.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
2226
/* End PBXBuildFile section */
2327

28+
/* Begin PBXContainerItemProxy section */
29+
C1E5C38624BA2AED0050E663 /* PBXContainerItemProxy */ = {
30+
isa = PBXContainerItemProxy;
31+
containerPortal = C141B61D23EF0AAB003AAE22 /* Project object */;
32+
proxyType = 1;
33+
remoteGlobalIDString = C141B62423EF0AAB003AAE22;
34+
remoteInfo = SampleiOS;
35+
};
36+
/* End PBXContainerItemProxy section */
37+
2438
/* Begin PBXCopyFilesBuildPhase section */
2539
C17070A5241709B600A35D8A /* CopyFiles */ = {
2640
isa = PBXCopyFilesBuildPhase;
@@ -34,6 +48,17 @@
3448
);
3549
runOnlyForDeploymentPostprocessing = 0;
3650
};
51+
C1E5C38D24BA356C0050E663 /* CopyFiles */ = {
52+
isa = PBXCopyFilesBuildPhase;
53+
buildActionMask = 2147483647;
54+
dstPath = "";
55+
dstSubfolderSpec = 10;
56+
files = (
57+
C1E5C38F24BA358D0050E663 /* GCDWebServers.framework in CopyFiles */,
58+
C1E5C38E24BA35750050E663 /* mokttp.framework in CopyFiles */,
59+
);
60+
runOnlyForDeploymentPostprocessing = 0;
61+
};
3762
/* End PBXCopyFilesBuildPhase section */
3863

3964
/* Begin PBXFileReference section */
@@ -49,6 +74,10 @@
4974
C17070A92422D74300A35D8A /* ContributorsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContributorsView.swift; sourceTree = "<group>"; };
5075
C17E09C424AF756700BB0A33 /* sharedMock.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = sharedMock.framework; path = "../sample-sharedCode/build/bin/iosX64/debugFramework/sharedMock.framework"; sourceTree = "<group>"; };
5176
C1C6B0D624AFABEB0062B742 /* mokttp.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mokttp.framework; path = ../library/build/bin/iosX64/debugFramework/mokttp.framework; sourceTree = "<group>"; };
77+
C1E5C38124BA2AED0050E663 /* SampleiOSUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SampleiOSUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
78+
C1E5C38324BA2AED0050E663 /* HttpStubTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HttpStubTests.swift; sourceTree = "<group>"; };
79+
C1E5C38524BA2AED0050E663 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
80+
C1E5C38C24BA35390050E663 /* UITest.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = UITest.xctestplan; sourceTree = "<group>"; };
5281
/* End PBXFileReference section */
5382

5483
/* Begin PBXFrameworksBuildPhase section */
@@ -61,13 +90,23 @@
6190
);
6291
runOnlyForDeploymentPostprocessing = 0;
6392
};
93+
C1E5C37E24BA2AED0050E663 /* Frameworks */ = {
94+
isa = PBXFrameworksBuildPhase;
95+
buildActionMask = 2147483647;
96+
files = (
97+
C1E5C38B24BA2C4A0050E663 /* mokttp.framework in Frameworks */,
98+
);
99+
runOnlyForDeploymentPostprocessing = 0;
100+
};
64101
/* End PBXFrameworksBuildPhase section */
65102

66103
/* Begin PBXGroup section */
67104
C141B61C23EF0AAB003AAE22 = {
68105
isa = PBXGroup;
69106
children = (
107+
C1E5C38C24BA35390050E663 /* UITest.xctestplan */,
70108
C141B62723EF0AAB003AAE22 /* SampleiOS */,
109+
C1E5C38224BA2AED0050E663 /* SampleiOSUITests */,
71110
C141B62623EF0AAB003AAE22 /* Products */,
72111
C157091A23EF604F003481FB /* Frameworks */,
73112
);
@@ -77,6 +116,7 @@
77116
isa = PBXGroup;
78117
children = (
79118
C141B62523EF0AAB003AAE22 /* SampleiOS.app */,
119+
C1E5C38124BA2AED0050E663 /* SampleiOSUITests.xctest */,
80120
);
81121
name = Products;
82122
sourceTree = "<group>";
@@ -114,6 +154,15 @@
114154
name = Frameworks;
115155
sourceTree = "<group>";
116156
};
157+
C1E5C38224BA2AED0050E663 /* SampleiOSUITests */ = {
158+
isa = PBXGroup;
159+
children = (
160+
C1E5C38324BA2AED0050E663 /* HttpStubTests.swift */,
161+
C1E5C38524BA2AED0050E663 /* Info.plist */,
162+
);
163+
path = SampleiOSUITests;
164+
sourceTree = "<group>";
165+
};
117166
/* End PBXGroup section */
118167

119168
/* Begin PBXNativeTarget section */
@@ -136,19 +185,42 @@
136185
productReference = C141B62523EF0AAB003AAE22 /* SampleiOS.app */;
137186
productType = "com.apple.product-type.application";
138187
};
188+
C1E5C38024BA2AED0050E663 /* SampleiOSUITests */ = {
189+
isa = PBXNativeTarget;
190+
buildConfigurationList = C1E5C38A24BA2AED0050E663 /* Build configuration list for PBXNativeTarget "SampleiOSUITests" */;
191+
buildPhases = (
192+
C1E5C37D24BA2AED0050E663 /* Sources */,
193+
C1E5C37E24BA2AED0050E663 /* Frameworks */,
194+
C1E5C37F24BA2AED0050E663 /* Resources */,
195+
C1E5C38D24BA356C0050E663 /* CopyFiles */,
196+
);
197+
buildRules = (
198+
);
199+
dependencies = (
200+
C1E5C38724BA2AED0050E663 /* PBXTargetDependency */,
201+
);
202+
name = SampleiOSUITests;
203+
productName = SampleiOSUITests;
204+
productReference = C1E5C38124BA2AED0050E663 /* SampleiOSUITests.xctest */;
205+
productType = "com.apple.product-type.bundle.ui-testing";
206+
};
139207
/* End PBXNativeTarget section */
140208

141209
/* Begin PBXProject section */
142210
C141B61D23EF0AAB003AAE22 /* Project object */ = {
143211
isa = PBXProject;
144212
attributes = {
145-
LastSwiftUpdateCheck = 1130;
213+
LastSwiftUpdateCheck = 1140;
146214
LastUpgradeCheck = 1130;
147215
ORGANIZATIONNAME = "Michal Laskowski";
148216
TargetAttributes = {
149217
C141B62423EF0AAB003AAE22 = {
150218
CreatedOnToolsVersion = 11.3;
151219
};
220+
C1E5C38024BA2AED0050E663 = {
221+
CreatedOnToolsVersion = 11.4;
222+
TestTargetID = C141B62423EF0AAB003AAE22;
223+
};
152224
};
153225
};
154226
buildConfigurationList = C141B62023EF0AAB003AAE22 /* Build configuration list for PBXProject "SampleiOS" */;
@@ -165,6 +237,7 @@
165237
projectRoot = "";
166238
targets = (
167239
C141B62423EF0AAB003AAE22 /* SampleiOS */,
240+
C1E5C38024BA2AED0050E663 /* SampleiOSUITests */,
168241
);
169242
};
170243
/* End PBXProject section */
@@ -180,6 +253,13 @@
180253
);
181254
runOnlyForDeploymentPostprocessing = 0;
182255
};
256+
C1E5C37F24BA2AED0050E663 /* Resources */ = {
257+
isa = PBXResourcesBuildPhase;
258+
buildActionMask = 2147483647;
259+
files = (
260+
);
261+
runOnlyForDeploymentPostprocessing = 0;
262+
};
183263
/* End PBXResourcesBuildPhase section */
184264

185265
/* Begin PBXShellScriptBuildPhase section */
@@ -215,8 +295,24 @@
215295
);
216296
runOnlyForDeploymentPostprocessing = 0;
217297
};
298+
C1E5C37D24BA2AED0050E663 /* Sources */ = {
299+
isa = PBXSourcesBuildPhase;
300+
buildActionMask = 2147483647;
301+
files = (
302+
C1E5C38424BA2AED0050E663 /* HttpStubTests.swift in Sources */,
303+
);
304+
runOnlyForDeploymentPostprocessing = 0;
305+
};
218306
/* End PBXSourcesBuildPhase section */
219307

308+
/* Begin PBXTargetDependency section */
309+
C1E5C38724BA2AED0050E663 /* PBXTargetDependency */ = {
310+
isa = PBXTargetDependency;
311+
target = C141B62423EF0AAB003AAE22 /* SampleiOS */;
312+
targetProxy = C1E5C38624BA2AED0050E663 /* PBXContainerItemProxy */;
313+
};
314+
/* End PBXTargetDependency section */
315+
220316
/* Begin PBXVariantGroup section */
221317
C141B63323EF0AAE003AAE22 /* LaunchScreen.storyboard */ = {
222318
isa = PBXVariantGroup;
@@ -391,6 +487,46 @@
391487
};
392488
name = Release;
393489
};
490+
C1E5C38824BA2AED0050E663 /* Debug */ = {
491+
isa = XCBuildConfiguration;
492+
buildSettings = {
493+
CODE_SIGN_STYLE = Automatic;
494+
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../library/build/bin/iOSX64/debugFramework";
495+
INFOPLIST_FILE = SampleiOSUITests/Info.plist;
496+
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
497+
LD_RUNPATH_SEARCH_PATHS = (
498+
"$(inherited)",
499+
"@executable_path/Frameworks",
500+
"@loader_path/Frameworks",
501+
);
502+
PRODUCT_BUNDLE_IDENTIFIER = dev.michallaskowski.mokttp.SampleiOSUITests;
503+
PRODUCT_NAME = "$(TARGET_NAME)";
504+
SWIFT_VERSION = 5.0;
505+
TARGETED_DEVICE_FAMILY = "1,2";
506+
TEST_TARGET_NAME = SampleiOS;
507+
};
508+
name = Debug;
509+
};
510+
C1E5C38924BA2AED0050E663 /* Release */ = {
511+
isa = XCBuildConfiguration;
512+
buildSettings = {
513+
CODE_SIGN_STYLE = Automatic;
514+
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../library/build/bin/iOSX64/debugFramework";
515+
INFOPLIST_FILE = SampleiOSUITests/Info.plist;
516+
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
517+
LD_RUNPATH_SEARCH_PATHS = (
518+
"$(inherited)",
519+
"@executable_path/Frameworks",
520+
"@loader_path/Frameworks",
521+
);
522+
PRODUCT_BUNDLE_IDENTIFIER = dev.michallaskowski.mokttp.SampleiOSUITests;
523+
PRODUCT_NAME = "$(TARGET_NAME)";
524+
SWIFT_VERSION = 5.0;
525+
TARGETED_DEVICE_FAMILY = "1,2";
526+
TEST_TARGET_NAME = SampleiOS;
527+
};
528+
name = Release;
529+
};
394530
/* End XCBuildConfiguration section */
395531

396532
/* Begin XCConfigurationList section */
@@ -412,6 +548,15 @@
412548
defaultConfigurationIsVisible = 0;
413549
defaultConfigurationName = Release;
414550
};
551+
C1E5C38A24BA2AED0050E663 /* Build configuration list for PBXNativeTarget "SampleiOSUITests" */ = {
552+
isa = XCConfigurationList;
553+
buildConfigurations = (
554+
C1E5C38824BA2AED0050E663 /* Debug */,
555+
C1E5C38924BA2AED0050E663 /* Release */,
556+
);
557+
defaultConfigurationIsVisible = 0;
558+
defaultConfigurationName = Release;
559+
};
415560
/* End XCConfigurationList section */
416561
};
417562
rootObject = C141B61D23EF0AAB003AAE22 /* Project object */;

sample-ios/SampleiOS.xcodeproj/xcshareddata/xcschemes/SampleiOS.xcscheme

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,17 @@
2828
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
2929
shouldUseLaunchSchemeArgsEnv = "YES">
3030
<TestPlans>
31+
<TestPlanReference
32+
reference = "container:UITest.xctestplan"
33+
default = "YES">
34+
</TestPlanReference>
3135
</TestPlans>
3236
<Testables>
3337
<TestableReference
3438
skipped = "NO">
3539
<BuildableReference
3640
BuildableIdentifier = "primary"
37-
BlueprintIdentifier = "C157090E23EF4E37003481FB"
41+
BlueprintIdentifier = "C1E5C38024BA2AED0050E663"
3842
BuildableName = "SampleiOSUITests.xctest"
3943
BlueprintName = "SampleiOSUITests"
4044
ReferencedContainer = "container:SampleiOS.xcodeproj">

sample-ios/SampleiOS/EnvironmentPickerView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ struct EnvironmentPickerView: View {
3333
self.didTap?(self.environment)
3434
}, label: {
3535
Text("Go make that call")
36-
}).accessibility(identifier: "show_list")
36+
}).accessibility(identifier: "contributors")
3737
}
3838
}
3939
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//
2+
// SampleiOSUITests.swift
3+
// SampleiOSUITests
4+
//
5+
// Created by mlaskowski on 11/07/2020.
6+
// Copyright © 2020 Michal Laskowski. All rights reserved.
7+
//
8+
9+
import XCTest
10+
import mokttp
11+
12+
final class SampleiOSUITests: XCTestCase {
13+
14+
private var httpServer: HttpServer!
15+
16+
override func setUpWithError() throws {
17+
continueAfterFailure = false
18+
httpServer = HttpServer()
19+
}
20+
21+
override func tearDownWithError() throws {
22+
httpServer.stop()
23+
}
24+
25+
func testStubs() {
26+
let port: Int32 = Int32.random(in: 1025...10000)
27+
httpServer.router = MockRouter()
28+
httpServer.start(port: port)
29+
// UI tests must launch the application that they test.
30+
let app = XCUIApplication()
31+
app.launchArguments = ["-contributors_url", "http://localhost:\(port)"]
32+
app.launch()
33+
34+
app.segmentedControls.buttons["original"].tap()
35+
app.buttons["contributors"].tap()
36+
37+
XCTAssertTrue(app.staticTexts["xcuitest"].waitForExistence(timeout: 5.0))
38+
}
39+
}
40+
41+
final class MockRouter: Router {
42+
func handleRequest(request: Request) -> Response {
43+
let data = try! JSONSerialization.data(withJSONObject: [
44+
["login": "xcuitest", "contributions": 1]
45+
], options: [])
46+
return Response(status: 200, headers: [:], body: data, contentType: "application/json")
47+
}
48+
}

0 commit comments

Comments
 (0)