Routines for testing WSGI applications with selenium.
Most interesting is SeleniumApp and the selenium() decorator
Those value are used if found in environment:
SELENIUM_HOST: Default to 127.0.0.1
SELENIUM_PORT: Default to 4444
SELENIUM_BIND: IP used to bind extra servers (WSGI Server/File server). Default to 127.0.0.1
SELENIUM_DRIVER: The driver used to start the browser. Usualy something in *chrome, *firefox, *googlechrome. Default to *googlechrome. You can get the full list by running:
$ java -jar selenium-server.jar -interactive
cmd=getNewBrowserSession
SELENIUM_KEEP_OPEN: If exist then browser session are not closed so you can introspect the problem on failure.
SELENIUM_JAR: If selenium is not running then this jar is used to run selenium.
See webtest.TestApp
SeleniumApp only support GET requests
Close selenium and the WSGI server if needed
Selenium RC control aka browser
A object use to manipulate DOM nodes. This object allow to use the underlying selenium api. See Selenium api
You can use the original method name:
browser.fireEvent('id=#myid", 'focus')
Or a more pythonic name:
browser.fire_event('id=#myid", 'focus')
Both are equal to:
browser.execute('fireEvent', 'id=#myid', 'focus')
A callable usable as:
Some of the return values return instances of these classes:
Expose a Document
If this request is a redirect, follow that redirect. It is an error if this is not a redirect response. Returns another response object.
The browser document. resp.doc.myid is egual to resp.doc.css('#myid')
Get a button
Get an Element using a css selector
Return an element matching tag, an attribute and an index. For example:
resp.doc.get('input', name='go') => xpath=//input[@name="go"]
resp.doc.get('li', description='Item') => xpath=//li[.="Item"]
Get an input field
Get a link
Get an Element using xpath
A object use to manipulate DOM nodes. This object allow to use the underlying selenium api for the specified locator. See Selenium api
You can use the original method name:
element.fireEvent('focus')
Or a more pythonic name:
element.fire_event('focus')
Both are equal to:
browser.execute('fireEvent', element.locator, 'focus')
Return the attribute value of the element
Drag and drop to element
Eval a javascript expression in Selenium RC. You can use the following variables:
return true is the element is present
True iif the class is present
Return the innerHTML of the element
Return the text of the element
Wait for an element and return this element
Wait for an element, click on it and return this element
class TestApp(unittest.TestCase):
def setUp(self):
self.app = webtest.TestApp(application)
def test_webtest(self):
resp = self.app.get('/', {'redirect': '/message.html?message=submited'})
resp.mustcontain('It Works!')
form = resp.forms['myform']
form.lint()
self.assertEqual(form['mytext'].value, '')
resp.mustcontain(no='Form submited')
with webtest.selenium(resp) as sresp:
if sresp:
sform = sresp.forms['myform']
sform['mytext'] = 'foo'
sresp = sform.submit(name='go', timeout=0)
sresp.mustcontain('Form submited')
if resp.updated:
resp.mustcontain('Form submited')
form = resp.forms['myform']
self.assertEqual(form['mytext'].value, 'foo')
resp = form.submit(name='go')
resp = resp.follow()
resp.mustcontain('<pre>submited</pre>')
@webtest.selenium
def test_selenium(self):
resp = self.app.get('/', {'redirect': '/message.html?message=submited'})
resp.mustcontain('It Works!')
form = resp.forms['myform']
form.lint()
form['mytext'] = 'foo'
self.assertEqual(form['mytext'].value, 'foo')
# file upload are only supported with *firefox *chrome drivers
filename = os.path.join(files, 'html', 'index.html')
file = form['myfile']
file.value = (filename,)
form['myradio'] = 'true'
self.assertEqual(form['myradio'].value, 'true')
check = form.get('mycheckbox', index=0)
check.value = 'true'
self.assertEqual(check.value, 'true')
form['myselect'] = 'value2'
form['myselect'] = 'value2'
self.assertEqual(form['myselect'].value, 'value2')
form['mymultiselect'] = ['value1', 'value3']
self.assertEqual(form['mymultiselect'].value, ['value1', 'value3'])
# there is an ajax hook on the page
resp = form.submit(name='go', timeout=0)
resp.mustcontain('Form submited')
# but we can submit the form to get the non-javascript behavior
resp = form.submit()
resp = resp.follow()
resp.mustcontain('<pre>submited</pre>')
class TestJQueryUI(unittest.TestCase):
@classmethod
def setupClass(cls):
cls.app = webtest.SeleniumApp(url='http://jqueryui.com/')
def setUp(self):
self.resp = self.app.get('http://jqueryui.com/demos/')
def test_autocomplete(self):
resp = self.resp.click('Autocomplete')
field = resp.doc.xpath('//input[@id="tags"]')
field.value = 'a'
item = resp.doc.xpath('//ul[@role="listbox"]//a[.="AppleScript"]')
item.wait().fireEvent('mouseover')
field.value = resp.doc.css('#ui-active-menuitem').html()
self.assertEqual(field.value, "AppleScript")
def test_datepicker(self):
resp = self.resp.click('Datepicker')
field = resp.doc.datepicker
field.fireEvent('focus')
resp.doc.link('16').wait_and_click()
self.assertIn('/16/', field.value)
def test_dialog(self):
resp = self.resp.click('Dialog')
close = resp.doc.xpath('//div[@role="dialog"]//span[.="close"]')
close.wait_and_click()
resp.doc.link('Modal form').click()
resp.doc.button('Create new user').wait().click()
form = resp.form
form['name'].value = 'Gael'
form['email'] = 'gael@gawel.org'
create = resp.doc.button('Create an account')
create.click()
pwd = form['password']
self.assertTrue(pwd.hasClass('ui-state-error'))
pwd.value = 'pwd'
create.click()
resp.mustcontain('Length of password must be between 5 and 16.')
pwd.value = 'passwd'
create.click()
resp.mustcontain('<td>Gael</td>')
def test_dropable(self):
resp = self.resp.click('Droppable')
draggable = resp.doc.draggable
droppable = resp.doc.droppable
self.assertFalse(droppable.hasClass('ui-state-highlight'))
draggable.drag_and_drop(droppable)
self.assertTrue(droppable.hasClass('ui-state-highlight'))
resp.doc.link('Shopping Cart').click()
cart = resp.doc.css('#cart ol.ui-droppable')
cart.wait()
item = resp.doc.xpath('//li[.="Lolcat Shirt"]')
self.assertNotIn(item, cart)
item.drag_and_drop(cart)
self.assertIn(item, cart)
@classmethod
def teardownClass(cls):
cls.app.close()