I got following Problem. If I run this code I get this error message and I cant seem to fix it.
Uncaught Error Error: Evaluation failed: TypeError: Cannot read properties of undefined (reading 'click') at _evaluateInternal (c:\Users\Name\node_modules\puppeteer\lib\cjs\puppeteer\common\ExecutionContext.js:221:19) at processTicksAndRejections (node:internal/process/task_queues:96:5)
const puppeteer = require('puppeteer');
const url = "https://www.zalando.de/nike-sportswear-blazer-mid-77-sneaker-high-ni115n001-a13.html";
async function initBrowser() {
const browser = await puppeteer.launch({ headless: false });
const page = await browser.newPage();
await page.goto(url);
await page.screenshot({ path: 'example.png' });
return page;
}
async function addToCart(page) {
await page.$eval('span[class="piG9a1 _1IcNq Uxq3DH QylWsg JCuRr_ RYghuO _7Cm1F9 ka2E9k uMhVZi FxZV-M"]', element => element.click());
await page.$$eval('.example', elements => {
const element = elements.find(element => element.innerHTML === '39');
element.click();
});
await page.$eval('button[class="DJxzzA u9KIT8 uEg2FS U_OhzR ZkIJC- Vn-7c- FCIprz heWLCX JIgPn9 LyRfpJ pxpHHp Md_Vex NN8L-8 GTG2H9 MfX1a0 WCjo-q EKabf7 aX2-iv r9BRio mo6ZnF E6Km4r"]', element => element.click());
}
async function checkout() {
const page = await initBrowser();
await addToCart(page);
}
checkout();
You are doing
await page.$$eval('.example')
Not sure if there is any element example and .find is not guaranteed to return any value. Always do if check
const element = elements.find(element => element.innerHTML === '39');
if (element){
element.click();
}
MDN on find - The find() method returns the first element in the provided array that satisfies the provided testing function. If no values satisfy the testing function, undefined is returned.
This one was pretty tricky. I'm not sure why, but there are some strange visibility and event handling characteristics on the page, so I basically "brute forced" it by trying both trusted and untrusted events for clicks and selection.
For the picker trigger (size select dropdown), I used an untrusted event. Selecting the size worked best with a trusted event, and adding to cart worked with a trusted event. These might not be hard-and-fast rules, so I might have missed something, but the code below should capture a screenshot of the item in the cart.
I was also finding that the cookie banner seems to throw off the dropdown. Waiting and dismissing it improved the reliability of the script, but I eventually commented it out for speed and because it might not be necessary. I didn't do enough runs to say for sure, though, so it's left in the code below.
Here's the code:
const puppeteer = require("puppeteer"); // ^13.5.1
let browser;
(async () => {
browser = await puppeteer.launch({headless: true});
const [page] = await browser.pages();
const ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36";
await page.setExtraHTTPHeaders({"Accept-Language": "en-US,en;q=0.9"});
await page.setUserAgent(ua);
const url = "https://www.zalando.de/nike-sportswear-blazer-mid-77-sneaker-high-ni115n001-a13.html";
await page.goto(url, {waitUntil: "domcontentloaded"});
// optionally accept the cookie banner
//const cookie = await page.waitForSelector("#uc-btn-accept-banner");
//await cookie.evaluate(el => el.click());
const picker = await page.waitForSelector("#picker-trigger");
await picker.evaluate(el => el.click());
await page.waitForFunction(() =>
[...document.querySelectorAll(".fOd40J._0xLoFW.JT3_zV.FCIprz.LyRfpJ")]
.find(el => el.innerText === "39")
);
const size = await page.evaluateHandle(() =>
[...document.querySelectorAll(".fOd40J._0xLoFW.JT3_zV.FCIprz.LyRfpJ")]
.find(el => el.innerText === "39")
);
await size.click();
await page.click(".U4aOaA > .DJxzzA");
await page.evaluate(() => window.scrollTo(0, 0));
await page.waitForFunction(() =>
document.querySelector('a[title="Your bag"]')?.textContent.startsWith("1")
);
await page.goto("https://en.zalando.de/cart/");
await page.screenshot({path: "testing-in-bag.png"});
})()
.catch(err => console.error(err))
.finally(() => browser?.close())
;