Puppeteer: Puppeteer not working when is not focused

Created on 3 Oct 2018  Â·  58Comments  Â·  Source: puppeteer/puppeteer

Environment:

  • Puppeteer version: 1.8.0
  • Platform / OS version: Win 10 64b and Ubuntu 18.04.1 LTS
  • URLs (if applicable): No
  • Node.js version: v10.6.0

I am using puppeteer for testing my pages. When I run the app and hide it into background then puppeteer is paused (or freeze). When I move puppeteer into foreground is running normally.

I think that its problem "when window is not focused, its not working".

This behavior is on windows and linux too.

Set up code:

            const args = []
            args.push('--start-maximized')
            args.push('--disable-gpu')
            args.push('--disable-setuid-sandbox')
            args.push('--force-device-scale-factor')
            args.push('--ignore-certificate-errors')
            args.push('--no-sandbox')

            this.driver = await puppeteer.launch({
                headless: false,
                args,
                userDataDir: `puppeteer_profile`,
            })


i happen only "sometimes" I don't know when.

chromium

Most helpful comment

Nope you are not only one, I have same problem above.

All 58 comments

@JaLe29 what do you mean by "not running"? Does the page's javascript stop running?

Yes, page`s javascript are paused. While window is not focused.

I think, this behaviour is related something settings in my operating system.

But as I am writing in first post, i tested on two OS - linux and windows.

@JaLe29 This is probably related to https://github.com/WICG/web-lifecycle/

The easy workaround would be:

const session = await page.target().createCDPSession();
await session.send('Page.enable');
await session.send('Page.setWebLifecycleState', {state: 'active'});

This should unfreeze javascript execution in the background page.

@aslushnikov when we have multiple pages, will adding this snippet make all of them focused? Also it's page.target() as documented.
I tried with the snippet,

const puppeteer = require("puppeteer");

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  const page = await browser.newPage();

  const session = await page.target().createCDPSession();
  await session.send("Page.enable");
  await session.send("Page.setWebLifecycleState", { state: "active" });

  await page.goto("http://127.0.0.1:8080/");
  await page.screenshot({ path: "example.png", fullPage: true});

  await browser.close();
})();

and the html code,

<script type="text/javascript">
  window.onload = function () {
    function check() {
      if (document.hasFocus() == lastFocusStatus) return;
      lastFocusStatus = !lastFocusStatus;
      statusEl.innerText = lastFocusStatus ? 'with' : 'without';
    }
    window.statusEl = document.getElementById('status');
    window.lastFocusStatus = document.hasFocus();
    check();
    setInterval(check, 200);
  }
</script>

Currently <b id="status">without</b> focus...

The result,
image

It didn't focus back. Should it focus back?

@aslushnikov I tested your solution

const session = await page.target().createCDPSession();
await session.send('Page.enable');
await session.send('Page.setWebLifecycleState', {state: 'active'});

But it not working too. Still same behaviour. :-(

I'm the only one who has this problem?

With this error it's useless.

Nope you are not only one, I have same problem above.

My friend has same problem. I don't have any idea how to fix it. Sometimes is working, sometimes not.

I must focus manually the window and then it's working.

I have a similar issue, In VM i have scheduled to execute the puppeteer stuffs using node-corn in my nodejs app. I disconnected the VM and connected after some hrs of the actual scheduled time i can see the log as the scheduler has started at the correct time, i havnt seen any log entry in the puppeteers code, then i enter in the cmd window, then the puppeteer stuffs run, u can see the time after the job started log entry.

image

`

import puppeteer = require('puppeteer');
import reader = require('./webPageReader');
import config = require('./config');

import { configure, getLogger } from 'log4js';
configure(config.project.LOG_CONFIG);
const logger = getLogger('bdayWisherLog');


import cron = require('node-cron');

let start = async () => {
    logger.debug("Job Fired...");
    const browser:puppeteer.Browser = await puppeteer.launch({headless: true});
    reader.runThroughPage(browser);
};

let startSchedule = () => {
    logger.debug('Schedule started... Job will fire by '+config.schedule.HR+':'+ config.schedule.MIN);

    process.on("unhandledRejection", (reason, p) => {
        logger.debug("Unhandled Rejection at: Promise", p, "reason:", reason);
    });

    cron.schedule(config.schedule.MIN+' '+ config.schedule.HR +' * * *', ()=>{
        start();
    }, {
        scheduled: true,
        timezone: "Asia/Kolkata"
    });
}

startSchedule();

`

@jonesprabu Totally the same problem. I am using a scheduling system too. But I am using setTimeoutfor start new task.

@aslushnikov any updates about this? I am so sad that I can't use this amazing lib :(

@JaLe29 can you please try running the following script and confirm that "heartbits" stop from both pages once you minimize browser window?

const puppeteer = require('.');

(async() => {
  const browser = await puppeteer.launch({
    headless: false,
  });
  const [page] = await browser.pages();
  await setupPageHeartbit('ONE', page);
  await setupPageHeartbit('TWO', await browser.newPage());
})();

async function setupPageHeartbit(pageId, page) {
  page.on('console', msg => console.log(`[${pageId}]: ${msg.text()}`));
  await page.evaluate(() => {
    let i = 0;
    setInterval(() => {
      console.log((++i) + ' heartbit');
    }, 1000);
  });
}

Same issue here, I have 2 tabs and the tab that is not focused pauses. And the session tricks does not work for me

I also faced the same problem. I tried the snippet given by @aslushnikov , but it didn't work. I read in a report where they advised running on multiple instances of browser instead of trying to manage different tabs and it worked for me. It does not pause in separate browser instances.
So, if you are stuck and your requirement allows you to use/test multiple browser instances, I think you should go for it.

If you can't use multiple browser instances, you can stick to some previous version of puppeteer

image

I randomly tested 1.3.0 version and there is no tab discarding exist in chromium

I'm having somewhat a similar problem. I'm launching 5 Chrome 73.0.3683.103 instances (not chromium) on Centos 7. I launch them as child processes so they all run concurrently no problem.

If I don't minimize them, they run fine even if they are not focused. If I run a script to miminize the windows, they freeze execution until I unminimize. I'm not sure if this is website specific or a problem with chrome/puppeteer. I don't have time to test more extensively, just wanted to share my experience.

I have the same issue.

Hey @aslushnikov I have tested the script you provided above and heartbits do not stop. They do keep happening.

But when I try running normal script, it goes into the paused state and nothing happens on that website page. Things also don't get timed out from puppeteer's side. It's as if the whole puppeteer script and browser just went into a paused state.

I read the WICG/page-lifecycle which goes into more details about the frozen state. But then how come this only happens when I am trying to execute something via puppeteer but not in normal chrome. Or is the argument that it happens in normal execution as well but we don't see it because we are not actively trying to do anything in that browser.

Shouldn't this be treated as bug for chromium though. If script is trying to do something in the current page, then that page should never get into the frozen state. If this is already an open bug, could someone link it please. Thanks!

Also, this didn't help: https://github.com/GoogleChrome/puppeteer/issues/3339#issuecomment-426907894

This is also a problem for me, is there any news or information on how to fix this? If i run Puppeteer in "headless:true" mode it seems to work just fine. So it only happens to me when the GUI is used (minimize browser pauses script, switching tabs pauses script

Also having this problem i.e. with multiple tabs open only the tab that has focus continues to work properly. Pages without focus "stop running" and '.waitForSelector' calls time out. Very keen for a fix.

I have same problem

This is happening to me as well. Specifically, page.type() will pause until the non-headless Chrome window regains focus. I have a cron which runs every 10 minutes, and if I minimize or switch windows, the typed text will not complete until I restore the window.

[Solution]:

Add the following values to the array you assign to the args property in the options object. Now, you should be able to run Puppeteer while your window is in the foreground, background, or minimized.

Update:
I'm running parallel instances of Puppeteer using the same script in multiple windows with one tab per window. Each window completed successfully whether it was in the foreground, background, or minimized. And, it worked in both headless and headful mode.

const chromeArgs = [
  '--disable-background-timer-throttling',
  '--disable-backgrounding-occluded-windows',
  '--disable-renderer-backgrounding'
];

Solution and explanation available in an article written by Rohit Kumar, @rkr090 at Big Binary:

Debugging failing tests in puppeteer because of background tab

Hey @captaindavepdx The issue is still there as mentioned here: https://github.com/GoogleChrome/chrome-launcher/issues/169

Hi @VikramTiwari ! Have you tried using multiple windows instead of multiple tabs?

I haven't. Multiple windows only work if the complete script execution is limited to a single page. As soon as execution is multiple page, we will face the issue again.

Could you please help me understand why multiple windows would only work for single page execution?

I think for me the UX is very icky if done with utilizing multiple windows rather than tabs.

An example would be:

  • Open Page A
  • Click on a link to open Page B in a new tab/window
  • Click on a button on Page B
  • Some content on Page A changes
  • Copy the content from Page A

Do this 50 times and we end up with 100 chrome windows taking over desktop. But if done with tabs, you have everything as tabs. Much cleaner UX.

Also, a solution would let script execute when tab or window is not focused. This strategy is a patch workaround to achieve a solution with windows. Nothing against the patch, it just isn't the solution.

Thanks for that clarification. I can see how it could be considered a patch or workaround for your situation. But, since the OP didn't mention multiple pages, maybe it could still serve as as a solution for others.

Also, the patch or workaround does allow the script to execute while the window is not focused.

I have to run 100+ puppeteer windows (not tabs) in parallel with puppeteer.launch(). If I have to use this workaround on all 100 windows, it will be a disaster for me. :(

I am having the same issue. I am using puppeteer-core and connect instead of launch.

Same issue here...
Sometimes when I run a scrape script, puppeteer opens the browser and puts focus on it. If I click on another window the script pauses. When I click back to the browser window of puppeteer the script continues execution.

OS: Arch Linux

i have the same problem。 set handless = false fix problem。

but handless = false debug is not friendly

@ganyanchuan1989 I am using puppeteer.connect with headless: false. Its still not working for me.

Same issue, so this problem lasts for more than a year??

I am suffering the same issue. Any fix or workaround?

it works on headless : false mode, but if i use headless: true, this problem would happen

Yes. I need headless: false

same here.

I also faced the same problem. I tried the snippet given by @aslushnikov , but it didn't work. I read in a report where they advised running on multiple instances of browser instead of trying to manage different tabs and it worked for me. It does not pause in separate browser instances.
So, if you are stuck and your requirement allows you to use/test multiple browser instances, I think you should go for it.

@abhi4singhal Yes, running multiple browsers (other than pages) really worked.
But this also brings a new problem, that is, the urls I need to scrape requires some init work.
For example if the browser launched open a url for the first time, the website shows some welcome messages that I need to manually interact with (such as accept cookie, choose location blabla).

With 1 browser + multiple pages, I could manually do this init work for once (to create user_data for those websites), later I won't have the init work for this particular browser (as long as I don't clean the user_data).

But with multiple browsers, this init work cannot be done manually, any advice?

Same here.
@aslushnikov do you guys have any update on this or this not something you expect to work? Hope it will be resolved once you have a chance. Cheers :)

same issue... i really need a solution

[Solution]:

Add the following values to the array you assign to the args property in the options object. Now, you should be able to run Puppeteer while your window is in the foreground, background, or minimized.

Update:
I'm running parallel instances of Puppeteer using the same script in multiple windows with one tab per window. Each window completed successfully whether it was in the foreground, background, or minimized. And, it worked in both headless and headful mode.

const chromeArgs = [
  '--disable-background-timer-throttling',
  '--disable-backgrounding-occluded-windows',
  '--disable-renderer-backgrounding'
];

Solution and explanation available in an article written by Rohit Kumar, @rkr090 at Big Binary:

Debugging failing tests in puppeteer because of background tab

FWIW, this solution worked for me today. I am scraping via an existing chrome session and connecting using Puppeteer.connect. I was having the same issue where the out-of-focus Chrome window would not execute Javascript in the background.

This is the command I used to start the chrome instance:

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222 --no-first-run --no-default-browser-check --disable-backgrounding-occluded-windows --disable-renderer-backgrounding --disable-background-timer-throttling --user-data-dir=$(mktemp -d -t 'chrome-remote_data_dir')

Note the use of the flags: --disable-backgrounding-occluded-windows --disable-renderer-backgrounding --disable-background-timer-throttling

For those having issues, this seems to be a feature of Chrome/Chromium/browsers in general that is designed to protect the user from websites snooping on them while they're not actively using the website. This feature can and should be turned off in the context of a web scraper running via a scheduler, headless or otherwise.

same issue... puppeteer script paused when switch to another tab, i need multi tabs to work simultaneously. but i have yet to find good solution now. help!!!!

Same issue with around 45 browser instances parallel open. The three Chrome command line arguments are not solving the issue.

any news ?

any news ?

I get this problem when i try to perform some click in the page. I solved this using a diferent way
to perform clicks. Check out:

Before:

let login_button = await page.$x('//a[contains(text(), "Login")]')  
 await login_button[0].click()

After:

await page.evaluate(() => {
        let but = document.querySelector("span[class='pr-2 pr-sm-2 pr-lg-4 pl-sm-2 pl-md-2 pt-1 pb-1 nao_logado active'] > a")
        if (but) {
            return Promise.resolve(but.click())
        }
    })

I don't know why, but using "evaluate()" i can click on page buttons and links with background, minimized mode

+1

Also still experiencing this issue. Any amount of flags passed to chrome have absolutely no effect (on Microsoft Windows). Will try to reproduce a minimal working example. We have 8 windows with 1-10 tabs each open at all times. Sometimes tabs load indefinitely, sometimes the entire page freezes, as well as puppeteer script execution. Quite often the program will appear to be idle and then open tens of tabs that have apparently been waiting for the newpage command to resolve open at once (usually after clicking into the window, but clicking on the commandline window seems to trigger this as well sometimes). This is incredibly hard to debug, as there seems to be no clear regularity to the issue.

for everyone who didn't figure it out yet.

Just try to implement these arguments.... and trust me . It works!

var ops = {args:[
        '--kiosks',
        '--disable-background-timer-throttling',
        '--disable-backgrounding-occluded-windows',
        '--disable-renderer-backgrounding',
        '--disable-canvas-aa',
        '--disable-2d-canvas-clip-aa',
        '--disable-gl-drawing-for-tests',
        '--disable-dev-shm-usage', 
        '--no-zygote', 
        '--use-gl=desktop', 
        '--enable-webgl',
        '--hide-scrollbars',
        '--mute-audio',
        '--start-maximized',
        '--no-first-run',
        '--disable-infobars',
        '--disable-breakpad', 
        '--user-data-dir='+tempFolder, 
        '--no-sandbox',
        '--disable-setuid-sandbox'
    ], headless: false, timeout:0   };
puppeteer = require('puppeteer');
    browser = await puppeteer.launch(ops);
    page = await browser.newPage();

Lets find out exactly which flag made it work, since there are lots of flags that will conflict with many different environment and testing solution.

for everyone who didn't figure it out yet.

Just try to implement these arguments.... and trust me . It works!

var ops = {args:[
      '--kiosks',
      '--disable-background-timer-throttling',
      '--disable-backgrounding-occluded-windows',
      '--disable-renderer-backgrounding',
      '--disable-canvas-aa',
        '--disable-2d-canvas-clip-aa',
        '--disable-gl-drawing-for-tests',
        '--disable-dev-shm-usage', 
        '--no-zygote', 
        '--use-gl=desktop', 
        '--enable-webgl',
        '--hide-scrollbars',
        '--mute-audio',
      '--start-maximized',
        '--no-first-run',
        '--disable-infobars',
        '--disable-breakpad', 
        '--user-data-dir='+tempFolder, 
        '--no-sandbox',
        '--disable-setuid-sandbox'
  ], headless: false, timeout:0   };
puppeteer = require('puppeteer');
  browser = await puppeteer.launch(ops);
    page = await browser.newPage();

Sorry to say @fgroupindonesia but still no luck with all of these flags...

If possible please use Headless=true, this would launch the browser without UI and tabs losing focus won't be a problem anymore.
^ @azazrehman

mayeb it's a header issue i fixed this with this code from an article in medium

const browser = await puppeteer.launch();
const page = await browser.newPage();

const headlessUserAgent = await page.evaluate(() => navigator.userAgent);
const chromeUserAgent = headlessUserAgent.replace('HeadlessChrome', 'Chrome');
await page.setUserAgent(chromeUserAgent);
await page.setExtraHTTPHeaders({
  'accept-language': 'en-US,en;q=0.8'
});

@sihamza is that not the opposite problem though? This is is not headless, where the there is no window.

+1

+1 with the same problem

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sean-hill picture sean-hill  Â·  49Comments

ghost picture ghost  Â·  84Comments

optikalefx picture optikalefx  Â·  49Comments

Nagisan picture Nagisan  Â·  52Comments

fortes picture fortes  Â·  191Comments