[flutter_tools] force page refresh when hot restarting in profile/release mode (#50215)

diff --git a/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart b/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart
index 931a1cb..b85e081 100644
--- a/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart
+++ b/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart
@@ -453,8 +453,12 @@
       .join(',');
 
     try {
-      if (fullRestart) {
-        await _wipConnection?.sendCommand('Page.reload');
+      if (fullRestart || !debuggingOptions.buildInfo.isDebug) {
+        // On non-debug builds, a hard refresh is required to ensure the
+        // up to date sources are loaded.
+        await _wipConnection?.sendCommand('Page.reload', <String, Object>{
+          'ignoreCache': !debuggingOptions.buildInfo.isDebug,
+        });
       } else {
         await _wipConnection?.debugger
             ?.sendCommand('Runtime.evaluate', params: <String, Object>{
@@ -808,10 +812,15 @@
           return chromeTab.url.contains(debuggingOptions.hostname);
         });
         final WipConnection wipConnection = await chromeTab.connect();
-        await wipConnection.sendCommand('Page.reload');
+        // On non-debug builds, a hard refresh is required to ensure the
+        // up to date sources are loaded.
+        await wipConnection?.sendCommand('Page.reload', <String, Object>{
+          'ignoreCache': !debuggingOptions.buildInfo.isDebug,
+        });
         status.stop();
         return OperationResult.ok;
       } catch (err) {
+        globals.printTrace(err.toString());
         // Ignore error and continue with posted message;
       }
     }
diff --git a/packages/flutter_tools/test/general.shard/resident_web_runner_cold_test.dart b/packages/flutter_tools/test/general.shard/resident_web_runner_cold_test.dart
index 0c15839..ae8f1d5 100644
--- a/packages/flutter_tools/test/general.shard/resident_web_runner_cold_test.dart
+++ b/packages/flutter_tools/test/general.shard/resident_web_runner_cold_test.dart
@@ -16,10 +16,13 @@
 import 'package:flutter_tools/src/resident_runner.dart';
 import 'package:flutter_tools/src/build_runner/resident_web_runner.dart';
 import 'package:flutter_tools/src/build_runner/web_fs.dart';
+import 'package:flutter_tools/src/web/chrome.dart';
+import 'package:flutter_tools/src/web/web_device.dart';
 import 'package:meta/meta.dart';
 import 'package:mockito/mockito.dart';
 import 'package:platform/platform.dart';
 import 'package:vm_service/vm_service.dart';
+import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';
 
 import '../src/common.dart';
 import '../src/testbed.dart';
@@ -126,6 +129,38 @@
     expect(result.message, contains('Failed to recompile application.'));
   }));
 
+  test('Correctly performs a full refresh on attached chrome device.', () => testbed.run(() async {
+    _setupMocks();
+    final MockChromeDevice chromeDevice = MockChromeDevice();
+    final MockChrome chrome = MockChrome();
+    final MockChromeConnection mockChromeConnection = MockChromeConnection();
+    final MockChromeTab mockChromeTab = MockChromeTab();
+    final MockWipConnection mockWipConnection = MockWipConnection();
+    when(mockChromeConnection.getTab(any)).thenAnswer((Invocation invocation) async {
+      return mockChromeTab;
+    });
+    when(mockChromeTab.connect()).thenAnswer((Invocation invocation) async {
+      return mockWipConnection;
+    });
+    when(chrome.chromeConnection).thenReturn(mockChromeConnection);
+    launchChromeInstance(chrome);
+    when(mockFlutterDevice.device).thenReturn(chromeDevice);
+    final Completer<DebugConnectionInfo> connectionInfoCompleter = Completer<DebugConnectionInfo>();
+    unawaited(residentWebRunner.run(
+      connectionInfoCompleter: connectionInfoCompleter,
+    ));
+    await connectionInfoCompleter.future;
+    when(mockWebFs.recompile()).thenAnswer((Invocation _) async {
+      return true;
+    });
+    final OperationResult result = await residentWebRunner.restart(fullRestart: true);
+
+    expect(result.code, 0);
+    verify(mockWipConnection.sendCommand('Page.reload', <String, Object>{
+      'ignoreCache': true,
+    })).called(1);
+  }));
+
 }
 
 class MockWebDevice extends Mock implements Device {}
@@ -135,3 +170,8 @@
 class MockVmService extends Mock implements VmService {}
 class MockStatus extends Mock implements Status {}
 class MockFlutterDevice extends Mock implements FlutterDevice {}
+class MockChromeDevice extends Mock implements ChromeDevice {}
+class MockChrome extends Mock implements Chrome {}
+class MockChromeConnection extends Mock implements ChromeConnection {}
+class MockChromeTab extends Mock implements ChromeTab {}
+class MockWipConnection extends Mock implements WipConnection {}