Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 21 additions & 77 deletions packages/flutter_test/lib/src/_matchers_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,69 +59,37 @@ class MatchesGoldenFile extends AsyncMatcher {
return 'matched too many widgets';
}
final Element element = elements.single;
final RenderObject renderObject = _findRepaintBoundary(element);
final Size size = renderObject.paintBounds.size;
final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.instance;
final ui.FlutterView view = binding.platformDispatcher.implicitView!;
final RenderView renderView = binding.renderViews.firstWhere(
(RenderView r) => r.flutterView == view,
);

if (isSkiaWeb) {
// In CanvasKit and Skwasm, use Layer.toImage to generate the screenshot.
final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.instance;
return binding.runAsync<String?>(() async {
assert(element.renderObject != null);
RenderObject renderObject = element.renderObject!;
while (!renderObject.isRepaintBoundary) {
renderObject = renderObject.parent!;
}
assert(!renderObject.debugNeedsPaint);
final OffsetLayer layer = renderObject.debugLayer! as OffsetLayer;
final ui.Image image = await layer.toImage(renderObject.paintBounds);
try {
final ByteData? bytes = await image.toByteData(format: ui.ImageByteFormat.png);
if (bytes == null) {
return 'could not encode screenshot.';
}
if (autoUpdateGoldenFiles) {
await goldenFileComparator.update(key, bytes.buffer.asUint8List());
return null;
}
try {
final bool success = await goldenFileComparator.compare(
bytes.buffer.asUint8List(),
key,
);
return success ? null : 'does not match';
} on TestFailure catch (ex) {
return ex.message;
}
} finally {
image.dispose();
// In CanvasKit and Skwasm, use Layer.toImage to generate the screenshot.
final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.instance;
return binding.runAsync<String?>(() async {
assert(element.renderObject != null);
RenderObject renderObject = element.renderObject!;
while (!renderObject.isRepaintBoundary) {
renderObject = renderObject.parent!;
}
assert(!renderObject.debugNeedsPaint);
final OffsetLayer layer = renderObject.debugLayer! as OffsetLayer;
final ui.Image image = await layer.toImage(renderObject.paintBounds);
try {
final ByteData? bytes = await image.toByteData(format: ui.ImageByteFormat.png);
if (bytes == null) {
return 'could not encode screenshot.';
}
});
} else {
// In the HTML renderer, we don't have the ability to render an element
// to an image directly. Instead, we will use `window.render()` to render
// only the element being requested, and send a request to the test server
// requesting it to take a screenshot through the browser's debug interface.
_renderElement(view, renderObject);
final String? result = await binding.runAsync<String?>(() async {
if (autoUpdateGoldenFiles) {
await webGoldenComparator.update(size.width, size.height, key);
await goldenFileComparator.update(key, bytes.buffer.asUint8List());
return null;
}
try {
final bool success = await webGoldenComparator.compare(size.width, size.height, key);
final bool success = await goldenFileComparator.compare(bytes.buffer.asUint8List(), key);
return success ? null : 'does not match';
} on TestFailure catch (ex) {
return ex.message;
}
});
_renderElement(view, renderView);
return result;
}
} finally {
image.dispose();
}
});
}

@override
Expand All @@ -130,27 +98,3 @@ class MatchesGoldenFile extends AsyncMatcher {
return description.add('one widget whose rasterized image matches golden image "$testNameUri"');
}
}

RenderObject _findRepaintBoundary(Element element) {
assert(element.renderObject != null);
RenderObject renderObject = element.renderObject!;
while (!renderObject.isRepaintBoundary) {
renderObject = renderObject.parent!;
}
return renderObject;
}

void _renderElement(ui.FlutterView window, RenderObject renderObject) {
assert(renderObject.debugLayer != null);
final Layer layer = renderObject.debugLayer!;
final ui.SceneBuilder sceneBuilder = ui.SceneBuilder();
if (layer is OffsetLayer) {
sceneBuilder.pushOffset(-layer.offset.dx, -layer.offset.dy);
}
// ignore: invalid_use_of_visible_for_testing_member, invalid_use_of_protected_member
layer.updateSubtreeNeedsAddToScene();
// ignore: invalid_use_of_protected_member
layer.addToScene(sceneBuilder);
sceneBuilder.pop();
window.render(sceneBuilder.build());
}
Loading