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
66.48k stars 3.64k forks source link

[BUG] `.toHaveScreenshot()` does not respect `backface-visibility: hidden;` CSS property #21620

Open ngnijland opened 1 year ago

ngnijland commented 1 year ago

System info

Source code

HTML and CSS is to sketch the situation. The screen recordings should give more context to the issue.

<div class="card-wrapper">
  <div class="card card--rotate-to-front">
    <div class="card-face card-face--front">
      <div class="card-frame card-frame--front" style="transform: none;"></div>
    </div>
    <div class="card-face card-face--back">
      <div class="card-frame card-frame--back"></div>
    </div>
  </div>
</div>
.card-wrapper {
     perspective: 800px;
}

.card {
    transform-style: preserve-3d;
}

.card--rotate-to-front {
    animation: rotateBounceToFront;
    animation-duration: 1s;
    animation-fill-mode: forwards;
}

.card--rotate-to-back {
    animation: rotateBounceToBack;
    animation-duration: 1s;
    animation-fill-mode: forwards;
}

.card-face {
    backface-visibility: hidden;
}

The above HTML and CSS (among other code) result in the following interface: https://user-images.githubusercontent.com/4727742/224694220-047a0a1a-0ed4-4315-865e-e4f8480027b2.mov

Config file

// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  projects: [
    {
      name: "Mobile Safari",
      use: { ...devices["iPhone 12"] },
    },
});

Test file (self-contained)

test("gift cards", async ({ page, isMobile }) => {
    await page.goto("/gift-card");

    await page.getByText("Wondrous waterways").click();
    await expect.soft(page).toHaveScreenshot("card.png");
});

Steps

Expected

Front of the card should be visible.

Actual

Back of the card is visible mirrored.

NOTE: The behavior of seeing the back of the card mirrored is the same as when you remove backface-visibility: hidden; css property from the .card-face class.

Video of the actual behavior:

https://user-images.githubusercontent.com/4727742/224695831-17ccd2f3-ee0e-4c77-85af-0fdc183595e3.mov

dgozman commented 1 year ago

I was able to reproduce with an example from MDN.

repro test here ```ts import { test, expect } from '@playwright/test'; test('issue', async function ({ page }) { await page.setContent(`
backface-visibility: visible; backface-visibility: hidden;
1
2
3
4
5
6

Since all faces are partially transparent, the back faces (2, 4, 5) are visible through the front faces (1, 3, 6).

1
2
3
4
5
6

The three back faces (2, 4, 5) are hidden.

`); await expect(page).toHaveScreenshot(); }); ```
dimkin-eu commented 1 year ago

having same with 1.32.1, but not with 1.31.1 ( which is strange )

comparing screenshots with this property in reset.css makes some elements to look "transparent"

    -webkit-backface-visibility: hidden;
yury-s commented 1 year ago

Looks like the problem has to do with CSS perspective property which is not respected on the screenshots:

      perspective: 550px;
      perspective-origin: 150% 150%;
repro ```ts import { test, expect } from '@playwright/test'; test('issue', async function ({ page }) { await page.setContent(`
3
`); await expect(page).toHaveScreenshot(); }); ```
yury-s commented 1 year ago

Turns out this is an upstream issue: https://bugs.webkit.org/show_bug.cgi?id=207266

dimkin-eu commented 1 year ago

@yury-s now we just wait for webkit devs ? :(

yury-s commented 1 year ago

Another related upstream bug: https://bugs.webkit.org/show_bug.cgi?id=242215