blob: 12e4d3bf935c67407d87213164b9fb0bc68a8f9a [file] [log] [blame]
// 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 'dart:math' as math;
import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart' hide TextStyle;
import 'package:web_engine_tester/golden_tester.dart';
void main() {
internalBootstrapBrowserTest(() => testMain);
}
Future<void> testMain() async {
const double screenWidth = 600.0;
const double screenHeight = 800.0;
const Rect screenRect = Rect.fromLTWH(0, 0, screenWidth, screenHeight);
// Commit a recording canvas to a bitmap, and compare with the expected
Future<void> _checkScreenshot(RecordingCanvas rc, String fileName,
{Rect region = const Rect.fromLTWH(0, 0, 500, 500),
double? maxDiffRatePercent}) async {
final EngineCanvas engineCanvas = BitmapCanvas(screenRect,
RenderStrategy());
rc.endRecording();
rc.apply(engineCanvas, screenRect);
// Wrap in <flt-scene> so that our CSS selectors kick in.
final html.Element sceneElement = html.Element.tag('flt-scene');
try {
sceneElement.append(engineCanvas.rootElement);
html.document.body!.append(sceneElement);
await matchGoldenFile('$fileName.png', region: region, maxDiffRatePercent: maxDiffRatePercent);
} finally {
// The page is reused across tests, so remove the element after taking the
// Scuba screenshot.
sceneElement.remove();
}
}
setUp(() async {
debugEmulateFlutterTesterEnvironment = true;
await webOnlyInitializePlatform();
webOnlyFontCollection.debugRegisterTestFonts();
await webOnlyFontCollection.ensureFontsLoaded();
});
test('Should draw transformed line.', () async {
final RecordingCanvas rc =
RecordingCanvas(const Rect.fromLTRB(0, 0, 500, 500));
final Path path = Path();
path.moveTo(0, 0);
path.lineTo(300, 200);
rc.drawPath(
path,
SurfacePaint()
..style = PaintingStyle.stroke
..strokeWidth = 2.0
..color = const Color(0xFF404000));
final Path transformedPath = Path();
final Matrix4 testMatrixTranslateRotate =
Matrix4.rotationZ(math.pi * 30.0 / 180.0)..translate(100, 20);
transformedPath.addPath(path, Offset.zero,
matrix4: testMatrixTranslateRotate.toFloat64());
rc.drawPath(
transformedPath,
SurfacePaint()
..style = PaintingStyle.stroke
..strokeWidth = 2.0
..color = const Color.fromRGBO(0, 128, 255, 1.0));
await _checkScreenshot(rc, 'path_transform_with_line');
});
test('Should draw transformed line.', () async {
final RecordingCanvas rc =
RecordingCanvas(const Rect.fromLTRB(0, 0, 500, 500));
final Path path = Path();
path.addRect(const Rect.fromLTRB(50, 40, 300, 100));
rc.drawPath(
path,
SurfacePaint()
..style = PaintingStyle.stroke
..strokeWidth = 2.0
..color = const Color(0xFF404000));
final Path transformedPath = Path();
final Matrix4 testMatrixTranslateRotate =
Matrix4.rotationZ(math.pi * 30.0 / 180.0)..translate(100, 20);
transformedPath.addPath(path, Offset.zero,
matrix4: testMatrixTranslateRotate.toFloat64());
rc.drawPath(
transformedPath,
SurfacePaint()
..style = PaintingStyle.stroke
..strokeWidth = 2.0
..color = const Color.fromRGBO(0, 128, 255, 1.0));
await _checkScreenshot(rc, 'path_transform_with_rect');
});
test('Should draw transformed quadratic curve.', () async {
final RecordingCanvas rc =
RecordingCanvas(const Rect.fromLTRB(0, 0, 500, 500));
final Path path = Path();
path.moveTo(100, 100);
path.quadraticBezierTo(100, 300, 400, 300);
rc.drawPath(
path,
SurfacePaint()
..style = PaintingStyle.stroke
..strokeWidth = 2.0
..color = const Color(0xFF404000));
final Path transformedPath = Path();
final Matrix4 testMatrixTranslateRotate =
Matrix4.rotationZ(math.pi * 30.0 / 180.0)..translate(100, -80);
transformedPath.addPath(path, Offset.zero,
matrix4: testMatrixTranslateRotate.toFloat64());
rc.drawPath(
transformedPath,
SurfacePaint()
..style = PaintingStyle.stroke
..strokeWidth = 2.0
..color = const Color.fromRGBO(0, 128, 255, 1.0));
await _checkScreenshot(rc, 'path_transform_with_quadratic_curve');
});
test('Should draw transformed conic.', () async {
final RecordingCanvas rc =
RecordingCanvas(const Rect.fromLTRB(0, 0, 500, 500));
const double yStart = 20;
const Offset p0 = Offset(25, yStart + 25);
const Offset pc = Offset(60, yStart + 150);
const Offset p2 = Offset(100, yStart + 50);
final Path path = Path();
path.moveTo(p0.dx, p0.dy);
path.conicTo(pc.dx, pc.dy, p2.dx, p2.dy, 0.5);
path.close();
path.moveTo(p0.dx, p0.dy + 100);
path.conicTo(pc.dx, pc.dy + 100, p2.dx, p2.dy + 100, 10);
path.close();
rc.drawPath(
path,
SurfacePaint()
..style = PaintingStyle.stroke
..strokeWidth = 2.0
..color = const Color(0xFF404000));
final Path transformedPath = Path();
final Matrix4 testMatrixTranslateRotate =
Matrix4.rotationZ(math.pi * 30.0 / 180.0)..translate(100, -80);
transformedPath.addPath(path, Offset.zero,
matrix4: testMatrixTranslateRotate.toFloat64());
rc.drawPath(
transformedPath,
SurfacePaint()
..style = PaintingStyle.stroke
..strokeWidth = 2.0
..color = const Color.fromRGBO(0, 128, 255, 1.0));
await _checkScreenshot(rc, 'path_transform_with_conic');
});
test('Should draw transformed arc.', () async {
final RecordingCanvas rc =
RecordingCanvas(const Rect.fromLTRB(0, 0, 500, 500));
final Path path = Path();
path.moveTo(350, 280);
path.arcToPoint(const Offset(450, 90),
radius: const Radius.elliptical(200, 50),
rotation: -math.pi / 6.0,
largeArc: true,
clockwise: true);
path.close();
rc.drawPath(
path,
SurfacePaint()
..style = PaintingStyle.stroke
..strokeWidth = 2.0
..color = const Color(0xFF404000));
final Path transformedPath = Path();
final Matrix4 testMatrixTranslateRotate =
Matrix4.rotationZ(math.pi * 30.0 / 180.0)..translate(100, 10);
transformedPath.addPath(path, Offset.zero,
matrix4: testMatrixTranslateRotate.toFloat64());
rc.drawPath(
transformedPath,
SurfacePaint()
..style = PaintingStyle.stroke
..strokeWidth = 2.0
..color = const Color.fromRGBO(0, 128, 255, 1.0));
await _checkScreenshot(rc, 'path_transform_with_arc',
maxDiffRatePercent: 1.4);
});
test('Should draw transformed rrect.', () async {
final RecordingCanvas rc =
RecordingCanvas(const Rect.fromLTRB(0, 0, 500, 500));
final Path path = Path();
path.addRRect(RRect.fromLTRBR(50, 50, 300, 200, const Radius.elliptical(4, 8)));
rc.drawPath(
path,
SurfacePaint()
..style = PaintingStyle.stroke
..strokeWidth = 2.0
..color = const Color(0xFF404000));
final Path transformedPath = Path();
final Matrix4 testMatrixTranslateRotate =
Matrix4.rotationZ(math.pi * 30.0 / 180.0)..translate(100, -80);
transformedPath.addPath(path, Offset.zero,
matrix4: testMatrixTranslateRotate.toFloat64());
rc.drawPath(
transformedPath,
SurfacePaint()
..style = PaintingStyle.stroke
..strokeWidth = 2.0
..color = const Color.fromRGBO(0, 128, 255, 1.0));
await _checkScreenshot(rc, 'path_transform_with_rrect');
});
}