Monorail Project: chromedriver Issues People Development process History Sign in
New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.
Issue 1772 Chromedriver running against canary chrome w/ headless flag requires XVFB for sendKey interactions
Starred by 22 users Reported by malone.s...@gmail.com, Apr 19 Back to list
Status: Assigned
Owner:
Cc:

Blocking:
issue chromium:604324



Sign in to add a comment
Issue Description:
Using a canary build of chrome w/ the headless flag, sendkeys doesn't work if driving with chromedriver. It'd be super nice to have a solution for this because otherwise the headless flag is wayyy less useful.

Steps to reproduce:
I'm using docker for this, so bear with me.

Throw all of this into a terminal:
1) docker run --entrypoint=bash -it justinribeiro/chrome-headless:latest
Inside the docker container from here on out
2) apt-get update && apt-get install wget unzip python python-pip
3) LATEST=$(wget -q -O - http://chromedriver.storage.googleapis.com/LATEST_RELEASE)
4) wget http://chromedriver.storage.googleapis.com/$LATEST/chromedriver_linux64.zip
5) unzip chromedriver_linux64.zip && ln -s $PWD/chromedriver /usr/local/bin/chromedriver
6) echo '#\!/usr/bin/env bash' > /usr/bin/google-chrome 
7) echo '/opt/stickmanventures/chrome-headless/headless_shell --headless --no-sandbox "$@"' >> /usr/bin/google-chrome
8) chmod 755 /usr/bin/google-chrome
9) pip install selenium
10) python
11) follow the python steps found here: https://sites.google.com/a/chromium.org/chromedriver/getting-started


Here's the output of the python steps:

root@9c6a5969d51b:/# python
Python 2.7.12 (default, Nov 19 2016, 06:48:10) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import time
>>> from selenium import webdriver
>>> 
>>> driver = webdriver.Chrome()
>>> driver.get('http://www.google.com/xhtml');
>>> search_box = driver.find_element_by_name('q')
>>> search_box.send_keys('ChromeDriver')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webelement.py", line 349, in send_keys
    'value': keys_to_typing(value)})
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webelement.py", line 493, in _execute
    return self._parent.execute(command, params)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 249, in execute
    self.error_handler.check_response(response)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/errorhandler.py", line 193, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: unknown error: an X display is required for keycode conversions, consider using Xvfb
  (Session info: content shell=)
  (Driver info: chromedriver=2.29.461571 (8a88bbe0775e2a23afda0ceaf2ef7ee74e822cc5),platform=Linux 4.9.4-moby x86_64)
 
Project Member Comment 1 by gmanikpure@chromium.org, Apr 19
Labels: Needs-Feedback
Chrome Canary builds are not available for Linux platform. Did you test on Chrome Dev build? What is the version of chrome browser ?
Sorry, it was someone else's early build of the headless project that didn't have the version flag. Just realized that the google-chrome-unstable has the headless flag these days, so I used that.

root@aa791cabef8b:/# google-chrome --version
Google Chrome 59.0.3071.9 dev

To install in that container, you essentially need to take the steps I outlined above and skip steps 6-8, but instead do...

6) sh -c 'echo "deb [arch=amd64] https://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
7) apt-get install apt-transport-https && apt-get update && apt-get install google-chrome-unstable

I think this should work, but haven't tested it yet from the start of those instructions.

And then when you start the chromedriver in python, you'll need to add in a set of options for the headless chrome:

>>> from selenium.webdriver.chrome.options import Options
>>> 
>>> chrome_options = Options()
>>> chrome_options.add_argument("--disable-gpu")
>>> chrome_options.add_argument("--no-sandbox")
>>> chrome_options.add_argument("--headless")
>>> driver = webdriver.Chrome(chrome_options=chrome_options)


It still gives the same error though.
Project Member Comment 3 by gmanikpure@chromium.org, Apr 19
I tried the test without docker setup in following manner :-

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

opts = Options()
opts.add_argument('--headless')
opts.add_argument('--no-sandbox')
opts.add_argument('--disable-gpu')
opts.binary_location = "/usr/bin/google-chrome-unstable"

browser = webdriver.Chrome(chrome_options=opts, executable_path='/path/to/chromedriver')
browser.get('http://google.com')
elem = browser.find_element_by_name('q')
elem.send_keys('testing')
browser.quit()

and it works fine with Chromedriver v2.29 on Chrome v59.0.3071.9 dev.

Do you know if this happens only with docker setup? Can you also please provide chromedriver verbose logs?
Were you in a "headless environment"? If I add XVFB (or I imagine, if I run on mac/windows/another GUI environment), it does work. I guess I'm not sure where this should land, on the Chromedriver side, or the headless chrome side. I'll get you the verbose logs tomorrow. Our hope was that we wouldn't have to have the overhead of XVFB if chrome doesn't need to render anything. I know with just the chrome debugging protocol, we can do sendkey actions in a headless environment, so it just seemed like it should be possible for chromedriver.

(see: https://github.com/knq/chromedp/tree/master/examples/headless, which is running headless chrome in docker using the debugging protocol and is able to send keys)
Blocking: chromium:604324
#4 I am running into the same problems you are.

Booted up a minimal CentOS7 environment and just ran into this issue when trying to use sendKeys() (Java/Selenium). I'm using ChromeDriver v2.29.

I did see some material on https://github.com/SeleniumHQ/selenium/wiki/Advanced-User-Interactions#native-events-versus-synthetic-events re: Chrome's usage of WebKit Events vs "Raw Events". I assume this may help me towards using sendKeys(), but there is no information on how to toggle the usage of WebKit events.

Is the current workaround to just run an instance of Xvfb? Echoing #4, I had hoped that we wouldn't have to use Xvfb.
Ran into this with the following versions:

OS: Ubuntu 14.04
Chromium 60.0.3097.0
Chromedriver: 2.29.464589 (7cda776b17ae612ddc45b948e4a350a5295a1b5b)

Using ""selenium-webdriver" gem with Ruby. I have attached the script. The error comes only at "element.send_keys" call.

Full error message:

Selenium::WebDriver::Error::UnknownError: unknown error: an X display is required for keycode conversions, consider using Xvfb
  (Session info: headless chrome=60.0.3097.0)
  (Driver info: chromedriver=2.29.464589 (7cda776b17ae612ddc45b948e4a350a5295a1b5b),platform=Linux 4.4.0-64-generic x86_64)
	from /home/deploy/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/selenium-webdriver-3.4.0/lib/selenium/webdriver/remote/response.rb:69:in `assert_ok'
chromeheadless.rb
420 bytes View Download
Cc: samu...@chromium.org irisu@chromium.org jzfeng@chromium.org
Looks like we should maybe switch from keycode_text_conversion_x.cc to keycode_text_conversion_ozone.cc in headless mode?
Project Member Comment 9 by gmanikpure@chromium.org, May 11
Cc: johnchen@chromium.org
+johnchen@

John is the new lead for Chromedriver.
I have the same issue Ubuntu 16.04.2

Google Chrome: 59.0.3071.47 beta
Chrome Driver: 2.29.461571
Selenium: 3.4.1

>>> from selenium import webdriver
>>> from selenium.webdriver.chrome.options import Options
>>> opts = Options()
>>> opts.add_argument('--headless')
>>> opts.add_argument('--no-sandbox')
>>> opts.add_argument('--disable-gpu')
>>> browser = webdriver.Chrome(chrome_options=opts, executable_path='/usr/local/bin/chromedriver')
>>> browser.get('http://google.com')
>>> browser.title
'Google'
>>> browser.find_element_by_name('q').send_keys('test')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/user/.local/lib/python3.5/site-packages/selenium/webdriver/remote/webelement.py", line 349, in send_keys
    'value': keys_to_typing(value)})
  File "/home/user/.local/lib/python3.5/site-packages/selenium/webdriver/remote/webelement.py", line 493, in _execute
    return self._parent.execute(command, params)
  File "/home/user/.local/lib/python3.5/site-packages/selenium/webdriver/remote/webdriver.py", line 252, in execute
    self.error_handler.check_response(response)
  File "/home/user/.local/lib/python3.5/site-packages/selenium/webdriver/remote/errorhandler.py", line 194, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: unknown error: an X display is required for keycode conversions, consider using Xvfb
  (Session info: headless chrome=59.0.3071.47)
  (Driver info: chromedriver=2.29.461571 (8a88bbe0775e2a23afda0ceaf2ef7ee74e822cc5),platform=Linux 4.4.0-75-generic x86_64)

Cc: -irisu@chromium.org
Owner: irisu@chromium.org
Status: Assigned
irisu@, this was also mentioned in the comments of https://developers.google.com/web/updates/2017/04/headless-chrome

Have you been able to repro this?
I have been able to reproduce the error.

I am able to avoid the error if I compile chrome and chromedriver with the use_ozone = true build flag. Unfortunately the choice between keycode_text_conversion_x.cc vs keycode_text_conversion_ozone.cc is made at compile time, whereas the choice to run chrome in headless mode is done at runtime.

I will have to look into this more to find a good solution.
Sign in to add a comment