Search code examples
javaselenium-webdriverwebdrivertestngreddit

Reddit.com NoSuchShadowRootException - But there is a shadow-root


I am testing functionality of Reddit using Java/Selenium/TestNG.

I am having an awful time finding the Join button element on r/SoftwareEngineering. Earlier today, it seems like all of the element id's and CSS Selectors I had working before simply stopped working. I did not change any code or change anything about the browser driver I am using. So, I started over.

Now, I've managed to log in, use the search bar, and navigate to r/SoftwareEngineering. I want to join the sub using the "Join" button. However, I cannot locate it. It is nested in shadow-roots. I got some help yesterday with using nested shadowRoots to find elements,

Automation Testing using Selenium, TestNT, Java - Reddit.com - Log In button in Pop-Up

Now, it seems like the shadow-root elements are just disappearing randomly. That is, I was able to find the shadow-root originally using the following code:

WebElement joinButton = driver.findElement(By.xpath("/html/body/shreddit-app/dsa-transparency-modal-provider/report-flow-provider/div/div[1]/div[1]/section/div/div[2]/shreddit-subreddit-header-buttons"));
SearchContext shadowRoot = joinButton.getShadowRoot();
joinButton = joinButton.findElement(By.xpath("//div/faceplate-tracker/shreddit-join-button//button"));

But, somehow the next time I ran the test I got the NoSuchShadowRootException when there's clearly a shadow-root.

<shreddit-join-button button-classes="px-sm py-xs" subscribe-label="Join" unsubscribe-label="Joined" unsubscribe-button-type-override="bordered" name="SoftwareEngineering" subreddit-id="t5_2qmng" buttonsize="medium">
    #shadow-root (open) ==$0
    <!---->
    <button class=" button-primary button-medium button join-btn leading-none px-sm py-xs " data-post-click-location="join">
     <!--?lit$173368049$-->
    "Join"
    </button>
</shreddit-join-button>

Any help is appreciated!


Solution

  • I'm not sure where your issue is coming from but I wrote my code originally from a logged in account. Once I ran the script, there was a shadow-root node missing. You may not be aware but Selenium, at least by default, launches the browser with no profile so I wasn't logged in and the HTML was slightly different. Anyway, once I realized that I updated my code using the Selenium launched browser and came up with the code below. I didn't click the Join button but I did print the text on the button to confirm that it was in fact the correct button.

    String url = "https://www.reddit.com/r/SoftwareEngineering/";
    
    driver = new ChromeDriver();
    driver.manage().window().maximize();
    driver.get(url);
    
    WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    WebElement shadowHost1 = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("shreddit-app")));
    shadowHost1.getShadowRoot();
    WebElement shadowHost2 = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("dsa-transparency-modal-provider")));
    shadowHost2.getShadowRoot();        
    WebElement shadowHost3 = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("shreddit-subreddit-header-buttons")));
    SearchContext shadowRoot4 = shadowHost3.getShadowRoot();
    WebElement shadowHost5 = shadowRoot4.findElement(By.cssSelector("shreddit-join-button"));
    SearchContext shadowRoot5 = shadowHost5.getShadowRoot();
    WebElement joinButton = shadowRoot5.findElement(By.cssSelector("button"));
    System.out.println(joinButton.getText());