@@ -334,66 +334,6 @@ void main() {
334334 verify (span.setData ('route_settings_arguments' , arguments));
335335 });
336336
337- test ('root route does not start transaction on non-web' , () async {
338- final rootRoute = route (RouteSettings (name: '/' ));
339-
340- final hub = _MockHub ();
341- hub.options.platform = MockPlatform (isWeb: false );
342- final span = getMockSentryTracer ();
343- when (span.context).thenReturn (SentrySpanContext (operation: 'op' ));
344- when (span.finished).thenReturn (false );
345- when (span.status).thenReturn (SpanStatus .ok ());
346- _whenAnyStart (hub, span);
347-
348- final sut = fixture.getSut (hub: hub);
349-
350- sut.didPush (rootRoute, null );
351- await Future <void >.delayed (const Duration (milliseconds: 100 ));
352-
353- verifyNever (hub.startTransactionWithContext (
354- any,
355- startTimestamp: anyNamed ('startTimestamp' ),
356- waitForChildren: true ,
357- autoFinishAfter: anyNamed ('autoFinishAfter' ),
358- trimEnd: true ,
359- onFinish: anyNamed ('onFinish' ),
360- ));
361-
362- await hub.configureScope ((scope) {
363- expect (scope.span, null );
364- });
365- });
366-
367- test ('root route starts transaction on web' , () async {
368- final rootRoute = route (RouteSettings (name: '/' ));
369-
370- final hub = _MockHub ();
371- hub.options.platform = MockPlatform (isWeb: true );
372- final span = getMockSentryTracer ();
373- when (span.context).thenReturn (SentrySpanContext (operation: 'op' ));
374- when (span.finished).thenReturn (false );
375- when (span.status).thenReturn (SpanStatus .ok ());
376- _whenAnyStart (hub, span);
377-
378- final sut = fixture.getSut (hub: hub);
379-
380- sut.didPush (rootRoute, null );
381- await Future <void >.delayed (const Duration (milliseconds: 100 ));
382-
383- verify (hub.startTransactionWithContext (
384- any,
385- startTimestamp: anyNamed ('startTimestamp' ),
386- waitForChildren: true ,
387- autoFinishAfter: anyNamed ('autoFinishAfter' ),
388- trimEnd: true ,
389- onFinish: anyNamed ('onFinish' ),
390- ));
391-
392- await hub.configureScope ((scope) {
393- expect (scope.span, isNotNull);
394- });
395- });
396-
397337 test ('didPush sets current route name' , () async {
398338 const name = 'Current Route' ;
399339 final currentRoute = route (RouteSettings (name: name));
@@ -484,6 +424,93 @@ void main() {
484424
485425 expect (SentryNavigatorObserver .currentRouteName, 'Old Route' );
486426 });
427+
428+ group ('root route transaction behavior by platform' , () {
429+ // Platforms that skip root transactions (have app start integration)
430+ final platformsWithAppStart = [
431+ ('iOS' , MockPlatform .iOS ()),
432+ ('Android' , MockPlatform .android ()),
433+ ('macOS' , MockPlatform .macOS (isWeb: false )),
434+ ];
435+
436+ // Platforms that don't skip root transactions (no app start integration)
437+ final platformsWithoutAppStart = [
438+ ('Web' , MockPlatform (isWeb: true )),
439+ ('Linux' , MockPlatform .linux (isWeb: false )),
440+ ('Windows' , MockPlatform .windows (isWeb: false )),
441+ ];
442+
443+ void testRootRouteTransaction ({
444+ required String platformName,
445+ required MockPlatform platform,
446+ required bool shouldStartTransaction,
447+ }) {
448+ test (
449+ 'root route ${shouldStartTransaction ? 'starts' : 'does not start' } transaction on $platformName ' ,
450+ () async {
451+ final rootRoute = route (RouteSettings (name: '/' ));
452+
453+ final hub = _MockHub ();
454+ hub.options.platform = platform;
455+ final span = getMockSentryTracer ();
456+ when (span.context).thenReturn (SentrySpanContext (operation: 'op' ));
457+ when (span.finished).thenReturn (false );
458+ when (span.status).thenReturn (SpanStatus .ok ());
459+ _whenAnyStart (hub, span);
460+
461+ final sut = fixture.getSut (hub: hub);
462+
463+ sut.didPush (rootRoute, null );
464+ await Future <void >.delayed (const Duration (milliseconds: 100 ));
465+
466+ if (shouldStartTransaction) {
467+ verify (hub.startTransactionWithContext (
468+ any,
469+ startTimestamp: anyNamed ('startTimestamp' ),
470+ waitForChildren: true ,
471+ autoFinishAfter: anyNamed ('autoFinishAfter' ),
472+ trimEnd: true ,
473+ onFinish: anyNamed ('onFinish' ),
474+ ));
475+
476+ await hub.configureScope ((scope) {
477+ expect (scope.span, isNotNull);
478+ });
479+ } else {
480+ verifyNever (hub.startTransactionWithContext (
481+ any,
482+ startTimestamp: anyNamed ('startTimestamp' ),
483+ waitForChildren: true ,
484+ autoFinishAfter: anyNamed ('autoFinishAfter' ),
485+ trimEnd: true ,
486+ onFinish: anyNamed ('onFinish' ),
487+ ));
488+
489+ await hub.configureScope ((scope) {
490+ expect (scope.span, null );
491+ });
492+ }
493+ });
494+ }
495+
496+ // Test platforms that skip root transactions
497+ for (final (platformName, platform) in platformsWithAppStart) {
498+ testRootRouteTransaction (
499+ platformName: platformName,
500+ platform: platform,
501+ shouldStartTransaction: false ,
502+ );
503+ }
504+
505+ // Test platforms that don't skip root transactions
506+ for (final (platformName, platform) in platformsWithoutAppStart) {
507+ testRootRouteTransaction (
508+ platformName: platformName,
509+ platform: platform,
510+ shouldStartTransaction: true ,
511+ );
512+ }
513+ });
487514 });
488515
489516 group ('RouteObserverBreadcrumb' , () {
0 commit comments