- 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. - - -