How to click a link in a frame with Puppeteer?

789 Views Asked by At

I'm trying to click on an anchor link within a page that'll open a new tab to export a PDF, but this link lives within a frame inside a frameset like this:

html content

I tried this:

//[login and navigating to the page]
//wait for schedule page
await page.waitForSelector(`frameset`);

//select content frame
const frame = (await page.$("frame[name='link']"));

/*clicking the button after looking for it allow the page to scroll until the button is in frame before clicking it*/
const pdfExport = await frame.$(`a[href='pdf.jsp?clearTree=false']`)
await pdfExport.evaluate(b => b.click()); //error here

await browser.close();

but I get this error:

TypeError: Cannot read properties of null (reading 'evaluate')
    at C:\Projects\scrapproject\Main.js:69:25
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

it seems that it cannot find my a link button but I cannot figure out how to click it. Can you help me please ?

1

There are 1 best solutions below

2
Infern0 On

You are trying to initialize and click on element which is on the main page and not inside the frame. Puppeteer / Playwright have another context for interacting with frames.

Both frameworks have similar context for working with frames.

You can read more about frames context:

Puppeteer: https://pub.dev/documentation/puppeteer/latest/puppeteer/Frame-class.html Playwright: https://playwright.dev/docs/frames

Here is an example snippet of working with frames based on your case:

Puppeteer:

const page = await browser.newPage();
await page.goto('<the actual page>', {waituntil: "networkidle0"});

// Search for the frame with tag name - link
const frameObject = await page.frames.firstWhere((frame) => frame.name == 'link');
if (!frameObject) {
    throw Error('Could not find frame with name: link');
}

// now you can click on the element from the frame - using Frame Object
const downloadLinkElement = await frameObject.$("a[href='pdf.jsp?clearTree=false']"); // init element
// Note: you can add some wait or other condition checker
await downloadLinkElement.click(); // click on the element

Playwright:

test('example switch to frame and click', async ({ page }) => {
    await page.goto('<the actual page>');

    // switch to the frame with name tag - link
    const frameObject = page.frame({ name: 'link' });
    if (!frameObject) {
        throw Error('Could not find frame with name: link');
    }

    // now you can click on the element from the frame - using Frame Object
    const downloadLinkElement = frameObject.locator("a[href='pdf.jsp?clearTree=false']"); // init element
    // Note: you can add some wait or other condition checker
    await downloadLinkElement.click(); // click on the element
});