Skip to content

Commit

Permalink
feat: add option to activate/deactivate video recording anonymization
Browse files Browse the repository at this point in the history
  • Loading branch information
rfe-sdev committed Nov 29, 2023
1 parent b665f72 commit 2143051
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 60 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
### Added

- Anonymization of video recordings controllable from Gravity
- Option to enable/disable video recording anonymization in debug mode
- Track new HTML events:
- `contextmenu`
- `dblclick`
Expand Down
37 changes: 19 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,24 +63,25 @@ GravityCollector.init(/*options*/)

The `GravityCollector.init()` can take a `CollectorOptions` object with the following optional properties:

| key | type | use | default value |
| ---------------------- | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- |
| authKey | String | The authentication key provided by Gravity to select the correct collection | |
| requestInterval | Integer | Time (in ms) between two sends to Gravity server (buffering) | 1000 |
| gravityServerUrl | String | Gravity server URL | https://api.gravity.smartesting.com |
| debug | Boolean | Logs user action in the console instead of sending them to Gravity | false |
| maxDelay | Integer | In debug mode, adds a random delay (in ms) between 0 and this value before printing an user action. | 500 |
| excludeRegex | RegExp | <u>Deprecated</u>, use <code>selectorsOptions</code> instead. <br/>Regular expression of ID and class names to ignore in selector computation. | null |
| customSelector | String (optional) | <u>Deprecated</u>, use <code>selectorsOptions</code> instead. <br/>The attribute to use as a selector if defined on an HTML element targeted by a user action. | undefined |
| selectorsOptions | Object (optional) | See [Work with selectors](#work-with-selectors). | undefined |
| sessionsPercentageKept | [0..100] | Rate of sessions to be collected | 100 |
| rejectSession | function `() => boolean` | Boolean function to ignore session tracking. For instance, to ignore sessions from some bots:<br /><code>rejectSession: () => /bot&#124;googlebot&#124;robot/i.test(navigator.userAgent)</code> | `() => false` |
| onPublish | function (optional) | Adds a function called after each publish to the gravity server. | undefined |
| originsToRecord | String[] (optional) | <u>Deprecated</u>, renamed <code>recordRequestsFor</code>. | undefined |
| recordRequestsFor | String[] (optional) | The Gravity Data Collector does not record requests by default. You must specify here the URL origin(s) of the requests to record. For example: "https://myserver.com/" | undefined |
| buildId | String (optional) | The build reference when running tests | undefined |
| enableEventRecording | Boolean (optional) | Set to `false` to deactivate any recording (event & video) | true |
| enableVideoRecording | Boolean (optional) | Set to `false` to deactivate video recording | true |
| key | type | use | default value |
| ------------------------ | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- |
| authKey | String | The authentication key provided by Gravity to select the correct collection | |
| requestInterval | Integer | Time (in ms) between two sends to Gravity server (buffering) | 1000 |
| gravityServerUrl | String | Gravity server URL | https://api.gravity.smartesting.com |
| debug | Boolean | Logs user action in the console instead of sending them to Gravity | false |
| maxDelay | Integer | In debug mode, adds a random delay (in ms) between 0 and this value before printing an user action. | 500 |
| excludeRegex | RegExp | <u>Deprecated</u>, use <code>selectorsOptions</code> instead. <br/>Regular expression of ID and class names to ignore in selector computation. | null |
| customSelector | String (optional) | <u>Deprecated</u>, use <code>selectorsOptions</code> instead. <br/>The attribute to use as a selector if defined on an HTML element targeted by a user action. | undefined |
| selectorsOptions | Object (optional) | See [Work with selectors](#work-with-selectors). | undefined |
| sessionsPercentageKept | [0..100] | Rate of sessions to be collected | 100 |
| rejectSession | function `() => boolean` | Boolean function to ignore session tracking. For instance, to ignore sessions from some bots:<br /><code>rejectSession: () => /bot&#124;googlebot&#124;robot/i.test(navigator.userAgent)</code> | `() => false` |
| onPublish | function (optional) | Adds a function called after each publish to the gravity server. | undefined |
| originsToRecord | String[] (optional) | <u>Deprecated</u>, renamed <code>recordRequestsFor</code>. | undefined |
| recordRequestsFor | String[] (optional) | The Gravity Data Collector does not record requests by default. You must specify here the URL origin(s) of the requests to record. For example: "https://myserver.com/" | undefined |
| buildId | String (optional) | The build reference when running tests | undefined |
| enableEventRecording | Boolean (optional) | Set to `false` to deactivate any recording (event & video) (only in debug mode, otherwise this option is controlled from the Gravity interface) | true |
| enableVideoRecording | Boolean (optional) | Set to `false` to deactivate video recording (only in debug mode, otherwise this option is controlled from the Gravity interface) | true |
| enableVideoAnonymization | Boolean (optional) | Set to `false` to deactivate video anonymization (only in debug mode, otherwise this option is controlled from the Gravity interface) | true |

## Features

Expand Down
13 changes: 6 additions & 7 deletions src/collector/CollectorWrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,21 +260,20 @@ class CollectorWrapper {
private async fetchRecordingSettings(): Promise<RecordingSettings> {
if (this.options.debug) {
return {
enableEventRecording: true,
enableVideoRecording: true,
enableVideoAnonymization: false,
enableEventRecording: this.options.enableEventRecording,
enableVideoRecording: this.options.enableVideoRecording,
enableVideoAnonymization: this.options.enableVideoAnonymization,
}
}

return await this.gravityClient.readSessionCollectionSettings().then(({ settings, error }) => {
if (settings === null || error !== null) {
return ALL_RECORDING_SETTINGS_DISABLED
}
const enableEventRecording = settings.sessionRecording ?? this.options.enableEventRecording
const enableVideoRecording = settings.videoRecording ?? this.options.enableVideoRecording

return {
enableEventRecording,
enableVideoRecording,
enableEventRecording: settings.sessionRecording,
enableVideoRecording: settings.videoRecording,
enableVideoAnonymization: settings.videoAnonymization,
}
})
Expand Down
55 changes: 54 additions & 1 deletion src/collector/sessionRecording.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,60 @@ describe('Session recording (events & video) depends on remote Gravity settings'
beforeEach(() => installSpies(ConsoleGravityClient))
afterEach(uninstallSpies)

it('use default settings', async () => {
describe('use options settings if available', () => {
it('records events & video', async () => {
const collector = installer()
.withOptions({
enableEventRecording: true,
enableVideoRecording: true,
})
.install()

await emitEachEventKind(collector)
expect(handleSessionUserActions).toHaveBeenCalled()
expect(handleSessionTraits).toHaveBeenCalled()
expect(handleScreenRecords).toHaveBeenCalled()

expect(terminateEventRecording).not.toHaveBeenCalled()
expect(terminateVideoRecording).not.toHaveBeenCalled()
})

it('records events BUT no videos', async () => {
const collector = installer()
.withOptions({
enableEventRecording: true,
enableVideoRecording: false,
})
.install()

await emitEachEventKind(collector)
expect(handleSessionUserActions).toHaveBeenCalled()
expect(handleSessionTraits).toHaveBeenCalled()
expect(handleScreenRecords).not.toHaveBeenCalled()

expect(terminateEventRecording).not.toHaveBeenCalled()
expect(terminateVideoRecording).toHaveBeenCalled()
})

it('records nothing', async () => {
const collector = installer()
.withOptions({
enableEventRecording: false,
enableVideoRecording: true,
})
.install()

await emitEachEventKind(collector)
expect(handleSessionUserActions).not.toHaveBeenCalled()
expect(handleSessionTraits).not.toHaveBeenCalled()
expect(handleScreenRecords).not.toHaveBeenCalled()

expect(terminateEventRecording).toHaveBeenCalled()
expect(terminateVideoRecording).toHaveBeenCalled()
})
})

it('else use default settings', async () => {
const collector = installer().install()

await emitEachEventKind(collector)
Expand Down
7 changes: 4 additions & 3 deletions src/gravity-client/AbstractGravityClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ export interface GravityClientOptions {
onPublish?: (userActions: ReadonlyArray<SessionUserAction>) => void
}

export type RecordingSettings = Pick<CollectorOptions, 'enableEventRecording' | 'enableVideoRecording'> & {
enableVideoAnonymization: boolean
}
export type RecordingSettings = Pick<
CollectorOptions,
'enableEventRecording' | 'enableVideoRecording' | 'enableVideoAnonymization'
>

export default abstract class AbstractGravityClient implements IGravityClient {
private readonly sessionUserActionBuffer: DataBuffering<SessionUserAction, AddSessionUserActionsResponse>
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ export interface CollectorOptions {
disableVideoRecording?: boolean
enableEventRecording?: boolean
enableVideoRecording?: boolean
enableVideoAnonymization?: boolean
}

export type CollectorOptionsWithWindow = CollectorOptions & {
Expand Down
Loading

0 comments on commit 2143051

Please sign in to comment.