diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /toolkit/components/extensions/test/mochitest/test_ext_tabs_captureTab.html | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/extensions/test/mochitest/test_ext_tabs_captureTab.html')
-rw-r--r-- | toolkit/components/extensions/test/mochitest/test_ext_tabs_captureTab.html | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/toolkit/components/extensions/test/mochitest/test_ext_tabs_captureTab.html b/toolkit/components/extensions/test/mochitest/test_ext_tabs_captureTab.html new file mode 100644 index 0000000000..ab06a965ed --- /dev/null +++ b/toolkit/components/extensions/test/mochitest/test_ext_tabs_captureTab.html @@ -0,0 +1,324 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Tests tabs.captureTab and tabs.captureVisibleTab</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script> + <script type="text/javascript" src="head.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<script type="text/javascript"> +"use strict"; + +async function runTest({ html, fullZoom, coords, rect, scale }) { + let url = `data:text/html,${encodeURIComponent(html)}#scroll`; + + async function background({ coords, rect, scale, method, fullZoom }) { + try { + // Wait for the page to load + await new Promise(resolve => { + browser.webNavigation.onCompleted.addListener( + () => resolve(), + {url: [{schemes: ["data"]}]}); + }); + + let [tab] = await browser.tabs.query({ + currentWindow: true, + active: true, + }); + + // TODO: Bug 1665429 - on mobile we ignore zoom for now + if (browser.tabs.setZoom) { + await browser.tabs.setZoom(tab.id, fullZoom ?? 1); + } + + let id = method === "captureVisibleTab" ? tab.windowId : tab.id; + + let [jpeg, png, ...pngs] = await Promise.all([ + browser.tabs[method](id, { format: "jpeg", quality: 95, rect, scale }), + browser.tabs[method](id, { format: "png", quality: 95, rect, scale }), + browser.tabs[method](id, { quality: 95, rect, scale }), + browser.tabs[method](id, { rect, scale }), + ]); + + browser.test.assertTrue( + pngs.every(url => url == png), + "All PNGs are identical" + ); + + browser.test.assertTrue( + jpeg.startsWith("data:image/jpeg;base64,"), + "jpeg is JPEG" + ); + browser.test.assertTrue( + png.startsWith("data:image/png;base64,"), + "png is PNG" + ); + + let promises = [jpeg, png].map( + url => + new Promise(resolve => { + let img = new Image(); + img.src = url; + img.onload = () => resolve(img); + }) + ); + + let width = (rect?.width ?? tab.width) * (scale ?? devicePixelRatio); + let height = (rect?.height ?? tab.height) * (scale ?? devicePixelRatio); + + [jpeg, png] = await Promise.all(promises); + let images = { jpeg, png }; + for (let format of Object.keys(images)) { + let img = images[format]; + + // WGP.drawSnapshot() deals in int coordinates, and rounds down. + browser.test.assertTrue( + Math.abs(width - img.width) <= 1, + `${format} ok image width: ${img.width}, expected: ${width}` + ); + browser.test.assertTrue( + Math.abs(height - img.height) <= 1, + `${format} ok image height ${img.height}, expected: ${height}` + ); + + let canvas = document.createElement("canvas"); + canvas.width = img.width; + canvas.height = img.height; + canvas.mozOpaque = true; + + let ctx = canvas.getContext("2d"); + ctx.drawImage(img, 0, 0); + + for (let { x, y, color } of coords) { + x = (x + img.width) % img.width; + y = (y + img.height) % img.height; + let imageData = ctx.getImageData(x, y, 1, 1).data; + + if (format == "png") { + browser.test.assertEq( + `rgba(${color},255)`, + `rgba(${[...imageData]})`, + `${format} image color is correct at (${x}, ${y})` + ); + } else { + // Allow for some deviation in JPEG version due to lossy compression. + const SLOP = 3; + + browser.test.log( + `Testing ${format} image color at (${x}, ${y}), have rgba(${[ + ...imageData, + ]}), expecting approx. rgba(${color},255)` + ); + + browser.test.assertTrue( + Math.abs(color[0] - imageData[0]) <= SLOP, + `${format} image color.red is correct at (${x}, ${y})` + ); + browser.test.assertTrue( + Math.abs(color[1] - imageData[1]) <= SLOP, + `${format} image color.green is correct at (${x}, ${y})` + ); + browser.test.assertTrue( + Math.abs(color[2] - imageData[2]) <= SLOP, + `${format} image color.blue is correct at (${x}, ${y})` + ); + browser.test.assertEq( + 255, + imageData[3], + `${format} image color.alpha is correct at (${x}, ${y})` + ); + } + } + } + + browser.test.notifyPass("captureTab"); + } catch (e) { + browser.test.fail(`Error: ${e} :: ${e.stack}`); + browser.test.notifyFail("captureTab"); + } + } + + for (let method of ["captureTab", "captureVisibleTab"]) { + let options = { coords, rect, scale, method, fullZoom }; + info(`Testing configuration: ${JSON.stringify(options)}`); + + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + permissions: ["<all_urls>", "webNavigation"], + }, + + background: `(${background})(${JSON.stringify(options)})`, + }); + + await extension.startup(); + + let testWindow = window.open(url); + await extension.awaitFinish("captureTab"); + + testWindow.close(); + await extension.unload(); + } +} + +async function testEdgeToEdge({ color, fullZoom }) { + let neutral = [0xaa, 0xaa, 0xaa]; + + let html = ` + <!DOCTYPE html> + <html lang="en"> + <head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + </head> + <body style="background-color: rgb(${color})"> + <!-- Fill most of the image with a neutral color to test edge-to-edge scaling. --> + <div style="position: absolute; + left: 2px; + right: 2px; + top: 2px; + bottom: 2px; + background: rgb(${neutral});"></div> + </body> + </html> + `; + + // Check the colors of the first and last pixels of the image, to make + // sure we capture the entire frame, and scale it correctly. + let coords = [ + { x: 0, y: 0, color }, + { x: -1, y: -1, color }, + { x: 300, y: 200, color: neutral }, + ]; + + info(`Test edge to edge color ${color} at fullZoom=${fullZoom}`); + await runTest({ html, fullZoom, coords }); +} + +add_task(async function testCaptureEdgeToEdge() { + await testEdgeToEdge({ color: [0, 0, 0], fullZoom: 1 }); + await testEdgeToEdge({ color: [0, 0, 0], fullZoom: 2 }); + await testEdgeToEdge({ color: [0, 0, 0], fullZoom: 0.5 }); + await testEdgeToEdge({ color: [255, 255, 255], fullZoom: 1 }); +}); + +const tallDoc = `<!DOCTYPE html> + <meta charset=utf-8> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <div style="background: yellow; width: 50%; height: 500px;"></div> + <div id=scroll style="background: red; width: 25%; height: 5000px;"></div> + Opened with the #scroll fragment, scrolls the div ^ into view. +`; + +// Test currently visible viewport is captured if scrolling is involved. +add_task(async function testScrolledViewport() { + await runTest({ + html: tallDoc, + coords: [ + { x: 50, y: 50, color: [255, 0, 0] }, + { x: 50, y: -50, color: [255, 0, 0] }, + { x: -50, y: -50, color: [255, 255, 255] }, + ], + }); +}); + +// Test rect and scale options. +add_task(async function testRectAndScale() { + await runTest({ + html: tallDoc, + rect: { x: 50, y: 50, width: 10, height: 1000 }, + scale: 4, + coords: [ + { x: 0, y: 0, color: [255, 255, 0] }, + { x: -1, y: 0, color: [255, 255, 0] }, + { x: 0, y: -1, color: [255, 0, 0] }, + { x: -1, y: -1, color: [255, 0, 0] }, + ], + }); +}); + +// Test OOP iframes are captured, for Fission compatibility. +add_task(async function testOOPiframe() { + await runTest({ + html: `<!DOCTYPE html> + <meta charset=utf-8> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <iframe src="http://example.net/tests/toolkit/components/extensions/test/mochitest/file_green.html"></iframe> + `, + coords: [ + { x: 50, y: 50, color: [0, 255, 0] }, + { x: 50, y: -50, color: [255, 255, 255] }, + { x: -50, y: 50, color: [255, 255, 255] }, + ], + }); +}); + +add_task(async function testOOPiframeScale() { + let scale = 2; + await runTest({ + html: `<!DOCTYPE html> + <meta charset=utf-8> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <style> + body { + background: yellow; + margin: 0; + } + </style> + <iframe frameborder="0" style="width: 300px; height: 300px" src="http://example.net/tests/toolkit/components/extensions/test/mochitest/file_green_blue.html"></iframe> + `, + coords: [ + { x: 20 * scale, y: 20 * scale, color: [0, 255, 0] }, + { x: 200 * scale, y: 20 * scale, color: [0, 0, 255] }, + { x: 20 * scale, y: 200 * scale, color: [0, 0, 255] }, + ], + scale, + }); +}); + +add_task(async function testCaptureTabPermissions() { + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + permissions: ["tabs"], + }, + + background() { + browser.test.assertEq( + undefined, + browser.tabs.captureTab, + 'Extension without "<all_urls>" permission should not have access to captureTab' + ); + browser.test.notifyPass("captureTabPermissions"); + }, + }); + + await extension.startup(); + await extension.awaitFinish("captureTabPermissions"); + await extension.unload(); +}); + +add_task(async function testCaptureVisibleTabPermissions() { + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + permissions: ["tabs"], + }, + + background() { + browser.test.assertEq( + undefined, + browser.tabs.captureVisibleTab, + 'Extension without "<all_urls>" permission should not have access to captureVisibleTab' + ); + browser.test.notifyPass("captureVisibleTabPermissions"); + }, + }); + + await extension.startup(); + await extension.awaitFinish("captureVisibleTabPermissions"); + await extension.unload(); +}); +</script> +</body> +</html> |