| <!DOCTYPE HTML> |
| <meta charset=utf-8> |
| <title>Largest Contentful Paint: Image size affected by css scale and rotation.</title> |
| <body> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="resources/largest-contentful-paint-helpers.js"></script> |
| <script src="/common/utils.js"></script> |
| <script> |
| setup({"hide_test_state": true}); |
| setup(() => |
| assert_implements(window.LargestContentfulPaint, "LargestContentfulPaint is not implemented")); |
| |
| const imageURL = `${window.location.origin}/images/blue.png`; |
| async function load_image_and_get_lcp_size(t, |
| imageStyle = {}, containerStyle = {}) { |
| const popup = window.open(); |
| t.add_cleanup(() => popup.close()); |
| const image = popup.document.createElement('img'); |
| image.src = imageURL; |
| |
| // We decode the image to get the natural size (though it's a constant) |
| await image.decode(); |
| const naturalSize = image.width * image.height; |
| |
| const container = popup.document.createElement('div'); |
| container.appendChild(image); |
| const applyStyle = (el, style = {}) => |
| Object.entries(style).forEach(([k, v]) => el.style.setProperty(k, v)); |
| |
| applyStyle(image, imageStyle); |
| applyStyle(container, containerStyle); |
| image.id = token(); |
| container.id = token(); |
| const entryReported = new Promise(resolve => |
| new popup.PerformanceObserver(entryList => { |
| entryList.getEntries().forEach(entry => { |
| if (entry.id === image.id || entry.id === container.id){ |
| step_timeout(() => { resolve(entry.size)}, 1000) |
| } |
| }); |
| }).observe({type: 'largest-contentful-paint'})); |
| popup.document.body.appendChild(container); |
| return { |
| lcpSize: (await await_with_timeout(7000, 'not reported', entryReported)), |
| naturalSize |
| }; |
| } |
| |
| /* We set the image to display: none when testing background, |
| so that only the background is reported |
| and not the image itself */ |
| const load_background_image_and_get_lcp_size = (t, style) => |
| load_image_and_get_lcp_size(t, {display: 'none'}, |
| { |
| position: 'absolute', |
| 'background-image': `url(${imageURL})`, |
| ...style, |
| }); |
| |
| promise_test(async t => { |
| const {naturalSize, lcpSize} = await load_image_and_get_lcp_size(t); |
| assert_equals(lcpSize, naturalSize); |
| }, 'Non-scaled image should report the natural size'); |
| |
| promise_test(async t => { |
| const {naturalSize, lcpSize} = await load_image_and_get_lcp_size(t, |
| {width: '50px', height: '50px'}); |
| assert_equals(lcpSize, 50 * 50); |
| }, 'A downscaled image (width/height) should report the displayed size'); |
| |
| promise_test(async t => { |
| const {naturalSize, lcpSize} = await load_image_and_get_lcp_size(t, |
| {transform: 'scale(0.5)'}); |
| assert_equals(Math.floor(lcpSize), Math.floor(naturalSize / 4)); |
| }, 'A downscaled image (using scale) should report the displayed size'); |
| |
| promise_test(async t => { |
| const {naturalSize, lcpSize} = await load_image_and_get_lcp_size(t, |
| {width: '500px', height: '500px'}); |
| assert_equals(lcpSize, naturalSize); |
| }, 'An upscaled image (width/height) should report the natural size'); |
| |
| promise_test(async t => { |
| const {naturalSize, lcpSize} = await load_image_and_get_lcp_size(t, |
| {transform: 'scale(2)'}); |
| assert_equals(Math.floor(lcpSize), Math.floor(naturalSize)); |
| }, 'An upscaled image (using scale) should report the natural size'); |
| |
| promise_test(async t => { |
| const {naturalSize, lcpSize} = await load_image_and_get_lcp_size(t, |
| {'object-size': '300px 300px'}); |
| assert_equals(Math.floor(lcpSize), Math.floor(naturalSize)); |
| }, 'An upscaled image (using object-size) should report the natural size'); |
| |
| promise_test(async t => { |
| const {naturalSize, lcpSize} = await load_image_and_get_lcp_size(t, |
| {'object-position': '-100px 0'}); |
| assert_equals(lcpSize, 3498); |
| }, |
| 'Intersecting element with partial-intersecting image to report image intersection'); |
| |
| promise_test(async t => { |
| const {naturalSize, lcpSize} = await load_background_image_and_get_lcp_size(t, |
| {width: '50px', height: '50px'}); |
| assert_equals(lcpSize, 50 * 50); |
| }, 'A background image larger than the container should report the container size'); |
| |
| promise_test(async t => { |
| const {naturalSize, lcpSize} = await load_background_image_and_get_lcp_size(t, |
| {width: '300px', height: '300px'}); |
| assert_equals(lcpSize, naturalSize); |
| }, 'A background image smaller than the container should report the natural size'); |
| |
| promise_test(async t => { |
| const {naturalSize, lcpSize} = await load_background_image_and_get_lcp_size(t, |
| {width: '300px', height: '300px', 'background-size': '10px 10x'}); |
| assert_equals(lcpSize, 100); |
| }, 'A scaled-down background image should report the background size'); |
| |
| promise_test(async t => { |
| const {naturalSize, lcpSize} = await load_image_and_get_lcp_size(t, |
| {transform: 'rotateX(60deg)'}); |
| assert_equals(Math.floor(lcpSize), Math.floor(naturalSize/2)); |
| }, 'A rotated image with size half of the natural size along x-axis'); |
| |
| promise_test(async t => { |
| const {naturalSize, lcpSize} = await load_image_and_get_lcp_size(t, |
| {transform: 'rotateX(90deg)'}); |
| assert_equals(Math.floor(lcpSize), 0); |
| }, 'A rotated image with natural size 0 along x-axis'); |
| |
| promise_test(async t => { |
| const {naturalSize, lcpSize} = await load_image_and_get_lcp_size(t, |
| {transform: 'rotateX(180deg)'}); |
| assert_equals(Math.floor(lcpSize), Math.floor(naturalSize)); |
| }, 'A rotated image with size equal to the natural size along x-axis'); |
| |
| promise_test(async t => { |
| const {naturalSize, lcpSize} = await load_image_and_get_lcp_size(t, |
| {transform: 'rotateY(60deg)'}); |
| assert_equals(Math.floor(lcpSize), Math.floor(naturalSize/2)); |
| }, 'A rotated image with size half of the natural size along y-axis'); |
| |
| promise_test(async t => { |
| const {naturalSize, lcpSize} = await load_image_and_get_lcp_size(t, |
| {transform: 'rotateY(89.99deg)'}); |
| assert_equals(Math.floor(lcpSize), 0); |
| }, 'A rotated image with natural size 0 along y-axis'); |
| |
| promise_test(async t => { |
| const {naturalSize, lcpSize} = await load_image_and_get_lcp_size(t, |
| {transform: 'rotateY(180deg)'}); |
| assert_equals(Math.floor(lcpSize), Math.floor(naturalSize)); |
| }, 'A rotated image with size equal to the natural size along y-axis') |
| |
| promise_test(async t => { |
| const {naturalSize, lcpSize} = await load_image_and_get_lcp_size(t, |
| {transform: 'rotateZ(90.1deg)'}); |
| assert_equals(Math.floor(lcpSize), Math.floor(naturalSize)); |
| }, 'A rotated image with size equal to the natural size'); |
| </script> |
| </body> |