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 sourceCreate 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 ***
LibrarySelenium2Library
LibrarySelenium2Screenshots
Suite TeardownClose all browsers
*** Test Cases ***
Open Plone Awards
Open browserhttp://ploneawards.com
Set window size1024768
Show how to browse
${note} = Add pointy notecss=#carousel a.next.browse
... Click here to browse through the nominees
... position=left
Capture and crop page screenshotchoosing-nominee.png
... css=#carousel ${note}
Remove elements ${note}
Tag a nominee
Page should contain elementxpath=//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
... 60s2s
... Chosen nominee should be visible
Show how to vote
${note} = Add pointy notecss=#chosen-nominee .votebutton
... Click here to vote
... position=bottom
Capture and crop page screenshotvoting-nominee.png
... css=#carousel ${note}
*** Keywords ***
Chosen nominee should be visible
${invisible} = Run keyword and return status
... Element should not be visiblechosen-nominee
Run keyword if ${invisible}
... Click linkcss=#carousel a.next.browse
Wait until element is visiblechosen-nominee1s
Build the documentation:
$ sphinx-build source buildWait 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.pyAnd 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.2Run the buildout:
$ python bootstrap.py
$ bin/buildoutCreate a source directory for you documentation:
$ mkdir sourceCreate 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:
$ bin/sphinx-build source build
P.S. The next Robot Framework release should include our GSOC code to support executing this kind of documentation normally as Robot Framework test suite.