[Bug]: Playwright UI Preview Pane not showing SVG's with fill properties
Version
1.54.2
Steps to reproduce
-
Clone the following repo https://github.com/JohnCooling/playwright-svg-not-showing.git
-
Install node modules
npm i -
Run the React app
npm run start -
Run Playwright in UI mode in a new terminal
npx playwright test --ui -
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
Screenshot captured by Playwright test
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
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.
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)
And in the page profiling timeline
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:
Non-Headless:
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.
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
I have the same issue