4

Basically I'm trying to use cypress to run tests on my Svelte app. But I need to use a web worker but it gets blocked by this error when I try on Cypress (with Chrome):

DOMException: Failed to execute 'postMessage' on 'Worker': SharedArrayBuffer transfer requires self.crossOriginIsolated.

Normally it works, I've set the following headers on the svelte.config.js file:

/** @type {import('vite').Plugin} */
const viteServerConfig = {
    name: 'log-request-middleware',
    configureServer(server) {
        server.middlewares.use((req, res, next) => {
            res.setHeader("Access-Control-Allow-Origin", "*");
            res.setHeader("Access-Control-Allow-Methods", "GET");
            res.setHeader("Cross-Origin-Opener-Policy", "same-origin");
            res.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
            next();
        });
    }
};

while on Cypress, to try to solve this I've set the chromeWebSecurity to false on the cypress.config.js, but nothing changes. The worker gets loaded normally if I look inside network, but the post message fails with that error, any clue?

Gum Rick
  • 205
  • 2
  • 13

1 Answers1

4

I'm not sure who (Vite, Svelte, Cypress), but something in your code wants to use a SharedArrayBuffer.

SharedArrayBuffer was removed from all browsers in 2018 because of the Spectre and Meltdown attacks. The Chrome feature known as Site Isolation allowed it to return, as long as the site requesting to use SharedArrayBuffer is in state known as crossOriginIsolated.

In order to achieve cross origin isolation, you need to configure 3 HTTP response headers:

  1. Cross-Origin-Resource-Policy (CORP)
  2. Cross-Origin-Opener-Policy (COOP)
  3. Cross-Origin-Embedder-Policy (COEP)

As Eiji Kitamura explains in this video, you need to do 3 things:

  1. add the Cross-Origin-Opener-Policy (COOP) response header to the top-level document returned by your server. Its value should be same-origin.
  2. add the Cross-Origin-Resource-Policy (CORP) response header to all assets you are self-hosting on your origin. Its value should be same-site. You should also check that cross-origin resources that you want to include on your site (e.g. a YouTube <iframe>) are returned with Cross-Origin-Resource-Policy: cross-origin. If a cross-origin server (i.e. a server you don't control) does not add the CORP header to the resources it returns, it could also return a Cross-Origin Resource Sharing (CORS) header, but you would need to add a crossorigin attribute to those cross-origin resources (e.g. <img src="some-image-not-on-your-site.png" crossorigin>).
  3. add the Cross-Origin-Embedder-Policy (COEP) response header to the top-level document returned by your server. Its value should be require-corp.

Also, please keep in mind this point from the cross-origin-isolation-guide:

Make sure there are no cross-origin popup windows that require communication through postMessage(). There's no way to keep them working when cross-origin isolation is enabled. You can move the communication to another document that isn't cross-origin isolated, or use a different communication method (for example, HTTP requests).

You may also take a look at this talk about cross-origin fetches.

jackdbd
  • 4,583
  • 3
  • 26
  • 36
  • So, as I said I already set the headers, and it all works good on chrome, but if use cypress with chrome it doesn't, it gives me the cors issue that it's solved on normal chrome cause I've setted the headers as shown in my question. – Gum Rick Jul 19 '22 at 14:06
  • does the error still occur if you use `$window.dispatchEvent(messageEvent)` instead of `postMessage()`, as it's written here? https://github.com/cypress-io/cypress/issues/6429#issuecomment-1079197535 – jackdbd Jul 19 '22 at 14:41