-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
196 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
================ | ||
The Test Browser | ||
================ | ||
|
||
The ``zope.app.testing.testbrowser`` module exposes a ``Browser`` class that | ||
simulates a web browser similar to Mozilla Firefox or IE. | ||
|
||
>>> from zope.app.testing.testbrowser import Browser | ||
>>> browser = Browser() | ||
>>> browser.addHeader('Authorization', 'Basic mgr:mgrpw') | ||
|
||
The browser can `open` web pages: | ||
|
||
>>> browser.open('http://localhost/++etc++site/default') | ||
>>> browser.url | ||
'http://localhost/++etc++site/default' | ||
|
||
|
||
Page Contents | ||
------------- | ||
|
||
The contents of the current page are available: | ||
|
||
>>> print browser.contents | ||
<... | ||
<html...> | ||
<body...> | ||
... | ||
|
||
Making assertions about page contents are easy. | ||
|
||
>>> '<a href="RootErrorReportingUtility">' in browser.contents | ||
True | ||
|
||
|
||
Headers | ||
------- | ||
|
||
The page's headers are also available as an httplib.HTTPMessage instance: | ||
|
||
>>> browser.headers | ||
<httplib.HTTPMessage instance...> | ||
|
||
The headers can be accesed as a string: | ||
|
||
>>> print browser.headers | ||
Status: 200 Ok | ||
Content-Length: ... | ||
Content-Type: text/html;charset=utf-8 | ||
X-Powered-By: Zope (www.zope.org), Python (www.python.org) | ||
|
||
Or as a mapping: | ||
|
||
>>> browser.headers['content-type'] | ||
'text/html;charset=utf-8' | ||
|
||
|
||
Navigation | ||
---------- | ||
|
||
If you want to simulate clicking on a link, there is a `click` method. | ||
|
||
>>> browser.click('RootErrorReportingUtility') | ||
>>> browser.url | ||
'http://localhost/++etc++site/default/RootErrorReportingUtility' | ||
|
||
We'll navigate to a form and fill in some values and the submit the form. | ||
|
||
>>> browser.click('Configure') | ||
>>> browser.url | ||
'http://localhost/++etc++site/default/RootErrorReportingUtility/@@configure.html' | ||
|
||
|
||
Forms | ||
----- | ||
|
||
The current page has a form on it, let's look at some of the controls: | ||
|
||
>>> browser.controls['keep_entries'] | ||
'20' | ||
>>> browser.controls['copy_to_zlog'] | ||
False | ||
|
||
If we request a control that doesn't exist, an exception is raised. | ||
|
||
>>> browser.controls['does_not_exist'] | ||
Traceback (most recent call last): | ||
... | ||
KeyError: 'does_not_exist' | ||
|
||
We want to change some of the form values and submit. | ||
|
||
>>> browser.controls['keep_entries'] = '40' | ||
>>> browser.controls['copy_to_zlog'] = True | ||
>>> browser.click('Save Changes') | ||
|
||
Are our changes reflected on the resulting page? | ||
|
||
>>> browser.controls['keep_entries'] | ||
'40' | ||
>>> browser.controls['copy_to_zlog'] | ||
True | ||
|
||
The `controls` object also has an `update()` method similar to that of | ||
a dictionary: | ||
|
||
>>> browser.controls.update(dict(keep_entries='30', copy_to_zlog=False)) | ||
>>> browser.click('Save Changes') | ||
>>> browser.controls['keep_entries'] | ||
'30' | ||
>>> browser.controls['copy_to_zlog'] | ||
False | ||
|
||
Finding Specific Forms | ||
---------------------- | ||
|
||
Because pages can have multiple forms with like-named controls, it is sometimes | ||
neccesary to access forms by name or id. The browser's `forms` attribute can | ||
be used to do so. The key value is the form's name or id. If more than one | ||
form has the same name or id, the first one will be returned. | ||
|
||
XXX these need to be re-targeted to pages registered just for this test | ||
## >>> # zope form and use that instead | ||
## >>> form = browser.forms['portlet_form'] | ||
|
||
The form exposes several attributes: | ||
|
||
## >>> form.name | ||
## 'portlet_form' | ||
## >>> form.action | ||
## 'http://localhost/++etc++site/default/...' | ||
## >>> form.method | ||
## 'POST' | ||
## >>> form.id is None | ||
## True | ||
|
||
The form's controls can also be accessed with the `controls` mapping. | ||
|
||
## >>> form.controls['portlet_action'] | ||
## '...' | ||
|
||
More Forms | ||
---------- | ||
|
||
Now, let's navegate to a page with a slightly more complex form. | ||
|
||
>>> browser.click('Registration') | ||
>>> browser.click('Advanced Options') | ||
>>> browser.click('UtilityRegistration') | ||
|
||
Is the expected control on the page? | ||
|
||
>>> 'field.permission' in browser.controls | ||
True | ||
|
||
Good, let's retrieve it then: | ||
|
||
>>> permission = browser.getControl('field.permission') | ||
|
||
What kind of control is it? | ||
|
||
>>> permission.type | ||
'select' | ||
|
||
Is it a single- or multi-select? | ||
|
||
>>> permission.multiple | ||
False | ||
|
||
What options are available for the "field.permission" control? | ||
|
||
>>> permission.options | ||
['', 'zope.Public', ... 'zope.ManageContent', ... 'zope.View', ...] | ||
|
||
|
||
We'll store the current setting so we can set it back later. | ||
|
||
>>> original_permission = permission.value | ||
|
||
Let's set one of the options and submit the form. | ||
|
||
>>> permission.value = ['zope.Public'] | ||
>>> browser.click('Change') | ||
|
||
Ok, did our change take effect? (Note that the order may not be preserved for | ||
multi-selects.) | ||
|
||
>>> browser.controls['field.permission'] == ['zope.Public'] | ||
True | ||
|
||
Let's set it back, so we don't mess anything up. | ||
|
||
>>> permission.value = original_permission | ||
>>> browser.click('Change') | ||
|
||
|