Company logo
  • Jobs
  • Bootcamp
  • About Us
  • For professionals
    • Home
    • Jobs
    • Courses
    • Questions
    • Teachers
    • Bootcamp
  • For business
    • Home
    • Our process
    • Plans
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Calculator

0

401
Views
Node JS Puppeteer click on a li element without name or id

I'm trying to click on a li element which for some reason works as a size selector on a certain website. It looks like this

size selector

And its html looks like this

enter image description here

Each <li> represents one size option, I've tried some stuff but none of it works.

my first attempt was using xpath:

const [size_button] = await page.$x(`//*[contains(., '${data[ii][1]}')]`); // doesn't work
await size_button.click();

I also tried a regular click action:

await page.click(`li[data-original-title="Größe in EU: ${data[ii][1]}"]`); // the array contains a specific size, eg. 40.5 like in the li data-original-title field

None of this worked, and I'm wondering if it is even possible to click on such a element with puppeteer...

If anyone would like to examine the page, the link is here

8 months ago · Santiago Trujillo
2 answers
Answer question

0

This is a bit tricky. Your selector is working OK, as is the click event, but I suspect that event does nothing but call e.preventDefault() to prevent navigation to the anchor's href.

The highlight showing the size was selected is actually applied by a mousedown event in the <a>'s parent <li>, and it seems the child event hasn't been applied or doesn't bubble using your .click method:

image showing browser console element tree with the li element's mousedown event circled to indicate it's the important event OP wants to trigger

You can trigger this as follows:

const puppeteer = require("puppeteer"); // ^13.5.1

let browser;
(async () => {
  browser = await puppeteer.launch({headless: false});
  const [page] = await browser.pages();
  await page.setRequestInterception(true);
  page.on("request", req => {
    req.resourceType() === "image" ? req.abort() : req.continue();
  });
  const url = "https://en.afew-store.com/products/air-jordan-4-retro-tour-yellow-dark-blue-grey-white";
  await page.goto(url, {waitUntil: "domcontentloaded"});
  const size = "8.5";
  const xp = `//a[contains(@class, "btn-sm") and text()="${size}"]`;
  const sizeButton = await page.waitForXPath(xp);
  await sizeButton.evaluate(btn => {
    btn.closest("li").dispatchEvent(new Event("mousedown"));
    //  ^--- .parentNode is also possible instead of .closest("li")
  });
  await page.waitForTimeout(10000);
})()
  .catch(err => console.error(err))
  .finally(() => browser?.close())
;

The final timeout gives you a chance to look at the page and see that size 8.5 was highlighted.

Note that I've made your xpath selector more precise to avoid false positives.

8 months ago · Santiago Trujillo Report

0

In this case you could for instance get al <a tags with the class="btn btn-sm"

I think is a good idea get the expected result in the console of the browser using Vainilla Javascript, and when suscess try to reach the same result with Puppeteer

  • Vainilla Javascript

     const sizeLinks = document.querySelectorAll('a.btn.btn-sm')
     sizeLinks[1].click()
    
  • Puppeteer (Full working example)

      'use strict'
    
       const puppeteer = require('puppeteer');
    
      (async () => {
         const baseUrl = 'https://en.afew-store.com/products/air-jordan-4-retro-tour-yellow-dark-blue-grey-white'
    
         const browser = await puppeteer.launch({ headless: false }); // default is true
    
         const page = await browser.newPage();
         await page.goto(baseUrl, {
              waitUntil: 'networkidle2',
         });
    
          await page.waitForTimeout(5000) // Leave extra time for complete the page load (Just to be cautious)
    
          const sizeLinks = await page.$$('a.btn.btn-sm')
          await sizeLinks[1].click() 
    
          console.log('Debugging')
    
          //await browser.close();
          //console.log(`Browser has been closed`);
    
          //process.exit(0);
    })();
    
  • Reference:

JavaScript querySelector() and querySelectorAll()

enter image description here

8 months ago · Santiago Trujillo Report
Answer question
Find remote jobs