The problem is that I am trying to click on a specific option and I try to do another operation but seems that I am accessing it before the page is loaded fully after clicking on PersonalData
import { Page as PuppeterrPage } from "puppeteer";
export async function enterPersonalField(page: PuppeterrPage) {
const personalFieldElement =
"#sidebar-user-name > bb-ui-username > div > div > bdi";
const personalData = await page.waitForSelector(personalFieldElement);
if (personalData) {
await personalData.click();
// from here is the problem
await page.waitForNavigation();
await getPersonalData(page);
} else {
console.log("Something broke while clicking the personal data button");
}
}
async function getPersonalData(page) {
await getBasicData(page);
await getAdditinalInfo(page);
}
async function getBasicData(page) {
const nameSelector =
"#base-profile-full-name > bb-ui-username > div > div > bdi";
const fullName = await page.$eval(
nameSelector,
(element) => element.innerText
);
const emailSelector = "#base-profile-email";
console.log("Full Name:", fullName);
const emailAddress = await page.$eval(
emailSelector,
(element) => element.innerText
);
const idSelector =
"#body-content > div.row.collapse > div.columns.small-12.profile-content > div.columns.large-6.small-12.user-information > section:nth-child(1) > ul > li:nth-child(3) > div > a > span:nth-child(1)";
const ID = await page.$eval(idSelector, (element) => element.innerText);
}
async function getAdditinalInfo(page) {
const genderSelector =
"#body-content > div.row.collapse > div.columns.small-12.profile-content > div.columns.large-6.small-12.user-information > section:nth-child(2) > ul > li:nth-child(1) > div > a > span:nth-child(1) > span";
const gender = await page.$eval(
genderSelector,
(element) => element.innerText
);
const birthSelector =
"#body-content > div.row.collapse > div.columns.small-12.profile-content > div.columns.large-6.small-12.user-information > section:nth-child(2) > ul > li:nth-child(3) > div > a > span:nth-child(1)";
const birthday = await page.$eval(
birthSelector,
(element) => element.innerText
);
console.log("Birthday: ", birthday);
const eduLevelSelector =
"#body-content > div.row.collapse > div.columns.small-12.profile-content > div.columns.large-6.small-12.user-information > section:nth-child(2) > ul > li:nth-child(4) > div > a > span:nth-child(1) > span";
const eduLevelInfo = await page.$eval(
eduLevelSelector,
(element) => element.innerText
);
console.log("Education level: ", eduLevelInfo);
}
when I run this, it gives me this error: throw new Error(Error: failed to find element matching selector "${selector}");
^
I tried to add a waiter for an element to load but I don’t want that because it is not always going to wait for a specific amount of time
>Solution :
I think the only solutions are:
- Wait until an element is visible:
if (personalData) {
await personalData.click();
await page.waitForNavigation();
const nameSelector = "#base-profile-full-name > bb-ui-username > div > div > bdi";
await page.waitForSelector(nameSelector, { visible: true });
await getPersonalData(page);
} else {
console.log("Something broke while clicking the personal data button");
}
}
- Insert a timeout:
if (personalData) {
await personalData.click();
await page.waitForNavigation();
await new Promise(r => setTimeout(r, 5000)); // 5 Seconds
await getPersonalData(page);
} else {
console.log("Something broke while clicking the personal data button");
}
}