Skip to content

Commit

Permalink
Integration test improvements (#3330)
Browse files Browse the repository at this point in the history
* Send a message from integration tests and check that it doesn't show up in the app logs
* Increase photo library timeout

* Wait for image tapping to process

* Send a message using the rich text editor too

* Wait for the various pickers to finish loading

* Set all logs to `trace` in integration tests

* Close formatting options after sending the second message

* Make sure logs are actually sent to tracing and get redirected to the right file

* Switch from using a custom `trace` log configuration to the lowest level `TracingConfiguration` we support
  • Loading branch information
stefanceriu authored Sep 26, 2024
1 parent a8dbda9 commit dc6d7f2
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 16 deletions.
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)

- 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 @@ -311,6 +311,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 @@ -458,6 +459,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 @@ -525,6 +527,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 @@ -1130,7 +1133,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 @@ -1234,6 +1236,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 @@ -1974,7 +1977,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 @@ -3260,6 +3262,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 @@ -4866,7 +4869,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 @@ -6053,6 +6055,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 @@ -6063,6 +6066,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 @@ -6672,7 +6676,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
File renamed without changes.
18 changes: 16 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,15 @@ enum RustTracing {
// as the app is unlikely to be running continuously.
let maxFiles: UInt64 = 24 * 7

setupTracing(config: .init(filter: configuration.filter,
// Log everything on integration tests to check whether
// the logs contain any sensitive data. See `UserFlowTests.swift`
let filter = if ProcessInfo.isRunningIntegrationTests {
TracingConfiguration(logLevel: .trace, target: nil).filter
} else {
configuration.filter
}

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
74 changes: 64 additions & 10 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!"

private var app: XCUIApplication!

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

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,58 @@ class UserFlowTests: XCTestCase {

checkRoomDetails()

app.logout()
// Go back to the room list
tapOnBackButton("Chats")

// 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 100 in IntegrationTests/Sources/UserFlowTests.swift

View workflow job for this annotation

GitHub Actions / Integration Tests

testUserFlow, XCTAssertTrue failed
secondImage.tap()

Check failure on line 101 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 +111,17 @@ class UserFlowTests: XCTestCase {
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 @@ -139,9 +196,6 @@ class UserFlowTests: XCTestCase {

// Go back to the room
tapOnBackButton("Chat")

// Go back to the room list
tapOnBackButton("Chats")
}

private func checkSettings() {
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

0 comments on commit dc6d7f2

Please sign in to comment.