diff options
| author | Gael Pasgrimaud <gael@gawel.org> | 2011-08-27 19:13:36 +0200 |
|---|---|---|
| committer | Gael Pasgrimaud <gael@gawel.org> | 2011-08-27 19:13:36 +0200 |
| commit | b6fb936bcc0974216a8e25f42087954c0547f43d (patch) | |
| tree | 5b4d458f71e6347785f991594574e94edc62ab74 | |
| parent | 6bc6cc78c1f9ffd298256a37902dafdf755c7213 (diff) | |
| download | webtest-1.3.tar.gz | |
Improve selenium api1.3
Add Form.__repr__
Few doc improvements
| -rw-r--r-- | docs/index.txt | 15 | ||||
| -rw-r--r-- | docs/modules/sel.txt | 3 | ||||
| -rw-r--r-- | docs/modules/webtest.txt | 11 | ||||
| -rw-r--r-- | tests/compat.py | 2 | ||||
| -rw-r--r-- | tests/test_selenium.py | 2 | ||||
| -rw-r--r-- | webtest/app.py | 18 | ||||
| -rw-r--r-- | webtest/compat.py | 4 | ||||
| -rw-r--r-- | webtest/sel.py | 40 |
8 files changed, 62 insertions, 33 deletions
diff --git a/docs/index.txt b/docs/index.txt index 3954c36..f472102 100644 --- a/docs/index.txt +++ b/docs/index.txt @@ -2,6 +2,7 @@ Testing Applications with WebTest +++++++++++++++++++++++++++++++++ :author: Ian Bicking <ianb@colorstudy.com> +:maintainer: Gael Pasgrimaud <gael@gawel.org> .. toctree:: :maxdepth: 1 @@ -75,10 +76,10 @@ run WSGI applications and verify the output. TestApp ======= -The most important object in WebTest is ``webtest.TestApp``, the -wrapper for WSGI applications. To use it, you simply instantiate it -with your WSGI application. (Note: if your WSGI application requires -any configuration, you must set that up manually in your tests.) +The most important object in WebTest is :class:`~webtest.TestApp`, the wrapper +for WSGI applications. To use it, you simply instantiate it with your WSGI +application. (Note: if your WSGI application requires any configuration, you +must set that up manually in your tests.) .. code-block:: python @@ -89,7 +90,7 @@ any configuration, you must set that up manually in your tests.) >>> res.status '200 OK' >>> res.form - <webtest.app.Form object at ...> + <Form /> Making Requests --------------- @@ -227,13 +228,15 @@ The added methods: ``response.forms``: Return a dictionary of forms; you can use both indexes (refer to the forms in order) or the string ids of forms (if you've given - them ids) to identify the form. See `Form Submissions <#form-submissions>`_ for + them ids) to identify the form. See :ref:`form-submissions` for more on the form objects. ``response.form``: If there is just a single form, this returns that. It is an error if you use this and there are multiple forms. +.. _form-submissions: + Form Submissions ================ diff --git a/docs/modules/sel.txt b/docs/modules/sel.txt index a3ab41e..f80b92c 100644 --- a/docs/modules/sel.txt +++ b/docs/modules/sel.txt @@ -47,10 +47,13 @@ Some of the return values return instances of these classes: .. autoclass:: TestResponse :members: + .. autoclass:: Document :members: + .. autoclass:: Element :members: + .. autoclass:: Form :members: diff --git a/docs/modules/webtest.txt b/docs/modules/webtest.txt index 7f710fd..03a3d61 100644 --- a/docs/modules/webtest.txt +++ b/docs/modules/webtest.txt @@ -8,6 +8,7 @@ Module Contents .. autoclass:: TestApp :members: + .. autoexception:: AppError Return Values @@ -17,17 +18,27 @@ Some of the return values return instances of these classes: .. autoclass:: TestResponse :members: + .. autoclass:: TestRequest :members: + .. autoclass:: Form :members: + .. autoclass:: Field + .. autoclass:: Select + .. autoclass:: Radio + .. autoclass:: Checkbox + .. autoclass:: Text + .. autoclass:: Textarea + .. autoclass:: Hidden + .. autoclass:: Submit diff --git a/tests/compat.py b/tests/compat.py index 3630429..a2f6a7b 100644 --- a/tests/compat.py +++ b/tests/compat.py @@ -3,7 +3,7 @@ import sys try: # py < 2.7 - import unnitest2 as unittest + import unittest2 as unittest except ImportError: import unittest diff --git a/tests/test_selenium.py b/tests/test_selenium.py index 26d87d4..aee7763 100644 --- a/tests/test_selenium.py +++ b/tests/test_selenium.py @@ -186,7 +186,7 @@ class TestJQueryUI(unittest.TestCase): draggable = resp.doc.draggable droppable = resp.doc.droppable self.assertFalse(droppable.hasClass('ui-state-highlight')) - draggable.dragAndDropToObject(droppable) + draggable.drag_and_drop(droppable) self.assertTrue(droppable.hasClass('ui-state-highlight')) resp.doc.link('Shopping Cart').click() diff --git a/webtest/app.py b/webtest/app.py index 8252ec4..8934c47 100644 --- a/webtest/app.py +++ b/webtest/app.py @@ -92,8 +92,8 @@ class TestResponse(Response): def forms__get(self): """ - Returns a dictionary of ``Form`` objects. Indexes are both in - order (from zero) and by form id (if the form is given an id). + Returns a dictionary of :class:`~webtest.Form` objects. Indexes are + both in order (from zero) and by form id (if the form is given an id). """ if self._forms_indexed is None: self._parse_forms() @@ -101,8 +101,7 @@ class TestResponse(Response): forms = property(forms__get, doc=""" - A list of <form>s found on the page (instances of - ``Form``) + A list of :class:`~webtest.Form`s found on the page """) def form__get(self): @@ -118,9 +117,8 @@ class TestResponse(Response): form = property(form__get, doc=""" - Returns a single ``Form`` instance; it - is an error if there are multiple forms on the - page. + Returns a single :class:`~webtest.Form` instance; it is an + error if there are multiple forms on the page. """) @property @@ -1630,6 +1628,12 @@ class Form(object): submit.append((name, value)) return submit + def __repr__(self): + value = '<Form' + if self.id: + value += ' id=%r' % str(self.id) + return value + ' />' + ######################################## ## Utility functions ######################################## diff --git a/webtest/compat.py b/webtest/compat.py index 4626c88..83d5f89 100644 --- a/webtest/compat.py +++ b/webtest/compat.py @@ -22,12 +22,12 @@ if sys.version_info[0] > 2: def to_bytes(s): if isinstance(s, bytes): return s - return s.encode('ISO-8859-1') + return s.encode('latin1') def to_string(s): if isinstance(s, str): return s - return str(s, 'ISO-8859-1') + return str(s, 'latin1') def join_bytes(sep, l): l = [to_bytes(e) for e in l] diff --git a/webtest/sel.py b/webtest/sel.py index 7cc5bf1..88bd434 100644 --- a/webtest/sel.py +++ b/webtest/sel.py @@ -5,8 +5,8 @@ """ Routines for testing WSGI applications with selenium. -Most interesting is :class:`~webtest.browser.browsereniumApp` and the -:func:`~webtest.browser.browserenium` decorator +Most interesting is :class:`~webtest.sel.SeleniumApp` and the +:func:`~webtest.sel.selenium` decorator """ import os import cgi @@ -44,9 +44,14 @@ except ImportError: json = False +try: + unicode() +except NameError: + unicode = str + + log = logging.getLogger(__name__) -sys_stdout = sys.stdout if 'SELENIUM_VERBOSE': log.addHandler(logging.StreamHandler(sys.stderr)) @@ -384,7 +389,7 @@ class TestResponse(testapp.TestResponse): def _body__get(self): body = self.browser.getHtmlSource() if isinstance(body, binary_type): - return body.encode(self.charset or 'utf-8') + return unicode(body, self.charset or 'utf-8') else: return body @@ -440,6 +445,10 @@ class Element(object): return wrapped + def exist(self): + """return true is the element is present""" + return self.isElementPresent() + def wait(self, timeout=3000): """Wait for an element and return this element""" script = "selenium.isElementPresent(%r) || null" % str(self) @@ -455,7 +464,7 @@ class Element(object): def hasClass(self, name): """True iif the class is present""" - classes = self.eval('e.getAttribute("class")').split() + classes = self.attr('class').split() return name in classes def html(self): @@ -468,7 +477,10 @@ class Element(object): def attr(self, attr): """Return the attribute value of the element""" - return self.getAttribute(attr) + return self.eval('e.getAttribute(%r)' % str(attr)) + + def drag_and_drop(self, element): + return self.dragAndDropToObject(element) def value__get(self): return self.getValue() @@ -514,7 +526,7 @@ class Element(object): return s in self.html() def __nonzero__(self): - return self.isElementPresent() + return self.exist() __bool__ = __nonzero__ def __repr__(self): @@ -569,7 +581,7 @@ class Document(object): def __contains__(self, s): if isinstance(s, Element): - return s.isElementPresent() + return s.exist() return self.browser.isTextPresent(_get_value(s)) def __call__(self, locator): @@ -764,7 +776,7 @@ class Forms(object): return Form(self.resp, key) -class Form(testapp.Form): +class Form(testapp.Form, Element): """See :class:`~webtest.Form`""" FieldClass = Field @@ -777,10 +789,9 @@ class Form(testapp.Form): self.locator = _eval_xpath('form', index=id) else: self.locator = _eval_xpath('form', id=id) - if not self.browser.isElementPresent(self.locator): + if not self: raise LookupError('No form found at %s' % self.locator) - form = self.browser.getEval( - "this.browserbot.findElement('%s').innerHTML;" % self.locator) + form = self.eval('e.innerHTML') super(Form, self).__init__(resp, '<form>%s</form>' % form) def _parse_fields(self): @@ -795,9 +806,6 @@ class Form(testapp.Form): """Submits the form. If ``name`` is given, then also select that button (using ``index`` to disambiguate)``. - Any extra keyword arguments are passed to the ``.get()`` or - ``.post()`` method. - Returns a :class:`webtest.browser.TestResponse` object. """ if timeout != 0: @@ -946,7 +954,7 @@ def is_available(): return False else: jar = os.environ['SELENIUM_JAR'] - p = subprocess.Popen(['java', '-jar', jar], stdout=sys_stdout) + p = subprocess.Popen(['java', '-jar', jar]) os.environ['SELENIUM_PID'] = str(p.pid) for i in range(30): time.sleep(.3) |
