By playing with the new headless browser playwright from microsoft, I contsructed something that neither returns an error nore something else.
At this time, my ideas are over and I ask you for some hints to point me to my failure.
This piece of code should just start a multiple headless browser group asynchron. But the launch of the browser hangs and the application stays in an endless loop. I paste the code here, it is a simple nodejs script, to reproduce the behaviour.
Thanks for help & reading ;)
const playwright = require('playwright');
log('start playwright async');
let maxRunners = 1;
let running = 0;
let list = [1,2,3,4,5,6,7,8,9,0,11,12,13,14,15];
log('start job');
while (list.length > 0) {
if (running < maxRunners) {
log('runner started');
running++;
let entry = list[0];
list.shift();
log('start browser loop');
for (const browserType of ['chromium', 'firefox', 'webkit']) {
log('fire async');
(async () => {
log('loop next');
log('launch: ', browserType);
const browser = await playwright[browserType].launch({
headless: false
});
log(browserType, ' launched');
const context = await browser.newContext();
log('open new page');
const page = await context.newPage('http://whatsmyuseragent.org/');
log('page opened');
log('make screenshot');
await page.screenshot({path: `example-${browserType}.png`});
log('screenshot made');
log('close browser');
await browser.close();
log('browser closed');
log('loop succeed');
running--;
})();
log('end async');
}
log('end loop');
if (running === 0 && list.length === 0) {
log('job finished');
}
}
}
log('end playwright script');
function log(...msgs) {
let date = new Date();
let timeString = date.toISOString().substr(11, 8);
let msg = '';
for (let i in msgs) {
msg += msgs[i];
}
console.log(timeString, ':', msg);
}
The output:
20:53:29 : start playwright async
20:53:29 : start job
20:53:29 : runner started
20:53:29 : start browser loop
20:53:29 : fire async
20:53:29 : loop next
20:53:29 : launch: chromium
20:53:29 : end async
20:53:29 : fire async
20:53:29 : loop next
20:53:29 : launch: firefox
20:53:29 : end async
20:53:29 : fire async
20:53:29 : loop next
20:53:29 : launch: webkit
20:53:29 : end async
20:53:29 : end loop
There are a few things you can improve in your code:
(async()=>{
log('start playwright async');
let maxRunners = 1;
let running = 0;
let list = [1,2,3,4,5,6,7,8,9,0,11,12,13,14,15];
log('start job');
const promises = [];
while (list.length > 0) {
if (running < maxRunners) {
log('runner started');
running++;
let entry = list[0];
list.shift();
log('start browser loop');
for (const browserType of ['chromium', 'firefox', 'webkit']) {
log('fire async');
promises.push((async () => {
log('loop next');
log('launch: ', browserType);
const browser = await playwright[browserType].launch({
headless: false
});
log(browserType, ' launched');
const context = await browser.newContext();
log('open new page');
const page = await context.newPage('http://whatsmyuseragent.org/');
log('page opened');
log('make screenshot');
await page.screenshot({path: `example-${browserType}.png`});
log('screenshot made');
log('close browser');
await browser.close();
log('browser closed');
log('loop succeed');
running--;
})());
log('end async');
}
log('end loop');
} else {
await Promise.all(promises);
}
}
await Promise.all(promises);
log('job finished');
log('end playwright script');
function log(...msgs) {
let date = new Date();
let timeString = date.toISOString().substr(11, 8);
//date.setSeconds(45); // specify value for SECONDS here
//var timeString = date.toISOString().substr(11, 8);
let msg = '';
for (let i in msgs) {
msg += msgs[i];
}
console.log(timeString, ':', msg);
}
})()
Let's wrap everything in an async function
(async()=>{
)();
Then, let's keep track of those tasks/promises:
const promises = [];
...
log('fire async');
promises.push((async () => {
})());
If you get out of workers you need to wait for them:
if (running < maxRunners) {
...
} else {
await Promise.all(promises);
}
You should get running with this.
Thank you for your usefull hints. Better to wait for promise than execute conditon all time. Now I also clear the promise array after all completed.