Skip to content

Commit

Permalink
Add web engine screenshot (scuba) tests (flutter#12353)
Browse files Browse the repository at this point in the history
* Import all golden files and tests from internal repo.
* Adapt test files to new screenshot API, and tweak some settings.

(Check PR to see individual changes to each file)

Fixes flutter/flutter#40975
  • Loading branch information
ditman authored Sep 20, 2019
1 parent 22f42cf commit b875c7a
Show file tree
Hide file tree
Showing 131 changed files with 2,137 additions and 3 deletions.
2 changes: 1 addition & 1 deletion lib/web_ui/dev/test_platform.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import 'goldens.dart';
const int _kChromeDevtoolsPort = 12345;
const int _kMaxScreenshotWidth = 1024;
const int _kMaxScreenshotHeight = 1024;
const double _kMaxDiffRateFailure = 1.0/100000; // 0.001%
const double _kMaxDiffRateFailure = 0.211/100; // 0.211%

class BrowserPlatform extends PlatformPlugin {
/// Starts the server.
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added lib/web_ui/test/golden_files/engine/svg_arc_1.png
Binary file added lib/web_ui/test/golden_files/engine/svg_arc_2.png
Binary file added lib/web_ui/test/golden_files/engine/svg_arc_3.png
Binary file added lib/web_ui/test/golden_files/engine/svg_arc_4.png
Binary file added lib/web_ui/test/golden_files/engine/svg_arc_5.png
Binary file added lib/web_ui/test/golden_files/engine/svg_arc_6.png
Binary file added lib/web_ui/test/golden_files/engine/svg_arc_7.png
Binary file added lib/web_ui/test/golden_files/engine/svg_notch.png
Binary file added lib/web_ui/test/golden_files/engine/svg_rect.png
86 changes: 86 additions & 0 deletions lib/web_ui/test/golden_tests/engine/canvas_rrect_scuba_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:html' as html;

import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart';
import 'package:test/test.dart';

import 'package:web_engine_tester/golden_tester.dart';

void main() async {
final Rect region = Rect.fromLTWH(8, 8, 500, 100); // Compensate for old scuba tester padding

BitmapCanvas canvas;

final PaintData niceRRectPaint = PaintData()
..color = const Color.fromRGBO(250, 186, 218, 1.0) // #fabada
..style = PaintingStyle.fill;

// Some values to see how the algo behaves as radius get absurdly large
const List<double> rRectRadii = <double>[0, 10, 20, 80, 8000];

const Radius someFixedRadius = Radius.circular(10);

setUp(() {
canvas = BitmapCanvas(const Rect.fromLTWH(0, 0, 500, 100));
canvas.translate(10, 10); // Center
});

tearDown(() {
canvas.rootElement.remove();
});

test('round square with big (equal) radius ends up as a circle', () async {
for (int i = 0; i < 5; i++) {
canvas.drawRRect(
RRect.fromRectAndRadius(Rect.fromLTWH(100 * i.toDouble(), 0, 80, 80),
Radius.circular(rRectRadii[i])),
niceRRectPaint);
}

html.document.body.append(canvas.rootElement);
await matchGoldenFile('engine/canvas_rrect_round_square.png', region: region);
}, timeout: const Timeout(Duration(seconds: 10)));

test('round rect with big radius scale down smaller radius', () async {
for (int i = 0; i < 5; i++) {
final Radius growingRadius = Radius.circular(rRectRadii[i]);
final RRect rrect = RRect.fromRectAndCorners(
Rect.fromLTWH(100 * i.toDouble(), 0, 80, 80),
bottomRight: someFixedRadius,
topRight: growingRadius,
bottomLeft: growingRadius);

canvas.drawRRect(rrect, niceRRectPaint);
}

html.document.body.append(canvas.rootElement);
await matchGoldenFile('engine/canvas_rrect_overlapping_radius.png', region: region);
}, timeout: const Timeout(Duration(seconds: 10)));

test('diff round rect with big radius scale down smaller radius', () async {
for (int i = 0; i < 5; i++) {
final Radius growingRadius = Radius.circular(rRectRadii[i]);
final RRect outerRRect = RRect.fromRectAndCorners(
Rect.fromLTWH(100 * i.toDouble(), 0, 80, 80),
bottomRight: someFixedRadius,
topRight: growingRadius,
bottomLeft: growingRadius);

// Inner is half of outer, but offset a little so it looks nicer
final RRect innerRRect = RRect.fromRectAndCorners(
Rect.fromLTWH(100 * i.toDouble() + 5, 5, 40, 40),
bottomRight: someFixedRadius / 2,
topRight: growingRadius / 2,
bottomLeft: growingRadius / 2);

canvas.drawDRRect(outerRRect, innerRRect, niceRRectPaint);
}

html.document.body.append(canvas.rootElement);
await matchGoldenFile('engine/canvas_drrect_overlapping_radius.png', region: region);
}, timeout: const Timeout(Duration(seconds: 10)));
}
112 changes: 112 additions & 0 deletions lib/web_ui/test/golden_tests/engine/canvas_scuba_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:html' as html;

import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart';
import 'package:test/test.dart';

import 'package:web_engine_tester/golden_tester.dart';

void main() async {
final Rect region = Rect.fromLTWH(8, 8, 500, 100); // Compensate for old scuba tester padding

BitmapCanvas canvas;

setUp(() {
html.document.body.style.transform = 'translate(10px, 10px)';
});

tearDown(() {
html.document.body.style.transform = 'none';
canvas.rootElement.remove();
});

/// Draws several lines, some aligned precisely with the pixel grid, and some
/// that are offset by 0.5 vertically or horizontally.
///
/// The produced picture stresses the antialiasing generated by the browser
/// when positioning and rasterizing `<canvas>` tags. Aliasing artifacts can
/// be seen depending on pixel alignment and whether antialiasing happens
/// before or after rasterization.
void drawMisalignedLines(BitmapCanvas canvas) {
final PaintData linePaint = (Paint()
..style = PaintingStyle.stroke
..strokeWidth = 1)
.webOnlyPaintData;

final PaintData fillPaint =
(Paint()..style = PaintingStyle.fill).webOnlyPaintData;

canvas.drawRect(
const Rect.fromLTWH(0, 0, 40, 40),
linePaint,
);

canvas.drawLine(
const Offset(10, 0),
const Offset(10, 40),
linePaint,
);

canvas.drawLine(
const Offset(20.5, 0),
const Offset(20, 40),
linePaint,
);

canvas.drawCircle(const Offset(30, 10), 3, fillPaint);
canvas.drawCircle(const Offset(30.5, 30), 3, fillPaint);
}

test('renders pixels that are not aligned inside the canvas', () async {
canvas = BitmapCanvas(const Rect.fromLTWH(0, 0, 60, 60));

drawMisalignedLines(canvas);

html.document.body.append(canvas.rootElement);

await matchGoldenFile('engine/misaligned_pixels_in_canvas_test.png', region: region);
}, timeout: const Timeout(Duration(seconds: 10)));

test('compensates for misalignment of the canvas', () async {
// Notice the 0.5 offset in the bounds rectangle. It's what causes the
// misalignment of canvas relative to the pixel grid. BitmapCanvas will
// shift its position back to 0.0 and at the same time it will it will
// compensate by shifting the contents of the canvas in the opposite
// direction.
canvas = BitmapCanvas(const Rect.fromLTWH(0.5, 0.5, 60, 60));

drawMisalignedLines(canvas);

html.document.body.append(canvas.rootElement);

await matchGoldenFile('engine/misaligned_canvas_test.png', region: region);
}, timeout: const Timeout(Duration(seconds: 10)));

test('fill the whole canvas with color even when transformed', () async {
canvas = BitmapCanvas(const Rect.fromLTWH(0, 0, 50, 50));

canvas.translate(25, 25);
canvas.drawColor(const Color.fromRGBO(0, 255, 0, 1.0), BlendMode.src);

html.document.body.append(canvas.rootElement);

await matchGoldenFile('engine/bitmap_canvas_fills_color_when_transformed.png', region: region);
}, timeout: const Timeout(Duration(seconds: 10)));

test('fill the whole canvas with paint even when transformed', () async {
canvas = BitmapCanvas(const Rect.fromLTWH(0, 0, 50, 50));

canvas.translate(25, 25);
canvas.drawPaint(PaintData()
..color = const Color.fromRGBO(0, 255, 0, 1.0)
..style = PaintingStyle.fill);

html.document.body.append(canvas.rootElement);

await matchGoldenFile('engine/bitmap_canvas_fills_paint_when_transformed.png', region: region);
}, timeout: const Timeout(Duration(seconds: 10)));
}
Loading

0 comments on commit b875c7a

Please sign in to comment.