puppeteer: Click event is not firing

Sorry for my bad English. I have a problem with authentication on… pornhub. 🙂 The login page have an auth form with #submit button, the button have a click event which makes an AJAX request to /front/authenticate, but the event is not firing and the browser navigates to /login?[params] (the form does not have “action” and “method” attributes). The submit button works normally If I click it manually (in non-headless mode). Also, I can’t access internal variables (for example, $j or loginAjax() (script below)) inside page.evaluate().

My script:

const puppeteer = require('puppeteer');
(async() => {
const browser = await puppeteer.launch({
    headless: false
});
const page = await browser.newPage();
await page.setViewport({width: 1024, height: 768});
await page.goto('https://www.pornhub.com/login');
await page.evaluate(() => {
    document.getElementById('username').value = 'user';
    document.getElementById('password').value = 'pass';
    document.getElementById('submit').click();
});
// does not help
// await page.click('#submit');
})();

Internal auth script:

function loginAjax() {
    return $j.ajax({
        type: "POST",
        url: "/front/authenticate",
        cache: !1,
        dataType: "json",
        data: $j(".js-loginForm").serialize(),
        success: function(n) {
            "0" == n.premium_redirect_cookie ? n.redirect ? document.location.assign(n.redirect) : $j(".signinError").show().text(n.message) : $j.ajax({
                url: premiumRedirectCookieURL,
                cache: !1,
                crossDomain: !0,
                xhrFields: {
                    withCredentials: !0
                },
                success: function() {
                    n.redirect ? document.location.assign(n.redirect) : $j(".signinError").show().text(n.message)
                }
            })
        }
    }), !1
}
head.ready(document, function() {
    var n = !1;
    $j(".js-loginSubmit").on("click", function(n) {
        n.preventDefault(), loginAjax()
    }), $j("input.js-signinUsername, input.js-signinPassword").on("keydown", function(i) {
        n || (13 == i.which && loginAjax(), n = !0)
    }), $j("input.js-signinUsername, input.js-signinPassword").on("keyup", function(i) {
        n && (n = !1)
    })
});

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 54
  • Comments: 20 (2 by maintainers)

Most upvoted comments

The following works for me. Note the ‘networkidle’ argument for page.goto. Also, the delay in typing is just for the ease of debugging.

const puppeteer = require('puppeteer');

(async() => {
const browser = await puppeteer.launch({
    headless: false
});
const page = await browser.newPage();
await page.setViewport({width: 1024, height: 768});
await page.goto('https://www.pornhub.com/login', {waitUntil: 'networkidle'});
await page.focus('#username');
await page.type('user', {delay: 100});
await page.focus('#password');
await page.type('pass', {delay: 100});
await page.click('#submit');
})();

I’ve found another really weird case, on 0.13.0:

The following does not work:

for (let element of elements) {
      await element.click()
    }

The following works:

for (let element of elements) {
      await page.evaluate((el) => {
        return el.click()
      }, element);
    }

@JoelEinbinder I found already the second website for which

await page.evaluate((el) => {
        return el.click()
      }, element);

works

while element.click() does not.

To be sure I understood your comment, is element.click() useful only for triggering the mouse-hover event and move the mouse on the element?

I had similar issue where click was working half the time. I figured out that moving first the mouse then trigger the click is 100% working:

const mouse = page.mouse
await mouse.move(parseFloat(x), parseFloat(y));
await mouse.click(parseFloat(x), parseFloat(y), {
            "button": "left",
            "clickCount": 1,
            "delay": 0
        });

It sounds like not all of the JavaScript is done loading by the time you try to click the button.

Consider this website: https://jsfiddle.net/3zes4tkp/

If you run HTMLElement.click, on the page, you can trigger on the onclick listener. But the div isn’t actually clickable, because it is being covered by something else. Puppeteer’s click will fail to trigger the onclick. This is intended, because that is what would happen if the user tried to click the element.

el.click() did not work. I use the following for my click and click text functions Hope this is useful who has issue that I had, which click not happening

  async click(selector, within='') {
    const cssSelector = within ? `${within} ${selector}`: selector;
    const element = await page.waitForSelector(cssSelector, {visible: true});
    return await page.evaluate(el => el.click(), element);  // <---- this
  }

  async clickText(text, selector) {
    const element = await page.waitForFunction(iSeeText, {}, text, selector);
    return await page.evaluate(el => el.click(), element); // <---- this
  }

The documentation for page.goto specifies four options for waitUntil. I had to wait for all four, like so:

const puppeteer = require('puppeteer');

(async() => {
    puppeteer.launch().then(async browser => {
        const page = await browser.newPage();
        await page.goto('https://example.com/login', {
            waitUntil: ['load','domcontentloaded','networkidle0','networkidle2']
        });
        // now try here ...
        // await page.focus('#username');
        // await page.type('user');
        // await page.focus('#password');
        // await page.type('pass');
        // await page.click('#submit');
    });
});

@bitliner Puppeteer’s .click is very different from HTMLElement.click. The latter just fakes a “click” event. We tell Chrome that the mouse moved over the center of the element and was pressed, which triggers hover effects, clicks deep into the element, will be blocked by overlay elements, etc.

If Puppeteer’s click doesn’t work for you, there is a very good chance that clicking is not working on your site. Make sure the element is actually onscreen and clickable when you are trying to click it.

There is another reason why the click event may not effect the website. Take the send button of web.telegram.org for example. The button listens for the event “mousedown”. I assume that “onclick” and “onmousedown” are different so that clicking will only trigger the event “onclick”. This made me headaches for two days. Do it better.

const send = document.querySelector("button[class='btn btn-md im_submit im_submit_send']");
//Does not work.
send.click()
//Works!
const ev = new Event("mousedown");
send.dispatchEvent(ev);

Have the same issue. Scripts are loaded.