Skip to content

Commit 017479f

Browse files
Merge pull request #1257 from firebase/swiftui-tests
2 parents 616f3f4 + 758fe3f commit 017479f

File tree

22 files changed

+744
-81
lines changed

22 files changed

+744
-81
lines changed

.github/workflows/swiftui-auth.yml

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
name: SwiftUI Auth
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
paths:
7+
- '.github/workflows/swiftui-auth.yml'
8+
- 'samples/swiftui/**'
9+
- 'FirebaseSwiftUI/**'
10+
- 'Package.swift'
11+
pull_request:
12+
branches: [ main ]
13+
paths:
14+
- '.github/workflows/swiftui-auth.yml'
15+
- 'samples/swiftui/**'
16+
- 'FirebaseSwiftUI/**'
17+
- 'Package.swift'
18+
19+
workflow_dispatch:
20+
21+
permissions:
22+
contents: read
23+
24+
jobs:
25+
swiftui-auth:
26+
runs-on: macOS-latest
27+
timeout-minutes: 30
28+
steps:
29+
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
30+
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a
31+
name: Install Node.js 20
32+
with:
33+
node-version: '20'
34+
- uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b
35+
with:
36+
distribution: 'temurin'
37+
java-version: '17'
38+
- name: Install Firebase
39+
run: |
40+
sudo npm i -g firebase-tools
41+
- name: Start Firebase Emulator
42+
run: |
43+
sudo chown -R 501:20 "/Users/runner/.npm" && cd ./samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExample && ./start-firebase-emulator.sh
44+
- name: Install xcpretty
45+
run: gem install xcpretty
46+
- name: Select Xcode version
47+
run: |
48+
sudo xcode-select -switch /Applications/Xcode_16.1.app/Contents/Developer
49+
- name: Run Integration Tests
50+
run: |
51+
cd ./samples/swiftui/FirebaseSwiftUIExample
52+
set -o pipefail
53+
xcodebuild test -scheme FirebaseSwiftUIExampleTests -destination 'platform=iOS Simulator,name=iPhone 16 Plus' -enableCodeCoverage YES -resultBundlePath FirebaseSwiftUIExampleTests.xcresult | tee FirebaseSwiftUIExampleTests.log | xcpretty --test --color --simple
54+
- name: Run View UI Tests
55+
run: |
56+
cd ./samples/swiftui/FirebaseSwiftUIExample
57+
set -o pipefail
58+
xcodebuild test -scheme FirebaseSwiftUIExampleUITests -destination 'platform=iOS Simulator,name=iPhone 16 Plus' -enableCodeCoverage YES -resultBundlePath FirebaseSwiftUIExampleUITests.xcresult | tee FirebaseSwiftUIExampleUITests.log | xcpretty --test --color --simple
59+
- name: Upload test logs
60+
if: failure()
61+
uses: actions/upload-artifact@v4
62+
with:
63+
name: swiftui-auth-test-logs
64+
path: |
65+
samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExampleTests.log
66+
samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExampleUITests.log
67+
- name: Upload FirebaseSwiftUIExampleUITests.xcresult bundle
68+
if: failure()
69+
uses: actions/upload-artifact@v4
70+
with:
71+
name: FirebaseSwiftUIExampleUITests.xcresult
72+
path: samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExampleUITests.xcresult
73+
- name: Upload FirebaseSwiftUIExampleTests.xcresult bundle
74+
if: failure()
75+
uses: actions/upload-artifact@v4
76+
with:
77+
name: FirebaseSwiftUIExampleTests.xcresult
78+
path: samples/swiftui/FirebaseSwiftUIExample/FirebaseSwiftUIExampleTests.xcresult

FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthConfiguration.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ import FirebaseAuth
1616
import Foundation
1717

1818
public struct AuthConfiguration {
19-
let shouldHideCancelButton: Bool
20-
let interactiveDismissEnabled: Bool
21-
let shouldAutoUpgradeAnonymousUsers: Bool
22-
let customStringsBundle: Bundle?
23-
let tosUrl: URL?
24-
let privacyPolicyUrl: URL?
25-
let emailLinkSignInActionCodeSettings: ActionCodeSettings?
26-
let verifyEmailActionCodeSettings: ActionCodeSettings?
19+
public let shouldHideCancelButton: Bool
20+
public let interactiveDismissEnabled: Bool
21+
public let shouldAutoUpgradeAnonymousUsers: Bool
22+
public let customStringsBundle: Bundle?
23+
public let tosUrl: URL?
24+
public let privacyPolicyUrl: URL?
25+
public let emailLinkSignInActionCodeSettings: ActionCodeSettings?
26+
public let verifyEmailActionCodeSettings: ActionCodeSettings?
2727

2828
public init(shouldHideCancelButton: Bool = false,
2929
interactiveDismissEnabled: Bool = true,

FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Services/AuthService.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ public final class AuthService {
142142
private var unsafePhoneAuthProvider: (any PhoneAuthProviderAuthUIProtocol)?
143143

144144
private var listenerManager: AuthListenerManager?
145-
private var signedInCredential: AuthCredential?
145+
public var signedInCredential: AuthCredential?
146146

147147
var emailSignInEnabled = false
148148

FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/AuthPickerView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ extension AuthPickerView: View {
8282
.emailLoginFlowLabel : authService.string.emailSignUpFlowLabel)
8383
.fontWeight(.semibold)
8484
.foregroundColor(.blue)
85-
}
85+
}.accessibilityIdentifier("switch-auth-flow")
8686
}
8787
}
8888
PrivacyTOCsView(displayMode: .footer)

FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EmailAuthView.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,13 @@ extension EmailAuthView: View {
7979
.padding(.vertical, 6)
8080
.background(Divider(), alignment: .bottom)
8181
.padding(.bottom, 4)
82+
.accessibilityIdentifier("email-field")
8283

8384
LabeledContent {
8485
SecureField(authService.string.passwordInputLabel, text: $password)
8586
.focused($focus, equals: .password)
87+
.textInputAutocapitalization(.never)
88+
.disableAutocorrection(true)
8689
.submitLabel(.go)
8790
.onSubmit {
8891
Task { await signInWithEmailPassword() }
@@ -93,19 +96,22 @@ extension EmailAuthView: View {
9396
.padding(.vertical, 6)
9497
.background(Divider(), alignment: .bottom)
9598
.padding(.bottom, 8)
99+
.accessibilityIdentifier("password-field")
96100

97101
if authService.authenticationFlow == .login {
98102
Button(action: {
99103
authService.authView = .passwordRecovery
100104
}) {
101105
Text(authService.string.passwordButtonLabel)
102-
}
106+
}.accessibilityIdentifier("password-recovery-button")
103107
}
104108

105109
if authService.authenticationFlow == .signUp {
106110
LabeledContent {
107111
SecureField(authService.string.confirmPasswordInputLabel, text: $confirmPassword)
108112
.focused($focus, equals: .confirmPassword)
113+
.textInputAutocapitalization(.never)
114+
.disableAutocorrection(true)
109115
.submitLabel(.go)
110116
.onSubmit {
111117
Task { await createUserWithEmailPassword() }
@@ -116,6 +122,7 @@ extension EmailAuthView: View {
116122
.padding(.vertical, 6)
117123
.background(Divider(), alignment: .bottom)
118124
.padding(.bottom, 8)
125+
.accessibilityIdentifier("confirm-password-field")
119126
}
120127

121128
Button(action: {
@@ -140,11 +147,12 @@ extension EmailAuthView: View {
140147
.padding([.top, .bottom, .horizontal], 8)
141148
.frame(maxWidth: .infinity)
142149
.buttonStyle(.borderedProminent)
150+
.accessibilityIdentifier("sign-in-button")
143151
Button(action: {
144152
authService.authView = .emailLink
145153
}) {
146154
Text(authService.string.signUpWithEmailLinkButtonLabel)
147-
}
155+
}.accessibilityIdentifier("sign-in-with-email-link-button")
148156
}
149157
}
150158
}

FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/EmailLinkView.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ extension EmailLinkView: View {
3535
public var body: some View {
3636
VStack {
3737
Text(authService.string.signInWithEmailLinkViewTitle)
38+
.accessibilityIdentifier("email-link-title-text")
3839
LabeledContent {
3940
TextField(authService.string.emailInputLabel, text: $email)
4041
.textInputAutocapitalization(.never)
@@ -84,7 +85,7 @@ extension EmailLinkView: View {
8485
.foregroundColor(.blue)
8586
Text(authService.string.backButtonLabel)
8687
.foregroundColor(.blue)
87-
})
88+
}.accessibilityIdentifier("email-link-back-button"))
8889
}
8990
}
9091

FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/PasswordRecoveryView.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ extension PasswordRecoveryView: View {
4646
.font(.largeTitle)
4747
.fontWeight(.bold)
4848
.padding()
49+
.accessibilityIdentifier("password-recovery-text")
4950

5051
Divider()
5152

@@ -85,7 +86,7 @@ extension PasswordRecoveryView: View {
8586
.foregroundColor(.blue)
8687
Text(authService.string.backButtonLabel)
8788
.foregroundColor(.blue)
88-
})
89+
}.accessibilityIdentifier("password-recovery-back-button"))
8990
}
9091

9192
@ViewBuilder

FirebaseSwiftUI/FirebaseAuthSwiftUI/Sources/Views/SignedInView.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ extension SignedInView: View {
3737
.font(.largeTitle)
3838
.fontWeight(.bold)
3939
.padding()
40+
.accessibilityIdentifier("signed-in-text")
4041
Text(authService.string.accountSettingsEmailLabel)
4142
Text("\(authService.currentUser?.email ?? "Unknown")")
4243

@@ -54,7 +55,7 @@ extension SignedInView: View {
5455
try await authService.signOut()
5556
} catch {}
5657
}
57-
}
58+
}.accessibilityIdentifier("sign-out-button")
5859
Divider()
5960
Button(authService.string.deleteAccountButtonLabel) {
6061
Task {

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

Lines changed: 30 additions & 2 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 */;
@@ -511,7 +518,7 @@
511518
CURRENT_PROJECT_VERSION = 1;
512519
DEVELOPMENT_TEAM = YYX2P3XVJ7;
513520
GENERATE_INFOPLIST_FILE = YES;
514-
IPHONEOS_DEPLOYMENT_TARGET = 18.2;
521+
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
515522
MARKETING_VERSION = 1.0;
516523
PRODUCT_BUNDLE_IDENTIFIER = io.invertase.testing.FirebaseSwiftUIExampleTests;
517524
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -530,7 +537,7 @@
530537
CURRENT_PROJECT_VERSION = 1;
531538
DEVELOPMENT_TEAM = YYX2P3XVJ7;
532539
GENERATE_INFOPLIST_FILE = YES;
533-
IPHONEOS_DEPLOYMENT_TARGET = 18.2;
540+
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
534541
MARKETING_VERSION = 1.0;
535542
PRODUCT_BUNDLE_IDENTIFIER = io.invertase.testing.FirebaseSwiftUIExampleTests;
536543
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -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;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Scheme
3+
LastUpgradeVersion = "1620"
4+
version = "1.7">
5+
<BuildAction
6+
parallelizeBuildables = "YES"
7+
buildImplicitDependencies = "YES"
8+
buildArchitectures = "Automatic">
9+
</BuildAction>
10+
<TestAction
11+
buildConfiguration = "Debug"
12+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
13+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
14+
shouldUseLaunchSchemeArgsEnv = "YES"
15+
shouldAutocreateTestPlan = "YES">
16+
<Testables>
17+
<TestableReference
18+
skipped = "NO"
19+
parallelizable = "YES">
20+
<BuildableReference
21+
BuildableIdentifier = "primary"
22+
BlueprintIdentifier = "46F89C192D64A86D000F8BC0"
23+
BuildableName = "FirebaseSwiftUIExampleTests.xctest"
24+
BlueprintName = "FirebaseSwiftUIExampleTests"
25+
ReferencedContainer = "container:FirebaseSwiftUIExample.xcodeproj">
26+
</BuildableReference>
27+
</TestableReference>
28+
</Testables>
29+
</TestAction>
30+
<LaunchAction
31+
buildConfiguration = "Debug"
32+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
33+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
34+
launchStyle = "0"
35+
useCustomWorkingDirectory = "NO"
36+
ignoresPersistentStateOnLaunch = "NO"
37+
debugDocumentVersioning = "YES"
38+
debugServiceExtension = "internal"
39+
allowLocationSimulation = "YES">
40+
</LaunchAction>
41+
<ProfileAction
42+
buildConfiguration = "Release"
43+
shouldUseLaunchSchemeArgsEnv = "YES"
44+
savedToolIdentifier = ""
45+
useCustomWorkingDirectory = "NO"
46+
debugDocumentVersioning = "YES">
47+
</ProfileAction>
48+
<AnalyzeAction
49+
buildConfiguration = "Debug">
50+
</AnalyzeAction>
51+
<ArchiveAction
52+
buildConfiguration = "Release"
53+
revealArchiveInOrganizer = "YES">
54+
</ArchiveAction>
55+
</Scheme>

0 commit comments

Comments
 (0)