Diagnosing errors on Puppeteer running on Heroku with screenshot - node.js

I can't figure out why Puppeteer is unable to locate elements when running on Heroku that it can locate while running locally.
I'd like to try and diagnose my issue by having Puppeteer take a screenshot of the page, but I can't figure out how to retrieve the screenshot so I can see it.
Where do I go on Heroku to view the screenshot which is generated?
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
let url =
"https://www.realtor.ca/map#ZoomLevel=14&Center=43.744046%2C-79.406789&LatitudeMax=43.76832&LongitudeMax=-79.36641&LatitudeMin=43.71977&LongitudeMin=-79.44717&view=list&Sort=6-D&PropertyTypeGroupID=1&PropertySearchTypeId=1&TransactionTypeId=2&PriceMax=1500000&BuildingTypeId=1&Currency=CAD";
await page.goto(url, { timeout: 60000, waitUntil: "domcontentloaded" });
await page.setViewport({ width: 1024, height: 800 });
await page.screenshot({
path: "./screenshot.jpg",
type: "jpeg",
fullPage: true
});
await page.close();
await browser.close();
})();

Related

Twitter Puppeteer - how to click elements

Hello I'm trying join twitter via puppeteer to twitter, sign up via gmail.
But I'm facing objects I see by inspect aren't visible source of page, and I don't understand.
Here is example of code:
async function twitter(browserID) {
const browserData = await getProfileData(browserID);
const port = browserData.automation.port;
const wsEndpoint = browserData.automation.wsEndpoint;
// temp
// let port = "52654";
// let wsEndpoint = "/devtools/browser/7e7701c5-64c1-4d32-be9a-6198c58d58ae";
const browser = await puppeteer.connect({
browserWSEndpoint: `ws://127.0.0.1:${port}${wsEndpoint}`,
});
const page = await browser.newPage();
await page.setViewport({
width: 1920,
height: 1080,
deviceScaleFactor: 1,
});
await page.goto('https://twitter.com', { waitUntil: 'networkidle2' });
await sleep(5000);
await page.click('span[class^="nsm7Bb-HzV7m-LgbsSe-"]');
await sleep(3000);
};
I've fixed issue:
await page.goto('https://twitter.com');
await sleep(3000);
const frame = page.frames().find(f => f.url().startsWith('https://accounts.google.com/gsi/button'));
const acceptBtn = await frame.$('#container > div > div.nsm7Bb-HzV7m-LgbsSe-bN97Pc-sM5MNb.oXtfBe-l4eHX > span.nsm7Bb-HzV7m-LgbsSe-BPrWId');
await acceptBtn.click();

puppeteer writing in the label doesn't work pop up

I'm creating a bot to enter the site.
After opening the popup I have 2 fields, emailAddress and password. Both have random id and only name value.
The emailAddress is not completing. But the password works normally(completing).
This is a part my code
//open poupup
await page.$eval( '#anchor-open', form => form.click() );
//wait for the screen to load
await page.waitForSelector('input[name="emailAddress"]');
//write in the fields
await page.type('input[name="emailAddress"]', '22#d.com', {delay: 100});
await page.type('input[name="password"]', '****************', {delay: 100});
Can someone help me?
You need to wait for domcontentloaded event. then wait for #anchor-acessar element before click it.
The code below working fine with me.
const puppeteer = require("puppeteer");
(async () => {
const browser = await puppeteer.launch({
headless: false,
});
const page = await browser.newPage();
await page.goto("https://www.nike.com.br", {
waitUntil: "domcontentloaded",
});
await page.waitForSelector('#anchor-acessar');
await page.$eval("#anchor-acessar", (form) => form.click());
await page.waitForSelector('input[name="emailAddress"]');
await page.type('input[name="emailAddress"]', "22#d.com", { delay: 100 });
await page.type('input[name="password"]', "****************", { delay: 100 });
await page.keyboard.press('Enter');
// await browser.close();
})();

Puppeteer taking so long to load the page

I am trying to load a URL using Puppeteer and take the screenshot, somehow the page loading is taking too long. Here is my code
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
// headless: false,
args: [
`--window-size=42280,39960`,
// `--shm-size=1gb`,
// `--disable-dev-shm-usage`
]
});
const page = await browser.newPage();
await page.setViewport({
height: 39960,
width: 42280,
});
console.log('Page created');
await page.goto('https://www.google.com');
console.log('page loaded');
await page.screenshot({
path: 'example.png'
});
await browser.close();
})();
Did anyone face the same problem?
The reason of the failure is this:
await page.setViewport({
height: 39960,
width: 42280,
});
Error running your code. Error: Protocol error
(Page.captureScreenshot): Target closed.
Puppeteer can't take a screenshot with that resolution.

Running a loop within an instance of Puppeteer

Just getting started with Puppeteer and i can launch the browser, go to a url, run a bunch of actions and then close the browser. What i am looking to see if i can do though is open the browser and loop over a set of actions in the same session.
I have a JSON object with urls i want to visit, so want to loop over that
// teams.js
module.exports = {
premier_league: [
{ team_name: "Team 1", url: "https://url-of-site/team_1"},
{ team_name: "Team 2", url: "https://url-of-site/team_2"}
]
}
My script to launch puppeteer is as follows
// index.js
const TEAM = require('./teams');
const puppeteer = require('puppeteer');
(async () => {
// Initialise Browser
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
await page.setViewport({
width: 1280,
height: 800
});
await page.goto('login page');
await page.click('login_box');
await page.keyboard.type('username');
await page.click('login_password');
await page.keyboard.type('password');
await page.click('login_button');
await page.waitForNavigation();
// Go To Team URL
await page.goto('Team URL')
await browser.close();
})();
So to loop over my JSON object I can use
Object.keys(TEAM['premier_league']).forEach(function(key) {
// Output url of each team
console.log(TEAM['premier_league'][key]['url'])
});
If i wrap my go to url with my loop, then page is no longer accessible
// index.js
const TEAM = require('./teams');
const puppeteer = require('puppeteer');
(async () => {
// Initialise Browser
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
await page.setViewport({
width: 1280,
height: 800
});
await page.goto('login page');
await page.click('login_box');
await page.keyboard.type('username');
await page.click('login_password');
await page.keyboard.type('password');
await page.click('login_button');
await page.waitForNavigation();
Object.keys(TEAM['premier_league']).forEach(function(key) {
// Go To Team URL
await page.goto(TEAM['premier_league'][key]['url'])
});
await browser.close();
})();
The actual error is
await page.goto(TEAM[args][key]['url'])
^^^^
SyntaxError: Unexpected identifier
Your Object.keys callback function need to use async as well in order to use await inside. Try to change as below
Object.keys(TEAM['premier_league']).forEach( async function(key) {
// Go To Team URL
await page.goto(TEAM['premier_league'][key]['url'])
});
Hope it helps

Node puppeteer take screenshot full page SPA

I have a single page application with scrolling. I am trying to take a screenshot of the whole page, but it only gives me the visible part. How can I make it shoot the whole page?
const browser = await puppeteer.launch(options);
const page = await browser.newPage();
await page.goto(url);
await page.screenshot({ path: 'page.png', fullPage: true })
await browser.close();
Actually what is happening here that your page might took a while to load in full. So we have to increase the timeout. And before taking screen shot take a short break of 500ms and then it will take full page screenshot. Try below code.
const puppeteer = require('puppeteer');
async function runTest() {
const browser = await puppeteer.launch({
headless: false,
timeout: 100000
});
const page = await browser.newPage();
const url = 'https://stackoverflow.com/questions/47616985/node-puppeteer-take-screenshot-full-page-spa';
await page.goto(url, {
waitUntil: 'networkidle2'
});
await page.waitFor(500);
await page.screenshot({ path: 'fullpage.png', fullPage: true });
browser.close();
}
runTest();
Your code looks correct. What are you passing in options?
Is the page actually launching? Try turning off headless browser to check:
const browser = await puppeteer.launch({
headless: false
});
The following works for me to take a full page screenshot:
const puppeteer = require('puppeteer');
async function run() {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://yahoo.com');
await page.screenshot({ path: 'yahooPage.png', fullPage: true });
browser.close();
}
run();

Resources