web-dev-qa-db-fra.com

Comment interagir avec les éléments dans # shadow-root (open) tout en effaçant les données de navigation de Chrome Browser using cssSelector

J'avais suivi la discussion Comment automatiser les éléments du shadow DOM en utilisant du sélénium? pour travailler avec les éléments #shadow-root (open).

Pendant le processus de localisation du Clear data dans la fenêtre Effacer les données de navigation , qui apparaît lors de l'accès à l'URL chrome://settings/clearBrowserData à Sélénium I suis incapable de localiser l'élément suivant:

#shadow-root (open)
<settings-privacy-page>

Instantané:

settings-privacy-page

En utilisant Selenium , voici mes essais de code et les erreurs associées rencontrées:

  • Tentative 1:

    WebElement root5 = shadow_root4.findElement(By.tagName("settings-privacy-page"));
    
    • Erreur:

      Exception in thread "main" org.openqa.Selenium.JavascriptException: javascript error: b.getElementsByTagName is not a function
      
  • Tentative 2:

    WebElement root5 = shadow_root4.findElement(By.cssSelector("settings-privacy-page"));
    
    • Erreur:

      Exception in thread "main" org.openqa.Selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"settings-privacy-page"}
      
  • Tentative 3:

    WebElement root5 = (WebElement)((JavascriptExecutor)shadow_root4).executeScript("return document.getElementsByTagName('settings-privacy-page')[0]");
    
    • Erreur:

      Exception in thread "main" Java.lang.ClassCastException: org.openqa.Selenium.remote.RemoteWebElement cannot be cast to org.openqa.Selenium.JavascriptExecutor
      

Si cela est utile, le bloc de code initial (jusqu'à la ligne ci-dessus) fonctionne parfaitement:

driver.get("chrome://settings/clearBrowserData");
WebElement root1 = driver.findElement(By.tagName("settings-ui"));
WebElement shadow_root1 = expand_shadow_element(root1);

WebElement root2 = shadow_root1.findElement(By.cssSelector("settings-main#main"));
WebElement shadow_root2 = expand_shadow_element(root2);

WebElement root3 = shadow_root2.findElement(By.cssSelector("settings-basic-page[role='main']"));
WebElement shadow_root3 = expand_shadow_element(root3);

WebElement root4 = shadow_root3.findElement(By.cssSelector("settings-section[page-title='Privacy and security']"));
WebElement shadow_root4 = expand_shadow_element(root4);

PS: expand_shadow_element() fonctionne parfaitement.

6
DebanjanB

J'ai dû faire un test similaire qui nécessitait d'effacer la navigation dans l'historique chrome. Une différence mineure était que j'effaçais les données après être allé à la section avancée de la fenêtre contextuelle. Comme vous avez du mal pour ne cliquer que sur le bouton "Effacer les données", je suis sûr que vous avez manqué un ou deux éléments de la hiérarchie par erreur. Ou que vous vous êtes probablement trompé entre les frères et les parents. D'après votre code, je suppose que vous savez déjà que pour accéder à un élément DOM ombre particulier, vous avez besoin d'un séquencement approprié et cela a également été expliqué très bien ci-dessus.
Pour en venir à votre problème maintenant, voici mon extrait de code qui fonctionne correctement. Le code attend que les données soient nettoyées, puis passera à votre prochaine action-

public WebElement expandRootElement(WebElement element) {
WebElement ele = (WebElement) ((JavascriptExecutor) driver).executeScript("return arguments[0].shadowRoot",
        element);
return ele;
}

public void clearBrowsingHistory() throws Exception {

    WebDriverWait wait = new WebDriverWait(driver, 15);
    driver.get("chrome://settings/clearBrowserData");
// Get shadow root elements
    WebElement shadowRoot1 = expandRootElement(driver.findElement(By.xpath("/html/body/settings-ui")));

    WebElement root2 = shadowRoot1.findElement(By.cssSelector("settings-main"));
    WebElement shadowRoot2 = expandRootElement(root2);

    WebElement root3 = shadowRoot2.findElement(By.cssSelector("settings-basic-page"));
    WebElement shadowRoot3 = expandRootElement(root3);

    WebElement root4 = shadowRoot3
        .findElement(By.cssSelector("#advancedPage > settings-section > settings-privacy-page"));
    WebElement shadowRoot4 = expandRootElement(root4);

    WebElement root5 = shadowRoot4.findElement(By.cssSelector("settings-clear-browsing-data-dialog"));
    WebElement shadowRoot5 = expandRootElement(root5);

    WebElement root6 = shadowRoot5
        .findElement(By.cssSelector("cr-dialog div[slot ='button-container'] #clearBrowsingDataConfirm"));

    root6.click();
    wait.until(ExpectedConditions.invisibilityOf(root6));
}

Cela devrait également fonctionner correctement dans votre cas si vous n'avez pas l'intention de modifier l'une des options sélectionnées par défaut dans la fenêtre contextuelle (dans ce cas, vous devrez ajouter quelques codes supplémentaires concernant la sélection de ces cases à cocher). Veuillez me dire si cela résout votre problème. J'espère que cela est utile, j'ai ajouté un instantané de l'écran ici aussi image

0

La réponse de @ supputuri est la réponse de travail et acceptée car la Stratégie de localisation à document.querySelector() fonctionne parfaitement à travers google-chrome-devtools

Cependant, comme l'élément souhaité s'ouvre à partir de shadow-dom vous devez induire WebDriverWait pour la elementToBeClickable() et vous pouvez vous la solution suivante:

  • Bloc de code:

    driver.get("chrome://settings/clearBrowserData");
    new WebDriverWait(driver, 5).until(ExpectedConditions.elementToBeClickable((WebElement) ((JavascriptExecutor)driver).executeScript("return document.querySelector('settings-ui').shadowRoot.querySelector('settings-main').shadowRoot.querySelector('settings-basic-page').shadowRoot.querySelector('settings-section > settings-privacy-page').shadowRoot.querySelector('settings-clear-browsing-data-dialog').shadowRoot.querySelector('#clearBrowsingDataDialog').querySelector('#clearBrowsingDataConfirm')"))).click();
    System.out.println("Clear data Button Clicked");
    
  • Sortie console:

    Clear data Button Clicked
    
0
DebanjanB