Skip to content

Commit d50a587

Browse files
authored
fix(ui-tests): Fix duplicate accessibility identifiers and camera crashes (#6138)
1 parent 25f4532 commit d50a587

File tree

4 files changed

+33
-16
lines changed

4 files changed

+33
-16
lines changed

Samples/iOS-Swift/iOS-Swift-UITests/SessionReplayUITests.swift

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,17 @@ import XCTest
22

33
class SessionReplayUITests: BaseUITest {
44

5-
func testCameraUI_shouldNotCrashOnIOS26() {
5+
func testCameraUI_shouldNotCrashOnIOS26() throws {
6+
guard UIImagePickerController.isSourceTypeAvailable(.camera) else {
7+
throw XCTSkip("Camera UI is not available on this device.")
8+
}
69
// -- Arrange --
710
// During the beta phase of iOS 26.0 we noticed crashes when traversing the view hierarchy
811
// of the camera UI. This test is used to verify that no regression occurs.
912
// See https://github.com/getsentry/sentry-cocoa/issues/5647
1013
app.buttons["Extra"].tap()
14+
15+
// -- Act --
1116
app.buttons["Show Camera UI"].tap()
1217

1318
// We need to verify the camera UI is shown by checking for the existence of a UI element.
@@ -17,18 +22,12 @@ class SessionReplayUITests: BaseUITest {
1722
let cameraUIElement = app.buttons["PhotoCapture"]
1823
XCTAssertTrue(cameraUIElement.waitForExistence(timeout: 5))
1924

20-
// After the Camera UI is shown, we keep it open for 6 seconds to trigger at least one full
25+
// After the Camera UI is shown, we keep it open for 10 seconds to trigger at least one full
2126
// video segment captured (segments are 5 seconds long).
22-
wait(10)
27+
delay(seconds: 10)
2328

29+
// -- Assert --
2430
// We know the test succeeded if we reach this point without the app crashing.
25-
}
26-
27-
private func wait(_ seconds: TimeInterval) {
28-
let exp = expectation(description: "Waiting for \(seconds) seconds")
29-
DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
30-
exp.fulfill()
31-
}
32-
wait(for: [exp], timeout: seconds + 1)
31+
XCTAssertTrue(cameraUIElement.waitForExistence(timeout: 5))
3332
}
3433
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import XCTest
2+
3+
public extension XCTestCase {
4+
func delay(seconds: TimeInterval) {
5+
let exp = expectation(description: "Waiting for \(seconds) seconds")
6+
DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
7+
exp.fulfill()
8+
}
9+
wait(for: [exp], timeout: seconds + 1)
10+
}
11+
}

Samples/iOS-Swift/iOS-Swift/Base.lproj/Main.storyboard

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,9 +1212,9 @@
12121212
<segue destination="ehF-Y7-8St" kind="presentation" id="H7t-Et-KMM"/>
12131213
</connections>
12141214
</button>
1215-
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4Dg-dP-BxN" userLabel="View Lifecycle Test">
1215+
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4Dg-dP-BxN" userLabel="Show Camera UI">
12161216
<rect key="frame" x="0.0" y="448" width="160" height="28"/>
1217-
<accessibility key="accessibilityConfiguration" identifier="view-lifecycle-test"/>
1217+
<accessibility key="accessibilityConfiguration" identifier="show-camera-ui"/>
12181218
<fontDescription key="fontDescription" type="system" pointSize="13"/>
12191219
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
12201220
<state key="normal" title="Show Camera UI"/>
@@ -1835,16 +1835,16 @@
18351835
<color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
18361836
</systemColor>
18371837
<systemColor name="secondarySystemBackgroundColor">
1838-
<color red="0.94901960780000005" green="0.94901960780000005" blue="0.96862745100000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
1838+
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
18391839
</systemColor>
18401840
<systemColor name="systemBackgroundColor">
18411841
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
18421842
</systemColor>
18431843
<systemColor name="systemGray5Color">
1844-
<color red="0.8980392157" green="0.8980392157" blue="0.91764705879999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
1844+
<color red="0.89803921568627454" green="0.89803921568627454" blue="0.91764705882352937" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
18451845
</systemColor>
18461846
<systemColor name="systemRedColor">
1847-
<color red="1" green="0.23137254900000001" blue="0.18823529410000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
1847+
<color red="1" green="0.23137254901960785" blue="0.18823529411764706" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
18481848
</systemColor>
18491849
</resources>
18501850
</document>

Samples/iOS-Swift/iOS-Swift/ExtraViewController.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,13 @@ class ExtraViewController: UIViewController {
414414
}
415415

416416
@IBAction func showCameraUIAction(_ sender: Any) {
417+
// We need to check if the camera is available, otherwise simulators running on a Mac Mini (device without any
418+
// built-in camera) would crash with this error:
419+
//
420+
// *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Source type 1 not available'
421+
guard UIImagePickerController.isSourceTypeAvailable(.camera) else {
422+
preconditionFailure("Can not display the camera UI because the source type is not available.")
423+
}
417424
let imagePicker = UIImagePickerController()
418425
imagePicker.sourceType = .camera
419426
imagePicker.allowsEditing = false

0 commit comments

Comments
 (0)