'How to click on a specific TD element with puppeteer without id and name

I'm having trouble while trying to find a way to click the submenu option in this nav menu The submenu option I want to click and the code of it

Is there a way of selecting it by it's content of it or by other alternative?

I tried await page.click(); but since i don't have any id, name or value to identify that option it automatically closes the chromium page

also tried clicking wit the content const select = require('puppeteer-select'); const element = await select(page).getElement('div:contains(Negociação)'); await element.click(); didn't work either.



Solution 1:[1]

It is possible to filter certain elements by its text. Here is an example on how to select a table element and search in all its cells for a given text.

I started by writing 2 helper functions for getting text from an element and another to search text within an array of elements:

// returns text for an array of elements
async function findElementByText(elements, searchText) {

    for(let el of elements) {

        // get the text of the element and return
        // element if text matches
        const text = await getText(el)

        console.log(`found text: "${text}", searchText: "${searchText}"`)
        // alternatively you could use this for being a little more error tolerant
        // depends on your use case and comes with some pitfalls.
        // return text.toUpperCase().includes(searchText.toUpperCase())
        
        // compare text and return element if matched
        if(searchText === text) {
            return el
        }
    }

    // NO element found..
    console.log('No element found by text', searchText)
    return null

}

// returns text from a html element
async function getText(element) {
    const textElement = await element.getProperty('textContent')
    const text = await textElement.jsonValue()

    // make sure to remove white spaces.
    return text.trim()
}

With given helper functions you can now select the table and search within its td elements (the cells) .


// This selects the first found table. You may wanna grab the correct table by a classname.
const table = await page.$('table')

// select all cells in the table.
const cells = await table.$$('td')

// search in the cells for a given text. "cell" will be a JSHandle
// which can be clicked!
const searchText = 'text4'
const cell = await findElementByText(cells, searchText)

if(!cell) {
    throw 'Cell with text ' + searchText + ' not found!!.' 
}

console.log('clicking cell now.')
// click the element
await cell.click()

If you host the html yourselve it would make life easier by setting a classname OR id to the cells you wanna click. (only if allowed and possible ofc) .

In your next question you should provide the html as plaint text instead of an image. Plain text can easily be copied by other users to test and debug.

Feel free to leave a comment.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1