{"id":17274446,"url":"https://github.com/codedrivenmitch/wdio-webcomponents","last_synced_at":"2025-10-26T02:41:52.540Z","repository":{"id":67952329,"uuid":"105857434","full_name":"CodeDrivenMitch/wdio-webcomponents","owner":"CodeDrivenMitch","description":"Webdriver.io plugin to support Shadow DOM","archived":false,"fork":false,"pushed_at":"2021-05-20T17:58:11.000Z","size":36,"stargazers_count":16,"open_issues_count":4,"forks_count":7,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-06-27T08:43:40.141Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CodeDrivenMitch.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-10-05T06:40:28.000Z","updated_at":"2025-05-30T22:33:43.000Z","dependencies_parsed_at":null,"dependency_job_id":"50bf6f8b-f00a-42d8-98fa-ece3711b1329","html_url":"https://github.com/CodeDrivenMitch/wdio-webcomponents","commit_stats":null,"previous_names":["morlack/wdio-webcomponents"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/CodeDrivenMitch/wdio-webcomponents","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeDrivenMitch%2Fwdio-webcomponents","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeDrivenMitch%2Fwdio-webcomponents/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeDrivenMitch%2Fwdio-webcomponents/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeDrivenMitch%2Fwdio-webcomponents/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CodeDrivenMitch","download_url":"https://codeload.github.com/CodeDrivenMitch/wdio-webcomponents/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeDrivenMitch%2Fwdio-webcomponents/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267578003,"owners_count":24110351,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-28T02:00:09.689Z","response_time":68,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-15T08:53:57.348Z","updated_at":"2025-10-26T02:41:47.507Z","avatar_url":"https://github.com/CodeDrivenMitch.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# wdio-webcomponents\n\n!!!! Unsupported notice !!!\nI have developed this plugin in the times I developed on webcomponents with a Shadow DOM. I have not done this for quite some time however, and am currently not updating this plugin. If you'd like to take over support, send me a mail at mitchellherrijgers@gmail.com. Thanks!\n\n\n\nwdio-webcomponents is a webdriver.io plugin which makes webdriver compatible with Open Shadow Roots. \n\nShadow DOMs are a great solution to encapsulate your components from the rest of your application, but it prevents your components from easily being e2e tested. Normal Selenium commands fail,\ndue to the element actually not beind in the main document. \n\nWith the rise of Shadow DOM in webcomponent applications, we need a solution to test the components using Webdriver(Selenium). This plugin is that solution!\n\nWhen this plugin is enabled, every Webdriver command will work with Shadow DOMS.\n\n## Installation\nInstall the npm lib:\n\n`npm install wdio-webcomponents --save-dev`\n\nThen add the plugin to your `wdio.conf` under plugins.\n\n```javascript\n{\n    plugins: {\n        'wdio-webcomponents': {}\n    }\n}\n```\n\n## How to use\nYou can use it just like you normally use webdriver. However, there are some pitfalls:\n \n- You can only use CSS selectors.\n- The selector should contain every Shadow Host on the way to the element. (Read down for explanation)\n- Visibility is checked recursively (Read down for explanation)\n\nFor examples on how to use it, the internal test suite contains a lot of examples. These examples 'test' the Polymer example shop.\n\nYou can find the test-suite at [https://github.com/Morlack/wdio-webcomponents/blob/master/test/wdio/specs/main.spec.js](https://github.com/Morlack/wdio-webcomponents/blob/master/test/wdio/specs/main.spec.js)\n\n### Visibility checks\nOne of the things that are hard to solve with Selenium and Shadow DOM is checking the visiblity of a selected element. \n\nThis is because Selenium checks whether the element is visible or not by checking styling and attributes on the element and it's parents. \nIf the element, or one of it's parents, are hidden (such as when display is set to none) the element is considered invisible. \nThis becomes a problem when Selenium can't check outside the Shadow DOM, since the Shadow DOM can be located inside an element. \n\nYou can find the code where Selenium checks visibility here: https://github.com/SeleniumHQ/selenium/blob/master/javascript/atoms/dom.js#L437 (This is the Javascript version). \n\nBecause of the we have to check whether all shadow hosts on the way are visibile. This is built in and you don't have to do anything for it. \n\nHowever, there are some cases where part of the visibility check should be skipped. For example when your element is located inside an invisible element (element itself is absolute with width and height, but it's parent has a height of 0 and thus it's invisible). In this case you can add `:skip-visible` to the element. For example, the selector 'could' become: `my-app my-dialog-wrapper:skip-visible my-element`. In this case, only the `my-app` and `my-element` will be checked for visibility.\n\n### Shadow Host inclusion\nA Shadow host is an element which has at least a Shadow DOM, and might have a light DOM. The Light DOM is\ncontent added through slot/content tags. The Actual HTML of a component having both might look like this:\n\n```html\n\u003cmy-awesome-element\u003e\n    #shadow-root\n        \u003cdiv class=\"shadow\"\u003eThis is a shadow DOM element!\u003c/div\u003e\n        \u003cslot\u003e\u003c/slot\u003e\n    \u003c!-- End shadow root --\u003e\n\n    \u003cp class=\"light\"\u003eThis is a light DOM element!\u003c/p\u003e\n\u003c/my-awesome-element\u003e\n```\n\nWhen considering the markup above, the shadow and light dom elements are queried differently. To query either of them, use the following selectors:\n\n#### Querying Shadow DOM\nShadow selector: `my-awesome-element .shadow` \n\nResulting JS: `document.querySelector('my-awesome-element).shadowRoot.querySelector('.shadow')`\n\nThe resulting JS shows how the plugin works internally. This is because you can only query elements in a Shadow DOM from the shadowRoot of the host element.\n\n#### Querying light DOM\n\nLight selector: `my-awesome-element::.light` \n\nResulting JS: `document.querySelector('my-awesome-element .light')`\n\nSince we do not need to descend into a shadowRoot, but `my-awesome-element` has one, we want to prevent descending. \nThe `::` syntax is here to provide this; When concatenating selectors using `::` they will be executed in the same `querySelector` call.\n\nNote that when there are nested shadowRoots, you need to include the parent Shadow Hosts. Example:\n\n```html\n\u003cmy-awesome-element\u003e\n    #shadow-root\n        \u003cmy-awesome-nested-element\u003e\n            #shadow-root\n                \u003cp class=\"shadow\"\u003eThis is a Shadow DOM element\u003c/p\u003e\n                \u003cslot\u003e\u003c/slot\u003e\n            \u003c!-- End nested shadow root --\u003e\n            \n            \u003cp class=\"nested-light\"\u003eThis is another light DOM element!\u003c/p\u003e\n        \u003c/my-awesome-nested-element\u003e\n    \u003c!-- End top-level shadow root --\u003e\n\n    \u003cp class=\"light\"\u003eThis is a light DOM element!\u003c/p\u003e\n\u003c/my-awesome-element\u003e\n```\n\nIn the above case, to retrieve the `.nested-light` element, you will need to use `my-awesome-element my-awesome-nested-element::.nested-light` selector. \n\n\n## Internal workings\nThe plugin works by replacing the `browser.element` and `browser.elements` commands with another implementation. All other webdriver commands use these two functions, so overriding these two fixes all other commands.\n\nIt uses a Javascript function, sent to the browser, to find the correct element/elements in or outside of a Shadow DOM. The implementation is based on ChadKillingsworth's code, that can be found here: [https://gist.github.com/ChadKillingsworth/d4cb3d30b9d7fbc3fd0af93c2a133a53](https://gist.github.com/ChadKillingsworth/d4cb3d30b9d7fbc3fd0af93c2a133a53)\n\nThe code in this plugin has been modified to support more use cases, non-shadowroots and multiple element selection. You can find it in `src/finders/findElement.js`. \n\n \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodedrivenmitch%2Fwdio-webcomponents","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodedrivenmitch%2Fwdio-webcomponents","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodedrivenmitch%2Fwdio-webcomponents/lists"}