cypress-shadow-patch
v3.8.3
Published
Makes Shadow DOM a first class citizen of Cypress
Downloads
4,496
Readme
⚠️ 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.
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
- ➤ Installation
- ➤ Usage
- ➤ FAQ
- What is missing right now?
- How does this library query the DOM?
- What makes this library special?
- What are the goals of this library?
- Why patch internals?
- Which internals are being patched?
- Why make Shadow DOM opt-out instead of opt-in?
- What are the limitations to the approach of this library?
- What versions of Cypress does this library work with?
- How can I support this library?
- What are some alternatives to this library?
- ➤ Example using with Github Actions
- ➤ Contributors
- ➤ License
➤ 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("[email protected]{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.
- 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.
- We want to show that it's possible to add native support for Shadow DOM within Cypress.
- 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, useel.getRootNode()
where applicable to get a Shadow Root instead.Instead of just finding
document.activeElement
, traverse recursively by usingactiveElement
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
andparent
.
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? |
➤ License
Licensed under MIT.