playwright icon indicating copy to clipboard operation
playwright copied to clipboard

[Bug]: Playwright UI Preview Pane not showing SVG's with fill properties

Open JohnCooling opened this issue 4 months ago • 6 comments

Version

1.54.2

Steps to reproduce

  1. Clone the following repo https://github.com/JohnCooling/playwright-svg-not-showing.git

  2. Install node modules npm i

  3. Run the React app npm run start

  4. Run Playwright in UI mode in a new terminal npx playwright test --ui

  5. Run the test

Expected behavior

Given I am a developer When I run Playwright in UI mode Then I expect to see SVG's rendered in the preview pane

Notes: When you browse to the running instance of the application http://localhost:3006; both Hello World text and the secure padlock are rendered.

Actual behavior

When Playwright runs a test, the preview pane is not showing a SVG icon which has a css fill property; the underlying HTML and SVG are loading correctly on page load, but for some reason; the CSS fill prop isn't being applied to the icon.

The test also captures a screenshot using playwright, this does show the icon correctly.

Additional context

App running, with playwright UI mode difference

Image

Screenshot captured by Playwright test

Image

Environment

System:
    OS: macOS 15.2
    CPU: (12) arm64 Apple M4 Pro
    Memory: 264.50 MB / 24.00 GB
  Binaries:
    Node: 21.7.0 - ~/.nvm/versions/node/v21.7.0/bin/node
    npm: 10.5.0 - ~/.nvm/versions/node/v21.7.0/bin/npm
  IDEs:
    VSCode: 1.96.3 - /Applications/Visual Studio Code.app/Contents/Resources/app/bin/code
  Languages:
    Bash: 3.2.57 - /bin/bash
  npmPackages:
    @playwright/test: ^1.54.2 => 1.54.2

JohnCooling avatar Aug 06 '25 20:08 JohnCooling

SVGs are not mere images; they are XML documents that can contain HTML and JavaScript. Because of this, the browser considers them much more risky than images. Specifically use copies elements from a remote host to the current page.

Most likely this is why your SVGs are being blocked. SVGs function in general in Trace Viewer and UI Mode. It also could be a strict CORS issue, depending on your server's configuration.

agg23 avatar Aug 07 '25 19:08 agg23

general in Trace Viewer and UI Mode. It also could be a strict CORS issue, depending on your server's configuration.

Thanks for the advise but I have to disagree in this case; the icon is being loaded correctly by the UI mode but its not rendered on the preview pane.

SVG's without a fill property render without any issue.

These are the request / responses should they be of any further use

General
  URL: http://localhost:3006/secure-m-default.svg
  Method: GET
  Status Code: 200 OK
Request Headers
  Accept: image/svg+xml
  Sec-Fetch-Site: same-origin
  Sec-Fetch-Dest: image
  Accept-Language: en-US
  Sec-Fetch-Mode: same-origin
  Host: localhost:3006
  User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Safari/605.1.15
  Referer: http://localhost:3006/
  Accept-Encoding: gzip, deflate
  Connection: keep-alive
Response Headers
Content-Type: image/svg+xml
Access-Control-Allow-Origin: *
Keep-Alive: timeout=5
Last-Modified: Wed
Last-Modified: 06 Aug 2025 19:42:30 GMT
Access-Control-Allow-Methods: *
Access-Control-Allow-Headers: *
Cache-Control: public
Cache-Control: max-age=0
Date: Thu
Date: 07 Aug 2025 20:03:57 GMT
Content-Length: 788
Connection: keep-alive
Accept-Ranges: bytes
ETag: W/"314-19880e815e4"
Vary: Accept-Encoding
X-Powered-By: Express

Interestingly, the icon shows in the image preview (in the network tab)

Image

And in the page profiling timeline

Image

JohnCooling avatar Aug 07 '25 20:08 JohnCooling

I think I've managed to narrow it down to the svg content not being added to the shadow dom in headless mode; when headless is disabled, I can see the icon appearing as expected.

Headless:

Image

Non-Headless:

Image

JohnCooling avatar Aug 07 '25 21:08 JohnCooling

Ah, I think we misunderstood each other. It's not a CORS issue with your application, that is, Chrome was not allowed to load your SVG. It's a CORS issue with the information presented by your application server and how Playwright renders traces.

Playwright uses a service worker to mock all network requests in the preview. However, SVGs are much more strict than other assets, so the request doesn't even hit the service worker, so Playwright has no chance to load it. I believe this is due to the application server's CORS configuration. I think this is likely alleviated by using something other than the use tag for the SVG, and can also be improved by less strict CORS on the host server. This doesn't apply to images as images are considered benign and are allowed for cross origin in most scenarios.

agg23 avatar Aug 08 '25 13:08 agg23

My previous responses were unclear. First of all, this is an issue specifically with Playwright's Trace Viewer/UI Mode. In your case you may be able to properly load the SVG if you change how you load it (not using the use tag), but I'm not sure that will fix it.


SVGs under certain conditions are held to higher CORS standards, similar to fonts and a few other things. Under these conditions, the service worker never gets a chance to intercept because it's killed by preflight checks. As far as I know, the only thing we can do to fix that is make the request not cross origin, or rewrite the URL

agg23 avatar Aug 19 '25 12:08 agg23

I have the same issue

artsiom-voitas avatar Nov 28 '25 13:11 artsiom-voitas