- SimpleTest's web browser component can be used not just - outside of the WebTestCase class, but also - independently of the SimpleTest framework itself. -
- - -- You can use the web browser in PHP scripts to confirm - services are up and running, or to extract information - from them at a regular basis. - For example, here is a small script to extract the current number of - open PHP 5 bugs from the PHP web site... -
-<?php
- require_once('simpletest/browser.php');
-
- $browser = &new SimpleBrowser();
- $browser->get('http://php.net/');
- $browser->clickLink('reporting bugs');
- $browser->clickLink('statistics');
- $page = $browser->clickLink('PHP 5 bugs only');
- preg_match('/status=Open.*?by=Any.*?(\d+)<\/a>/', $page, $matches);
- print $matches[1];
-?>
-
- There are simpler methods to do this particular example in PHP
- of course.
- For example you can just use the PHP file()
- command against what here is a pretty fixed page.
- However, using the web browser for scripts allows authentication,
- correct handling of cookies, automatic loading of frames, redirects,
- form submission and the ability to examine the page headers.
- Such methods are fragile against a site that is constantly
- evolving and you would want a more direct way of accessing
- data in a permanent set up, but for simple tasks this can provide
- a very rapid solution.
-
- - All of the navigation methods used in the - WebTestCase - are present in the SimpleBrowser class, but - the assertions are replaced with simpler accessors. - Here is a full list of the page navigation methods... -
| addHeader($header) | Adds a header to every fetch | -
| useProxy($proxy, $username, $password) | Use this proxy from now on | -
| head($url, $parameters) | Perform a HEAD request | -
| get($url, $parameters) | Fetch a page with GET | -
| post($url, $parameters) | Fetch a page with POST | -
| clickLink($label) | Follows a link by label | -
| isLink($label) | See if a link is present by label | -
| clickLinkById($id) | Follows a link by attribute | -
| isLinkById($id) | See if a link is present by attribut | -
| getUrl() | Current URL of page or frame | -
| getTitle() | Page title | -
| getContent() | Raw page or frame | -
| getContentAsText() | HTML removed except for alt text | -
| retry() | Repeat the last request | -
| back() | Use the browser back button | -
| forward() | Use the browser forward button | -
| authenticate($username, $password) | Retry page or frame after a 401 response | -
| restart($date) | Restarts the browser for a new session | -
| ageCookies($interval) | Ages the cookies by the specified time | -
| setCookie($name, $value) | Sets an additional cookie | -
| getCookieValue($host, $path, $name) | Reads the most specific cookie | -
| getCurrentCookieValue($name) | Reads cookie for the current context | -
- Navigating forms is similar to the - WebTestCase form navigation... -
| setField($name, $value) | Sets all form fields with that name | -
| setFieldById($id, $value) | Sets all form fields with that id | -
| getField($name) | Accessor for a form element value | -
| getFieldById($id) | Accessor for a form element value | -
| clickSubmit($label) | Submits form by button label | -
| clickSubmitByName($name) | Submits form by button attribute | -
| clickSubmitById($id) | Submits form by button attribute | -
| clickImage($label, $x, $y) | Clicks the image by alt text | -
| clickImageByName($name, $x, $y) | Clicks the image by attribute | -
| clickImageById($id, $x, $y) | Clicks the image by attribute | -
| submitFormById($id) | Submits by the form tag attribute | -
- Within a page, individual frames can be selected. - If no selection is made then all the frames are merged together - in one large conceptual page. - The content of the current page will be a concatenation of all of the - frames in the order that they were specified in the "frameset" - tags. -
| getFrames() | A dump of the current frame structure | -
| getFrameFocus() | Current frame label or index | -
| setFrameFocusByIndex($choice) | Select a frame numbered from 1 | -
| setFrameFocus($name) | Select frame by label | -
| clearFrameFocus() | Treat all the frames as a single page | -
- All of this functionality is great when we actually manage to fetch pages, - but that doesn't always happen. - To help figure out what went wrong, the browser has some methods to - aid in debugging... -
| setConnectionTimeout($timeout) | Close the socket on overrun | -
| getRequest() | Raw request header of page or frame | -
| getHeaders() | Raw response header of page or frame | -
| getTransportError() | Any socket level errors in the last fetch | -
| getResponseCode() | HTTP response of page or frame | -
| getMimeType() | Mime type of page or frame | -
| getAuthentication() | Authentication type in 401 challenge header | -
| getRealm() | Authentication realm in 401 challenge header | -
| setMaximumRedirects($max) | Number of redirects before page is loaded anyway | -
| setMaximumNestedFrames($max) | Protection against recursive framesets | -
| ignoreFrames() | Disables frames support | -
| useFrames() | Enables frames support | -
-
-Complex unit tests with multiple browsers
-
-
- Anything that could be done in a - WebTestCase can - now be done in a UnitTestCase. - This means that we can freely mix domain object testing with the - web interface... -
-
-class TestOfRegistration extends UnitTestCase {
- function testNewUserAddedToAuthenticator() {
- $browser = &new SimpleBrowser();
- $browser->get('http://my-site.com/register.php');
- $browser->setField('email', 'me@here');
- $browser->setField('password', 'Secret');
- $browser->clickSubmit('Register');
-
- $authenticator = &new Authenticator();
- $member = &$authenticator->findByEmail('me@here');
- $this->assertEqual($member->getPassword(), 'Secret');
- }
-}
-
- While this may be a useful temporary expediency, I am not a fan
- of this type of testing.
- The testing has cut across application layers, make it twice as
- likely it will need refactoring when the code changes.
-
- - A more useful case of where using the browser directly can be helpful - is where the WebTestCase cannot cope. - An example is where two browsers are needed at the same time. -
-- For example, say we want to disallow multiple simultaneous - usage of a site with the same username. - This test case will do the job... -
-class TestOfSecurity extends UnitTestCase {
- function testNoMultipleLoginsFromSameUser() {
- $first = &new SimpleBrowser();
- $first->get('http://my-site.com/login.php');
- $first->setField('name', 'Me');
- $first->setField('password', 'Secret');
- $first->clickSubmit('Enter');
- $this->assertEqual($first->getTitle(), 'Welcome');
-
- $second = &new SimpleBrowser();
- $second->get('http://my-site.com/login.php');
- $second->setField('name', 'Me');
- $second->setField('password', 'Secret');
- $second->clickSubmit('Enter');
- $this->assertEqual($second->getTitle(), 'Access Denied');
- }
-}
-
- You can also use the SimpleBrowser class
- directly when you want to write test cases using a different
- test tool than SimpleTest.
-
-
-