Permalink
Browse files

Supports headless mode.

  • Loading branch information...
1 parent 30fee7a commit 11bfbca8bb2dd5bae12333940d1931c68a18e6d1 @tomchristie committed Dec 23, 2011
Showing with 91 additions and 2 deletions.
  1. +1 −0 .gitignore
  2. +2 −2 docs/browsers.rst
  3. +1 −0 docs/index.rst
  4. +61 −0 webdriverplus/__init__.py
  5. +26 −0 webdriverplus/utils.py
View
@@ -1,6 +1,7 @@
*.pyc
*~
.*
+chromedriver.log
!.gitignore
View
@@ -13,8 +13,8 @@ To create a WebDriver browser instance:
from webdriverplus import WebDriver
browser = WebDriver('firefox')
-Currently supported browsers are ``firefox``, ``chrome``, ``ie`` and
-``remote``.
+Currently supported browsers are ``firefox``, ``chrome``, ``ie``, ``htmlunit``,
+ and ``remote``.
The default browser is firefox. If called without any arguments,
``WebDriver()`` will create a firefox instance.
View
@@ -22,6 +22,7 @@ What's so great about WebDriver Plus?
complex xpath expressions.
* Perform actions directly on elements without having to use ActionChains.
* Element highlighting makes working from the Python console a joy.
+* Supports headless mode using HtmlUnit.
.. note::
WebDriver Plus is currently in alpha.
View
@@ -3,10 +3,16 @@
from selenium.webdriver.chrome.webdriver import WebDriver as _Chrome
from selenium.webdriver.ie.webdriver import WebDriver as _Ie
from selenium.webdriver.remote.webdriver import WebDriver as _Remote
+
+from webdriverplus.utils import _download
from webdriverplus.webdriver import WebDriverMixin
from webdriverplus.webelement import WebElement
import atexit
+import os
+import socket
+import subprocess
+import time
import urllib2
VERSION = (0, 0, 4, 'dev')
@@ -24,10 +30,14 @@ def get_version():
class WebDriver(WebDriverMixin):
_pool = {} # name -> (instance, signature)
_quit_on_exit = set() # set of instances
+ _selenium_server = None # Popen object
_default_browser = 'firefox'
@classmethod
def _at_exit(cls):
+ if cls._selenium_server:
+ cls._selenium_server.kill()
+
for driver in cls._quit_on_exit:
try:
driver.quit(force=True)
@@ -99,13 +109,64 @@ class Remote(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):
+ self._perform_auto_install()
+ self._autorun_selenium_server()
super(HtmlUnit, self).__init__("http://localhost:4444/wd/hub",
DesiredCapabilities.HTMLUNIT)
def _create_web_element(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):
def descendants(self):
View
@@ -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.