From b8fe075c1e964eb28043fbe42eb5b9c095e678f8 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Wed, 16 Jul 2025 22:00:26 -0700 Subject: [PATCH 1/3] Rework the integration test timeout logic --- .../test/live_connection/app_test.dart | 24 +- .../live_connection/debugger_panel_test.dart | 4 +- .../devtools_extensions_test.dart | 242 +++++++++--------- .../live_connection/eval_and_browse_test.dart | 38 +-- .../eval_and_inspect_test.dart | 23 +- .../live_connection/export_snapshot_test.dart | 4 +- ...rformance_screen_event_recording_test.dart | 190 +++++++------- .../service_connection_test.dart | 146 ++++++----- .../service_extensions_test.dart | 104 ++++---- .../offline/memory_offline_data_test.dart | 38 +-- .../test/offline/perfetto_test.dart | 1 + .../lib/src/test/integration_test_runner.dart | 10 +- 12 files changed, 432 insertions(+), 392 deletions(-) diff --git a/packages/devtools_app/integration_test/test/live_connection/app_test.dart b/packages/devtools_app/integration_test/test/live_connection/app_test.dart index 66035955bd5..2f1e4ae97fe 100644 --- a/packages/devtools_app/integration_test/test/live_connection/app_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/app_test.dart @@ -25,14 +25,18 @@ void main() { await resetHistory(); }); - testWidgets('connect to app and switch tabs', (tester) async { - await pumpAndConnectDevTools(tester, testApp); - - // For the sake of this test, do not show extension screens by default. - preferences.devToolsExtensions.showOnlyEnabledExtensions.value = true; - await tester.pumpAndSettle(shortPumpDuration); - - logStatus('verify that we can load each DevTools screen'); - await navigateThroughDevToolsScreens(tester, connectedToApp: true); - }); + testWidgets( + 'connect to app and switch tabs', + timeout: const Timeout(Duration(minutes: 2)), + (tester) async { + await pumpAndConnectDevTools(tester, testApp); + + // For the sake of this test, do not show extension screens by default. + preferences.devToolsExtensions.showOnlyEnabledExtensions.value = true; + await tester.pumpAndSettle(shortPumpDuration); + + logStatus('verify that we can load each DevTools screen'); + await navigateThroughDevToolsScreens(tester, connectedToApp: true); + }, + ); } diff --git a/packages/devtools_app/integration_test/test/live_connection/debugger_panel_test.dart b/packages/devtools_app/integration_test/test/live_connection/debugger_panel_test.dart index feb7865cbb8..497435d9dcc 100644 --- a/packages/devtools_app/integration_test/test/live_connection/debugger_panel_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/debugger_panel_test.dart @@ -29,7 +29,9 @@ void main() { expect(testApp.vmServiceUri, isNotNull); }); - testWidgets('Debugger panel', (tester) async { + testWidgets('Debugger panel', timeout: const Timeout(Duration(minutes: 4)), ( + tester, + ) async { await pumpAndConnectDevTools(tester, testApp); await switchToScreen( tester, diff --git a/packages/devtools_app/integration_test/test/live_connection/devtools_extensions_test.dart b/packages/devtools_app/integration_test/test/live_connection/devtools_extensions_test.dart index 5dfb1456dfd..3787457a530 100644 --- a/packages/devtools_app/integration_test/test/live_connection/devtools_extensions_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/devtools_extensions_test.dart @@ -41,125 +41,129 @@ void main() { resetDevToolsExtensionEnabledStates(); }); - testWidgets('end to end extensions flow', (tester) async { - await pumpDevTools(tester); - - // TODO(https://github.com/flutter/devtools/issues/9196): re-enable this - // test verification once DTD can be started from the integration test - // harness. - // logStatus( - // 'verify static extensions are available before connecting to an app', - // ); - // expect(extensionService.availableExtensions.length, 2); - // expect(extensionService.visibleExtensions.length, 2); - // await _verifyExtensionsSettingsMenu(tester, [ - // ExtensionEnabledState.none, // dart_foo - // ExtensionEnabledState.none, // standalone_extension - // ]); - - await connectToTestApp(tester, testApp); - - expect(extensionService.availableExtensions.length, 3); - expect(extensionService.visibleExtensions.length, 3); - await _verifyExtensionsSettingsMenu(tester, [ - ExtensionEnabledState.none, // dart_foo - ExtensionEnabledState.none, // foo - ExtensionEnabledState.none, // standalone_extension - ], closeMenuWhenDone: false); - - await _verifyExtensionVisibilitySetting(tester); - - // dart_foo extension. - // Enable, test context menu actions, then disable from context menu. - await _switchToExtensionScreen( - tester, - extensionIndex: 0, - initialLoad: true, - ); - await _answerEnableExtensionPrompt(tester, enable: true); - await _verifyExtensionsSettingsMenu(tester, [ - ExtensionEnabledState.enabled, // dart_foo - ExtensionEnabledState.none, // foo - ExtensionEnabledState.none, // standalone_extension - ]); - - await _verifyContextMenuActionsAndDisable(tester); - - expect(extensionService.availableExtensions.length, 3); - expect(extensionService.visibleExtensions.length, 2); - await _verifyExtensionTabVisibility( - tester, - extensionIndex: 0, - visible: false, - ); - await _verifyExtensionsSettingsMenu(tester, [ - ExtensionEnabledState.disabled, // dart_foo - ExtensionEnabledState.none, // foo - ExtensionEnabledState.none, // standalone_extension - ]); - - // foo extension. Hide immediately. - await _switchToExtensionScreen( - tester, - extensionIndex: 1, - initialLoad: true, - ); - await _answerEnableExtensionPrompt(tester, enable: false); - - expect(extensionService.availableExtensions.length, 3); - expect(extensionService.visibleExtensions.length, 1); - await _verifyExtensionTabVisibility( - tester, - extensionIndex: 1, - visible: false, - ); - await _verifyExtensionsSettingsMenu(tester, [ - ExtensionEnabledState.disabled, // dart_foo - ExtensionEnabledState.disabled, // foo - ExtensionEnabledState.none, // standalone_extension - ]); - - // Re-enable foo extension from the extensions settings menu. - logStatus('verify we can re-enable an extension from the settings menu'); - await _changeExtensionSetting(tester, extensionIndex: 1, enable: true); - - expect(extensionService.availableExtensions.length, 3); - expect(extensionService.visibleExtensions.length, 2); - await _switchToExtensionScreen(tester, extensionIndex: 1); - expect(find.byType(EnableExtensionPrompt), findsNothing); - expect(find.byType(EmbeddedExtensionView), findsOneWidget); - expect(find.byType(HtmlElementView), findsOneWidget); - await _verifyExtensionsSettingsMenu(tester, [ - ExtensionEnabledState.disabled, // dart_foo - ExtensionEnabledState.enabled, // foo - ExtensionEnabledState.none, // standalone_extension - ]); - - // standalone_extension. Disable directly from settings menu. - logStatus( - 'verify we can disable an extension screen directly from the settings menu', - ); - await _verifyExtensionTabVisibility( - tester, - extensionIndex: 2, - visible: true, - ); - - logStatus('disable the extension from the settings menu'); - await _changeExtensionSetting(tester, extensionIndex: 2, enable: false); - expect(extensionService.availableExtensions.length, 3); - expect(extensionService.visibleExtensions.length, 1); - await _verifyExtensionTabVisibility( - tester, - extensionIndex: 2, - visible: false, - ); - await _verifyExtensionsSettingsMenu(tester, [ - ExtensionEnabledState.disabled, // dart_foo - ExtensionEnabledState.enabled, // foo - ExtensionEnabledState.disabled, // standalone_extension - ]); - }); + testWidgets( + 'end to end extensions flow', + timeout: const Timeout(Duration(minutes: 3)), + (tester) async { + await pumpDevTools(tester); + + // TODO(https://github.com/flutter/devtools/issues/9196): re-enable this + // test verification once DTD can be started from the integration test + // harness. + // logStatus( + // 'verify static extensions are available before connecting to an app', + // ); + // expect(extensionService.availableExtensions.length, 2); + // expect(extensionService.visibleExtensions.length, 2); + // await _verifyExtensionsSettingsMenu(tester, [ + // ExtensionEnabledState.none, // dart_foo + // ExtensionEnabledState.none, // standalone_extension + // ]); + + await connectToTestApp(tester, testApp); + + expect(extensionService.availableExtensions.length, 3); + expect(extensionService.visibleExtensions.length, 3); + await _verifyExtensionsSettingsMenu(tester, [ + ExtensionEnabledState.none, // dart_foo + ExtensionEnabledState.none, // foo + ExtensionEnabledState.none, // standalone_extension + ], closeMenuWhenDone: false); + + await _verifyExtensionVisibilitySetting(tester); + + // dart_foo extension. + // Enable, test context menu actions, then disable from context menu. + await _switchToExtensionScreen( + tester, + extensionIndex: 0, + initialLoad: true, + ); + await _answerEnableExtensionPrompt(tester, enable: true); + await _verifyExtensionsSettingsMenu(tester, [ + ExtensionEnabledState.enabled, // dart_foo + ExtensionEnabledState.none, // foo + ExtensionEnabledState.none, // standalone_extension + ]); + + await _verifyContextMenuActionsAndDisable(tester); + + expect(extensionService.availableExtensions.length, 3); + expect(extensionService.visibleExtensions.length, 2); + await _verifyExtensionTabVisibility( + tester, + extensionIndex: 0, + visible: false, + ); + await _verifyExtensionsSettingsMenu(tester, [ + ExtensionEnabledState.disabled, // dart_foo + ExtensionEnabledState.none, // foo + ExtensionEnabledState.none, // standalone_extension + ]); + + // foo extension. Hide immediately. + await _switchToExtensionScreen( + tester, + extensionIndex: 1, + initialLoad: true, + ); + await _answerEnableExtensionPrompt(tester, enable: false); + + expect(extensionService.availableExtensions.length, 3); + expect(extensionService.visibleExtensions.length, 1); + await _verifyExtensionTabVisibility( + tester, + extensionIndex: 1, + visible: false, + ); + await _verifyExtensionsSettingsMenu(tester, [ + ExtensionEnabledState.disabled, // dart_foo + ExtensionEnabledState.disabled, // foo + ExtensionEnabledState.none, // standalone_extension + ]); + + // Re-enable foo extension from the extensions settings menu. + logStatus('verify we can re-enable an extension from the settings menu'); + await _changeExtensionSetting(tester, extensionIndex: 1, enable: true); + + expect(extensionService.availableExtensions.length, 3); + expect(extensionService.visibleExtensions.length, 2); + await _switchToExtensionScreen(tester, extensionIndex: 1); + expect(find.byType(EnableExtensionPrompt), findsNothing); + expect(find.byType(EmbeddedExtensionView), findsOneWidget); + expect(find.byType(HtmlElementView), findsOneWidget); + await _verifyExtensionsSettingsMenu(tester, [ + ExtensionEnabledState.disabled, // dart_foo + ExtensionEnabledState.enabled, // foo + ExtensionEnabledState.none, // standalone_extension + ]); + + // standalone_extension. Disable directly from settings menu. + logStatus( + 'verify we can disable an extension screen directly from the settings menu', + ); + await _verifyExtensionTabVisibility( + tester, + extensionIndex: 2, + visible: true, + ); + + logStatus('disable the extension from the settings menu'); + await _changeExtensionSetting(tester, extensionIndex: 2, enable: false); + expect(extensionService.availableExtensions.length, 3); + expect(extensionService.visibleExtensions.length, 1); + await _verifyExtensionTabVisibility( + tester, + extensionIndex: 2, + visible: false, + ); + await _verifyExtensionsSettingsMenu(tester, [ + ExtensionEnabledState.disabled, // dart_foo + ExtensionEnabledState.enabled, // foo + ExtensionEnabledState.disabled, // standalone_extension + ]); + }, + ); } Future _switchToExtensionScreen( diff --git a/packages/devtools_app/integration_test/test/live_connection/eval_and_browse_test.dart b/packages/devtools_app/integration_test/test/live_connection/eval_and_browse_test.dart index f37ba180d01..c323dec8a9f 100644 --- a/packages/devtools_app/integration_test/test/live_connection/eval_and_browse_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/eval_and_browse_test.dart @@ -30,30 +30,34 @@ void main() { await resetHistory(); }); - testWidgets('memory eval and browse', (tester) async { - await pumpAndConnectDevTools(tester, testApp); + testWidgets( + 'memory eval and browse', + timeout: const Timeout(Duration(minutes: 3)), + (tester) async { + await pumpAndConnectDevTools(tester, testApp); - final evalTester = EvalTester(tester); - await prepareMemoryUI(tester, makeConsoleWider: true); + final evalTester = EvalTester(tester); + await prepareMemoryUI(tester, makeConsoleWider: true); - logStatus('test basic evaluation'); - await testBasicEval(evalTester); + logStatus('test basic evaluation'); + await testBasicEval(evalTester); - logStatus('test variable assignment'); - await testAssignment(evalTester); + logStatus('test variable assignment'); + await testAssignment(evalTester); - logStatus('test dump one instance to console'); - await _profileOneInstance(evalTester); + logStatus('test dump one instance to console'); + await _profileOneInstance(evalTester); - logStatus('test dump all instances to console'); - await _profileAllInstances(evalTester); + logStatus('test dump all instances to console'); + await _profileAllInstances(evalTester); - logStatus('test take a snapshot'); - await evalTester.takeSnapshot(); + logStatus('test take a snapshot'); + await evalTester.takeSnapshot(); - logStatus('test inbound references are listed on console instance'); - await _inboundReferencesAreListed(evalTester); - }); + logStatus('test inbound references are listed on console instance'); + await _inboundReferencesAreListed(evalTester); + }, + ); } Future _profileOneInstance(EvalTester tester) async { diff --git a/packages/devtools_app/integration_test/test/live_connection/eval_and_inspect_test.dart b/packages/devtools_app/integration_test/test/live_connection/eval_and_inspect_test.dart index 43baef74519..3c7279888d8 100644 --- a/packages/devtools_app/integration_test/test/live_connection/eval_and_inspect_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/eval_and_inspect_test.dart @@ -32,21 +32,26 @@ void main() { await resetHistory(); }); - testWidgets('eval with scope in inspector window', (tester) async { - await pumpAndConnectDevTools(tester, testApp); + testWidgets( + 'eval with scope in inspector window', + timeout: const Timeout(Duration(minutes: 3)), + (tester) async { + await pumpAndConnectDevTools(tester, testApp); - final evalTester = EvalTester(tester); - await evalTester.prepareInspectorUI(); + final evalTester = EvalTester(tester); + await evalTester.prepareInspectorUI(); - logStatus('testing basic evaluation'); - await testBasicEval(evalTester); + logStatus('testing basic evaluation'); + await testBasicEval(evalTester); - logStatus('testing variable assignment'); - await testAssignment(evalTester); - }); + logStatus('testing variable assignment'); + await testAssignment(evalTester); + }, + ); testWidgets( 'eval with scope on widget tree node', + timeout: const Timeout(Duration(minutes: 3)), (tester) async { await pumpAndConnectDevTools(tester, testApp); diff --git a/packages/devtools_app/integration_test/test/live_connection/export_snapshot_test.dart b/packages/devtools_app/integration_test/test/live_connection/export_snapshot_test.dart index e5d57792c5c..ac26935c09e 100644 --- a/packages/devtools_app/integration_test/test/live_connection/export_snapshot_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/export_snapshot_test.dart @@ -25,7 +25,9 @@ void main() { await resetHistory(); }); - testWidgets('Export snapshot', (tester) async { + testWidgets('Export snapshot', timeout: const Timeout(Duration(minutes: 2)), ( + tester, + ) async { await pumpAndConnectDevTools(tester, testApp); await prepareMemoryUI(tester); await takeHeapSnapshot(tester); diff --git a/packages/devtools_app/integration_test/test/live_connection/performance_screen_event_recording_test.dart b/packages/devtools_app/integration_test/test/live_connection/performance_screen_event_recording_test.dart index 2a00a8d91bd..14707baf33a 100644 --- a/packages/devtools_app/integration_test/test/live_connection/performance_screen_event_recording_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/performance_screen_event_recording_test.dart @@ -24,96 +24,102 @@ void main() { expect(testApp.vmServiceUri, isNotNull); }); - testWidgets('can process and refresh timeline data', (tester) async { - await pumpAndConnectDevTools(tester, testApp); - - logStatus( - 'Open the Performance screen and switch to the Timeline Events tab', - ); - - await switchToScreen( - tester, - tabIcon: ScreenMetaData.performance.icon, - tabIconAsset: ScreenMetaData.performance.iconAsset, - screenId: ScreenMetaData.performance.id, - ); - await tester.pump(safePumpDuration); - - await tester.tap(find.widgetWithText(InkWell, 'Timeline Events')); - await tester.pumpAndSettle(longPumpDuration); - - // Find the [PerformanceController] to access its data. - final performanceScreenFinder = find.byType(PerformanceScreenBody); - expect(performanceScreenFinder, findsOneWidget); - final screenState = tester.state( - performanceScreenFinder, - ); - final performanceController = screenState.controller; - - logStatus('Verifying that data is processed upon first load'); - final initialTrace = Trace.fromBuffer( - performanceController.timelineEventsController.fullPerfettoTrace, - ); - final initialTracePacket = List.of(initialTrace.packet, growable: false); - final initialTrackDescriptors = initialTracePacket.where( - (e) => e.hasTrackDescriptor(), - ); - expect(initialTracePacket, isNotEmpty); - expect(initialTrackDescriptors, isNotEmpty); - - final trackEvents = initialTracePacket.where((e) => e.hasTrackEvent()); - expect(trackEvents, isNotEmpty); - - expect( - performanceController - .timelineEventsController - .perfettoController - .processor - .uiTrackId, - isNotNull, - reason: 'Expected uiTrackId to be non-null', - ); - expect( - performanceController - .timelineEventsController - .perfettoController - .processor - .rasterTrackId, - isNotNull, - reason: 'Expected rasterTrackId to be non-null', - ); - expect( - performanceController - .timelineEventsController - .perfettoController - .processor - .frameRangeFromTimelineEvents, - isNotNull, - reason: 'Expected frameRangeFromTimelineEvents to be non-null', - ); - - logStatus('toggling the Performance Overlay to trigger new Flutter frames'); - final performanceOverlayFinder = find.text('Performance Overlay'); - expect(performanceOverlayFinder, findsOneWidget); - await tester.tap(performanceOverlayFinder); - await tester.pump(longPumpDuration); - - logStatus('Refreshing the timeline to load new events'); - await tester.tap(find.byType(RefreshTimelineEventsButton)); - await tester.pump(longPumpDuration); - - logStatus('Verifying that we have recorded new events'); - final refreshedTrace = Trace.fromBuffer( - performanceController.timelineEventsController.fullPerfettoTrace, - ); - final refreshedTracePacket = List.of( - refreshedTrace.packet, - growable: false, - ); - expect( - refreshedTracePacket.length, - greaterThan(initialTracePacket.length), - reason: 'Expected new events to have been recorded, but none were.', - ); - }); + testWidgets( + 'can process and refresh timeline data', + timeout: const Timeout(Duration(minutes: 4)), + (tester) async { + await pumpAndConnectDevTools(tester, testApp); + + logStatus( + 'Open the Performance screen and switch to the Timeline Events tab', + ); + + await switchToScreen( + tester, + tabIcon: ScreenMetaData.performance.icon, + tabIconAsset: ScreenMetaData.performance.iconAsset, + screenId: ScreenMetaData.performance.id, + ); + await tester.pump(safePumpDuration); + + await tester.tap(find.widgetWithText(InkWell, 'Timeline Events')); + await tester.pumpAndSettle(longPumpDuration); + + // Find the [PerformanceController] to access its data. + final performanceScreenFinder = find.byType(PerformanceScreenBody); + expect(performanceScreenFinder, findsOneWidget); + final screenState = tester.state( + performanceScreenFinder, + ); + final performanceController = screenState.controller; + + logStatus('Verifying that data is processed upon first load'); + final initialTrace = Trace.fromBuffer( + performanceController.timelineEventsController.fullPerfettoTrace, + ); + final initialTracePacket = List.of(initialTrace.packet, growable: false); + final initialTrackDescriptors = initialTracePacket.where( + (e) => e.hasTrackDescriptor(), + ); + expect(initialTracePacket, isNotEmpty); + expect(initialTrackDescriptors, isNotEmpty); + + final trackEvents = initialTracePacket.where((e) => e.hasTrackEvent()); + expect(trackEvents, isNotEmpty); + + expect( + performanceController + .timelineEventsController + .perfettoController + .processor + .uiTrackId, + isNotNull, + reason: 'Expected uiTrackId to be non-null', + ); + expect( + performanceController + .timelineEventsController + .perfettoController + .processor + .rasterTrackId, + isNotNull, + reason: 'Expected rasterTrackId to be non-null', + ); + expect( + performanceController + .timelineEventsController + .perfettoController + .processor + .frameRangeFromTimelineEvents, + isNotNull, + reason: 'Expected frameRangeFromTimelineEvents to be non-null', + ); + + logStatus( + 'toggling the Performance Overlay to trigger new Flutter frames', + ); + final performanceOverlayFinder = find.text('Performance Overlay'); + expect(performanceOverlayFinder, findsOneWidget); + await tester.tap(performanceOverlayFinder); + await tester.pump(longPumpDuration); + + logStatus('Refreshing the timeline to load new events'); + await tester.tap(find.byType(RefreshTimelineEventsButton)); + await tester.pump(longPumpDuration); + + logStatus('Verifying that we have recorded new events'); + final refreshedTrace = Trace.fromBuffer( + performanceController.timelineEventsController.fullPerfettoTrace, + ); + final refreshedTracePacket = List.of( + refreshedTrace.packet, + growable: false, + ); + expect( + refreshedTracePacket.length, + greaterThan(initialTracePacket.length), + reason: 'Expected new events to have been recorded, but none were.', + ); + }, + ); } diff --git a/packages/devtools_app/integration_test/test/live_connection/service_connection_test.dart b/packages/devtools_app/integration_test/test/live_connection/service_connection_test.dart index c672a1139d5..66e9f51a148 100644 --- a/packages/devtools_app/integration_test/test/live_connection/service_connection_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/service_connection_test.dart @@ -27,82 +27,88 @@ void main() { await resetHistory(); }); - testWidgets('initial service connection state', (tester) async { - await pumpAndConnectDevTools(tester, testApp); + testWidgets( + 'initial service connection state', + timeout: const Timeout(Duration(minutes: 3)), + (tester) async { + await pumpAndConnectDevTools(tester, testApp); - // Await a delay to ensure the service extensions have had a chance to - // be called. This delay may be able to be shortened if doing so does - // not cause bot flakiness. - await tester.pump(longDuration); + // Await a delay to ensure the service extensions have had a chance to + // be called. This delay may be able to be shortened if doing so does + // not cause bot flakiness. + await tester.pump(longDuration); - // Ensure all futures are completed before running checks. - await serviceConnection.serviceManager.service!.allFuturesCompleted; + // Ensure all futures are completed before running checks. + await serviceConnection.serviceManager.service!.allFuturesCompleted; - logStatus('verify the vm service calls that occur on connect'); - final vmServiceCallCount = - serviceConnection.serviceManager.service!.vmServiceCallCount; - expect( - // Use a range instead of an exact number because service extension - // calls are not consistent. This will still catch any spurious calls - // that are unintentionally added at start up. - const Range(35, 70).contains(vmServiceCallCount), - isTrue, - reason: - 'Unexpected number of vm service calls upon connection: ' - '$vmServiceCallCount. If this is expected, please update this test ' - 'to the new expected number of calls. Here are the calls for this ' - 'test run:\n ${serviceConnection.serviceManager.service!.vmServiceCalls.toString()}', - ); - - // Check the ordering of the vm service calls we can expect to occur - // in a stable order. - expect( - serviceConnection.serviceManager.service!.vmServiceCalls - // Filter out unawaited streamListen calls. - .where((call) => call != 'streamListen') - .toList() - .sublist(0, 8), - equals([ - 'getSupportedProtocols', - 'getVersion', - 'setFlag', - 'requirePermissionToResume', - 'getFlagList', - 'getDartDevelopmentServiceVersion', - 'getDartDevelopmentServiceVersion', - 'getVM', - ]), - reason: - 'Unexpected order of vm service calls upon connection. ' - 'Here are the calls for this test run:\n ' - '${serviceConnection.serviceManager.service!.vmServiceCalls.toString()}', - ); + logStatus('verify the vm service calls that occur on connect'); + final vmServiceCallCount = + serviceConnection.serviceManager.service!.vmServiceCallCount; + expect( + // Use a range instead of an exact number because service extension + // calls are not consistent. This will still catch any spurious calls + // that are unintentionally added at start up. + const Range(35, 70).contains(vmServiceCallCount), + isTrue, + reason: + 'Unexpected number of vm service calls upon connection: ' + '$vmServiceCallCount. If this is expected, please update this test ' + 'to the new expected number of calls. Here are the calls for this ' + 'test run:\n ${serviceConnection.serviceManager.service!.vmServiceCalls.toString()}', + ); - expect( - serviceConnection.serviceManager.service!.vmServiceCalls - .where((call) => call == 'streamListen') - .toList() - .length, - equals(10), - ); + // Check the ordering of the vm service calls we can expect to occur + // in a stable order. + expect( + serviceConnection.serviceManager.service!.vmServiceCalls + // Filter out unawaited streamListen calls. + .where((call) => call != 'streamListen') + .toList() + .sublist(0, 8), + equals([ + 'getSupportedProtocols', + 'getVersion', + 'setFlag', + 'requirePermissionToResume', + 'getFlagList', + 'getDartDevelopmentServiceVersion', + 'getDartDevelopmentServiceVersion', + 'getVM', + ]), + reason: + 'Unexpected order of vm service calls upon connection. ' + 'Here are the calls for this test run:\n ' + '${serviceConnection.serviceManager.service!.vmServiceCalls.toString()}', + ); - logStatus('verify managers have all been initialized'); - expect(serviceConnection.serviceManager.isolateManager, isNotNull); - expect(serviceConnection.serviceManager.serviceExtensionManager, isNotNull); - expect(serviceConnection.vmFlagManager, isNotNull); - expect( - serviceConnection.serviceManager.isolateManager.isolates.value, - isNotEmpty, - ); - expect(serviceConnection.vmFlagManager.flags.value, isNotNull); + expect( + serviceConnection.serviceManager.service!.vmServiceCalls + .where((call) => call == 'streamListen') + .toList() + .length, + equals(10), + ); - if (serviceConnection.serviceManager.isolateManager.selectedIsolate.value == - null) { - await whenValueNonNull( - serviceConnection.serviceManager.isolateManager.selectedIsolate, + logStatus('verify managers have all been initialized'); + expect( + serviceConnection.serviceManager.serviceExtensionManager, + isNotNull, ); - } + expect( + serviceConnection.serviceManager.isolateManager.isolates.value, + isNotEmpty, + ); + expect(serviceConnection.vmFlagManager.flags.value, isNotNull); - await disconnectFromTestApp(tester); - }); + final selectedIsolate = + serviceConnection.serviceManager.isolateManager.selectedIsolate; + if (selectedIsolate.value == null) { + await whenValueNonNull( + serviceConnection.serviceManager.isolateManager.selectedIsolate, + ); + } + + await disconnectFromTestApp(tester); + }, + ); } diff --git a/packages/devtools_app/integration_test/test/live_connection/service_extensions_test.dart b/packages/devtools_app/integration_test/test/live_connection/service_extensions_test.dart index 8b011a088de..962060d1ed9 100644 --- a/packages/devtools_app/integration_test/test/live_connection/service_extensions_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/service_extensions_test.dart @@ -37,7 +37,7 @@ void main() { testWidgets( 'can call services and service extensions', - + timeout: const Timeout(Duration(minutes: 3)), (tester) async { await pumpAndConnectDevTools(tester, testApp); await tester.pump(longDuration); @@ -75,58 +75,62 @@ void main() { skip: true, // https://github.com/flutter/devtools/issues/8107 ); - testWidgets('loads initial extension states from device', (tester) async { - await pumpAndConnectDevTools(tester, testApp); - await tester.pump(longDuration); - - // Ensure all futures are completed before running checks. - final service = serviceConnection.serviceManager.service!; - await service.allFuturesCompleted; - - final serviceExtensionsToEnable = [ - (extensions.debugPaint.extension, true), - (extensions.slowAnimations.extension, 5.0), - (extensions.togglePlatformMode.extension, 'iOS'), - ]; - - logStatus('enabling service extensions on the test device'); - // Enable a service extension of each type (boolean, numeric, string). - for (final ext in serviceExtensionsToEnable) { - await serviceConnection.serviceManager.serviceExtensionManager - .setServiceExtensionState(ext.$1, enabled: true, value: ext.$2); - } - - logStatus('disconnecting from the test device'); - await disconnectFromTestApp(tester); - - for (final ext in serviceExtensionsToEnable) { - expect( - serviceConnection.serviceManager.serviceExtensionManager - .isServiceExtensionAvailable(ext.$1), - isFalse, - ); - } + testWidgets( + 'loads initial extension states from device', + timeout: const Timeout(Duration(minutes: 3)), + (tester) async { + await pumpAndConnectDevTools(tester, testApp); + await tester.pump(longDuration); - logStatus('reconnecting to the test device'); - await connectToTestApp(tester, testApp); + // Ensure all futures are completed before running checks. + final service = serviceConnection.serviceManager.service!; + await service.allFuturesCompleted; + + final serviceExtensionsToEnable = [ + (extensions.debugPaint.extension, true), + (extensions.slowAnimations.extension, 5.0), + (extensions.togglePlatformMode.extension, 'iOS'), + ]; + + logStatus('enabling service extensions on the test device'); + // Enable a service extension of each type (boolean, numeric, string). + for (final ext in serviceExtensionsToEnable) { + await serviceConnection.serviceManager.serviceExtensionManager + .setServiceExtensionState(ext.$1, enabled: true, value: ext.$2); + } + + logStatus('disconnecting from the test device'); + await disconnectFromTestApp(tester); - logStatus('verify extension states have been restored from the device'); - for (final ext in serviceExtensionsToEnable) { - expect( - serviceConnection.serviceManager.serviceExtensionManager - .isServiceExtensionAvailable(ext.$1), - isTrue, - reason: 'Expect ${ext.$1} to be available', - ); - await _verifyExtensionStateInServiceManager( - ext.$1, - enabled: true, - value: ext.$2, - ); - } + for (final ext in serviceExtensionsToEnable) { + expect( + serviceConnection.serviceManager.serviceExtensionManager + .isServiceExtensionAvailable(ext.$1), + isFalse, + ); + } + + logStatus('reconnecting to the test device'); + await connectToTestApp(tester, testApp); + + logStatus('verify extension states have been restored from the device'); + for (final ext in serviceExtensionsToEnable) { + expect( + serviceConnection.serviceManager.serviceExtensionManager + .isServiceExtensionAvailable(ext.$1), + isTrue, + reason: 'Expect ${ext.$1} to be available', + ); + await _verifyExtensionStateInServiceManager( + ext.$1, + enabled: true, + value: ext.$2, + ); + } - await disconnectFromTestApp(tester); - }); + await disconnectFromTestApp(tester); + }, + ); } Future _verifyBooleanExtension(WidgetTester tester) async { diff --git a/packages/devtools_app/integration_test/test/offline/memory_offline_data_test.dart b/packages/devtools_app/integration_test/test/offline/memory_offline_data_test.dart index 15461c2f235..08db030e205 100644 --- a/packages/devtools_app/integration_test/test/offline/memory_offline_data_test.dart +++ b/packages/devtools_app/integration_test/test/offline/memory_offline_data_test.dart @@ -14,24 +14,28 @@ import 'package:integration_test/integration_test.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - testWidgets('Memory screen can load offline data', (tester) async { - await pumpDevTools(tester); - logStatus('1 - pumped devtools'); - await loadSampleData(tester, memoryFileName); - logStatus('2 - loaded sample data'); - await tester.pumpAndSettle(longPumpDuration); - logStatus('3 - pumped and settled'); + testWidgets( + 'Memory screen can load offline data', + timeout: const Timeout(Duration(minutes: 3)), + (tester) async { + await pumpDevTools(tester); + logStatus('1 - pumped devtools'); + await loadSampleData(tester, memoryFileName); + logStatus('2 - loaded sample data'); + await tester.pumpAndSettle(longPumpDuration); + logStatus('3 - pumped and settled'); - const diffTab = 'Diff Snapshots'; - const profileTab = 'Profile Memory'; - const traceTab = 'Trace Instances'; + const diffTab = 'Diff Snapshots'; + const profileTab = 'Profile Memory'; + const traceTab = 'Trace Instances'; - expect(find.text('_MyClass'), findsOneWidget); - logStatus('5 - found _MyClass'); + expect(find.text('_MyClass'), findsOneWidget); + logStatus('5 - found _MyClass'); - for (final tab in [diffTab, profileTab, traceTab]) { - expect(find.text(tab), findsOneWidget); - logStatus('6.$tab - found'); - } - }); + for (final tab in [diffTab, profileTab, traceTab]) { + expect(find.text(tab), findsOneWidget); + logStatus('6.$tab - found'); + } + }, + ); } diff --git a/packages/devtools_app/integration_test/test/offline/perfetto_test.dart b/packages/devtools_app/integration_test/test/offline/perfetto_test.dart index 1cefd067f4b..5a7aa68ea72 100644 --- a/packages/devtools_app/integration_test/test/offline/perfetto_test.dart +++ b/packages/devtools_app/integration_test/test/offline/perfetto_test.dart @@ -19,6 +19,7 @@ void main() { testWidgets( 'Perfetto trace viewer loads data and scrolls for Flutter frames', + timeout: const Timeout(Duration(minutes: 3)), (tester) async { await pumpDevTools(tester); await loadSampleData(tester, performanceFileName); diff --git a/packages/devtools_shared/lib/src/test/integration_test_runner.dart b/packages/devtools_shared/lib/src/test/integration_test_runner.dart index 3f6faae5f38..6029142959d 100644 --- a/packages/devtools_shared/lib/src/test/integration_test_runner.dart +++ b/packages/devtools_shared/lib/src/test/integration_test_runner.dart @@ -115,15 +115,13 @@ class IntegrationTestRunner with IOMixin { ); bool testTimedOut = false; - final timeout = Future.delayed(const Duration(minutes: 8)).then((_) { + await process.exitCode.timeout(const Duration(minutes: 8), onTimeout: () { testTimedOut = true; + // TODO(srawlins): Refactor the retry situation to catch a + // TimeoutException, and not recursively call `runTest`. + return -1; }); - await Future.any([ - process.exitCode, - timeout, - ]); - debugLog( 'shutting down processes because ' '${testTimedOut ? 'test timed out' : 'test finished'}', From 81553fb5c97bc8e3e2173d4c25af93949c0dd268 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Mon, 21 Jul 2025 07:12:30 -0700 Subject: [PATCH 2/3] feedback --- .../test/live_connection/app_test.dart | 24 +- .../live_connection/debugger_panel_test.dart | 6 +- .../devtools_extensions_test.dart | 246 +++++++++--------- .../live_connection/eval_and_browse_test.dart | 39 ++- .../eval_and_inspect_test.dart | 27 +- .../live_connection/export_snapshot_test.dart | 5 +- ...rformance_screen_event_recording_test.dart | 194 +++++++------- .../service_connection_test.dart | 157 ++++++----- .../service_extensions_test.dart | 4 +- .../offline/memory_offline_data_test.dart | 48 ++-- .../test/offline/perfetto_test.dart | 4 +- .../test_infra/run/_utils.dart | 23 ++ 12 files changed, 397 insertions(+), 380 deletions(-) diff --git a/packages/devtools_app/integration_test/test/live_connection/app_test.dart b/packages/devtools_app/integration_test/test/live_connection/app_test.dart index 2f1e4ae97fe..20108def5cf 100644 --- a/packages/devtools_app/integration_test/test/live_connection/app_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/app_test.dart @@ -8,6 +8,8 @@ import 'package:devtools_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; +import '../../test_infra/run/_utils.dart'; + // To run: // dart run integration_test/run_tests.dart --target=integration_test/test/live_connection/app_test.dart @@ -25,18 +27,16 @@ void main() { await resetHistory(); }); - testWidgets( - 'connect to app and switch tabs', - timeout: const Timeout(Duration(minutes: 2)), - (tester) async { - await pumpAndConnectDevTools(tester, testApp); + testWidgets('connect to app and switch tabs', timeout: shortTimeout, ( + tester, + ) async { + await pumpAndConnectDevTools(tester, testApp); - // For the sake of this test, do not show extension screens by default. - preferences.devToolsExtensions.showOnlyEnabledExtensions.value = true; - await tester.pumpAndSettle(shortPumpDuration); + // For the sake of this test, do not show extension screens by default. + preferences.devToolsExtensions.showOnlyEnabledExtensions.value = true; + await tester.pumpAndSettle(shortPumpDuration); - logStatus('verify that we can load each DevTools screen'); - await navigateThroughDevToolsScreens(tester, connectedToApp: true); - }, - ); + logStatus('verify that we can load each DevTools screen'); + await navigateThroughDevToolsScreens(tester, connectedToApp: true); + }); } diff --git a/packages/devtools_app/integration_test/test/live_connection/debugger_panel_test.dart b/packages/devtools_app/integration_test/test/live_connection/debugger_panel_test.dart index 497435d9dcc..dfc0617fa39 100644 --- a/packages/devtools_app/integration_test/test/live_connection/debugger_panel_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/debugger_panel_test.dart @@ -13,6 +13,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; +import '../../test_infra/run/_utils.dart'; + // To run the test while connected to a flutter-tester device: // dart run integration_test/run_tests.dart --target=integration_test/test/live_connection/debugger_panel_test.dart @@ -29,9 +31,7 @@ void main() { expect(testApp.vmServiceUri, isNotNull); }); - testWidgets('Debugger panel', timeout: const Timeout(Duration(minutes: 4)), ( - tester, - ) async { + testWidgets('Debugger panel', timeout: longTimeout, (tester) async { await pumpAndConnectDevTools(tester, testApp); await switchToScreen( tester, diff --git a/packages/devtools_app/integration_test/test/live_connection/devtools_extensions_test.dart b/packages/devtools_app/integration_test/test/live_connection/devtools_extensions_test.dart index 3787457a530..813bcd046af 100644 --- a/packages/devtools_app/integration_test/test/live_connection/devtools_extensions_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/devtools_extensions_test.dart @@ -20,6 +20,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; +import '../../test_infra/run/_utils.dart'; + // To run: // dart run integration_test/run_tests.dart --target=integration_test/test/live_connection/devtools_extensions_test.dart @@ -41,129 +43,127 @@ void main() { resetDevToolsExtensionEnabledStates(); }); - testWidgets( - 'end to end extensions flow', - timeout: const Timeout(Duration(minutes: 3)), - (tester) async { - await pumpDevTools(tester); - - // TODO(https://github.com/flutter/devtools/issues/9196): re-enable this - // test verification once DTD can be started from the integration test - // harness. - // logStatus( - // 'verify static extensions are available before connecting to an app', - // ); - // expect(extensionService.availableExtensions.length, 2); - // expect(extensionService.visibleExtensions.length, 2); - // await _verifyExtensionsSettingsMenu(tester, [ - // ExtensionEnabledState.none, // dart_foo - // ExtensionEnabledState.none, // standalone_extension - // ]); - - await connectToTestApp(tester, testApp); - - expect(extensionService.availableExtensions.length, 3); - expect(extensionService.visibleExtensions.length, 3); - await _verifyExtensionsSettingsMenu(tester, [ - ExtensionEnabledState.none, // dart_foo - ExtensionEnabledState.none, // foo - ExtensionEnabledState.none, // standalone_extension - ], closeMenuWhenDone: false); - - await _verifyExtensionVisibilitySetting(tester); - - // dart_foo extension. - // Enable, test context menu actions, then disable from context menu. - await _switchToExtensionScreen( - tester, - extensionIndex: 0, - initialLoad: true, - ); - await _answerEnableExtensionPrompt(tester, enable: true); - await _verifyExtensionsSettingsMenu(tester, [ - ExtensionEnabledState.enabled, // dart_foo - ExtensionEnabledState.none, // foo - ExtensionEnabledState.none, // standalone_extension - ]); - - await _verifyContextMenuActionsAndDisable(tester); - - expect(extensionService.availableExtensions.length, 3); - expect(extensionService.visibleExtensions.length, 2); - await _verifyExtensionTabVisibility( - tester, - extensionIndex: 0, - visible: false, - ); - await _verifyExtensionsSettingsMenu(tester, [ - ExtensionEnabledState.disabled, // dart_foo - ExtensionEnabledState.none, // foo - ExtensionEnabledState.none, // standalone_extension - ]); - - // foo extension. Hide immediately. - await _switchToExtensionScreen( - tester, - extensionIndex: 1, - initialLoad: true, - ); - await _answerEnableExtensionPrompt(tester, enable: false); - - expect(extensionService.availableExtensions.length, 3); - expect(extensionService.visibleExtensions.length, 1); - await _verifyExtensionTabVisibility( - tester, - extensionIndex: 1, - visible: false, - ); - await _verifyExtensionsSettingsMenu(tester, [ - ExtensionEnabledState.disabled, // dart_foo - ExtensionEnabledState.disabled, // foo - ExtensionEnabledState.none, // standalone_extension - ]); - - // Re-enable foo extension from the extensions settings menu. - logStatus('verify we can re-enable an extension from the settings menu'); - await _changeExtensionSetting(tester, extensionIndex: 1, enable: true); - - expect(extensionService.availableExtensions.length, 3); - expect(extensionService.visibleExtensions.length, 2); - await _switchToExtensionScreen(tester, extensionIndex: 1); - expect(find.byType(EnableExtensionPrompt), findsNothing); - expect(find.byType(EmbeddedExtensionView), findsOneWidget); - expect(find.byType(HtmlElementView), findsOneWidget); - await _verifyExtensionsSettingsMenu(tester, [ - ExtensionEnabledState.disabled, // dart_foo - ExtensionEnabledState.enabled, // foo - ExtensionEnabledState.none, // standalone_extension - ]); - - // standalone_extension. Disable directly from settings menu. - logStatus( - 'verify we can disable an extension screen directly from the settings menu', - ); - await _verifyExtensionTabVisibility( - tester, - extensionIndex: 2, - visible: true, - ); - - logStatus('disable the extension from the settings menu'); - await _changeExtensionSetting(tester, extensionIndex: 2, enable: false); - expect(extensionService.availableExtensions.length, 3); - expect(extensionService.visibleExtensions.length, 1); - await _verifyExtensionTabVisibility( - tester, - extensionIndex: 2, - visible: false, - ); - await _verifyExtensionsSettingsMenu(tester, [ - ExtensionEnabledState.disabled, // dart_foo - ExtensionEnabledState.enabled, // foo - ExtensionEnabledState.disabled, // standalone_extension - ]); - }, - ); + testWidgets('end to end extensions flow', timeout: mediumTimeout, ( + tester, + ) async { + await pumpDevTools(tester); + + // TODO(https://github.com/flutter/devtools/issues/9196): re-enable this + // test verification once DTD can be started from the integration test + // harness. + // logStatus( + // 'verify static extensions are available before connecting to an app', + // ); + // expect(extensionService.availableExtensions.length, 2); + // expect(extensionService.visibleExtensions.length, 2); + // await _verifyExtensionsSettingsMenu(tester, [ + // ExtensionEnabledState.none, // dart_foo + // ExtensionEnabledState.none, // standalone_extension + // ]); + + await connectToTestApp(tester, testApp); + + expect(extensionService.availableExtensions.length, 3); + expect(extensionService.visibleExtensions.length, 3); + await _verifyExtensionsSettingsMenu(tester, [ + ExtensionEnabledState.none, // dart_foo + ExtensionEnabledState.none, // foo + ExtensionEnabledState.none, // standalone_extension + ], closeMenuWhenDone: false); + + await _verifyExtensionVisibilitySetting(tester); + + // dart_foo extension. + // Enable, test context menu actions, then disable from context menu. + await _switchToExtensionScreen( + tester, + extensionIndex: 0, + initialLoad: true, + ); + await _answerEnableExtensionPrompt(tester, enable: true); + await _verifyExtensionsSettingsMenu(tester, [ + ExtensionEnabledState.enabled, // dart_foo + ExtensionEnabledState.none, // foo + ExtensionEnabledState.none, // standalone_extension + ]); + + await _verifyContextMenuActionsAndDisable(tester); + + expect(extensionService.availableExtensions.length, 3); + expect(extensionService.visibleExtensions.length, 2); + await _verifyExtensionTabVisibility( + tester, + extensionIndex: 0, + visible: false, + ); + await _verifyExtensionsSettingsMenu(tester, [ + ExtensionEnabledState.disabled, // dart_foo + ExtensionEnabledState.none, // foo + ExtensionEnabledState.none, // standalone_extension + ]); + + // foo extension. Hide immediately. + await _switchToExtensionScreen( + tester, + extensionIndex: 1, + initialLoad: true, + ); + await _answerEnableExtensionPrompt(tester, enable: false); + + expect(extensionService.availableExtensions.length, 3); + expect(extensionService.visibleExtensions.length, 1); + await _verifyExtensionTabVisibility( + tester, + extensionIndex: 1, + visible: false, + ); + await _verifyExtensionsSettingsMenu(tester, [ + ExtensionEnabledState.disabled, // dart_foo + ExtensionEnabledState.disabled, // foo + ExtensionEnabledState.none, // standalone_extension + ]); + + // Re-enable foo extension from the extensions settings menu. + logStatus('verify we can re-enable an extension from the settings menu'); + await _changeExtensionSetting(tester, extensionIndex: 1, enable: true); + + expect(extensionService.availableExtensions.length, 3); + expect(extensionService.visibleExtensions.length, 2); + await _switchToExtensionScreen(tester, extensionIndex: 1); + expect(find.byType(EnableExtensionPrompt), findsNothing); + expect(find.byType(EmbeddedExtensionView), findsOneWidget); + expect(find.byType(HtmlElementView), findsOneWidget); + await _verifyExtensionsSettingsMenu(tester, [ + ExtensionEnabledState.disabled, // dart_foo + ExtensionEnabledState.enabled, // foo + ExtensionEnabledState.none, // standalone_extension + ]); + + // standalone_extension. Disable directly from settings menu. + logStatus( + 'verify we can disable an extension screen directly from the settings menu', + ); + await _verifyExtensionTabVisibility( + tester, + extensionIndex: 2, + visible: true, + ); + + logStatus('disable the extension from the settings menu'); + await _changeExtensionSetting(tester, extensionIndex: 2, enable: false); + expect(extensionService.availableExtensions.length, 3); + expect(extensionService.visibleExtensions.length, 1); + await _verifyExtensionTabVisibility( + tester, + extensionIndex: 2, + visible: false, + ); + await _verifyExtensionsSettingsMenu(tester, [ + ExtensionEnabledState.disabled, // dart_foo + ExtensionEnabledState.enabled, // foo + ExtensionEnabledState.disabled, // standalone_extension + ]); + }); } Future _switchToExtensionScreen( diff --git a/packages/devtools_app/integration_test/test/live_connection/eval_and_browse_test.dart b/packages/devtools_app/integration_test/test/live_connection/eval_and_browse_test.dart index c323dec8a9f..bb9cbc79bb1 100644 --- a/packages/devtools_app/integration_test/test/live_connection/eval_and_browse_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/eval_and_browse_test.dart @@ -10,6 +10,7 @@ import 'package:devtools_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; +import '../../test_infra/run/_utils.dart'; import 'eval_utils.dart'; import 'memory_screen_helpers.dart'; @@ -30,34 +31,30 @@ void main() { await resetHistory(); }); - testWidgets( - 'memory eval and browse', - timeout: const Timeout(Duration(minutes: 3)), - (tester) async { - await pumpAndConnectDevTools(tester, testApp); + testWidgets('memory eval and browse', timeout: mediumTimeout, (tester) async { + await pumpAndConnectDevTools(tester, testApp); - final evalTester = EvalTester(tester); - await prepareMemoryUI(tester, makeConsoleWider: true); + final evalTester = EvalTester(tester); + await prepareMemoryUI(tester, makeConsoleWider: true); - logStatus('test basic evaluation'); - await testBasicEval(evalTester); + logStatus('test basic evaluation'); + await testBasicEval(evalTester); - logStatus('test variable assignment'); - await testAssignment(evalTester); + logStatus('test variable assignment'); + await testAssignment(evalTester); - logStatus('test dump one instance to console'); - await _profileOneInstance(evalTester); + logStatus('test dump one instance to console'); + await _profileOneInstance(evalTester); - logStatus('test dump all instances to console'); - await _profileAllInstances(evalTester); + logStatus('test dump all instances to console'); + await _profileAllInstances(evalTester); - logStatus('test take a snapshot'); - await evalTester.takeSnapshot(); + logStatus('test take a snapshot'); + await evalTester.takeSnapshot(); - logStatus('test inbound references are listed on console instance'); - await _inboundReferencesAreListed(evalTester); - }, - ); + logStatus('test inbound references are listed on console instance'); + await _inboundReferencesAreListed(evalTester); + }); } Future _profileOneInstance(EvalTester tester) async { diff --git a/packages/devtools_app/integration_test/test/live_connection/eval_and_inspect_test.dart b/packages/devtools_app/integration_test/test/live_connection/eval_and_inspect_test.dart index 3c7279888d8..a2915f402f9 100644 --- a/packages/devtools_app/integration_test/test/live_connection/eval_and_inspect_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/eval_and_inspect_test.dart @@ -10,6 +10,7 @@ import 'package:devtools_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; +import '../../test_infra/run/_utils.dart'; import 'eval_utils.dart'; // To run the test while connected to a flutter-tester device: @@ -32,26 +33,24 @@ void main() { await resetHistory(); }); - testWidgets( - 'eval with scope in inspector window', - timeout: const Timeout(Duration(minutes: 3)), - (tester) async { - await pumpAndConnectDevTools(tester, testApp); + testWidgets('eval with scope in inspector window', timeout: mediumTimeout, ( + tester, + ) async { + await pumpAndConnectDevTools(tester, testApp); - final evalTester = EvalTester(tester); - await evalTester.prepareInspectorUI(); + final evalTester = EvalTester(tester); + await evalTester.prepareInspectorUI(); - logStatus('testing basic evaluation'); - await testBasicEval(evalTester); + logStatus('testing basic evaluation'); + await testBasicEval(evalTester); - logStatus('testing variable assignment'); - await testAssignment(evalTester); - }, - ); + logStatus('testing variable assignment'); + await testAssignment(evalTester); + }); testWidgets( 'eval with scope on widget tree node', - timeout: const Timeout(Duration(minutes: 3)), + timeout: mediumTimeout, (tester) async { await pumpAndConnectDevTools(tester, testApp); diff --git a/packages/devtools_app/integration_test/test/live_connection/export_snapshot_test.dart b/packages/devtools_app/integration_test/test/live_connection/export_snapshot_test.dart index ac26935c09e..7ef637c1b71 100644 --- a/packages/devtools_app/integration_test/test/live_connection/export_snapshot_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/export_snapshot_test.dart @@ -6,6 +6,7 @@ import 'package:devtools_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; +import '../../test_infra/run/_utils.dart'; import 'memory_screen_helpers.dart'; // To run: @@ -25,9 +26,7 @@ void main() { await resetHistory(); }); - testWidgets('Export snapshot', timeout: const Timeout(Duration(minutes: 2)), ( - tester, - ) async { + testWidgets('Export snapshot', timeout: shortTimeout, (tester) async { await pumpAndConnectDevTools(tester, testApp); await prepareMemoryUI(tester); await takeHeapSnapshot(tester); diff --git a/packages/devtools_app/integration_test/test/live_connection/performance_screen_event_recording_test.dart b/packages/devtools_app/integration_test/test/live_connection/performance_screen_event_recording_test.dart index 14707baf33a..061b4d8eaea 100644 --- a/packages/devtools_app/integration_test/test/live_connection/performance_screen_event_recording_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/performance_screen_event_recording_test.dart @@ -11,6 +11,8 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:vm_service_protos/vm_service_protos.dart'; +import '../../test_infra/run/_utils.dart'; + // To run: // dart run integration_test/run_tests.dart --target=integration_test/test/live_connection/performance_screen_event_recording_test.dart @@ -24,102 +26,98 @@ void main() { expect(testApp.vmServiceUri, isNotNull); }); - testWidgets( - 'can process and refresh timeline data', - timeout: const Timeout(Duration(minutes: 4)), - (tester) async { - await pumpAndConnectDevTools(tester, testApp); - - logStatus( - 'Open the Performance screen and switch to the Timeline Events tab', - ); - - await switchToScreen( - tester, - tabIcon: ScreenMetaData.performance.icon, - tabIconAsset: ScreenMetaData.performance.iconAsset, - screenId: ScreenMetaData.performance.id, - ); - await tester.pump(safePumpDuration); - - await tester.tap(find.widgetWithText(InkWell, 'Timeline Events')); - await tester.pumpAndSettle(longPumpDuration); - - // Find the [PerformanceController] to access its data. - final performanceScreenFinder = find.byType(PerformanceScreenBody); - expect(performanceScreenFinder, findsOneWidget); - final screenState = tester.state( - performanceScreenFinder, - ); - final performanceController = screenState.controller; - - logStatus('Verifying that data is processed upon first load'); - final initialTrace = Trace.fromBuffer( - performanceController.timelineEventsController.fullPerfettoTrace, - ); - final initialTracePacket = List.of(initialTrace.packet, growable: false); - final initialTrackDescriptors = initialTracePacket.where( - (e) => e.hasTrackDescriptor(), - ); - expect(initialTracePacket, isNotEmpty); - expect(initialTrackDescriptors, isNotEmpty); - - final trackEvents = initialTracePacket.where((e) => e.hasTrackEvent()); - expect(trackEvents, isNotEmpty); - - expect( - performanceController - .timelineEventsController - .perfettoController - .processor - .uiTrackId, - isNotNull, - reason: 'Expected uiTrackId to be non-null', - ); - expect( - performanceController - .timelineEventsController - .perfettoController - .processor - .rasterTrackId, - isNotNull, - reason: 'Expected rasterTrackId to be non-null', - ); - expect( - performanceController - .timelineEventsController - .perfettoController - .processor - .frameRangeFromTimelineEvents, - isNotNull, - reason: 'Expected frameRangeFromTimelineEvents to be non-null', - ); - - logStatus( - 'toggling the Performance Overlay to trigger new Flutter frames', - ); - final performanceOverlayFinder = find.text('Performance Overlay'); - expect(performanceOverlayFinder, findsOneWidget); - await tester.tap(performanceOverlayFinder); - await tester.pump(longPumpDuration); - - logStatus('Refreshing the timeline to load new events'); - await tester.tap(find.byType(RefreshTimelineEventsButton)); - await tester.pump(longPumpDuration); - - logStatus('Verifying that we have recorded new events'); - final refreshedTrace = Trace.fromBuffer( - performanceController.timelineEventsController.fullPerfettoTrace, - ); - final refreshedTracePacket = List.of( - refreshedTrace.packet, - growable: false, - ); - expect( - refreshedTracePacket.length, - greaterThan(initialTracePacket.length), - reason: 'Expected new events to have been recorded, but none were.', - ); - }, - ); + testWidgets('can process and refresh timeline data', timeout: longTimeout, ( + tester, + ) async { + await pumpAndConnectDevTools(tester, testApp); + + logStatus( + 'Open the Performance screen and switch to the Timeline Events tab', + ); + + await switchToScreen( + tester, + tabIcon: ScreenMetaData.performance.icon, + tabIconAsset: ScreenMetaData.performance.iconAsset, + screenId: ScreenMetaData.performance.id, + ); + await tester.pump(safePumpDuration); + + await tester.tap(find.widgetWithText(InkWell, 'Timeline Events')); + await tester.pumpAndSettle(longPumpDuration); + + // Find the [PerformanceController] to access its data. + final performanceScreenFinder = find.byType(PerformanceScreenBody); + expect(performanceScreenFinder, findsOneWidget); + final screenState = tester.state( + performanceScreenFinder, + ); + final performanceController = screenState.controller; + + logStatus('Verifying that data is processed upon first load'); + final initialTrace = Trace.fromBuffer( + performanceController.timelineEventsController.fullPerfettoTrace, + ); + final initialTracePacket = List.of(initialTrace.packet, growable: false); + final initialTrackDescriptors = initialTracePacket.where( + (e) => e.hasTrackDescriptor(), + ); + expect(initialTracePacket, isNotEmpty); + expect(initialTrackDescriptors, isNotEmpty); + + final trackEvents = initialTracePacket.where((e) => e.hasTrackEvent()); + expect(trackEvents, isNotEmpty); + + expect( + performanceController + .timelineEventsController + .perfettoController + .processor + .uiTrackId, + isNotNull, + reason: 'Expected uiTrackId to be non-null', + ); + expect( + performanceController + .timelineEventsController + .perfettoController + .processor + .rasterTrackId, + isNotNull, + reason: 'Expected rasterTrackId to be non-null', + ); + expect( + performanceController + .timelineEventsController + .perfettoController + .processor + .frameRangeFromTimelineEvents, + isNotNull, + reason: 'Expected frameRangeFromTimelineEvents to be non-null', + ); + + logStatus('toggling the Performance Overlay to trigger new Flutter frames'); + final performanceOverlayFinder = find.text('Performance Overlay'); + expect(performanceOverlayFinder, findsOneWidget); + await tester.tap(performanceOverlayFinder); + await tester.pump(longPumpDuration); + + logStatus('Refreshing the timeline to load new events'); + await tester.tap(find.byType(RefreshTimelineEventsButton)); + await tester.pump(longPumpDuration); + + logStatus('Verifying that we have recorded new events'); + final refreshedTrace = Trace.fromBuffer( + performanceController.timelineEventsController.fullPerfettoTrace, + ); + final refreshedTracePacket = List.of( + refreshedTrace.packet, + growable: false, + ); + expect( + refreshedTracePacket.length, + greaterThan(initialTracePacket.length), + reason: 'Expected new events to have been recorded, but none were.', + ); + }); } diff --git a/packages/devtools_app/integration_test/test/live_connection/service_connection_test.dart b/packages/devtools_app/integration_test/test/live_connection/service_connection_test.dart index 66e9f51a148..48cfff8a483 100644 --- a/packages/devtools_app/integration_test/test/live_connection/service_connection_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/service_connection_test.dart @@ -10,6 +10,8 @@ import 'package:devtools_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; +import '../../test_infra/run/_utils.dart'; + // To run: // dart run integration_test/run_tests.dart --target=integration_test/test/live_connection/service_connection_test.dart @@ -27,88 +29,83 @@ void main() { await resetHistory(); }); - testWidgets( - 'initial service connection state', - timeout: const Timeout(Duration(minutes: 3)), - (tester) async { - await pumpAndConnectDevTools(tester, testApp); - - // Await a delay to ensure the service extensions have had a chance to - // be called. This delay may be able to be shortened if doing so does - // not cause bot flakiness. - await tester.pump(longDuration); - - // Ensure all futures are completed before running checks. - await serviceConnection.serviceManager.service!.allFuturesCompleted; - - logStatus('verify the vm service calls that occur on connect'); - final vmServiceCallCount = - serviceConnection.serviceManager.service!.vmServiceCallCount; - expect( - // Use a range instead of an exact number because service extension - // calls are not consistent. This will still catch any spurious calls - // that are unintentionally added at start up. - const Range(35, 70).contains(vmServiceCallCount), - isTrue, - reason: - 'Unexpected number of vm service calls upon connection: ' - '$vmServiceCallCount. If this is expected, please update this test ' - 'to the new expected number of calls. Here are the calls for this ' - 'test run:\n ${serviceConnection.serviceManager.service!.vmServiceCalls.toString()}', - ); + testWidgets('initial service connection state', timeout: mediumTimeout, ( + tester, + ) async { + await pumpAndConnectDevTools(tester, testApp); - // Check the ordering of the vm service calls we can expect to occur - // in a stable order. - expect( - serviceConnection.serviceManager.service!.vmServiceCalls - // Filter out unawaited streamListen calls. - .where((call) => call != 'streamListen') - .toList() - .sublist(0, 8), - equals([ - 'getSupportedProtocols', - 'getVersion', - 'setFlag', - 'requirePermissionToResume', - 'getFlagList', - 'getDartDevelopmentServiceVersion', - 'getDartDevelopmentServiceVersion', - 'getVM', - ]), - reason: - 'Unexpected order of vm service calls upon connection. ' - 'Here are the calls for this test run:\n ' - '${serviceConnection.serviceManager.service!.vmServiceCalls.toString()}', - ); + // Await a delay to ensure the service extensions have had a chance to + // be called. This delay may be able to be shortened if doing so does + // not cause bot flakiness. + await tester.pump(longDuration); - expect( - serviceConnection.serviceManager.service!.vmServiceCalls - .where((call) => call == 'streamListen') - .toList() - .length, - equals(10), - ); + // Ensure all futures are completed before running checks. + await serviceConnection.serviceManager.service!.allFuturesCompleted; - logStatus('verify managers have all been initialized'); - expect( - serviceConnection.serviceManager.serviceExtensionManager, - isNotNull, - ); - expect( - serviceConnection.serviceManager.isolateManager.isolates.value, - isNotEmpty, + logStatus('verify the vm service calls that occur on connect'); + final vmServiceCallCount = + serviceConnection.serviceManager.service!.vmServiceCallCount; + expect( + // Use a range instead of an exact number because service extension + // calls are not consistent. This will still catch any spurious calls + // that are unintentionally added at start up. + const Range(35, 70).contains(vmServiceCallCount), + isTrue, + reason: + 'Unexpected number of vm service calls upon connection: ' + '$vmServiceCallCount. If this is expected, please update this test ' + 'to the new expected number of calls. Here are the calls for this ' + 'test run:\n ${serviceConnection.serviceManager.service!.vmServiceCalls.toString()}', + ); + + // Check the ordering of the vm service calls we can expect to occur + // in a stable order. + expect( + serviceConnection.serviceManager.service!.vmServiceCalls + // Filter out unawaited streamListen calls. + .where((call) => call != 'streamListen') + .toList() + .sublist(0, 8), + equals([ + 'getSupportedProtocols', + 'getVersion', + 'setFlag', + 'requirePermissionToResume', + 'getFlagList', + 'getDartDevelopmentServiceVersion', + 'getDartDevelopmentServiceVersion', + 'getVM', + ]), + reason: + 'Unexpected order of vm service calls upon connection. ' + 'Here are the calls for this test run:\n ' + '${serviceConnection.serviceManager.service!.vmServiceCalls.toString()}', + ); + + expect( + serviceConnection.serviceManager.service!.vmServiceCalls + .where((call) => call == 'streamListen') + .toList() + .length, + equals(10), + ); + + logStatus('verify managers have all been initialized'); + expect(serviceConnection.serviceManager.serviceExtensionManager, isNotNull); + expect( + serviceConnection.serviceManager.isolateManager.isolates.value, + isNotEmpty, + ); + expect(serviceConnection.vmFlagManager.flags.value, isNotNull); + + final selectedIsolate = + serviceConnection.serviceManager.isolateManager.selectedIsolate; + if (selectedIsolate.value == null) { + await whenValueNonNull( + serviceConnection.serviceManager.isolateManager.selectedIsolate, ); - expect(serviceConnection.vmFlagManager.flags.value, isNotNull); - - final selectedIsolate = - serviceConnection.serviceManager.isolateManager.selectedIsolate; - if (selectedIsolate.value == null) { - await whenValueNonNull( - serviceConnection.serviceManager.isolateManager.selectedIsolate, - ); - } - - await disconnectFromTestApp(tester); - }, - ); + } + + await disconnectFromTestApp(tester); + }); } diff --git a/packages/devtools_app/integration_test/test/live_connection/service_extensions_test.dart b/packages/devtools_app/integration_test/test/live_connection/service_extensions_test.dart index 962060d1ed9..0e77008f6b8 100644 --- a/packages/devtools_app/integration_test/test/live_connection/service_extensions_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/service_extensions_test.dart @@ -18,6 +18,8 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:vm_service/vm_service.dart'; +import '../../test_infra/run/_utils.dart'; + // To run: // dart run integration_test/run_tests.dart --target=integration_test/test/live_connection/service_extensions_test.dart @@ -37,7 +39,7 @@ void main() { testWidgets( 'can call services and service extensions', - timeout: const Timeout(Duration(minutes: 3)), + timeout: mediumTimeout, (tester) async { await pumpAndConnectDevTools(tester, testApp); await tester.pump(longDuration); diff --git a/packages/devtools_app/integration_test/test/offline/memory_offline_data_test.dart b/packages/devtools_app/integration_test/test/offline/memory_offline_data_test.dart index 08db030e205..ed5949d9e27 100644 --- a/packages/devtools_app/integration_test/test/offline/memory_offline_data_test.dart +++ b/packages/devtools_app/integration_test/test/offline/memory_offline_data_test.dart @@ -8,34 +8,34 @@ import 'package:devtools_test/test_data.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; +import '../../test_infra/run/_utils.dart'; + // To run: // dart run integration_test/run_tests.dart --target=integration_test/test/offline/memory_offline_data_test.dart void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - testWidgets( - 'Memory screen can load offline data', - timeout: const Timeout(Duration(minutes: 3)), - (tester) async { - await pumpDevTools(tester); - logStatus('1 - pumped devtools'); - await loadSampleData(tester, memoryFileName); - logStatus('2 - loaded sample data'); - await tester.pumpAndSettle(longPumpDuration); - logStatus('3 - pumped and settled'); - - const diffTab = 'Diff Snapshots'; - const profileTab = 'Profile Memory'; - const traceTab = 'Trace Instances'; - - expect(find.text('_MyClass'), findsOneWidget); - logStatus('5 - found _MyClass'); - - for (final tab in [diffTab, profileTab, traceTab]) { - expect(find.text(tab), findsOneWidget); - logStatus('6.$tab - found'); - } - }, - ); + testWidgets('Memory screen can load offline data', timeout: mediumTimeout, ( + tester, + ) async { + await pumpDevTools(tester); + logStatus('1 - pumped devtools'); + await loadSampleData(tester, memoryFileName); + logStatus('2 - loaded sample data'); + await tester.pumpAndSettle(longPumpDuration); + logStatus('3 - pumped and settled'); + + const diffTab = 'Diff Snapshots'; + const profileTab = 'Profile Memory'; + const traceTab = 'Trace Instances'; + + expect(find.text('_MyClass'), findsOneWidget); + logStatus('5 - found _MyClass'); + + for (final tab in [diffTab, profileTab, traceTab]) { + expect(find.text(tab), findsOneWidget); + logStatus('6.$tab - found'); + } + }); } diff --git a/packages/devtools_app/integration_test/test/offline/perfetto_test.dart b/packages/devtools_app/integration_test/test/offline/perfetto_test.dart index 5a7aa68ea72..d3e1d18b452 100644 --- a/packages/devtools_app/integration_test/test/offline/perfetto_test.dart +++ b/packages/devtools_app/integration_test/test/offline/perfetto_test.dart @@ -11,6 +11,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; +import '../../test_infra/run/_utils.dart'; + // To run: // dart run integration_test/run_tests.dart --target=integration_test/test/offline/perfetto_test.dart @@ -19,7 +21,7 @@ void main() { testWidgets( 'Perfetto trace viewer loads data and scrolls for Flutter frames', - timeout: const Timeout(Duration(minutes: 3)), + timeout: mediumTimeout, (tester) async { await pumpDevTools(tester); await loadSampleData(tester, performanceFileName); diff --git a/packages/devtools_app/integration_test/test_infra/run/_utils.dart b/packages/devtools_app/integration_test/test_infra/run/_utils.dart index ebf1e030e62..f5d0a797242 100644 --- a/packages/devtools_app/integration_test/test_infra/run/_utils.dart +++ b/packages/devtools_app/integration_test/test_infra/run/_utils.dart @@ -4,6 +4,11 @@ // ignore_for_file: avoid_print +/// @docImport 'package:flutter_test/flutter_test.dart'; +library; + +import 'package:test/test.dart' show Timeout; + bool debugTestScript = false; void debugLog(String log) { @@ -11,3 +16,21 @@ void debugLog(String log) { print(log); } } + +/// A timeout for a "short" integration test. +/// +/// Adjust as needed; this is used to override the 10-minute or infinite timeout +/// in [testWidgets]. +const Timeout shortTimeout = Timeout(Duration(minutes: 2)); + +/// A timeout for a "medium" integration test. +/// +/// Adjust as needed; this is used to override the 10-minute or infinite timeout +/// in [testWidgets]. +const Timeout mediumTimeout = Timeout(Duration(minutes: 3)); + +/// A timeout for a "long" integration test. +/// +/// Adjust as needed; this is used to override the 10-minute or infinite timeout +/// in [testWidgets]. +const Timeout longTimeout = Timeout(Duration(minutes: 4)); From 3d818621b9b9593891fe6957a6703c0779cb9e44 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Mon, 21 Jul 2025 07:25:21 -0700 Subject: [PATCH 3/3] feedback --- .../test/live_connection/app_test.dart | 2 -- .../live_connection/debugger_panel_test.dart | 2 -- .../devtools_extensions_test.dart | 2 -- .../live_connection/eval_and_browse_test.dart | 1 - .../eval_and_inspect_test.dart | 1 - .../live_connection/export_snapshot_test.dart | 1 - ...rformance_screen_event_recording_test.dart | 2 -- .../service_connection_test.dart | 2 -- .../service_extensions_test.dart | 2 -- .../offline/memory_offline_data_test.dart | 2 -- .../test/offline/perfetto_test.dart | 2 -- .../test_infra/run/_utils.dart | 23 ------------------- .../integration_test_utils.dart | 18 +++++++++++++++ 13 files changed, 18 insertions(+), 42 deletions(-) diff --git a/packages/devtools_app/integration_test/test/live_connection/app_test.dart b/packages/devtools_app/integration_test/test/live_connection/app_test.dart index 20108def5cf..2b40eaacafd 100644 --- a/packages/devtools_app/integration_test/test/live_connection/app_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/app_test.dart @@ -8,8 +8,6 @@ import 'package:devtools_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; -import '../../test_infra/run/_utils.dart'; - // To run: // dart run integration_test/run_tests.dart --target=integration_test/test/live_connection/app_test.dart diff --git a/packages/devtools_app/integration_test/test/live_connection/debugger_panel_test.dart b/packages/devtools_app/integration_test/test/live_connection/debugger_panel_test.dart index dfc0617fa39..58b5a097344 100644 --- a/packages/devtools_app/integration_test/test/live_connection/debugger_panel_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/debugger_panel_test.dart @@ -13,8 +13,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; -import '../../test_infra/run/_utils.dart'; - // To run the test while connected to a flutter-tester device: // dart run integration_test/run_tests.dart --target=integration_test/test/live_connection/debugger_panel_test.dart diff --git a/packages/devtools_app/integration_test/test/live_connection/devtools_extensions_test.dart b/packages/devtools_app/integration_test/test/live_connection/devtools_extensions_test.dart index 813bcd046af..377b03d137f 100644 --- a/packages/devtools_app/integration_test/test/live_connection/devtools_extensions_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/devtools_extensions_test.dart @@ -20,8 +20,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; -import '../../test_infra/run/_utils.dart'; - // To run: // dart run integration_test/run_tests.dart --target=integration_test/test/live_connection/devtools_extensions_test.dart diff --git a/packages/devtools_app/integration_test/test/live_connection/eval_and_browse_test.dart b/packages/devtools_app/integration_test/test/live_connection/eval_and_browse_test.dart index bb9cbc79bb1..3fa80f76193 100644 --- a/packages/devtools_app/integration_test/test/live_connection/eval_and_browse_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/eval_and_browse_test.dart @@ -10,7 +10,6 @@ import 'package:devtools_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; -import '../../test_infra/run/_utils.dart'; import 'eval_utils.dart'; import 'memory_screen_helpers.dart'; diff --git a/packages/devtools_app/integration_test/test/live_connection/eval_and_inspect_test.dart b/packages/devtools_app/integration_test/test/live_connection/eval_and_inspect_test.dart index a2915f402f9..be03ece7984 100644 --- a/packages/devtools_app/integration_test/test/live_connection/eval_and_inspect_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/eval_and_inspect_test.dart @@ -10,7 +10,6 @@ import 'package:devtools_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; -import '../../test_infra/run/_utils.dart'; import 'eval_utils.dart'; // To run the test while connected to a flutter-tester device: diff --git a/packages/devtools_app/integration_test/test/live_connection/export_snapshot_test.dart b/packages/devtools_app/integration_test/test/live_connection/export_snapshot_test.dart index 7ef637c1b71..673c3c55787 100644 --- a/packages/devtools_app/integration_test/test/live_connection/export_snapshot_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/export_snapshot_test.dart @@ -6,7 +6,6 @@ import 'package:devtools_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; -import '../../test_infra/run/_utils.dart'; import 'memory_screen_helpers.dart'; // To run: diff --git a/packages/devtools_app/integration_test/test/live_connection/performance_screen_event_recording_test.dart b/packages/devtools_app/integration_test/test/live_connection/performance_screen_event_recording_test.dart index 061b4d8eaea..dd34a1c8811 100644 --- a/packages/devtools_app/integration_test/test/live_connection/performance_screen_event_recording_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/performance_screen_event_recording_test.dart @@ -11,8 +11,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:vm_service_protos/vm_service_protos.dart'; -import '../../test_infra/run/_utils.dart'; - // To run: // dart run integration_test/run_tests.dart --target=integration_test/test/live_connection/performance_screen_event_recording_test.dart diff --git a/packages/devtools_app/integration_test/test/live_connection/service_connection_test.dart b/packages/devtools_app/integration_test/test/live_connection/service_connection_test.dart index 48cfff8a483..93e3f5f335b 100644 --- a/packages/devtools_app/integration_test/test/live_connection/service_connection_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/service_connection_test.dart @@ -10,8 +10,6 @@ import 'package:devtools_test/integration_test.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; -import '../../test_infra/run/_utils.dart'; - // To run: // dart run integration_test/run_tests.dart --target=integration_test/test/live_connection/service_connection_test.dart diff --git a/packages/devtools_app/integration_test/test/live_connection/service_extensions_test.dart b/packages/devtools_app/integration_test/test/live_connection/service_extensions_test.dart index 0e77008f6b8..18105d3f41d 100644 --- a/packages/devtools_app/integration_test/test/live_connection/service_extensions_test.dart +++ b/packages/devtools_app/integration_test/test/live_connection/service_extensions_test.dart @@ -18,8 +18,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:vm_service/vm_service.dart'; -import '../../test_infra/run/_utils.dart'; - // To run: // dart run integration_test/run_tests.dart --target=integration_test/test/live_connection/service_extensions_test.dart diff --git a/packages/devtools_app/integration_test/test/offline/memory_offline_data_test.dart b/packages/devtools_app/integration_test/test/offline/memory_offline_data_test.dart index ed5949d9e27..86a49697d93 100644 --- a/packages/devtools_app/integration_test/test/offline/memory_offline_data_test.dart +++ b/packages/devtools_app/integration_test/test/offline/memory_offline_data_test.dart @@ -8,8 +8,6 @@ import 'package:devtools_test/test_data.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; -import '../../test_infra/run/_utils.dart'; - // To run: // dart run integration_test/run_tests.dart --target=integration_test/test/offline/memory_offline_data_test.dart diff --git a/packages/devtools_app/integration_test/test/offline/perfetto_test.dart b/packages/devtools_app/integration_test/test/offline/perfetto_test.dart index d3e1d18b452..f2fb3c30ed7 100644 --- a/packages/devtools_app/integration_test/test/offline/perfetto_test.dart +++ b/packages/devtools_app/integration_test/test/offline/perfetto_test.dart @@ -11,8 +11,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; -import '../../test_infra/run/_utils.dart'; - // To run: // dart run integration_test/run_tests.dart --target=integration_test/test/offline/perfetto_test.dart diff --git a/packages/devtools_app/integration_test/test_infra/run/_utils.dart b/packages/devtools_app/integration_test/test_infra/run/_utils.dart index f5d0a797242..ebf1e030e62 100644 --- a/packages/devtools_app/integration_test/test_infra/run/_utils.dart +++ b/packages/devtools_app/integration_test/test_infra/run/_utils.dart @@ -4,11 +4,6 @@ // ignore_for_file: avoid_print -/// @docImport 'package:flutter_test/flutter_test.dart'; -library; - -import 'package:test/test.dart' show Timeout; - bool debugTestScript = false; void debugLog(String log) { @@ -16,21 +11,3 @@ void debugLog(String log) { print(log); } } - -/// A timeout for a "short" integration test. -/// -/// Adjust as needed; this is used to override the 10-minute or infinite timeout -/// in [testWidgets]. -const Timeout shortTimeout = Timeout(Duration(minutes: 2)); - -/// A timeout for a "medium" integration test. -/// -/// Adjust as needed; this is used to override the 10-minute or infinite timeout -/// in [testWidgets]. -const Timeout mediumTimeout = Timeout(Duration(minutes: 3)); - -/// A timeout for a "long" integration test. -/// -/// Adjust as needed; this is used to override the 10-minute or infinite timeout -/// in [testWidgets]. -const Timeout longTimeout = Timeout(Duration(minutes: 4)); diff --git a/packages/devtools_test/lib/src/integration_test/integration_test_utils.dart b/packages/devtools_test/lib/src/integration_test/integration_test_utils.dart index 9074fb629c6..4b3d520c334 100644 --- a/packages/devtools_test/lib/src/integration_test/integration_test_utils.dart +++ b/packages/devtools_test/lib/src/integration_test/integration_test_utils.dart @@ -157,3 +157,21 @@ Future verifyScreenshot( 'last_screenshot': lastScreenshot, }); } + +/// A timeout for a "short" integration test. +/// +/// Adjust as needed; this is used to override the 10-minute or infinite timeout +/// in [testWidgets]. +const Timeout shortTimeout = Timeout(Duration(minutes: 2)); + +/// A timeout for a "medium" integration test. +/// +/// Adjust as needed; this is used to override the 10-minute or infinite timeout +/// in [testWidgets]. +const Timeout mediumTimeout = Timeout(Duration(minutes: 3)); + +/// A timeout for a "long" integration test. +/// +/// Adjust as needed; this is used to override the 10-minute or infinite timeout +/// in [testWidgets]. +const Timeout longTimeout = Timeout(Duration(minutes: 4));