Get Element(s) in Puppeteer

Unlike other automation tools, getting an element in puppeteer a bit difficult and also Limited. It is not because the automation tool has a limitation, but puppeteer provides all the operations as functions that you need without requiring the element.

This is the reason why it is difficult to get an element(s) in puppeteer. But some cases explicitly requires element rather than performing operations; in such cases, we have to get the element for further use.

Here I have listed a few ways, using which you can get an element/elements with the puppeteer.

  • $ and $$
  • $x fetches all elements
  • $evaluateHandle

Percy with Puppeteer Integration

$ and $$

$("locator") - Get single element
const element = await page.$("a"); // get only the first link

The complete program to get an element in puppeteer

const puppeteer = require('puppeteer');
async function run(){
    const browser = await puppeteer.launch({headless:false})
    const page = await browser.newPage()
    await page.goto('https://google.com')
    const element = await page.$("a");
    const text = await (await element.getProperty("innerText")).jsonValue();
    console.log(await text);
}
run() 

get-element-puppeteer

$$("locator") - Get all matching elements

Instead of using forEach you can also use the for loop, using for loop is easier.

const elements = await page.$$("a");
elements.forEach(async element => {
	const text = await (await element.getProperty("innerText")).jsonValue();
	console.log(await text);
});

get-all-elements-puppeteer

Custom Commands in Puppeteer

$x fetches all the values

$x is used to fetch elements based on XPath, it returns all the matching elements, if no matching elements are there then returns an empty array.

You can form the Xpath in a way that puppeteer can find using text

const elements = await page.$x("//a");
elements.forEach(async element => {
	const text = await (await element.getProperty("innerText")).jsonValue();
	console.log(await text);
});

xpath-get-all-elements-puppeteer

$x for a single element

As I mentioned earlier, $x returns all the matching elements, in case if you are only interested in one element then you can use the index 0, to get the first element.

const element = await page.$x("//a");
const text = await (await element[0].getProperty("innerText")).jsonValue();
console.log(await text);

get-single-element-puppeteer-xpath

Radio Button and Checkbox in Puppeteer

$evaluateHandle

The below discussing things will be executed on the console of the browser. you can check this by opening the console under Dev Tool.
dev-console-find-all-elements-puppeteer

Single match

You can use javascript on the browser to get the elements from the UI. querySelectorAll() function returns all the matches for the given CSS selector. But for now, we are only interested in the first element.

let elementsHandles = await page.evaluateHandle(
	() => document.querySelectorAll('a'));
let elements = await elementsHandles.getProperties();
let elements_arr = Array.from(elements.values());
console.log(await (await elements_arr[0].getProperty("innerText")).jsonValue())

element-handles-puppeteer-find-element

All matches:

Instead of sticking to a single match, we can get all the matches and iterate them

const puppeteer = require('puppeteer');
async function run(){
    const browser = await puppeteer.launch({headless:false})
    const page = await browser.newPage()
    await page.goto('https://google.com')
    let elementsHandles = await page.evaluateHandle(
        () => document.querySelectorAll('a'));
    let elements = await elementsHandles.getProperties();
    let elements_arr = Array.from(elements.values());
    elements_arr.forEach(async element => {
        console.log(await (await element.getProperty("innerText")).jsonValue())
    });
}
run() 

evaluate-handles-puppeteer-get-all-mathcing-elements

You can use other functions as well inside evaluateHandle:

Instead of querySelectorAll, you can use different functions as well to find elements.

  • getElementById
  • getElementsByClassName
  • getElementsByName
  • getElementsByTagName

get-element-javascript-dev-tools-puppeteer

In case if you are very good at Javascript on the browser console, then you might have an idea of JQuery; but for this scenario, JQuery does not work inside evaluateHandle

Get Element(s) in Puppeteer

Frequently Asked Questions

puppeteer find element by text

You have to form XPath based on the text so that you can find the element.

//tagname[text()='text on ui']
Example on google page
//a[text()='Gmail']

Once you form the XPath then you can use the $x method to find the element. Please read above for the $x topic.

puppeteer get element by class

You can get the elements by using the class in puppeteer, but the puppeteer does not understand what is class or id; so you have to use the CSS format to make the puppeteer understand it.

Use . (dot) before the class name to denote that the following is class.

<a class='abc' href='#'>ABC</a>
CSS locator is :
.abc
// in code
await page.$x(".abc")

If you have more than one class to use the form CSS selector by combining.

<a class='abc bbc' href='#'>ABC</a>
CSS (note below, there no space between classes, because they are from the same element:
.abc.bbc
// in code
await page.$x(".abc.bbc")

If you have classes under different elements then use space between the classes:

<div class='xyz'>
  <a class='abc' href='#'>ABC</a>
<.div>
CSS (note the space between two classes):
.xyz  .abc
// in code
await page.$x(".xyz  .abc")
Puppeteer get the element with id:

For id, use the # sign to form the CSS locator:

<a id='abc' href='#'>ABC</a>
CSS:
#abc
// in code
await page.$x("#abc")
Puppeteer get the element with a name :
<a name='abc' href='#'>ABC</a>
CSS:
[name='abc']
// in code
await page.$x("[name='abc']")

iFrames in Puppeteer

About Author :

I am Pavankumar, Having 8.5 years of experience currently working in Video/Live Analytics project.

Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions