From 3011da257c376d393cfe7d7d4cd7fa37c670b3ad Mon Sep 17 00:00:00 2001 From: Manish Singh Date: Tue, 30 Dec 2025 17:06:35 +0100 Subject: [PATCH 01/10] share extension tests --- .../LoginViaEmailUseCase.swift | 2 +- .../AuthenticationAPI/AuthenticationAPI.swift | 4 +- .../AuthenticationAPIV0.swift | 6 +- .../Rest/ConnectionsAPI/ConnectionsAPI.swift | 18 ++++ .../ConnectionsAPI/ConnectionsAPIV0.swift | 38 +++++++ .../ShareExtensionViewController.swift | 1 + wire-ios/WireUITests/Helper/UserHelper.swift | 34 ++++++- .../Pages/ShareExtensionPage.swift | 0 .../WireUITests/ShareExtensionTests.swift | 99 +++++++++++++++++++ 9 files changed, 194 insertions(+), 8 deletions(-) create mode 100644 wire-ios/WireUITests/Pages/ShareExtensionPage.swift create mode 100644 wire-ios/WireUITests/ShareExtensionTests.swift diff --git a/WireAuthentication/Sources/WireAuthenticationLogic/LoginViaEmailUseCase.swift b/WireAuthentication/Sources/WireAuthenticationLogic/LoginViaEmailUseCase.swift index c35a787c026..bae1dfc071e 100644 --- a/WireAuthentication/Sources/WireAuthenticationLogic/LoginViaEmailUseCase.swift +++ b/WireAuthentication/Sources/WireAuthenticationLogic/LoginViaEmailUseCase.swift @@ -34,7 +34,7 @@ public struct LoginViaEmailUseCase: LoginViaEmailUseCaseProtocol { verificationCode: String? ) async throws -> ([HTTPCookie], AccessToken) { do { - let (cookies, token) = try await authenticationAPI.login( + let (cookies, token, _) = try await authenticationAPI.login( email: email, password: password, verificationCode: verificationCode, diff --git a/WireNetwork/Sources/WireNetwork/APIs/Rest/AuthenticationAPI/AuthenticationAPI.swift b/WireNetwork/Sources/WireNetwork/APIs/Rest/AuthenticationAPI/AuthenticationAPI.swift index 1d2d4c86511..a0ba6101701 100644 --- a/WireNetwork/Sources/WireNetwork/APIs/Rest/AuthenticationAPI/AuthenticationAPI.swift +++ b/WireNetwork/Sources/WireNetwork/APIs/Rest/AuthenticationAPI/AuthenticationAPI.swift @@ -29,14 +29,14 @@ public protocol AuthenticationAPI: Sendable { /// - verificationCode: The verification code is sent to the given user’s email address, /// this is an optional field and depends on the team/server settings. /// - label: An optional label to associate with the access token. - /// - Returns: HTTP cookie, a valid access token. + /// - Returns: HTTP cookie, a valid access token, and userId func login( email: String, password: String, verificationCode: String?, label: String? - ) async throws -> ([HTTPCookie], AccessToken) + ) async throws -> (cookie: [HTTPCookie], accessToken: AccessToken, userId: String) /// Get on-prem config `URL` for domain diff --git a/WireNetwork/Sources/WireNetwork/APIs/Rest/AuthenticationAPI/AuthenticationAPIV0.swift b/WireNetwork/Sources/WireNetwork/APIs/Rest/AuthenticationAPI/AuthenticationAPIV0.swift index 36cf6a7d1ef..af232903774 100644 --- a/WireNetwork/Sources/WireNetwork/APIs/Rest/AuthenticationAPI/AuthenticationAPIV0.swift +++ b/WireNetwork/Sources/WireNetwork/APIs/Rest/AuthenticationAPI/AuthenticationAPIV0.swift @@ -36,7 +36,7 @@ class AuthenticationAPIV0: AuthenticationAPI, VersionedAPI { password: String, verificationCode: String?, label: String? - ) async throws -> ([HTTPCookie], AccessToken) { + ) async throws -> (cookie: [HTTPCookie], accessToken: AccessToken, userId: String) { let path = "\(pathPrefix)/login" let body = LoginRequestBodyV0( email: email, @@ -118,7 +118,9 @@ class AuthenticationAPIV0: AuthenticationAPI, VersionedAPI { throw error } - return (cookies, accessToken) + let userId = accessToken.userID.uuidString + + return (cookies, accessToken, userId) } func getOnPremConfigURL(forDomain domain: String) async throws -> DomainInfo { diff --git a/WireNetwork/Sources/WireNetwork/APIs/Rest/ConnectionsAPI/ConnectionsAPI.swift b/WireNetwork/Sources/WireNetwork/APIs/Rest/ConnectionsAPI/ConnectionsAPI.swift index b9f5a796aa4..e7b706566a8 100644 --- a/WireNetwork/Sources/WireNetwork/APIs/Rest/ConnectionsAPI/ConnectionsAPI.swift +++ b/WireNetwork/Sources/WireNetwork/APIs/Rest/ConnectionsAPI/ConnectionsAPI.swift @@ -25,4 +25,22 @@ public protocol ConnectionsAPI { /// Fetch all connections . func getConnections() async throws -> PayloadPager<[Connection]> + + /// Send connection request to user + /// - Parameters: + /// - domain: domain info + /// - userID: userID + + #if DEBUG + func sendConnectionRequest(domain: String, userId: String) async throws + #endif + + /// Accept connection request from user + /// - Parameters: + /// - domain: domain info + /// - userID: userID + + #if DEBUG + func acceptConnectionRequest(domain: String, userId: String) async throws + #endif } diff --git a/WireNetwork/Sources/WireNetwork/APIs/Rest/ConnectionsAPI/ConnectionsAPIV0.swift b/WireNetwork/Sources/WireNetwork/APIs/Rest/ConnectionsAPI/ConnectionsAPIV0.swift index d7afae19c5a..b5239080a64 100644 --- a/WireNetwork/Sources/WireNetwork/APIs/Rest/ConnectionsAPI/ConnectionsAPIV0.swift +++ b/WireNetwork/Sources/WireNetwork/APIs/Rest/ConnectionsAPI/ConnectionsAPIV0.swift @@ -61,6 +61,39 @@ class ConnectionsAPIV0: ConnectionsAPI, VersionedAPI { .parse(code: response.statusCode, data: data) } } + + func sendConnectionRequest( + domain: String, + userId: String + ) async throws { + + let request = try URLRequestBuilder(path: "\(pathPrefix)/connections/\(domain)/\(userId)") + .withMethod(.post) + .build() + + let (_, response) = try await apiService.executeRequest(request, requiringAccessToken: true) + guard response.statusCode == HTTPStatusCode.created.rawValue else { + throw ConnectionsAPIError.invalidBody + } + } + + func acceptConnectionRequest( + domain: String, + userId: String + ) async throws { + + let body = try JSONEncoder.defaultEncoder.encode(RequestBodyAcceptConnectionRequestV0.accepted) + + let request = try URLRequestBuilder(path: "\(pathPrefix)/connections/\(domain)/\(userId)") + .withMethod(.put) + .withBody(body, contentType: .json) + .build() + + let (_, response) = try await apiService.executeRequest(request, requiringAccessToken: true) + guard response.statusCode == HTTPStatusCode.ok.rawValue else { + throw ConnectionsAPIError.invalidBody + } + } } private struct PaginatedConnectionListV0: Decodable, ToAPIModelConvertible { @@ -120,3 +153,8 @@ private struct ConnectionResponseV0: Decodable, ToAPIModelConvertible { ) } } + +private struct RequestBodyAcceptConnectionRequestV0: Encodable { + static let accepted = Self() + let status: String = "accepted" +} diff --git a/wire-ios/Wire-iOS Share Extension/Sources/View Controllers/ShareExtensionViewController.swift b/wire-ios/Wire-iOS Share Extension/Sources/View Controllers/ShareExtensionViewController.swift index fe41b1585ec..612cb491d35 100644 --- a/wire-ios/Wire-iOS Share Extension/Sources/View Controllers/ShareExtensionViewController.swift +++ b/wire-ios/Wire-iOS Share Extension/Sources/View Controllers/ShareExtensionViewController.swift @@ -185,6 +185,7 @@ final class ShareExtensionViewController: SLComposeServiceViewController { guard let item = navigationController?.navigationBar.items?.first else { return } item.rightBarButtonItem?.action = #selector(appendPostTapped) item.rightBarButtonItem?.title = L10n.ShareExtension.SendButton.title + item.rightBarButtonItem?.accessibilityIdentifier = "sendButtonOnShareExtension" item .titleView = UIImageView( image: WireStyleKit.imageOfLogo(color: UIColor.Wire.primaryLabel) diff --git a/wire-ios/WireUITests/Helper/UserHelper.swift b/wire-ios/WireUITests/Helper/UserHelper.swift index a74cab591e3..a9f5f34008f 100644 --- a/wire-ios/WireUITests/Helper/UserHelper.swift +++ b/wire-ios/WireUITests/Helper/UserHelper.swift @@ -34,6 +34,7 @@ class UserHelper { let teamsAPI: TeamsAPI let selfUserAPI: SelfUserAPI let conversationsAPI: ConversationsAPI + let connectionsAPI: ConnectionsAPI private let cookieStorage = MockCookieStorage() private let authenticationManager = MockAuthManager() @@ -54,6 +55,7 @@ class UserHelper { self.teamsAPI = TeamsAPIBuilder(apiService: networkStack.apiService) .makeAPI(for: apiVersion) self.conversationsAPI = ConversationsAPIBuilder(apiService: networkStack.apiService).makeAPI(for: apiVersion) + self.connectionsAPI = ConnectionsAPIBuilder(apiService: networkStack.apiService).makeAPI(for: apiVersion) } func basicAuth(_ backend: BackendTarget = BackendContext.current) -> String { @@ -93,12 +95,13 @@ class UserHelper { try await authenticationAPI.activateUser(email: user.email, key: activationKey, code: activationCode) // get accessToken for current user - let (_, accessToken) = try await authenticationAPI.login( + let (_, accessToken, userId) = try await authenticationAPI.login( email: user.email, password: user.password, verificationCode: nil, label: nil ) + user.id = userId authenticationManager.accessToken = accessToken // Set username @@ -180,7 +183,7 @@ class UserHelper { try await authenticationAPI.activateUser(email: email, key: activationKey, code: activationCode) - let (_, accessToken) = try await authenticationAPI.login( + let (_, accessToken, _) = try await authenticationAPI.login( email: email, password: password, verificationCode: nil, @@ -269,7 +272,7 @@ class UserHelper { isReadReceiptsEnabled: true ) - let (_, accessToken) = try await authenticationAPI.login( + let (_, accessToken, _) = try await authenticationAPI.login( email: owner.email, password: owner.password, verificationCode: nil, @@ -279,6 +282,31 @@ class UserHelper { _ = try await conversationsAPI.createGroupConversation(parameters: params) } + + func sendConnectionRequestToUser( + domain: String, + userId: String + ) async throws { + + _ = try await connectionsAPI.sendConnectionRequest(domain: domain, userId: userId) + } + + func acceptConnectionRequestFromUser( + domain: String, + user1: UserInfo, + userId: String + ) async throws { + + let (_, accessToken, _) = try await authenticationAPI.login( + email: user1.email, + password: user1.password, + verificationCode: nil, + label: nil + ) + authenticationManager.accessToken = accessToken + + try await connectionsAPI.acceptConnectionRequest(domain: domain, userId: userId) + } } extension BackendEnvironment { diff --git a/wire-ios/WireUITests/Pages/ShareExtensionPage.swift b/wire-ios/WireUITests/Pages/ShareExtensionPage.swift new file mode 100644 index 00000000000..e69de29bb2d diff --git a/wire-ios/WireUITests/ShareExtensionTests.swift b/wire-ios/WireUITests/ShareExtensionTests.swift new file mode 100644 index 00000000000..794612b4c00 --- /dev/null +++ b/wire-ios/WireUITests/ShareExtensionTests.swift @@ -0,0 +1,99 @@ +// +// Wire +// Copyright (C) 2025 Wire Swiss GmbH +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see http://www.gnu.org/licenses/. +// + +import WireFoundation +import XCTest + +final class ShareExtensionTests: WireUITestCase { + + private let photosApp = XCUIApplication(bundleIdentifier: "com.apple.mobileslideshow") + + @MainActor + func testCritical_ShareImageOnetoOne() async throws { + + let user1 = try await userHelper.createPersonalUser() + let user2 = try await userHelper.createPersonalUser() + let domain = BackendTarget.staging.domainInfo + + try await userHelper.sendConnectionRequestToUser(domain: domain, userId: user1.id) + + try await userHelper.acceptConnectionRequestFromUser(domain: domain, user1: user1, userId: user2.id) + let firstTimePage = try app.loginUser(email: user1.email, password: user1.password) + _ = try firstTimePage.acceptPopup(with: self) + + _ = try await launchPhotosAppAndOpenFirstImage() + + try await shareToWireApp() + + try await chooseConversationAndSend(name: user2.name) + try await switchBackToWireApp() + + // verify shared via Wire app - pending + + } + + @MainActor + private func launchPhotosAppAndOpenFirstImage() async throws -> String { + photosApp.launch() + XCTAssertTrue(photosApp.wait(for: .runningForeground, timeout: 10)) + + let firstImage = photosApp.images + .matching(identifier: "PXGGridLayout-Info") + .element(boundBy: 0) + + let imageLabel = firstImage.label + // NOTE: Use a coordinate tap on center because Photos grid cells are not always directly hittable in UI + // tests. + firstImage + .coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5)) + .tap() + + return imageLabel + } + + @MainActor + private func shareToWireApp() async throws { + let shareButton = photosApp.buttons + .matching(identifier: "PUOneUpBarButtonItemIdentifierShare") + .firstMatch + + shareButton.tap() + let shareToWireApp = photosApp.cells["Wire"].firstMatch + shareToWireApp.tap() + } + + @MainActor + private func chooseConversationAndSend(name: String) async throws { + let chooseConversationButton = photosApp.buttons["chevron"] + + let selectConversation = photosApp.staticTexts[name] + let sendButton = photosApp.buttons["sendButtonOnShareExtension"].firstMatch + + chooseConversationButton.tap() + selectConversation.tap() + sendButton.tap() + } + + @MainActor + private func switchBackToWireApp() async throws { + app.activate() + if app.state != .runningForeground { + app.launch() + } + } +} From 35d497c0e79983a9d17406fb2a84d40f0ec64e11 Mon Sep 17 00:00:00 2001 From: Manish Singh Date: Wed, 31 Dec 2025 11:05:25 +0100 Subject: [PATCH 02/10] share image to 1:1 conversation via share extension --- WireUI/Sources/WireLocators/Locators.swift | 10 ++ .../Pages/ActiveConversationPage .swift | 4 + .../WireUITests/Pages/PhotosAppPage.swift | 96 +++++++++++++++++++ .../Pages/ShareExtensionPage.swift | 0 .../WireUITests/ShareExtensionTests.swift | 84 +++++----------- 5 files changed, 135 insertions(+), 59 deletions(-) create mode 100644 wire-ios/WireUITests/Pages/PhotosAppPage.swift delete mode 100644 wire-ios/WireUITests/Pages/ShareExtensionPage.swift diff --git a/WireUI/Sources/WireLocators/Locators.swift b/WireUI/Sources/WireLocators/Locators.swift index 03640135a01..70394f49860 100644 --- a/WireUI/Sources/WireLocators/Locators.swift +++ b/WireUI/Sources/WireLocators/Locators.swift @@ -99,6 +99,7 @@ public enum Locators { case conversationTitleButton case conversationDetailsButton case message + case imageCell = "ImageCell" } public enum BackupOrRestorePage: String { @@ -266,4 +267,13 @@ public enum Locators { case closeButton } + public enum ShareExtensionPage: String { + + case imageTile = "PXGGridLayout-Info" + case shareButton = "PUOneUpBarButtonItemIdentifierShare" + + case chooseConversations = "chevron" + case sendButtonOnShareExtension + } + } diff --git a/wire-ios/WireUITests/Pages/ActiveConversationPage .swift b/wire-ios/WireUITests/Pages/ActiveConversationPage .swift index a3be0ab9cbd..6ad547d5944 100644 --- a/wire-ios/WireUITests/Pages/ActiveConversationPage .swift +++ b/wire-ios/WireUITests/Pages/ActiveConversationPage .swift @@ -61,6 +61,10 @@ class ActiveConversationPage: PageModel { app.buttons[Locators.ActiveConversationPage.conversationDetailsButton.rawValue] } + var imageCell: XCUIElement { + app.otherElements[Locators.ActiveConversationPage.imageCell.rawValue] + } + func fetchMessages() -> [String] { var messages: [String] = [] for i in 0 ..< messageLabels.count { diff --git a/wire-ios/WireUITests/Pages/PhotosAppPage.swift b/wire-ios/WireUITests/Pages/PhotosAppPage.swift new file mode 100644 index 00000000000..3d3fd46a5f7 --- /dev/null +++ b/wire-ios/WireUITests/Pages/PhotosAppPage.swift @@ -0,0 +1,96 @@ +// +// Wire +// Copyright (C) 2025 Wire Swiss GmbH +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see http://www.gnu.org/licenses/. +// + +import WireLocators +import XCTest + +class PhotosAppPage: PageModel { + + private let photosApp = XCUIApplication(bundleIdentifier: "com.apple.mobileslideshow") + + override var pageMainElement: XCUIElement { + firstImageTile + } + + var firstImageTile: XCUIElement { + photosApp.images + .matching(identifier: Locators.ShareExtensionPage.imageTile.rawValue) + .element(boundBy: 0) + } + + var shareButton: XCUIElement { + photosApp.buttons + .matching(identifier: Locators.ShareExtensionPage.shareButton.rawValue) + .firstMatch + } + + var shareToWireApp: XCUIElement { + photosApp.cells["Wire"].firstMatch + } + + var chooseConversationButton: XCUIElement { + photosApp.buttons[Locators.ShareExtensionPage.chooseConversations.rawValue].firstMatch + } + + var sendButton: XCUIElement { + photosApp.buttons[Locators.ShareExtensionPage.sendButtonOnShareExtension.rawValue].firstMatch + } + + func selectConversation(name: String) -> XCUIElement { + photosApp.staticTexts[name].firstMatch + } + + @discardableResult + func launchPhotosApp() throws -> PhotosAppPage { + photosApp.launch() + XCTAssertTrue(photosApp.wait(for: .runningForeground, timeout: 5)) + return self + } + + @discardableResult + func openFirstImage() throws -> PhotosAppPage { + XCTAssertTrue(firstImageTile.waitForExistence(timeout: 5)) + // NOTE: Use a coordinate tap on center because Photos grid cells are not always directly hittable in UITests + firstImageTile + .coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5)) + .tap() + return self + } + + @discardableResult + func shareImageToWire() throws -> PhotosAppPage { + XCTAssertTrue(shareButton.waitForExistence(timeout: 5)) + shareButton.tap() + XCTAssertTrue(shareToWireApp.waitForExistence(timeout: 5)) + shareToWireApp.tap() + return self + } + + func chooseConversationAndSend(name: String) throws { + XCTAssertTrue(chooseConversationButton.waitForExistence(timeout: 5)) + chooseConversationButton.tap() + + let conversationToSend = selectConversation(name: name) + XCTAssertTrue(conversationToSend.waitForExistence(timeout: 5)) + conversationToSend.tap() + + XCTAssertTrue(sendButton.waitForExistence(timeout: 5)) + sendButton.tap() + } + +} diff --git a/wire-ios/WireUITests/Pages/ShareExtensionPage.swift b/wire-ios/WireUITests/Pages/ShareExtensionPage.swift deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/wire-ios/WireUITests/ShareExtensionTests.swift b/wire-ios/WireUITests/ShareExtensionTests.swift index 794612b4c00..3f84a0f90be 100644 --- a/wire-ios/WireUITests/ShareExtensionTests.swift +++ b/wire-ios/WireUITests/ShareExtensionTests.swift @@ -17,11 +17,29 @@ // import WireFoundation +import WireLocators import XCTest final class ShareExtensionTests: WireUITestCase { - private let photosApp = XCUIApplication(bundleIdentifier: "com.apple.mobileslideshow") + @MainActor + private func shareFirstPhotoToWire(name: String) async throws { + let photosApp = try PhotosAppPage() + try photosApp + .launchPhotosApp() + .openFirstImage() + .shareImageToWire() + .chooseConversationAndSend(name: name) + } + + @MainActor + private func switchBackToWireApp() async throws { + app.activate() + if !app.wait(for: .runningForeground, timeout: 10) { + app.launch() + _ = app.wait(for: .runningForeground, timeout: 10) + } + } @MainActor func testCritical_ShareImageOnetoOne() async throws { @@ -31,69 +49,17 @@ final class ShareExtensionTests: WireUITestCase { let domain = BackendTarget.staging.domainInfo try await userHelper.sendConnectionRequestToUser(domain: domain, userId: user1.id) - try await userHelper.acceptConnectionRequestFromUser(domain: domain, user1: user1, userId: user2.id) let firstTimePage = try app.loginUser(email: user1.email, password: user1.password) - _ = try firstTimePage.acceptPopup(with: self) - - _ = try await launchPhotosAppAndOpenFirstImage() + let conversationsPage = try firstTimePage.acceptPopup(with: self) - try await shareToWireApp() - - try await chooseConversationAndSend(name: user2.name) + try await shareFirstPhotoToWire(name: user2.name) try await switchBackToWireApp() - // verify shared via Wire app - pending - - } - - @MainActor - private func launchPhotosAppAndOpenFirstImage() async throws -> String { - photosApp.launch() - XCTAssertTrue(photosApp.wait(for: .runningForeground, timeout: 10)) - - let firstImage = photosApp.images - .matching(identifier: "PXGGridLayout-Info") - .element(boundBy: 0) + let activeConversationPage = try conversationsPage.openConversation() - let imageLabel = firstImage.label - // NOTE: Use a coordinate tap on center because Photos grid cells are not always directly hittable in UI - // tests. - firstImage - .coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5)) - .tap() - - return imageLabel - } - - @MainActor - private func shareToWireApp() async throws { - let shareButton = photosApp.buttons - .matching(identifier: "PUOneUpBarButtonItemIdentifierShare") - .firstMatch - - shareButton.tap() - let shareToWireApp = photosApp.cells["Wire"].firstMatch - shareToWireApp.tap() - } - - @MainActor - private func chooseConversationAndSend(name: String) async throws { - let chooseConversationButton = photosApp.buttons["chevron"] - - let selectConversation = photosApp.staticTexts[name] - let sendButton = photosApp.buttons["sendButtonOnShareExtension"].firstMatch - - chooseConversationButton.tap() - selectConversation.tap() - sendButton.tap() - } - - @MainActor - private func switchBackToWireApp() async throws { - app.activate() - if app.state != .runningForeground { - app.launch() - } + XCTAssertTrue( + activeConversationPage.imageCell.exists, "No Image cell found" + ) } } From 8d683699eb5cc5b3348e301f7b5df8a23ca0ff00 Mon Sep 17 00:00:00 2001 From: Manish Singh Date: Fri, 2 Jan 2026 13:09:29 +0100 Subject: [PATCH 03/10] clean up and finish up this test --- WireUI/Sources/WireLocators/Locators.swift | 2 +- .../WireUITests/Pages/PhotosAppPage.swift | 36 ++++++++++++------- .../WireUITests/ShareExtensionTests.swift | 14 ++++++-- 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/WireUI/Sources/WireLocators/Locators.swift b/WireUI/Sources/WireLocators/Locators.swift index 70394f49860..aacff533f61 100644 --- a/WireUI/Sources/WireLocators/Locators.swift +++ b/WireUI/Sources/WireLocators/Locators.swift @@ -271,9 +271,9 @@ public enum Locators { case imageTile = "PXGGridLayout-Info" case shareButton = "PUOneUpBarButtonItemIdentifierShare" - case chooseConversations = "chevron" case sendButtonOnShareExtension + case continueButton = "Continue" } } diff --git a/wire-ios/WireUITests/Pages/PhotosAppPage.swift b/wire-ios/WireUITests/Pages/PhotosAppPage.swift index 3d3fd46a5f7..7825f1c650c 100644 --- a/wire-ios/WireUITests/Pages/PhotosAppPage.swift +++ b/wire-ios/WireUITests/Pages/PhotosAppPage.swift @@ -20,11 +20,19 @@ import WireLocators import XCTest class PhotosAppPage: PageModel { - - private let photosApp = XCUIApplication(bundleIdentifier: "com.apple.mobileslideshow") + private let photosApp: XCUIApplication override var pageMainElement: XCUIElement { - firstImageTile + photosApp.windows.firstMatch + } + + init(photosApp: XCUIApplication) throws { + self.photosApp = photosApp + try super.init() + } + + var continueButtonOnWhatsNewPhotosApp: XCUIElement { + photosApp.buttons[Locators.ShareExtensionPage.continueButton.rawValue].firstMatch } var firstImageTile: XCUIElement { @@ -54,17 +62,19 @@ class PhotosAppPage: PageModel { func selectConversation(name: String) -> XCUIElement { photosApp.staticTexts[name].firstMatch } - + @discardableResult - func launchPhotosApp() throws -> PhotosAppPage { - photosApp.launch() - XCTAssertTrue(photosApp.wait(for: .runningForeground, timeout: 5)) + func continueWhatsNewIfPresent() throws -> PhotosAppPage { + if continueButtonOnWhatsNewPhotosApp.waitForExistence(timeout: 3) { + continueButtonOnWhatsNewPhotosApp.tap() + } return self } @discardableResult func openFirstImage() throws -> PhotosAppPage { - XCTAssertTrue(firstImageTile.waitForExistence(timeout: 5)) + try continueWhatsNewIfPresent() + XCTAssertTrue(firstImageTile.waitForExistence(timeout: 10)) // NOTE: Use a coordinate tap on center because Photos grid cells are not always directly hittable in UITests firstImageTile .coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5)) @@ -74,22 +84,22 @@ class PhotosAppPage: PageModel { @discardableResult func shareImageToWire() throws -> PhotosAppPage { - XCTAssertTrue(shareButton.waitForExistence(timeout: 5)) + XCTAssertTrue(shareButton.waitForExistence(timeout: 10)) shareButton.tap() - XCTAssertTrue(shareToWireApp.waitForExistence(timeout: 5)) + XCTAssertTrue(shareToWireApp.waitForExistence(timeout: 10)) shareToWireApp.tap() return self } func chooseConversationAndSend(name: String) throws { - XCTAssertTrue(chooseConversationButton.waitForExistence(timeout: 5)) + XCTAssertTrue(chooseConversationButton.waitForExistence(timeout: 10)) chooseConversationButton.tap() let conversationToSend = selectConversation(name: name) - XCTAssertTrue(conversationToSend.waitForExistence(timeout: 5)) + XCTAssertTrue(conversationToSend.waitForExistence(timeout: 10)) conversationToSend.tap() - XCTAssertTrue(sendButton.waitForExistence(timeout: 5)) + XCTAssertTrue(sendButton.waitForExistence(timeout: 10)) sendButton.tap() } diff --git a/wire-ios/WireUITests/ShareExtensionTests.swift b/wire-ios/WireUITests/ShareExtensionTests.swift index 3f84a0f90be..7f970bd09e8 100644 --- a/wire-ios/WireUITests/ShareExtensionTests.swift +++ b/wire-ios/WireUITests/ShareExtensionTests.swift @@ -22,11 +22,18 @@ import XCTest final class ShareExtensionTests: WireUITestCase { + private let photosAppBundleId = XCUIApplication(bundleIdentifier: "com.apple.mobileslideshow") + + @MainActor + private func launchPhotosApp() async throws { + photosAppBundleId.launch() + XCTAssertTrue(photosAppBundleId.wait(for: .runningForeground, timeout: 10)) + } + @MainActor private func shareFirstPhotoToWire(name: String) async throws { - let photosApp = try PhotosAppPage() + let photosApp = try PhotosAppPage(photosApp: photosAppBundleId) try photosApp - .launchPhotosApp() .openFirstImage() .shareImageToWire() .chooseConversationAndSend(name: name) @@ -42,7 +49,7 @@ final class ShareExtensionTests: WireUITestCase { } @MainActor - func testCritical_ShareImageOnetoOne() async throws { + func test_ShareImageOnetoOne() async throws { let user1 = try await userHelper.createPersonalUser() let user2 = try await userHelper.createPersonalUser() @@ -53,6 +60,7 @@ final class ShareExtensionTests: WireUITestCase { let firstTimePage = try app.loginUser(email: user1.email, password: user1.password) let conversationsPage = try firstTimePage.acceptPopup(with: self) + try await launchPhotosApp() try await shareFirstPhotoToWire(name: user2.name) try await switchBackToWireApp() From f961a6c1d5f0457866f053e78aece56d175f1936 Mon Sep 17 00:00:00 2001 From: Manish Singh Date: Fri, 2 Jan 2026 13:43:27 +0100 Subject: [PATCH 04/10] formatting and changed the logic to store id in UserInfo --- .../LoginViaEmailUseCase.swift | 2 +- .../Rest/AuthenticationAPI/AuthenticationAPI.swift | 4 ++-- .../AuthenticationAPI/AuthenticationAPIV0.swift | 6 ++---- wire-ios/WireUITests/Helper/UserHelper.swift | 14 +++++++++----- wire-ios/WireUITests/Pages/PhotosAppPage.swift | 2 +- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/WireAuthentication/Sources/WireAuthenticationLogic/LoginViaEmailUseCase.swift b/WireAuthentication/Sources/WireAuthenticationLogic/LoginViaEmailUseCase.swift index bae1dfc071e..c35a787c026 100644 --- a/WireAuthentication/Sources/WireAuthenticationLogic/LoginViaEmailUseCase.swift +++ b/WireAuthentication/Sources/WireAuthenticationLogic/LoginViaEmailUseCase.swift @@ -34,7 +34,7 @@ public struct LoginViaEmailUseCase: LoginViaEmailUseCaseProtocol { verificationCode: String? ) async throws -> ([HTTPCookie], AccessToken) { do { - let (cookies, token, _) = try await authenticationAPI.login( + let (cookies, token) = try await authenticationAPI.login( email: email, password: password, verificationCode: verificationCode, diff --git a/WireNetwork/Sources/WireNetwork/APIs/Rest/AuthenticationAPI/AuthenticationAPI.swift b/WireNetwork/Sources/WireNetwork/APIs/Rest/AuthenticationAPI/AuthenticationAPI.swift index a0ba6101701..5e49a515a7d 100644 --- a/WireNetwork/Sources/WireNetwork/APIs/Rest/AuthenticationAPI/AuthenticationAPI.swift +++ b/WireNetwork/Sources/WireNetwork/APIs/Rest/AuthenticationAPI/AuthenticationAPI.swift @@ -29,14 +29,14 @@ public protocol AuthenticationAPI: Sendable { /// - verificationCode: The verification code is sent to the given user’s email address, /// this is an optional field and depends on the team/server settings. /// - label: An optional label to associate with the access token. - /// - Returns: HTTP cookie, a valid access token, and userId + /// - Returns: HTTP cookie, a valid access token func login( email: String, password: String, verificationCode: String?, label: String? - ) async throws -> (cookie: [HTTPCookie], accessToken: AccessToken, userId: String) + ) async throws -> ([HTTPCookie], AccessToken) /// Get on-prem config `URL` for domain diff --git a/WireNetwork/Sources/WireNetwork/APIs/Rest/AuthenticationAPI/AuthenticationAPIV0.swift b/WireNetwork/Sources/WireNetwork/APIs/Rest/AuthenticationAPI/AuthenticationAPIV0.swift index 5b93ff3b52d..31315139bda 100644 --- a/WireNetwork/Sources/WireNetwork/APIs/Rest/AuthenticationAPI/AuthenticationAPIV0.swift +++ b/WireNetwork/Sources/WireNetwork/APIs/Rest/AuthenticationAPI/AuthenticationAPIV0.swift @@ -36,7 +36,7 @@ class AuthenticationAPIV0: AuthenticationAPI, VersionedAPI { password: String, verificationCode: String?, label: String? - ) async throws -> (cookie: [HTTPCookie], accessToken: AccessToken, userId: String) { + ) async throws -> ([HTTPCookie], AccessToken) { let path = "\(pathPrefix)/login" let body = LoginRequestBodyV0( email: email, @@ -118,9 +118,7 @@ class AuthenticationAPIV0: AuthenticationAPI, VersionedAPI { throw error } - let userId = accessToken.userID.uuidString - - return (cookies, accessToken, userId) + return (cookies, accessToken) } func getOnPremConfigURL(forDomain domain: String) async throws -> DomainInfo { diff --git a/wire-ios/WireUITests/Helper/UserHelper.swift b/wire-ios/WireUITests/Helper/UserHelper.swift index 3a5105e9b2a..f50942c861c 100644 --- a/wire-ios/WireUITests/Helper/UserHelper.swift +++ b/wire-ios/WireUITests/Helper/UserHelper.swift @@ -95,18 +95,22 @@ class UserHelper { try await authenticationAPI.activateUser(email: user.email, key: activationKey, code: activationCode) // get accessToken for current user - let (_, accessToken, userId) = try await authenticationAPI.login( + let (_, accessToken) = try await authenticationAPI.login( email: user.email, password: user.password, verificationCode: nil, label: nil ) - user.id = userId + authenticationManager.accessToken = accessToken // Set username try await selfUserAPI.updateHandle(handle: user.username) + // Store id in UserInfo + let getSelfUser = try await selfUserAPI.getSelfUser() + user.id = getSelfUser.id.uuidString + createdUsers.append(user) return user } @@ -183,7 +187,7 @@ class UserHelper { try await authenticationAPI.activateUser(email: email, key: activationKey, code: activationCode) - let (_, accessToken, _) = try await authenticationAPI.login( + let (_, accessToken) = try await authenticationAPI.login( email: email, password: password, verificationCode: nil, @@ -272,7 +276,7 @@ class UserHelper { isReadReceiptsEnabled: true ) - let (_, accessToken, _) = try await authenticationAPI.login( + let (_, accessToken) = try await authenticationAPI.login( email: owner.email, password: owner.password, verificationCode: nil, @@ -297,7 +301,7 @@ class UserHelper { userId: String ) async throws { - let (_, accessToken, _) = try await authenticationAPI.login( + let (_, accessToken) = try await authenticationAPI.login( email: user1.email, password: user1.password, verificationCode: nil, diff --git a/wire-ios/WireUITests/Pages/PhotosAppPage.swift b/wire-ios/WireUITests/Pages/PhotosAppPage.swift index 7825f1c650c..2089c37bfef 100644 --- a/wire-ios/WireUITests/Pages/PhotosAppPage.swift +++ b/wire-ios/WireUITests/Pages/PhotosAppPage.swift @@ -62,7 +62,7 @@ class PhotosAppPage: PageModel { func selectConversation(name: String) -> XCUIElement { photosApp.staticTexts[name].firstMatch } - + @discardableResult func continueWhatsNewIfPresent() throws -> PhotosAppPage { if continueButtonOnWhatsNewPhotosApp.waitForExistence(timeout: 3) { From a5366c704ca96d420675f93b25c6e87dd446b91d Mon Sep 17 00:00:00 2001 From: Manish Singh Date: Fri, 2 Jan 2026 13:44:17 +0100 Subject: [PATCH 05/10] formatting --- .../APIs/Rest/AuthenticationAPI/AuthenticationAPI.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WireNetwork/Sources/WireNetwork/APIs/Rest/AuthenticationAPI/AuthenticationAPI.swift b/WireNetwork/Sources/WireNetwork/APIs/Rest/AuthenticationAPI/AuthenticationAPI.swift index 5e49a515a7d..1d2d4c86511 100644 --- a/WireNetwork/Sources/WireNetwork/APIs/Rest/AuthenticationAPI/AuthenticationAPI.swift +++ b/WireNetwork/Sources/WireNetwork/APIs/Rest/AuthenticationAPI/AuthenticationAPI.swift @@ -29,7 +29,7 @@ public protocol AuthenticationAPI: Sendable { /// - verificationCode: The verification code is sent to the given user’s email address, /// this is an optional field and depends on the team/server settings. /// - label: An optional label to associate with the access token. - /// - Returns: HTTP cookie, a valid access token + /// - Returns: HTTP cookie, a valid access token. func login( email: String, From 7684a924c78eb680095b2f2a56039c75e5faa843 Mon Sep 17 00:00:00 2001 From: Manish Singh Date: Thu, 8 Jan 2026 11:55:44 +0100 Subject: [PATCH 06/10] pr feedbacks --- .../ShareExtensionViewController.swift | 3 ++- wire-ios/WireUITests/Helper/UserHelper.swift | 4 ++-- wire-ios/WireUITests/Pages/PhotosAppPage.swift | 17 ++++++++--------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/wire-ios/Wire-iOS Share Extension/Sources/View Controllers/ShareExtensionViewController.swift b/wire-ios/Wire-iOS Share Extension/Sources/View Controllers/ShareExtensionViewController.swift index 612cb491d35..e9ba282e2f1 100644 --- a/wire-ios/Wire-iOS Share Extension/Sources/View Controllers/ShareExtensionViewController.swift +++ b/wire-ios/Wire-iOS Share Extension/Sources/View Controllers/ShareExtensionViewController.swift @@ -32,6 +32,7 @@ import WireLogging import WireNetwork import WireShareEngine import WireUtilities +import WireLocators typealias Completion = () -> Void private let zmLog = ZMSLog(tag: "UI") @@ -185,7 +186,7 @@ final class ShareExtensionViewController: SLComposeServiceViewController { guard let item = navigationController?.navigationBar.items?.first else { return } item.rightBarButtonItem?.action = #selector(appendPostTapped) item.rightBarButtonItem?.title = L10n.ShareExtension.SendButton.title - item.rightBarButtonItem?.accessibilityIdentifier = "sendButtonOnShareExtension" + item.rightBarButtonItem?.accessibilityIdentifier = Locators.ShareExtensionPage.sendButtonOnShareExtension.rawValue item .titleView = UIImageView( image: WireStyleKit.imageOfLogo(color: UIColor.Wire.primaryLabel) diff --git a/wire-ios/WireUITests/Helper/UserHelper.swift b/wire-ios/WireUITests/Helper/UserHelper.swift index f50942c861c..a5b00c6c7fa 100644 --- a/wire-ios/WireUITests/Helper/UserHelper.swift +++ b/wire-ios/WireUITests/Helper/UserHelper.swift @@ -108,8 +108,8 @@ class UserHelper { try await selfUserAPI.updateHandle(handle: user.username) // Store id in UserInfo - let getSelfUser = try await selfUserAPI.getSelfUser() - user.id = getSelfUser.id.uuidString + let selfUser = try await selfUserAPI.getSelfUser() + user.id = selfUser.id.uuidString createdUsers.append(user) return user diff --git a/wire-ios/WireUITests/Pages/PhotosAppPage.swift b/wire-ios/WireUITests/Pages/PhotosAppPage.swift index 2089c37bfef..e576859d59a 100644 --- a/wire-ios/WireUITests/Pages/PhotosAppPage.swift +++ b/wire-ios/WireUITests/Pages/PhotosAppPage.swift @@ -21,6 +21,7 @@ import XCTest class PhotosAppPage: PageModel { private let photosApp: XCUIApplication + private let timeout: TimeInterval = 2 override var pageMainElement: XCUIElement { photosApp.windows.firstMatch @@ -36,9 +37,7 @@ class PhotosAppPage: PageModel { } var firstImageTile: XCUIElement { - photosApp.images - .matching(identifier: Locators.ShareExtensionPage.imageTile.rawValue) - .element(boundBy: 0) + photosApp.images[Locators.ShareExtensionPage.imageTile.rawValue].firstMatch } var shareButton: XCUIElement { @@ -65,7 +64,7 @@ class PhotosAppPage: PageModel { @discardableResult func continueWhatsNewIfPresent() throws -> PhotosAppPage { - if continueButtonOnWhatsNewPhotosApp.waitForExistence(timeout: 3) { + if continueButtonOnWhatsNewPhotosApp.waitForExistence(timeout: timeout) { continueButtonOnWhatsNewPhotosApp.tap() } return self @@ -84,22 +83,22 @@ class PhotosAppPage: PageModel { @discardableResult func shareImageToWire() throws -> PhotosAppPage { - XCTAssertTrue(shareButton.waitForExistence(timeout: 10)) + XCTAssertTrue(shareButton.waitForExistence(timeout: timeout)) shareButton.tap() - XCTAssertTrue(shareToWireApp.waitForExistence(timeout: 10)) + XCTAssertTrue(shareToWireApp.waitForExistence(timeout: timeout)) shareToWireApp.tap() return self } func chooseConversationAndSend(name: String) throws { - XCTAssertTrue(chooseConversationButton.waitForExistence(timeout: 10)) + XCTAssertTrue(chooseConversationButton.waitForExistence(timeout: timeout)) chooseConversationButton.tap() let conversationToSend = selectConversation(name: name) - XCTAssertTrue(conversationToSend.waitForExistence(timeout: 10)) + XCTAssertTrue(conversationToSend.waitForExistence(timeout: timeout)) conversationToSend.tap() - XCTAssertTrue(sendButton.waitForExistence(timeout: 10)) + XCTAssertTrue(sendButton.waitForExistence(timeout: timeout)) sendButton.tap() } From ce37bea09de0003fdb4bcd667936bb696bf090ea Mon Sep 17 00:00:00 2001 From: Manish Singh Date: Thu, 8 Jan 2026 12:03:29 +0100 Subject: [PATCH 07/10] formatting --- .../View Controllers/ShareExtensionViewController.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wire-ios/Wire-iOS Share Extension/Sources/View Controllers/ShareExtensionViewController.swift b/wire-ios/Wire-iOS Share Extension/Sources/View Controllers/ShareExtensionViewController.swift index e9ba282e2f1..76574fcb48a 100644 --- a/wire-ios/Wire-iOS Share Extension/Sources/View Controllers/ShareExtensionViewController.swift +++ b/wire-ios/Wire-iOS Share Extension/Sources/View Controllers/ShareExtensionViewController.swift @@ -28,11 +28,11 @@ import WireDesign import WireDomain import WireFoundation import WireLinkPreview +import WireLocators import WireLogging import WireNetwork import WireShareEngine import WireUtilities -import WireLocators typealias Completion = () -> Void private let zmLog = ZMSLog(tag: "UI") @@ -186,7 +186,8 @@ final class ShareExtensionViewController: SLComposeServiceViewController { guard let item = navigationController?.navigationBar.items?.first else { return } item.rightBarButtonItem?.action = #selector(appendPostTapped) item.rightBarButtonItem?.title = L10n.ShareExtension.SendButton.title - item.rightBarButtonItem?.accessibilityIdentifier = Locators.ShareExtensionPage.sendButtonOnShareExtension.rawValue + item.rightBarButtonItem?.accessibilityIdentifier = Locators.ShareExtensionPage.sendButtonOnShareExtension + .rawValue item .titleView = UIImageView( image: WireStyleKit.imageOfLogo(color: UIColor.Wire.primaryLabel) From ccefa168c8b16340d6c364f0ed85d16b74184dfd Mon Sep 17 00:00:00 2001 From: Manish Singh Date: Thu, 8 Jan 2026 17:00:02 +0100 Subject: [PATCH 08/10] formatting + feedbacks --- wire-ios/WireUITests/Pages/PhotosAppPage.swift | 7 ++++++- wire-ios/WireUITests/ShareExtensionTests.swift | 9 +++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/wire-ios/WireUITests/Pages/PhotosAppPage.swift b/wire-ios/WireUITests/Pages/PhotosAppPage.swift index e576859d59a..0e46af8cf0f 100644 --- a/wire-ios/WireUITests/Pages/PhotosAppPage.swift +++ b/wire-ios/WireUITests/Pages/PhotosAppPage.swift @@ -74,7 +74,7 @@ class PhotosAppPage: PageModel { func openFirstImage() throws -> PhotosAppPage { try continueWhatsNewIfPresent() XCTAssertTrue(firstImageTile.waitForExistence(timeout: 10)) - // NOTE: Use a coordinate tap on center because Photos grid cells are not always directly hittable in UITests + // NOTE: Tap the center via coordinates because Photos grid cells are often not directly hittable in UITests firstImageTile .coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5)) .tap() @@ -91,6 +91,8 @@ class PhotosAppPage: PageModel { } func chooseConversationAndSend(name: String) throws { + defer { photosApp.terminate() } + XCTAssertTrue(chooseConversationButton.waitForExistence(timeout: timeout)) chooseConversationButton.tap() @@ -100,6 +102,9 @@ class PhotosAppPage: PageModel { XCTAssertTrue(sendButton.waitForExistence(timeout: timeout)) sendButton.tap() + + XCTAssertTrue(shareButton.waitForExistence(timeout: timeout)) + photosApp.terminate() } } diff --git a/wire-ios/WireUITests/ShareExtensionTests.swift b/wire-ios/WireUITests/ShareExtensionTests.swift index 7f970bd09e8..f7640173d87 100644 --- a/wire-ios/WireUITests/ShareExtensionTests.swift +++ b/wire-ios/WireUITests/ShareExtensionTests.swift @@ -23,18 +23,19 @@ import XCTest final class ShareExtensionTests: WireUITestCase { private let photosAppBundleId = XCUIApplication(bundleIdentifier: "com.apple.mobileslideshow") + private let timeout: TimeInterval = 2 @MainActor private func launchPhotosApp() async throws { photosAppBundleId.launch() - XCTAssertTrue(photosAppBundleId.wait(for: .runningForeground, timeout: 10)) + XCTAssertTrue(photosAppBundleId.wait(for: .runningForeground, timeout: timeout)) } @MainActor private func shareFirstPhotoToWire(name: String) async throws { let photosApp = try PhotosAppPage(photosApp: photosAppBundleId) try photosApp - .openFirstImage() + .openImage() .shareImageToWire() .chooseConversationAndSend(name: name) } @@ -42,9 +43,9 @@ final class ShareExtensionTests: WireUITestCase { @MainActor private func switchBackToWireApp() async throws { app.activate() - if !app.wait(for: .runningForeground, timeout: 10) { + if !app.wait(for: .runningForeground, timeout: timeout) { app.launch() - _ = app.wait(for: .runningForeground, timeout: 10) + _ = app.wait(for: .runningForeground, timeout: timeout) } } From 4ddc905115ee146e4bead4d729e6ba3a331faa52 Mon Sep 17 00:00:00 2001 From: Manish Singh Date: Thu, 8 Jan 2026 17:02:56 +0100 Subject: [PATCH 09/10] typo fixed --- wire-ios/WireUITests/ShareExtensionTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wire-ios/WireUITests/ShareExtensionTests.swift b/wire-ios/WireUITests/ShareExtensionTests.swift index f7640173d87..eaacad42d61 100644 --- a/wire-ios/WireUITests/ShareExtensionTests.swift +++ b/wire-ios/WireUITests/ShareExtensionTests.swift @@ -35,7 +35,7 @@ final class ShareExtensionTests: WireUITestCase { private func shareFirstPhotoToWire(name: String) async throws { let photosApp = try PhotosAppPage(photosApp: photosAppBundleId) try photosApp - .openImage() + .openFirstImage() .shareImageToWire() .chooseConversationAndSend(name: name) } From 5cc4873b5cb9210ad57b461a998aba5e94bb1a92 Mon Sep 17 00:00:00 2001 From: Manish Singh Date: Thu, 8 Jan 2026 17:14:13 +0100 Subject: [PATCH 10/10] file header swiftlint issue --- wire-ios/WireUITests/Pages/PhotosAppPage.swift | 2 +- wire-ios/WireUITests/ShareExtensionTests.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/wire-ios/WireUITests/Pages/PhotosAppPage.swift b/wire-ios/WireUITests/Pages/PhotosAppPage.swift index 0e46af8cf0f..aee38a9e117 100644 --- a/wire-ios/WireUITests/Pages/PhotosAppPage.swift +++ b/wire-ios/WireUITests/Pages/PhotosAppPage.swift @@ -1,6 +1,6 @@ // // Wire -// Copyright (C) 2025 Wire Swiss GmbH +// Copyright (C) 2026 Wire Swiss GmbH // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by diff --git a/wire-ios/WireUITests/ShareExtensionTests.swift b/wire-ios/WireUITests/ShareExtensionTests.swift index eaacad42d61..cf07968e5f5 100644 --- a/wire-ios/WireUITests/ShareExtensionTests.swift +++ b/wire-ios/WireUITests/ShareExtensionTests.swift @@ -1,6 +1,6 @@ // // Wire -// Copyright (C) 2025 Wire Swiss GmbH +// Copyright (C) 2026 Wire Swiss GmbH // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by