×
☰ See All Chapters

Xpath Axes

In xpath, navigating from one element to another element is called traversing. In order to traverse from one element to another, we use xpath axes. Axes are something using which xpath traverses in the html tree either in upward or downward direction. We have the following 6 xpath axes in puppeteer.

  1. child 

  2. descendant 

  3. parent 

  4. ancestor 

  5. preceding-sibling 

  6. following-sibling 

For all the examples of all the below axes we consider the below sample html code

<html>

</head>

<body>

        <form id="form">

                Input 1 : <input type="text">

                Input 2 : <input type="text">

                Input 3 : <input type="text">

                Input 4 : <input type="text">

                Input 5 : <input type="text">

                Input 6 : <input type="text">

                Input 7 : <input type="text">

                Input 8 : <input type="text">

                Input 9 : <input type="text">

        </form>

</body>

</html>

child (/)

Using this axes, xpath traverses to the immediate child element in the html tree.  Axes is represented by single forward slash (/). We use this child axes in deriving the absolute xpath expression.

e.g.: /html → can be written using child axes as → child::html

descendant (//)

Using this axes, xpath traverses to any child element   in the html tree. Axes is represented by double forward slash (//). Use this descendant axes in deriving the relative xpath expression.

e.g.: //input[5] → can be written using descendant axes as → descendant::input[5]

parent axes (/..)

Using this axes, xpath traverses to the immediate parent element in the html tree. Shortcut of this axes is single forward slash (/..)

e.g.: //input[5]/.. → can be written using parent axes as → //input[5]/parent::form

ancestor axes

Using this axes, xpath traverses to any parent element in the html tree.

e.g.: //input[5]/../.. → can be written using ancestor axes as → //descendant::input[5]/ancestor::body

preceding-sibling

Using this axes, xpath traverses with in the siblings in upward direction.

e.g.: → xpath using preceding-sibling axes  → descendant::input[5]/preceding-sibling::input[1]  - it will select Input 4

following-sibling

Using this axes, xpath  traverses with in the siblings in downward direction.

e.g. : → xpath using following-sibling axes  → descendant::input[5]/following-sibling::oinput[1]  - it will select Input 6

Following table illustrates a detailed level understanding of all the xpath axes for below html code

<html>

</head>

<body>

        <form id="form">

                Input 1 : <input type="text">

                Input 2 : <input type="text">

                Input 3 : <input type="text">

                Input 4 : <input type="text">

                Input 5 : <input type="text">

                Input 6 : <input type="text">

                Input 7 : <input type="text">

                Input 8 : <input type="text">

                Input 9 : <input type="text">

        </form>

</body>

</html>

 

axes

xpath using axes

xpath without using axes

Matching element

child

//form[@id='form']/child::input[9]

//form[@id='form']/input[1]

Input 9

descendant

//descendant::input[5]

// input[5]

Input 5

parent

//descendant::input[5]/parent::form

//input[4]/..

form tag

//input[5]/parent::form

Not available

 

ancestor

//input[5]/ ancestor::form

form tag

//input[5]/ ancestor::body

body tag

//input[5]/ ancestor::hmtl

html tag

preceding-sibling

//input[5]/preceding-sibling::input

Not available

Input 1

(It matches with Input 1, Input 2, Input 3, Input 3, but puppeteer return first matching element, i.e. Input 1)

//input[5]/preceding-sibling::input[1]

Input 4

//input[5]/preceding-sibling::input[2]

Input 3

//input[5]/preceding-sibling::input[3]

Input 2

//input[5]/preceding-sibling::input[last()]

Input 1

//input[5]/preceding-sibling::input[last()-1]

Input 2

//input[5]/preceding-sibling::input[position()=2]

Input 3

following-sibling

//input[5]/following-sibling::input

Not available

Input 1

(It matches with Input 6, Input 6, Input 7, Input 8, but puppeteer return first matching element, i.e. Input 6)

//input[5]/following-sibling::input[1]

Input 6

//input[5]/following-sibling::input[2]

Input 7

//input[5]/following-sibling::input[3]

Input 8

//input[5]/following-sibling::input[position()=2]

Input 7

//input[5]/following-sibling::input[last()-1]

Input 8

//input[5]/following-sibling::input[position()=last()]

Input 9

You can write the script and test these using our Test Page

xpath-axes-0
 

import { launch, Page } from 'puppeteer';

 

example();

 

async function example() {

    const browser = await launch({headless : false});

    const page = await browser.newPage();

    await page.setViewport({ width: 1366, height: 768});

    await page.goto('https://www.tools4testing.com/contents/puppeteer/testpages/xpath-axes-testpage');

   

    await testXpath(page);

   

    //wait for some time before closing, specify time in milliseconds

    await wait(5000);

   

    //Close browser

    await browser.close();

}

 

async function testXpath(page: Page) : Promise<void> {

    await (await page.$x("//input[5]/preceding-sibling::input[last()]"))[0].type("Input 1");

    await (await page.$x("//input[5]/preceding-sibling::input[last()-1]"))[0].type("Input 2");

    await (await page.$x("//input[5]/preceding-sibling::input[position()=2]"))[0].type("Input 3");

    await (await page.$x("//input[5]/preceding-sibling::input[1]"))[0].type("Input 4");

    await (await page.$x("// input[5]"))[0].type("Input 5");

    await (await page.$x("//input[5]/following-sibling::input[1]"))[0].type("Input 6");

    await (await page.$x("//input[5]/following-sibling::input[2]"))[0].type("Input 7");

    await (await page.$x("//input[5]/following-sibling::input[3]"))[0].type("Input 8");

    await (await page.$x("//input[5]/following-sibling::input[position()=last()]"))[0].type("Input 9");

}

 

//wait if needed

async function wait(time) {

    return new Promise(function(resolve) {

        setTimeout(resolve, time)

    });

}

 

Click here to learn to execute puppeteer example using typescript


All Chapters
Author