webtest.sel – Functional Testing with Selenium — WebTest v1.3 documentation

### Navigation

- index
- modules |
- previous |
- WebTest v1.3 documentation »

# `webtest.sel` – Functional Testing with Selenium

Routines for testing WSGI applications with selenium.

Most interesting is `SeleniumApp` and the `selenium()` decorator

## Environment variables

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.

## Module Contents

class `webtest.sel.` `SeleniumApp`(app=None, url=None, timeout=30000, extra_environ=None, relative_to=None, **kwargs)

  See `webtest.TestApp`

  SeleniumApp only support `GET` requests

  `browser`

    The current `Selenium`

  `close`()

    Close selenium and the WSGI server if needed

class `webtest.sel.` `Selenium`

  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')

`webtest.sel.` `selenium`(obj)

  A callable usable as:

  - class decorator
  - function decorator
  - contextmanager

### Return Values

Some of the return values return instances of these classes:

class `webtest.sel.` `TestResponse`(body=None, status=None, headerlist=None, app_iter=None, request=None, content_type=None, conditional_response=None, **kw)
  `doc`

    Expose a `Document`

  `follow`(status=None, **kw)

    If this request is a redirect, follow that redirect. It is an error if this is not a redirect response. Returns another response object.

class `webtest.sel.` `Document`(resp)

  The browser document. `resp.doc.myid` is egual to `resp.doc.css('#myid')`

  `button`(description=None, buttonid=None, index=None)

    Get a button

  `css`(selector)

    Get an `Element` using a css selector

  `get`(tag, **kwargs)

    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"]

  `input`(value=None, name=None, inputid=None, index=None)

    Get an input field

  `link`(description=None, linkid=None, href=None, index=None)

    Get a link

  `xpath`(path)

    Get an `Element` using xpath

class `webtest.sel.` `Element`(resp, locator)

  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')

  `attr`(attr)

    Return the attribute value of the element

  `drag_and_drop`(element)

    Drag and drop to element

  `eval`(*expr)

    Eval a javascript expression in Selenium RC. You can use the following variables:

    - s: the `selenium` object
    - b: the `browserbot` object
    - l: the element locator string
    - e: the element itself
  `exist`()

    return true is the element is present

  `hasClass`(name)

    True iif the class is present

  `html`()

    Return the innerHTML of the element

  `text`()

    Return the text of the element

  `wait`(timeout=3000)

    Wait for an element and return this element

  `wait_and_click`(timeout=3000)

    Wait for an element, click on it and return this element

class `webtest.sel.` `Form`(resp, id)

  See `Form`

  `submit`(name=None, index=None, extra_environ=None, timeout=None)

    Submits the form. If `name` is given, then also select that button (using `index` to disambiguate)``.

    Returns a `webtest.browser.TestResponse` object.

## Examples

### Testing a wsgi application

    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>')

### Testing the jquery.ui website

    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()

### Navigation

- index
- modules |
- previous |
- WebTest v1.3 documentation »