Puppeteer: waitForSelector works in local Docker container but times out when deployed on Kubernetes

8/5/2021

I have built a nodeJS service that takes a screenshot of a Single Page Application using Puppeteer. When the SPA is finished loading, a <div> element is added to the DOM. I am trying to capture this in order to continue with the screenshot.

Each request to the service is executed in a new Puppeteer incognito context.

const context = await browser.createIncognitoBrowserContext();
const page = await context.newPage();

I am adding some custom HTTP headers for Google authentification as the SPA is behind an Identity-Aware Proxy:

const auth = new GoogleAuth();
const client = await auth.getIdTokenClient(process.env.AUDIENCE);
const headers = await client.getRequestHeaders(url);
await page.setExtraHTTPHeaders(headers);

The rest of the code is as follows:

const response = await page.goto(url, {waitUntil: 'domcontentloaded', timeout: 50000});
error.handleResponse(response, log);

// Now wait for the dom element marking the map finished loading
log.writeToConsole('Waiting for the #trigger-print selector');
await page.waitForSelector('#trigger-print', {timeout: 50000});
log.writeToConsole('Selector found!');

The web service containing this snippet is dockerised; when I run the image on my local machine (running MacOS 10.15.7) and use the web service, the selector is found. However, when I deploy the same image in the cloud (Kubernetes workload or Google Could Run), page.goto(url) is successful but the waitForSelector function always times out. In this case I capture page.content() and there is no <div id=trigger_print> element. It looks like the SPA stopped loading after page.goto(url) completed.

I am logging all requests and console output but nothing looks out of the ordinary. What I am missing, what could it be and/or how could I debug this?

-- Chloe
docker
kubernetes
node.js
puppeteer

0 Answers