Puppeteer downloads blank PDF instead of the one expected, with content - download

I have to download a pdf, but it requires first to collect cookies, by visiting the page which hosts the PDF link.
I click the link but a blanc PDF is downloaded with same pages number as the expected one.
(async () => {
const browser = await puppeteer.launch({
dumpio: true,
headless: false,
devtools: true,// I want to see what's going on
})
const [page] = await browser.pages();
page.on('console', msg => console.log(msg.text()));
await page.goto(url_cookie, { waitUntil: ['domcontentloaded', 'networkidle0', 'load'] });
page._client.send('Page.setDownloadBehavior', { behavior: 'allow', downloadPath: './', });
page.once('response', async (response) => {
if (response.url() !== url_pdf) return;
console.log('resp', response.url());
});
const css = 'a[href="' + url + '"]';
await page.waitForSelector(css)
const eval = async css => {
const a = document.querySelector(css);
console.log(a)
return fetch(a.href, {
method: 'GET',
credentials: 'include',
}).then(r => r.text())
};
const txt = await page.evaluate(eval, [css]);
fs.writeFileSync('./test.pdf', txt,)
await page.close();
await browser.close();
})();

Related

Window.open() does not work on safari IOS 16

I am using JavaScript window.open() method to open new window inside of async function, it works well in IE, Firefox, chrome, brave but not working in safari for mobile.
fetch('http://example.com/movies.json')
.then((response) =>
if(response){
const blob = new Blob([response], { type: "application/pdf" });
const url = window.URL.createObjectURL(blob)
window.open(url)
}
)
.catch((error) => console.log(error));
I found one solution for above problem for all browsers with all OS (IOS, android and windows, linux).
It's working for me.
function downloadBlobFile(blob, fileName) {
//Check the Browser type and download the File.
const isIE = !!document.documentMode;
if (isIE) {
window.navigator.msSaveBlob(blob, fileName);
} else {
const url = window.URL || window.webkitURL;
const link = url.createObjectURL(blob);
const a = document.createElement("a");
a.setAttribute("download", fileName);
a.setAttribute("href", link);
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
}
fetch('http://example.com/movies.json')
.then((response) =>
if(response){
const blob = new Blob([response], { type: "application/octetstream" });
downloadBlobFile(blob, "test.pdf")
}
)
.catch((error) => console.log(error));

How can I use multiple await in cypress?

I am trying to fetch multiple data from UI using cypress.
First of all, I thought my selector is incorrect, but I have tried it with the same selector as the below codebase, but it still not working
below is the function
async getData(model?: any) {
const listSelector='[ng-repeat="workflow in vm.workflows track by $index"]';
const dataFromUi = {};
const data = await cy.get(listSelector); // this gives data
const data1 = await cy.get(listSelector); // this doesn't
dataFromUi['Test1'] = data;
dataFromUi['Test2'] = data1;
debugger;
return dataFromUi;
}
I was calling this method from a spec file, below is the calling spec file
describe('app test', () => {
beforeEach(() => {
cy.login();
cy.navigateUsingMenu('dasboard', '');
});
it('',async ()=>{
const result = await getData();
result.Test1 // contains data
result.Test2 // contains undefined
})
})
In data I am getting contents, but data1 returns undefined.
I have found a solution and that is using different methods and different it blocks. The below codebase is working, but I want them in a single block.
The service methods
async getData1(model?: any) {
const listSelector='[ng-repeat="workflow in vm.workflows track by $index"]';
const data = await cy.get(ListSelector);
return data;
}
async getData2(model?: any) {
const listSelector='[ng-repeat="workflow in vm.workflows track by $index"]';
const data1 = await cy.get(ListSelector);
return data1;
}
The spec
describe('app test', () => {
beforeEach(() => {
cy.login();
cy.navigateUsingMenu('dashboard', '');
});
it('',async ()=>{
const result = await getData1();
})
it('',async ()=>{
const result = await getData2();
})
})

How to handle navigation of pages in Puppeteer UI Automation code

Here's the automation code for the web application for user name and password:
const puppeteer = require('puppeteer');
const expect = require('chai').expect;
describe("User Login",()=>{
let browser;
let page;
before(async function(){
browser = await puppeteer.launch({
headless:false,
slowMo:100
});
page = await browser.newPage();
await page.goto('https://www.test.com');
await page.waitForSelector('input[name=UserName]');
});
it("Successful login",async()=>{
await page.type('input[name=UserName]', 'test', {delay: 20});
await page.type('input[name=Password]', 'test', {delay: 20});
const button = await page.$('input[id=submitCredentials]');
await button.click();
//await page.waitForSelector('.item-group security-question');
});
after(async function(){
await browser.close();
})
});
Once the login is successful the application navigates to a different page, I cannot find a way to get the page object in puppeteer which I can use to validate if the login is successful or not. Any suggestions ?
I did find a solution to the problem at: Codota
Here's the modified code :
const puppeteer = require('puppeteer');
const expect = require('chai').expect;
describe("User Login",()=>{
let browser;
let page;
before(async function(){
browser = await puppeteer.launch({
headless:false,
slowMo:100
});
page = await browser.newPage();
await page.goto('https://www.test.com');
await page.waitForSelector('input[name=UserName]');
});
it("Successful login",async()=>{
await page.type('input[name=UserName]', 'test', {delay: 20});
await page.type('input[name=Password]', 'test', {delay: 20});
const button = await page.$('input[id=submitCredentials]');
const navigationPromise = page.waitForNavigation();
await button.click();
await navigationPromise;
await page.waitForSelector('div[class="item-group security-question"]');
const question = await page.$eval('input[id=QuestionId]', element => element.textContent);
expect(question).to.be.not.null;
});
after(async function(){
await browser.close();
})
});

Failed to launch chrome! spawn ...node_modules/puppeteer/.../chrome ENOENT TROUBLESHOOTING when using Puppeteer

I was trying to build a quick lambda that prints a pdf with a specific url, but I get this error: Failed to launch chrome! spawn ...node_modules/puppeteer/.../chrome ... TROUBLESHOOTING
Methods mentioned here : https://github.com/GoogleChrome/puppeteer/issues/807#issuecomment-366529860 did not help me.
The code I'm using:
const browser = await puppeteer.launch({
headless: true,
executablePath: '../../node_modules/puppeteer/.local-chromium/linux-624487/chrome-linux/chrome',
args: ['--no-sandbox', '--disable-setuid-sandbox'],
});
try {
const result = await exports.run(browser);
callback(null, result);
} catch (e) {
callback(e);
}
...
exports.run = async (browser) => {
// implement here
// this is sample
const page = await browser.newPage();
await page.goto('https://www.google.com', {
waitUntil: ['domcontentloaded', 'networkidle0']
});
console.log((await page.content()).slice(0, 500));
await page.type('#lst-ib', 'aaaaa');
// avoid to timeout waitForNavigation() after click()
await Promise.all([
// avoid to
// 'Cannot find context with specified id undefined' for localStorage
page.waitForNavigation(),
page.click('[name=btnK]'),
]);
// cookie and localStorage
await page.setCookie({
name: 'name',
value: 'cookieValue'
});
console.log(await page.cookies());
console.log(await page.evaluate(() => {
localStorage.setItem('name', 'localStorageValue');
return localStorage.getItem('name');
}));
const result = await page.pdf({
path: 'hn.pdf',
format: 'A4'
});
console.log(` typeof : ${typeof result}, pdf: ${result}`);
await page.close();
return 'done';
};
check this path =>
\node_modules\puppeteer.local-chromium\win32-818858\chrome-win
you will notice chrome.exe will not exist, now got back one step =>
*\node_modules\puppeteer.local-chromium*
you will find zip file "chrome-win" extract it and move it int to =>
\node_modules\puppeteer.local-chromium\win32-818858
Now you may check it will work.

puppeteer blank pdf generation

I'm using this simple code to generate a pdf document from http://example.com/
but I keep getting a blank pdf generated ...
Am I missing something ?
const puppeteer = require('puppeteer');
puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] }).then(function (browser) {
browser.newPage().then(function (page) {
page
.goto('http://example.com/', { waitUntil:['domcontentloaded', 'networkidle0','load'] })
.then(page.pdf({ path: 'result.pdf', format: 'letter' }))
.then(() => {
browser.close();
})
})
})
I used the no-sandbox option because of kernel issues.
I'm using CentOS 7
I had to wait for the promise in page.goto().then ...
const puppeteer = require('puppeteer');
puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] }).then(function (browser) {
browser.newPage().then(function (page) {
page
.goto('https://www.example.com', { waitUntil: ['domcontentloaded', 'networkidle0', 'load'] }).then(function (response) {
// page.emulateMedia('screen')
page.pdf({ path: 'result.pdf', format: 'letter' })
.then(function (res) {
browser.close();
}).catch(function (e) {
browser.close();
})
})
})
})

Resources