Skip to content

Commit

Permalink
Merge pull request #492 from DataDog/louiszawadzki/add-action-name-at…
Browse files Browse the repository at this point in the history
…tribute-to-config

Add action name attribute to config
  • Loading branch information
louiszawadzki committed Jun 20, 2023
2 parents ec3ad9a + 8a88595 commit 9367e06
Show file tree
Hide file tree
Showing 7 changed files with 221 additions and 72 deletions.
4 changes: 3 additions & 1 deletion packages/core/src/DdSdkReactNative.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,9 @@ export class DdSdkReactNative {
return;
}
if (configuration.trackInteractions) {
DdRumUserInteractionTracking.startTracking();
DdRumUserInteractionTracking.startTracking({
actionNameAttribute: configuration.actionNameAttribute
});
}

if (configuration.trackResources) {
Expand Down
22 changes: 22 additions & 0 deletions packages/core/src/DdSdkReactNativeConfiguration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,19 @@ export class DdSdkReactNativeConfiguration {
*/
public trackBackgroundEvents: boolean = DEFAULTS.trackBackgroundEvents;

/**
* Specifies a custom prop to name RUM actions on elements having an `onPress` prop.
*
* For example if you set it to `testID`, the value of the `testID` prop is used as a custom action name:
*
* ```js
* <TouchableOpacity testID="Dismiss notification" onPress={() => dismiss()}>
* ```
*
* `dd-action-name` is favored when both attributes are present on an element.
*/
public actionNameAttribute?: string;

public logEventMapper: LogEventMapper | null = DEFAULTS.logEventMapper;

public errorEventMapper: ErrorEventMapper | null =
Expand Down Expand Up @@ -280,6 +293,7 @@ export type AutoInstrumentationConfiguration = {
readonly errorEventMapper?: ErrorEventMapper | null;
readonly resourceEventMapper?: ResourceEventMapper | null;
readonly actionEventMapper?: ActionEventMapper | null;
readonly actionNameAttribute?: string;
};

/**
Expand All @@ -295,6 +309,7 @@ export type AutoInstrumentationParameters = {
readonly errorEventMapper: ErrorEventMapper | null;
readonly resourceEventMapper: ResourceEventMapper | null;
readonly actionEventMapper: ActionEventMapper | null;
readonly actionNameAttribute?: string;
};

/**
Expand Down Expand Up @@ -439,6 +454,13 @@ export const buildConfigurationFromPartialConfiguration = (
},
SdkConfiguration
);
setConfigurationAttribute(
{
name: 'actionNameAttribute',
value: features.actionNameAttribute
},
SdkConfiguration
);

return SdkConfiguration;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ describe('DdSdkReactNativeConfiguration', () => {
logEventMapper: event => event,
errorEventMapper: event => event,
resourceEventMapper: event => event,
actionEventMapper: event => event
actionEventMapper: event => event,
actionNameAttribute: 'testID'
},
{
applicationId: 'fake-app-id',
Expand Down Expand Up @@ -111,6 +112,7 @@ describe('DdSdkReactNativeConfiguration', () => {
).toMatchInlineSnapshot(`
DdSdkReactNativeConfiguration {
"actionEventMapper": [Function],
"actionNameAttribute": "testID",
"additionalConfig": {
"additionalField": "fake-value",
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,60 @@ it('M send a RUM Action event W interceptOnPress { arguments with dd-action-name
expect(DdRum.addAction.mock.calls[0][4]).toBe(fakeArguments);
});

it('M send a RUM Action event W interceptOnPress { arguments with actionNameAttribute } ', async () => {
// GIVEN
const eventsInterceptor = new DdEventsInterceptor({
actionNameAttribute: 'testID'
});
const fakeAccessibilityLabel = 'target_name';
const fakeTestId = 'testID';
const fakeArguments = {
_targetInst: {
memoizedProps: {
accessibilityLabel: fakeAccessibilityLabel,
testID: fakeTestId
}
}
};

// WHEN
eventsInterceptor.interceptOnPress(fakeArguments);

// THEN
expect(DdRum.addAction.mock.calls.length).toBe(1);
expect(DdRum.addAction.mock.calls[0][0]).toBe(RumActionType.TAP);
expect(DdRum.addAction.mock.calls[0][1]).toBe(fakeTestId);
expect(DdRum.addAction.mock.calls[0][4]).toBe(fakeArguments);
});

it('M send a RUM Action event W interceptOnPress { arguments with dd-action-name over actionNameAttribute } ', async () => {
// GIVEN
const eventsInterceptor = new DdEventsInterceptor({
actionNameAttribute: 'testID'
});
const fakeAccessibilityLabel = 'target_name';
const fakeTestId = 'testID';
const fakeDdActionLabel = 'DdActionLabel';
const fakeArguments = {
_targetInst: {
memoizedProps: {
accessibilityLabel: fakeAccessibilityLabel,
'dd-action-name': fakeDdActionLabel,
testID: fakeTestId
}
}
};

// WHEN
eventsInterceptor.interceptOnPress(fakeArguments);

// THEN
expect(DdRum.addAction.mock.calls.length).toBe(1);
expect(DdRum.addAction.mock.calls[0][0]).toBe(RumActionType.TAP);
expect(DdRum.addAction.mock.calls[0][1]).toBe(fakeDdActionLabel);
expect(DdRum.addAction.mock.calls[0][4]).toBe(fakeArguments);
});

it('M send a RUM Action event W interceptOnPress { arguments with dd-action-name on a parent node} ', async () => {
// GIVEN
const fakeAccessibilityLabel = 'target_name';
Expand Down
Loading

0 comments on commit 9367e06

Please sign in to comment.