diff --git a/.github/workflows/integ_test_auth.yml b/.github/workflows/integ_test_auth.yml index ab67b782fe..86d4e5c2c3 100644 --- a/.github/workflows/integ_test_auth.yml +++ b/.github/workflows/integ_test_auth.yml @@ -22,6 +22,11 @@ on: required: true default: true type: boolean + webauthn-ios: + description: 'WebAuthn iOS' + required: true + default: true + type: boolean workflow_call: permissions: @@ -60,6 +65,7 @@ jobs: secrets: inherit auth-webauthn-integration-test-iOS: + if: ${{ inputs.webauthn-ios != 'false' }} name: Auth WebAuthn Integration Tests (iOS) uses: ./.github/workflows/integ_test_auth_webauthn.yml secrets: inherit diff --git a/.github/workflows/integ_test_auth_webauthn.yml b/.github/workflows/integ_test_auth_webauthn.yml index f965a11531..2aa587c94a 100644 --- a/.github/workflows/integ_test_auth_webauthn.yml +++ b/.github/workflows/integ_test_auth_webauthn.yml @@ -69,6 +69,10 @@ jobs: npm install npm start & shell: bash + + - name: Verify server is running + run: | + curl --fail -X POST http://127.0.0.1:9293/boot || exit 1 - name: Run iOS Integration Tests id: run-tests @@ -85,6 +89,10 @@ jobs: derived_data_path: ${{ github.workspace }}/Build disable_package_resolution: ${{ steps.dependencies-cache.outputs.cache-hit }} + - name: Enrol Biometrics + run: | + curl --fail -X POST http://127.0.0.1:9293/enroll || exit 1 + - name: Retry iOS Integration Tests if: steps.run-tests.outcome=='failure' id: retry-tests diff --git a/AmplifyPlugins/Auth/Tests/AuthWebAuthnApp/AuthWebAuthnAppUITests/AuthWebAuthnAppUITests.swift b/AmplifyPlugins/Auth/Tests/AuthWebAuthnApp/AuthWebAuthnAppUITests/AuthWebAuthnAppUITests.swift index a314bd2fb3..fd4ebca922 100644 --- a/AmplifyPlugins/Auth/Tests/AuthWebAuthnApp/AuthWebAuthnAppUITests/AuthWebAuthnAppUITests.swift +++ b/AmplifyPlugins/Auth/Tests/AuthWebAuthnApp/AuthWebAuthnAppUITests/AuthWebAuthnAppUITests.swift @@ -21,21 +21,9 @@ final class AuthWebAuthnAppUITests: XCTestCase { private var springboard: XCUIApplication! private var continueButton: XCUIElement! - private lazy var deviceIdentifier: String = { - let paths = Bundle.main.bundleURL.pathComponents - guard let index = paths.firstIndex(where: { $0 == "Devices" }), - let identifier = paths.dropFirst(index + 1).first - else { - fatalError("Failed to get device identifier") - } - - return identifier - }() - @MainActor override func setUp() async throws { continueAfterFailure = false - try await bootDevice() try await enrollBiometrics() if ProcessInfo.processInfo.arguments.contains("GEN2") { app.launchArguments.append("GEN2") @@ -162,25 +150,25 @@ final class AuthWebAuthnAppUITests: XCTestCase { } private func bootDevice() async throws { - let request = LocalServer.boot(deviceIdentifier).urlRequest + let request = LocalServer.boot.urlRequest let (_, response) = try await URLSession.shared.data(for: request) XCTAssertTrue((response as! HTTPURLResponse).statusCode < 300, "Failed to boot the device") } private func enrollBiometrics() async throws { - let request = LocalServer.enroll(deviceIdentifier).urlRequest + let request = LocalServer.enroll.urlRequest let (_, response) = try await URLSession.shared.data(for: request) XCTAssertTrue((response as! HTTPURLResponse).statusCode < 300, "Failed to enroll biometrics in the device") } private func matchBiometrics() async throws { - let request = LocalServer.match(deviceIdentifier).urlRequest + let request = LocalServer.match.urlRequest let (_, response) = try await URLSession.shared.data(for: request) XCTAssertTrue((response as! HTTPURLResponse).statusCode < 300, "Failed to match biometrics in the device") } private func uninstallApp() async throws { - let request = LocalServer.uninstall(deviceIdentifier).urlRequest + let request = LocalServer.uninstall.urlRequest let (_, response) = try await URLSession.shared.data(for: request) XCTAssertTrue((response as! HTTPURLResponse).statusCode < 300, "Failed to uninstall the App") } diff --git a/AmplifyPlugins/Auth/Tests/AuthWebAuthnApp/AuthWebAuthnAppUITests/LocalServer.swift b/AmplifyPlugins/Auth/Tests/AuthWebAuthnApp/AuthWebAuthnAppUITests/LocalServer.swift index 07e7c02a3c..90527c4a7a 100644 --- a/AmplifyPlugins/Auth/Tests/AuthWebAuthnApp/AuthWebAuthnAppUITests/LocalServer.swift +++ b/AmplifyPlugins/Auth/Tests/AuthWebAuthnApp/AuthWebAuthnAppUITests/LocalServer.swift @@ -10,10 +10,10 @@ import Foundation enum LocalServer { static let endpoint = "http://127.0.0.1:9293" - case boot(String) - case enroll(String) - case match(String) - case uninstall(String) + case boot + case enroll + case match + case uninstall } extension LocalServer { @@ -32,11 +32,11 @@ extension LocalServer { var payload: Data? { switch self { - case .boot(let deviceId), - .enroll(let deviceId), - .match(let deviceId), - .uninstall(let deviceId): - return try? JSONEncoder().encode(["deviceId": deviceId]) + case .boot, + .enroll, + .match, + .uninstall: + return try? JSONEncoder().encode(["deviceId": ""]) } } diff --git a/AmplifyPlugins/Auth/Tests/AuthWebAuthnApp/LocalServer/index.mjs b/AmplifyPlugins/Auth/Tests/AuthWebAuthnApp/LocalServer/index.mjs index 1ca545833c..d7b7705d7b 100644 --- a/AmplifyPlugins/Auth/Tests/AuthWebAuthnApp/LocalServer/index.mjs +++ b/AmplifyPlugins/Auth/Tests/AuthWebAuthnApp/LocalServer/index.mjs @@ -19,10 +19,21 @@ const run = (cmd) => { }) } +const getDeviceId = async () => { + const cmd = `xcrun simctl list | grep "iPhone" | grep "Booted" | awk -F '[()]' '{print $2}' | uniq` + try { + const deviceId = await run(cmd) + return deviceId.trim() + } catch (error) { + console.error("Failed to retrieve deviceId", error) + throw new Error("Failed to retrieve deviceId") + } +} + app.post('/uninstall', async (req, res) => { console.log("POST /uninstall ") - const { deviceId } = req.body try { + const deviceId = await getDeviceId() const cmd = `xcrun simctl uninstall ${deviceId} ${bundleId}` await run(cmd) res.send("Done") @@ -34,8 +45,8 @@ app.post('/uninstall', async (req, res) => { app.post('/boot', async (req, res) => { console.log("POST /boot ") - const { deviceId } = req.body try { + const deviceId = await getDeviceId() const cmd = `xcrun simctl bootstatus ${deviceId} -b` await run(cmd) res.send("Done") @@ -47,8 +58,8 @@ app.post('/boot', async (req, res) => { app.post('/enroll', async (req, res) => { console.log("POST /enroll ") - const { deviceId } = req.body try { + const deviceId = await getDeviceId() const cmd = `xcrun simctl spawn ${deviceId} notifyutil -s com.apple.BiometricKit.enrollmentChanged '1' && xcrun simctl spawn ${deviceId} notifyutil -p com.apple.BiometricKit.enrollmentChanged` await run(cmd) res.send("Done") @@ -58,20 +69,17 @@ app.post('/enroll', async (req, res) => { } }) - app.post('/match', async (req, res) => { console.log("POST /match ") - const { deviceId } = req.body try { + const deviceId = await getDeviceId() const cmd = `xcrun simctl spawn ${deviceId} notifyutil -p com.apple.BiometricKit_Sim.fingerTouch.match` await run(cmd) res.send("Done") } catch (error) { - console.error("Failed to match biometrics", error) + console.error("Failed to match biometrics in the device", error) res.sendStatus(500) } }) -app.listen(9293, () => { - console.log("Simulator server started!") -}) +export default app \ No newline at end of file