How to test a basic (No Javascript) experience in Testcafé

I am relatively new to Testcafé testing framework that claims for:

End-to-end testing, simplified No WebDriver required. No manual timeouts needed. Cross-browser testing out-of-the-box.

I must admit the syntax is a bit confusing at first, but you get quickly up to speed, thanks to useful documentation, what is quite rewarding.

Progressive enhancement

I do care a great deal about Progressive enhancement. This is my go to approach to build components and experiences for the web.
First deliver a basic experience that works without Javascript, and then second, if Javascript is available and if the browser in use can support the enhancement, deliver the enhanced experience.

If you are doing Agile developement, this fits perfectly as you could first ship a basic working experience and in the next iteration the enhanced experience.

What I needed

In order to gain confidence upon the fact that both my basic and enhanced experiences are working, I needed to be able to:

  1. Test the basic experience when the Javascript that enhances my component is unavailable
  2. Test the enhanced experience when the Javascript that enhances my component is available

We, from the Testcafé configuration, have no such thing as an option to disable Javascript, and most especially because Testcafé runs using Javascript in the browser that drives the test.

Solution

Important: For this solution to work, the Javascript holding the code necessary for the enhancement should be an external file.
Why? Because the hack is to fake that the Javascript file is Not found, resolving to a 404 status code.

To perform this lie, we can use Testcafé Request Mock feature.

A request mocker that intercepts requests to a web resource and emulates the response.

The small code snippet below led me to success:

const turnOfJavascriptMock = RequestMock()
    .onRequestTo(new RegExp('.*\.js'))
    .respond(null, 404);

This is how you instanciate the mock to make any requested .js file in the page under test to respond with a 404 Not Found.

Now you can use this mock in your tests as below:

test
	.page `URL-OF-PAGE-UNDER-TEST`
(`Enter your test label here for the enhanced experience`, async t => {
	// Add your assertions here
});

test
	.page `URL-OF-PAGE-UNDER-TEST`
	.requestHooks(turnOfJavascriptMock)
(`Enter your test label here for the basic experience`, async t => {
	// Add your assertions here
});

The magic operates through the call to .requestHooks() function that takes our Request Mock as argument and applies it the page under test.

Conclusion

Using a very concise Request Mock that turns off any external Javascript we are able to end-to-end test the fall back experience of our enhanced experience, i.e the basic experience 😉.