'when running testCafe some language constructs ruin the postMessage from an iFrame

So I encountered the maybe strangest thing in the last years. It took me hours to make it reproducible but still, I can not explain it at all.

I have an application that loads variable stuff in an iFrame. Then host and iFrame communicate via postMessage. The application is in use for years and there were never such problems in production or development as the one we encountered when we wanted to write e2e-tests in Testcafe. In the tests, the communication between host and client fails under certain circumstances: The iFrame sends a message with some data but the data attribute of the postMessage is undefined at the host's end. WTF.

Under what circumstances? It seems that, when certain language constructs are used in the JavaScript of the page inside the iFrame, the message gets distorted. Again: only when using Testcafe. Regardless of with Chrome, Chromium, or Firefox.

Ho to Reproduce:

Have a test.html:

<!DOCTYPE HTML>
<html>
  <body>
    <h1 id='output'>test</h1>
        <iframe srcdoc='<!DOCTYPE html><html><body>inner<script>setTimeout(() => {window.parent.postMessage({type: `communication worked`}, `*`);}, 1500);const x = new class { y = new class {} } </script></body></html>' sandbox="allow-forms allow-scripts allow-same-origin"></iframe>
    <script>
        window.addEventListener('message', (event) => {
          console.log({event});
          document.getElementById('output').innerText = event.data.type;
        });
    </script>
  </body>
</html>

Serve it with your favorite server. I use node with a server.js int his example, ng in the real-life application.

const connect = require('connect');
const serveStatic = require('serve-static');

var app = connect();

app.use(serveStatic(__dirname))

app.listen('8000', () => console.log('Server running on 8000...'));

And then, run the testcafe-test: npx testcafe firefox e2e/src/test.ts

fixture`Foo`
  .page`http://localhost:8080/test.html`;

test('Bar', async t => {
  await t.wait(120000);
});

As you can find in the browser console the host is receiving the message from the client, but its data is empty.

Now, remove those characters y = new class {} from the srcdoc. Do the test again. Communication works, seriously WTF.

Maybe using new class inside of new class might be a strange style. If it would even be bogus somehow, how come there is no error at all? And how can it distort the postMessage without even being connected to it in any way? How does this problem only occur with Testcafe, not when you run the code by yourself or even with Protractor? I am maximum clueless.

Some Details:

  • In the real life the iFrame's content can contain also a more complex app, written in angular, with which the same thing happens. I am not able to say if it's the very same language construct in this case which "breaks the postMessage-system of the whole page" or a different one.
  • It doesn't change if the content of the src doc is not hardcoded (naturally it's not in the real-life application)
  • I use testcafe 1.18.2, Firefox 91.5.0, Chromium 90.0, Google Chrome, Debian 10

I am very thankful for the slightest hint!



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source