Skip to content

Commit

Permalink
Supports headless mode.
Browse files Browse the repository at this point in the history
  • Loading branch information
tomchristie committed Dec 23, 2011
1 parent 30fee7a commit 11bfbca
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Original file line Diff line number Diff line change
@@ -1,6 +1,7 @@
*.pyc *.pyc
*~ *~
.* .*
chromedriver.log


!.gitignore !.gitignore


Expand Down
4 changes: 2 additions & 2 deletions docs/browsers.rst
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ To create a WebDriver browser instance:
from webdriverplus import WebDriver from webdriverplus import WebDriver
browser = WebDriver('firefox') browser = WebDriver('firefox')
Currently supported browsers are ``firefox``, ``chrome``, ``ie`` and Currently supported browsers are ``firefox``, ``chrome``, ``ie``, ``htmlunit``,
``remote``. and ``remote``.


The default browser is firefox. If called without any arguments, The default browser is firefox. If called without any arguments,
``WebDriver()`` will create a firefox instance. ``WebDriver()`` will create a firefox instance.
Expand Down
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ What's so great about WebDriver Plus?
complex xpath expressions. complex xpath expressions.
* Perform actions directly on elements without having to use ActionChains. * Perform actions directly on elements without having to use ActionChains.
* Element highlighting makes working from the Python console a joy. * Element highlighting makes working from the Python console a joy.
* Supports headless mode using HtmlUnit.


.. note:: .. note::
WebDriver Plus is currently in alpha. WebDriver Plus is currently in alpha.
Expand Down
61 changes: 61 additions & 0 deletions webdriverplus/__init__.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@
from selenium.webdriver.chrome.webdriver import WebDriver as _Chrome from selenium.webdriver.chrome.webdriver import WebDriver as _Chrome
from selenium.webdriver.ie.webdriver import WebDriver as _Ie from selenium.webdriver.ie.webdriver import WebDriver as _Ie
from selenium.webdriver.remote.webdriver import WebDriver as _Remote from selenium.webdriver.remote.webdriver import WebDriver as _Remote

from webdriverplus.utils import _download
from webdriverplus.webdriver import WebDriverMixin from webdriverplus.webdriver import WebDriverMixin
from webdriverplus.webelement import WebElement from webdriverplus.webelement import WebElement


import atexit import atexit
import os
import socket
import subprocess
import time
import urllib2 import urllib2


VERSION = (0, 0, 4, 'dev') VERSION = (0, 0, 4, 'dev')
Expand All @@ -24,10 +30,14 @@ def get_version():
class WebDriver(WebDriverMixin): class WebDriver(WebDriverMixin):
_pool = {} # name -> (instance, signature) _pool = {} # name -> (instance, signature)
_quit_on_exit = set() # set of instances _quit_on_exit = set() # set of instances
_selenium_server = None # Popen object
_default_browser = 'firefox' _default_browser = 'firefox'


@classmethod @classmethod
def _at_exit(cls): def _at_exit(cls):
if cls._selenium_server:
cls._selenium_server.kill()

for driver in cls._quit_on_exit: for driver in cls._quit_on_exit:
try: try:
driver.quit(force=True) driver.quit(force=True)
Expand Down Expand Up @@ -99,13 +109,64 @@ class Remote(WebDriverMixin, _Remote):




class HtmlUnit(WebDriverMixin, _Remote): class HtmlUnit(WebDriverMixin, _Remote):
_selenium = 'selenium-server-standalone-2.15.0.jar'
_selenium_url = 'http://selenium.googlecode.com/files/' + _selenium
_auto_install = True

def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self._perform_auto_install()
self._autorun_selenium_server()
super(HtmlUnit, self).__init__("http://localhost:4444/wd/hub", super(HtmlUnit, self).__init__("http://localhost:4444/wd/hub",
DesiredCapabilities.HTMLUNIT) DesiredCapabilities.HTMLUNIT)


def _create_web_element(self, element_id): def _create_web_element(self, element_id):
return HtmlUnitWebElement(self, element_id) return HtmlUnitWebElement(self, element_id)


def _get_webdriver_dir(self):
directory = os.path.expanduser('~/.webdriverplus')
if not os.path.exists(directory):
os.mkdir(directory)
return directory

def _get_selenium_path(self):
return self._get_webdriver_dir() + '/' + self._selenium

def _perform_auto_install(self):
if not self._auto_install:
return

selenium_server = self._get_selenium_path()
if not os.path.exists(selenium_server):
_download(self._selenium_url, selenium_server)

def _autorun_selenium_server(self):
if WebDriver._selenium_server:
return

if subprocess.call(['hash', 'java']) != 0:
raise Exception('java does not appear to be installed.')

fnull = open(os.devnull, 'w')
args = ['java', '-jar', self._get_selenium_path()]
WebDriver._selenium_server = subprocess.Popen(args, stdout=fnull, stderr=fnull)

now = time.time()
timeout = 10
connected = False
while time.time() - now < timeout:
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('127.0.0.1', 4444))
except:
time.sleep(0.2)
else:
sock.close()
connected = True
break

if not connected:
raise Exception('Could not connect to selenium server')



class HtmlUnitWebElement(WebElement): class HtmlUnitWebElement(WebElement):
def descendants(self): def descendants(self):
Expand Down
26 changes: 26 additions & 0 deletions webdriverplus/utils.py
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,26 @@
import urllib2


def _download(url, filename):
file_name = url.split('/')[-1]
u = urllib2.urlopen(url)
f = open(filename, 'wb')
meta = u.info()
size = int(meta.getheaders("Content-Length")[0])
print "Downloading: %s Bytes: %s" % (file_name, size)

downloaded = 0
block_sz = 8192
while True:
buffer = u.read(block_sz)
if not buffer:
break

downloaded += len(buffer)
f.write(buffer)
status = r"%10d [%3.2f%%]" % (downloaded, downloaded * 100. / size)
status = status + chr(8) * (len(status) + 1)
print status,

print chr(8) + 'Done' + ' ' * (len(status) + 1)
f.close()

0 comments on commit 11bfbca

Please sign in to comment.