blob: 64b01b7273120cdbc9788545f3af16e0039699a3 [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:js_util' as js_util;
import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/ui.dart' hide TextStyle;
import 'package:ui/src/engine.dart';
import 'package:web_engine_tester/golden_tester.dart';
void main() {
internalBootstrapBrowserTest(() => testMain);
}
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 = 0.0, bool write = false}) 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, write: write);
} 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('Blend circles with difference and color', () async {
final RecordingCanvas rc =
RecordingCanvas(const Rect.fromLTRB(0, 0, 400, 300));
rc.save();
rc.drawRect(
Rect.fromLTRB(0, 0, 400, 400),
SurfacePaint()
..style = PaintingStyle.fill
..color = const Color.fromARGB(255, 255, 255, 255));
rc.drawCircle(
Offset(100, 100),
80.0,
SurfacePaint()
..style = PaintingStyle.fill
..color = const Color.fromARGB(128, 255, 0, 0)
..blendMode = BlendMode.difference);
rc.drawCircle(
Offset(170, 100),
80.0,
SurfacePaint()
..style = PaintingStyle.fill
..blendMode = BlendMode.color
..color = const Color.fromARGB(128, 0, 255, 0));
rc.drawCircle(
Offset(135, 170),
80.0,
SurfacePaint()
..style = PaintingStyle.fill
..color = const Color.fromARGB(128, 255, 0, 0));
rc.restore();
await _checkScreenshot(rc, 'canvas_blend_circle_diff_color',
maxDiffRatePercent: operatingSystem == OperatingSystem.macOs ? 2.95 :
operatingSystem == OperatingSystem.iOs ? 1.0 : 0);
});
test('Blend circle and text with multiply', () async {
final RecordingCanvas rc =
RecordingCanvas(const Rect.fromLTRB(0, 0, 400, 300));
rc.save();
rc.drawRect(
Rect.fromLTRB(0, 0, 400, 400),
SurfacePaint()
..style = PaintingStyle.fill
..color = const Color.fromARGB(255, 255, 255, 255));
rc.drawCircle(
Offset(100, 100),
80.0,
SurfacePaint()
..style = PaintingStyle.fill
..color = const Color.fromARGB(128, 255, 0, 0)
..blendMode = BlendMode.difference);
rc.drawCircle(
Offset(170, 100),
80.0,
SurfacePaint()
..style = PaintingStyle.fill
..blendMode = BlendMode.color
..color = const Color.fromARGB(128, 0, 255, 0));
rc.drawCircle(
Offset(135, 170),
80.0,
SurfacePaint()
..style = PaintingStyle.fill
..color = const Color.fromARGB(128, 255, 0, 0));
rc.drawImage(createTestImage(), Offset(135.0, 130.0),
SurfacePaint()..blendMode = BlendMode.multiply);
rc.restore();
await _checkScreenshot(rc, 'canvas_blend_image_multiply',
maxDiffRatePercent: operatingSystem == OperatingSystem.macOs ? 2.95 :
operatingSystem == OperatingSystem.iOs ? 2.0 : 0);
});
}
HtmlImage createTestImage() {
const int width = 100;
const int height = 50;
html.CanvasElement canvas =
new html.CanvasElement(width: width, height: height);
html.CanvasRenderingContext2D ctx = canvas.context2D;
ctx.fillStyle = '#E04040';
ctx.fillRect(0, 0, 33, 50);
ctx.fill();
ctx.fillStyle = '#40E080';
ctx.fillRect(33, 0, 33, 50);
ctx.fill();
ctx.fillStyle = '#2040E0';
ctx.fillRect(66, 0, 33, 50);
ctx.fill();
html.ImageElement imageElement = html.ImageElement();
imageElement.src = js_util.callMethod(canvas, 'toDataURL', <dynamic>[]);
return HtmlImage(imageElement, width, height);
}