percy / cli

The Percy CLI is used to interact with, and upload snapshots to, percy.io via the command line.
https://docs.percy.io/docs/cli-overview
70 stars 43 forks source link

BUG: Failed to execute 'btoa' on 'Window` due to some CSS from bootstrap 5 #1204

Closed cgaube closed 1 year ago

cgaube commented 1 year ago

The problem

When trying to create the snapshot, percy and percy/storybook fail because it cannot serialize some text. Error: DOMException: Failed to execute 'btoa' on 'Window

// converts text to base64
let content = window.btoa(data);

https://github.com/percy/cli/blob/520bd156af47080881b651e4819014cbacf76781/packages/dom/src/utils.js#LL23C35-L23C35

This is happening because im injecting some CSS in the web element shadow dom More precisely this is coming from BOOTSTRAP CSS https://github.com/twbs/bootstrap/blob/main/scss/_type.scss#L104

 content: "\2014\00A0"; // em dash, nbsp

Environment

Debug logs

[percy:config] Config file not found (0ms)
[percy:storybook] Requesting Storybook: http://localhost:55245 (29ms)
[percy:core:browser] Launching browser (11ms)
[percy:core:browser] Browser connected [2966]: HeadlessChrome/96.0.4664.0 (335ms)
[percy:core] Percy has started! (1ms)
[percy:core:page] Page created (40ms)
[percy:core:page] Page created (2ms)
[percy:core:page] Navigate to: http://localhost:55245/?path=/settings/about (106ms)
[percy:core:page] Navigate to: http://localhost:55245/iframe.html (0ms)
[percy:core:page] Page navigated (20ms)
[percy:core:page] Page navigated (107ms)
[percy:core:page] Page closed (4ms)
[percy:core:page] Page closed (5005ms)
[percy:core:page] Page created (7ms)
[percy:core:page] Navigate to: http://localhost:55245/iframe.html (34ms)
[percy:core:page] Page navigated (97ms)
[percy:core:page] Taking snapshot: Theme/Buttons: Primary (11ms)
[percy:core:discovery] Wait for 100ms idle (1ms)
[percy:core:page] Inject @percy/dom (102ms)
[percy:core:page] Serialize DOM (3ms)
[percy:core:page] Page closed (5ms)
[percy:core] Stopping percy... (1ms)
[percy:core:browser] Closing browser (0ms)
[percy:core:browser] Browser closed (13ms)
[percy:core] Build not created (0ms)
[percy:cli] Error: DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.
    at resourceFromText (<anonymous>:144:28)
    at serializeCSSOM (<anonymous>:238:26)
    at serializeElements (<anonymous>:475:9)
    at serializeElements (<anonymous>:482:11)
    at Object.serializeDOM (<anonymous>:514:7)
    at <anonymous>:11:29
    at withPercyStorybookHelpers (<anonymous>:13:8)
    at withPercyHelpers (<anonymous>:64:3)
    at withPage (file:///XXXX/node_modules/.pnpm/@percy+storybook@4.3.5/node_modules/@percy/storybook/dist/utils.js:113:47)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async takeStorybookSnapshots (file:///XXXX/node_modules/.pnpm/@percy+storybook@4.3.5/node_modules/@percy/storybook/dist/snapshots.js:187:5)
    at async Object.callback (file:///XXX/node_modules/.pnpm/@percy+storybook@4.3.5/node_modules/@percy/storybook/dist/storybook.js:36:3)
    at async generatePromise (file:///XXXX/node_modules/.pnpm/@percy+core@1.20.3/node_modules/@percy/core/dist/utils.js:85:115)
    at async runCommandWithContext (file:///XXX/node_modules/.pnpm/@percy+cli-command@1.20.3/node_modules/@percy/cli-command/dist/command.js:132:3)
    at async percy (file:///XXX/node_modules/.pnpm/@percy+cli-command@1.20.3/node_modules/@percy/cli-command/dist/command.js:162:9)
    at async /XXXX/node_modules/.pnpm/@percy+cli@1.20.3/node_modules/@percy/cli/bin/run.cjs:13:5 (1ms)
 ELIFECYCLE  Command failed with exit code 1.
samarsault commented 1 year ago

@cgaube thanks for reporting this. This is happening because btoa doesn't support unicode characters, which bootstrap seems to be using. We're looking into this and will get back to you soon.

cgaube commented 1 year ago

Thanks @samarsault Looking forward to that

I did some testing around and removing the call to btoa seem to make everything work for me. I must be missing some context but I am not sure why this data has to be base64 for it to work

let content = data;
samarsault commented 1 year ago

Are you using bootstrap with adoptedStylesheets? We use btoa to create a serialized resource at our server for an adoptedStylesheet, and the server expects a byte data buffer.

cgaube commented 1 year ago

We are using Lit to create web components and for styles they tell us to do this https://lit.dev/docs/components/styles/

I believe their css function does use adoptedStylesheet under the hood https://github.com/lit/lit/blob/c10df5d71ed08e4834959fe1ed9e865f13c0e31b/packages/reactive-element/src/css-tag.ts#L11

Thank you