@@ -11,6 +11,12 @@ bool get isIosSafari =>
11
11
browserEngine == BrowserEngine .webkit &&
12
12
operatingSystem == OperatingSystem .iOs;
13
13
14
+ /// Some text measurements are sensitive to browser implementations. Position
15
+ /// info in the following tests only pass in Chrome, they are slightly different
16
+ /// on each browser. So we need to ignore position info on non-Chrome browsers
17
+ /// when comparing expectations with actual output.
18
+ bool get isChrome => browserEngine == BrowserEngine .blink;
19
+
14
20
String fontFamilyToAttribute (String fontFamily) {
15
21
fontFamily = canonicalizeFontFamily (fontFamily)! ;
16
22
if (browserEngine == BrowserEngine .firefox) {
@@ -42,19 +48,20 @@ Future<void> testMain() async {
42
48
expect (paragraph.spans, hasLength (1 ));
43
49
44
50
paragraph.layout (const ParagraphConstraints (width: double .infinity));
45
- expect (
46
- paragraph. toDomElement ().outerHtml ,
51
+ expectOuterHtml (
52
+ paragraph,
47
53
'<p style="${paragraphStyle (fontSize : 13 )}">'
48
54
'<span style="${spanStyle (top : 0 , left : 0 , fontSize : 13 )}">'
49
55
'Hello'
50
56
'</span>'
51
57
'</p>' ,
58
+ ignorePositions: ! isChrome,
52
59
);
53
60
54
61
// Should break "Hello" into "Hel" and "lo".
55
62
paragraph.layout (const ParagraphConstraints (width: 39.0 ));
56
- expect (
57
- paragraph. toDomElement ().outerHtml ,
63
+ expectOuterHtml (
64
+ paragraph,
58
65
'<p style="${paragraphStyle (fontSize : 13 )}">'
59
66
'<span style="${spanStyle (top : 0 , left : 0 , fontSize : 13 )}">'
60
67
'Hel'
@@ -63,6 +70,7 @@ Future<void> testMain() async {
63
70
'lo'
64
71
'</span>'
65
72
'</p>' ,
73
+ ignorePositions: ! isChrome,
66
74
);
67
75
68
76
final ParagraphSpan span = paragraph.spans.single;
@@ -195,8 +203,8 @@ Future<void> testMain() async {
195
203
expect (paragraph.spans, hasLength (2 ));
196
204
197
205
paragraph.layout (const ParagraphConstraints (width: double .infinity));
198
- expect (
199
- paragraph. toDomElement ().outerHtml ,
206
+ expectOuterHtml (
207
+ paragraph,
200
208
'<p style="${paragraphStyle (fontSize : 13 )}">'
201
209
'<span style="${spanStyle (top : 0 , left : 0 , fontSize : 13 , fontWeight : 'bold' )}">'
202
210
'Hello'
@@ -208,12 +216,13 @@ Future<void> testMain() async {
208
216
'world'
209
217
'</span>'
210
218
'</p>' ,
219
+ ignorePositions: ! isChrome,
211
220
);
212
221
213
222
// Should break "Hello world" into 2 lines: "Hello" and " world".
214
223
paragraph.layout (const ParagraphConstraints (width: 75.0 ));
215
- expect (
216
- paragraph. toDomElement ().outerHtml ,
224
+ expectOuterHtml (
225
+ paragraph,
217
226
'<p style="${paragraphStyle (fontSize : 13 )}">'
218
227
'<span style="${spanStyle (top : 0 , left : 0 , fontSize : 13 , fontWeight : 'bold' )}">'
219
228
'Hello'
@@ -225,6 +234,7 @@ Future<void> testMain() async {
225
234
'world'
226
235
'</span>'
227
236
'</p>' ,
237
+ ignorePositions: ! isChrome,
228
238
);
229
239
230
240
final FlatTextSpan hello = paragraph.spans.first as FlatTextSpan ;
@@ -266,8 +276,8 @@ Future<void> testMain() async {
266
276
expect (paragraph.spans, hasLength (3 ));
267
277
268
278
paragraph.layout (const ParagraphConstraints (width: double .infinity));
269
- expect (
270
- paragraph. toDomElement ().outerHtml ,
279
+ expectOuterHtml (
280
+ paragraph,
271
281
'<p style="${paragraphStyle (fontSize : 13 )}">'
272
282
'<span style="${spanStyle (top : 0 , left : 0 , lineHeight : 2 , fontSize : 13 , fontWeight : 'bold' )}">'
273
283
'Hello'
@@ -282,6 +292,7 @@ Future<void> testMain() async {
282
292
'!'
283
293
'</span>'
284
294
'</p>' ,
295
+ ignorePositions: ! isChrome,
285
296
);
286
297
287
298
final FlatTextSpan hello = paragraph.spans[0 ] as FlatTextSpan ;
@@ -333,8 +344,8 @@ Future<void> testMain() async {
333
344
// There's a new line between "First" and "Second", but "Second" and
334
345
// "ThirdLongLine" remain together since constraints are infinite.
335
346
paragraph.layout (const ParagraphConstraints (width: double .infinity));
336
- expect (
337
- paragraph. toDomElement ().outerHtml ,
347
+ expectOuterHtml (
348
+ paragraph,
338
349
'<p style="${paragraphStyle (fontSize : 13 )}">'
339
350
'<span style="${spanStyle (top : 0 , left : 0 , fontSize : 13 )}">'
340
351
'First'
@@ -349,12 +360,13 @@ Future<void> testMain() async {
349
360
'ThirdLongLine'
350
361
'</span>'
351
362
'</p>' ,
363
+ ignorePositions: ! isChrome,
352
364
);
353
365
354
366
// Should break the paragraph into "First", "Second" and "ThirdLongLine".
355
367
paragraph.layout (const ParagraphConstraints (width: 180.0 ));
356
- expect (
357
- paragraph. toDomElement ().outerHtml ,
368
+ expectOuterHtml (
369
+ paragraph,
358
370
'<p style="${paragraphStyle (fontSize : 13 )}">'
359
371
'<span style="${spanStyle (top : 0 , left : 0 , fontSize : 13 )}">'
360
372
'First'
@@ -369,6 +381,7 @@ Future<void> testMain() async {
369
381
'ThirdLongLine'
370
382
'</span>'
371
383
'</p>' ,
384
+ ignorePositions: ! isChrome,
372
385
);
373
386
});
374
387
@@ -393,10 +406,8 @@ Future<void> testMain() async {
393
406
// The paragraph should take the font size and family from the span with the
394
407
// greatest font size.
395
408
paragraph.layout (const ParagraphConstraints (width: double .infinity));
396
- expect (
397
- // Since we are using unknown font families, we can't predict the text
398
- // measurements.
399
- removePositionInfo (paragraph.toDomElement ().outerHtml! ),
409
+ expectOuterHtml (
410
+ paragraph,
400
411
'<p style="${paragraphStyle (fontSize : 18 , fontFamily : 'second' )}">'
401
412
'<span style="${spanStyle (top : null , left : null , fontSize : 12 , fontFamily : 'first' )}">'
402
413
'First'
@@ -414,6 +425,9 @@ Future<void> testMain() async {
414
425
'Third'
415
426
'</span>'
416
427
'</p>' ,
428
+ // Since we are using unknown font families, we can't predict the text
429
+ // measurements.
430
+ ignorePositions: true ,
417
431
);
418
432
debugEmulateFlutterTesterEnvironment = true ;
419
433
});
@@ -460,16 +474,6 @@ String spanStyle({
460
474
].join (' ' );
461
475
}
462
476
463
- /// Removes "top" and "left" CSS styles from the given html string.
464
- ///
465
- /// This is needed when the positioning information in the html output is
466
- /// unknown and could be different depending on browser and environment.
467
- String removePositionInfo (String outerHtml) {
468
- return outerHtml
469
- .replaceAll (RegExp (r'\s*top:\s*[\d\.]+px\s*;\s*' ), '' )
470
- .replaceAll (RegExp (r'\s*left:\s*[\d\.]+px\s*;\s*' ), '' );
471
- }
472
-
473
477
TextStyle styleWithDefaults ({
474
478
Color color = const Color (0xFFFF0000 ),
475
479
String fontFamily = FlutterViewEmbedder .defaultFontFamily,
@@ -489,3 +493,23 @@ TextStyle styleWithDefaults({
489
493
letterSpacing: letterSpacing,
490
494
);
491
495
}
496
+
497
+ void expectOuterHtml (CanvasParagraph paragraph, String expected, {required bool ignorePositions}) {
498
+ String outerHtml = paragraph.toDomElement ().outerHtml! ;
499
+ if (ignorePositions) {
500
+ outerHtml = removePositionInfo (outerHtml);
501
+ expected = removePositionInfo (expected);
502
+ }
503
+
504
+ expect (outerHtml, expected);
505
+ }
506
+
507
+ /// Removes "top" and "left" CSS styles from the given html string.
508
+ ///
509
+ /// This is needed when the positioning information in the html output is
510
+ /// unknown and could be different depending on browser and environment.
511
+ String removePositionInfo (String outerHtml) {
512
+ return outerHtml
513
+ .replaceAll (RegExp (r'\s*top:\s*[\d\.]+px\s*;\s*' ), '' )
514
+ .replaceAll (RegExp (r'\s*left:\s*[\d\.]+px\s*;\s*' ), '' );
515
+ }
0 commit comments