cypress-shadow-patch
TypeScript icon, indicating that this package has built-in type declarations

3.8.3 • Public • Published

⚠️ This library is still in it's early days. Expect a few rough edges during the first couple of weeks. If you encounter anything unexpected, please open an issue and we will fix it as quickly as possible.

Cypress Shadow Patch

This library makes Shadow DOM a first class citizen of Cypress.

Commands such as get, contains, click and type now understand Shadow DOM, so you get all the sweetness of Cypress while maintaining the benifits of Shadow DOM. You no longer have to worry about using special commands for dealing with Shadow DOM, - everything just works out of the box.

This library does it by patching internals of Cypress. First of all this shows that it's possible for Cypress to support Shadow DOM. The patch also acts as a guide for where Cypress could update it's own code if they were to add native support for Shadow DOM in the future.

If you are interested in showing support for natively having Shadow DOM support in Cypress, please go to this issue and take part in the discussion.

📖 Table of Contents

-----------------------------------------------------

➤ Table of Contents

-----------------------------------------------------

➤ Installation

1. Install the dependency

The package is distributed via npm and should be installed as one of your project's devDependencies.

npm install cypress-shadow-patch -D

2. Overwrite commands

Add the following line to the top of cypress/support/commands.js

import "cypress-shadow-patch";

3. Patch Cypress Internals

In order to apply the Shadow DOM patch to your local installation of Cypress you will have to run the following command. This command will tell you what's being patched. Read the FAQ to learn why we need to apply this patch.

npx cypress-shadow-patch apply

Note: You can always remove the patch by running npx cypress-shadow-patch reset or cypress cache clear.

To automate this process we recommend that you add a postinstall script to your package.json file like this:

{
  "scripts": {
    "postinstall": "npx cypress-shadow-patch apply"
  }
}

-----------------------------------------------------

➤ Usage

After installation you can use Cypress as you normally would. Selectors now support JQuery and can pierce through shadow boundaries.

cy.contains("Elements").click();
 
cy.get("#container my-text-field[name=email]").type("test@test.com{enter}");
 
cy.get("container-element")
  .contains("Get Started")
  .click();

In order to only search in light dom, use { shallow: true }.

cy.get("#get-started", { shallow: true }).click();

-----------------------------------------------------

➤ FAQ

What is missing right now?

A lot of commands/features have been tested with this library, but some commands might not work with Shadow DOM right now. In this section we will note if we find commands/features that do not yet work with cypress-shadow-patch.

  • Snapshots might not work in all cases.

How does this library query the DOM?

This library uses the wonderful library query-selector-shadow-dom to query the DOM. This library provides a querySelector that can pierce shadow boundaries without knowing the path through nested shadow roots.

We patched the library to support JQuery selectors because Cypress require JQuery support.

What makes this library special?

A shortcoming with existing approaches for adding Shadow DOM support to Cypress is that they need to 'reimplement' various Cypress commands. For example, you can no longer use type, but you will have to use shadowType and so on. This is needed because Cypress validates input/output to commands that are executed to ensure that they, for example, are connected to the DOM. Cypress doesn't think elements within Shadow Roots are connected to the DOM and fails.

The thing that makes this library special is that you can use the existing commands documented in Cypress with Shadow DOM support.

What are the goals of this library?

The overall goal is to seamlessly make Shadow DOM a first-class citizen of Cypress. Here are some of the most important design goals we had in mind while building this library.

  1. It should be possible to use Cypress with exactly the same API and functionality as you are used to when dealing with the light dom.
  2. We want to show that it's possible to add native support for Shadow DOM within Cypress.
  3. When Cypress in the future hopefully adds native support for Shadow DOM you should be able to remove this library and all of your tests should still work without any refactoring.

Why patch internals?

We decided that, in order achieve our goals as decribed above, we needed to patch the internals within Cypress. An alternative solution would have been to upload/publish executables from a fork of Cypress, but we decided against it because we think this will become a bigger burden than simply applying the patch using the CLI.

Which internals are being patched?

We maintain a fork of Cypress with Shadow DOM support. Here you can see which changes we made to the internals of Cypress. Feel free to contribute.

Here is a short overview of the main challenges encountered:

Cypress:

  • Cypress assumes that root of a node is always the document of the node by using el.ownerDocument, but this is not always the case. Instead, use el.getRootNode() where applicable to get a Shadow Root instead.

  • Instead of just finding document.activeElement, traverse recursively by using activeElement through shadow boundaries.

JQuery:

  • Cypress heavily depends on JQuery which doesn't support Shadow DOM. This library overwrites JQuery methods that don't understand Shadow DOM such as isConnected and parent.

Why make Shadow DOM opt-out instead of opt-in?

The aim of this library is to make Shadow DOM a native part of Cypress. When writing tests, you shouldn't care about shadow boundaries, you should care about writing good tests with simple selectors. Therefore we chose to make Shadow DOM opt-out instead of opt-in.

What are the limitations to the approach of this library?

The main limitation of patching Cypress internals is the fact that we need to generate a new patch for each new version of Cypress to keep the patch up-to-date with the new code. This means that this library will always be slighty behind in supporting the newest version of Cypress. We generate the patch using a fork of Cypress and diffing the file cypress_runner.js.

What versions of Cypress does this library work with?

We will make sure to add a new patch for each new major and minor versions of Cypress. Currently this library works with the following versions of Cypress:

  • 3.8.0

How can I support this library?

You are more than welcome to give our library a spin and give us feedback on how we might improve it. If you like the library you are more than welcome to share it with other people you think you know about this tiny corner of the internet.

This library is still in its early days. If you find a bug, a use-case that is not covered or have any ideas for improvements you are very welcome to open an issue on this repository.

What are some alternatives to this library?

A lot of awesome people have already built some great libraries that adds support for Shadow DOM in Cypress. Here are a few of the ones we could find:

-----------------------------------------------------

➤ Example using with Github Actions

If you use this library you will also need to patch Cypress when running your CI. Here's an example on how you would run your Cypress tests using Github Actions.

- uses: cypress-io/github-action@v1
  with:
    browser: chrome
    build: npm run build_and_patch

Note: The command build_and_patch would need to build your project and run cypress-shadow-patch apply.

Important: You will need to patch Cypress in the build hook because the Github action cypress-io/github-action@v1 overwrites the Cypress executable when running. Therefore you cannot patch Cypress before this action.

-----------------------------------------------------

➤ Contributors

Rune Mehlsen Andreas Mehlsen Frederik Wessberg You?
Rune Mehlsen Andreas Mehlsen Frederik Wessberg You?

-----------------------------------------------------

➤ License

Licensed under MIT.

Dependencies (5)

Dev Dependencies (9)

Package Sidebar

Install

npm i cypress-shadow-patch

Weekly Downloads

884

Version

3.8.3

License

MIT

Unpacked Size

100 kB

Total Files

26

Last publish

Collaborators

  • runebm