The workflow right now is just a single code node containing this script. I went a bit crazy sanitizing, so just know that the real code does work perfectly except that there is no previewing the pngs or pdfs, I must download them to view:
const puppeteer = require('puppeteer');
async function captureScreenshot(page) {
return await page.screenshot({ encoding: 'base64' });
}
async function navigateAndWaitForNavigation(page, selector) {
try {
await Promise.all([
page.click(selector),
page.waitForNavigation({ waitUntil: 'networkidle2' }) // Adjust timeout as needed
]);
} catch (error) {
console.log(`Navigation error: ${error.message}`);
}
}
//function for quickly adding screenshots to output item array
async function addItemWithScreenshot(items, page, filename) {
const screenshot = await captureScreenshot(page);
items.push(
{
json:
{
filename: filename,
size: screenshot.length
},
binary: {
[filename]: {
data: screenshot,
mimeType: 'image/png',
fileExtension: 'png',
fileName: filename
}
}
});
}
//define sleep function for explicit waiting
const sleep = ms => new Promise(r => setTimeout(r, ms));
//main process
return new Promise(async (resolve, reject) => {
try {
const browser = await puppeteer.launch({
executablePath: '/usr/bin/chromium-browser',
args: ['--no-sandbox', '--disable-setuid-sandbox', '--user-data-dir="/xxx/"'],
headless: true
});
const url = 'xxx';
const items = [];
var page = await browser.newPage();
await page.setViewport({ width: 1280, height: 800 });
await page.goto(url, { waitUntil: 'networkidle2' });
// take screenshot before submitting and nav away
await addItemWithScreenshot(items, page, '1.png');
// type email address into textbox
await page.type('#email', 'xxx');
// take screenshot before submitting and nav away
await addItemWithScreenshot(items, page, 2.png');
// click submit button and wait for nav
'''
try {
await navigateAndWaitForNavigation(page, '#xxx');
} catch (error) {
console.log(`Error during post email entry navigation: ${error.message}`);
}
// Type the password
await page.waitForSelector('xxx');
await page.type('xxx', 'xxx');
// ss the filled in pw before submitting
await addItemWithScreenshot(items, page, '3.png');
// submit pw
try {
await navigateAndWaitForNavigation(page, 'xxx'); // Hitting Enter
} catch (error) {
console.log(`Error during password submit navigation: ${error.message}`);
}
// 2 FA page
try {
await Promise.all(
[
page.waitForSelector('[data-value="xxx"]'),
addItemWithScreenshot(items, page, '4.png'),
navigateAndWaitForNavigation(page, '[data-value="xxx"]' )
]
)
}
catch (error) {
console.log(`Error clicking element: ${error.message}`);
}
await addItemWithScreenshot(items, page, '5.png');
try {
await Promise.all(
[
page.click('[name="xxx"]'),
navigateAndWaitForNavigation(page, '[id="xxx"]')
]
)
}
catch (error) {
console.log(`Error clicking element: ${error.message}`);
}
await addItemWithScreenshot(items, page, '6.png');
await page.goto('xxx', { waitUntil: 'networkidle2' });
await page.waitForSelector('[xxx]');
await addItemWithScreenshot(items, page, '7.png');
const reportelement = await page.$('[aria-label="xxx"]');
const reportpdf = await page.pdf();
const pcookies = await page.cookies();
// Generate a PDF from the screenshot
items.push(
{
json:
{
filename: 'report.pdf',
size: reportpdf.length
},
binary: {
['report.pdf']: {
data: reportpdf.toString('base64'),
fileName: 'report.pdf',
mimeType: 'application/pdf'
}
}
});
await page.close();
await browser.close();
// Resolve the promise with the items array
resolve(items);
} catch (error) {
console.log(`Error in Puppeteer operation: ${error.message}`);
reject(error);
}
});