Pretty much what it says on the box - adds a Sphinx directive, to take screen shots of HTML pages from Selenium
Caveat: You need to have PhantomJS installed for this to work, which means for now this won't work on readthedocs (unless we can convince them to install it when building documentation). You can get around that by building the images locally, and checking them into wherever your documentation is.
Install
sphinx
andsphinx-selenium-screenshots
Add
selenium_screenshots.screener
to the extensions in your configuration file:extensions = [ # ... , 'selenium_screenshots.screener', # ... , ]
Add the configuration parameters:
screenshots_server_path = 'http://127.0.0.1:8080' screenshots_read_path = '/_static/screenshots' screenshots_save_path = os.path.abspath(os.path.join('.',screenshots_read_path[1:]))
Insert screenshots into your documentation with the
screenshot
directive:.. screenshot:: :server_path: /path/to/a/file.html :alt: Here is how your page looks.
The screenshot
directive is a subclass of the built-in Image directive, so any parameters that work on that
also work on screenshot
.
This is the basic directive:
.. screenshot:: :server_path: /path/to/a/file.html
By default, screenshot
gives each page load a generated filename, however if you want to
reuse the generated file you can add a filename as the first (and only) argument like so:
.. screenshot:: my_file.jpg :server_path: /path/to/a/file.html
And reuse it by loading it from screenshots_read_path
..image:: /_static/screenshots/my_file.jpg
Crop to a section by passing a pair of tuples in a list with opposite corners of the bounding box to the crop
parameter:
.. screenshot:: :server_path: /path/to/a/file.html :crop: [(0,0),(100,100)]
You can pass any valid css selector to the crop_element
parameter to capture just a particular element:
.. screenshot:: :server_path: /path/to/a/file.html :alt: The login button :crop_element: a[href^=/login/]
By default a padding of 50px on all edges, this padding can be changed with crop_element_padding
.
This argument can be 1, 2 or 4 entries long, as a python array, where:
- 1 element sets the padding for all edges uniformly in pixels - eg.
[60]
sets all edges to 60px of padding - 2 entries sets the padding for top and bottom, and left and right respectively - eg.
[20, 40]
sets the topp and bottom padding to 20px, and left and right to 40px. - 4 entries sets the padding as top, right, bottom and left (i.e clockwise from the top) - eg.
[10, 20, 30, 40]
set the top padding to 10px, right to 20px, bottom to 30px and left to 40px
For example:
.. screenshot:: :server_path: /path/to/a/file.html :alt: The login button :crop_element: a[href^=/login/] :crop_element_padding: [50, 50]
To login quickly, you can use the login
parameter. The screen shot will be taken after the user has logged in.
The login
parameter takes a dictionary with 3 arguments:
url
- the url the login page is atusername
- the user name of the user to login aspassword
- the password for the user -- Note: Do not use the password of an actual account, this is stored in plain text.
This works, as long as the login page has two form elements with the HTML form names username
and password
:
.. screenshot:: :server_path: /path/to/a/file.html :login: {'url': '/login', "username": "vicky", "password": "Viewer"}
Just pass the url of the logout page as the logout
directive to log out after the screen shot is taken:
.. screenshot:: :server_path: /path/to/a/file.html :login: {'url': '/login', "username": "vicky", "password": "Viewer"} :logout: {'url': '/logout'}
Use the form_data
parameter to show the actions of filling in a form before taking a screenshot.
The form_data
parameter takes an array of dictionaries that describe which fields in a form to fill in.
This works on all field types, including <input>
, <textarea>
and <select>
elements.
This example expects a form with name
and address
inputs available:
.. screenshot:: :server_path: /path/to/a/file.html :form_data: [ {'name': 'John Citizen', 'address': '123 Fake St'}, ]
Just add the __submit__
key and set it to False, like so:
.. screenshot:: :server_path: /path/to/a/file.html :form_data: [ {'name': 'John Citizen', 'address': '123 Fake St', '__submit__': False}, ]
Now we can see what the page looks like before the form is submitted.
Adding multiple dictionaries in the list given as the form_data
parameter will cause the browser
to attempt to pass each form and submit it. This is useful when showing transitions or end states for form wizards:
.. screenshot:: :server_path: /path/to/a/file.html :form_data: [ {'name': 'John Citizen', 'address': '123 Fake St'}, {'date_of_birth': '01/01/1970',}, {'eye_colour': 'Blue'}, ]
The ``screenshot``directive just directly captures whats happening on the virtual browser screen, so page loads aren't necessary when capturing different parts of the same page. This can speed up the build time, as pages don't have to be reloaded and rerendered.
To prevent a page reloading, just leave off the server_path
directive. This example submits the same forms as
above, but captures a screenshot when the first page loads and after submitting each successive form:
.. screenshot:: :server_path: /some/form/to/submit.html .. screenshot:: :form_data: [ {'name': 'John Citizen', 'address': '123 Fake St'}, ] .. screenshot:: :form_data: [ {'date_of_birth': '01/01/1970',}, ]
There are two ways to highlight page elements, boxes and clickers which can be used in the same screenshot.
A clicker is an icon that shows where a user would want to click on a regular interface.
The default (and currently only) style is a transparent yellow circle in the center of the HTML element.
It can be called with the clicker
parameter which accepts a css selector and only hightlights the first matching element found:
.. screenshot:: :server_path: /some/page.html :clicker: #element_of_interest
Alternatively, you can insert a hightlighting box to bring attention to an element of interest.
The default (and currently only) style is a red rectangle around the HTML element.
It can be called with the box
parameter which accepts a css selector and only hightlights the first matching element found:
.. screenshot:: :server_path: /some/page.html :box: #element_of_interest
Everything after the parameters is interpreted as python code run by the screenshot directive, before the screenshot is taken. This makes for a very powerful but also very dangerous tool for capturing screenshots.
Variables available in this scope are:
browser
the selenium browser at that point in time.
This is especially useful when there is additional javascript that is loaded that changes the user interface. For example, CKEditor will update parts of the user interface after page load to insert its WYSIWYG editor. An example of how to cause the delay is:
.. screenshot:: :server_path: /a/page/with/slow/javascript.html import time time.sleep(2)
Do this by accessing the local browser element:
.. screenshot:: :server_path: /path/to/a/file.html browser.find_element_by_css_selector('a#some_button').click()
All documents start with a fresh virtual browser, but tTo reduce running time, the selenium browser in the background
keeps sessions logged in (or out) when processing a document.
This can mean that if you need to access a page with an anonymous user, you need to make sure to logout
in the previous screenshot.