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 931a1cbe25..b85e081492 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 @@ class _ExperimentalResidentWebRunner extends ResidentWebRunner { .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', { + 'ignoreCache': !debuggingOptions.buildInfo.isDebug, + }); } else { await _wipConnection?.debugger ?.sendCommand('Runtime.evaluate', params: { @@ -808,10 +812,15 @@ class _DwdsResidentWebRunner extends ResidentWebRunner { 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', { + '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 0c1583910f..ae8f1d5c4c 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/project.dart'; 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 @@ void main() { 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 connectionInfoCompleter = Completer(); + 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', { + 'ignoreCache': true, + })).called(1); + })); + } class MockWebDevice extends Mock implements Device {} @@ -135,3 +170,8 @@ class MockDebugConnection extends Mock implements DebugConnection {} 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 {}