Documentation – a plausible excuse for acceptance testing
Or how to use Sphinx to create user guides with screenshots, which are automatically generated, annotated and kept up-to-date using Robot Framework and Selenium.
I’m sure that this is not the first time when someone proposes to mix documentation with acceptance testing, but this time it should feel different.
Any decent user documentation should include a good amount of screenshots. Unfortunately, good screenshots are pain to make, edit and keep up-to-date…
I’ve been mentoring Vivek Kumar Verma in this years Google Summer of Code to implement a better ReStructureText parser into Robot Framework. A part of his GSOC project was to implement a Sphinx-plugin to execute embedded Robot Framework tests while compiling the documentation.
Now, after a summer of co-operation with me and Vivek around this GSOC topic, I have good news for you all:
How to create a new Sphinx-based documentation with generated screenshots
-
Install package sphinxcontrib-robotframework with docs-extras to get all the required packages for executing Selenium-tests with robotframework-selenium2screenshots-library:
$ pip install 'sphinxcontrib-robotframework[docs]'
-
Create a source directory for you documentation:
$ mkdir source
-
Create a minimal Sphinx-configuration file with our plugin enabled by creating the following
./source/conf.py
:extensions = ['sphinxcontrib_robotframework'] master_doc = 'index'
-
Dump the following example documentation into
./source/index.rst
:How to vote in Plone Innovation Awards? --------------------------------------- Choose your nominee by going to http://ploneawards.com/ and clicking the next button until you find something you like: .. image:: choosing-nominee.png :width: 800 Once you have found your favorite, just click the *vote*-button to tweet your vote: .. image:: voting-nominee.png :width: 800 .. code:: robotframework *** Settings *** Library Selenium2Library Library Selenium2Screenshots Suite Teardown Close all browsers *** Test Cases *** Open Plone Awards Open browser http://ploneawards.com Set window size 1024 768 Show how to browse ${note} = Add pointy note css=#carousel a.next.browse ... Click here to browse through the nominees ... position=left Capture and crop page screenshot choosing-nominee.png ... css=#carousel ${note} Remove elements ${note} Tag a nominee Page should contain element xpath=//a[contains(@href, 'robots')] Assign id to element ... xpath=//a[contains(@href, 'robots')]/ancestor::div[@class='awardinfo'] ... chosen-nominee Choose a Plone Award nominee Wait until keyword succeeds ... 60s 2s ... Chosen nominee should be visible Show how to vote ${note} = Add pointy note css=#chosen-nominee .votebutton ... Click here to vote ... position=bottom Capture and crop page screenshot voting-nominee.png ... css=#carousel ${note} *** Keywords *** Chosen nominee should be visible ${invisible} = Run keyword and return status ... Element should not be visible chosen-nominee Run keyword if ${invisible} ... Click link css=#carousel a.next.browse Wait until element is visible chosen-nominee 1s
-
Build the documentation:
$ sphinx-build source build
-
Wait for a while by watching something like this:
Making output directory... Running Sphinx v1.2b2 loading pickled environment... not yet created No builder selected, using default: html building [html]: targets for 1 source files that are out of date updating environment: 1 added, 0 changed, 0 removed reading sources... [100%] index .../source/index.rst:None: WARNING: image file not readable: choosing-nominee.png .../source/index.rst:None: WARNING: image file not readable: voting-nominee.png looking for now-outdated files... none found pickling environment... done checking consistency... done preparing documents... done ======================================================================== tmpl4e3nU ======================================================================== Open Plone Awards | PASS | ------------------------------------------------------------------------ Show how to browse | PASS | ------------------------------------------------------------------------ Tag a nominee | PASS | ------------------------------------------------------------------------ Choose a Plone Award nominee | PASS | ------------------------------------------------------------------------ Show how to vote | PASS | ------------------------------------------------------------------------ tmpl4e3nU | PASS | 5 critical tests, 5 passed, 0 failed 5 tests total, 5 passed, 0 failed ======================================================================== Output: None writing additional files... genindex search copying images... [100%] choosing-nominee.png copying static files... done copying extra files... dumping search index... done dumping object inventory... done build succeeded, 2 warnings.
-
See the results in
./build/index.html
, just like in this video:
Of course, it would be nice to do the same continuously with a code in development in a sandboxed environment. Luckily, with Plone, that’s trivial with plone.app.robotframework.
Generating screenshots for a Plone add-on
-
As always, we need a
bootstrap.py
:$ curl -O http://downloads.buildout.org/2/bootstrap.py
-
And
buildout.cfg
:[buildout] extends = http://dist.plone.org/release/4.3-latest/versions.cfg versions = versions parts = sphinx-build [sphinx-build] recipe = zc.recipe.egg eggs = Sphinx collective.cover[test] sphinxcontrib-robotframework[docs] plone.app.robotframework scripts = sphinx-build [versions] collective.cover = 1.0a4 selenium = 2.35.0 robotframework-selenium2library = 1.4.0 # These versions are from collective.cover/versions.cfg plone.app.blocks = 1.1.1 plone.app.drafts = 1.0a2 plone.app.jquery = 1.7.2 plone.app.jquerytools = 1.5.5 plone.app.tiles = 1.0.1 plone.tiles = 1.2
-
Run the buildout:
$ python bootstrap.py $ bin/buildout
-
Create a source directory for you documentation:
$ mkdir source
-
Create a minimal Sphinx-configuration with our plugin enabled by creating a file
./source/conf.py
:extensions = ['sphinxcontrib_robotframework'] master_doc = 'index'
-
Add the following
./source/index.rst
:My first cover page =================== This tutorial will show, how to create your first cover page. .. code:: robotframework :class: hidden *** Settings *** Resource plone/app/robotframework/server.robot Library Selenium2Screenshots Suite Setup Setup Plone site with Cover Suite Teardown Run keywords Teardown Plone site Close all browsers *** Keywords *** Setup Plone site with Cover Setup Plone site collective.cover.testing.FUNCTIONAL_TESTING ... plone.app.robotframework.testing.AUTOLOGIN_LIBRARY_FIXTURE Import library Remote ${PLONE_URL}/RobotRemote Enable autologin as Site Administrator Set autologin username test-user-1 Set window size 1024 768 At first, open the *Add new...*-menu and select *Cover*: .. image:: add-menu-cover.png .. code:: robotframework :class: hidden *** Test Cases *** Open the Plone site Go to ${PLONE_URL} Open the Add new menu Click link css=#plone-contentmenu-factories dt a Element should be visible ... css=#plone-contentmenu-factories dd.actionMenuContent Show how to add a new cover ${note1} Add pointy note plone-contentmenu-factories ... Click here to open the menu ... position=top ${note2} Add pointy note collective-cover-content ... Click here to add a new Cover-page ... position=left Capture and crop page screenshot add-menu-cover.png ... css=#plone-contentmenu-factories .actionMenuContent ... ${note1} ${note2} Next, you should see a form like this: .. image:: add-form-cover.png .. code:: robotframework :class: hidden *** Test Cases *** Add a new Cover page Click link collective-cover-content Page should contain element form-widgets-IBasic-title Show how to fill the form Set window size 640 768 ${note1} Add note form-widgets-IBasic-title ... For a front-page, enter the title of your site here ... width=400 ${note2} Add note form-widgets-IBasic-description ... For a front-page, enter the description for your site here ... width=400 ${note3} Add pointy note form-widgets-template_layout ... Select a layout to start with ... position=bottom ${note4} Add note canvas-layout ... A preview of the selected layout will be updated here ${note5} Add pointy note form-buttons-save ... Finally, click save ... position=right Capture and crop page screenshot add-form-cover.png ... content ${note1} ${note2} ${note3} ${note4} ${note 5}
-
Build the documentation:
$ sphinx-build source build
P.S. Robot Framework 2.8.3 should include our GSOC code to support executing this kind of documentation normally as Robot Framework test suite.