microsoft / playwright

Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.
https://playwright.dev
Apache License 2.0
63.91k stars 3.46k forks source link

[Bug]: WebKit page screenshots are missing alpha channel in Linux #30617

Open jaydenseric opened 2 months ago

jaydenseric commented 2 months ago

Version

1.43.1

Steps to reproduce

If you take a page screenshot using the WebKit browser, if your system is macOS the screenshot image will have an alpha channel (consistent with other browsers like Chromium and Firefox), but if your system is Linux (in our case, in a GitHub Actions workflow for CI), it will not have an alpha channel.

playwright install --with-deps webkit
import { webkit } from "playwright";

const browser = await webkit.launch();
const page = await browser.newPage();

await page.goto("https://playwright.dev");

// Has alpha channel when using macOS, but not Linux.
const screenshotBuffer = await page.screenshot();

await browser.close();

Expected behavior

When using the same browser WebKit, page screenshots should be the same regarding alpha channel regardless of the operating system used. Since the other Chromium and Firefox browsers have alpha channel, I suppose the expected behavior is consistency with that.

Actual behavior

When using the same browser WebKit, page screenshots have no alpha channel with a Linux operating system, and have an alpha channel with a macOS operating system.

Additional context

We create WebKit screenshot images on our local macOS dev machines and use them as the expected images for image snapshot testing. These snapshot tests run in a GitHub Actions workflow for CI. This was not a problem while we were only using the Chromium browser to take the screenshots, but now we are additionally using WebKit to take screenshots for image snapshot tests. Because WebKit in CI is taking screenshots without alpha channel, this difference is causing our snapshot test assertions to fail.

Environment

System:
  OS: Ubuntu 22.04.4 LTS
Binaries:
  Node: 22.0.0
dgozman commented 2 months ago

@jaydenseric Could you please attach two screenshots, one with the alpha channel and another without? It would also be great to clarify how does this difference cause your snapshot test assertions to fail? Does it render a different image entirely? Or is the difference only in the internal channels representation, but pixels are the same?

jaydenseric commented 2 months ago

Here is a screenshot taken with WebKit on Linux (paste it in a browser URL to see it):

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAACWCAIAAACzY+a1AAAABmJLR0QA/wD/AP+gvaeTAAABcElEQVR4nO3RwQkAIBDAsNPJHd0hfEghmaDQNWdI278DeGVhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmGdhnoV5FuZZmHcBD84BrGfmAcwAAAAASUVORK5CYII=

Here is a screenshot of the same thing, with WebKit on macOS:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAACWCAYAAAA8AXHiAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAlqADAAQAAAABAAAAlgAAAAAXS0ggAAACqklEQVR4Ae3SwQ2AQAwDwXCV0zlIV0P2Ny7Aj9U88843psBygbP8506BWwAsEJICYCVZnYLFQFIArCSrU7AYSAqAlWR1ChYDSQGwkqxOwWIgKQBWktUpWAwkBcBKsjoFi4GkAFhJVqdgMZAUACvJ6hQsBpICYCVZnYLFQFIArCSrU7AYSAqAlWR1ChYDSQGwkqxOwWIgKQBWktUpWAwkBcBKsjoFi4GkAFhJVqdgMZAUACvJ6hQsBpICYCVZnYLFQFIArCSrU7AYSAqAlWR1ChYDSQGwkqxOwWIgKQBWktUpWAwkBcBKsjoFi4GkAFhJVqdgMZAUACvJ6hQsBpICYCVZnYLFQFIArCSrU7AYSAqAlWR1ChYDSQGwkqxOwWIgKQBWktUpWAwkBcBKsjoFi4GkAFhJVqdgMZAUACvJ6hQsBpICYCVZnYLFQFIArCSrU7AYSAqAlWR1ChYDSQGwkqxOwWIgKQBWktUpWAwkBcBKsjoFi4GkAFhJVqdgMZAUACvJ6hQsBpICYCVZnYLFQFIArCSrU7AYSAqAlWR1ChYDSQGwkqxOwWIgKQBWktUpWAwkBcBKsjoFi4GkAFhJVqdgMZAUACvJ6hQsBpICYCVZnYLFQFIArCSrU7AYSAqAlWR1ChYDSQGwkqxOwWIgKQBWktUpWAwkBcBKsjoFi4GkAFhJVqdgMZAUACvJ6hQsBpICYCVZnYLFQFIArCSrU7AYSAqAlWR1ChYDSQGwkqxOwWIgKQBWktUpWAwkBcBKsjoFi4GkAFhJVqdgMZAUACvJ6hQsBpICYCVZnYLFQFIArCSrU7AYSAqAlWR1ChYDSQGwkqxOwWIgKQBWktUpWAwkBcBKsjoFi4GkAFhJVqdgMZAUACvJ6hQsBpICYCVZnYLFQFIArCSr0x+1SgKrtZgbcAAAAABJRU5ErkJggg==

Here is a diff of expected vs actual image metadata (analyzed using sharp method metadata):

 {
+  "background" : {
+    "b" : 255,
+    "g" : 255,
+    "r" : 255
+  },
-  "channels" : 4,
+  "channels" : 3,
   "density" : 72,
   "depth" : "uchar",
-  "exif" : <buffer>,
   "format" : "png",
-  "hasAlpha" : true,
+  "hasAlpha" : false,
   "hasProfile" : false,
   "height" : 150,
   "isProgressive" : false,
   "space" : "srgb",
   "width" : 150
 }

Note that WebKit on Linux is adding a background, not including an alpha channel, and is not including exif data like other environments and browsers do. Potentially all 3 differences could be considered a bug.

I'm not sure if you set screenshot option omitBackground to true, whether or not WebKit in linux would respect that or not and start adding an alpha channel, so I'm not sure if this bug leads to visual differences where transparency is missing in screenshots taken by WebKit in Linux. In the screenshots we happen to be taking in our snapshot tests they are of web pages that have a background color, so we are noticing a metadata difference in the snapshot images not a visual difference. Because we are using Playwright as part of a larger system analyzing screenshots, having one environment generating images with a pretty different format (alpha channel without a background, vs no alpha channel with a background) is a cause for concern and something I'm glad our pretty strict image snapshot testing assertion function picked up.

dpino commented 2 months ago

Probably this is a bug upstream. In the case of WebKitGTK, the API for taking a snapshot stores only RGB information (CAIRO_FORMAT_RGB24).

https://github.com/WebKit/WebKit/blob/main/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp#L3047

Maybe it could be possible to change it to CAIRO_FORMAT_ARGB32 without side effects.

dgozman commented 2 months ago

@jaydenseric Thank you for the explanation. While it would be nice to have the same representation across platforms, that's not the goal for Playwright's screenshots. In fact, even rendering is often different between platforms, e.g. due to different system fonts. Therefore, I would not consider this a bug, but I would also not be opposed to align between platforms where possible.

@dpino Thank you for the pointer! I think we are using FrameSnapshotting in the web process at the moment, but when/if we switch to taking screenshots from the UI process, this would be a good place to fix indeed.