Skip to content

Commit

Permalink
feat: Add reportAccessibilityIdentifier option (#4183)
Browse files Browse the repository at this point in the history
Added an option to choose whether to report accessibilityIdentifier with the view hierarchy
  • Loading branch information
brustolin authored Jul 26, 2024
1 parent e94a36f commit b2fea10
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Features

- Add `reportAccessibilityIdentifier` option (#4183)
- Record dropped spans (#4172)

### Fixes
Expand Down
9 changes: 9 additions & 0 deletions Sources/Sentry/Public/SentryOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,15 @@ NS_SWIFT_NAME(Options)
*/
@property (nonatomic, assign) BOOL attachViewHierarchy;

/**
* @brief If enabled, view hierarchy attachment will contain view `accessibilityIdentifier`.
* Set it to @c NO if your project uses `accessibilityIdentifier` for PII.
* @warning This feature is not available in @c DebugWithoutUIKit and @c ReleaseWithoutUIKit
* configurations even when targeting iOS or tvOS platforms.
* @note Default value is @c YES.
*/
@property (nonatomic, assign) BOOL reportAccessibilityIdentifier;

/**
* When enabled, the SDK creates transactions for UI events like buttons clicks, switch toggles,
* and other ui elements that uses UIControl @c sendAction:to:forEvent:
Expand Down
4 changes: 4 additions & 0 deletions Sources/Sentry/SentryOptions.m
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ - (instancetype)init
self.enableUIViewControllerTracing = YES;
self.attachScreenshot = NO;
self.attachViewHierarchy = NO;
self.reportAccessibilityIdentifier = YES;
self.enableUserInteractionTracing = YES;
self.idleTimeout = SentryTracerDefaultTimeout;
self.enablePreWarmedAppStartTracing = NO;
Expand Down Expand Up @@ -416,6 +417,9 @@ - (BOOL)validateOptions:(NSDictionary<NSString *, id> *)options
[self setBool:options[@"attachViewHierarchy"]
block:^(BOOL value) { self->_attachViewHierarchy = value; }];

[self setBool:options[@"reportAccessibilityIdentifier"]
block:^(BOOL value) { self->_reportAccessibilityIdentifier = value; }];

[self setBool:options[@"enableUserInteractionTracing"]
block:^(BOOL value) { self->_enableUserInteractionTracing = value; }];

Expand Down
11 changes: 10 additions & 1 deletion Sources/Sentry/SentryViewHierarchy.m
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@

@implementation SentryViewHierarchy

- (instancetype)init
{
if (self = [super init]) {
self.reportAccessibilityIdentifier = YES;
}
return self;
}

- (BOOL)saveViewHierarchy:(NSString *)filePath
{
NSArray<UIWindow *> *windows = [SentryDependencyContainer.sharedInstance.application windows];
Expand Down Expand Up @@ -119,7 +127,8 @@ - (int)viewHierarchyFromView:(UIView *)view intoContext:(SentryCrashJSONEncodeCo
tryJson(sentrycrashjson_addStringElement(
context, "type", viewClassName, SentryCrashJSON_SIZE_AUTOMATIC));

if (view.accessibilityIdentifier && view.accessibilityIdentifier.length != 0) {
if (self.reportAccessibilityIdentifier && view.accessibilityIdentifier
&& view.accessibilityIdentifier.length != 0) {
tryJson(sentrycrashjson_addStringElement(context, "identifier",
view.accessibilityIdentifier.UTF8String, SentryCrashJSON_SIZE_AUTOMATIC));
}
Expand Down
2 changes: 2 additions & 0 deletions Sources/Sentry/SentryViewHierarchyIntegration.m
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ - (BOOL)installWithOptions:(nonnull SentryOptions *)options

sentrycrash_setSaveViewHierarchy(&saveViewHierarchy);

SentryDependencyContainer.sharedInstance.viewHierarchy.reportAccessibilityIdentifier
= options.reportAccessibilityIdentifier;
return YES;
}

Expand Down
5 changes: 5 additions & 0 deletions Sources/Sentry/include/SentryViewHierarchy.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ NS_ASSUME_NONNULL_BEGIN

@interface SentryViewHierarchy : NSObject

/**
* Whether we should add `accessibilityIdentifier` to the view hierarchy.
*/
@property (nonatomic) BOOL reportAccessibilityIdentifier;

/**
Get the view hierarchy in a json format.
Always runs in the main thread.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,23 @@ class SentryViewHierarchyIntegrationTests: XCTestCase {

wait(for: [ex], timeout: 1)
}

func testReportAccessibilityIdentifierTrue() {
SentrySDK.start {
$0.attachViewHierarchy = true
$0.setIntegrations([SentryViewHierarchyIntegration.self])
}
XCTAssertTrue(SentryDependencyContainer.sharedInstance().viewHierarchy.reportAccessibilityIdentifier)
}

func testReportAccessibilityIdentifierFalse() {
SentrySDK.start {
$0.attachViewHierarchy = true
$0.reportAccessibilityIdentifier = false
$0.setIntegrations([SentryViewHierarchyIntegration.self])
}
XCTAssertFalse(SentryDependencyContainer.sharedInstance().viewHierarchy.reportAccessibilityIdentifier)
}
}

#endif // os(iOS) || os(tvOS) || targetEnvironment(macCatalyst)
6 changes: 6 additions & 0 deletions Tests/SentryTests/SentryOptionsTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,7 @@ - (void)assertDefaultValues:(SentryOptions *)options
XCTAssertEqual(options.enableUserInteractionTracing, YES);
XCTAssertEqual(options.enablePreWarmedAppStartTracing, NO);
XCTAssertEqual(options.attachViewHierarchy, NO);
XCTAssertEqual(options.reportAccessibilityIdentifier, YES);
XCTAssertEqual(options.experimental.sessionReplay.errorSampleRate, 0);
XCTAssertEqual(options.experimental.sessionReplay.sessionSampleRate, 0);
#endif // SENTRY_HAS_UIKIT
Expand Down Expand Up @@ -808,6 +809,11 @@ - (void)testAttachScreenshot
[self testBooleanField:@"attachScreenshot" defaultValue:NO];
}

- (void)testReportAccessibilityIdentifier
{
[self testBooleanField:@"reportAccessibilityIdentifier" defaultValue:YES];
}

- (void)testEnableUserInteractionTracing
{
[self testBooleanField:@"enableUserInteractionTracing" defaultValue:YES];
Expand Down
16 changes: 16 additions & 0 deletions Tests/SentryTests/SentryViewHierarchyTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,22 @@ class SentryViewHierarchyTests: XCTestCase {

XCTAssertEqual(descriptions, "{\"rendering_system\":\"UIKIT\",\"windows\":[{\"type\":\"UIWindow\",\"identifier\":\"WindowId\",\"width\":10,\"height\":10,\"x\":0,\"y\":0,\"alpha\":1,\"visible\":false,\"children\":[]}]}")
}

func test_ViewHierarchy_save_noIdentifier() throws {
let window = UIWindow(frame: CGRect(x: 0, y: 0, width: 10, height: 10))
window.accessibilityIdentifier = "WindowId"

fixture.uiApplication.windows = [window]

let path = FileManager.default.temporaryDirectory.appendingPathComponent("view.json").path
let sut = self.fixture.sut
sut.reportAccessibilityIdentifier = false
sut.save(path)

let descriptions = try XCTUnwrap(String(contentsOfFile: path))

XCTAssertEqual(descriptions, "{\"rendering_system\":\"UIKIT\",\"windows\":[{\"type\":\"UIWindow\",\"width\":10,\"height\":10,\"x\":0,\"y\":0,\"alpha\":1,\"visible\":false,\"children\":[]}]}")
}

func test_invalidFilePath() {
let window = UIWindow(frame: CGRect(x: 0, y: 0, width: 10, height: 10))
Expand Down

0 comments on commit b2fea10

Please sign in to comment.