Remove legacy integration tests and address several TODOs (#8784)

diff --git a/packages/devtools_app/lib/src/screens/logging/_message_column.dart b/packages/devtools_app/lib/src/screens/logging/_message_column.dart
index 8e38481..371b885 100644
--- a/packages/devtools_app/lib/src/screens/logging/_message_column.dart
+++ b/packages/devtools_app/lib/src/screens/logging/_message_column.dart
@@ -92,10 +92,7 @@
               padding: const EdgeInsets.symmetric(vertical: densePadding),
               child: LayoutBuilder(
                 builder: (context, constraints) {
-                  return MetadataChips(
-                    data: data,
-                    maxWidth: constraints.maxWidth,
-                  );
+                  return MetadataChips(data: data);
                 },
               ),
             ),
diff --git a/packages/devtools_app/lib/src/screens/logging/metadata.dart b/packages/devtools_app/lib/src/screens/logging/metadata.dart
index 7860ad8..40a8d85 100644
--- a/packages/devtools_app/lib/src/screens/logging/metadata.dart
+++ b/packages/devtools_app/lib/src/screens/logging/metadata.dart
@@ -13,16 +13,9 @@
 import 'logging_controller.dart';
 
 class MetadataChips extends StatelessWidget {
-  const MetadataChips({
-    super.key,
-    required this.data,
-    // TODO(kenz): remove maxWidth from these metadata chips once the Logging
-    // V2 code is removed.
-    required this.maxWidth,
-  });
+  const MetadataChips({super.key, required this.data});
 
   final LogData data;
-  final double maxWidth;
 
   @override
   Widget build(BuildContext context) {
@@ -41,7 +34,6 @@
     final logLevelChip = LogLevelMetadataChip(
       level: logLevel,
       rawLevel: data.level,
-      maxWidth: maxWidth,
       backgroundColor: logLevelColors.background,
       foregroundColor: logLevelColors.foreground,
     );
@@ -53,7 +45,6 @@
       isolateChip = IsolateChip(
         name: isolateName,
         id: data.isolateRef?.id,
-        maxWidth: maxWidth,
         backgroundColor: colorScheme.surface,
         foregroundColor: colorScheme.onSurface,
         outlined: true,
@@ -68,7 +59,6 @@
       zoneChip = ZoneChip(
         name: zoneName,
         identityHashCode: zone!.identityHashCode,
-        maxWidth: maxWidth,
         backgroundColor: colorScheme.surface,
         foregroundColor: colorScheme.onSurface,
         outlined: true,
@@ -96,7 +86,6 @@
       children: [
         KindMetaDataChip(
           kind: data.kind,
-          maxWidth: maxWidth,
           icon: kindIcon.icon,
           iconAsset: kindIcon.iconAsset,
           backgroundColor: kindColors.background,
@@ -105,7 +94,6 @@
         logLevelChip,
         if (elapsedFrameTimeAsString != null)
           FrameElapsedMetaDataChip(
-            maxWidth: maxWidth,
             elapsedTimeDisplay: elapsedFrameTimeAsString,
           ),
         if (isolateChip != null) isolateChip,
@@ -118,7 +106,6 @@
 abstract class MetadataChip extends StatelessWidget {
   const MetadataChip({
     super.key,
-    required this.maxWidth,
     required this.text,
     this.tooltip,
     this.icon,
@@ -129,7 +116,6 @@
     this.includeLeadingMargin = true,
   });
 
-  final double maxWidth;
   final IconData? icon;
   final String? iconAsset;
   final String text;
@@ -156,7 +142,6 @@
     return maybeWrapWithTooltip(
       tooltip: tooltip,
       child: Container(
-        constraints: BoxConstraints(maxWidth: maxWidth),
         decoration: BoxDecoration(
           color: backgroundColor,
           borderRadius: BorderRadius.circular(_borderRadius),
@@ -207,7 +192,6 @@
   const KindMetaDataChip({
     super.key,
     required String kind,
-    required super.maxWidth,
     super.icon,
     super.iconAsset,
     super.backgroundColor,
@@ -251,7 +235,6 @@
 class FrameElapsedMetaDataChip extends MetadataChip {
   const FrameElapsedMetaDataChip({
     super.key,
-    required super.maxWidth,
     required String elapsedTimeDisplay,
   }) : super(icon: Icons.timer, text: elapsedTimeDisplay);
 }
@@ -261,7 +244,6 @@
     super.key,
     required Level level,
     required int rawLevel,
-    required super.maxWidth,
     super.backgroundColor,
     super.foregroundColor,
   }) : super(text: 'Level.${level.name} ($rawLevel)');
@@ -307,7 +289,6 @@
     super.key,
     required String name,
     required String? id,
-    required super.maxWidth,
     super.backgroundColor,
     super.foregroundColor,
     super.outlined = false,
@@ -319,7 +300,6 @@
     super.key,
     required String name,
     required int? identityHashCode,
-    required super.maxWidth,
     super.backgroundColor,
     super.foregroundColor,
     super.outlined = false,
diff --git a/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart b/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart
index 1bf9602..1a4bba4 100644
--- a/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart
+++ b/packages/devtools_app/lib/src/screens/network/network_request_inspector_views.dart
@@ -456,14 +456,8 @@
         label: Expanded(
           child: Text(
             title,
-            // TODO(kenz): use top level overflow parameter if
-            // https://github.com/flutter/flutter/issues/82722 is fixed.
-            // TODO(kenz): add overflow after flutter 2.3.0 is stable. It was
-            // added in commit 65388ee2eeaf0d2cf087eaa4a325e3689020c46a.
-            // style: theme.textTheme.titleMedium.copyWith(
-            //   overflow: TextOverflow.fade,
-            // ),
             style: theme.textTheme.titleMedium,
+            overflow: TextOverflow.ellipsis,
           ),
         ),
         numeric: numeric,
diff --git a/packages/devtools_app/lib/src/screens/network/network_screen.dart b/packages/devtools_app/lib/src/screens/network/network_screen.dart
index ce7e247..7014600 100644
--- a/packages/devtools_app/lib/src/screens/network/network_screen.dart
+++ b/packages/devtools_app/lib/src/screens/network/network_screen.dart
@@ -295,13 +295,11 @@
   Widget build(BuildContext context) {
     return RoundedOutlinedBorder(
       clip: true,
-      // TODO(kenz): use SearchableFlatTable instead.
-      child: FlatTable<NetworkRequest?>(
-        keyFactory: (NetworkRequest? data) => ValueKey<NetworkRequest?>(data),
+      child: SearchableFlatTable<NetworkRequest>(
+        searchController: networkController,
+        keyFactory: (NetworkRequest data) => ValueKey<NetworkRequest>(data),
         data: requests,
         dataKey: 'network-requests',
-        searchMatchesNotifier: searchMatchesNotifier,
-        activeSearchMatchNotifier: activeSearchMatchNotifier,
         autoScrollContent: true,
         columns: columns,
         selectionNotifier: networkController.selectedRequest,
diff --git a/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/timeline_events_controller.dart b/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/timeline_events_controller.dart
index b97cd7d..da8b2b4 100644
--- a/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/timeline_events_controller.dart
+++ b/packages/devtools_app/lib/src/screens/performance/panes/timeline_events/timeline_events_controller.dart
@@ -282,9 +282,7 @@
       // iOS: "io.flutter.1.raster (12651)"
       // Linux, Windows, Dream (g3): "io.flutter.raster (12651)"
       // MacOS: Does not exist
-      // Also look for .gpu here for older versions of Flutter.
-      // TODO(kenz): remove check for .gpu name in April 2021.
-      if (name.contains(rasterThreadSuffix) || name.contains(gpuThreadSuffix)) {
+      if (name.contains(rasterThreadSuffix)) {
         rasterTrackId = id;
       }
 
diff --git a/packages/devtools_app/lib/src/screens/profiler/panes/controls/profiler_screen_controls.dart b/packages/devtools_app/lib/src/screens/profiler/panes/controls/profiler_screen_controls.dart
index 41fdc2d..809eaee 100644
--- a/packages/devtools_app/lib/src/screens/profiler/panes/controls/profiler_screen_controls.dart
+++ b/packages/devtools_app/lib/src/screens/profiler/panes/controls/profiler_screen_controls.dart
@@ -32,24 +32,22 @@
 
   @override
   Widget build(BuildContext context) {
-    // TODO(kenz): use the [OfflineAwareControls] helper widget.
-    return Row(
-      mainAxisAlignment: MainAxisAlignment.spaceBetween,
-      children: [
-        if (offline)
-          Padding(
-            padding: const EdgeInsets.only(right: defaultSpacing),
-            child: ExitOfflineButton(gaScreen: gac.cpuProfiler),
-          )
-        else ...[
-          _PrimaryControls(controller: controller, recording: recording),
-          const SizedBox(width: defaultSpacing),
-          _SecondaryControls(
-            controller: controller,
-            profilerBusy: recording || processing,
-          ),
-        ],
-      ],
+    return OfflineAwareControls(
+      gaScreen: gac.cpuProfiler,
+      controlsBuilder: (offline) {
+        if (offline) return const SizedBox.shrink();
+        return Row(
+          mainAxisAlignment: MainAxisAlignment.spaceBetween,
+          children: [
+            _PrimaryControls(controller: controller, recording: recording),
+            const SizedBox(width: defaultSpacing),
+            _SecondaryControls(
+              controller: controller,
+              profilerBusy: recording || processing,
+            ),
+          ],
+        );
+      },
     );
   }
 }
diff --git a/packages/devtools_app/lib/src/shared/framework/screen.dart b/packages/devtools_app/lib/src/shared/framework/screen.dart
index e664a00..08aaebd 100644
--- a/packages/devtools_app/lib/src/shared/framework/screen.dart
+++ b/packages/devtools_app/lib/src/shared/framework/screen.dart
@@ -19,7 +19,6 @@
 
 final _log = Logger('screen.dart');
 
-// TODO(kenz): use correct assets.
 enum ScreenMetaData {
   home(
     'home',
diff --git a/packages/devtools_app/macos/Flutter/GeneratedPluginRegistrant.swift b/packages/devtools_app/macos/Flutter/GeneratedPluginRegistrant.swift
index b4599a2..4e44bc8 100644
--- a/packages/devtools_app/macos/Flutter/GeneratedPluginRegistrant.swift
+++ b/packages/devtools_app/macos/Flutter/GeneratedPluginRegistrant.swift
@@ -1,6 +1,3 @@
-// Copyright 2025 The Flutter Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
 //
 //  Generated file. Do not edit.
 //
diff --git a/packages/devtools_app/test/legacy_integration_tests/app.dart b/packages/devtools_app/test/legacy_integration_tests/app.dart
deleted file mode 100644
index cb14aa6..0000000
--- a/packages/devtools_app/test/legacy_integration_tests/app.dart
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2019 The Flutter Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
-
-import 'package:devtools_shared/devtools_test_utils.dart';
-import 'package:flutter_test/flutter_test.dart';
-
-import 'integration.dart';
-
-void appTests() {
-  late CliAppFixture appFixture;
-  late BrowserTabInstance tabInstance;
-
-  setUp(() async {
-    appFixture = await CliAppFixture.create(
-      'test/test_infra/fixtures/logging_app.dart',
-    );
-    tabInstance = await browserManager.createNewTab();
-  });
-
-  tearDown(() async {
-    await tabInstance.close();
-    await appFixture.teardown();
-  });
-
-  test('can switch pages', () async {
-    final tools = DevtoolsManager(tabInstance, webBuildFixture.baseUri);
-    await tools.start(appFixture);
-    await tools.switchPage('logging');
-
-    final currentPageId = await tools.currentPageId();
-    expect(currentPageId, 'logging');
-  });
-
-  test('connect dialog displays', () async {
-    // start with no port
-    final baseAppUri = webBuildFixture.baseUri.resolve('index.html');
-    final tools = DevtoolsManager(tabInstance, webBuildFixture.baseUri);
-    await tools.start(
-      appFixture,
-      overrideUri: baseAppUri,
-      waitForConnection: false,
-    );
-
-    final connectDialog = ConnectDialogManager(tools);
-
-    // make sure the connect dialog displays
-    await waitFor(() async => await connectDialog.isVisible());
-
-    // have it connect to a port
-    await connectDialog.connectTo(appFixture.serviceUri);
-
-    // make sure the connect dialog becomes hidden
-    await waitFor(() async => !(await connectDialog.isVisible()));
-  });
-}
-
-class ConnectDialogManager {
-  ConnectDialogManager(this.tools);
-
-  final DevtoolsManager tools;
-
-  Future<bool> isVisible() async {
-    final response = await tools.tabInstance.send('connectDialog.isVisible');
-    return response.result as bool;
-  }
-
-  Future connectTo(Uri uri) async {
-    // We have to convert to String here as this goes over JSON.
-    await tools.tabInstance.send('connectDialog.connectTo', uri.toString());
-  }
-}
diff --git a/packages/devtools_app/test/legacy_integration_tests/debugger.dart b/packages/devtools_app/test/legacy_integration_tests/debugger.dart
deleted file mode 100644
index 420b258..0000000
--- a/packages/devtools_app/test/legacy_integration_tests/debugger.dart
+++ /dev/null
@@ -1,402 +0,0 @@
-// Copyright 2019 The Flutter Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
-
-import 'package:devtools_shared/devtools_test_utils.dart';
-import 'package:flutter_test/flutter_test.dart';
-
-import 'integration.dart';
-
-void debuggingTests() {
-  late CliAppFixture appFixture;
-  late BrowserTabInstance tabInstance;
-
-  setUp(() async {
-    tabInstance = await browserManager.createNewTab();
-  });
-
-  tearDown(() async {
-    await tabInstance.close();
-    await appFixture.teardown();
-  });
-
-  test('lists scripts', () async {
-    appFixture = await CliAppFixture.create(
-      'test/test_infra/fixtures/debugging_app.dart',
-    );
-
-    final tools = DevtoolsManager(tabInstance, webBuildFixture.baseUri);
-    await tools.start(appFixture);
-    await tools.switchPage('debugger');
-
-    final currentPageId = await tools.currentPageId();
-    expect(currentPageId, 'debugger');
-
-    final debuggingManager = DebuggingManager(tools);
-
-    // Allow some time for the scripts view to be populated, as it requires
-    // some isolate events to fire that we have not already waited for.
-    await waitFor(
-      () async => (await debuggingManager.getScripts()).isNotEmpty,
-      timeoutMessage: 'Scripts view was not populated',
-    );
-    final scripts = await debuggingManager.getScripts();
-    expect(scripts, isNotEmpty);
-    expect(scripts, anyElement(endsWith(appFixture.appScriptPath)));
-  });
-
-  test('breakpoints, variables, resume', () async {
-    appFixture = await CliAppFixture.create(
-      'test/test_infra/fixtures/debugging_app.dart',
-    );
-
-    final source = appFixture.scriptSource;
-    final breakpointLines = CliAppFixture.parseBreakpointLines(source);
-
-    final tools = DevtoolsManager(tabInstance, webBuildFixture.baseUri);
-    await tools.start(appFixture);
-    await tools.switchPage('debugger');
-
-    final currentPageId = await tools.currentPageId();
-    expect(currentPageId, 'debugger');
-
-    final debuggingManager = DebuggingManager(tools);
-
-    // clear and verify breakpoints
-    List<String> breakpoints = await debuggingManager.getBreakpoints();
-    expect(breakpoints, isEmpty);
-
-    await delay();
-
-    // set and verify breakpoints
-    for (final line in breakpointLines) {
-      await debuggingManager.addBreakpoint(appFixture.appScriptPath, line);
-    }
-
-    breakpoints = await debuggingManager.getBreakpoints();
-    expect(breakpoints, isNotEmpty);
-
-    // wait for paused state
-    await waitFor(() async => await debuggingManager.getState() == 'paused');
-
-    await delay();
-
-    // verify location
-    expect(
-      await debuggingManager.getLocation(),
-      endsWith('${appFixture.appScriptPath}:${breakpointLines.first}'),
-    );
-
-    // verify stack frame
-    final frames = await debuggingManager.getCallStackFrames();
-    expect(frames.length, greaterThan(2));
-    expect(frames.sublist(0, 2), [
-      'Cat.performAction:debugging_app.dart',
-      'main.run.<anonymous closure>:debugging_app.dart',
-    ]);
-
-    // verify variables
-    expect(
-      await debuggingManager.getVariables(),
-      unorderedEquals(['this:Cat', 'actionStr:catAction!']),
-    );
-
-    // resume
-    await debuggingManager.clearBreakpoints();
-    await debuggingManager.resume();
-
-    await delay();
-
-    // verify state resumed
-    expect(await debuggingManager.getState(), 'running');
-  });
-
-  test('stepping, async step, async frames', () async {
-    appFixture = await CliAppFixture.create(
-      'test/test_infra/fixtures/debugging_app_async.dart',
-    );
-
-    final source = appFixture.scriptSource;
-    final breakpointLine = CliAppFixture.parseBreakpointLines(source).single;
-    final steppingLines = CliAppFixture.parseSteppingLines(source);
-
-    final tools = DevtoolsManager(tabInstance, webBuildFixture.baseUri);
-    await tools.start(appFixture);
-    await tools.switchPage('debugger');
-
-    final currentPageId = await tools.currentPageId();
-    expect(currentPageId, 'debugger');
-
-    final debuggingManager = DebuggingManager(tools);
-
-    // clear and verify breakpoints
-    List<String> breakpoints = await debuggingManager.getBreakpoints();
-    expect(breakpoints, isEmpty);
-
-    await delay();
-
-    // set and verify breakpoint
-    await debuggingManager.addBreakpoint(
-      appFixture.appScriptPath,
-      breakpointLine,
-    );
-
-    breakpoints = await debuggingManager.getBreakpoints();
-    expect(breakpoints, hasLength(1));
-
-    // wait for paused state
-    await waitFor(() async => await debuggingManager.getState() == 'paused');
-
-    await shortDelay();
-
-    // verify location
-    expect(
-      await debuggingManager.getLocation(),
-      endsWith('${appFixture.appScriptPath}:$breakpointLine'),
-    );
-
-    // test stepping
-    for (final stepLine in steppingLines) {
-      // step
-      await debuggingManager.step();
-
-      // wait for paused state
-      await waitFor(() async => await debuggingManager.getState() == 'paused');
-
-      await delay();
-
-      // verify location
-      expect(
-        await debuggingManager.getLocation(),
-        endsWith('${appFixture.appScriptPath}:$stepLine'),
-      );
-    }
-
-    // verify an async stack frame
-    final frames = await debuggingManager.getCallStackFrames();
-    expect(frames.length, greaterThan(4));
-    expect(frames.sublist(0, 4), [
-      'performAction:debugging_app_async.dart',
-      '<async break>',
-      'main.run.<anonymous closure>:debugging_app_async.dart',
-      '<async break>',
-    ]);
-
-    // resume
-    await debuggingManager.clearBreakpoints();
-    await debuggingManager.resume();
-
-    await delay();
-
-    // verify state resumed
-    expect(await debuggingManager.getState(), 'running');
-  });
-
-  test('break on exceptions', () async {
-    appFixture = await CliAppFixture.create(
-      'test/test_infra/fixtures/debugging_app_exception.dart',
-    );
-
-    final source = appFixture.scriptSource;
-    final exceptionLine = CliAppFixture.parseExceptionLines(source).first;
-
-    final tools = DevtoolsManager(tabInstance, webBuildFixture.baseUri);
-    await tools.start(appFixture);
-    await tools.switchPage('debugger');
-
-    final currentPageId = await tools.currentPageId();
-    expect(currentPageId, 'debugger');
-
-    final debuggingManager = DebuggingManager(tools);
-
-    // verify running state
-    expect(await debuggingManager.getState(), 'running');
-
-    // set break on exceptions mode
-    await debuggingManager.setIsolatePauseMode('All');
-
-    // wait for paused state
-    await waitFor(() async => await debuggingManager.getState() == 'paused');
-
-    await delay();
-
-    // verify location
-    expect(
-      await debuggingManager.getLocation(),
-      endsWith('${appFixture.appScriptPath}:$exceptionLine'),
-    );
-
-    // verify locals, including the exception object
-    expect(await debuggingManager.getVariables(), [
-      '<exception>:StateError',
-      'foo:2',
-    ]);
-
-    // resume
-    await debuggingManager.setIsolatePauseMode('Unhandled');
-    await debuggingManager.resume();
-
-    await delay();
-
-    // verify state resumed
-    expect(await debuggingManager.getState(), 'running');
-  });
-
-  test('console output', () async {
-    appFixture = await CliAppFixture.create(
-      'test/test_infra/fixtures/color_console_output_app.dart',
-    );
-
-    final tools = DevtoolsManager(tabInstance, webBuildFixture.baseUri);
-    await tools.start(appFixture);
-    await tools.switchPage('debugger');
-
-    final currentPageId = await tools.currentPageId();
-    expect(currentPageId, 'debugger');
-
-    final debuggingManager = DebuggingManager(tools);
-
-    // This test app must start paused so we don't have race conditions where
-    // we miss some console output that was emitted too early.
-    await waitFor(() async => await debuggingManager.getState() == 'paused');
-    await debuggingManager.resume();
-    expect(await debuggingManager.getState(), 'running');
-
-    // Wait until there is enough console output.
-    await waitFor(
-      () async =>
-          (await debuggingManager.getConsoleContents())!.split('\n').length >=
-          13,
-    );
-    // Verify the console contents.
-    expect(
-      await debuggingManager.getConsoleContents(),
-      startsWith(
-        'starting ansi color app\n'
-        '<span style=\'background-color: rgb(0,0,0);color: rgb(255,255,255)\'>0 <span style=\'color: rgb(0,0,0)\'> </span>0 <span style=\'background-color: rgb(187,0,0);color: rgb(255,255,255)\'>1</span> <span style=\'color: rgb(187,0,0)\'> </span>1 <span style=\'background-color: rgb(0,187,0);color: rgb(255,255,255)\'>2</span> <span style=\'color: rgb(0,187,0)\'> </span>2 <span style=\'background-color: rgb(187,187,0);color: rgb(255,255,255)\'>3</span> <span style=\'color: rgb(187,187,0)\'> </span>3 <span style=\'background-color: rgb(0,0,187);color: rgb(255,255,255)\'>4</span> <span style=\'color: rgb(0,0,187)\'> </span>4 <span style=\'background-color: rgb(187,0,187);color: rgb(255,255,255)\'>5</span> <span style=\'color: rgb(187,0,187)\'> </span>5 <span style=\'background-color: rgb(0,187,187);color: rgb(255,255,255)\'>6</span> <span style=\'color: rgb(0,187,187)\'> </span>6 <span style=\'background-color: rgb(255,255,255);color: rgb(255,255,255)\'>7</span> <span style=\'color: rgb(255,255,255)\'> </span>7 \n'
-        '<span style=\'background-color: rgb(85,85,85);color: rgb(255,255,255)\'>8 <span style=\'color: rgb(85,85,85)\'> </span>8 <span style=\'background-color: rgb(255,85,85);color: rgb(255,255,255)\'>9</span> <span style=\'color: rgb(255,85,85)\'> </span>9 <span style=\'background-color: rgb(0,255,0);color: rgb(255,255,255)\'>1</span>0 <span style=\'color: rgb(0,255,0)\'> </span>10 <span style=\'background-color: rgb(255,255,85);color: rgb(255,255,255)\'>1</span>1 <span style=\'color: rgb(255,255,85)\'> </span>11 <span style=\'background-color: rgb(85,85,255);color: rgb(255,255,255)\'>1</span>2 <span style=\'color: rgb(85,85,255)\'> </span>12 <span style=\'background-color: rgb(255,85,255);color: rgb(255,255,255)\'>1</span>3 <span style=\'color: rgb(255,85,255)\'> </span>13 <span style=\'background-color: rgb(85,255,255);color: rgb(255,255,255)\'>1</span>4 <span style=\'color: rgb(85,255,255)\'> </span>14 <span style=\'background-color: rgb(255,255,255);color: rgb(255,255,255)\'>1</span>5 <span style=\'color: rgb(255,255,255)\'> </span>15 \n'
-        '\n'
-        '<span style=\'background-color: rgb(0,0,0);color: rgb(255,255,255)\'> 16 <span style=\'color: rgb(0,0,0)\'> </span>16 <span style=\'background-color: rgb(0,0,175);color: rgb(255,255,255)\'> </span>19 <span style=\'color: rgb(0,0,175)\'> </span>19 \n'
-        '<span style=\'background-color: rgb(0,175,0);color: rgb(255,255,255)\'> 34 <span style=\'color: rgb(0,175,0)\'> </span>34 <span style=\'background-color: rgb(0,175,175);color: rgb(255,255,255)\'> </span>37 <span style=\'color: rgb(0,175,175)\'> </span>37 \n'
-        '\n'
-        '<span style=\'background-color: rgb(175,0,0);color: rgb(255,255,255)\'> 124 <span style=\'color: rgb(175,0,0)\'> </span>124 <span style=\'background-color: rgb(175,0,175);color: rgb(255,255,255)\'> </span>127 <span style=\'color: rgb(175,0,175)\'> </span>127 \n'
-        '<span style=\'background-color: rgb(175,175,0);color: rgb(255,255,255)\'> 142 <span style=\'color: rgb(175,175,0)\'> </span>142 <span style=\'background-color: rgb(175,175,175);color: rgb(255,255,255)\'> </span>145 <span style=\'color: rgb(175,175,175)\'> </span>145 \n'
-        '\n'
-        '<span style=\'background-color: rgb(8,8,8);color: rgb(255,255,255)\'> 232 <span style=\'color: rgb(8,8,8)\'> </span>232 <span style=\'background-color: rgb(18,18,18);color: rgb(255,255,255)\'> </span>233 <span style=\'color: rgb(18,18,18)\'> </span>233 <span style=\'background-color: rgb(28,28,28);color: rgb(255,255,255)\'> </span>234 <span style=\'color: rgb(28,28,28)\'> </span>234 <span style=\'background-color: rgb(38,38,38);color: rgb(255,255,255)\'> </span>235 <span style=\'color: rgb(38,38,38)\'> </span>235 <span style=\'background-color: rgb(48,48,48);color: rgb(255,255,255)\'> </span>236 <span style=\'color: rgb(48,48,48)\'> </span>236 <span style=\'background-color: rgb(58,58,58);color: rgb(255,255,255)\'> </span>237 <span style=\'color: rgb(58,58,58)\'> </span>237 <span style=\'background-color: rgb(68,68,68);color: rgb(255,255,255)\'> </span>238 <span style=\'color: rgb(68,68,68)\'> </span>238 <span style=\'background-color: rgb(78,78,78);color: rgb(255,255,255)\'> </span>239 <span style=\'color: rgb(78,78,78)\'> </span>239 \n'
-        '<span style=\'background-color: rgb(88,88,88);color: rgb(255,255,255)\'> 240 <span style=\'color: rgb(88,88,88)\'> </span>240 <span style=\'background-color: rgb(98,98,98);color: rgb(255,255,255)\'> </span>241 <span style=\'color: rgb(98,98,98)\'> </span>241 <span style=\'background-color: rgb(108,108,108);color: rgb(255,255,255)\'> </span>242 <span style=\'color: rgb(108,108,108)\'> </span>242 <span style=\'background-color: rgb(118,118,118);color: rgb(255,255,255)\'> </span>243 <span style=\'color: rgb(118,118,118)\'> </span>243 <span style=\'background-color: rgb(128,128,128);color: rgb(255,255,255)\'> </span>244 <span style=\'color: rgb(128,128,128)\'> </span>244 <span style=\'background-color: rgb(138,138,138);color: rgb(255,255,255)\'> </span>245 <span style=\'color: rgb(138,138,138)\'> </span>245 <span style=\'background-color: rgb(148,148,148);color: rgb(255,255,255)\'> </span>246 <span style=\'color: rgb(148,148,148)\'> </span>246 <span style=\'background-color: rgb(158,158,158);color: rgb(255,255,255)\'> </span>247 <span style=\'color: rgb(158,158,158)\'> </span>247 \n'
-        '<span style=\'background-color: rgb(168,168,168);color: rgb(255,255,255)\'> 248 <span style=\'color: rgb(168,168,168)\'> </span>248 <span style=\'background-color: rgb(178,178,178);color: rgb(255,255,255)\'> </span>249 <span style=\'color: rgb(178,178,178)\'> </span>249 <span style=\'background-color: rgb(188,188,188);color: rgb(255,255,255)\'> </span>250 <span style=\'color: rgb(188,188,188)\'> </span>250 <span style=\'background-color: rgb(198,198,198);color: rgb(255,255,255)\'> </span>251 <span style=\'color: rgb(198,198,198)\'> </span>251 <span style=\'background-color: rgb(208,208,208);color: rgb(255,255,255)\'> </span>252 <span style=\'color: rgb(208,208,208)\'> </span>252 <span style=\'background-color: rgb(218,218,218);color: rgb(255,255,255)\'> </span>253 <span style=\'color: rgb(218,218,218)\'> </span>253 <span style=\'background-color: rgb(228,228,228);color: rgb(255,255,255)\'> </span>254 <span style=\'color: rgb(228,228,228)\'> </span>254 <span style=\'background-color: rgb(238,238,238);color: rgb(255,255,255)\'> </span>255 <span style=\'color: rgb(238,238,238)\'> </span>255 \n',
-      ),
-    );
-  });
-
-  test('pause', () async {
-    appFixture = await CliAppFixture.create(
-      'test/test_infra/fixtures/debugging_app.dart',
-    );
-
-    final tools = DevtoolsManager(tabInstance, webBuildFixture.baseUri);
-    await tools.start(appFixture);
-    await tools.switchPage('debugger');
-
-    final currentPageId = await tools.currentPageId();
-    expect(currentPageId, 'debugger');
-
-    final debuggingManager = DebuggingManager(tools);
-
-    // verify running state
-    expect(await debuggingManager.getState(), 'running');
-
-    // pause
-    await debuggingManager.pause();
-
-    // wait for paused state
-    await waitFor(() async => await debuggingManager.getState() == 'paused');
-    expect(await debuggingManager.getState(), 'paused');
-
-    // resume
-    await debuggingManager.resume();
-
-    await delay();
-
-    // verify state resumed
-    expect(await debuggingManager.getState(), 'running');
-  });
-}
-
-class DebuggingManager {
-  DebuggingManager(this.tools);
-
-  final DevtoolsManager tools;
-
-  Future<void> resume() async {
-    await tools.tabInstance.send('debugger.resume');
-  }
-
-  Future<void> pause() async {
-    await tools.tabInstance.send('debugger.pause');
-  }
-
-  Future<void> step() async {
-    await tools.tabInstance.send('debugger.step');
-  }
-
-  Future<String?> getLocation() async {
-    final response = await tools.tabInstance.send('debugger.getLocation');
-    return response.result as String?;
-  }
-
-  Future<List<String>> getVariables() async {
-    final response = await tools.tabInstance.send('debugger.getVariables');
-    final result = response.result as List<Object?>;
-    return result.cast<String>();
-  }
-
-  Future<String?> getState() async {
-    final response = await tools.tabInstance.send('debugger.getState');
-    return response.result as String?;
-  }
-
-  Future<String?> getConsoleContents() async {
-    final response = await tools.tabInstance.send(
-      'debugger.getConsoleContents',
-    );
-    return response.result as String?;
-  }
-
-  Future<void> clearBreakpoints() async {
-    await tools.tabInstance.send('debugger.clearBreakpoints');
-  }
-
-  Future<void> addBreakpoint(String path, int line) async {
-    await tools.tabInstance.send('debugger.addBreakpoint', [path, line]);
-  }
-
-  Future<void> setIsolatePauseMode(String mode) async {
-    await tools.tabInstance.send('debugger.setIsolatePauseMode', mode);
-  }
-
-  Future<List<String>> getBreakpoints() async {
-    final response = await tools.tabInstance.send('debugger.getBreakpoints');
-    final result = response.result as List<Object?>;
-    return result.cast<String>();
-  }
-
-  Future<List<String>> getScripts() async {
-    final response = await tools.tabInstance.send('debugger.getScripts');
-    final result = response.result as List<Object?>;
-    return result.cast<String>();
-  }
-
-  Future<bool> supportsScripts() async {
-    final response = await tools.tabInstance.send('debugger.supportsScripts');
-    return response.result as bool;
-  }
-
-  Future<List<String>> getCallStackFrames() async {
-    final response = await tools.tabInstance.send(
-      'debugger.getCallStackFrames',
-    );
-    final result = response.result as List<Object?>;
-    return result.cast<String>();
-  }
-}
diff --git a/packages/devtools_app/test/legacy_integration_tests/integration.dart b/packages/devtools_app/test/legacy_integration_tests/integration.dart
deleted file mode 100644
index eadfcfb..0000000
--- a/packages/devtools_app/test/legacy_integration_tests/integration.dart
+++ /dev/null
@@ -1,444 +0,0 @@
-// Copyright 2018 The Flutter Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
-
-// ignore_for_file: avoid_print
-
-@TestOn('vm')
-library;
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:devtools_shared/devtools_shared.dart';
-import 'package:devtools_shared/devtools_test_utils.dart';
-import 'package:flutter_test/flutter_test.dart';
-import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'
-    show ConsoleAPIEvent, RemoteObject;
-
-const verboseTesting = false;
-
-late WebBuildFixture webBuildFixture;
-late BrowserManager browserManager;
-
-class DevtoolsManager {
-  DevtoolsManager(this.tabInstance, this.baseUri);
-
-  final BrowserTabInstance tabInstance;
-  final Uri baseUri;
-
-  Future<void> start(
-    AppFixture appFixture, {
-    Uri? overrideUri,
-    bool waitForConnection = true,
-  }) async {
-    final baseAppUri = baseUri.resolve(
-      'index.html?uri=${Uri.encodeQueryComponent(appFixture.serviceUri.toString())}',
-    );
-    await tabInstance.tab.navigate('${overrideUri ?? baseAppUri}');
-
-    // wait for app initialization
-    await Future.wait([
-      waitForConnection
-          ? tabInstance.onEvent.firstWhere(
-            (msg) => msg.event == 'app.devToolsReady',
-          )
-          : Future<void>.value(),
-      tabInstance.getBrowserChannel(),
-    ]);
-  }
-
-  Future<void> switchPage(String page) async {
-    await tabInstance.send('switchPage', page);
-  }
-
-  Future<String?> currentPageId() async {
-    final response = await tabInstance.send('currentPageId');
-    return response.result as String?;
-  }
-}
-
-class BrowserManager {
-  BrowserManager._(this.chromeProcess, this.tab);
-
-  static Future<BrowserManager> create() async {
-    final chrome = Chrome.locate();
-    if (chrome == null) {
-      throw 'unable to locate Chrome';
-    }
-
-    final chromeProcess = await chrome.start();
-    final tab = (await chromeProcess.getFirstTab())!;
-
-    await tab.connect();
-
-    return BrowserManager._(chromeProcess, tab);
-  }
-
-  final ChromeProcess chromeProcess;
-  final ChromeTab tab;
-
-  Future<BrowserTabInstance> createNewTab() async {
-    final targetId = await this.tab.createNewTarget();
-
-    await delay();
-
-    final tab = (await chromeProcess.connectToTabId('localhost', targetId))!;
-    await tab.connect(verbose: true);
-
-    await delay();
-
-    await tab.wipConnection!.target.activateTarget(targetId);
-
-    await delay();
-
-    return BrowserTabInstance(tab);
-  }
-
-  void teardown() {
-    chromeProcess.kill();
-  }
-}
-
-class BrowserTabInstance {
-  BrowserTabInstance(this.tab) {
-    tab.onConsoleAPICalled
-        .where((ConsoleAPIEvent event) => event.type == 'log')
-        .listen((ConsoleAPIEvent event) {
-          if (event.args.isNotEmpty) {
-            final message = event.args.first;
-            final value = '${message.value}';
-            if (value.startsWith('[') && value.endsWith(']')) {
-              try {
-                final msg = jsonDecode(value.substring(1, value.length - 1));
-                if (msg is Map) {
-                  _handleBrowserMessage(msg);
-                }
-              } catch (_) {
-                // ignore
-              }
-            }
-          }
-        });
-  }
-
-  final ChromeTab tab;
-
-  RemoteObject? _remote;
-
-  Future<RemoteObject> getBrowserChannel() async {
-    final start = DateTime.now();
-    final end = start.add(const Duration(seconds: 30));
-
-    while (true) {
-      try {
-        return await _getAppChannelObject();
-      } catch (e) {
-        if (end.isBefore(DateTime.now())) {
-          final duration = DateTime.now().difference(start);
-          print('timeout getting the browser channel object ($duration)');
-          rethrow;
-        }
-      }
-
-      await Future<void>.delayed(const Duration(milliseconds: 25));
-    }
-  }
-
-  Future<RemoteObject> _getAppChannelObject() {
-    return tab.wipConnection!.runtime.evaluate('devtools');
-  }
-
-  int _nextId = 1;
-
-  final _completers = <int, Completer<AppResponse>>{};
-
-  final _eventStream = StreamController<AppEvent>.broadcast();
-
-  Stream<AppEvent> get onEvent => _eventStream.stream;
-
-  Future<AppResponse> send(String method, [Object? params]) async {
-    _remote ??= await _getAppChannelObject();
-
-    final id = _nextId++;
-
-    final completer = Completer<AppResponse>();
-    _completers[id] = completer;
-
-    try {
-      await tab.wipConnection!.runtime.callFunctionOn(
-        "function (method, id, params) { return window['devtools'].send(method, id, params); }",
-        objectId: _remote!.objectId,
-        arguments: <Object?>[method, id, params],
-      );
-
-      return completer.future;
-    } catch (e, st) {
-      _completers.remove(id);
-      completer.completeError(e, st);
-      rethrow;
-    }
-  }
-
-  Future<void> close() async {
-    // In Headless Chrome, we get Inspector.detached when we close the last
-    // target rather than a response.
-    await Future.any(<Future<Object>>[
-      tab.wipConnection!.onNotification.firstWhere(
-        (n) => n.method == 'Inspector.detached',
-      ),
-      tab.wipConnection!.target.closeTarget(tab.wipTab.id),
-    ]);
-  }
-
-  void _handleBrowserMessage(Map<dynamic, dynamic> message) {
-    if (verboseTesting) {
-      print(message);
-    }
-
-    if (message.containsKey('id')) {
-      // handle a response: {id: 1}
-      final response = AppResponse(message);
-      final completer = _completers.remove(response.id)!;
-      if (response.hasError) {
-        completer.completeError(response.error);
-      } else {
-        completer.complete(response);
-      }
-    } else {
-      // handle an event: {event: app.echo, params: foo}
-      _eventStream.add(AppEvent(message));
-    }
-  }
-}
-
-class AppEvent {
-  AppEvent(this.json);
-
-  final Map<dynamic, dynamic> json;
-
-  String? get event => json['event'];
-
-  Object? get params => json['params'];
-
-  @override
-  String toString() => '$event ${params ?? ''}';
-}
-
-class AppResponse {
-  AppResponse(this.json);
-
-  final Map<dynamic, dynamic> json;
-
-  int? get id => json['id'];
-
-  Object? get result => json['result'];
-
-  bool get hasError => json.containsKey('error');
-
-  AppError get error => AppError(json['error']);
-
-  @override
-  String toString() {
-    return hasError ? error.toString() : result.toString();
-  }
-}
-
-class AppError {
-  AppError(this.json);
-
-  final Map<dynamic, dynamic> json;
-
-  String? get message => json['message'];
-
-  String? get stackTrace => json['stackTrace'];
-
-  @override
-  String toString() => '$message\n$stackTrace';
-}
-
-class WebBuildFixture {
-  WebBuildFixture._(this.process, this.url, this.verbose);
-
-  static Future<WebBuildFixture> serve({
-    bool release = false,
-    bool verbose = false,
-  }) async {
-    final cliArgs = <String>[
-      'pub',
-      'run',
-      'build_runner',
-      'serve',
-      'web',
-      '--delete-conflicting-outputs',
-    ];
-    if (release) {
-      cliArgs.add('--release');
-    }
-
-    final process = await _runFlutter(cliArgs);
-
-    final hasUrl = Completer<String>();
-
-    _toLines(process.stderr).listen((String line) {
-      if (verbose || hasUrl.isCompleted) {
-        print(
-          'pub run build_runner serve • ${process.pid}'
-          ' • STDERR • ${line.trim()}',
-        );
-      }
-
-      final err = 'error starting webdev: $line';
-      if (!hasUrl.isCompleted) {
-        hasUrl.completeError(err);
-      } else {
-        print('Ignoring stderr output because already completed');
-      }
-    });
-
-    _toLines(process.stdout).listen((String line) {
-      if (verbose) {
-        print('pub run build_runner serve • ${process.pid} • ${line.trim()}');
-      }
-
-      // Serving `web` on http://localhost:8080
-      if (line.contains('Serving `web`')) {
-        hasUrl.safeComplete(
-          line.substring(line.indexOf('http://')),
-          () => print(
-            'Ignoring "Serving..." notification because already completed',
-          ),
-        );
-      }
-    });
-
-    final url = await hasUrl.future;
-
-    await delay();
-
-    return WebBuildFixture._(process, url, verbose);
-  }
-
-  static Future<void> build({bool verbose = false}) async {
-    final clean = await _runFlutter(['clean']);
-    expect(await clean.exitCode, 0);
-    final pubGet = await _runFlutter(['pub', 'get']);
-    expect(await pubGet.exitCode, 0);
-
-    final cliArgs = <String>[];
-    String commandName;
-    commandName = 'flutter build web';
-    cliArgs.addAll([
-      'build',
-      'web',
-      '--pwa-strategy=none',
-      '--dart-define=FLUTTER_WEB_USE_SKIA=true',
-      '--no-tree-shake-icons',
-    ]);
-
-    final process = await _runFlutter(cliArgs, verbose: verbose);
-
-    final buildFinished = Completer<void>();
-
-    _toLines(process.stderr).listen((String line) {
-      // TODO(https://github.com/flutter/devtools/issues/2477): this is a
-      // work around for an expected warning that would otherwise fail the test.
-      if (line.toLowerCase().contains('warning')) {
-        return;
-      }
-      if (line.toLowerCase().contains(' from path ../devtools_')) {
-        return;
-      }
-
-      final err = 'error building flutter: $line';
-      if (!buildFinished.isCompleted) {
-        buildFinished.completeError(err);
-      } else {
-        print(err);
-      }
-    });
-
-    _toLines(process.stdout).listen((String line) {
-      if (verbose) {
-        print('$commandName • ${line.trim()}');
-      }
-
-      if (!buildFinished.isCompleted) {
-        if (line.contains('[INFO] Succeeded')) {
-          buildFinished.complete();
-        } else if (line.contains('[SEVERE]')) {
-          buildFinished.completeError(line);
-        }
-      }
-    });
-
-    unawaited(
-      process.exitCode.then((code) {
-        if (!buildFinished.isCompleted) {
-          if (code == 0) {
-            buildFinished.complete();
-          } else {
-            buildFinished.completeError('Exited with code $code');
-          }
-        }
-      }),
-    );
-
-    await buildFinished.future.catchError((Object? e) {
-      fail('Build failed: $e');
-    });
-
-    await process.exitCode;
-  }
-
-  final Process process;
-  final String url;
-  final bool verbose;
-
-  Uri get baseUri => Uri.parse(url);
-
-  Future<void> teardown() async {
-    process.kill();
-    final exitCode = await process.exitCode;
-    if (verbose) {
-      print('flutter exited with code $exitCode');
-    }
-  }
-
-  static Future<Process> _runFlutter(
-    List<String> buildArgs, {
-    bool verbose = false,
-  }) {
-    // Remove the DART_VM_OPTIONS env variable from the child process, so the
-    // Dart VM doesn't try and open a service protocol port if
-    // 'DART_VM_OPTIONS: --enable-vm-service:63990' was passed in.
-    final environment = Map<String, String>.from(Platform.environment);
-    if (environment.containsKey('DART_VM_OPTIONS')) {
-      environment['DART_VM_OPTIONS'] = '';
-    }
-
-    // TODO(https://github.com/flutter/devtools/issues/1145): The pub-based
-    // version of this code would run a pub snapshot instead of starting pub
-    // directly to prevent Windows-based test runs getting killed but leaving
-    // the pub process behind. Something similar might be needed here.
-    // See here for more information:
-    // https://github.com/flutter/flutter/blob/master/docs/tool/README.md#debugging-the-flutter-command-line-tool
-    final executable = Platform.isWindows ? 'flutter.bat' : 'flutter';
-
-    if (verbose) {
-      print(
-        'Running "$executable" with args: ${buildArgs.join(' ')} from ${Directory.current.path}',
-      );
-    }
-    return Process.start(
-      executable,
-      buildArgs,
-      environment: environment,
-      workingDirectory: Directory.current.path,
-    );
-  }
-
-  static Stream<String> _toLines(Stream<List<int>> stream) =>
-      stream.transform(utf8.decoder).transform(const LineSplitter());
-}
diff --git a/packages/devtools_app/test/legacy_integration_tests/integration_test.dart b/packages/devtools_app/test/legacy_integration_tests/integration_test.dart
deleted file mode 100644
index 10b791d..0000000
--- a/packages/devtools_app/test/legacy_integration_tests/integration_test.dart
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2018 The Flutter Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
-
-@TestOn('vm')
-library;
-
-import 'dart:io';
-
-import 'package:flutter_test/flutter_test.dart';
-
-import 'app.dart';
-import 'debugger.dart';
-import 'integration.dart';
-import 'logging.dart';
-
-void main() {
-  group('integration', () {
-    // TODO(#1965): fix and re-enable integration tests.
-    // ignore: dead_code
-    if (false) {
-      setUpAll(() async {
-        final testInReleaseMode =
-            Platform.environment['WEBDEV_RELEASE'] == 'true';
-
-        webBuildFixture = await WebBuildFixture.serve(
-          release: testInReleaseMode,
-          verbose: true,
-        );
-        browserManager = await BrowserManager.create();
-      });
-
-      tearDownAll(() async {
-        browserManager.teardown();
-        await webBuildFixture.teardown();
-      });
-
-      group('app', appTests, skip: true);
-      group('logging', loggingTests, skip: true);
-      // Temporarily skip tests. See https://github.com/flutter/devtools/issues/1343.
-      group('debugging', debuggingTests, skip: true);
-    }
-  });
-}
diff --git a/packages/devtools_app/test/legacy_integration_tests/logging.dart b/packages/devtools_app/test/legacy_integration_tests/logging.dart
deleted file mode 100644
index 39d0eb5..0000000
--- a/packages/devtools_app/test/legacy_integration_tests/logging.dart
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2019 The Flutter Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
-
-import 'package:devtools_shared/devtools_test_utils.dart';
-import 'package:flutter_test/flutter_test.dart';
-
-import 'integration.dart';
-
-void loggingTests() {
-  late CliAppFixture appFixture;
-  late BrowserTabInstance tabInstance;
-
-  setUp(() async {
-    appFixture = await CliAppFixture.create(
-      'test/test_infra/fixtures/logging_app.dart',
-    );
-    tabInstance = await browserManager.createNewTab();
-  });
-
-  tearDown(() async {
-    await tabInstance.close();
-    await appFixture.teardown();
-  });
-
-  test('displays log data', () async {
-    final tools = DevtoolsManager(tabInstance, webBuildFixture.baseUri);
-    await tools.start(appFixture);
-    await tools.switchPage('logging');
-
-    final currentPageId = await tools.currentPageId();
-    expect(currentPageId, 'logging');
-
-    // Cause app to log.
-    final logs = LoggingManager(tools);
-    await logs.clearLogs();
-    expect(await logs.logCount(), 0);
-    await appFixture.invoke('controller.emitLog()');
-
-    // Verify the log data shows up in the UI.
-    await waitFor(() async => (await logs.logCount()) > 0);
-    expect(await logs.logCount(), greaterThan(0));
-  });
-
-  test('log screen postpones write when offscreen', () async {
-    final tools = DevtoolsManager(tabInstance, webBuildFixture.baseUri);
-    await tools.start(appFixture);
-    await tools.switchPage('logging');
-
-    final currentPageId = await tools.currentPageId();
-    expect(currentPageId, 'logging');
-
-    final logs = LoggingManager(tools);
-
-    // Verify that the log is empty.
-    expect(await logs.logCount(), 0);
-
-    // Switch to a different page.
-    await tools.switchPage('performance');
-
-    // Cause app to log.
-    await appFixture.invoke('controller.emitLog()');
-
-    // Verify that the log is empty.
-    expect(await logs.logCount(), 0);
-
-    // Switch to the logs page.
-    await tools.switchPage('logging');
-
-    // Verify the log data shows up in the UI.
-    await waitFor(() async => (await logs.logCount()) > 0);
-    expect(await logs.logCount(), greaterThan(0));
-  });
-}
-
-class LoggingManager {
-  LoggingManager(this.tools);
-
-  final DevtoolsManager tools;
-
-  Future<void> clearLogs() async {
-    await tools.tabInstance.send('logging.clearLogs');
-  }
-
-  Future<int> logCount() async {
-    final response = await tools.tabInstance.send('logging.logCount');
-    return response.result as int;
-  }
-}
diff --git a/packages/devtools_app/test/legacy_integration_tests/readme.md b/packages/devtools_app/test/legacy_integration_tests/readme.md
deleted file mode 100644
index f2e1f5a..0000000
--- a/packages/devtools_app/test/legacy_integration_tests/readme.md
+++ /dev/null
@@ -1,30 +0,0 @@
-<!--
-Copyright 2025 The Flutter Authors
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
--->
-## plan for integration tests
-
-Integration tests are expected to be heavyweight and test broad areas of a
-use case. We likely wouldn't have more than 1-2 dozen of them.
-
-### startup
-
-- start a Dart VM or a Flutter app on a sample app
-- connect to it via a service protocol connection
-- start a chrome process
-- connect to it via a chrome debug protocol connection
-- start a web serve serving a debug build of the devtools app
-- switch the chrome tab page to the devtools app w/ the port of the running dart/flutter app
-- wait for app initialization
-
-### testing
-- interact with devtools by invoking methods on objects registered globally
-- verify expected behavior by invoking methods, or listening to events written
-  to the browser's console
-
-### teardown
-
-- tear down chrome
-- tear down the web server
-- tear down the running Dart/Flutter app
diff --git a/packages/devtools_app/test/screens/logging/metadata_test.dart b/packages/devtools_app/test/screens/logging/metadata_test.dart
index 2fa6dcd..55b9f82 100644
--- a/packages/devtools_app/test/screens/logging/metadata_test.dart
+++ b/packages/devtools_app/test/screens/logging/metadata_test.dart
@@ -97,7 +97,7 @@
                   return Flexible(
                     child: Padding(
                       padding: const EdgeInsets.all(8.0),
-                      child: MetadataChips(data: log, maxWidth: 1000.0),
+                      child: MetadataChips(data: log),
                     ),
                   );
                 }).toList(),
diff --git a/packages/devtools_app/web/index.html b/packages/devtools_app/web/index.html
index 060532d..55fd1e0 100644
--- a/packages/devtools_app/web/index.html
+++ b/packages/devtools_app/web/index.html
@@ -55,7 +55,6 @@
     }
   </script>
 
-  <!-- TODO(elliette): Remove once https://github.com/flutter/flutter/issues/122541 is fixed. -->
   <link rel="stylesheet" href="styles.css">
 
 </head>
diff --git a/packages/devtools_app/web/styles.css b/packages/devtools_app/web/styles.css
index 513160a..909f566 100644
--- a/packages/devtools_app/web/styles.css
+++ b/packages/devtools_app/web/styles.css
@@ -3,11 +3,6 @@
 Use of this source code is governed by a BSD-style license that can be
 found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
 **/
-@media (-webkit-max-device-pixel-ratio: 1) {
-  * {
-    image-rendering: pixelated;
-  }
-}
 
 body {
   overscroll-behavior-x: none;
diff --git a/packages/devtools_app_shared/lib/src/ui/theme/theme.dart b/packages/devtools_app_shared/lib/src/ui/theme/theme.dart
index 9ddfbde..f200402 100644
--- a/packages/devtools_app_shared/lib/src/ui/theme/theme.dart
+++ b/packages/devtools_app_shared/lib/src/ui/theme/theme.dart
@@ -2,9 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
 
-// TODO(kenz): remove once min flutter version of devtools_app_shared >= 3.25
-// ignore_for_file: deprecated_member_use, analysis performed with newer flutter version than min sdk
-
 import 'package:flutter/material.dart';
 
 import '../ui_utils.dart';
@@ -231,9 +228,10 @@
 );
 
 const searchMatchColor = Colors.yellow;
-final searchMatchColorOpaque = Colors.yellow.withOpacity(0.5);
+final searchMatchColorOpaque = Colors.yellow.withValues(alpha: 255 / 2);
 const activeSearchMatchColor = Colors.orangeAccent;
-final activeSearchMatchColorOpaque = Colors.orangeAccent.withOpacity(0.5);
+final activeSearchMatchColorOpaque =
+    Colors.orangeAccent.withValues(alpha: 255 / 2);
 
 /// Gets an alternating color to use for indexed UI elements.
 Color alternatingColorForIndex(int index, ColorScheme colorScheme) {
diff --git a/packages/devtools_app_shared/lib/src/utils/utils.dart b/packages/devtools_app_shared/lib/src/utils/utils.dart
index 62d7e27..df6db61 100644
--- a/packages/devtools_app_shared/lib/src/utils/utils.dart
+++ b/packages/devtools_app_shared/lib/src/utils/utils.dart
@@ -2,9 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd.
 
-// TODO(kenz): remove once min flutter version of devtools_app_shared >= 3.25
-// ignore_for_file: deprecated_member_use, analysis performed with newer flutter version than min sdk
-
 import 'dart:async';
 import 'dart:math';
 
@@ -119,8 +116,9 @@
   // In CSS Hex, Alpha comes last, but in Flutter's `value` field, alpha is
   // in the high bytes, so just using `value.toRadixString(16)` will put alpha
   // in the wrong position.
-  String hex(int val) => val.toRadixString(16).padLeft(2, '0');
-  return '#${hex(color.red)}${hex(color.green)}${hex(color.blue)}${hex(color.alpha)}';
+  String hex(double channelValue) =>
+      (channelValue * 255).round().toRadixString(16).padLeft(2, '0');
+  return '#${hex(color.r)}${hex(color.g)}${hex(color.b)}${hex(color.a)}';
 }
 
 extension StringUtilities on String {