Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ShadowDOM support request #4367

Open
firstor opened this issue Jul 6, 2017 · 58 comments
Open

ShadowDOM support request #4367

firstor opened this issue Jul 6, 2017 · 58 comments
Labels

Comments

@firstor
Copy link

firstor commented Jul 6, 2017

Seems that ShadowDOM support is still missing:

Background

I am working with some Polymer 2 components which implements ShadowDOM v1 spec and I need to select elements inside their shadowRoots to run e2e tests. deepCss might be a solution but it doesn't work for me. As far as I can see, by.deepCss is nothing special difference with by.css but appending * /deep/ at the beginning of the given CSS selector, however, /deep/ seems deprecated on the browser.

I am working with the following versions:

  • Node Version: v6.10.3
  • Protractor Version: v5.1.2
  • Angular Version: v4.2.4
  • Browser(s): Chrome
  • Operating System and Version: Ubuntu v16.04.2 AMD64 LTS Xenial

I think I checked all relevant articles including the followings and I couldn't get any satisfied answer:

Workaround

Anyway, I can select inner elements of ShadowDOM elements by adding a custom locator. Here is my workaround:

/**
 * Usage:
 *   O  element(by.css_sr('#parentElement #innerElement'))          <=> $('#parentElement #innerElement')
 *   O  element(by.css_sr('#parentElement::sr #innerElement'))      <=> $('#parentElement').shadowRoot.$('#innerElement')
 *   O  element.all(by.css_sr('#parentElement .inner-element'))     <=> $$('#parentElement .inner-element')
 *   O  element.all(by.css_sr('#parentElement::sr .inner-element')) <=> $$('#parentElement').shadowRoot.$$('.inner-element')
 *   O  parentElement.element(by.css_sr('#innerElement'))           <=> parentElement.$('#innerElement')
 *   O  parentElement.element(by.css_sr('::sr #innerElement'))      <=> parentElement.shadowRoot.$('#innerElement')
 *   O  parentElement.all(by.css_sr('.inner-element'))              <=> parentElement.$$('.inner-element')
 *   O  parentElement.all(by.css_sr('::sr .inner-element'))         <=> parentElement.shadowRoot.$$('.inner-element')
 */
by.addLocator('css_sr', (cssSelector: string, opt_parentElement, opt_rootSelector) => {
    let selectors = cssSelector.split('::sr');
    if (selectors.length === 0) {
        return [];
    }

    let shadowDomInUse = (document.head.createShadowRoot || document.head.attachShadow);
    let getShadowRoot  = (el) => ((el && shadowDomInUse) ? el.shadowRoot : el);
    let findAllMatches = (selector: string, targets: any[], firstTry: boolean) => {
        let using, i, matches = [];
        for (i = 0; i < targets.length; ++i) {
            using = (firstTry) ? targets[i] : getShadowRoot(targets[i]);
            if (using) {
                if (selector === '') {
                    matches.push(using);
                } else {
                    Array.prototype.push.apply(matches, using.querySelectorAll(selector));
                }
            }
        }
        return matches;
    };

    let matches = findAllMatches(selectors.shift().trim(), [opt_parentElement || document], true);
    while (selectors.length > 0 && matches.length > 0) {
        matches = findAllMatches(selectors.shift().trim(), matches, false);
    }
    return matches;
});

Conclusion

Since the workaround works on my side, so I am asking~ is there anything I missed or I misused the background principle of Protractor in my workaround? I am politely saying ... if I don't violate your certain rules too much, is it possible to add ShadowDOM support something like that into the next update of Protractor?

Thank you.

@wswebcreation
Copy link
Contributor

@First87

Tnx for sharing this. It looks nice and it's a nice workaround.

If you would like to see this in a newer version of Protractor you could add a PR with a new locator like element(by. shadowRoot('#parentElement #innerElement'))

@firstor
Copy link
Author

firstor commented Jul 17, 2017

@wswebcreation Ok, good. I will add a PR.
But I want to make sure just one thing before go: are you okay with this style of selector #parentElement::sr #innerElement to indicate the element #innerElement inside the shadow tree of the #parentElement?

@wswebcreation
Copy link
Contributor

@First87

Looks good to me 👍

I'm only not the (only) one who decides about the PR's. The core members, that will also review your PR, decide in the end.

I think it will be a great addition and a clear logging, so go for it 😉

@firstor
Copy link
Author

firstor commented Jul 17, 2017

@wswebcreation How can I push my commits? Seems that I have no enough permission to contribute.

@wswebcreation
Copy link
Contributor

Hi @First87 ,

Have you seen this document. It holds all the steps you need to take.

@firstor
Copy link
Author

firstor commented Jul 18, 2017

@wswebcreation Yes, I checked DEVELOPER.md and did not find any guide to push. These are steps I went:

  • git clone git@github.com:angular/protractor.git
  • cd protractor/
  • git remote add upstream https://github.com/angular/protractor.git
  • git checkout -b feature/shadow-root-locator master to create my own branch
  • npm install
  • made several commits
  • gulp lint to check if code formatted correctly
  • npm start, webdriver-manager start, npm test to pass all tests

Now what should I do for next?

@wswebcreation
Copy link
Contributor

Hi @First87,

  • You start by forking the project.
  • Then it will be add to your account.
  • Do a clone to your local machine
  • Then push your changes and click on the "Create PR"-button.

That should do the trick

@firstor
Copy link
Author

firstor commented Jul 18, 2017

@wswebcreation Ok, thank you for guiding.

@firstor
Copy link
Author

firstor commented Jul 18, 2017

@wswebcreation I just created a PR #4392.

@wswebcreation
Copy link
Contributor

@First87 Tnx!!

@SirJackovich
Copy link

What is the status on this? We would like to be able to use the by.shadowRoot function.

@firstor
Copy link
Author

firstor commented Jan 23, 2018

Hope someone helps me resolve this: #4392 (comment)

@msbasanth
Copy link

msbasanth commented Jan 24, 2018

@First87 I tried using your new locator in my e2e tests. I am unable to get the elements in the shadow dom.

Environment: Angular (v5) Application with Polymer Web Components. Protractor for running e2e tests.

Angular CLI: 1.6.4
Node: 6.10.0
Angular: 5.2.0
@angular/cli: 1.6.4
typescript: 2.5.3
Below given is my polymer web component shadow root expanded in chrome. You could see input type = "text" inside this custom element.

I am unable to access input element inside custom polymer component using protractor by.css_sr.

var polymerFirstName = element(by.className('polyFName'));
var inputElement = polymerFirstName.element(by.css_sr('input')); // returns nothing.

It failed with an error "No element found using locator: by.css_sr("input")".

shadowroot

I need to access the inner input element so that I can perform UI Automation tasks like.
polymerFirstName.element(by.css_sr('input')).clear();
polymerFirstName.element(by.css_sr('input')).sendKeys('Ritchie');

Anything I am missing?

@firstor
Copy link
Author

firstor commented Jan 24, 2018

@msbasanth You missed ::sr since by.css_sr won't start to find elements in a shadow root of the element ~ it will dig into the shadow DOM tree of any element for each ::sr.
So you should replace your input element finder with this:

var inputElement = polymerFirstName.element(by.css_sr('::sr input'));

@msbasanth
Copy link

Thank you @First87 it worked like a charm.
Hope we will get this shadow DOM support in protractor soon.

@rominoushana
Copy link

rominoushana commented Feb 15, 2018

This works! Thank you! It's going to be so hard locating elements now especially if there are nested shadow doms :( since we can't test the locators in the console. Thanks again!

@oseasmoran73
Copy link

oseasmoran73 commented Jan 4, 2019

@firstor Thank you so much for this! Hopefully this can get integrated soon....

I was hoping to get some assistance from you on this though. While I am able to get the correct value using ::sr as needed, when I do title.getText() it seems to get the "incorrect" value. It seems to be coming in as an object. See the following output below:

Expected [ 'Title' ] to be 'Title'.

I have not had success in being able to get the string from that object/array and was wondering if you had an any idea?

Thanks again for the workaround!!

EDIT: Disregard!! Referenced this and it did the trick https://stackoverflow.com/questions/29478905/protractor-element-gettext-returns-an-object-and-not-string. Thanks again!!

@ssudhanshu
Copy link

ssudhanshu commented Mar 7, 2019

Hi @firstor / @msbasanth , I am unable to get an element present in shadow-root DOM. I copied your above code in a .ts file but getting a compilation error at line no. 6:
Code: let shadowDomInUse = (document.head.createShadowRoot .......
Error: Property 'createShadowRoot' does not exist on type 'HTMLHeadElement'.

Application: Angular v7
NodeJS: 6.9.0
typescript: 2.3.3
protractor: 5.3.2

Can you please elaborate on how to use your method to enter some text in the input box inside shadow-root?
Thanks!

image

@ansreenath
Copy link

image

@firstor
Thanks for this. Am trying to use it like this.
var searchBar = element(by.css_sr('::sr input'));
var searchButton = element(by.css_sr('::sr i'));

Am getting the below error
[11:36:06] E/launcher - TypeError: Invalid locator

What am i doing wrong?
Any help is highly appreciated. Thanks in advance.

@alexzavg
Copy link

alexzavg commented Sep 4, 2019

@firstor hey, thanks for the workaround)
however, we can't fully use it in our team unless it's merged into Protractor master branch (we're using Protractor on remote nodes so the libs are always pulled when the tests are being run).

Any progress on merging the #4786 ?

@sudeeppaudyal
Copy link

Any update on this?

@alexzavg
Copy link

any update? this is a blocker for many specs as of late(

@v1nc3kr0
Copy link

Hello @firstor ,

Application : Angular 8
NodeJS : 12.13.1
typescript: 3.5.3
Protractor : 5.4.0

Thank you for your workaround.

I try to find element into ShadowRoot. In our frontend architecture, we Have 3 depth levels

  • First level : Micro frontend application
  • Second level : Micro frontend component
  • Third level : Angular material Component

Protractor_ShadowRoot-issue

First and second shadowRoot level are accessible but not the last one.

Extract of the Code source :

    await expect(element(by.tagName('page-affaire')).isDisplayed());
    await browser.driver.sleep(3000);
    console.log('Page affaire chargée');
    var el1 = element(by.tagName('page-affaire'));
    
    var el2 = el1.element(by.css_sr('::sr rac-card'));
    console.log('rac-card found');

    var el3 = el1.element(by.css_sr('::sr rac-option'));
    console.log('rac-option found');

    var el4 = el1.element(by.css_sr('::sr mat-select')); 
    console.log('rac-card select');

Result logs :

Jasmine` started
Page affaire chargée
rac-card found
rac-option found
rac-card select
Sélection du type de demande

  créer Affaire
    × Select type demande
      - NoSuchElementError: No element found using locator: by.css_sr("::sr mat-select")

We try with other solution (https://stackoverflow.com/questions/57979981/how-to-check-in-protractor-javescript-in-shadow-dom-if-the-button-is-enabled-o). We have the same issue :

await browser.executeScript("return document.querySelector(\"page-affaire\");").then(function () {
      console.log('page affaire found');
      // browser.sleep(5000);
    });
    await browser.executeScript("return document.querySelector(\"page-affaire\").shadowRoot.querySelector(\"rac-card\");").then(function () {
      console.log('rac card found');
      // browser.sleep(5000);
    });
    await browser.executeScript("return document.querySelector(\"page-affaire\").shadowRoot.querySelector(\"rac-card\").shadowRoot.querySelector(\"rac-option\");").then(function () {
      console.log('rac option found');
      // browser.sleep(5000);
    });
    await browser.executeScript("return document.querySelector(\"page-affaire\").shadowRoot.querySelector(\"rac-card\").shadowRoot.querySelector(\"rac-option\").shadowRoot.querySelector(\"mat-select\").click();").then(function () {
      console.log('Type de Demande cliqué');
      browser.sleep(5000);
    });

Result :

Jasmine started
Page affaire chargée
rac-card found
rac-option found
rac-card select
Sélection du type de demande

  créer Affaire
    × Select type demande
      - NoSuchElementError: No element found using locator: by.css_sr("::sr mat-select")

Is there a limit regarding shadowRoot depth limit access ?

Thanks you for your support.

V1nc3kr0

@alagappan-qa
Copy link

Hello @firstor ,

Application : Angular 8
NodeJS : 12.13.1
typescript: 3.5.3
Protractor : 5.4.0

Thank you for your workaround.

I try to find element into ShadowRoot. In our frontend architecture, we Have 3 depth levels

  • First level : Micro frontend application
  • Second level : Micro frontend component
  • Third level : Angular material Component

Protractor_ShadowRoot-issue

First and second shadowRoot level are accessible but not the last one.

Extract of the Code source :

    await expect(element(by.tagName('page-affaire')).isDisplayed());
    await browser.driver.sleep(3000);
    console.log('Page affaire chargée');
    var el1 = element(by.tagName('page-affaire'));
    
    var el2 = el1.element(by.css_sr('::sr rac-card'));
    console.log('rac-card found');

    var el3 = el1.element(by.css_sr('::sr rac-option'));
    console.log('rac-option found');

    var el4 = el1.element(by.css_sr('::sr mat-select')); 
    console.log('rac-card select');

Result logs :

Jasmine` started
Page affaire chargée
rac-card found
rac-option found
rac-card select
Sélection du type de demande

  créer Affaire
    × Select type demande
      - NoSuchElementError: No element found using locator: by.css_sr("::sr mat-select")

We try with other solution (https://stackoverflow.com/questions/57979981/how-to-check-in-protractor-javescript-in-shadow-dom-if-the-button-is-enabled-o). We have the same issue :

await browser.executeScript("return document.querySelector(\"page-affaire\");").then(function () {
      console.log('page affaire found');
      // browser.sleep(5000);
    });
    await browser.executeScript("return document.querySelector(\"page-affaire\").shadowRoot.querySelector(\"rac-card\");").then(function () {
      console.log('rac card found');
      // browser.sleep(5000);
    });
    await browser.executeScript("return document.querySelector(\"page-affaire\").shadowRoot.querySelector(\"rac-card\").shadowRoot.querySelector(\"rac-option\");").then(function () {
      console.log('rac option found');
      // browser.sleep(5000);
    });
    await browser.executeScript("return document.querySelector(\"page-affaire\").shadowRoot.querySelector(\"rac-card\").shadowRoot.querySelector(\"rac-option\").shadowRoot.querySelector(\"mat-select\").click();").then(function () {
      console.log('Type de Demande cliqué');
      browser.sleep(5000);
    });

Result :

Jasmine started
Page affaire chargée
rac-card found
rac-option found
rac-card select
Sélection du type de demande

  créer Affaire
    × Select type demande
      - NoSuchElementError: No element found using locator: by.css_sr("::sr mat-select")

Is there a limit regarding shadowRoot depth limit access ?

Thanks you for your support.

V1nc3kr0

Give a try like
var el4 = el3.element(by.css_sr('::sr mat-select'));

@alagappan-qa
Copy link

@firstor
My Web Application is using Polymer.js with 10 levels of Shadow roots.
RJvlf
Is it possible to call the last Shadow root element from the top node instead of traversing the individual Shadow roots.
Thanks for your support.

@rugaba
Copy link

rugaba commented Jan 15, 2020

Hello guys ,
I am new to protractor and i wish i can get a help on how to include this locator script (shadowDOM) in protractor .
i am doing some UI testing on polymer webcomponent , the protractor version : 5.4.2 and node v12.13 .

could any one tell me where to include that script ? @firstor , @alagappan-qa

thanks in advance.

@Lakhs02
Copy link

Lakhs02 commented Mar 14, 2020

Hi,

Is it possible to include this script in a separate js file and import it in the protractor.conf file and include in onPrepare() method. If so, how do we do it ?

Thanks,
Lakshmi

@DanielRuf
Copy link

@pntgoswami18
Copy link

pntgoswami18 commented May 21, 2020

Hi,

Is it possible to include this script in a separate js file and import it in the protractor.conf file and include in onPrepare() method. If so, how do we do it ?

Thanks,
Lakshmi

@Lakhs02
Declare this locator in some other file as

exports.addShadowRootLocator = function () {
    by.addLocator('css_sr', function (
.
.
.
    return matches;
    });
};

Then in the onPrepare() method

onPrepare: function () {
        // register the shadow root locator, to use it globally
        require('./path/to/file').addShadowRootLocator();
}

@magdalenaBartkowiakJowsa

@firstor
My Web Application is using Polymer.js with 10 levels of Shadow roots.
RJvlf
Is it possible to call the last Shadow root element from the top node instead of traversing the individual Shadow roots.
Thanks for your support.

@firstor I can see on your profile that you are experienced with shadow DOM. Could you please be so kind and provide an example how you access nested shadow DOM? I am struggling with it for two weeks now and still cannot access some elements:
This is my example, I need to access highlighted div element: div.a-choosen-text:
image

I tried the below locator (and many others) but with no success:
nameOnTheProjectTab = element(by.css_sr('app-dumbledore::sr lit-route::sr app-dashboard::sr app-project:nth-child(1)::sr appkit-panel::sr app-assignee-dropdown::sr appkit-dropdown::sr div.a-choosen-text'));

What is suprising, the locator for app-project works fine, but when I go deeper, whatever I try, it does not work.
Works fine: static projectTab = element(by.css_sr('app-dumbledore::sr lit-route::sr app-dashboard::sr app-project:nth-child(1)'));

Do you have any idea what am I doing wrong?
Thank you in advance,
Magda

@alagappan-qa
Copy link

@firstor
My Web Application is using Polymer.js with 10 levels of Shadow roots.
RJvlf
Is it possible to call the last Shadow root element from the top node instead of traversing the individual Shadow roots.
Thanks for your support.

@firstor I can see on your profile that you are experienced with shadow DOM. Could you please be so kind and provide an example how you access nested shadow DOM? I am struggling with it for two weeks now and still cannot access some elements:
This is my example, I need to access highlighted div element: div.a-choosen-text:
image

I tried the below locator (and many others) but with no success:
nameOnTheProjectTab = element(by.css_sr('app-dumbledore::sr lit-route::sr app-dashboard::sr app-project:nth-child(1)::sr appkit-panel::sr app-assignee-dropdown::sr appkit-dropdown::sr div.a-choosen-text'));

What is suprising, the locator for app-project works fine, but when I go deeper, whatever I try, it does not work.
Works fine: static projectTab = element(by.css_sr('app-dumbledore::sr lit-route::sr app-dashboard::sr app-project:nth-child(1)'));

Do you have any idea what am I doing wrong?
Thank you in advance,
Magda

Hi Magda,
In your case, the shadow root under the WebElement appkit-panel is not expanded to find out your Element.
But in the nameOnTheProjectTab element it's expanded which causes this issue.
Try out the below element locator,
nameOnTheProjectTab = element(by.css_sr('app-dumbledore::sr lit-route::sr app-dashboard::sr app-project:nth-child(1)::sr app-assignee-dropdown::sr appkit-dropdown::sr div.a-choosen-text'));

@magdalenaBartkowiakJowsa
Copy link

@alagappan-annamalai
Copy link

Hey Everyone, Found a solution to locate the Shadow Elements inside the Shadow Root at any deep level.
With the help of the node module "query-selector-shadow-dom", we can identify the Web elements in the Shadow DOM with ease. No need to traverse through all the Shadow roots.
Using element(by.shadowDomCss('')), we can point to the Web element inside the Shadow Root at any level.

@sudeeppaudyal
Copy link

sudeeppaudyal commented Aug 19, 2020 via email

@alagappan-annamalai
Copy link

Hi Alagappan, can you please describe a little more with an example please.Thanks

On Wed, Aug 19, 2020 at 7:52 AM alagappan-annamalai < @.***> wrote: Hey Everyone, Found a solution to locate the Shadow Elements inside the Shadow Root at any deep level. With the help of the node module "query-selector-shadow-dom", we can identify the Web elements in the Shadow DOM with ease. No need to traverse through all the Shadow roots. Using element(by.shadowDomCss('')), we can point to the Web element inside the Shadow Root at any level. — You are receiving this because you commented. Reply to this email directly, view it on GitHub <#4367 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AK2OQDTZK2ZVJTICP3VGS3DSBPDJVANCNFSM4DR44ABQ .

72205775-de7d6300-34ac-11ea-93f7-37917052ce90
In the above screenshot, the tag paper-input-container with id=container is at 6+ shadow root layer. To take this webElement we can use element(by.shadowDomCss('paper-input#textbox paper-input-container#container')); This short element identifier will act on the WebElement.

@rob4226
Copy link

rob4226 commented Sep 24, 2020

Hi @firstor / @msbasanth , I am unable to get an element present in shadow-root DOM. I copied your above code in a .ts file but getting a compilation error at line no. 6:
Code: let shadowDomInUse = (document.head.createShadowRoot .......
Error: Property 'createShadowRoot' does not exist on type 'HTMLHeadElement'.

I also got this error and the solution is to replace createShadowRoot with attachShadow because the createShadowRoot() method has been deprecated in favor of attachShadow(). See reference:
https://developer.mozilla.org/en-US/docs/Web/API/Element/createShadowRoot

By the way @firstor, thank you for this contribution! It has been working great so far. I wasted so much time trying to get by.deepCss to work with Protractor and Angular 10. I have recently started using native shadowDom encapsulation with my Angular 10 components, encapsulation: ViewEncapsulation.ShadowDom which I love but was not happy I could not access any nested shadowDom elements during e2e testing. Thankfully I found this code!

@msbasanth
Copy link

@rob4226
Please look into package https://www.npmjs.com/package/query-selector-shadow-dom

Looks promising.

@shopmujahid
Copy link

@msbasanth @rob4226 I'm new to protractor, I'm trying to access text 'Downloads' of chrome download page
my code :
image
I also tried var x = await element.element(by.css_sr('h1')).getText(); It doesn't work.
I receive below error message:
image

Appreciate your response on this Thanks!

@shopmujahid
Copy link

I fixed it, I need to create separate element variable for every nested shadow root element.

@firstor I greatly appreciate for this code. many thanks 👍

@wasoek
Copy link

wasoek commented Nov 30, 2020

Hello i am currently tr to select shadow dom. I get the following error when using the workaround:

Logg: { StaleElementReferenceError: stale element reference: stale element not found (Session info: chrome=87.0.4280.66)

Usage:
const parent = element(by.css_sr('my-wrapper > div > div::sr my-data')); const domElement = parent.element(by.css('my-checkbox input')); console.log('Displayed', await domElement.isDisplayed());

<my-data> <my-checkbox> <input> <my-checkbox> </my-data> .....
What am I doing wrong?

@alagappan-annamalai
Copy link

Hello i am currently tr to select shadow dom. I get the following error when using the workaround:

Logg: { StaleElementReferenceError: stale element reference: stale element not found (Session info: chrome=87.0.4280.66)

Usage:
const parent = element(by.css_sr('my-wrapper > div > div::sr my-data')); const domElement = parent.element(by.css('my-checkbox input')); console.log('Displayed', await domElement.isDisplayed());

<my-data> <my-checkbox> <input> <my-checkbox> </my-data> .....
What am I doing wrong?

Hi @wasoek , Can you provide the Chrome Developer Tool > Inspect Element for this element from the Shadow Root. That will give more details on this issue.

@alagappan-annamalai
Copy link

alagappan-annamalai commented Dec 3, 2020 via email

@shopmujahid
Copy link

I'm trying to access one of div elements inside shadow dom both nth-child() and type-of() are not working in my case.
anybody faced this issue before?

Below is the DOM structure and my xpath
2134234

await browser.element(by.css_shadowroot('d2l-navigation::sr d2l-navigation-main-header:nth-type-of(3)'))

I'm receiving no element found error.

Any help would be greatly appreciated Thanks in advance.

@alagappan-annamalai
Copy link

alagappan-annamalai commented Dec 9, 2020 via email

@shopmujahid
Copy link

shopmujahid commented Dec 11, 2020

Thanks @alagappan-annamalai! 👍 the second solution worked for me by removing ::sr and adding tagname.classname, however I ran into other weird issue its not accessing the child elements below:
2134234

I need to access highlighted element above

tried with both xpaths below:
browser.element(by.css_sr('d2l-navigation d2l-navigation-main-header div.d2l-navigation-header-right div d2l-dropdown d2l-dropdown-content div div div div ul:nth-child(2)'))

and

browser.element(by.css_sr('d2l-navigation d2l-navigation-main-header div.d2l-navigation-header-right div d2l-dropdown d2l-dropdown-content div div div div ul li.<entire class name>')) (the li class name will append some text to it when we hover over it)

I'm receiving no element found error.
Thanks in advance.

@alagappan-annamalai
Copy link

Thanks @alagappan-annamalai! 👍 the second solution worked for me by removing ::sr and adding tagname.classname, however I ran into other weird issue its not accessing the child elements below:
2134234

I need to access highlighted element above

tried with both xpaths below:
browser.element(by.css_sr('d2l-navigation d2l-navigation-main-header div.d2l-navigation-header-right div d2l-dropdown d2l-dropdown-content div div div div ul:nth-child(2)'))

and

browser.element(by.css_sr('d2l-navigation d2l-navigation-main-header div.d2l-navigation-header-right div d2l-dropdown d2l-dropdown-content div div div div ul li.')) (the li class name will append some text to it when we hover over it)

I'm receiving no element found error.
Thanks in advance.

This can be handled in a simple way itself without css_sr and providing few HTML web elements
browser.element.all(by.css('d2l-navigation d2l-navigation-main-header ul[class="d2l-datalist vui-list"] li')).get(1);

@shopmujahid
Copy link

Bravo, worked like a charm Thanks @alagappan-annamalai ! 👍

@jawaadaslam
Copy link

I am getting an error on this line
let shadowDomInUse = (document.head.createShadowRoot || document.head.attachShadow);
it says createShadowRoot does not exist in document.head . Any solution.
Environment is
Protractor = 7.0.0
"ts-node": "^8.10.2"
Image is attached. Any help please
protractor_SR

@Rituparna2021
Copy link

Trying to click a button which is inside an iframe and the iframe is inside #shadow-root, but everytime the automation runs, getting #shadow-root (closed) and not able to switch the frame or access it's element. I am using this in Protractor.
Please suggest me how can the #shadow-root mode will be open and how to access the element inside the iframe.
Thanks in advance , will look forward for your help.

@lexigren
Copy link

@Rituparna2021 any progress?

@christian-bromann
Copy link

@lexigren as you might have seen in this RFC, Protractor is being discontinued and it is unlikely that this feature request will be implement. I recommend to take a look into WebdriverIO which supports shadow DOM. We have created a migration guide using a codemod to transition to WebdriverIO in an automated fashion. Let me know if you have any questions.

@StanislavKharchenko
Copy link

StanislavKharchenko commented Apr 29, 2021

@christian-bromann
I respect WDIO, but RFC != deprecation. They don't have published final decision and more people want to have new Protractor (or new Protractor-ish lite ver).

@OfficialSiev
Copy link

Include the script in the Configuration.js file under onPrepare() method.

Hello @alagappan-qa

I´m new to protractor and also a beginner programmer so basically a complete beginner and I wanted to ask you where exactly would you implement this workaround in an e2e unit-test with angular. I tried the protractor.conf.js under the onPrepare() Method as you recommended but I get lots of errors there....
Should I implement in diffrently or create a seperate js-file?

Thanks and greetings
Siev

@bharathitman
Copy link

bharathitman commented Jul 22, 2021

When combined with Angular's ShadowDom View Encapsulation, elements inside the shadowroot always return StaleElementReferenceError.

@richa-88
Copy link

richa-88 commented Aug 9, 2021

Hi, i m new to protractor just wanted to get multiple shadow root elements, I came across the avobe scripts but was not able to understand where to place the scripts and call. It will be a great help.

@pntgoswami18
Copy link

I have implemented it and documented how to do it on my medium article here

Hi, i m new to protractor just wanted to get multiple shadow root elements, I came across the avobe scripts but was not able to understand where to place the scripts and call. It will be a great help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests