From 9ca5625c9f5479b545158e20222cb4b66461baf4 Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Tue, 11 Jul 2023 14:14:22 +0200 Subject: [PATCH 01/20] add screen to sentry app --- dart/lib/src/protocol/sentry_app.dart | 9 +++++++++ dart/test/protocol/sentry_app_test.dart | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/dart/lib/src/protocol/sentry_app.dart b/dart/lib/src/protocol/sentry_app.dart index 67accebe1a..380494b9c7 100644 --- a/dart/lib/src/protocol/sentry_app.dart +++ b/dart/lib/src/protocol/sentry_app.dart @@ -18,6 +18,7 @@ class SentryApp { this.deviceAppHash, this.appMemory, this.inForeground, + this.screen, }); /// Human readable application name, as it appears on the platform. @@ -48,6 +49,9 @@ class SentryApp { /// An app is in foreground when it's visible to the user. final bool? inForeground; + /// The current application screen. + final String? screen; + /// Deserializes a [SentryApp] from JSON [Map]. factory SentryApp.fromJson(Map data) => SentryApp( name: data['app_name'], @@ -61,6 +65,7 @@ class SentryApp { deviceAppHash: data['device_app_hash'], appMemory: data['app_memory'], inForeground: data['in_foreground'], + screen: data['screen'], ); /// Produces a [Map] that can be serialized to JSON. @@ -75,6 +80,7 @@ class SentryApp { if (appMemory != null) 'app_memory': appMemory!, if (startTime != null) 'app_start_time': startTime!.toIso8601String(), if (inForeground != null) 'in_foreground': inForeground!, + if (screen != null) 'screen': screen! }; } @@ -88,6 +94,7 @@ class SentryApp { deviceAppHash: deviceAppHash, appMemory: appMemory, inForeground: inForeground, + screen: screen, ); SentryApp copyWith({ @@ -100,6 +107,7 @@ class SentryApp { String? deviceAppHash, int? appMemory, bool? inForeground, + String? screen, }) => SentryApp( name: name ?? this.name, @@ -111,5 +119,6 @@ class SentryApp { deviceAppHash: deviceAppHash ?? this.deviceAppHash, appMemory: appMemory ?? this.appMemory, inForeground: inForeground ?? this.inForeground, + screen: screen ?? this.screen, ); } diff --git a/dart/test/protocol/sentry_app_test.dart b/dart/test/protocol/sentry_app_test.dart index 6c72e956d3..6dce83f822 100644 --- a/dart/test/protocol/sentry_app_test.dart +++ b/dart/test/protocol/sentry_app_test.dart @@ -14,6 +14,7 @@ void main() { startTime: testStartTime, deviceAppHash: 'fixture-deviceAppHash', inForeground: true, + screen: 'fixture-screen' ); final sentryAppJson = { @@ -25,6 +26,7 @@ void main() { 'app_start_time': testStartTime.toIso8601String(), 'device_app_hash': 'fixture-deviceAppHash', 'in_foreground': true, + 'screen': 'fixture-screen', }; group('json', () { @@ -73,6 +75,7 @@ void main() { startTime: startTime, deviceAppHash: 'hash1', inForeground: true, + screen: 'screen1', ); expect('name1', copy.name); @@ -83,6 +86,7 @@ void main() { expect(startTime, copy.startTime); expect('hash1', copy.deviceAppHash); expect(true, copy.inForeground); + expect('screen1', copy.screen); }); }); } From 1fa6515d61157857e4dfaf5e1969eeaf06300a1e Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Tue, 11 Jul 2023 15:40:13 +0200 Subject: [PATCH 02/20] sett event.contexts.app.screen to navigator observers current route --- dart/test/protocol/sentry_app_test.dart | 19 ++++----- .../flutter_enricher_event_processor.dart | 13 ++++++ .../navigation/sentry_navigator_observer.dart | 6 +++ ...flutter_enricher_event_processor_test.dart | 41 +++++++++++++++++++ .../test/sentry_navigator_observer_test.dart | 20 +++++++++ 5 files changed, 89 insertions(+), 10 deletions(-) diff --git a/dart/test/protocol/sentry_app_test.dart b/dart/test/protocol/sentry_app_test.dart index 6dce83f822..4f72542f23 100644 --- a/dart/test/protocol/sentry_app_test.dart +++ b/dart/test/protocol/sentry_app_test.dart @@ -6,16 +6,15 @@ void main() { final testStartTime = DateTime.fromMicrosecondsSinceEpoch(0); final sentryApp = SentryApp( - name: 'fixture-name', - version: 'fixture-version', - identifier: 'fixture-identifier', - build: 'fixture-build', - buildType: 'fixture-buildType', - startTime: testStartTime, - deviceAppHash: 'fixture-deviceAppHash', - inForeground: true, - screen: 'fixture-screen' - ); + name: 'fixture-name', + version: 'fixture-version', + identifier: 'fixture-identifier', + build: 'fixture-build', + buildType: 'fixture-buildType', + startTime: testStartTime, + deviceAppHash: 'fixture-deviceAppHash', + inForeground: true, + screen: 'fixture-screen'); final sentryAppJson = { 'app_name': 'fixture-name', diff --git a/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart b/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart index f72eb2470b..d68efaba0f 100644 --- a/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart +++ b/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart @@ -5,6 +5,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:sentry/sentry.dart'; +import '../navigation/sentry_navigator_observer.dart'; import '../sentry_flutter_options.dart'; typedef WidgetBindingGetter = WidgetsBinding? Function(); @@ -47,6 +48,11 @@ class FlutterEnricherEventProcessor implements EventProcessor { app: _getApp(event.contexts.app), ); + final app = contexts.app; + if (app != null) { + _getAppScreen(contexts, app); + } + // Flutter has a lot of Accessibility Settings available and exposes them contexts['accessibility'] = _getAccessibilityContext(); @@ -237,4 +243,11 @@ class FlutterEnricherEventProcessor implements EventProcessor { inForeground: inForeground, ); } + + void _getAppScreen(Contexts contexts, SentryApp app) { + final currentRouteName = SentryNavigatorObserver.currentRouteName; + if (currentRouteName != null) { + contexts.app = app.copyWith(screen: currentRouteName); + } + } } diff --git a/flutter/lib/src/navigation/sentry_navigator_observer.dart b/flutter/lib/src/navigation/sentry_navigator_observer.dart index de5b51c52e..c8bcd2c765 100644 --- a/flutter/lib/src/navigation/sentry_navigator_observer.dart +++ b/flutter/lib/src/navigation/sentry_navigator_observer.dart @@ -85,6 +85,11 @@ class SentryNavigatorObserver extends RouteObserver> { ISentrySpan? _transaction; + static String? _currentRouteName; + + /// Get the current route of the observer. + static String? get currentRouteName => _currentRouteName; + @override void didPush(Route route, Route? previousRoute) { super.didPush(route, previousRoute); @@ -201,6 +206,7 @@ class SentryNavigatorObserver extends RouteObserver> { } }, ); + _currentRouteName = name; // if _enableAutoTransactions is enabled but there's no traces sample rate if (_transaction is NoOpSentrySpan) { diff --git a/flutter/test/event_processor/flutter_enricher_event_processor_test.dart b/flutter/test/event_processor/flutter_enricher_event_processor_test.dart index bfccb8c773..bac759ce58 100644 --- a/flutter/test/event_processor/flutter_enricher_event_processor_test.dart +++ b/flutter/test/event_processor/flutter_enricher_event_processor_test.dart @@ -322,6 +322,42 @@ void main() { .length; expect(ioEnricherCount, 1); }); + + testWidgets('adds SentryNavigatorObserver.currentRouteName as app.screen', + (tester) async { + final observer = SentryNavigatorObserver(); + final route = + fixture.route(RouteSettings(name: 'fixture-currentRouteName')); + observer.didPush(route, null); + + final eventWithContextsApp = + SentryEvent(contexts: Contexts(app: SentryApp())); + + final enricher = fixture.getSut( + binding: () => tester.binding, + ); + final event = await enricher.apply(eventWithContextsApp); + + expect(event?.contexts.app?.screen, 'fixture-currentRouteName'); + }); + + testWidgets( + 'does not add SentryNavigatorObserver.currentRouteName if no app', + (tester) async { + final observer = SentryNavigatorObserver(); + final route = + fixture.route(RouteSettings(name: 'fixture-currentRouteName')); + observer.didPush(route, null); + + final eventWithoutContextsApp = SentryEvent(contexts: Contexts()); + + final enricher = fixture.getSut( + binding: () => tester.binding, + ); + final event = await enricher.apply(eventWithoutContextsApp); + + expect(event?.contexts.app?.screen, isNull); + }); }); } @@ -342,6 +378,11 @@ class Fixture { )..reportPackages = reportPackages; return FlutterEnricherEventProcessor(options); } + + PageRoute route(RouteSettings? settings) => PageRouteBuilder( + pageBuilder: (_, __, ___) => Container(), + settings: settings, + ); } void loadTestPackage() { diff --git a/flutter/test/sentry_navigator_observer_test.dart b/flutter/test/sentry_navigator_observer_test.dart index d3871b4390..81a1b841f2 100644 --- a/flutter/test/sentry_navigator_observer_test.dart +++ b/flutter/test/sentry_navigator_observer_test.dart @@ -368,6 +368,26 @@ void main() { expect(scope.span, span); }); }); + + test('exposes current route name', () { + const name = 'Current Route'; + final currentRoute = route(RouteSettings(name: name)); + + const op = 'navigation'; + final hub = _MockHub(); + final span = getMockSentryTracer(name: name); + when(span.context).thenReturn(SentrySpanContext(operation: op)); + _whenAnyStart(hub, span); + + final sut = fixture.getSut( + hub: hub, + autoFinishAfter: Duration(seconds: 5), + ); + + sut.didPush(currentRoute, null); + + expect(SentryNavigatorObserver.currentRouteName, 'Current Route'); + }); }); group('RouteObserverBreadcrumb', () { From 90b59e1e3501a83933a2c528b50879e2538d4cd2 Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Tue, 11 Jul 2023 16:24:30 +0200 Subject: [PATCH 03/20] add changelog entry --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd21c716a0..c929b15b3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased + +- Set `SentryNavigatorObserver` current route as `event.app.contexts.screen` ([#1545](https://github.com/getsentry/sentry-dart/pull/1545)) + ## 7.8.0 ### Enhancements From 93debb72d6046b0b525771239c33578918b52d24 Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Tue, 11 Jul 2023 16:27:49 +0200 Subject: [PATCH 04/20] remove failing test, as lifecyle may init new app instance --- .../flutter_enricher_event_processor_test.dart | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/flutter/test/event_processor/flutter_enricher_event_processor_test.dart b/flutter/test/event_processor/flutter_enricher_event_processor_test.dart index bac759ce58..831434af18 100644 --- a/flutter/test/event_processor/flutter_enricher_event_processor_test.dart +++ b/flutter/test/event_processor/flutter_enricher_event_processor_test.dart @@ -340,24 +340,6 @@ void main() { expect(event?.contexts.app?.screen, 'fixture-currentRouteName'); }); - - testWidgets( - 'does not add SentryNavigatorObserver.currentRouteName if no app', - (tester) async { - final observer = SentryNavigatorObserver(); - final route = - fixture.route(RouteSettings(name: 'fixture-currentRouteName')); - observer.didPush(route, null); - - final eventWithoutContextsApp = SentryEvent(contexts: Contexts()); - - final enricher = fixture.getSut( - binding: () => tester.binding, - ); - final event = await enricher.apply(eventWithoutContextsApp); - - expect(event?.contexts.app?.screen, isNull); - }); }); } From 8eadcddd971b8292a1d3c8be39283ba280fdf666 Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Mon, 17 Jul 2023 10:16:40 +0200 Subject: [PATCH 05/20] rename property and add more comments --- dart/lib/src/protocol/sentry_app.dart | 16 ++++++++-------- dart/test/protocol/sentry_app_test.dart | 8 ++++---- .../flutter_enricher_event_processor.dart | 2 +- .../navigation/sentry_navigator_observer.dart | 3 +++ .../flutter_enricher_event_processor_test.dart | 2 +- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/dart/lib/src/protocol/sentry_app.dart b/dart/lib/src/protocol/sentry_app.dart index 380494b9c7..b4fa436ebd 100644 --- a/dart/lib/src/protocol/sentry_app.dart +++ b/dart/lib/src/protocol/sentry_app.dart @@ -18,7 +18,7 @@ class SentryApp { this.deviceAppHash, this.appMemory, this.inForeground, - this.screen, + this.viewName, }); /// Human readable application name, as it appears on the platform. @@ -49,8 +49,8 @@ class SentryApp { /// An app is in foreground when it's visible to the user. final bool? inForeground; - /// The current application screen. - final String? screen; + /// The name of the current view that is visible. + final String? viewName; /// Deserializes a [SentryApp] from JSON [Map]. factory SentryApp.fromJson(Map data) => SentryApp( @@ -65,7 +65,7 @@ class SentryApp { deviceAppHash: data['device_app_hash'], appMemory: data['app_memory'], inForeground: data['in_foreground'], - screen: data['screen'], + viewName: data['view_name'], ); /// Produces a [Map] that can be serialized to JSON. @@ -80,7 +80,7 @@ class SentryApp { if (appMemory != null) 'app_memory': appMemory!, if (startTime != null) 'app_start_time': startTime!.toIso8601String(), if (inForeground != null) 'in_foreground': inForeground!, - if (screen != null) 'screen': screen! + if (viewName != null) 'view_name': viewName! }; } @@ -94,7 +94,7 @@ class SentryApp { deviceAppHash: deviceAppHash, appMemory: appMemory, inForeground: inForeground, - screen: screen, + viewName: viewName, ); SentryApp copyWith({ @@ -107,7 +107,7 @@ class SentryApp { String? deviceAppHash, int? appMemory, bool? inForeground, - String? screen, + String? viewName, }) => SentryApp( name: name ?? this.name, @@ -119,6 +119,6 @@ class SentryApp { deviceAppHash: deviceAppHash ?? this.deviceAppHash, appMemory: appMemory ?? this.appMemory, inForeground: inForeground ?? this.inForeground, - screen: screen ?? this.screen, + viewName: viewName ?? this.viewName, ); } diff --git a/dart/test/protocol/sentry_app_test.dart b/dart/test/protocol/sentry_app_test.dart index 4f72542f23..7af55ec250 100644 --- a/dart/test/protocol/sentry_app_test.dart +++ b/dart/test/protocol/sentry_app_test.dart @@ -14,7 +14,7 @@ void main() { startTime: testStartTime, deviceAppHash: 'fixture-deviceAppHash', inForeground: true, - screen: 'fixture-screen'); + viewName: 'fixture-viewName'); final sentryAppJson = { 'app_name': 'fixture-name', @@ -25,7 +25,7 @@ void main() { 'app_start_time': testStartTime.toIso8601String(), 'device_app_hash': 'fixture-deviceAppHash', 'in_foreground': true, - 'screen': 'fixture-screen', + 'view_name': 'fixture-viewName', }; group('json', () { @@ -74,7 +74,7 @@ void main() { startTime: startTime, deviceAppHash: 'hash1', inForeground: true, - screen: 'screen1', + viewName: 'screen1', ); expect('name1', copy.name); @@ -85,7 +85,7 @@ void main() { expect(startTime, copy.startTime); expect('hash1', copy.deviceAppHash); expect(true, copy.inForeground); - expect('screen1', copy.screen); + expect('screen1', copy.viewName); }); }); } diff --git a/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart b/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart index d68efaba0f..28a7eb04b4 100644 --- a/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart +++ b/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart @@ -247,7 +247,7 @@ class FlutterEnricherEventProcessor implements EventProcessor { void _getAppScreen(Contexts contexts, SentryApp app) { final currentRouteName = SentryNavigatorObserver.currentRouteName; if (currentRouteName != null) { - contexts.app = app.copyWith(screen: currentRouteName); + contexts.app = app.copyWith(viewName: currentRouteName); } } } diff --git a/flutter/lib/src/navigation/sentry_navigator_observer.dart b/flutter/lib/src/navigation/sentry_navigator_observer.dart index c8bcd2c765..d664d316fa 100644 --- a/flutter/lib/src/navigation/sentry_navigator_observer.dart +++ b/flutter/lib/src/navigation/sentry_navigator_observer.dart @@ -23,6 +23,9 @@ typedef AdditionalInfoExtractor = Map? Function( /// The [RouteSettings] is null if a developer has not specified any /// RouteSettings. /// +/// The current route name will also be set to [SentryEvent] +/// `contexts.app.view_name` by [FlutterEnricherEventProcessor]. +/// /// [SentryNavigatorObserver] must be added to the [navigation observer](https://api.flutter.dev/flutter/material/MaterialApp/navigatorObservers.html) of /// your used app. This is an example for [MaterialApp](https://api.flutter.dev/flutter/material/MaterialApp/navigatorObservers.html), /// but the integration for [CupertinoApp](https://api.flutter.dev/flutter/cupertino/CupertinoApp/navigatorObservers.html) diff --git a/flutter/test/event_processor/flutter_enricher_event_processor_test.dart b/flutter/test/event_processor/flutter_enricher_event_processor_test.dart index 831434af18..b48e98e405 100644 --- a/flutter/test/event_processor/flutter_enricher_event_processor_test.dart +++ b/flutter/test/event_processor/flutter_enricher_event_processor_test.dart @@ -338,7 +338,7 @@ void main() { ); final event = await enricher.apply(eventWithContextsApp); - expect(event?.contexts.app?.screen, 'fixture-currentRouteName'); + expect(event?.contexts.app?.viewName, 'fixture-currentRouteName'); }); }); } From b3565710365fbec8a23eb473f48cb7e61890a1a4 Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Mon, 17 Jul 2023 14:35:03 +0200 Subject: [PATCH 06/20] update changelog --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c929b15b3d..2fe9090754 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,9 @@ ## Unreleased -- Set `SentryNavigatorObserver` current route as `event.app.contexts.screen` ([#1545](https://github.com/getsentry/sentry-dart/pull/1545)) +### Features + +- Set `SentryNavigatorObserver` current route as `event.app.contexts.viewName` ([#1545](https://github.com/getsentry/sentry-dart/pull/1545)) ## 7.8.0 From 320fe7a6220552e7a5a8b44cca2b31d07f596684 Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Mon, 31 Jul 2023 11:54:46 +0200 Subject: [PATCH 07/20] change to array --- dart/lib/src/protocol/sentry_app.dart | 45 ++++++++-------- dart/test/protocol/sentry_app_test.dart | 51 +++++++++++-------- flutter/example/lib/main.dart | 1 - .../flutter_enricher_event_processor.dart | 4 +- ...flutter_enricher_event_processor_test.dart | 2 +- 5 files changed, 59 insertions(+), 44 deletions(-) diff --git a/dart/lib/src/protocol/sentry_app.dart b/dart/lib/src/protocol/sentry_app.dart index b4fa436ebd..bdded1d28e 100644 --- a/dart/lib/src/protocol/sentry_app.dart +++ b/dart/lib/src/protocol/sentry_app.dart @@ -18,7 +18,7 @@ class SentryApp { this.deviceAppHash, this.appMemory, this.inForeground, - this.viewName, + this.viewNames, }); /// Human readable application name, as it appears on the platform. @@ -50,23 +50,26 @@ class SentryApp { final bool? inForeground; /// The name of the current view that is visible. - final String? viewName; + final List? viewNames; /// Deserializes a [SentryApp] from JSON [Map]. - factory SentryApp.fromJson(Map data) => SentryApp( - name: data['app_name'], - version: data['app_version'], - identifier: data['app_identifier'], - build: data['app_build'], - buildType: data['build_type'], - startTime: data['app_start_time'] != null - ? DateTime.tryParse(data['app_start_time']) - : null, - deviceAppHash: data['device_app_hash'], - appMemory: data['app_memory'], - inForeground: data['in_foreground'], - viewName: data['view_name'], - ); + factory SentryApp.fromJson(Map data) { + final viewNamesJson = data['view_names'] as List?; + return SentryApp( + name: data['app_name'], + version: data['app_version'], + identifier: data['app_identifier'], + build: data['app_build'], + buildType: data['build_type'], + startTime: data['app_start_time'] != null + ? DateTime.tryParse(data['app_start_time']) + : null, + deviceAppHash: data['device_app_hash'], + appMemory: data['app_memory'], + inForeground: data['in_foreground'], + viewNames: viewNamesJson?.map((e) => e as String).toList(), + ); + } /// Produces a [Map] that can be serialized to JSON. Map toJson() { @@ -76,11 +79,11 @@ class SentryApp { if (identifier != null) 'app_identifier': identifier!, if (build != null) 'app_build': build!, if (buildType != null) 'build_type': buildType!, + if (startTime != null) 'app_start_time': startTime!.toIso8601String(), if (deviceAppHash != null) 'device_app_hash': deviceAppHash!, if (appMemory != null) 'app_memory': appMemory!, - if (startTime != null) 'app_start_time': startTime!.toIso8601String(), if (inForeground != null) 'in_foreground': inForeground!, - if (viewName != null) 'view_name': viewName! + if (viewNames != null && viewNames!.isNotEmpty) 'view_names': viewNames!, }; } @@ -94,7 +97,7 @@ class SentryApp { deviceAppHash: deviceAppHash, appMemory: appMemory, inForeground: inForeground, - viewName: viewName, + viewNames: viewNames, ); SentryApp copyWith({ @@ -107,7 +110,7 @@ class SentryApp { String? deviceAppHash, int? appMemory, bool? inForeground, - String? viewName, + List? viewNames, }) => SentryApp( name: name ?? this.name, @@ -119,6 +122,6 @@ class SentryApp { deviceAppHash: deviceAppHash ?? this.deviceAppHash, appMemory: appMemory ?? this.appMemory, inForeground: inForeground ?? this.inForeground, - viewName: viewName ?? this.viewName, + viewNames: viewNames ?? this.viewNames, ); } diff --git a/dart/test/protocol/sentry_app_test.dart b/dart/test/protocol/sentry_app_test.dart index 7af55ec250..6fd4236efc 100644 --- a/dart/test/protocol/sentry_app_test.dart +++ b/dart/test/protocol/sentry_app_test.dart @@ -6,15 +6,16 @@ void main() { final testStartTime = DateTime.fromMicrosecondsSinceEpoch(0); final sentryApp = SentryApp( - name: 'fixture-name', - version: 'fixture-version', - identifier: 'fixture-identifier', - build: 'fixture-build', - buildType: 'fixture-buildType', - startTime: testStartTime, - deviceAppHash: 'fixture-deviceAppHash', - inForeground: true, - viewName: 'fixture-viewName'); + name: 'fixture-name', + version: 'fixture-version', + identifier: 'fixture-identifier', + build: 'fixture-build', + buildType: 'fixture-buildType', + startTime: testStartTime, + deviceAppHash: 'fixture-deviceAppHash', + inForeground: true, + viewNames: ['fixture-viewName', 'fixture-viewName2'], + ); final sentryAppJson = { 'app_name': 'fixture-name', @@ -25,26 +26,36 @@ void main() { 'app_start_time': testStartTime.toIso8601String(), 'device_app_hash': 'fixture-deviceAppHash', 'in_foreground': true, - 'view_name': 'fixture-viewName', + 'view_names': ['fixture-viewName', 'fixture-viewName2'], }; group('json', () { test('toJson', () { final json = sentryApp.toJson(); - expect( - MapEquality().equals(sentryAppJson, json), - true, - ); + expect(json['app_name'], 'fixture-name'); + expect(json['app_version'], 'fixture-version'); + expect(json['app_identifier'], 'fixture-identifier'); + expect(json['app_build'], 'fixture-build'); + expect(json['build_type'], 'fixture-buildType'); + expect(json['app_start_time'], testStartTime.toIso8601String()); + expect(json['device_app_hash'], 'fixture-deviceAppHash'); + expect(json['in_foreground'], true); + expect(json['view_names'], ['fixture-viewName', 'fixture-viewName2']); }); test('fromJson', () { final sentryApp = SentryApp.fromJson(sentryAppJson); final json = sentryApp.toJson(); - expect( - MapEquality().equals(sentryAppJson, json), - true, - ); + expect(json['app_name'], 'fixture-name'); + expect(json['app_version'], 'fixture-version'); + expect(json['app_identifier'], 'fixture-identifier'); + expect(json['app_build'], 'fixture-build'); + expect(json['build_type'], 'fixture-buildType'); + expect(json['app_start_time'], testStartTime.toIso8601String()); + expect(json['device_app_hash'], 'fixture-deviceAppHash'); + expect(json['in_foreground'], true); + expect(json['view_names'], ['fixture-viewName', 'fixture-viewName2']); }); }); @@ -74,7 +85,7 @@ void main() { startTime: startTime, deviceAppHash: 'hash1', inForeground: true, - viewName: 'screen1', + viewNames: ['screen1'], ); expect('name1', copy.name); @@ -85,7 +96,7 @@ void main() { expect(startTime, copy.startTime); expect('hash1', copy.deviceAppHash); expect(true, copy.inForeground); - expect('screen1', copy.viewName); + expect(['screen1'], copy.viewNames); }); }); } diff --git a/flutter/example/lib/main.dart b/flutter/example/lib/main.dart index 9d02d1ecba..6d657a589e 100644 --- a/flutter/example/lib/main.dart +++ b/flutter/example/lib/main.dart @@ -2,7 +2,6 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:io' show Platform; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; diff --git a/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart b/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart index 28a7eb04b4..ebe15f5297 100644 --- a/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart +++ b/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart @@ -247,7 +247,9 @@ class FlutterEnricherEventProcessor implements EventProcessor { void _getAppScreen(Contexts contexts, SentryApp app) { final currentRouteName = SentryNavigatorObserver.currentRouteName; if (currentRouteName != null) { - contexts.app = app.copyWith(viewName: currentRouteName); + final viewNames = app.viewNames ?? []; + viewNames.add(currentRouteName); + contexts.app = app.copyWith(viewNames: viewNames); } } } diff --git a/flutter/test/event_processor/flutter_enricher_event_processor_test.dart b/flutter/test/event_processor/flutter_enricher_event_processor_test.dart index b48e98e405..4e748b2934 100644 --- a/flutter/test/event_processor/flutter_enricher_event_processor_test.dart +++ b/flutter/test/event_processor/flutter_enricher_event_processor_test.dart @@ -338,7 +338,7 @@ void main() { ); final event = await enricher.apply(eventWithContextsApp); - expect(event?.contexts.app?.viewName, 'fixture-currentRouteName'); + expect(event?.contexts.app?.viewNames, ['fixture-currentRouteName']); }); }); } From 5ae2e54f0d6f03fd4fa3bcf98cd40cfa756ed9f8 Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Mon, 31 Jul 2023 11:55:43 +0200 Subject: [PATCH 08/20] change comment --- dart/lib/src/protocol/sentry_app.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dart/lib/src/protocol/sentry_app.dart b/dart/lib/src/protocol/sentry_app.dart index bdded1d28e..b5163e5856 100644 --- a/dart/lib/src/protocol/sentry_app.dart +++ b/dart/lib/src/protocol/sentry_app.dart @@ -49,7 +49,7 @@ class SentryApp { /// An app is in foreground when it's visible to the user. final bool? inForeground; - /// The name of the current view that is visible. + /// The names of the currently visible views. final List? viewNames; /// Deserializes a [SentryApp] from JSON [Map]. From 2c2e6d2bff9fdbcb9e7ddb8c4733d37674b5d11f Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Mon, 31 Jul 2023 11:56:53 +0200 Subject: [PATCH 09/20] update comment --- flutter/lib/src/navigation/sentry_navigator_observer.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flutter/lib/src/navigation/sentry_navigator_observer.dart b/flutter/lib/src/navigation/sentry_navigator_observer.dart index 73dad38922..91ee0617e4 100644 --- a/flutter/lib/src/navigation/sentry_navigator_observer.dart +++ b/flutter/lib/src/navigation/sentry_navigator_observer.dart @@ -24,7 +24,7 @@ typedef AdditionalInfoExtractor = Map? Function( /// RouteSettings. /// /// The current route name will also be set to [SentryEvent] -/// `contexts.app.view_name` by [FlutterEnricherEventProcessor]. +/// `contexts.app.view_names` by [FlutterEnricherEventProcessor]. /// /// [SentryNavigatorObserver] must be added to the [navigation observer](https://api.flutter.dev/flutter/material/MaterialApp/navigatorObservers.html) of /// your used app. This is an example for [MaterialApp](https://api.flutter.dev/flutter/material/MaterialApp/navigatorObservers.html), From 6ac2ec60b3d2f32b9c161835f2fc8480bc6abc10 Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Mon, 31 Jul 2023 13:28:00 +0200 Subject: [PATCH 10/20] update changelog entry --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc97ea2b91..0452f321d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ### Features -- Set `SentryNavigatorObserver` current route as `event.app.contexts.viewName` ([#1545](https://github.com/getsentry/sentry-dart/pull/1545)) +- Add `SentryNavigatorObserver` current route to `event.app.contexts.viewNames` ([#1545](https://github.com/getsentry/sentry-dart/pull/1545)) - Send trace origin ([#1534](https://github.com/getsentry/sentry-dart/pull/1534)) [Trace origin](https://develop.sentry.dev/sdk/performance/trace-origin/) indicates what created a trace or a span. Not all transactions and spans contain enough information to tell whether the user or what precisely in the SDK created it. Origin solves this problem. The SDK now sends origin for transactions and spans. From 54283bb5b33ca63073cb08e2421112614bc25b00 Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Tue, 22 Aug 2023 11:02:38 +0200 Subject: [PATCH 11/20] fix changelog --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79d8758f81..66e9dcafa1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Features + +- Add `SentryNavigatorObserver` current route to `event.app.contexts.viewNames` ([#1545](https://github.com/getsentry/sentry-dart/pull/1545)) + ### Fixes - Fixing memory leak issue in SentryFlutterPlugin (Android Plugin) ([#1588](https://github.com/getsentry/sentry-dart/pull/1588)) @@ -19,7 +23,6 @@ ### Features -- Add `SentryNavigatorObserver` current route to `event.app.contexts.viewNames` ([#1545](https://github.com/getsentry/sentry-dart/pull/1545)) - Send trace origin ([#1534](https://github.com/getsentry/sentry-dart/pull/1534)) [Trace origin](https://develop.sentry.dev/sdk/performance/trace-origin/) indicates what created a trace or a span. Not all transactions and spans contain enough information to tell whether the user or what precisely in the SDK created it. Origin solves this problem. The SDK now sends origin for transactions and spans. From 18185456ba94faf3a6c62b94f077c3895ace5e1c Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Tue, 29 Aug 2023 17:10:04 +0200 Subject: [PATCH 12/20] run `dart fix --apply` --- dio/test/dio_event_processor_test.dart | 24 +++++++++---------- dio/test/failed_request_interceptor_test.dart | 2 +- dio/test/mocks.dart | 2 +- sqflite/test/mocks/mocks.dart | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/dio/test/dio_event_processor_test.dart b/dio/test/dio_event_processor_test.dart index af45d0c681..3cd060ea8e 100644 --- a/dio/test/dio_event_processor_test.dart +++ b/dio/test/dio_event_processor_test.dart @@ -67,7 +67,7 @@ void main() { throwable: throwable, exceptions: [ fixture.sentryError(throwable), - fixture.sentryError(dioError) + fixture.sentryError(dioError), ], ); final processedEvent = sut.apply(event) as SentryEvent; @@ -96,7 +96,7 @@ void main() { throwable: throwable, exceptions: [ fixture.sentryError(throwable), - fixture.sentryError(dioError) + fixture.sentryError(dioError), ], ); final processedEvent = sut.apply(event) as SentryEvent; @@ -125,7 +125,7 @@ void main() { throwable: throwable, exceptions: [ fixture.sentryError(throwable), - fixture.sentryError(dioError) + fixture.sentryError(dioError), ], ); final processedEvent = sut.apply(event) as SentryEvent; @@ -177,7 +177,7 @@ void main() { throwable: throwable, exceptions: [ fixture.sentryError(throwable), - fixture.sentryError(dioError) + fixture.sentryError(dioError), ], ); final processedEvent = sut.apply(event) as SentryEvent; @@ -207,7 +207,7 @@ void main() { data: 'foobar', headers: Headers.fromMap(>{ 'foo': ['bar'], - 'set-cookie': ['foo=bar'] + 'set-cookie': ['foo=bar'], }), requestOptions: request, isRedirect: true, @@ -219,7 +219,7 @@ void main() { throwable: throwable, exceptions: [ fixture.sentryError(throwable), - fixture.sentryError(dioError) + fixture.sentryError(dioError), ], ); final processedEvent = sut.apply(event) as SentryEvent; @@ -248,7 +248,7 @@ void main() { response: Response( data: 'foobar', headers: Headers.fromMap(>{ - 'foo': ['bar'] + 'foo': ['bar'], }), requestOptions: request, isRedirect: true, @@ -260,7 +260,7 @@ void main() { throwable: throwable, exceptions: [ fixture.sentryError(throwable), - fixture.sentryError(dioError) + fixture.sentryError(dioError), ], ); final processedEvent = sut.apply(event) as SentryEvent; @@ -320,7 +320,7 @@ void main() { throwable: throwable, exceptions: [ fixture.sentryError(throwable), - fixture.sentryError(dioError) + fixture.sentryError(dioError), ], ); final processedEvent = sut.apply(event) as SentryEvent; @@ -338,7 +338,7 @@ void main() { final dataByType = { ResponseType.plain: ['plain'], ResponseType.bytes: [ - [1337] + [1337], ], ResponseType.json: [ 9001, @@ -347,7 +347,7 @@ void main() { true, ['list'], {'map-key': 'map-value'}, - ] + ], }; for (final entry in dataByType.entries) { @@ -375,7 +375,7 @@ void main() { throwable: throwable, exceptions: [ fixture.sentryError(throwable), - fixture.sentryError(dioError) + fixture.sentryError(dioError), ], ); final processedEvent = sut.apply(event) as SentryEvent; diff --git a/dio/test/failed_request_interceptor_test.dart b/dio/test/failed_request_interceptor_test.dart index 80eede8803..e7fb5a63e1 100644 --- a/dio/test/failed_request_interceptor_test.dart +++ b/dio/test/failed_request_interceptor_test.dart @@ -113,7 +113,7 @@ class Fixture { FailedRequestInterceptor getSut({ List failedRequestStatusCodes = const [ - SentryStatusCode.defaultRange() + SentryStatusCode.defaultRange(), ], List failedRequestTargets = const ['.*'], }) { diff --git a/dio/test/mocks.dart b/dio/test/mocks.dart index 83454cbfb3..5ed6dcd00a 100644 --- a/dio/test/mocks.dart +++ b/dio/test/mocks.dart @@ -42,7 +42,7 @@ final fakeEvent = SentryEvent( type: 'navigation', data: {'screen': 'MainActivity', 'state': 'created'}, level: SentryLevel.info, - ) + ), ], contexts: Contexts( operatingSystem: const SentryOperatingSystem( diff --git a/sqflite/test/mocks/mocks.dart b/sqflite/test/mocks/mocks.dart index 0a3115df74..5ecd57ce50 100644 --- a/sqflite/test/mocks/mocks.dart +++ b/sqflite/test/mocks/mocks.dart @@ -33,7 +33,7 @@ ISentrySpan startTransactionShim( DatabaseExecutor, ], customMocks: [ - MockSpec(fallbackGenerators: {#startTransaction: startTransactionShim}) + MockSpec(fallbackGenerators: {#startTransaction: startTransactionShim}), ], ) void main() {} From c02722668f2fbdb69fc303a1c54d5d68e5400d0e Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Mon, 11 Sep 2023 13:48:23 +0200 Subject: [PATCH 13/20] fix changelog --- CHANGELOG.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c05ba4886b..89b7976dd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,6 @@ ## Unreleased -### Features - -- Add `SentryNavigatorObserver` current route to `event.app.contexts.viewNames` ([#1545](https://github.com/getsentry/sentry-dart/pull/1545)) ### Enhancements - Add http.request.method attribute to http spans data ([#1633](https://github.com/getsentry/sentry-dart/pull/1633)) @@ -13,6 +10,7 @@ ### Features - Tracing without performance ([#1621](https://github.com/getsentry/sentry-dart/pull/1621)) +- Add `SentryNavigatorObserver` current route to `event.app.contexts.viewNames` ([#1545](https://github.com/getsentry/sentry-dart/pull/1545)) ### Fixes From 6da8a51a9fd7f293886d07e2aacf5dc66414aa28 Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Mon, 2 Oct 2023 15:45:52 +0200 Subject: [PATCH 14/20] fix changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ba89f9317..4fe9995fd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Features - Breadcrumbs for file I/O operations ([#1649](https://github.com/getsentry/sentry-dart/pull/1649)) +- Add `SentryNavigatorObserver` current route to `event.app.contexts.viewNames` ([#1545](https://github.com/getsentry/sentry-dart/pull/1545)) ### Dependencies @@ -25,7 +26,6 @@ ### Features - Tracing without performance ([#1621](https://github.com/getsentry/sentry-dart/pull/1621)) -- Add `SentryNavigatorObserver` current route to `event.app.contexts.viewNames` ([#1545](https://github.com/getsentry/sentry-dart/pull/1545)) ### Fixes From 445babb8f6523492d658b4d698d7da14b49d6af9 Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Tue, 3 Oct 2023 17:56:13 +0200 Subject: [PATCH 15/20] Add missing import --- flutter/lib/src/navigation/sentry_navigator_observer.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/flutter/lib/src/navigation/sentry_navigator_observer.dart b/flutter/lib/src/navigation/sentry_navigator_observer.dart index 0029775b62..55e894168d 100644 --- a/flutter/lib/src/navigation/sentry_navigator_observer.dart +++ b/flutter/lib/src/navigation/sentry_navigator_observer.dart @@ -1,6 +1,7 @@ import 'package:flutter/widgets.dart'; import '../../sentry_flutter.dart'; +import '../event_processor/flutter_enricher_event_processor.dart'; import '../native/sentry_native.dart'; /// This key must be used so that the web interface displays the events nicely From 9e07c771cb25fa7b22d478a960e0b4274d3ecb79 Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Mon, 9 Oct 2023 16:08:32 +0200 Subject: [PATCH 16/20] Update changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67aaa0caea..4aa5530705 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,8 @@ - Breadcrumbs for file I/O operations ([#1649](https://github.com/getsentry/sentry-dart/pull/1649)) - Add `SentryNavigatorObserver` current route to `event.app.contexts.viewNames` ([#1545](https://github.com/getsentry/sentry-dart/pull/1545)) - + - Requires relay version [23.9.0](https://github.com/getsentry/relay/blob/master/CHANGELOG.md#2390) for self-hosted instances + ### Dependencies - Enable compatibility with uuid v4 ([#1647](https://github.com/getsentry/sentry-dart/pull/1647)) From 3cef7aaa5dd3671306c02b88e8ccfeaa70685292 Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Mon, 9 Oct 2023 16:19:24 +0200 Subject: [PATCH 17/20] rename method --- .../event_processor/flutter_enricher_event_processor.dart | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart b/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart index ebe15f5297..b0eaa0fe71 100644 --- a/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart +++ b/flutter/lib/src/event_processor/flutter_enricher_event_processor.dart @@ -50,7 +50,7 @@ class FlutterEnricherEventProcessor implements EventProcessor { final app = contexts.app; if (app != null) { - _getAppScreen(contexts, app); + contexts.app = _appWithCurrentRouteViewName(app); } // Flutter has a lot of Accessibility Settings available and exposes them @@ -244,12 +244,14 @@ class FlutterEnricherEventProcessor implements EventProcessor { ); } - void _getAppScreen(Contexts contexts, SentryApp app) { + SentryApp _appWithCurrentRouteViewName(SentryApp app) { final currentRouteName = SentryNavigatorObserver.currentRouteName; if (currentRouteName != null) { final viewNames = app.viewNames ?? []; viewNames.add(currentRouteName); - contexts.app = app.copyWith(viewNames: viewNames); + return app.copyWith(viewNames: viewNames); + } else { + return app; } } } From 5975e5c50a56b6ddcbf7a8adb8b6c8299dd4143b Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Mon, 9 Oct 2023 16:47:36 +0200 Subject: [PATCH 18/20] Also set current route name on replace --- .../navigation/sentry_navigator_observer.dart | 18 +++++-- .../test/sentry_navigator_observer_test.dart | 49 ++++++++++++++++++- 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/flutter/lib/src/navigation/sentry_navigator_observer.dart b/flutter/lib/src/navigation/sentry_navigator_observer.dart index 55e894168d..5dff01493d 100644 --- a/flutter/lib/src/navigation/sentry_navigator_observer.dart +++ b/flutter/lib/src/navigation/sentry_navigator_observer.dart @@ -97,7 +97,8 @@ class SentryNavigatorObserver extends RouteObserver> { void didPush(Route route, Route? previousRoute) { super.didPush(route, previousRoute); - _setCurrentRoute(route); + _setCurrentRouteName(route); + _setCurrentRouteNameAsTransaction(route); _addBreadcrumb( type: 'didPush', @@ -113,7 +114,9 @@ class SentryNavigatorObserver extends RouteObserver> { void didReplace({Route? newRoute, Route? oldRoute}) { super.didReplace(newRoute: newRoute, oldRoute: oldRoute); - _setCurrentRoute(newRoute); + _setCurrentRouteName(newRoute); + _setCurrentRouteNameAsTransaction(newRoute); + _addBreadcrumb( type: 'didReplace', from: oldRoute?.settings, @@ -125,7 +128,9 @@ class SentryNavigatorObserver extends RouteObserver> { void didPop(Route route, Route? previousRoute) { super.didPop(route, previousRoute); - _setCurrentRoute(previousRoute); + _setCurrentRouteName(previousRoute); + _setCurrentRouteNameAsTransaction(previousRoute); + _addBreadcrumb( type: 'didPop', from: route.settings, @@ -156,7 +161,11 @@ class SentryNavigatorObserver extends RouteObserver> { ?.name; } - Future _setCurrentRoute(Route? route) async { + Future _setCurrentRouteName(Route? route) async { + _currentRouteName = _getRouteName(route); + } + + Future _setCurrentRouteNameAsTransaction(Route? route) async { final name = _getRouteName(route); if (name == null) { return; @@ -212,7 +221,6 @@ class SentryNavigatorObserver extends RouteObserver> { } }, ); - _currentRouteName = name; // if _enableAutoTransactions is enabled but there's no traces sample rate if (_transaction is NoOpSentrySpan) { diff --git a/flutter/test/sentry_navigator_observer_test.dart b/flutter/test/sentry_navigator_observer_test.dart index 90ec48ccae..b573d4a92e 100644 --- a/flutter/test/sentry_navigator_observer_test.dart +++ b/flutter/test/sentry_navigator_observer_test.dart @@ -368,7 +368,7 @@ void main() { }); }); - test('exposes current route name', () { + test('didPush sets current route name', () { const name = 'Current Route'; final currentRoute = route(RouteSettings(name: name)); @@ -387,6 +387,53 @@ void main() { expect(SentryNavigatorObserver.currentRouteName, 'Current Route'); }); + + test('didReplace sets new route name', () { + const oldRouteName = 'Old Route'; + final oldRoute = route(RouteSettings(name: oldRouteName)); + const newRouteName = 'New Route'; + final newRoute = route(RouteSettings(name: newRouteName)); + + const op = 'navigation'; + final hub = _MockHub(); + final span = getMockSentryTracer(name: oldRouteName); + when(span.context).thenReturn(SentrySpanContext(operation: op)); + _whenAnyStart(hub, span); + + final sut = fixture.getSut( + hub: hub, + autoFinishAfter: Duration(seconds: 5), + ); + + sut.didPush(oldRoute, null); + sut.didReplace(newRoute: newRoute, oldRoute: oldRoute); + + expect(SentryNavigatorObserver.currentRouteName, 'New Route'); + }); + + test('popRoute sets previous route name', () { + const oldRouteName = 'Old Route'; + final oldRoute = route(RouteSettings(name: oldRouteName)); + const newRouteName = 'New Route'; + final newRoute = route(RouteSettings(name: newRouteName)); + + const op = 'navigation'; + final hub = _MockHub(); + final span = getMockSentryTracer(name: oldRouteName); + when(span.context).thenReturn(SentrySpanContext(operation: op)); + when(span.status).thenReturn(null); + _whenAnyStart(hub, span); + + final sut = fixture.getSut( + hub: hub, + autoFinishAfter: Duration(seconds: 5), + ); + + sut.didPush(oldRoute, null); + sut.didPop(newRoute, oldRoute); + + expect(SentryNavigatorObserver.currentRouteName, 'Old Route'); + }); }); group('RouteObserverBreadcrumb', () { From f97795838df45bb2fc7392c6601b11eb2760b022 Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Tue, 24 Oct 2023 11:46:20 +0200 Subject: [PATCH 19/20] mark current route as internal --- flutter/lib/src/navigation/sentry_navigator_observer.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/flutter/lib/src/navigation/sentry_navigator_observer.dart b/flutter/lib/src/navigation/sentry_navigator_observer.dart index 5dff01493d..7d586d0571 100644 --- a/flutter/lib/src/navigation/sentry_navigator_observer.dart +++ b/flutter/lib/src/navigation/sentry_navigator_observer.dart @@ -1,4 +1,5 @@ import 'package:flutter/widgets.dart'; +import 'package:meta/meta.dart'; import '../../sentry_flutter.dart'; import '../event_processor/flutter_enricher_event_processor.dart'; @@ -90,7 +91,7 @@ class SentryNavigatorObserver extends RouteObserver> { static String? _currentRouteName; - /// Get the current route of the observer. + @internal static String? get currentRouteName => _currentRouteName; @override From 6aacd98f544c90a8765a364bf3ae99c4eba42243 Mon Sep 17 00:00:00 2001 From: Denis Andrasec Date: Mon, 30 Oct 2023 10:29:25 +0100 Subject: [PATCH 20/20] fix changelog --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb264643e0..7a51e639a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ ### Features - Initial (alpha) support for profiling on iOS and macOS ([#1611](https://github.com/getsentry/sentry-dart/pull/1611)) +- Add `SentryNavigatorObserver` current route to `event.app.contexts.viewNames` ([#1545](https://github.com/getsentry/sentry-dart/pull/1545)) + - Requires relay version [23.9.0](https://github.com/getsentry/relay/blob/master/CHANGELOG.md#2390) for self-hosted instances ## 7.11.0 @@ -19,9 +21,7 @@ ### Features - Breadcrumbs for file I/O operations ([#1649](https://github.com/getsentry/sentry-dart/pull/1649)) -- Add `SentryNavigatorObserver` current route to `event.app.contexts.viewNames` ([#1545](https://github.com/getsentry/sentry-dart/pull/1545)) - - Requires relay version [23.9.0](https://github.com/getsentry/relay/blob/master/CHANGELOG.md#2390) for self-hosted instances - + ### Dependencies - Enable compatibility with uuid v4 ([#1647](https://github.com/getsentry/sentry-dart/pull/1647))