Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(replay): Add Mobile Replay #3830

Merged
merged 29 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
60d07df
feat(replay): Add Mobile Replay Alpha (#3714)
krystofwoldrich May 21, 2024
41f816a
Merge branch 'main' into feat/replay
vaind Jun 4, 2024
c3ff79f
Merge branch 'main' into feat/replay
vaind Jun 18, 2024
13a9360
feat(sample): add running indicator (animation overlay) (#3903)
krystofwoldrich Jun 21, 2024
1f1e41e
Merge branch 'main' into feat/replay
vaind Jun 26, 2024
38d8d7c
feat(replay): Add breadcrumbs mapping from RN to RRWeb format (#3846)
vaind Jun 26, 2024
ac72abc
feat(replay): Add network breadcrumbs (#3912)
krystofwoldrich Jun 27, 2024
5f3a5c8
fix(replay): Add tests for touch events (#3924)
krystofwoldrich Jul 2, 2024
b4aaa68
feat(replay): Filter Sentry event breadcrumbs (#3925)
krystofwoldrich Jul 2, 2024
00aa520
Merge branch 'main' into feat/replay
krystofwoldrich Jul 2, 2024
cfd5aee
fix(changelog): Add latest native SDKs details
krystofwoldrich Jul 2, 2024
83f5a0c
release: 5.25.0-alpha.2
getsentry-bot Jul 2, 2024
8e9c3a0
Merge branch 'release/5.25.0-alpha.2' into feat/replay
Jul 2, 2024
9672e88
misc(samples): Add console anything examples for replay testing (#3928)
krystofwoldrich Jul 3, 2024
6067ecc
feat: Add Sentry Babel Transformer (#3916)
krystofwoldrich Jul 3, 2024
3b28c40
fix(replay): Add app lifecycle breadcrumbs conversion tests (#3932)
krystofwoldrich Jul 5, 2024
e25da10
Merge remote-tracking branch 'origin/main' into feat/replay
krystofwoldrich Jul 9, 2024
6d8c4dd
chore(deps): bump sentry-android to 7.12.0-alpha.3
krystofwoldrich Jul 9, 2024
6fd2a34
chore(deps): bump sentry-android to 7.12.0-alpha.4
krystofwoldrich Jul 9, 2024
3dcf57b
fix(replay): Mask SVGs from `react-native-svg` when `maskAllVectors=t…
krystofwoldrich Jul 10, 2024
361867e
Merge remote-tracking branch 'origin/main' into feat/replay
krystofwoldrich Jul 10, 2024
f96cf53
Merge remote-tracking branch 'origin/main' into feat/replay
krystofwoldrich Jul 12, 2024
254b772
fix(replay): Add missing properties to android nav breadcrumbs (#3942)
krystofwoldrich Jul 12, 2024
7b9baca
release: 5.26.0-alpha.3
getsentry-bot Jul 12, 2024
222c9dd
Merge branch 'release/5.26.0-alpha.3' into feat/replay
Jul 12, 2024
0b74944
misc(replay): Add Mobile Replay Public Beta changelog (#3943)
krystofwoldrich Jul 15, 2024
4088ea8
Merge branch 'main' into feat/replay
romtsn Jul 15, 2024
a1da3bf
Merge branch 'main' into feat/replay
bruno-garcia Jul 15, 2024
b9a7f9d
Merge branch 'main' into feat/replay
bruno-garcia Jul 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,6 @@ yalc.lock

# E2E tests
test/react-native/versions

# Created by Sentry Metro Plugin
.sentry/
131 changes: 128 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,58 @@

## Unreleased

### Features

- Session Replay Public Beta ([#3830](https://github.com/getsentry/sentry-react-native/pull/3830))

To enable Replay use the `replaysSessionSampleRate` or `replaysOnErrorSampleRate` options.

```js
import * as Sentry from '@sentry/react-native';

Sentry.init({
_experiments: {
replaysSessionSampleRate: 1.0,
replaysOnErrorSampleRate: 1.0,
},
});
```

To add React Component Names use `annotateReactComponents` in `metro.config.js`.

```js
// For Expo
const { getSentryExpoConfig } = require("@sentry/react-native/metro");
const config = getSentryExpoConfig(__dirname, { annotateReactComponents: true });

// For RN
const { getDefaultConfig } = require('@react-native/metro-config');
const { withSentryConfig } = require('@sentry/react-native/metro');
module.exports = withSentryConfig(getDefaultConfig(__dirname), { annotateReactComponents: true });
```

To change default redaction behavior add the `mobileReplayIntegration`.

```js
import * as Sentry from '@sentry/react-native';

Sentry.init({
_experiments: {
replaysSessionSampleRate: 1.0,
replaysOnErrorSampleRate: 1.0,
},
integrations: [
Sentry.mobileReplayIntegration({
maskAllImages: true,
maskAllVectors: true,
maskAllText: true,
}),
],
});
```

To learn more visit [Sentry's Mobile Session Replay](https://docs.sentry.io/product/explore/session-replay/mobile/) documentation page.

### Dependencies

- Bump Cocoa SDK from v8.30.0 to v8.31.1 ([#3954](https://github.com/getsentry/sentry-react-native/pull/3954))
Expand Down Expand Up @@ -34,6 +86,30 @@
- [changelog](https://github.com/getsentry/sentry-java/blob/main/CHANGELOG.md#7110)
- [diff](https://github.com/getsentry/sentry-java/compare/7.10.0...7.11.0)

## 5.25.0-alpha.2

### Features

- Improve touch event component info if annotated with [`@sentry/babel-plugin-component-annotate`](https://www.npmjs.com/package/@sentry/babel-plugin-component-annotate) ([#3899](https://github.com/getsentry/sentry-react-native/pull/3899))
- Add replay breadcrumbs for touch & navigation events ([#3846](https://github.com/getsentry/sentry-react-native/pull/3846))
- Add network data to Session Replays ([#3912](https://github.com/getsentry/sentry-react-native/pull/3912))
- Filter Sentry Event Breadcrumbs from Mobile Replays ([#3925](https://github.com/getsentry/sentry-react-native/pull/3925))

### Fixes

- `sentry-expo-upload-sourcemaps` no longer requires Sentry url when uploading sourcemaps to `sentry.io` ([#3915](https://github.com/getsentry/sentry-react-native/pull/3915))

### Dependencies

- Bump Cocoa SDK from v8.25.0-alpha.0 to v8.30.0 ([#3914](https://github.com/getsentry/sentry-react-native/pull/3914))
- [changelog](https://github.com/getsentry/sentry-cocoa/blob/main/CHANGELOG.md#8300)
- [diff](https://github.com/getsentry/sentry-cocoa/compare/8.25.0-alpha.0...8.30.0)
- Bump Android SDK from v7.9.0-alpha.1 to v7.11.0-alpha.2 ([#3830](https://github.com/getsentry/sentry-react-native/pull/3830))
- [changelog](https://github.com/getsentry/sentry-java/blob/7.11.0-alpha.2/CHANGELOG.md#7110-alpha2)
- [diff](https://github.com/getsentry/sentry-java/compare/7.9.0-alpha.1...7.11.0-alpha.2)

Access to Mobile Replay is limited to early access orgs on Sentry. If you're interested, [sign up for the waitlist](https://sentry.io/lp/mobile-replay-beta/)

## 5.24.1

### Fixes
Expand Down Expand Up @@ -133,6 +209,14 @@ This release does *not* build on iOS. Please use `5.23.1` or newer.
- [changelog](https://github.com/getsentry/sentry-cocoa/blob/main/CHANGELOG.md#8270)
- [diff](https://github.com/getsentry/sentry-cocoa/compare/8.26.0...8.27.0)

## 5.23.0-alpha.1

### Fixes

- Pass `replaysSessionSampleRate` option to Android ([#3714](https://github.com/getsentry/sentry-react-native/pull/3714))

Access to Mobile Replay is limited to early access orgs on Sentry. If you're interested, [sign up for the waitlist](https://sentry.io/lp/mobile-replay-beta/)

## 5.22.3

### Fixes
Expand Down Expand Up @@ -166,6 +250,47 @@ This release does *not* build on iOS. Please use `5.23.1` or newer.
- [changelog](https://github.com/getsentry/sentry-cocoa/blob/main/CHANGELOG.md#8250)
- [diff](https://github.com/getsentry/sentry-cocoa/compare/8.24.0...8.25.0)

## 5.23.0-alpha.0

### Features

- Mobile Session Replay Alpha ([#3714](https://github.com/getsentry/sentry-react-native/pull/3714))

To enable Replay for React Native on mobile and web add the following options.

```js
Sentry.init({
_experiments: {
replaysSessionSampleRate: 1.0,
replaysOnErrorSampleRate: 1.0,
},
});
```

To change the default Mobile Replay options add the `mobileReplayIntegration`.

```js
Sentry.init({
_experiments: {
replaysSessionSampleRate: 1.0,
replaysOnErrorSampleRate: 1.0,
},
integration: [
Sentry.mobileReplayIntegration({
maskAllText: true,
maskAllImages: true,
}),
],
});
```

Access is limited to early access orgs on Sentry. If you're interested, [sign up for the waitlist](https://sentry.io/lp/mobile-replay-beta/)

### Dependencies

- Bump Cocoa SDK to [8.25.0-alpha.0](https://github.com/getsentry/sentry-cocoa/releases/tag/8.25.0-alpha.0)
- Bump Android SDK to [7.9.0-alpha.1](https://github.com/getsentry/sentry-java/releases/tag/7.9.0-alpha.1)

## 5.22.0

### Features
Expand Down Expand Up @@ -444,7 +569,7 @@ see [the Expo guide](https://docs.sentry.io/platforms/react-native/manual-setup/
const { getSentryExpoConfig } = require("@sentry/react-native/metro");

// const config = getDefaultConfig(__dirname);
const config = getSentryExpoConfig(config, {});
const config = getSentryExpoConfig(__dirname);
```

- New `npx sentry-expo-upload-sourcemaps` for simple EAS Update (`npx expo export`) source maps upload ([#3491](https://github.com/getsentry/sentry-react-native/pull/3491), [#3510](https://github.com/getsentry/sentry-react-native/pull/3510), [#3515](https://github.com/getsentry/sentry-react-native/pull/3515), [#3507](https://github.com/getsentry/sentry-react-native/pull/3507))
Expand Down Expand Up @@ -676,7 +801,7 @@ This release is compatible with `[email protected]` and newer.
});
```

Read more at https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md#7690
Read more at <https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md#7690>

- Report current screen in `contexts.app.view_names` ([#3339](https://github.com/getsentry/sentry-react-native/pull/3339))

Expand Down Expand Up @@ -2715,7 +2840,7 @@ We are looking into ways making this more stable and plan to re-enable it again

## v0.23.2

- Fixed #228 again ¯\\_(ツ)_
- Fixed #228 again ¯\\*(ツ)*

## v0.23.1

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
package io.sentry.rnsentryandroidtester

import io.sentry.Breadcrumb
import io.sentry.SentryLevel
import io.sentry.react.RNSentryReplayBreadcrumbConverter
import io.sentry.rrweb.RRWebBreadcrumbEvent
import io.sentry.rrweb.RRWebEventType
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4

@RunWith(JUnit4::class)
class RNSentryReplayBreadcrumbConverterTest {

@Test
fun convertNavigationBreadcrumb() {
val converter = RNSentryReplayBreadcrumbConverter()
val testBreadcrumb = Breadcrumb()
testBreadcrumb.level = SentryLevel.INFO
testBreadcrumb.type = "navigation"
testBreadcrumb.category = "navigation"
testBreadcrumb.setData("from", "HomeScreen")
testBreadcrumb.setData("to", "ProfileScreen")
val actual = converter.convert(testBreadcrumb) as RRWebBreadcrumbEvent

assertRRWebBreadcrumbDefaults(actual)
assertEquals(SentryLevel.INFO, actual.level)
assertEquals("navigation", actual.category)
assertEquals("HomeScreen", actual.data?.get("from"))
assertEquals("ProfileScreen", actual.data?.get("to"))
}

@Test
fun convertNavigationBreadcrumbWithOnlyTo() {
val converter = RNSentryReplayBreadcrumbConverter()
val testBreadcrumb = Breadcrumb()
testBreadcrumb.level = SentryLevel.INFO
testBreadcrumb.type = "navigation"
testBreadcrumb.category = "navigation"
testBreadcrumb.setData("to", "ProfileScreen")
val actual = converter.convert(testBreadcrumb) as RRWebBreadcrumbEvent

assertRRWebBreadcrumbDefaults(actual)
assertEquals(SentryLevel.INFO, actual.level)
assertEquals("navigation", actual.category)
assertEquals(null, actual.data?.get("from"))
assertEquals("ProfileScreen", actual.data?.get("to"))
}

@Test
fun convertForegroundBreadcrumb() {
val converter = RNSentryReplayBreadcrumbConverter()
val testBreadcrumb = Breadcrumb()
testBreadcrumb.type = "navigation"
testBreadcrumb.category = "app.lifecycle"
testBreadcrumb.setData("state", "foreground");
val actual = converter.convert(testBreadcrumb) as RRWebBreadcrumbEvent

assertRRWebBreadcrumbDefaults(actual)
assertEquals("app.foreground", actual.category)
}

@Test
fun convertBackgroundBreadcrumb() {
val converter = RNSentryReplayBreadcrumbConverter()
val testBreadcrumb = Breadcrumb()
testBreadcrumb.type = "navigation"
testBreadcrumb.category = "app.lifecycle"
testBreadcrumb.setData("state", "background");
val actual = converter.convert(testBreadcrumb) as RRWebBreadcrumbEvent

assertRRWebBreadcrumbDefaults(actual)
assertEquals("app.background", actual.category)
}

@Test
fun doesNotConvertSentryEventBreadcrumb() {
val converter = RNSentryReplayBreadcrumbConverter()
val testBreadcrumb = Breadcrumb();
testBreadcrumb.category = "sentry.event"
val actual = converter.convert(testBreadcrumb)
assertEquals(null, actual)
}

@Test
fun doesNotConvertSentryTransactionBreadcrumb() {
val converter = RNSentryReplayBreadcrumbConverter()
val testBreadcrumb = Breadcrumb();
testBreadcrumb.category = "sentry.transaction"
val actual = converter.convert(testBreadcrumb)
assertEquals(null, actual)
}

@Test
fun convertTouchBreadcrumb() {
val converter = RNSentryReplayBreadcrumbConverter()
val testBreadcrumb = Breadcrumb()
testBreadcrumb.level = SentryLevel.INFO
testBreadcrumb.type = "user"
testBreadcrumb.category = "touch"
testBreadcrumb.message = "this won't be used for replay"
testBreadcrumb.setData(
"path",
arrayListOf(mapOf(
"element" to "element4",
"file" to "file4")))
val actual = converter.convert(testBreadcrumb) as RRWebBreadcrumbEvent

assertRRWebBreadcrumbDefaults(actual)
assertEquals(SentryLevel.INFO, actual.level)
assertEquals("ui.tap", actual.category)
assertEquals(1, actual.data?.keys?.size)
assertEquals(
arrayListOf(mapOf(
"element" to "element4",
"file" to "file4")),
actual.data?.get("path"))
}

@Test
fun doesNotConvertNullPath() {
val actual = RNSentryReplayBreadcrumbConverter.getTouchPathMessage(null)
assertEquals(null, actual)
}

@Test
fun doesNotConvertPathContainingNull() {
val actual = RNSentryReplayBreadcrumbConverter.getTouchPathMessage(arrayListOf(arrayOfNulls<Any>(1)))
assertEquals(null, actual)
}

@Test
fun doesNotConvertPathWithValuesMissingNameAndLevel() {
val actual = RNSentryReplayBreadcrumbConverter.getTouchPathMessage(arrayListOf(mapOf(
"element" to "element4",
"file" to "file4")))
assertEquals(null, actual)
}

@Test
fun doesConvertValidPathExample1() {
val actual = RNSentryReplayBreadcrumbConverter.getTouchPathMessage(listOf(
mapOf("label" to "label0"),
mapOf("name" to "name1"),
mapOf("name" to "item2", "label" to "label2"),
mapOf("name" to "item3", "label" to "label3", "element" to "element3"),
mapOf("name" to "item4", "label" to "label4", "file" to "file4"),
mapOf("name" to "item5", "label" to "label5", "element" to "element5", "file" to "file5")))
assertEquals("label3(element3) > label2 > name1 > label0", actual)
}

@Test
fun doesConvertValidPathExample2() {
val actual = RNSentryReplayBreadcrumbConverter.getTouchPathMessage(listOf(
mapOf("name" to "item2", "label" to "label2"),
mapOf("name" to "item3", "label" to "label3", "element" to "element3"),
mapOf("name" to "item4", "label" to "label4", "file" to "file4"),
mapOf("name" to "item5", "label" to "label5", "element" to "element5", "file" to "file5"),
mapOf("label" to "label6"),
mapOf("name" to "name7")))
assertEquals("label5(element5, file5) > label4(file4) > label3(element3) > label2", actual)
}

private fun assertRRWebBreadcrumbDefaults(actual: RRWebBreadcrumbEvent) {
assertEquals("default", actual.breadcrumbType)
assertEquals(actual.breadcrumbTimestamp * 1000, actual.timestamp.toDouble(), 0.05)
assert(actual.breadcrumbTimestamp > 0)
}
}
Loading
Loading