[web test] add basic windmill tests and documentation
- connection / deconnection
- user creation
--- a/doc/book/en/tutorials/index.rst Tue Jun 01 17:09:22 2010 +0200
+++ b/doc/book/en/tutorials/index.rst Mon May 31 19:33:43 2010 +0200
@@ -17,3 +17,4 @@
base/index
advanced/index
+ tools/windmill.rst
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/tutorials/tools/windmill.rst Mon May 31 19:33:43 2010 +0200
@@ -0,0 +1,133 @@
+==========================
+Use Windmill with CubicWeb
+==========================
+
+Windmill_ implements cross browser testing, in-browser recording and playback,
+and functionality for fast accurate debugging and test environment integration.
+
+.. _Windmill: http://www.getwindmill.com/
+
+`Online features list <http://www.getwindmill.com/features>`_ is available.
+
+
+Installation
+============
+
+Windmill
+--------
+
+You have to install Windmill manually for now. If you're using Debian, there is
+no binary package (`yet <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=579109>`_).
+
+The simplest solution is to use a *setuptools/pip* command (for a clean
+environment, take a look to the `virtualenv
+<http://pypi.python.org/pypi/virtualenv>`_ project as well)::
+
+ pip install windmill
+ curl -O http://github.com/windmill/windmill/tarball/master
+
+Some install instructions are `available <http://wiki.github.com/windmill/windmill/installing>`_.
+
+Be sure to have the windmill module in your PYTHONPATH afterwards::
+
+ python -c "import windmill"
+
+X dummy
+-------
+
+In order to reduce unecessary system load from your test machines, It's
+recommended to use X dummy server for testing the Unix web clients, you need a
+dummy video X driver (as xserver-xorg-video-dummy package in Debian) coupled
+with a light X server as `Xvfb <http://en.wikipedia.org/wiki/Xvfb>`_.
+
+ The dummy driver is a special driver available with the XFree86 DDX. To use
+ the dummy driver, simply substitue it for your normal card driver in the
+ Device section of your xorg.conf configuration file. For example, if you
+ normally uses an ati driver, then you will have a Device section with
+ Driver "ati" to let the X server know that you want it to load and use the
+ ati driver; however, for these conformance tests, you would change that
+ line to Driver "dummy" and remove any other ati specific options from the
+ Device section.
+
+ *From: http://www.x.org/wiki/XorgTesting*
+
+Then, you can run the X server with the following command :
+
+ /usr/bin/X11/Xvfb :1 -ac -screen 0 1280x1024x8 -fbdir /tmp
+
+
+Windmill usage
+==============
+
+Record your use case
+--------------------
+
+- start your instance manually
+- start Windmill_ with url site as last argument (read Usage_ or use *'-h'*
+ option to find required command line arguments)
+- use the record button
+- click on save to obtain python code of your use case
+- copy the content to a new file in a *windmill* directory
+
+.. _Usage: http://wiki.github.com/windmill/windmill/running-tests
+
+If you are using firefox as client, consider the "firebug" option.
+
+You can refine the test by the *loadtest* windmill option:
+
+ windmill -m firebug loadtest=<test_file.py> <instance url>
+
+
+Integrate Windmill tests into CubicWeb
+======================================
+
+Run your tests
+--------------
+
+You can easily run your windmill test suite through `pytest` or :mod:`unittest`.
+You have to copy a *test_windmill.py* file from :mod:`web.test`.
+
+By default, CubicWeb will use **firefox** as the default browser and will try
+to run test instance server on localhost. In the general case, You've no need
+to change anything.
+
+Check the :class:`cubicweb.devtools.cwwindmill.CubicWebServerTC` class for server
+parameters and :class:`cubicweb.devtools.cwwindmill.CubicWebWindmillUseCase` for
+Windmill configuration.
+
+Best practises
+--------------
+
+Don't run another instance on the same port. You risk to silence some
+regressions (test runner will automatically fail in further versions).
+
+Start your use case by using an assert on the expected primary url page.
+Otherwise all your tests could fail without clear explanation of the used
+navigation.
+
+In the same location of the *test_windmill.py*, create a *windmill/* with your
+windmill recorded use cases.
+
+Then, you can launch the test series with::
+
+ % pytest test/test_windmill.py
+
+For instance, you can start CubicWeb framework use tests by::
+
+ % pytest web/test/test_windmill.py
+
+
+Preferences
+===========
+
+A *.windmill/prefs.py* could be used to redefine default configuration values.
+
+.. define CubicWeb preferences in the parent test case instead with a dedicated firefox profile
+
+For managing browser extensions, read `advanced topic chapter
+<http://wiki.github.com/windmill/windmill/advanced-topics>`_.
+
+More configuration examples could be seen in *windmill/conf/global_settings.py*
+as template.
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/test/test_windmill.py Mon May 31 19:33:43 2010 +0200
@@ -0,0 +1,42 @@
+from cubicweb.devtools import cwwindmill
+
+
+class CubicWebWindmillUseCase(cwwindmill.CubicWebWindmillUseCase):
+ """class for windmill use case tests
+
+ From test server parameters:
+
+ :params ports_range: range of http ports to test (range(7000, 8000) by default)
+ :type ports_range: iterable
+ :param anonymous_logged: is anonymous user logged by default ?
+ :type anonymous_logged: bool
+
+ The first port found as available in `ports_range` will be used to launch
+ the test server
+
+ From Windmill configuration:
+
+ :param browser: browser identification string (firefox|ie|safari|chrome) (firefox by default)
+ :param test_dir: testing file path or directory (./windmill by default)
+ """
+ #ports_range = range(7000, 8000)
+ anonymous_logged = False
+ #browser = 'firefox'
+ #test_dir = osp.join(os.getcwd(), 'windmill')
+
+ # If you prefer, you can put here the use cases recorded by windmill GUI
+ # (services transformer) instead of the windmill sub-directory
+ # You can change `test_dir` as following:
+ #test_dir = __file__
+
+
+from windmill.authoring import WindmillTestClient
+def test_usecase():
+ client = WindmillTestClient(__name__)
+ import pdb; pdb.set_trace()
+ client.open(url=u'/')
+# ...
+
+
+if __name__ == '__main__':
+ cwwindmill.unittest_main()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/test/windmill/test_connexion.py Mon May 31 19:33:43 2010 +0200
@@ -0,0 +1,35 @@
+from cubicweb.devtools import DEFAULT_SOURCES
+LOGIN, PASSWORD = DEFAULT_SOURCES['admin'].values()
+
+# Generated by the windmill services transformer
+from windmill.authoring import WindmillTestClient
+
+
+def test_connect():
+ client = WindmillTestClient(__name__)
+
+ client.open(url=u'/')
+ client.asserts.assertJS(js=u"$('#loginForm').is(':visible')")
+ client.type(text=LOGIN, id=u'__login')
+ client.type(text=PASSWORD, id=u'__password')
+ client.execJS(js=u"$('#loginForm').submit()")
+ client.waits.forPageLoad(timeout=u'20000')
+ client.asserts.assertJS(js=u'$(\'.message\').text() == "welcome %s !"' % LOGIN)
+ client.open(url=u'/logout')
+ client.open(url=u'/')
+ client.asserts.assertJS(js=u"$('#loginForm').is(':visible')")
+
+def test_wrong_connect():
+ client = WindmillTestClient(__name__)
+
+ client.open(url=u'/')
+ # XXX windmill wants to use its proxy internally on 403 :-(
+ #client.asserts.assertJS(js=u"$('#loginForm').is(':visible')")
+ #client.type(text=LOGIN, id=u'__login')
+ #client.type(text=u'novalidpassword', id=u'__password')
+ #client.click(value=u'log in')
+ client.open(url=u'/?__login=user&__password=nopassword')
+ client.waits.forPageLoad(timeout=u'20000')
+ client.asserts.assertTextIn(validator=u'authentication failure', id=u'loginBox')
+ client.open(url=u'/')
+ client.asserts.assertJS(js=u"$('#loginForm').is(':visible')")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/web/test/windmill/test_creation.py Mon May 31 19:33:43 2010 +0200
@@ -0,0 +1,55 @@
+from cubicweb.devtools import DEFAULT_SOURCES
+LOGIN, PASSWORD = DEFAULT_SOURCES['admin'].values()
+
+# Generated by the windmill services transformer
+from windmill.authoring import WindmillTestClient
+
+def test_creation():
+ client = WindmillTestClient(__name__)
+
+ client.open(url=u'/')
+ client.waits.forPageLoad(timeout=u'8000')
+ client.type(text=LOGIN, id=u'__login')
+ client.type(text=PASSWORD, id=u'__password')
+ client.click(value=u'log in')
+ client.waits.forPageLoad(timeout=u'20000')
+
+ # pre-condition
+ client.open(url=u'/cwuser/myuser')
+ client.asserts.assertJS(js=u'$(\'#contentmain h1\').text() == "this resource does not exist"')
+ client.open(url=u'/?rql=Any U WHERE U is CWUser, U login "myuser"')
+ client.asserts.assertJS(js=u'$(\'.searchMessage strong\').text() == "No result matching query"')
+
+ client.open(url=u'/manage')
+ client.open(url=u'/add/CWUser')
+ client.type(text=u'myuser', id=u'login-subject:A')
+ client.type(text=u'myuser', id=u'upassword-subject:A')
+ client.type(text=u'myuser', name=u'upassword-subject-confirm:A')
+ client.type(text=u'myuser', id=u'firstname-subject:A')
+ client.select(val=u'4', id=u'in_group-subject:A')
+ client.waits.forPageLoad(timeout=u'20000')
+ client.click(id=u'adduse_email:Alink')
+ client.waits.forPageLoad(timeout=u'20000')
+ client.type(text=u'myuser@logilab.fr', id=u'address-subject:B')
+ client.waits.forPageLoad(timeout=u'20000')
+ client.click(value=u'button_ok')
+ client.waits.forPageLoad(timeout=u'20000')
+ client.asserts.assertJS(js=u'$(\'.message\').text() == "entity created"')
+ client.open(url=u'/?rql=Any U WHERE U is CWUser, U login "myuser"')
+ client.asserts.assertJS(js=u'$(\'#contentmain h1\').text() == "myuser"')
+ client.waits.forPageLoad(timeout=u'8000')
+ client.open(url=u'/cwuser/myuser?vid=sameetypelist')
+ client.waits.forPageLoad(timeout=u'8000')
+ client.asserts.assertJS(js=u'$(\'#contentmain a\').text() == "myuser"')
+ client.open(url=u'/cwuser/myuser?vid=text')
+ client.waits.forPageLoad(timeout=u'8000')
+ client.asserts.assertJS(js=u'$(\'#contentmain\').text() == "\\nmyuser"')
+ client.open(url=u'/cwuser/myuser?vid=deleteconf')
+ client.waits.forElement(timeout=u'8000', value=u'button_delete')
+ client.click(value=u'button_delete')
+ client.waits.forPageLoad(timeout=u'8000')
+ client.open(url=u'/cwuser/myuser')
+ client.asserts.assertJS(js=u'$(\'#contentmain h1\').text() == "this resource does not exist"')
+ client.open(url=u'/?rql=Any U WHERE U is CWUser, U login "myuser"')
+ client.asserts.assertJS(js=u'$(\'.searchMessage strong\').text() == "No result matching query"')
+