Commit 48550efa authored by Andrey Kosyakov's avatar Andrey Kosyakov Committed by Commit Bot

Add a headless test for opacity animation

Bug: 1013000
Change-Id: I225064e4cdbeab4ed23588df8ec0154f00d6dd60
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1851225
Commit-Queue: Andrey Kosyakov <caseq@chromium.org>
Reviewed-by: default avatarJohannes Henkel <johannes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#705210}
parent 0bac2409
...@@ -93,6 +93,33 @@ ...@@ -93,6 +93,33 @@
} }
} }
/**
* Capture screenshot of the entire screen and return a 2d graphics context
* that has the resulting screenshot painted.
*/
async captureScreenshot() {
const frameTimeTicks = this.currentFrameTime();
const screenshotData =
(await this.dp_.HeadlessExperimental.beginFrame(
{frameTimeTicks, screenshot: {format: 'png'}}))
.result.screenshotData;
// Advance virtual time a bit so that next frame timestamp is greater.
this.virtualTimeBase_ += 0.01;
const image = new Image();
await new Promise(fulfill => {
image.onload = fulfill;
image.src = `data:image/png;base64,${screenshotData}`;
});
this.testRunner_.log(
`Screenshot size: ${image.naturalWidth} x ${image.naturalHeight}`);
const canvas = document.createElement('canvas');
canvas.width = image.naturalWidth;
canvas.height = image.naturalHeight;
const ctx = canvas.getContext('2d');
ctx.drawImage(image, 0, 0);
return ctx;
}
async issueAnimationFrameAndScheduleNextChunk_() { async issueAnimationFrameAndScheduleNextChunk_() {
if (this.totalElapsedTime_ > 0 && this.remainingBudget_ > 0) { if (this.totalElapsedTime_ > 0 && this.remainingBudget_ > 0) {
const remainder = this.totalElapsedTime_ % this.animationFrameInterval_; const remainder = this.totalElapsedTime_ % this.animationFrameInterval_;
......
...@@ -34,41 +34,15 @@ ...@@ -34,41 +34,15 @@
await virtualTimeController.grantInitialTime(500, 1000, await virtualTimeController.grantInitialTime(500, 1000,
null, null,
async () => { async () => {
const frameTimeTicks = virtualTimeController.currentFrameTime(); const ctx = await virtualTimeController.captureScreenshot();
const screenshotData =
(await dp.HeadlessExperimental.beginFrame(
{frameTimeTicks, screenshot: {format: 'png'}}))
.result.screenshotData;
await logScreenShotData(screenshotData);
testRunner.completeTest();
}
);
function logScreenShotData(pngBase64) {
const image = new Image();
let callback;
let promise = new Promise(fulfill => callback = fulfill);
image.onload = function() {
testRunner.log(`Screenshot size: `
+ `${image.naturalWidth} x ${image.naturalHeight}`);
const canvas = document.createElement('canvas');
canvas.width = image.naturalWidth;
canvas.height = image.naturalHeight;
const ctx = canvas.getContext('2d');
ctx.drawImage(image, 0, 0);
// Expected rgba @(0,0): 255,255,255,255
const rgba = ctx.getImageData(0, 0, 1, 1).data; const rgba = ctx.getImageData(0, 0, 1, 1).data;
testRunner.log(`rgba @(0,0): ${rgba}`); testRunner.log(`rgba @(0,0): ${rgba}`);
// Expected rgba @(25,25): 255,0,0,255 // Expected rgba @(25,25): 255,0,0,255
const rgba2 = ctx.getImageData(25, 25, 1, 1).data; const rgba2 = ctx.getImageData(25, 25, 1, 1).data;
testRunner.log(`rgba @(25,25): ${rgba2}`); testRunner.log(`rgba @(25,25): ${rgba2}`);
callback(); testRunner.completeTest();
} }
);
image.src = `data:image/png;base64,${pngBase64}`;
return promise;
}
await frameNavigationHelper.navigate('http://example.com/'); await frameNavigationHelper.navigate('http://example.com/');
}) })
Tests that animating layer transparency produces correct pixels
requested url: http://example.com/
Screenshot size: 800 x 600
rgba @(25,25) before animaion started: 255,255,255,255
Screenshot size: 800 x 600
rgba @(25,25) after animation started: 1,128,1,255
\ No newline at end of file
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
(async function(testRunner) {
let {page, session, dp} = await testRunner.startWithFrameControl(
'Tests that animating layer transparency produces correct pixels');
await dp.Runtime.enable();
await dp.HeadlessExperimental.enable();
let RendererTestHelper =
await testRunner.loadScript('../helpers/renderer-test-helper.js');
let {httpInterceptor, frameNavigationHelper, virtualTimeController} =
await (new RendererTestHelper(testRunner, dp, page)).init();
// Animate the opacity of the div from 0 to 1 after a 1s delay.
httpInterceptor.addResponse(
`http://example.com/`,
`<style>
body { margin: 0 }
div {
animation-delay: 1s;
opacity: 0;
animation-name: animation;
animation-fill-mode: forwards;
animation-duration: 1s;
background-color: green;
width: 100vw;
height: 100vh;
}
@keyframes animation {
0% { opacity: 1; }
100% { opacity: 1; }
}
</style>
<div></div>`);
let ctx = await new Promise(async fulfill => {
// Give page 500ms before capturing first screenshot. The screenshot
// should fall into animamtion-delay interval, so no animation effects
// should be present and the point shoule be white.
await virtualTimeController.grantInitialTime(500, 100,
null,
async () => fulfill(await virtualTimeController.captureScreenshot())
);
frameNavigationHelper.navigate('http://example.com/');
});
let rgba = ctx.getImageData(25, 25, 1, 1).data;
testRunner.log(`rgba @(25,25) before animaion started: ${rgba}`);
// After additional 550ms, the animation should have started and the test
// point shoule be green.
await new Promise(fulfill => virtualTimeController.grantTime(550, fulfill));
ctx = await virtualTimeController.captureScreenshot();
rgba = ctx.getImageData(25, 25, 1, 1).data;
testRunner.log(`rgba @(25,25) after animation started: ${rgba}`);
testRunner.completeTest();
})
...@@ -422,4 +422,7 @@ HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererCssUrlFilter, ...@@ -422,4 +422,7 @@ HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererCssUrlFilter,
"sanity/renderer-css-url-filter.js") "sanity/renderer-css-url-filter.js")
HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererCanvas, "sanity/renderer-canvas.js") HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererCanvas, "sanity/renderer-canvas.js")
HEADLESS_PROTOCOL_COMPOSITOR_TEST(RendererOpacityAnimation,
"sanity/renderer-opacity-animation.js")
} // namespace headless } // namespace headless
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment