6
6
library ;
7
7
8
8
import 'dart:async' ;
9
- import 'dart:io' as io;
10
9
11
10
import 'package:file/file.dart' ;
12
- import 'package:flutter_tools/src/web/chrome.dart' ;
13
- import 'package:flutter_tools/src/web/web_device.dart' show WebServerDevice;
14
11
15
12
import '../src/common.dart' ;
16
13
import 'test_data/hot_reload_project.dart' ;
14
+ import 'test_data/websocket_dwds_test_common.dart' ;
17
15
import 'test_driver.dart' ;
18
16
import 'test_utils.dart' ;
19
17
import 'transition_test_utils.dart' ;
@@ -26,8 +24,6 @@ void testAll({List<String> additionalCommandArgs = const <String>[]}) {
26
24
group ('WebSocket DWDS connection'
27
25
'${additionalCommandArgs .isEmpty ? '' : ' with args: $additionalCommandArgs ' }' , () {
28
26
// Test configuration constants
29
- const debugUrlTimeout = Duration (seconds: 20 );
30
- const appStartTimeout = Duration (seconds: 15 );
31
27
const hotReloadTimeout = Duration (seconds: 10 );
32
28
33
29
late Directory tempDir;
@@ -48,62 +44,17 @@ void testAll({List<String> additionalCommandArgs = const <String>[]}) {
48
44
testWithoutContext (
49
45
'hot reload with headless Chrome WebSocket connection' ,
50
46
() async {
51
- debugPrint ('Starting WebSocket DWDS test with headless Chrome...' );
52
-
53
- // Set up listening for app output before starting
54
- final stdout = StringBuffer ();
55
- final sawDebugUrl = Completer <String >();
56
- final StreamSubscription <String > subscription = flutter.stdout.listen ((String e) {
57
- stdout.writeln (e);
58
- // Extract the debug connection URL
59
- if (e.contains ('Waiting for connection from Dart debug extension at http://' )) {
60
- final debugUrlPattern = RegExp (
61
- r'Waiting for connection from Dart debug extension at (http://[^\s]+)' ,
62
- );
63
- final Match ? match = debugUrlPattern.firstMatch (e);
64
- if (match != null && ! sawDebugUrl.isCompleted) {
65
- sawDebugUrl.complete (match.group (1 )! );
66
- }
67
- }
68
- });
69
-
70
- io.Process ? chromeProcess;
71
- try {
72
- // Step 1: Start Flutter app with web-server device (will wait for debug connection)
73
- debugPrint ('Step 1: Starting Flutter app with web-server device...' );
74
- // Start the app but don't wait for it to complete - it won't complete until Chrome connects
75
- final Future <void > appStartFuture = runFlutterWithWebServerDevice (
76
- flutter,
77
- additionalCommandArgs: [...additionalCommandArgs, '--no-web-resources-cdn' ],
78
- );
47
+ debugPrint ('Starting WebSocket DWDS test with headless Chrome for hot reload...' );
79
48
80
- // Step 2: Wait for DWDS debug URL to be available
81
- debugPrint ('Step 2: Waiting for DWDS debug service URL...' );
82
- final String debugUrl = await sawDebugUrl.future.timeout (
83
- debugUrlTimeout,
84
- onTimeout: () {
85
- throw Exception ('DWDS debug URL not found - app may not have started correctly' );
86
- },
87
- );
88
- debugPrint ('✓ DWDS debug service available at: $debugUrl ' );
89
-
90
- // Step 3: Launch headless Chrome to connect to DWDS
91
- debugPrint ('Step 3: Launching headless Chrome to connect to DWDS...' );
92
- chromeProcess = await _launchHeadlessChrome (debugUrl);
93
- debugPrint ('✓ Headless Chrome launched and connecting to DWDS' );
94
-
95
- // Step 4: Wait for app to start (Chrome connection established)
96
- debugPrint ('Step 4: Waiting for Flutter app to start after Chrome connection...' );
97
- await appStartFuture.timeout (
98
- appStartTimeout,
99
- onTimeout: () {
100
- throw Exception ('App startup did not complete after Chrome connection' );
101
- },
102
- );
103
- debugPrint ('✓ Flutter app started successfully with WebSocket connection' );
49
+ // Set up WebSocket connection
50
+ final WebSocketDwdsTestSetup setup = await WebSocketDwdsTestUtils .setupWebSocketConnection (
51
+ flutter,
52
+ additionalCommandArgs: additionalCommandArgs,
53
+ );
104
54
105
- // Step 5: Test hot reload functionality
106
- debugPrint ('Step 5: Testing hot reload with WebSocket connection...' );
55
+ try {
56
+ // Test hot reload functionality
57
+ debugPrint ('Step 6: Testing hot reload with WebSocket connection...' );
107
58
await flutter.hotReload ().timeout (
108
59
hotReloadTimeout,
109
60
onTimeout: () {
@@ -114,80 +65,20 @@ void testAll({List<String> additionalCommandArgs = const <String>[]}) {
114
65
// Give some time for logs to capture
115
66
await Future <void >.delayed (const Duration (seconds: 2 ));
116
67
117
- final output = stdout.toString ();
68
+ final output = setup. stdout.toString ();
118
69
expect (output, contains ('Reloaded' ), reason: 'Hot reload should complete successfully' );
119
70
debugPrint ('✓ Hot reload completed successfully with WebSocket connection' );
120
71
121
72
// Verify the correct infrastructure was used
122
- expect (
123
- output,
124
- contains ('Waiting for connection from Dart debug extension' ),
125
- reason: 'Should wait for debug connection (WebSocket infrastructure)' ,
126
- );
127
- expect (output, contains ('web-server' ), reason: 'Should use web-server device' );
73
+ WebSocketDwdsTestUtils .verifyWebSocketInfrastructure (output);
128
74
129
75
debugPrint ('✓ WebSocket DWDS test completed successfully' );
130
76
debugPrint ('✓ Verified: web-server device + DWDS + WebSocket connection + hot reload' );
131
77
} finally {
132
- await _cleanupResources ( chromeProcess, subscription);
78
+ await cleanupWebSocketTestResources (setup. chromeProcess, setup. subscription);
133
79
}
134
80
},
135
81
skip: ! platform.isMacOS, // Skip on non-macOS platforms where Chrome paths may differ
136
82
);
137
83
});
138
84
}
139
-
140
- /// Launches headless Chrome with the given debug URL.
141
- /// Uses findChromeExecutable to locate Chrome on the current platform.
142
- Future <io.Process > _launchHeadlessChrome (String debugUrl) async {
143
- const chromeArgs = [
144
- '--headless' ,
145
- '--disable-gpu' ,
146
- '--no-sandbox' ,
147
- '--disable-extensions' ,
148
- '--disable-dev-shm-usage' ,
149
- '--remote-debugging-port=0' ,
150
- ];
151
-
152
- final String chromePath = findChromeExecutable (platform, fileSystem);
153
-
154
- try {
155
- return await io.Process .start (chromePath, [...chromeArgs, debugUrl]);
156
- } on Exception catch (e) {
157
- throw Exception (
158
- 'Could not launch Chrome at $chromePath : $e . Please ensure Chrome is installed.' ,
159
- );
160
- }
161
- }
162
-
163
- /// Cleans up test resources (Chrome process and stdout subscription).
164
- Future <void > _cleanupResources (
165
- io.Process ? chromeProcess,
166
- StreamSubscription <String > subscription,
167
- ) async {
168
- if (chromeProcess != null ) {
169
- try {
170
- chromeProcess.kill ();
171
- await chromeProcess.exitCode;
172
- debugPrint ('Chrome process cleaned up' );
173
- } on Exception catch (e) {
174
- debugPrint ('Warning: Failed to clean up Chrome process: $e ' );
175
- }
176
- }
177
- await subscription.cancel ();
178
- }
179
-
180
- // Helper to run flutter with web-server device using WebSocket connection.
181
- Future <void > runFlutterWithWebServerDevice (
182
- FlutterRunTestDriver flutter, {
183
- bool verbose = false ,
184
- bool withDebugger = true , // Enable debugger by default for WebSocket connection
185
- bool startPaused = false , // Don't start paused for this test
186
- List <String > additionalCommandArgs = const < String > [],
187
- }) => flutter.run (
188
- verbose: verbose,
189
- withDebugger: withDebugger, // Enable debugger to establish WebSocket connection
190
- startPaused: startPaused, // Let the app start normally after debugger connects
191
- device: WebServerDevice .kWebServerDeviceId,
192
- additionalCommandArgs: additionalCommandArgs,
193
- );
0 commit comments