javascripthtmlpuppeteer

How do you click on an element with text in Puppeteer?


Is there any method or solution to click on an element with text? I couldn't find one in the API.

For example I have the following HTML:

<div class="elements">
    <button>Button text</button>
    <a href=#>Href text</a>
    <div>Div text</div>
</div>

And I want to click on an element in which text is wrapped (click on the button inside .elements), like so:

Page.click('Button text', '.elements')

Solution

  • Short answer

    This XPath expression will query a button which contains the text "Button text":

    const [button] = await page.$x("//button[contains(., 'Button text')]");
    if (button) {
        await button.click();
    }
    

    To also respect the <div class="elements"> surrounding the buttons, use the following code:

    const [button] = await page.$x("//div[@class='elements']/button[contains(., 'Button text')]");
    

    Explanation

    To explain why using the text node (text()) is wrong in some cases, let's look at an example:

    <div>
        <button>Start End</button>
        <button>Start <em>Middle</em> End</button>
    </div>
    

    First, let's check the results when using contains(text(), 'Text'):

    Here are the XPath expressions for contains(., 'Text'), which works on the element itself including its child nodes:

    So in most cases, it makes more sense to use the . instead of text() in an XPath expression.