Skip to content

Commit 8c75a65

Browse files
[CI] Make CI great again (#521)
1 parent 6df7a70 commit 8c75a65

18 files changed

+144
-55
lines changed

.github/workflows/cron-checks.yml

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ jobs:
2626
run: bundle exec fastlane build_test_app_and_frameworks
2727
timeout-minutes: 60
2828
env:
29-
XCODE_VERSION: "14.3.1"
30-
- uses: actions/upload-artifact@v3
29+
XCODE_VERSION: "15.2" # Should match the minimum version in dependent jobs
30+
- uses: actions/upload-artifact@v4
3131
if: success()
3232
with:
3333
name: cache-derived-data
@@ -42,13 +42,13 @@ jobs:
4242
strategy:
4343
matrix:
4444
include:
45-
- ios: 17.4
45+
- ios: 17.2
4646
xcode: 15.2
4747
os: macos-14
4848
device: "iPhone 15 Pro"
4949
setup_runtime: false
5050
- ios: 16.4
51-
xcode: 14.3.1
51+
xcode: 15.2
5252
os: macos-14
5353
device: "iPhone 14 Pro Max"
5454
setup_runtime: false
@@ -61,14 +61,15 @@ jobs:
6161
XCODE_VERSION: ${{ matrix.xcode }}
6262
steps:
6363
- uses: actions/[email protected]
64-
- uses: actions/download-artifact@v3
64+
- uses: actions/download-artifact@v4
6565
with:
6666
name: cache-derived-data
6767
path: derived_data/Build/
6868
- uses: ./.github/actions/bootstrap
6969
env:
7070
INSTALL_ALLURE: true
7171
INSTALL_YEETD: true
72+
SKIP_MINT_BOOTSTRAP: true
7273
- name: Cache iOS Simulator Runtime
7374
uses: actions/cache@v4
7475
id: runtime-cache
@@ -105,13 +106,14 @@ jobs:
105106
run: |
106107
brew install chargepoint/xcparse/xcparse
107108
xcparse logs fastlane/test_output/StreamChatSwiftUITestsApp.xcresult fastlane/test_output/logs/
108-
- uses: actions/upload-artifact@v3
109+
- uses: actions/upload-artifact@v4
109110
if: failure()
110111
with:
111112
name: Test Data E2E (iOS ${{ matrix.ios }})
112113
path: |
113114
fastlane/recordings
114115
fastlane/sinatra_log.txt
116+
fastlane/test_output/report.junit
115117
fastlane/test_output/logs/*/Diagnostics/**/*.txt
116118
fastlane/test_output/logs/*/Diagnostics/simctl_diagnostics/DiagnosticReports/*
117119
@@ -120,12 +122,10 @@ jobs:
120122
strategy:
121123
matrix:
122124
include:
123-
- xcode: 15.2
125+
- xcode: 15.4
124126
os: macos-14
125-
- xcode: 14.3.1
127+
- xcode: 15.0.1
126128
os: macos-14
127-
- xcode: 14.2
128-
os: macos-12
129129
fail-fast: false
130130
runs-on: ${{ matrix.os }}
131131
steps:
@@ -175,9 +175,9 @@ jobs:
175175

176176
automated-code-review:
177177
name: Automated Code Review
178-
runs-on: macos-12
178+
runs-on: macos-13
179179
env:
180-
XCODE_VERSION: "14.0.1"
180+
XCODE_VERSION: "15.0.1"
181181
steps:
182182
- uses: actions/[email protected]
183183
- uses: ./.github/actions/bootstrap

.github/workflows/smoke-checks.yml

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ jobs:
3333
- name: Build
3434
run: bundle exec fastlane build_test_app_and_frameworks
3535
timeout-minutes: 60
36-
- uses: actions/upload-artifact@v3
36+
env:
37+
XCODE_VERSION: "15.2" # Should match the minimum version in dependent jobs
38+
- uses: actions/upload-artifact@v4
3739
if: success()
3840
with:
3941
name: cache-derived-data
@@ -48,7 +50,7 @@ jobs:
4850
needs: build-test-app-and-frameworks
4951
steps:
5052
- uses: actions/[email protected]
51-
- uses: actions/download-artifact@v3
53+
- uses: actions/download-artifact@v4
5254
with:
5355
name: cache-derived-data
5456
path: derived_data/Build/
@@ -90,7 +92,7 @@ jobs:
9092
brew install chargepoint/xcparse/xcparse
9193
xcparse logs fastlane/test_output/StreamChatSwiftUI.xcresult fastlane/test_output/logs/
9294
xcparse screenshots fastlane/test_output/StreamChatSwiftUI.xcresult fastlane/test_output/snapshots --test
93-
- uses: actions/upload-artifact@v3
95+
- uses: actions/upload-artifact@v4
9496
if: failure()
9597
with:
9698
name: Test Data UI
@@ -116,17 +118,21 @@ jobs:
116118
fail-fast: false
117119
steps:
118120
- uses: actions/[email protected]
119-
- uses: actions/download-artifact@v3
121+
- uses: actions/download-artifact@v4
120122
with:
121123
name: cache-derived-data
122124
path: derived_data/Build/
123125
- uses: ./.github/actions/bootstrap
124126
env:
125127
INSTALL_ALLURE: true
126128
INSTALL_YEETD: true
129+
SKIP_MINT_BOOTSTRAP: true
127130
- name: Run UI Tests (Debug)
128131
run: bundle exec fastlane test_e2e_mock device:"${{ env.IOS_SIMULATOR_DEVICE }}" batch:'${{ matrix.batch }}' test_without_building:true
132+
timeout-minutes: 100
129133
env:
134+
XCODE_VERSION: "15.2" # the most stable pair of Xcode
135+
IOS_SIMULATOR_DEVICE: "iPhone 15 Pro (17.2)" # and iOS
130136
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
131137
GITHUB_PR_NUM: ${{ github.event.number }}
132138
MATRIX_SIZE: ${{ strategy.job-total }}
@@ -146,13 +152,14 @@ jobs:
146152
run: |
147153
brew install chargepoint/xcparse/xcparse
148154
xcparse logs fastlane/test_output/StreamChatSwiftUITestsApp.xcresult fastlane/test_output/logs/
149-
- uses: actions/upload-artifact@v3
155+
- uses: actions/upload-artifact@v4
150156
if: failure()
151157
with:
152-
name: Test Data E2E
158+
name: Test Data E2E ${{ matrix.batch }}
153159
path: |
154160
fastlane/recordings
155161
fastlane/sinatra_log.txt
162+
fastlane/test_output/report.junit
156163
fastlane/test_output/logs/*/Diagnostics/**/*.txt
157164
fastlane/test_output/logs/*/Diagnostics/simctl_diagnostics/DiagnosticReports/*
158165
@@ -182,7 +189,7 @@ jobs:
182189
if: ${{ github.event_name != 'push' && github.event.inputs.snapshots != 'true' }}
183190
steps:
184191
- uses: actions/[email protected]
185-
- uses: actions/download-artifact@v3
192+
- uses: actions/download-artifact@v4
186193
with:
187194
name: cache-derived-data
188195
path: derived_data/Build/

Scripts/bootstrap.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,10 @@ chmod +x ./hooks/git-format-staged
4040
puts "Install brew dependencies"
4141
brew bundle -d
4242

43-
puts "Bootstrap Mint dependencies"
44-
mint bootstrap --link
43+
if [ "${SKIP_MINT_BOOTSTRAP:-}" != true ]; then
44+
puts "Bootstrap Mint dependencies"
45+
mint bootstrap --link
46+
fi
4547

4648
if [[ ${INSTALL_ALLURE-default} == true ]]; then
4749
puts "Install allurectl"

StreamChatSwiftUITestsAppTests/Pages/MessageListPage.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,10 @@ class MessageListPage {
192192
static func giphyLabel(in messageCell: XCUIElement) -> XCUIElement {
193193
messageCell.staticTexts["GiphyAttachmentView"]
194194
}
195+
196+
static func actionButtons() -> XCUIElementQuery {
197+
app.buttons.matching(NSPredicate(format: "identifier LIKE 'GiphyAttachmentView'"))
198+
}
195199

196200
private static func attachmentActionButton(in messageCell: XCUIElement, label: String) -> XCUIElement {
197201
messageCell.buttons.matching(NSPredicate(

StreamChatSwiftUITestsAppTests/Robots/UserRobot+Asserts.swift

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -442,22 +442,32 @@ extension UserRobot {
442442
XCTAssertTrue(errorButton.exists, "There is no error icon", file: file, line: line)
443443
return self
444444
}
445-
445+
446446
@discardableResult
447-
func assertMessageDeliveryStatus(
447+
func waitForMessageDeliveryStatus(
448448
_ deliveryStatus: MessageDeliveryStatus?,
449449
at messageCellIndex: Int? = nil,
450450
file: StaticString = #filePath,
451451
line: UInt = #line
452-
) -> Self {
452+
) -> Bool {
453453
let messageCell = messageCell(withIndex: messageCellIndex, file: file, line: line)
454454
let checkmark = attributes.statusCheckmark(for: deliveryStatus, in: messageCell)
455455
if deliveryStatus == .failed || deliveryStatus == nil {
456-
XCTAssertFalse(checkmark.exists, "Checkmark is visible", file: file, line: line)
456+
return !checkmark.exists
457457
} else {
458-
XCTAssertTrue(checkmark.wait(timeout: 10).exists, "Checkmark is not visible", file: file, line: line)
458+
return checkmark.wait(timeout: 10).exists
459459
}
460+
}
460461

462+
@discardableResult
463+
func assertMessageDeliveryStatus(
464+
_ deliveryStatus: MessageDeliveryStatus?,
465+
at messageCellIndex: Int? = nil,
466+
file: StaticString = #filePath,
467+
line: UInt = #line
468+
) -> Self {
469+
let success = waitForMessageDeliveryStatus(deliveryStatus, at: messageCellIndex, file: file, line: line)
470+
XCTAssertTrue(success)
461471
return self
462472
}
463473

@@ -705,7 +715,6 @@ extension UserRobot {
705715
let quotedMessage = attributes.quotedText(quotedText, in: messageCell).wait()
706716
XCTAssertTrue(quotedMessage.exists, "Quoted message was not showed", file: file, line: line)
707717
XCTAssertFalse(quotedMessage.isEnabled, "Quoted message should be disabled", file: file, line: line)
708-
XCTAssertTrue(quotedMessage.isHittable, "Quoted message is not visible", file: file, line: line)
709718
return self
710719
}
711720
}

StreamChatSwiftUITestsAppTests/Robots/UserRobot.swift

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,33 +29,34 @@ final class UserRobot: Robot {
2929
ChannelListPage.userAvatar.safeTap()
3030
return self
3131
}
32-
32+
3333
@discardableResult
34-
func openChannel(channelCellIndex: Int = 0) -> Self {
35-
let minExpectedCount = channelCellIndex + 1
36-
let cells = ChannelListPage.cells.waitCount(minExpectedCount)
34+
func waitForChannelListToLoad() -> Self {
35+
let timeout = 15.0
36+
let cells = ChannelListPage.cells.waitCount(1, timeout: timeout)
3737

3838
// TODO: CIS-1737
3939
if !cells.firstMatch.exists {
4040
for _ in 0...10 {
41-
server.stop()
4241
app.terminate()
43-
_ = server.start(port: in_port_t(MockServerConfiguration.port))
42+
server.stop()
43+
_ = server.start(port: UInt16(MockServerConfiguration.port))
4444
sleep(1)
4545
app.launch()
4646
login()
47-
cells.waitCount(minExpectedCount)
47+
cells.waitCount(1, timeout: timeout)
4848
if cells.firstMatch.exists { break }
4949
}
5050
}
5151

52-
XCTAssertGreaterThanOrEqual(
53-
cells.count,
54-
minExpectedCount,
55-
"Channel cell is not found at index #\(channelCellIndex)"
56-
)
57-
58-
cells.allElementsBoundByIndex[channelCellIndex].safeTap()
52+
XCTAssertGreaterThanOrEqual(cells.count, 1, "Channel list has not been loaded")
53+
return self
54+
}
55+
56+
@discardableResult
57+
func openChannel(channelCellIndex: Int = 0) -> Self {
58+
waitForChannelListToLoad()
59+
ChannelListPage.cells.allElementsBoundByIndex[channelCellIndex].waitForHitPoint().safeTap()
5960
return self
6061
}
6162
}
@@ -362,6 +363,7 @@ extension UserRobot {
362363
sendMessage(text, waitForAppearance: false)
363364
}
364365
if send { tapOnSendGiphyButton() }
366+
MessageListPage.Attributes.actionButtons().firstMatch.wait()
365367
return self
366368
}
367369

StreamChatSwiftUITestsAppTests/Tests/Attachments_Tests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ final class Attachments_Tests: StreamTestCase {
99
override func setUpWithError() throws {
1010
try super.setUpWithError()
1111
addTags([.coreFeatures])
12+
assertMockServer()
1213
}
1314

1415
func test_uploadImage() throws {

StreamChatSwiftUITestsAppTests/Tests/Base TestCase/StreamTestCase.swift

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class StreamTestCase: XCTestCase {
1414
var backendRobot: BackendRobot!
1515
var participantRobot: ParticipantRobot!
1616
var server: StreamMockServer!
17+
var mockServerCrashed = false
1718
var recordVideo = false
1819

1920
override func setUpWithError() throws {
@@ -35,7 +36,6 @@ class StreamTestCase: XCTestCase {
3536
stopVideo()
3637
app.terminate()
3738
server.stop()
38-
server = nil
3939
backendRobot.delayServerResponse(byTimeInterval: 0.0)
4040

4141
try super.tearDownWithError()
@@ -45,6 +45,10 @@ class StreamTestCase: XCTestCase {
4545
}
4646

4747
extension StreamTestCase {
48+
49+
func assertMockServer() {
50+
XCTAssertFalse(mockServerCrashed, "Mock server failed on start")
51+
}
4852

4953
private func useMockServer() {
5054
// Leverage web socket server
@@ -79,10 +83,17 @@ extension StreamTestCase {
7983
private func startMockServer() {
8084
server = StreamMockServer()
8185
server.configure()
82-
let result = server.start(port: in_port_t(MockServerConfiguration.port))
83-
if !result {
84-
XCTFail("Mock server failed on start")
86+
87+
for _ in 0...3 {
88+
let serverHasStarted = server.start(port: UInt16(MockServerConfiguration.port))
89+
if serverHasStarted {
90+
return
91+
}
92+
server.stop()
93+
MockServerConfiguration.port = Int.random(in: 61000..<62000)
8594
}
95+
96+
mockServerCrashed = true
8697
}
8798

8899
private func startVideo() {

StreamChatSwiftUITestsAppTests/Tests/ChannelList_Tests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ final class ChannelList_Tests: StreamTestCase {
1111
override func setUpWithError() throws {
1212
try super.setUpWithError()
1313
addTags([.coreFeatures])
14+
assertMockServer()
1415
}
1516

1617
func test_newMessageShownInChannelPreview_whenComingBackFromChannel() {

StreamChatSwiftUITestsAppTests/Tests/Ephemeral_Messages_Tests.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
import XCTest
66

77
final class Ephemeral_Messages_Tests: StreamTestCase {
8+
9+
override func setUpWithError() throws {
10+
try super.setUpWithError()
11+
assertMockServer()
12+
}
813

914
func test_userObservesAnimatedGiphy_whenUserAddsGiphyMessage() throws {
1015
linkToScenario(withId: 435)

0 commit comments

Comments
 (0)