Skip to content

Commit 38d3113

Browse files
test: create user UI flow
1 parent be2a093 commit 38d3113

File tree

9 files changed

+129
-15
lines changed

9 files changed

+129
-15
lines changed

FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ extension AuthPickerView: View {
5252
.emailLoginFlowLabel : authService.string.emailSignUpFlowLabel)
5353
.fontWeight(.semibold)
5454
.foregroundColor(.blue)
55-
}
55+
}.accessibilityIdentifier("switch-auth-flow")
5656
}
5757
PrivacyTOCsView(displayMode: .footer)
5858
Text(authService.errorMessage).foregroundColor(.red)

FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EmailAuthView.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ extension EmailAuthView: View {
7070
LabeledContent {
7171
SecureField(authService.string.passwordInputLabel, text: $password)
7272
.focused($focus, equals: .password)
73+
.textInputAutocapitalization(.never)
74+
.disableAutocorrection(true)
7375
.submitLabel(.go)
7476
.onSubmit {
7577
Task { await signInWithEmailPassword() }
@@ -94,6 +96,8 @@ extension EmailAuthView: View {
9496
LabeledContent {
9597
SecureField(authService.string.confirmPasswordInputLabel, text: $confirmPassword)
9698
.focused($focus, equals: .confirmPassword)
99+
.textInputAutocapitalization(.never)
100+
.disableAutocorrection(true)
97101
.submitLabel(.go)
98102
.onSubmit {
99103
Task { await createUserWithEmailPassword() }
@@ -104,6 +108,7 @@ extension EmailAuthView: View {
104108
.padding(.vertical, 6)
105109
.background(Divider(), alignment: .bottom)
106110
.padding(.bottom, 8)
111+
.accessibilityIdentifier("confirm-password-field")
107112
}
108113

109114
Button(action: {

samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample.xcodeproj/project.pbxproj

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
4600E5522DD777BE00EED5F3 /* FirebaseAuth in Frameworks */ = {isa = PBXBuildFile; productRef = 4600E5512DD777BE00EED5F3 /* FirebaseAuth */; };
11+
4600E5542DD777BE00EED5F3 /* FirebaseCore in Frameworks */ = {isa = PBXBuildFile; productRef = 4600E5532DD777BE00EED5F3 /* FirebaseCore */; };
1012
4607CC9C2D9BFE29009EC3F5 /* FirebaseAuthSwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = 4607CC9B2D9BFE29009EC3F5 /* FirebaseAuthSwiftUI */; };
1113
4607CC9E2D9BFE29009EC3F5 /* FirebaseGoogleSwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = 4607CC9D2D9BFE29009EC3F5 /* FirebaseGoogleSwiftUI */; };
1214
46CB7B252D773F2100F1FD0A /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 46CB7B242D773F2100F1FD0A /* GoogleService-Info.plist */; };
@@ -96,6 +98,8 @@
9698
isa = PBXFrameworksBuildPhase;
9799
buildActionMask = 2147483647;
98100
files = (
101+
4600E5542DD777BE00EED5F3 /* FirebaseCore in Frameworks */,
102+
4600E5522DD777BE00EED5F3 /* FirebaseAuth in Frameworks */,
99103
);
100104
runOnlyForDeploymentPostprocessing = 0;
101105
};
@@ -203,6 +207,8 @@
203207
);
204208
name = FirebaseSwiftUIExampleUITests;
205209
packageProductDependencies = (
210+
4600E5512DD777BE00EED5F3 /* FirebaseAuth */,
211+
4600E5532DD777BE00EED5F3 /* FirebaseCore */,
206212
);
207213
productName = FirebaseSwiftUIExampleUITests;
208214
productReference = 46F89C242D64A86D000F8BC0 /* FirebaseSwiftUIExampleUITests.xctest */;
@@ -242,6 +248,7 @@
242248
minimizedProjectReferenceProxies = 1;
243249
packageReferences = (
244250
8D808CB52DB07EBD00D2293F /* XCLocalSwiftPackageReference "../../../../FirebaseUI-iOS" */,
251+
4600E5502DD777BE00EED5F3 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */,
245252
);
246253
preferredProjectObjectVersion = 77;
247254
productRefGroup = 46F89C092D64A86C000F8BC0 /* Products */;
@@ -623,7 +630,28 @@
623630
};
624631
/* End XCLocalSwiftPackageReference section */
625632

633+
/* Begin XCRemoteSwiftPackageReference section */
634+
4600E5502DD777BE00EED5F3 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = {
635+
isa = XCRemoteSwiftPackageReference;
636+
repositoryURL = "https://github.com/firebase/firebase-ios-sdk";
637+
requirement = {
638+
kind = upToNextMajorVersion;
639+
minimumVersion = 11.12.0;
640+
};
641+
};
642+
/* End XCRemoteSwiftPackageReference section */
643+
626644
/* Begin XCSwiftPackageProductDependency section */
645+
4600E5512DD777BE00EED5F3 /* FirebaseAuth */ = {
646+
isa = XCSwiftPackageProductDependency;
647+
package = 4600E5502DD777BE00EED5F3 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
648+
productName = FirebaseAuth;
649+
};
650+
4600E5532DD777BE00EED5F3 /* FirebaseCore */ = {
651+
isa = XCSwiftPackageProductDependency;
652+
package = 4600E5502DD777BE00EED5F3 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
653+
productName = FirebaseCore;
654+
};
627655
4607CC9B2D9BFE29009EC3F5 /* FirebaseAuthSwiftUI */ = {
628656
isa = XCSwiftPackageProductDependency;
629657
productName = FirebaseAuthSwiftUI;

samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/ContentView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ struct ContentView: View {
2525
actionCodeSettings.linkDomain = "flutterfire-e2e-tests.firebaseapp.com"
2626
actionCodeSettings.setIOSBundleID(Bundle.main.bundleIdentifier!)
2727
let configuration = AuthConfiguration(
28-
shouldAutoUpgradeAnonymousUsers: isUITestRunner ? false : true,
28+
shouldAutoUpgradeAnonymousUsers: uiAuthEmulator ? false : true,
2929
tosUrl: URL(string: "https://example.com/tos"),
3030
privacyPolicyUrl: URL(string: "https://example.com/privacy"),
3131
emailLinkSignInActionCodeSettings: actionCodeSettings
3232
)
33-
33+
3434
authService = AuthService(
3535
configuration: configuration
3636
)

samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample/FirebaseSwiftUIExampleApp.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,16 @@ import FirebaseCore
1010
import GoogleSignIn
1111
import SwiftUI
1212

13-
public let isUITestRunner = CommandLine.arguments.contains("--ui-test-runner")
14-
1513
class AppDelegate: NSObject, UIApplicationDelegate {
1614
func application(_ application: UIApplication,
1715
didFinishLaunchingWithOptions launchOptions: [
1816
UIApplication.LaunchOptionsKey: Any
1917
]?) -> Bool {
2018
FirebaseApp.configure()
21-
if isUITestRunner {
19+
if uiAuthEmulator {
2220
Auth.auth().useEmulator(withHost: "localhost", port: 9099)
2321
}
22+
2423
ApplicationDelegate.shared.application(
2524
application,
2625
didFinishLaunchingWithOptions: launchOptions
@@ -63,6 +62,12 @@ class AppDelegate: NSObject, UIApplicationDelegate {
6362
struct FirebaseSwiftUIExampleApp: App {
6463
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
6564

65+
init() {
66+
Task {
67+
try await testCreateUser()
68+
}
69+
}
70+
6671
var body: some Scene {
6772
WindowGroup {
6873
NavigationView {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//
2+
// UITestUtils.swift
3+
// FirebaseSwiftUIExample
4+
//
5+
// Created by Russell Wheatley on 16/05/2025.
6+
//
7+
import FirebaseAuth
8+
import SwiftUI
9+
10+
// UI Test Runner keys
11+
public let uiAuthEmulator = CommandLine.arguments.contains("--auth-emulator")
12+
13+
public var testEmail: String? {
14+
guard let emailIndex = CommandLine.arguments.firstIndex(of: "--create-user"),
15+
CommandLine.arguments.indices.contains(emailIndex + 1)
16+
else { return nil }
17+
return CommandLine.arguments[emailIndex + 1]
18+
}
19+
20+
func testCreateUser() async throws {
21+
if let email = testEmail {
22+
let password = "123456"
23+
let auth = Auth.auth()
24+
try await auth.createUser(withEmail: email, password: password)
25+
try auth.signOut()
26+
}
27+
}

samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExampleTests/FirebaseSwiftUIExampleTests.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,6 @@ struct FirebaseSwiftUIExampleTests {
2424
return AuthService(configuration: resolvedConfiguration)
2525
}
2626

27-
func createEmail() -> String {
28-
let before = UUID().uuidString.prefix(8)
29-
let after = UUID().uuidString.prefix(6)
30-
return "\(before)@\(after).com"
31-
}
32-
3327
@Test
3428
@MainActor
3529
func testDefaultAuthConfigurationInjection() async throws {

samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExampleTests/TestHarness.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,9 @@ func clearAuthEmulatorState(projectID: String = "flutterfire-e2e-tests") async t
5757
print("🔥 clearAuthEmulatorState: status = \(httpResponse.statusCode)")
5858
}
5959
}
60+
61+
func createEmail() -> String {
62+
let before = UUID().uuidString.prefix(8)
63+
let after = UUID().uuidString.prefix(6)
64+
return "\(before)@\(after).com"
65+
}

samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExampleUITests/FirebaseSwiftUIExampleUITests.swift

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,16 @@
55
// Created by Russell Wheatley on 18/02/2025.
66
//
77

8+
import FirebaseAuth
9+
import FirebaseCore
810
import XCTest
911

12+
func createEmail() -> String {
13+
let before = UUID().uuidString.prefix(8)
14+
let after = UUID().uuidString.prefix(6)
15+
return "\(before)@\(after).com"
16+
}
17+
1018
final class FirebaseSwiftUIExampleUITests: XCTestCase {
1119
override func setUpWithError() throws {
1220
continueAfterFailure = false
@@ -30,15 +38,17 @@ final class FirebaseSwiftUIExampleUITests: XCTestCase {
3038
}
3139

3240
@MainActor
33-
func testSignInDisplaysSignedInView() throws {
41+
func testSignInDisplaysSignedInView() async throws {
3442
let app = XCUIApplication()
35-
app.launchArguments.append("--ui-test-runner")
43+
let email = createEmail()
44+
app.launchArguments.append("--auth-emulator")
45+
app.launchArguments.append("--create-user \(email)")
3646
app.launch()
3747

3848
let emailField = app.textFields["email-field"]
3949
XCTAssertTrue(emailField.waitForExistence(timeout: 2), "Email field should exist")
4050
emailField.tap()
41-
emailField.typeText("[email protected]")
51+
emailField.typeText(email)
4252

4353
let passwordField = app.secureTextFields["password-field"]
4454
XCTAssertTrue(passwordField.exists, "Password field should exist")
@@ -55,4 +65,43 @@ final class FirebaseSwiftUIExampleUITests: XCTestCase {
5565
"SignedInView should be visible after login"
5666
)
5767
}
68+
69+
@MainActor
70+
func testCreateUserDisplaysSignedInView() throws {
71+
let app = XCUIApplication()
72+
let email = createEmail()
73+
let password = "qwerty321@"
74+
app.launchArguments.append("--ui-test-runner")
75+
app.launch()
76+
77+
let switchFlowButton = app.buttons["switch-auth-flow"]
78+
switchFlowButton.tap()
79+
80+
let emailField = app.textFields["email-field"]
81+
82+
XCTAssertTrue(emailField.waitForExistence(timeout: 2), "Email field should exist")
83+
emailField.tap()
84+
emailField.typeText(email)
85+
86+
let passwordField = app.secureTextFields["password-field"]
87+
XCTAssertTrue(passwordField.exists, "Password field should exist")
88+
passwordField.tap()
89+
passwordField.typeText(password)
90+
91+
let confirmPasswordField = app.secureTextFields["confirm-password-field"]
92+
XCTAssertTrue(confirmPasswordField.exists, "Confirm password field should exist")
93+
confirmPasswordField.tap()
94+
confirmPasswordField.typeText(password)
95+
Thread.sleep(forTimeInterval: 3)
96+
97+
let signInButton = app.buttons["sign-in-button"]
98+
XCTAssertTrue(signInButton.exists, "Sign-In button should exist")
99+
signInButton.tap()
100+
101+
let signedInText = app.staticTexts["signed-in-text"]
102+
XCTAssertTrue(
103+
signedInText.waitForExistence(timeout: 10),
104+
"SignedInView should be visible after login"
105+
)
106+
}
58107
}

0 commit comments

Comments
 (0)