Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration test improvements #3330

Merged
merged 11 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ jobs:
INTEGRATION_TESTS_USERNAME: ${{ secrets.INTEGRATION_TESTS_USERNAME }}
INTEGRATION_TESTS_PASSWORD: ${{ secrets.INTEGRATION_TESTS_PASSWORD }}

- name: Check logs are set to the `trace` level
run: (grep ' TRACE ' /Users/Shared -qR)

- name: Check logs don't contain private messages
run: (! grep 'Go down in flames' /Users/Shared -qR)
stefanceriu marked this conversation as resolved.
Show resolved Hide resolved

- name: Zip results # for faster upload
if: failure()
working-directory: fastlane/test_output
Expand Down
12 changes: 8 additions & 4 deletions ElementX.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@
454311EAC17D778E19F46592 /* NotificationPermissionsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91868EB98818044E6FEBE532 /* NotificationPermissionsScreenCoordinator.swift */; };
454F8DDC4442C0DE54094902 /* LABiometryType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3F219838588C62198E726E3 /* LABiometryType.swift */; };
4557192F5B15A8D9BB920232 /* AdvancedSettingsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E492690C8B27A892C194CC4 /* AdvancedSettingsScreenCoordinator.swift */; };
45D6DC594816288983627484 /* UITestsScreenIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CEBE5EA91E8691EDF364EC2 /* UITestsScreenIdentifier.swift */; };
46562110EE202E580A5FFD9C /* RoomScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93CF7B19FFCF8EFBE0A8696A /* RoomScreenViewModelTests.swift */; };
4681820102DAC8BA586357D4 /* VoiceMessageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB8D7926A5684E18196B538 /* VoiceMessageCache.swift */; };
46A183C6125A669AEB005699 /* UserProfileScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F134D2D91DFF732FB75B2CB7 /* UserProfileScreenViewModelProtocol.swift */; };
Expand Down Expand Up @@ -456,6 +457,7 @@
663E198678778F7426A9B27D /* Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9FAFE1C2149E6AC8156ED2B /* Collection.swift */; };
67160204A8D362BB7D4AD259 /* Search.swift in Sources */ = {isa = PBXBuildFile; fileRef = 693E16574C6F7F9FA1015A8C /* Search.swift */; };
6786C4B0936AC84D993B20BF /* NotificationSettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5F06F2F09B2EDD067DC2174 /* NotificationSettingsScreen.swift */; };
6793E75E3EBE48EBB8F857AF /* ProcessInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077B01C13BBA2996272C5FB5 /* ProcessInfo.swift */; };
67C05C50AD734283374605E3 /* MatrixEntityRegex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AD1A853D605C2146B0DC028 /* MatrixEntityRegex.swift */; };
67D6E0700A9C1E676F6231F8 /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = AD544C0FA48DFFB080920061 /* Collections */; };
67E9926C4572C54F59FCA91A /* AuthenticationFlowCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9B069D7772DDF6513E0F1B8 /* AuthenticationFlowCoordinator.swift */; };
Expand Down Expand Up @@ -523,6 +525,7 @@
7640A4B412CACF15D143CCD4 /* Strings+SAS.swift in Sources */ = {isa = PBXBuildFile; fileRef = B172057567E049007A5C4D92 /* Strings+SAS.swift */; };
767D366C40F1311CFA333763 /* PillContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86376BEE425704AEE197CA54 /* PillContext.swift */; };
7691233E3572A9173FD96CB3 /* SecureBackupKeyBackupScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E88534A39781D76487D59DF /* SecureBackupKeyBackupScreenViewModelTests.swift */; };
76C874243A8C440D6CF7B344 /* ProcessInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077B01C13BBA2996272C5FB5 /* ProcessInfo.swift */; };
7708976CEE6AFB5CFAEFBA68 /* PillTextAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CF1EE0AA78470C674554262 /* PillTextAttachment.swift */; };
7756C4E90CABE6F14F7920A0 /* BugReportUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6FEA87EA3752203065ECE27 /* BugReportUITests.swift */; };
77574A519A4E484880053EAD /* IdentityConfirmationScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FDF541AE914059942B575B4 /* IdentityConfirmationScreenModels.swift */; };
Expand Down Expand Up @@ -1126,7 +1129,6 @@
FCDA202B246F75BA28E10C5F /* MapTilerAuthorization.swift in Sources */ = {isa = PBXBuildFile; fileRef = E062C1750EFC8627DE4CAB8E /* MapTilerAuthorization.swift */; };
FD29471C72872F8B7580E3E1 /* KeychainControllerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39C0D861FC397AC34BCF089E /* KeychainControllerMock.swift */; };
FD4C21F8DA1E273DE94FCD1A /* NotificationItemProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B927CF5EF7FCCDA5EDC474B /* NotificationItemProxyProtocol.swift */; };
FD4DEC88210F35C35B2FB386 /* ProcessInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3A1398EFF65090FDA1CB639 /* ProcessInfo.swift */; };
FD762761C5D0C30E6255C3D8 /* ServerConfirmationScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = ABA4CF2F5B4F68D02E412004 /* ServerConfirmationScreenViewModelProtocol.swift */; };
FDD5B4B616D9FF4DE3E9A418 /* QRCodeScannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92DB574F954CC2B40F7BE892 /* QRCodeScannerView.swift */; };
FE4593FC2A02AAF92E089565 /* ElementAnimations.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF1593DD87F974F8509BB619 /* ElementAnimations.swift */; };
Expand Down Expand Up @@ -1229,6 +1231,7 @@
06FAE373A7F20780BA84B59C /* MessageForwardingScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageForwardingScreenCoordinator.swift; sourceTree = "<group>"; };
0724EBDFE8BB4C9E5547C57D /* Client.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Client.swift; sourceTree = "<group>"; };
07579F9C29001E40715F3014 /* NotificationSettingsChatType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsChatType.swift; sourceTree = "<group>"; };
077B01C13BBA2996272C5FB5 /* ProcessInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProcessInfo.swift; sourceTree = "<group>"; };
077D7C3BE199B6E5DDEC07EC /* AppCoordinatorStateMachine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinatorStateMachine.swift; sourceTree = "<group>"; };
07C6B0B087FE6601C3F77816 /* JoinedRoomProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JoinedRoomProxy.swift; sourceTree = "<group>"; };
0825EAFD47332DD459DE893F /* SessionDirectoriesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionDirectoriesTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1967,7 +1970,6 @@
B2EAFFD44F81F86012D6EC27 /* AudioRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioRoomTimelineView.swift; sourceTree = "<group>"; };
B3005886F00029F058DB62BE /* StartChatScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartChatScreenCoordinator.swift; sourceTree = "<group>"; };
B383DCD3DCB19E00FD478A5F /* ConfirmationDialog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmationDialog.swift; sourceTree = "<group>"; };
B3A1398EFF65090FDA1CB639 /* ProcessInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProcessInfo.swift; sourceTree = "<group>"; };
B4005D82E9D27BAF006A8FE1 /* AppLockScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockScreenViewModel.swift; sourceTree = "<group>"; };
B40233F2989AD49906BB310D /* RoomPollsHistoryScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomPollsHistoryScreenViewModelTests.swift; sourceTree = "<group>"; };
B410B32B72C90BF94E481F33 /* AppLockSetupPINScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockSetupPINScreenModels.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3249,6 +3251,7 @@
95BAC0F6C9644336E9567EE6 /* NSRegularExpresion.swift */,
62B07B296D7A9D2F09120853 /* OrderedSet.swift */,
D26813CCE39221FE30BF22CD /* PlatformViewVersionPredicate.swift */,
077B01C13BBA2996272C5FB5 /* ProcessInfo.swift */,
1DFE0E493FB55E5A62E7852A /* ProposedViewSize.swift */,
7310D8DFE01AF45F0689C3AA /* Publisher.swift */,
584A61D9C459FAFEF038A7C0 /* Section.swift */,
Expand Down Expand Up @@ -4855,7 +4858,6 @@
7B25F959A434BB9923A3223F /* ExpiringTaskRunner.swift */,
6A580295A56B55A856CC4084 /* InfoPlistReader.swift */,
6AD1A853D605C2146B0DC028 /* MatrixEntityRegex.swift */,
B3A1398EFF65090FDA1CB639 /* ProcessInfo.swift */,
53482ECA4B6633961EC224F5 /* ScrollViewAdapter.swift */,
4481799F455B3DA243BDA2AC /* ShareToMapsAppActivity.swift */,
B1E227F34BE43B08E098796E /* TestablePreview.swift */,
Expand Down Expand Up @@ -6033,6 +6035,7 @@
62418EA4E3EB597AD184AEB6 /* PillConstants.swift in Sources */,
55CDD3968D95D1A820B5491E /* PlaceholderAvatarImage.swift in Sources */,
F12F6BED7B6D7EE4BEE55039 /* PlainMentionBuilder.swift in Sources */,
76C874243A8C440D6CF7B344 /* ProcessInfo.swift in Sources */,
414F50CFCFEEE2611127DCFB /* RestorationToken.swift in Sources */,
17BC15DA08A52587466698C5 /* RoomMessageEventStringBuilder.swift in Sources */,
7354D094A4C59B555F407FA1 /* RustTracing.swift in Sources */,
Expand All @@ -6043,6 +6046,7 @@
E0FB26262689F04D66A949D7 /* TestablePreview.swift in Sources */,
24DF253C18D3E2C56DD0E597 /* TracingConfiguration.swift in Sources */,
DDB47D29C6865669288BF87C /* UIFont+AttributedStringBuilder.m in Sources */,
45D6DC594816288983627484 /* UITestsScreenIdentifier.swift in Sources */,
281BED345D59A9A6A99E9D98 /* UNNotificationContent.swift in Sources */,
518C93DC6516D3D018DE065F /* UNNotificationRequest.swift in Sources */,
06B55882911B4BF5B14E9851 /* URL.swift in Sources */,
Expand Down Expand Up @@ -6648,7 +6652,7 @@
128FFD8A3D85845F9A927F47 /* PollRoomTimelineView.swift in Sources */,
1307268DC41730E5BCF7D9A0 /* PollView.swift in Sources */,
DF504B10A4918F971A57BEF2 /* PostHogAnalyticsClient.swift in Sources */,
FD4DEC88210F35C35B2FB386 /* ProcessInfo.swift in Sources */,
6793E75E3EBE48EBB8F857AF /* ProcessInfo.swift in Sources */,
69DE29C3E3180BB17D840690 /* ProgressCursorModifier.swift in Sources */,
C7ABEBECDC513F7887DACF66 /* ProgressMaskModifier.swift in Sources */,
9B356742E035D90A8BB5CABE /* ProposedViewSize.swift in Sources */,
Expand Down
3 changes: 3 additions & 0 deletions ElementX/Sources/Other/AccessibilityIdentifiers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ enum A11yIdentifiers {
let timelineItemActionMenu = "room-timeline_item_action_menu"
let joinCall = "room-join_call"
let scrollToBottom = "room-scroll_to_bottom"

let messageComposer = "room-message_composer"
let sendButton = "room-send_button"

let composerToolbar = ComposerToolbar()

Expand Down
16 changes: 14 additions & 2 deletions ElementX/Sources/Other/Logging/RustTracing.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@ enum RustTracing {
/// name and other log management metadata during rotation.
static let filePrefix = "console"
/// The directory that stores all of the log files.
static var logsDirectory: URL { .appGroupContainerDirectory }
static var logsDirectory: URL {
if ProcessInfo.isRunningIntegrationTests {
"/Users/Shared"
} else {
.appGroupContainerDirectory
}
}

private(set) static var currentTracingConfiguration: TracingConfiguration?
static func setup(configuration: TracingConfiguration) {
Expand All @@ -23,7 +29,13 @@ enum RustTracing {
// as the app is unlikely to be running continuously.
let maxFiles: UInt64 = 24 * 7

setupTracing(config: .init(filter: configuration.filter,
let filter = if ProcessInfo.isRunningIntegrationTests {
"trace"
} else {
configuration.filter
}
stefanceriu marked this conversation as resolved.
Show resolved Hide resolved

setupTracing(config: .init(filter: filter,
writeToStdoutOrSystem: true,
writeToFiles: .init(path: logsDirectory.path(percentEncoded: false),
filePrefix: configuration.fileName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ struct ComposerToolbar: View {
.disabled(context.viewState.sendButtonDisabled)
.animation(.linear(duration: 0.1).disabledDuringTests(), value: context.viewState.sendButtonDisabled)
.keyboardShortcut(.return, modifiers: [.command])
.accessibilityIdentifier(A11yIdentifiers.roomScreen.sendButton)
}

private var messageComposer: some View {
Expand Down Expand Up @@ -174,6 +175,7 @@ struct ComposerToolbar: View {
.focused($composerFocused)
.padding(.leading, context.composerFormattingEnabled ? 7 : 0)
.padding(.trailing, context.composerFormattingEnabled ? 4 : 0)
.accessibilityIdentifier(A11yIdentifiers.roomScreen.messageComposer)
.onTapGesture {
guard !composerFocused else { return }
composerFocused = true
Expand Down
70 changes: 62 additions & 8 deletions IntegrationTests/Sources/UserFlowTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
import XCTest

class UserFlowTests: XCTestCase {
private static let integrationTestsRoomName = "Element X iOS Integration Tests"
private static let integrationTestsMessage = "Go down in flames!"
stefanceriu marked this conversation as resolved.
Show resolved Hide resolved

private var app: XCUIApplication!

override func setUp() {
Expand All @@ -16,15 +19,28 @@
}

func testUserFlow() {
checkRoomFlows()

checkSettings()

checkRoomCreation()

// Open the first room in the list.
let firstRoom = app.buttons.matching(NSPredicate(format: "identifier BEGINSWITH %@", A11yIdentifiers.homeScreen.roomNamePrefix)).firstMatch
app.logout()
}

// Assumes app is on the home screen
private func checkRoomFlows() {
// Search for the special test room
let searchField = app.searchFields.firstMatch
searchField.clearAndTypeText(Self.integrationTestsRoomName)

// And open it
let firstRoom = app.buttons.matching(NSPredicate(format: "identifier CONTAINS %@", Self.integrationTestsRoomName)).firstMatch
XCTAssertTrue(firstRoom.waitForExistence(timeout: 10.0))
firstRoom.tap()

sendMessages()

checkPhotoSharing()

checkDocumentSharing()
Expand All @@ -35,21 +51,55 @@

checkRoomDetails()

app.logout()
// Cancel initial the room search
let searchCancelButton = app.buttons["Cancel"].firstMatch
XCTAssertTrue(searchCancelButton.waitForExistence(timeout: 10.0))
searchCancelButton.forceTap()
}

private func sendMessages() {
var composerTextField = app.textViews[A11yIdentifiers.roomScreen.messageComposer].firstMatch
XCTAssertTrue(composerTextField.waitForExistence(timeout: 10.0))
composerTextField.clearAndTypeText(Self.integrationTestsMessage)

var sendButton = app.buttons[A11yIdentifiers.roomScreen.sendButton].firstMatch
XCTAssertTrue(sendButton.waitForExistence(timeout: 10.0))
sendButton.tap()

sleep(10) // Wait for the message to be sent

// Switch to the rich text editor
tapOnMenu(A11yIdentifiers.roomScreen.composerToolbar.openComposeOptions)
tapOnButton(A11yIdentifiers.roomScreen.attachmentPickerTextFormatting)

composerTextField = app.textViews[A11yIdentifiers.roomScreen.messageComposer].firstMatch
XCTAssertTrue(composerTextField.waitForExistence(timeout: 10.0))
composerTextField.clearAndTypeText(Self.integrationTestsMessage)

sendButton = app.buttons[A11yIdentifiers.roomScreen.sendButton].firstMatch
XCTAssertTrue(sendButton.waitForExistence(timeout: 10.0))
sendButton.tap()

sleep(5) // Wait for the message to be sent

// Close the formatting options
app.buttons[A11yIdentifiers.roomScreen.composerToolbar.closeFormattingOptions].tap()
}

private func checkPhotoSharing() {
// Open attachments picker
tapOnMenu(A11yIdentifiers.roomScreen.composerToolbar.openComposeOptions)

// Open photo library picker
tapOnButton(A11yIdentifiers.roomScreen.attachmentPickerPhotoLibrary)

sleep(10) // Wait for the picker to load

// Tap on the second image. First one is always broken on simulators.
let secondImage = app.scrollViews.images.element(boundBy: 1)
XCTAssertTrue(secondImage.waitForExistence(timeout: 10.0)) // Photo library takes a bit to load
XCTAssertTrue(secondImage.waitForExistence(timeout: 20.0)) // Photo library takes a bit to load

Check failure on line 97 in IntegrationTests/Sources/UserFlowTests.swift

View workflow job for this annotation

GitHub Actions / Integration Tests

testUserFlow, XCTAssertTrue failed
secondImage.tap()

Check failure on line 98 in IntegrationTests/Sources/UserFlowTests.swift

View workflow job for this annotation

GitHub Actions / Integration Tests

testUserFlow, Failed to tap Image (Element at index 1): No matches found for Descendants matching type ScrollView from input {(

// Wait for the image to be processed and the new screen to appear
sleep(10)

// Cancel the upload flow
tapOnButton("Cancel", waitForDisappearance: true)
}
Expand All @@ -58,13 +108,17 @@
tapOnMenu(A11yIdentifiers.roomScreen.composerToolbar.openComposeOptions)
tapOnButton(A11yIdentifiers.roomScreen.attachmentPickerDocuments)

sleep(10) // Wait for the picker to load

tapOnButton("Cancel", waitForDisappearance: true)
}

private func checkLocationSharing() {
tapOnMenu(A11yIdentifiers.roomScreen.composerToolbar.openComposeOptions)
tapOnButton(A11yIdentifiers.roomScreen.attachmentPickerLocation)

sleep(10) // Wait for the picker to load

// The order of the alerts is a bit of a mistery so try twice

allowLocationPermissionOnce()
Expand Down Expand Up @@ -127,8 +181,8 @@
tapOnButton(A11yIdentifiers.roomDetailsScreen.people)

// Open the first member's details. Loading members for big rooms can take a while.
let firstRoomMember = app.scrollViews.buttons.firstMatch
let firstRoomMember = app.scrollViews.buttons.element(boundBy: 2) // First 2 are the segmented control
XCTAssertTrue(firstRoomMember.waitForExistence(timeout: 1000.0))

Check failure on line 185 in IntegrationTests/Sources/UserFlowTests.swift

View workflow job for this annotation

GitHub Actions / Integration Tests

testUserFlow, Failed to get matching snapshots: Timed out while evaluating UI query.
firstRoomMember.tap()

// Go back to the room member details
Expand Down
2 changes: 2 additions & 0 deletions NSE/SupportingFiles/target.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ targets:
- path: ../../ElementX/Sources/Other/Extensions/ImageCache.swift
- path: ../../ElementX/Sources/Other/Extensions/LayoutDirection.swift
- path: ../../ElementX/Sources/Other/Extensions/NSRegularExpresion.swift
- path: ../../ElementX/Sources/Other/Extensions/ProcessInfo.swift
- path: ../../ElementX/Sources/Other/Extensions/String.swift
- path: ../../ElementX/Sources/Other/Extensions/Task.swift
- path: ../../ElementX/Sources/Other/Extensions/UNNotificationContent.swift
Expand All @@ -112,3 +113,4 @@ targets:
- path: ../../ElementX/Sources/Services/Room/RoomSummary/RoomMessageEventStringBuilder.swift
- path: ../../ElementX/Sources/Services/UserSession/RestorationToken.swift
- path: ../../ElementX/Sources/Services/UserSession/SessionDirectories.swift
- path: ../../ElementX/Sources/UITests/UITestsScreenIdentifier.swift
Loading