API reference¶
Selenese API¶
General information¶
The Selenese
object available as self.selenium
for each TestCase
provides methods to control the browser, and to make assertions about things
the browser sees.
For a detailed list of commands and assertions please consult the Selenium Reference.
Assertions come in several flavours:
- Return the value
self.selenium.getText('id=foo')
- Assert
self.selenium.assertText('id=foo', 'blabla')
- Negated Assert
self.selenium.assertNotText('id=foo', 'blabla')
- Wait
self.selenium.waitForElementPresent('id=foo')
- Negated Wait
self.selenium.waitForNotElementPresent('id=foo')
Webdriver API¶
Starting with version 2, gocept.selenium also includes integration with Selenium’s webdriver backend, the plan being to keep our own API as backwards-compatible as possible during the 2.x release series and switching to a modernized API only with version 3.
This means that we’ve set out to implement the Selenese API on top of webdriver and while this has proven to be possible to a large extent, some details of the Selenese API don’t make any sense or are too different to be worth implementing in a webdriver environment.
Here’s how to set this up (see Integration for details):
import gocept.httpserverlayer.wsgi
import gocept.selenium
from mypackage import App
http_layer = gocept.httpserverlayer.wsgi.Layer(App())
webdriver_layer = gocept.selenium.WebdriverLayer(
name='WSGILayer', bases=(http_layer,))
test_layer = gocept.selenium.WebdriverSeleneseLayer(
name='WebdriverTestLayer', bases=(webdriver_layer))
class TestWSGITestCase(gocept.selenium.WebdriverSeleneseTestCase):
layer = test_layer
def test_something(self):
self.selenium.open('http://%s/foo.html' % self.selenium.server)
self.selenium.assertBodyText('foo')
Here’s a list of backwards-incompatibilities between using WebdriverSeleneseLayer and the (old) SeleniumRC-backed gocept.selenium.RCLayer:
getEval
behaves differently.getEval
adds areturn
statement in front of the code, i.e. to run Javascript code which is not an expression, userunScript
getEval
has access to different globals now:browserbot
is no longer defined, whilewindow
anddocument
refer directly to the window under test.getEval
returns the dictionary representation of objects instead of the rather uninformative[object Object]
.
- The browser name syntax has changed: specify Firefox as “firefox”, not “firefox*”
(concerns the environment variable for setting the browser, which used to be
GOCEPT_SELENIUM_BROWSER
and isGOCEPT_WEBDRIVER_BROWSER
for webdriver). See the WebDriver wiki for possible browser names.
- With Selenium Remote-Control one had to change the base Firefox profile to be
used on the server side (by passing
-firefoxProfileTemplate
toselenium-server.jar
). With WebDriver this has moved to the client side, so you can select a profile by setting the path to an existing Firefox profile as the environment variableGOCEPT_SELENIUM_FF_PROFILE
. - Selenese methods that don’t work yet:
highlight
getSpeed
setSpeed
getAllWindowNames
getAllWindowTitles
selectPopUp
deselectPopUp
- Selenese methods with changed behaviour:
open
: dropped theignoreResponseCode
parameterassertOrdered
only works with relative xpath locators, not with any element locators anymore.
- Selenese methods that have been removed and are not coming back:
addCustomRequestHeader
addLocationStrategy
addScript
allowNativeXpath
answerOnNextPrompt
assignId
captureNetworkTraffic
chooseCancelOnNextConfirmation
chooseOkOnNextConfirmation
fireEvent
focus
getMouseSpeed
getTable
ignoreAttributesWithoutValue
removeScript
retrieveLastRemoteControlLogs
setBrowserLogLevel
setContext
setCursorPosition
setMouseSpeed
useXpathLibrary
waitForFrameToLoad
- Locator patterns that can no longer be used:
- option: id
- frame: relative, dom
On the other hand, here are some new features that only WebdriverSeleneseLayer offers:
- Locator
js
(ordom
or anything that starts withdocument
): Find an element by evaluating a javascript expression. Example:getText('js=document.getElementsByClassName("foo")')
- Convenience locator
jquery
(when your site already loadsjQuery
). Example:getText('jquery=.foo')
(this is the equivalent ofgetText('js=window.jQuery(".foo")[0]')
)
Test helpers¶
assertScreenshot¶
Note
assertScreenshot
needs PIL. You might consider to require the
screenshot extra in your setup.py like so:
gocept.selenium[screenshot]
The assertScreenshot
method allows you to validate the rendering of a HTML
element in the browser. A screenshot of the element is saved in a given
directory and in your test assertScreenshot
takes a picture of the
currently rendered element and compares it with the one saved in disk. The test
will fail, if the screenshot and the taken picture do not match (within a given
threshold).
assertScreenshot
takes the following arguments:
name: | A name for the screenshot (which will be appended with .png). |
---|---|
locator: | A locator to the element, which will be captured. |
threshold: | If the difference [2] in percent between the saved and current image is greater than the threshold, a failure is triggered. (defaults to 1) |
There is a capture mode available to help you in retrieving your master
screenshot (which will be left on disk for comparison). When writing your test,
set capture_screenshot
on the Selenese object (see
General information) to True
and the test run will save the
screenshot to disk instead of comparing it. Before you check in your newly
created screenshot, you should watch it to make sure, it looks like you
expected it. Setting capture_screenshot
to False
will compare the
screenshot on disk with a newly created temporary image during the next test
run.
If assertScreenshot
fails, paths to the following images are provided to
you in the error message:
original: | The path to the original image (the master image). |
---|---|
current: | The path to the image taken in the current test run (from the browser). |
diff: | The path to an image highlighting the differences between original and current. |
If you would like to open the image showing the differences in an image viewer,
set the environment variable SHOW_DIFF_IMG
before running the test.
Skipping tests for certain browsers¶
There are cases when a test should does not pass on certain browsers. This is
either due to the application using browser features which are not supported by
the browser, or due to selenium not working well with the browser. To aid in
skipping tests in these cases, there is a test decorator
gocept.selenium.skipUnlessBrowser(name, version=None)
:
>>> class TestClass(...):
...
... @gocept.selenium.skipUnlessBrowser('Firefox', '>=16.0')
... def test_fancy_things(self):
... ...
Note
skipUnlessBrowser
only supports skipping test methods. It cannot
be used as class decorator.
Warning
The version test is only supported for Python >= 2.5. For Python < 2.5 only a name check can be performed. Giving a version number will skip the test unconditionally.
[2] | The difference is computed as normalised root mean square deviation of the two images. |