Luboš Račanský
5.1.2012

XPath a Selenium testy



XPath je dotazovací jazyk (query language) pro XML dokument. Nečekejte náhradu w3schools tutorialu, ale dozvíte se jak najít element v DOMu pomocí funkcí a atributů. Na názorném příkladu si ukážeme, jak lze XPath využít při psaní Selenium testů webových aplikací. Selenium používá jako lokátory například id, name, css selektor, text odkazu nebo právě XPath.

Mějme následující HTML stránku.

<html>
  <head>
  <title>User list</title>
</head>
  <body>
    <table>
      <tr>
        <td>Joe Smith</td>
        <td><a href="edit.do?id=1">Edit</a> | <a href="delete.do?id=1">Delete</a></td>
      </tr>
      <tr>
        <td>Eddie Johnson</td>
        <td><a href="edit.do?id=2">Edit</a> | <a href="delete.do?id=2">Delete</a></td>
      </tr>
      <tr>
        <td>Jack McCarthy</td>
        <td><a href="edit.do?id=3">Edit</a> | <a href="delete.do?id=3">Delete</a></td>
      </tr>
    </table>
    <button>New user</button>
  </body>
</html>

 

V testovacím scénáři potřebujeme editovat uživatele ‚Eddie Johnson‘.

/html/body/table/tbody/tr[2]/td[2]/a[1]

Toto je plný XPath dotaz. Nicméně lokátory je třeba co nejvíce abstrahovat od struktury stránky, aby vám jejich drobná změna nerozbila testy.

//a[@href='edit.do?id=2']

 To ovšem přepokládá, že víme jaké má Eddie id.

//a[contains(@href,'edit.do')][2]

 Ani tentokrát není dotaz ideální, protože spoléháme na to, že Eddie bude na druhém řádku tabulky.

//tr//*[contains(text(), 'Eddie Johnson')]

 Takto nalezneme element obsahující text ‚Eddie Johnson‘. Nicméně potřebujeme vybrat odkaz sice na stejné řádku ale v jiném sloupci. Řešením je najít předka pomocí klíčového slova ancestor. Nalezení odkazu na daném řádku už je hračka. Výsledný dotaz vypadá následovně.

//tr//*[contains(text(), 'Eddie Johnson')]/ancestor::tr/td/a[contains(text(), 'Edit')]

 Příklady si můžete vyzkoušet ve Firefox pluginu XPather. S nainstalovaným pluginem se vám kontextové menu (pravé tlačítko myši) rozšíří o možnost „Show in XPather“.

Ukázka pluginu XPatherSouvisející články Konfigurace Selenium testů ve Springu Selenium a návrhový vzor Page Objects

Vaše emailová adresa nebude zveřejněna

Komentáře

Děkujeme za váš komentář
Další
  • podhy

    Nebo by se dalo místo ancestor::tr použít jen ..

  • Luboš Račanský

    Ano, pomocí operátoru .. se dostanete o úroveň výš. Chtěl jsem ukázat na možnosti operátoru ancestor, který pomůže více abstrahovat od struktury stránky. Brzy se vám stane třeba to, že někdo obalí jméno elementem strong a lokátor nezafunguje podle očekávání. A to je zbytečné, ne?

  • Vojta Kral

    Jen mala poznamka, ze osa "ancestor" a .. neni uplne stejne. Ascestor veme vsechny predky cili otce, pradedecky atd. .. je zkratka za osu "parent" (stejne jako "//" je zkratka za "descedant") takze veme jen rodice, cili pouze jeden element. Zaroven, taky pozor pri pouziti ancestor (samozrejme i ostatnich os), kdy se vam vrati vsechny predky na to jestli pouzivate XPath 1.0 nebo XPath 2.0, protoze 1.0 vraci obecne node-set, cili nezarucuje poradi. 2.0 vraci sequence cili usporadanou mnozinu. Treba zde je strucny popis os v XPath: http://www.w3schools.com/xpath/xpath_axes.asp