What does the argument --virtual-time-budget of Chrome CLI really mean? - google-chrome

I'm aware of the documentation of the argument --virtual-time-budget in the source of Chromium, but I don't feel I understand it:
// If set the system waits the specified number of virtual milliseconds before
// deeming the page to be ready. For determinism virtual time does not advance
// while there are pending network fetches (i.e no timers will fire). Once all
// network fetches have completed, timers fire and if the system runs out of
// virtual time is fastforwarded so the next timer fires immediately, until the
// specified virtual time budget is exhausted.
const char kVirtualTimeBudget[] = "virtual-time-budget";
I did some experiments, and the results were confusing to me:
# I'm on macOS; you may change this alias according to your own OS
$ alias chrome="/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome"
$ chrome --version
Google Chrome 70.0.3538.110
$ time chrome --headless --disable-gpu --print-to-pdf https://www.chromestatus.com/
real 0m0.912s
user 0m0.264s
sys 0m0.219s
$ time chrome --headless --disable-gpu --print-to-pdf --virtual-time-budget=10000 https://www.chromestatus.com/
real 0m2.502s
user 0m0.347s
sys 0m0.244s
$ time chrome --headless --disable-gpu --print-to-pdf --virtual-time-budget=100000 https://www.chromestatus.com/
real 0m15.432s
user 0m0.759s
sys 0m0.406s
$ time chrome --headless --disable-gpu --print-to-pdf --virtual-time-budget=1000000 https://www.chromestatus.com/
real 0m15.755s
user 0m0.755s
sys 0m0.401s
I thought Chrome would wait for 0, 10, 100, and 1000 seconds in the above four examples before printing to PDF, but the actual waiting time seemed to be far off. My question is, how to make Chrome wait definitely for X seconds before printing a page to PDF? I'm only considering the Chrome CLI at the moment, and I'm not looking for tools like Puppeteer.

I can answer your title question easily(which explains your results). --virtual-time-budget, states how long the process will wait for a page to load, not that it will wait that long. If the result of the request is available(no more network requests are pending), it will return the results immediately.
The information returned should be correct, unless there is an AJAX request or other Javascript in the mix. If so, you must resort to Javascript/DOM manipulation to resolve the issue.

Related

How to configure pa11y timeout under actions for a json config file to override default 30 seconds timeout

We have a jenkins scripted pipeline to run pa11y automated testing against a set of authenticated URLs using Actions. We run it on linux and the config file is a json format file. Below is the file :-
{
"chromeLaunchConfig": {
"args": [
"--no-sandbox",
"--disable-setuid-sandbox",
"--disable-dev-shm-usage"
]
},
"actions":[
"set field #loginUserId to ***",
"set field #loginPassword to ***",
"click element #loginButton_0 to ***",
"wait for url to be https://www.qa.***.com/account/dashboard"
]
}
Here is the actual command line script that invokes this config json file to run the tests :-
pa11y --config config.json --threshold 500 -t 120000 --include-notices --include-warnings --reporter cli https://www.qa.***.com/login > results.json
Most of the times it works just fine but few times it just times out with below error :-
"Error: TimeoutError: waiting for function failed: timeout 30000ms exceeded"
I understand that default timeout is 30 seconds and hence i am overriding that using -t in command line with 120 seconds. But looks like under actions where its "wait for url to be *****", it still picks up default 30 seconds and fails sometimes with timeout.
How can i configure timeout option for actions in a json file to avoid this error?
Pa11y has a timeout flag/config option that allows you to specify the time in milliseconds that pa11y will wait for a test to finish before giving up.
This timeout value is for the entire test run, so that will include the time to initialise Chrome through the puppeteer library, load the page, carry any actions that have been specified, and finally run the automated accessibility test. As of pa11y 6.1.0 the default timeout is 60 seconds.
There's an additional timeout for each individual action that the browser takes, this is set by the puppeteer library and it's set to 30 seconds. Although this value can be changed in puppeteer, I don't think that this timeout is exposed in pa11y so it's not something that can be configured directly.
Some alternatives could be:
Make the site faster so the wait for action takes less than 30 seconds 😉
Pa11y by default will create a new puppeteer instance, but you can pass it an existing puppeteer instance with a page already loaded. You could use write a short node script that starts puppeteer, executes the desired actions using puppeteer commands (with a timeout higher than 30 seconds for each of them), and then finally calls pa11y: https://github.com/pa11y/pa11y/tree/9cf10d4d511ccb0e5129495968a24b6512bfe6ee#browser-browser-and-page-page

Google Chrome version 80 on GalliumOS reliably crashes after several hours

I have about 50 Chromeboxes running GalliumOS, displaying the same HTTP pages all day (dashboards) using Chrome version 80.0.3987.116.
For the past couple weeks, Chrome has been crashing every 18 hours or so, on every single Chromebox. It becomes unresponsive and I have to kill the process or restart the box.
I'm testing Chrome on one of them using this command that loads a given URL:
google-chrome-stable --load-media-router-component-extension=0 --disable-session-crashed-bubble --enable-logging --v=1 app="http://192.168.x.x/whatever"
(The --load-media-router-component-extension=0 is a workaround we put in for a previous issue- the Chrome Media Router was reliably crashing after only a few hours, and we aren't using Chromecast anyway, so that was a no-brainer. And --disable-session-crashed-bubble is to get rid of a modal dialog; we only have SSH access to these things.)
I came in this morning and it was locked up on schedule. On STDOUT it kept printing this over and over again:
[12171:1:0100/00000.627388:ERROR:broker_posix.cc(46)] Received unexpected number of handles
[12171:1:0100/00000.627421:ERROR:command_buffer_proxy_impl.cc(94)] ContextResult::kFatalFailure: AllocateAndMapSharedMemory failed
In chrome_debug.log I'm finding this at the end (repeated over and over):
[12171:1:0100/000000.404872:ERROR:command_buffer_proxy_impl.cc(94)] ContextResult::kFatalFailure: AllocateAndMapSharedMemory failed
[12171:1:0100/000000.405038:ERROR:broker_posix.cc(46)] Received unexpected number of handles
Right now, to get around this we're running a cron job that restarts lightdm on each Chromebox after a couple hours, but we're considering downgrading all of them to whatever the last stable version of Chrome was, 79 or 78.

running Chrome in headless mode

To run chrome in headless mode, I did
alias chrome="/Applications/Google\ Chrome.app/Contents/MacOS/Google\
Chrome"
chrome --remote-debugging-port=9222 --disable-gpu --headless
in console, But, I got this error,
[0305/140111.481537:ERROR:xattr.cc(64)] setxattr
org.chromium.crashpad.database.initialized on file
/var/folders/m3/92mmh21n0cx4ppf8c3bcns38hd4_kk/T/: Operation not
permitted (1) [0305/140111.484254:ERROR:xattr.cc(64)] setxattr
org.chromium.crashpad.database.initialized on file
/var/folders/m3/92mmh21n0cx4ppf8c3bcns38hd4_kk/T/: Operation not
permitted (1) [0305/140111.484254:INFO:crashpad_client_mac.cc(292)]
restarting handler in 0.983s
[0305/140111.513641:ERROR:gpu_process_transport_factory.cc(1009)] Lost
UI shared context. [0305/140111.513709:ERROR:instance.cc(49)] Unable
to locate service manifest for metrics
[0305/140111.513733:ERROR:service_manager.cc(890)] Failed to resolve
service name: metrics [0305/140111.514229:ERROR:socket_posix.cc(142)]
bind() returned an error, errno=48: Address already in use (48)
DevTools listening on
ws://[::1]:9222/devtools/browser/c46563ca-1891-48bd-bdd6-e6122f3f3b5d
[0305/140112.484141:ERROR:xattr.cc(64)] setxattr
org.chromium.crashpad.database.initialized on file
/var/folders/m3/92mmh21n0cx4ppf8c3bcns38hd4_kk/T/: Operation not
permitted (1) [0305/140112.484641:INFO:crashpad_client_mac.cc(292)]
restarting handler in 0.985s [0305/140113.489618:ERROR:xattr.cc(64)]
setxattr org.chromium.crashpad.database.initialized on file
/var/folders/m3/92mmh21n0cx4ppf8c3bcns38hd4_kk/T/: Operation not
permitted (1) [0305/140113.490274:INFO:crashpad_client_mac.cc(292)]
restarting handler in 0.979s [0305/140114.484881:ERROR:xattr.cc(64)]
setxattr org.chromium.crashpad.database.initialized on file
/var/folders/m3/92mmh21n0cx4ppf8c3bcns38hd4_kk/T/: Operation not
permitted (1) [0305/140114.485349:INFO:crashpad_client_mac.cc(292)]
restarting handler in 0.985s [0305/140115.489188:ERROR:xattr.cc(64)]
setxattr org.chromium.crashpad.database.initialized on file
/var/folders/m3/92mmh21n0cx4ppf8c3bcns38hd4_kk/T/: Operation not
permitted (1) [0305/140115.489638:INFO:crashpad_client_mac.cc(292)]
restarting handler in 0.985s
I also tried,
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome
--remote-debugging-port=9222 --disable-gpu --headless
but I got same error.
Is there any solution for this?
I got the answer from Chrome crashpad crashes on xattr
Just provide a different directory for "crash dumps" when starting Chrome, like this:
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222 --disable-gpu --headless --crash-dumps-dir=/tmp
add the following command flags
--disk-cache-dir=/tmp --user-data-dir=/tmp --crash-dumps-dir=/tmp
eg.
chrome --headless --disable-gpu --screenshot --disk-cache-dir=/tmp --user-data-dir=/tmp --crash-dumps-dir=/tmp http://m.baidu.com
For more command-line flags, see here
UPDATE 3/6
I checked the solution on my own MacBook and it worked.
I encounter the same issue today, and after searching some document, I suspect it's due to the SIP(System Integrity Protection) feature in MacOS, with that restrict, you can't modify the files under /var folder even you have the root privilege.
So here is the way to disable that feature:
Turn off your Mac (Apple > Shut Down).
Hold down Command-R and press the Power button. Keep holding Command-R until the Apple logo appears.
Wait for OS X to boot into the OS X Utilities window.
Choose Utilities > Terminal.
Enter csrutil disable.
Enter reboot.

Testing on Chrome with flash

I'm doing automated tests with Chrome.
Part of my suite needs flash to be activated (sight...).
I'm struggling to activate it. Here's what I got:
If I open a regular chrome session, with Flash checked in chrome://plugins, it works there:
When the tests start, the command line executed is:
â–¶ ps -edf | grep chrome
augustin 24752 24743 2 12:12 pts/0 00:00:07 /opt/google/chrome/chrome --user-data-dir=/tmp/karma-22735678 --no-default-browser-check --no-first-run --disable-default-apps --disable-popup-blocking --disable-translate --disable-background-timer-throttling http://test.example.com:8080/?id=22735678
I always get Download failed or sometimes flash version outdated.
Even if I check flash in plugins and reload, even if I allow it specifically for this tab and refresh:
I tried several command line options:
--always-authorize-plugins from there
--enable-plugins from there
without sucess. :(
Thanks for the help
EDIT:
If I click on + details in chrome://plugins, I can see that in a regular session, Location is set to /home/augustin/.config/google-chrome/PepperFlash/23.0.0.207/libpepflashplayer.so
, while, in the command-lined open I get: Location: internal-not-yet-present
This might be the explanation, though I still don't know how to fix it.
I made it by copying the content of /home/augustin/.config/google-chrome/PepperFlash/* into /opt/google/chrome/PepperFlash, chmod -r +rx /opt/google/chrome/PepperFlash and then adding the following flags to the launcher :
customLaunchers: {
Chrome_plugins: {
base: 'Chrome',
flags: ['--ppapi-flash-path=/opt/google/chrome/PepperFlash/23.0.0.207/libpepflashplayer.so', '--enable-plugins', '--always-authorize-plugins']
}
},
Not very plug&play, neither compatible with other laptops, but at least works.
A more robust solution would be welcome!

Starting google-chrome via Selenium on headless debian system

I'm trying to start the google-chrome browser in disabled web security mode. The selenium log says:
15:36:33.526 INFO - Command request: getNewBrowserSession[*googlechrome, http://www.myurl.de, , commandLineFlags=--disable-web-security] on session null
Anyways, it just hangs after
15:36:33.600 INFO - Launching Google Chrome...
Here's the stack trace:
16:36:44.605 ERROR - Failed to start new browser session, shutdown browser and clear all session data org.openqa.selenium.server.RemoteCommandException: timed out waiting for window 'null' to appear at org.openqa.selenium.server.FrameGroupCommandQueueSet.waitForLoad(FrameGroupCommandQueueSet.java:564) at org.openqa.selenium.server.FrameGroupCommandQueueSet.waitForLoad(FrameGroupCommandQueueSet.java:521) at org.openqa.selenium.server.BrowserSessionFactory.createNewRemoteSession(BrowserSessionFactory.java:374) at org.openqa.selenium.server.BrowserSessionFactory.getNewBrowserSession(BrowserSessionFactory.java:125) at org.openqa.selenium.server.BrowserSessionFactory.getNewBrowserSession(BrowserSessionFactory.java:87) at org.openqa.selenium.server.SeleniumDriverResourceHandler.getNewBrowserSession(SeleniumDriverResourceHandler.java:785) at org.openqa.selenium.server.SeleniumDriverResourceHandler.doCommand(SeleniumDriverResourceHandler.java:422) at org.openqa.selenium.server.SeleniumDriverResourceHandler.handleCommandRequest(SeleniumDriverResourceHandler.java:393) at org.openqa.selenium.server.SeleniumDriverResourceHandler.handle(SeleniumDriverResourceHandler.java:146) at org.openqa.jetty.http.HttpContext.handle(HttpContext.java:1530) at org.openqa.jetty.http.HttpContext.handle(HttpContext.java:1482) at org.openqa.jetty.http.HttpServer.service(HttpServer.java:909) at org.openqa.jetty.http.HttpConnection.service(HttpConnection.java:820) at org.openqa.jetty.http.HttpConnection.handleNext(HttpConnection.java:986) at org.openqa.jetty.http.HttpConnection.handle(HttpConnection.java:837) at org.openqa.jetty.http.SocketListener.handleConnection(SocketListener.java:243) at org.openqa.jetty.util.ThreadedServer.handle(ThreadedServer.java:357) at org.openqa.jetty.util.ThreadPool$PoolThread.run(ThreadPool.java:534)
Selenium is started by robotframework by the robotframework-maven-plugin. Also xvfb is started by the maven build script to simulate a display. But the startup configuration does not seem to be the problem. Everything starts fine, just the browser won't get up.
I hope anyone can help me.
Make sure that the user account that is launching the browser has a home directory. Otherwise the browser profile creation will fail.