Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1.11] Add support for the new Chrome headless mode #504

Open
wants to merge 3 commits into
base: 1.11
Choose a base branch
from

Conversation

sanderdlm
Copy link
Contributor

@sanderdlm sanderdlm commented Mar 31, 2023

Fixes #498

Reference: https://developer.chrome.com/articles/new-headless/

Imlemented just like Puppeteer:

To opt in to the new Headless mode in Puppeteer:

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({
  headless: 'new',
  // `headless: true` (default) enables old Headless;
  // `headless: 'new'` enables new Headless;
  // `headless: false` enables “headful” mode.
});

const page = await browser.newPage();
await page.goto('https://developer.chrome.com/');

// …

await browser.close();

Passing true or not setting the flag at all still enables the old mode. False still disables the headless mode. Passing "new" enables the new headless mode.

From the blog post:

Currently, passing the --headless command-line flag without an explicit value still activates the old Headless mode — but we plan to change this default to new Headless over time.

This code will work during the transition period and allow users to test their applications against the new set-up

We plan to completely remove the old Headless from the Chrome binary and stop supporting this mode in Puppeteer later this year. As part of this removal, we’ll make the old Headless available as a separate standalone binary for those users who can’t upgrade yet.

When the old headless mode is removed, the default in this library might have to be switched to "new" (or Chrome will simply map --headless to --headless=new internally, we don't know yet)

@GrahamCampbell GrahamCampbell changed the title Add support for the new Chrome headless mode without breaking BC [1.9] Add support for the new Chrome headless mode Apr 22, 2023
@GrahamCampbell GrahamCampbell changed the base branch from 1.8 to 1.9 April 22, 2023 12:42
@GrahamCampbell
Copy link
Member

Thanks for looking into this. This looks like a great solution. Are you able to add test coverage and update the documentation too, please?

@sanderdlm
Copy link
Contributor Author

Sure. Having a hard time coming up with a test though. From what I can tell Chrome has no way of differentiating between the old and new headless mode. Do you know about some flag I could check? Or is there a way I could read the parsed options from a BrowserProcess and check the mode there?

@GrahamCampbell
Copy link
Member

Fair enough. I'd merge with just the updated docs, then. ;)

@buismaarten
Copy link
Contributor

I just tested the new headless mode using the following code in a Docker container:

$browser = $browserFactory->createBrowser([
    'noSandbox' => true,
    'headless' => false,
    'customFlags' => [
        '--headless=new',
    ],
]);

I received the following error using Google Chrome 112.0.5615.165:

Fatal error: Uncaught RuntimeException: Chrome process stopped before startup completed. Additional info: mkdir: cannot create directory '/var/www/.local': Permission denied touch: cannot touch '/var/www/.local/share/applications/mimeapps.list': No such file or directory chrome_crashpad_handler: --database is required Try 'chrome_crashpad_handler --help' for more information. [109:109:0427/084518.084594:ERROR:socket.cc(120)] recvmsg: Connection reset by peer (104) in /var/www/html/vendor/chrome-php/chrome/src/Browser/BrowserProcess.php:418 Stack trace:
#0 /var/www/html/vendor/chrome-php/chrome/src/Utils.php(60): HeadlessChromium\Browser\BrowserProcess->HeadlessChromium\Browser\{closure}(Object(Symfony\Component\Process\Process))
#1 /var/www/html/vendor/chrome-php/chrome/src/Browser/BrowserProcess.php(458): HeadlessChromium\Utils::tryWithTimeout(30000000, Object(Generator))
#2 /var/www/html/vendor/chrome-php/chrome/src/Browser/BrowserProcess.php(139): HeadlessChromium\Browser\BrowserProcess->waitForStartup(Object(Symfony\Component\Process\Process), 30000000)
#3 /var/www/html/vendor/chrome-php/chrome/src/BrowserFactory.php(82): HeadlessChromium\Browser\BrowserProcess->start('google-chrome', Array)
#4 /var/www/html/public/html.php(10): HeadlessChromium\BrowserFactory->createBrowser(Array)
#5 {main} thrown in /var/www/html/vendor/chrome-php/chrome/src/Browser/BrowserProcess.php on line 418

Using the normal headless mode works fine without any issues.

@enricodias
Copy link
Member

I just tested the new headless mode using the following code in a Docker container:

$browser = $browserFactory->createBrowser([
    'noSandbox' => true,
    'headless' => false,
    'customFlags' => [
        '--headless=new',
    ],
]);

I received the following error using Google Chrome 112.0.5615.165:

Fatal error: Uncaught RuntimeException: Chrome process stopped before startup completed. Additional info: mkdir: cannot create directory '/var/www/.local': Permission denied touch: cannot touch '/var/www/.local/share/applications/mimeapps.list': No such file or directory chrome_crashpad_handler: --database is required Try 'chrome_crashpad_handler --help' for more information. [109:109:0427/084518.084594:ERROR:socket.cc(120)] recvmsg: Connection reset by peer (104) in /var/www/html/vendor/chrome-php/chrome/src/Browser/BrowserProcess.php:418 Stack trace:
#0 /var/www/html/vendor/chrome-php/chrome/src/Utils.php(60): HeadlessChromium\Browser\BrowserProcess->HeadlessChromium\Browser\{closure}(Object(Symfony\Component\Process\Process))
#1 /var/www/html/vendor/chrome-php/chrome/src/Browser/BrowserProcess.php(458): HeadlessChromium\Utils::tryWithTimeout(30000000, Object(Generator))
#2 /var/www/html/vendor/chrome-php/chrome/src/Browser/BrowserProcess.php(139): HeadlessChromium\Browser\BrowserProcess->waitForStartup(Object(Symfony\Component\Process\Process), 30000000)
#3 /var/www/html/vendor/chrome-php/chrome/src/BrowserFactory.php(82): HeadlessChromium\Browser\BrowserProcess->start('google-chrome', Array)
#4 /var/www/html/public/html.php(10): HeadlessChromium\BrowserFactory->createBrowser(Array)
#5 {main} thrown in /var/www/html/vendor/chrome-php/chrome/src/Browser/BrowserProcess.php on line 418

Using the normal headless mode works fine without any issues.

That's similar to #401. If you create that file manually, does the error change?

@buismaarten
Copy link
Contributor

When I manually create /var/www/.local/share/applications/mimeapps.list, it gives the following error:

Fatal error: Uncaught RuntimeException: Chrome process stopped before startup completed. Additional info: chrome_crashpad_handler: --database is required Try 'chrome_crashpad_handler --help' for more information. [227:227:0427/145755.211751:ERROR:socket.cc(120)] recvmsg: Connection reset by peer (104) in /var/www/html/vendor/chrome-php/chrome/src/Browser/BrowserProcess.php:418 Stack trace:
#0 /var/www/html/vendor/chrome-php/chrome/src/Utils.php(60): HeadlessChromium\Browser\BrowserProcess->HeadlessChromium\Browser\{closure}(Object(Symfony\Component\Process\Process))
#1 /var/www/html/vendor/chrome-php/chrome/src/Browser/BrowserProcess.php(458): HeadlessChromium\Utils::tryWithTimeout(30000000, Object(Generator))
#2 /var/www/html/vendor/chrome-php/chrome/src/Browser/BrowserProcess.php(139): HeadlessChromium\Browser\BrowserProcess->waitForStartup(Object(Symfony\Component\Process\Process), 30000000)
#3 /var/www/html/vendor/chrome-php/chrome/src/BrowserFactory.php(82): HeadlessChromium\Browser\BrowserProcess->start('google-chrome', Array)
#4 /var/www/html/public/html.php(10): HeadlessChromium\BrowserFactory->createBrowser(Array)
#5 {main} thrown in /var/www/html/vendor/chrome-php/chrome/src/Browser/BrowserProcess.php on line 418

@buismaarten
Copy link
Contributor

Chrome is switching by default to the new headless version later this year, this is not working in Docker (yet).

We could allow the following configuration values:

  1. new: enables new Headless;
  2. old: enables the old Headless for backwards compatibility;
  3. true: (default) enables old Headless;
  4. false: enables “headful” mode.

Reference: https://developer.chrome.com/articles/new-headless/

@GrahamCampbell GrahamCampbell changed the base branch from 1.9 to 1.10 April 30, 2023 19:46
@GrahamCampbell GrahamCampbell changed the title [1.9] Add support for the new Chrome headless mode [1.10] Add support for the new Chrome headless mode Apr 30, 2023
@buismaarten
Copy link
Contributor

FYI, the new Headless mode seems to work in version 113 and 114 using Docker.

@sanderdlm
Copy link
Contributor Author

I don't really see the need for the "old" option. Setting the flag to true already enables the old headless mode, and by the time the default switches to the new one, they'll likely remove the old mode altogether. Keeping true/false backwards compatible and adding the "new" option is the way to go IMOm (just like Puppeteer has it)

@stale
Copy link

stale bot commented Oct 15, 2023

This issue has been automatically marked as stale because there has been no recent activity. It will be closed after 30 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Oct 15, 2023
@GrahamCampbell GrahamCampbell changed the title [1.10] Add support for the new Chrome headless mode [1.11] Add support for the new Chrome headless mode Dec 10, 2023
@GrahamCampbell GrahamCampbell changed the base branch from 1.10 to 1.11 December 10, 2023 02:28
@stale stale bot removed the stale label Dec 10, 2023
Copy link

stale bot commented Apr 22, 2024

This issue has been automatically marked as stale because there has been no recent activity. It will be closed after 30 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Apr 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

Add support to 'new headless' mode
4 participants