7
7
@Timeout (Duration (minutes: 5 ))
8
8
library ;
9
9
10
+ import 'dart:async' ;
11
+
10
12
import 'package:dwds/dwds.dart' ;
11
13
import 'package:dwds/expression_compiler.dart' ;
12
14
import 'package:test/test.dart' ;
@@ -32,26 +34,54 @@ void runTests({
32
34
33
35
tearDownAll (provider.dispose);
34
36
35
- Future <void > makeEditAndRecompile () async {
36
- context.makeEditToDartEntryFile (
37
- toReplace: originalString,
38
- replaceWith: newString,
39
- );
37
+ Future <void > recompile ({bool hasEdits = false }) async {
40
38
if (compilationMode == CompilationMode .frontendServer) {
41
39
await context.recompile (fullRestart: true );
42
40
} else {
43
41
assert (compilationMode == CompilationMode .buildDaemon);
44
- await context.waitForSuccessfulBuild (propagateToBrowser: true );
42
+ if (hasEdits) {
43
+ // Only gets a new build if there were edits.
44
+ await context.waitForSuccessfulBuild (propagateToBrowser: true );
45
+ }
45
46
}
46
47
}
47
48
49
+ Future <void > makeEditAndRecompile () async {
50
+ context.makeEditToDartEntryFile (
51
+ toReplace: originalString,
52
+ replaceWith: newString,
53
+ );
54
+ await recompile (hasEdits: true );
55
+ }
56
+
48
57
void undoEdit () {
49
58
context.makeEditToDartEntryFile (
50
59
toReplace: newString,
51
60
replaceWith: originalString,
52
61
);
53
62
}
54
63
64
+ /// Wait for main to finish executing before checking expectations by checking
65
+ /// for a log output.
66
+ ///
67
+ /// If [debuggingEnabled] is false, we can't check for Chrome logs and instead
68
+ /// wait 1 second.
69
+ // TODO(srujzs): We should do something less prone to race conditions when
70
+ // debugging is disabled.
71
+ Future <void > waitForMainToExecute ({bool debuggingEnabled = true }) async {
72
+ if (! debuggingEnabled) return Future .delayed (const Duration (seconds: 1 ));
73
+ final completer = Completer <void >();
74
+ final expectedString = 'main executed' ;
75
+ final subscription = context.webkitDebugger.onConsoleAPICalled.listen ((e) {
76
+ if (e.args.first.value == expectedString) {
77
+ completer.complete ();
78
+ }
79
+ });
80
+ await completer.future.then ((_) {
81
+ subscription.cancel ();
82
+ });
83
+ }
84
+
55
85
group (
56
86
'Injected client with live reload' ,
57
87
() {
@@ -74,7 +104,9 @@ void runTests({
74
104
});
75
105
76
106
test ('can live reload changes ' , () async {
107
+ final mainDone = waitForMainToExecute ();
77
108
await makeEditAndRecompile ();
109
+ await mainDone;
78
110
final source = await context.webDriver.pageSource;
79
111
80
112
// A full reload should clear the state.
@@ -105,8 +137,9 @@ void runTests({
105
137
});
106
138
107
139
test ('can live reload changes ' , () async {
140
+ final mainDone = waitForMainToExecute (debuggingEnabled: false );
108
141
await makeEditAndRecompile ();
109
-
142
+ await mainDone;
110
143
final source = await context.webDriver.pageSource;
111
144
112
145
// A full reload should clear the state.
@@ -138,8 +171,9 @@ void runTests({
138
171
});
139
172
140
173
test ('can live reload changes ' , () async {
174
+ final mainDone = waitForMainToExecute (debuggingEnabled: false );
141
175
await makeEditAndRecompile ();
142
-
176
+ await mainDone;
143
177
final source = await context.webDriver.pageSource;
144
178
145
179
// A full reload should clear the state.
@@ -281,13 +315,15 @@ void runTests({
281
315
]),
282
316
),
283
317
);
318
+ final mainDone = waitForMainToExecute ();
284
319
final hotRestart = context.getRegisteredServiceExtension ('hotRestart' );
285
320
expect (
286
321
await fakeClient.callServiceExtension (hotRestart! ),
287
322
const TypeMatcher <Success >(),
288
323
);
289
324
290
325
await eventsDone;
326
+ await mainDone;
291
327
292
328
final source = await context.webDriver.pageSource;
293
329
// Main is re-invoked which shouldn't clear the state.
@@ -324,6 +360,8 @@ void runTests({
324
360
"registerExtension('ext.foo', $callback )" ,
325
361
);
326
362
363
+ await recompile ();
364
+ final mainDone = waitForMainToExecute ();
327
365
final hotRestart = context.getRegisteredServiceExtension ('hotRestart' );
328
366
expect (
329
367
await fakeClient.callServiceExtension (hotRestart! ),
@@ -342,6 +380,7 @@ void runTests({
342
380
);
343
381
344
382
await eventsDone;
383
+ await mainDone;
345
384
346
385
final source = await context.webDriver.pageSource;
347
386
// Main is re-invoked which shouldn't clear the state.
@@ -363,14 +402,15 @@ void runTests({
363
402
]),
364
403
),
365
404
);
366
-
405
+ final mainDone = waitForMainToExecute ();
367
406
final fullReload = context.getRegisteredServiceExtension ('fullReload' );
368
407
expect (
369
408
await fakeClient.callServiceExtension (fullReload! ),
370
409
isA <Success >(),
371
410
);
372
411
373
412
await eventsDone;
413
+ await mainDone;
374
414
375
415
final source = await context.webDriver.pageSource;
376
416
// Should see only the new text
@@ -399,8 +439,12 @@ void runTests({
399
439
);
400
440
401
441
await makeEditAndRecompile ();
442
+ final mainDone = waitForMainToExecute ();
402
443
final hotRestart = context.getRegisteredServiceExtension ('hotRestart' );
403
444
await fakeClient.callServiceExtension (hotRestart! );
445
+
446
+ await mainDone;
447
+
404
448
final source = await context.webDriver.pageSource;
405
449
406
450
// Main is re-invoked which shouldn't clear the state.
@@ -418,6 +462,7 @@ void runTests({
418
462
test ('can evaluate expressions after hot restart' , () async {
419
463
final client = context.debugConnection.vmService;
420
464
465
+ await recompile ();
421
466
final hotRestart = context.getRegisteredServiceExtension ('hotRestart' );
422
467
await fakeClient.callServiceExtension (hotRestart! );
423
468
@@ -461,8 +506,9 @@ void runTests({
461
506
});
462
507
463
508
test ('can hot restart changes ' , () async {
509
+ final mainDone = waitForMainToExecute ();
464
510
await makeEditAndRecompile ();
465
-
511
+ await mainDone;
466
512
final source = await context.webDriver.pageSource;
467
513
468
514
// Main is re-invoked which shouldn't clear the state.
@@ -521,8 +567,9 @@ void runTests({
521
567
});
522
568
523
569
test ('can hot restart changes ' , () async {
570
+ final mainDone = waitForMainToExecute (debuggingEnabled: false );
524
571
await makeEditAndRecompile ();
525
-
572
+ await mainDone;
526
573
final source = await context.webDriver.pageSource;
527
574
528
575
// Main is re-invoked which shouldn't clear the state.
@@ -582,6 +629,7 @@ void runTests({
582
629
),
583
630
);
584
631
632
+ final mainDone = waitForMainToExecute ();
585
633
final hotRestart = context.getRegisteredServiceExtension ('hotRestart' );
586
634
expect (
587
635
await fakeClient.callServiceExtension (hotRestart! ),
@@ -597,6 +645,8 @@ void runTests({
597
645
final isolateId = vm.isolates! .first.id! ;
598
646
await client.resume (isolateId);
599
647
648
+ await mainDone;
649
+
600
650
final sourceAfterResume = await context.webDriver.pageSource;
601
651
expect (sourceAfterResume.contains (newString), isTrue);
602
652
},
@@ -605,8 +655,8 @@ void runTests({
605
655
test (
606
656
'after page refresh, does not run app until there is a resume event' ,
607
657
() async {
658
+ final mainDone = waitForMainToExecute ();
608
659
await makeEditAndRecompile ();
609
-
610
660
await context.webDriver.driver.refresh ();
611
661
612
662
final eventsDone = expectLater (
@@ -629,6 +679,8 @@ void runTests({
629
679
final isolateId = vm.isolates! .first.id! ;
630
680
await client.resume (isolateId);
631
681
682
+ await mainDone;
683
+
632
684
final sourceAfterResume = await context.webDriver.pageSource;
633
685
expect (sourceAfterResume.contains (newString), isTrue);
634
686
},
0 commit comments