Existe-t-il un moyen d'obtenir l'élément par XPath en utilisant JavaScript dans Selenium WebDriver?


252

Je cherche quelque chose comme:

getElementByXpath(//html[1]/body[1]/div[1]).innerHTML

J'ai besoin d'obtenir le innerHTML des éléments en utilisant JS (pour l'utiliser dans Selenium WebDriver / Java, car WebDriver ne le trouve pas lui-même), mais comment?

Je pourrais utiliser l'attribut ID, mais tous les éléments n'ont pas d'attribut ID.

[FIXÉ]

J'utilise jsoup pour le faire en Java. Cela fonctionne pour mes besoins.


2
Soit dit en passant, les sélecteurs htmlet bodysont superflus car un DIV doit être un descendant de BODY (immédiat ou plus profond) et BODY doit être un enfant de HTML, donc à condition qu'il n'y ait pas d'autres éléments DIV dans le document, //DIV[1]devrait fonctionner (bien que je sois assez rouillé sur les expressions XPath). L'équivalent DOM est document.getElementsByTagName('div')[1](ou peut-être 0).
RobG

Réponses:


422

Vous pouvez utiliser document.evaluate:

Évalue une chaîne d'expression XPath et renvoie si possible un résultat du type spécifié.

Il est normalisé w3 et entièrement documenté: https://developer.mozilla.org/en-US/docs/Web/API/Document.evaluate

function getElementByXpath(path) {
  return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}

console.log( getElementByXpath("//html[1]/body[1]/div[1]") );
<div>foo</div>

https://gist.github.com/yckart/6351935

Il y a aussi une excellente introduction sur le réseau de développeurs mozilla: https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript#document.evaluate


Version alternative, utilisant XPathEvaluator:


11
Que signifie le chiffre magique 9? Il serait préférable d'utiliser une constante nommée ici.
Will Sheppard

5
@WillSheppard XPathResult.FIRST_ORDERED_NODE_TYPE === 9 developer.mozilla.org/en-US/docs/…
yckart

2
J'ai écrit une fonction getElementByXPath qui prend en charge IE mais une prise en charge de base de xpath pour l'instant. Il y a aussi une fonction getElementXpath là-dedans et ils fonctionnent bien ensemble pour ce dont j'avais besoin. gist.github.com/Joopmicroop/10471650
joopmicroop


var xpathResult = document.evaluate (xpathExpression, contextNode, namespaceResolver, resultType, result);
TechDog

167

Dans Chrome Dev Tools, vous pouvez exécuter les éléments suivants:

$x("some xpath")

1
J'ai joué avec cela et cela semble fonctionner, mais existe-t-il une documentation pour cette fonctionnalité? Je n'ai rien trouvé.
Eric

Cela doit être plus haut. Firefox le prend également en charge.
iSWORD

Ceci est très utile lorsque vous déboguez votre page Web. Merci.
theeranitp


21

Pour quelque chose comme $ x de l'API de ligne de commande Chrome (pour sélectionner plusieurs éléments), essayez:

var xpath = function(xpathToExecute){
  var result = [];
  var nodesSnapshot = document.evaluate(xpathToExecute, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null );
  for ( var i=0 ; i < nodesSnapshot.snapshotLength; i++ ){
    result.push( nodesSnapshot.snapshotItem(i) );
  }
  return result;
}

Cette présentation MDN a aidé: https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript


9

Vous pouvez utiliser le document.evaluate de javascript pour exécuter une expression XPath sur le DOM. Je pense qu'il est pris en charge d'une manière ou d'une autre dans les navigateurs de retour à IE 6.

MDN: https://developer.mozilla.org/en-US/docs/Web/API/Document/evaluate

IE prend plutôt en charge selectNodes .

MSDN: https://msdn.microsoft.com/en-us/library/ms754523(v=vs.85).aspx


7
Je voudrais noter que {document.evaluate} ne fonctionne pas dans IE.
Christopher Bales du


2
public class JSElementLocator {

    @Test
    public void locateElement() throws InterruptedException{
        WebDriver driver = WebDriverProducerFactory.getWebDriver("firefox");

        driver.get("https://www.google.co.in/");


        WebElement searchbox = null;

        Thread.sleep(1000);
        searchbox = (WebElement) (((JavascriptExecutor) driver).executeScript("return document.getElementById('lst-ib');", searchbox));
        searchbox.sendKeys("hello");
    }
}

Assurez-vous que vous utilisez le bon localisateur pour cela.


1
Salut Prerit, la question était de sélectionner par un élément en fonction de son xpath. La solution que vous avez fournie consiste à le sélectionner par l'identifiant. :)
Gaurav Thantry

2
**Different way to Find Element:**

IEDriver.findElement(By.id("id"));
IEDriver.findElement(By.linkText("linkText"));
IEDriver.findElement(By.xpath("xpath"));

IEDriver.findElement(By.xpath(".//*[@id='id']"));
IEDriver.findElement(By.xpath("//button[contains(.,'button name')]"));
IEDriver.findElement(By.xpath("//a[contains(.,'text name')]"));
IEDriver.findElement(By.xpath("//label[contains(.,'label name')]"));

IEDriver.findElement(By.xpath("//*[contains(text(), 'your text')]");

Check Case Sensitive:
IEDriver.findElement(By.xpath("//*[contains(lower-case(text()),'your text')]");

For exact match: 
IEDriver.findElement(By.xpath("//button[text()='your text']");

**Find NG-Element:**

Xpath == //td[contains(@ng-show,'childsegment.AddLocation')]
CssSelector == .sprite.icon-cancel

0
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

System.setProperty("webdriver.chrome.driver", "path of your chrome exe");
        WebDriver driver = new ChromeDriver();
        driver.manage().window().maximize();
        driver.get("https://www.google.com");

            driver.findElement(By.xpath(".//*[@id='UserName']")).clear();
            driver.findElement(By.xpath(".//*[@id='UserName']")).sendKeys(Email);

ajoutez une réponse descriptive. votre description aidera l'interrogateur à comprendre rapidement votre solution.
NickCoder

0

Pour aller droit au but, vous pouvez facilement utiliser xapth .La manière exacte et simple de le faire en utilisant le code ci-dessous. Veuillez essayer de fournir des commentaires .Merci.

JavascriptExecutor js = (JavascriptExecutor) driver;

    //To click an element 
    WebElement element=driver.findElement(By.xpath(Xpath));
    js.executeScript(("arguments[0].click();", element);

    //To gettext

    String theTextIWant = (String) js.executeScript("return arguments[0].value;",driver.findElement(By.xpath("//input[@id='display-name']")));

Lectures supplémentaires - https://medium.com/@smeesheady/webdriver-javascriptexecutor-interact-with-elements-and-open-and-handle-multiple-tabs-and-get-url-dcfda49bfa0f


Je pense que le PO n'a pas demandé une solution de sélénium comme la vôtre, n'est-ce pas?
ankostis
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.