UI seems different on puppeteer - puppeteer

Even though most of the process of my end-to-end test with puppeteer works fine ( which is a rather simply a series of page.select/type/waitfor/etc) the UI seems skewed.
When the process is over, at the very end of it the UI readjusts to what it should look like but only after everything has concluded. I tried firing up a plain Chromium instance and it looks as it should be as well.
test code looks like so
beforeAll(async () => {
browser = await puppeteer.launch(
{
headless: false,
slowMo: 250,
}
)
page = await browser.newPage()
await page.goto('http://localhost:3000/');
})
describe('on page load', () => {
test('MessageLists loads', async () => {
await page.waitForSelector('.MessageList', { timeout: 3000 })
await page.waitForSelector('.messageOuterContainer', { timeout: 10000 })
},
16000
);
test('Post Question', async () => {
await page.waitForSelector('.messageOuterContainer', { timeout: 10000 })
await page.focus('.input');
await page.keyboard.type('test');
await page.$('.AnswerList');
await page.screenshot({ path: 'screenshot1.png' });
}, 20000)
})
afterAll(() => {
// browser.close()
})
Im on MacOS Mojave 10.14 though i imagine this isnt the culprit here.

Even if you launch puppeteer in headless: false mode, the page will be run with a given viewport. By default that viewport size is 800x600. If you resize the window to something bigger it might indeed look like the page is run inside an iframe. You cannot resize the viewport by resizing the browser window. You have to rely on functions for that.
Code sample
To change the default viewport, you can add an argument when calling puppeteer.launch:
const browser = await puppeteer.launch({
defaultViewport: { // example: 1600x800
width: 1600,
height: 800
},
headless: false,
slowMo: 250,
})
You can also change it by calling the function page.setViewport.

Related

What exactly is "Viewport"?

I have troubles understanding what exactly "Viewport" is. The docs say it defines the "width" and the "height" in a "page". And what exactly was "page", again? I used to think of it as a browser tab, but this is also wrong, see below...
My tests fail because I seem to misunderstand "Viewport":
page.setViewport({ width: 640, height: 480 })
expect(window.innerWidth).toBe(640) // FAIL, it's 1366, Puppeteers default
From googling around, I know that there are options to launch Puppeteer in another window size. But this is not what I'm looking for, out of two reasons:
it still doesn't explain what "Viewport" is
I can't "restart" Puppeteer in every single test (I'm testing responsive behavior)
https://puppeteer.github.io/puppeteer/docs/puppeteer.page.viewport
You should expect the page.evaluate result of window.innerWidth.
Remember that the execution context inside of the page itself is different with puppeteer context.
import puppeteer, { Browser, BrowserContext, Page } from 'puppeteer'
const start = async () => {
const browser: Browser = await puppeteer.launch({ headless: false })
const page: Page = await browser.newPage()
page.setViewport({ width: 640, height: 480 })
await page.goto('http://www.samisite.com/test-csb2nf/id43.htm', { waitUntil: 'networkidle0' })
expect(await page.evaluate(() => window.innerWidth)).toBe(640)
console.log(await page.evaluate(() => window.innerWidth))
await page.close()
await browser.close()
}
;(async () => await start())()

how to wait for puppeteer to complete a print to printer function?

I am running puppeteer in kiosk-printing mode to automate the printing of PDF to the printer. But I have to use waitForTimeout to give the printer sufficient time to, I guess, receive the print instructions. Otherwise, browser.close( ) shuts puppeteer down too quickly, and nothing prints.
How to wait for the print function to complete? I am not sure what the arbitrary waitForTimeout value should be.
const puppeteer = require('puppeteer');
(async () =>
{
const browser = await puppeteer.launch(
{
headless: false,
"args": [ "--kiosk-printing" ]
});
const page = await browser.newPage();
await page.goto(`file:///C:/Users/srich/Downloads/packing-list.pdf`);
await page.evaluate(() => { window.print(); });
await page.waitForTimeout(2000) ;
await browser.close( ) ;
})();
I tried to goto a web page after running window.print. Then wait for that navigation to complete. But the shutdown of puppeteer still came too quickly and the PDF did not print.
await page.evaluate(() => { window.print(); });
await page.goto(`https://google.com`);
await page.waitForSelector('input');
await browser.close( ) ;

puppeteer: Different response from the puppeteer browser and the user browser

I use my own browser to get the result page I want. Everything is correct. Page link is below.
https://parcelsapp.com/en/tracking/016-35294405
img for working
I want to use puppeteer to help me to load the result page. The page shows differently.
I use options headless=false to debug. I found the browser pop up from puppeteer can not load the url correctly. I guess it is because the different environments. How can I solve the problem? Thank you.
img for not working
My code is below:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: false,
slowMo: 250, // slow down by 250ms
executablePath: '/usr/bin/google-chrome-stable',
});
const page = await browser.newPage();
await page.on("request", (request) => {
request.abort();
});
await page.goto('https://parcelsapp.com/en/tracking/016-35294405');
await page.waitForNavigation()
await page.screenshot({ path: 'result.png' });
await browser.close();
})();

issue with puppeteer console.log

i just want to use XPath to get innerText using Puppeteer. This is code
import * as puppeteer from 'puppeteer-core';
(async () => {
// Make the browser visible by default, extend the timeout, and set a default viewport size
const browser = await puppeteer.launch({
executablePath: 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
userDataDir: 'C:\\ctvbanhang\\browserData',
defaultViewport: { width: 1920, height: 1080 },
headless: false, // true = hide screen, false = show screen
timeout: 60000, // 60 seconds
});
// The browser automatically opens a page, so use that
const page = (await browser.pages())[0];
await page.goto('https://example.com/');
var XPath = "//h1/text()";// //'div.product-briefing > div > div > div > span';
// //await page.waitForSelector(selector);
await page.waitForXPath(XPath);
let result = await page.evaluate(element => {
console.log(element); //log in browser
console.log(typeof element); //log in browser
console.log(JSON.stringify(element)); //log in browser
return element;
}, (await page.$x(XPath))[0]);
console.log(result); //log in terminal
await page.waitFor(100000);
await browser.close();
})()
.then(() => {
console.log('Browser scans complete!');
})
Why the result is not the same?
this is result log in browser
and in terminal
According to the docs, various eval functions can transfer only serializable data (roughly, the data JSON can handle, with some additions). Your code returns a DOM element (Text node), which is not serializable (it has methods and circular references). Try to retrieve the data in the browser context and returns only serializable data. For example:
return element.wholeText;

Puppeteer-extra allow flash support

I need puppeteer (not in headless mode) to open a page and have flash enabled from the get go.
Meaning no manual downloading or clicking to run flash.
So far i've added puppeteer-extra and its flash plugin as was used in a prior question:
Allowing to run Flash on all sites in Puppeteer
My chrome version is 75.0.3770.142 and my puppeteer dependencies are:
* "puppeteer": "^1.19.0",
* "puppeteer-core": "^1.19.0",
* "puppeteer-extra": "^2.1.3",
* "puppeteer-extra-plugin-flash": "^2.1.3",
* "puppeteer-extra-plugin-user-data-dir": "^2.1.2",
* "puppeteer-extra-plugin-user-preferences": "^2.1.2",
import puppeteer from 'puppeteer';
import PuppeteerCore from 'puppeteer-core';
import PuppeteerExtra from 'puppeteer-extra';
import PuppeteerFlash from 'puppeteer-extra-plugin-flash';
PuppeteerExtra.use(PuppeteerFlash());
(async () => {
const browser = await PuppeteerExtra.launch({
headless: false,
executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google\ Chrome',
args: [
'--window-size=800,600',
'--enable-webgl',
'--enable-accelerated-2d-canvas',
],
});
const page = await browser.newPage();
await page.setViewport({ width: 800, height: 600 });
await page.goto('http://ultrasounds.com', { waitUntil: 'networkidle2' });
})();
I expected the above code to open the page, download the necessary flash and run the flash content when done.
As it is though, it does the download but still requires a user to click enable flash to make the content run.
I'm wondering if anyone could please let me know if I'm doing anything wrong in the above code, if I've misunderstood something or otherwise?
if you use the localPath chrome app, you needn't the puppeteer-extra-plugin-flash.
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
ignoreHTTPSErrors: true,
headless: false,
});
const page = await browser.newPage();
await page.goto('https://v.qq.com/iframe/preview.html?width=500&height=375&auto=0&vid=a30198lw6j2');
const dimensions = await page.evaluate(() => {
return {
src: document.getElementById('tenvideo_video_player_0').getAttribute('src'),
};
});
console.log('Dimensions:', dimensions);
await browser.close();
})();