How to make your site believe it isn't running in an iframe during Cypress E2E tests

May 11, 2020

Cypress is a fantastic front end testing tool but has one major limitation. I already blogged about it a while ago. The limitation is that it runs all tests within an iframe. This iframe approach makes sense, as it allows the tool to show the running tests and the page in one view. For me, this is also one of the strengths of the tool itself, but it could also make it impossible to test specific sites.

Info: you can find my related article about setting up Cypress for SharePoint testing here: https://www.eliostruyf.com/cypress-testing-sharepoint-solutions/

For example, when running Cypress against SharePoint, it will be a different experience. Most of the Microsoft 365 and SharePoint controls would not be loaded. The positive side about it is that it speeds the page load time enormously, but the downside is that you cannot test your solution from A to Z.

Here is a screenshot of my page loaded in a browser:

Page loaded in a browser
Page loaded in a browser

Notice the differences here with loading it in Cypress:

Page loaded in Cypress
Page loaded in Cypress

This iframe approach does not only affect tests running against SharePoint but other sites as well. The issue with SharePoint is that you do not own the platform, so you cannot make any modifications to make sure it loads these elements whenever it is testing in Cypress.

How to trick your site to load the full page experience

If you own/control the platform/site, you can verify if your website loads from Cypress with window.Cypress, and if that is the case, you could allow the elements to be loaded.

Info: Detect if a site/app is running under Cypress: https://docs.cypress.io/faq/questions/using-cypress-faq.html#Is-there-any-way-to-detect-if-my-app-is-running-under-Cypress

If you do not have control or do not want to do any code changes, you can also make use of the cy.stub functionality. Stubs allow you to modify a function so that you gain control over it during your tests.

Info: Read more on how to use stubs here: https://docs.cypress.io/api/commands/stub.html#Syntax

What if you do not have control, and there is no function to stub? This issue is the case when testing against SharePoint. SharePoint provides only the minified code to you, which means that the primary object name can be different with each version. Stubbing should still be a solution, but you might end up doing a lot of updates.

So how can we solve this issue?

First, you need to verify how the platform is doing the iframe check. In most cases, they will use window.parent !== window or window.top !== window, and this is where we are going to trick the site into believing it is the same.

The solution

The way to trick your browser is not so hard. Usually, when you use the cy.visit method to open a specific page with Cypress.

1
cy.visit(config.pageUrl);

What you can do, add the onBeforeLoad function. This function allows you to prepare things on the page before it gets loaded. To trick the site, all you need to do is this:

1
2
3
4
5
6
cy.visit(config.pageUrl, {
  onBeforeLoad: (win) => {
    // Let the child think it runs in the parent
    win["parent"] = win;
  }
});

The result of this change looks like this:

Fully loaded page in Cypress
Fully loaded page in Cypress

Example project

I have adapted the example project to include this scenario for you to check out the code. You can find the project here: https://github.com/estruyf/cypress-sharepoint-sample.

Happy testing

Comments

comments powered by Disqus