source: spip-zone/_plugins_/_stable_/simpletest/simpletest/web_tester.php @ 24737

Last change on this file since 24737 was 24737, checked in by marcimat@…, 12 years ago

Plugin pour des tests unitaires avec SPIP utilisant les librairies SimpleTest? (version 1.0.1).

L'api de simpleTest est enrichie pour proposer des tests spécifiques utilisant les fonctions de SPIP. La documentation sur Contrib va suivre.

Une remarque importante : pour que les tests fonctionnent, il ne PEUT pas y avoir le lien symbolique sur les répertoires plugins ou de simpleTests

Le répertoire tests/ (qui contient les premiers tests unitaires dans un format qui n'est pas simpleTest) peut être ajouté à la racine du site, les tests SimpleTests? se lanceront dedans correctement si ce plugin est activé.

File size: 53.5 KB
Line 
1<?php
2/**
3 *  Base include file for SimpleTest.
4 *  @package    SimpleTest
5 *  @subpackage WebTester
6 *  @version    $Id: web_tester.php 1723 2008-04-08 00:34:10Z lastcraft $
7 */
8
9/**#@+
10 *  include other SimpleTest class files
11 */
12require_once(dirname(__FILE__) . '/test_case.php');
13require_once(dirname(__FILE__) . '/browser.php');
14require_once(dirname(__FILE__) . '/page.php');
15require_once(dirname(__FILE__) . '/expectation.php');
16/**#@-*/
17
18/**
19 *    Test for an HTML widget value match.
20 *    @package SimpleTest
21 *    @subpackage WebTester
22 */
23class FieldExpectation extends SimpleExpectation {
24    var $_value;
25   
26    /**
27     *    Sets the field value to compare against.
28     *    @param mixed $value     Test value to match. Can be an
29     *                            expectation for say pattern matching.
30     *    @param string $message  Optiona message override. Can use %s as
31     *                            a placeholder for the original message.
32     *    @access public
33     */
34    function FieldExpectation($value, $message = '%s') {
35        $this->SimpleExpectation($message);
36        if (is_array($value)) {
37            sort($value);
38        }
39        $this->_value = $value;
40    }
41   
42    /**
43     *    Tests the expectation. True if it matches
44     *    a string value or an array value in any order.
45     *    @param mixed $compare        Comparison value. False for
46     *                                 an unset field.
47     *    @return boolean              True if correct.
48     *    @access public
49     */
50    function test($compare) {
51        if ($this->_value === false) {
52            return ($compare === false);
53        }
54        if ($this->_isSingle($this->_value)) {
55            return $this->_testSingle($compare);
56        }
57        if (is_array($this->_value)) {
58            return $this->_testMultiple($compare);
59        }
60        return false;
61    }
62   
63    /**
64     *    Tests for valid field comparisons with a single option.
65     *    @param mixed $value       Value to type check.
66     *    @return boolean           True if integer, string or float.
67     *    @access private
68     */
69    function _isSingle($value) {
70        return is_string($value) || is_integer($value) || is_float($value);
71    }
72   
73    /**
74     *    String comparison for simple field with a single option.
75     *    @param mixed $compare    String to test against.
76     *    @returns boolean         True if matching.
77     *    @access private
78     */
79    function _testSingle($compare) {
80        if (is_array($compare) && count($compare) == 1) {
81            $compare = $compare[0];
82        }
83        if (! $this->_isSingle($compare)) {
84            return false;
85        }
86        return ($this->_value == $compare);
87    }
88   
89    /**
90     *    List comparison for multivalue field.
91     *    @param mixed $compare    List in any order to test against.
92     *    @returns boolean         True if matching.
93     *    @access private
94     */
95    function _testMultiple($compare) {
96        if (is_string($compare)) {
97            $compare = array($compare);
98        }
99        if (! is_array($compare)) {
100            return false;
101        }
102        sort($compare);
103        return ($this->_value === $compare);
104    }
105   
106    /**
107     *    Returns a human readable test message.
108     *    @param mixed $compare      Comparison value.
109     *    @return string             Description of success
110     *                               or failure.
111     *    @access public
112     */
113    function testMessage($compare) {
114        $dumper = &$this->_getDumper();
115        if (is_array($compare)) {
116            sort($compare);
117        }
118        if ($this->test($compare)) {
119            return "Field expectation [" . $dumper->describeValue($this->_value) . "]";
120        } else {
121            return "Field expectation [" . $dumper->describeValue($this->_value) .
122                    "] fails with [" .
123                    $dumper->describeValue($compare) . "] " .
124                    $dumper->describeDifference($this->_value, $compare);
125        }
126    }
127}
128
129/**
130 *    Test for a specific HTTP header within a header block.
131 *    @package SimpleTest
132 *    @subpackage WebTester
133 */
134class HttpHeaderExpectation extends SimpleExpectation {
135    var $_expected_header;
136    var $_expected_value;
137   
138    /**
139     *    Sets the field and value to compare against.
140     *    @param string $header   Case insenstive trimmed header name.
141     *    @param mixed $value     Optional value to compare. If not
142     *                            given then any value will match. If
143     *                            an expectation object then that will
144     *                            be used instead.
145     *    @param string $message  Optiona message override. Can use %s as
146     *                            a placeholder for the original message.
147     */
148    function HttpHeaderExpectation($header, $value = false, $message = '%s') {
149        $this->SimpleExpectation($message);
150        $this->_expected_header = $this->_normaliseHeader($header);
151        $this->_expected_value = $value;
152    }
153   
154    /**
155     *    Accessor for aggregated object.
156     *    @return mixed        Expectation set in constructor.
157     *    @access protected
158     */
159    function _getExpectation() {
160        return $this->_expected_value;
161    }
162   
163    /**
164     *    Removes whitespace at ends and case variations.
165     *    @param string $header    Name of header.
166     *    @param string            Trimmed and lowecased header
167     *                             name.
168     *    @access private
169     */
170    function _normaliseHeader($header) {
171        return strtolower(trim($header));
172    }
173   
174    /**
175     *    Tests the expectation. True if it matches
176     *    a string value or an array value in any order.
177     *    @param mixed $compare   Raw header block to search.
178     *    @return boolean         True if header present.
179     *    @access public
180     */
181    function test($compare) {
182        return is_string($this->_findHeader($compare));
183    }
184   
185    /**
186     *    Searches the incoming result. Will extract the matching
187     *    line as text.
188     *    @param mixed $compare   Raw header block to search.
189     *    @return string          Matching header line.
190     *    @access protected
191     */
192    function _findHeader($compare) {
193        $lines = split("\r\n", $compare);
194        foreach ($lines as $line) {
195            if ($this->_testHeaderLine($line)) {
196                return $line;
197            }
198        }
199        return false;
200    }
201   
202    /**
203     *    Compares a single header line against the expectation.
204     *    @param string $line      A single line to compare.
205     *    @return boolean          True if matched.
206     *    @access private
207     */
208    function _testHeaderLine($line) {
209        if (count($parsed = split(':', $line, 2)) < 2) {
210            return false;
211        }
212        list($header, $value) = $parsed;
213        if ($this->_normaliseHeader($header) != $this->_expected_header) {
214            return false;
215        }
216        return $this->_testHeaderValue($value, $this->_expected_value);
217    }
218   
219    /**
220     *    Tests the value part of the header.
221     *    @param string $value        Value to test.
222     *    @param mixed $expected      Value to test against.
223     *    @return boolean             True if matched.
224     *    @access protected
225     */
226    function _testHeaderValue($value, $expected) {
227        if ($expected === false) {
228            return true;
229        }
230        if (SimpleExpectation::isExpectation($expected)) {
231            return $expected->test(trim($value));
232        }
233        return (trim($value) == trim($expected));
234    }
235   
236    /**
237     *    Returns a human readable test message.
238     *    @param mixed $compare      Raw header block to search.
239     *    @return string             Description of success
240     *                               or failure.
241     *    @access public
242     */
243    function testMessage($compare) {
244        if (SimpleExpectation::isExpectation($this->_expected_value)) {
245            $message = $this->_expected_value->overlayMessage($compare, $this->_getDumper());
246        } else {
247            $message = $this->_expected_header .
248                    ($this->_expected_value ? ': ' . $this->_expected_value : '');
249        }
250        if (is_string($line = $this->_findHeader($compare))) {
251            return "Searching for header [$message] found [$line]";
252        } else {
253            return "Failed to find header [$message]";
254        }
255    }
256}
257   
258/**
259 *    Test for a specific HTTP header within a header block that
260 *    should not be found.
261 *    @package SimpleTest
262 *    @subpackage WebTester
263 */
264class NoHttpHeaderExpectation extends HttpHeaderExpectation {
265    var $_expected_header;
266    var $_expected_value;
267   
268    /**
269     *    Sets the field and value to compare against.
270     *    @param string $unwanted   Case insenstive trimmed header name.
271     *    @param string $message    Optiona message override. Can use %s as
272     *                              a placeholder for the original message.
273     */
274    function NoHttpHeaderExpectation($unwanted, $message = '%s') {
275        $this->HttpHeaderExpectation($unwanted, false, $message);
276    }
277   
278    /**
279     *    Tests that the unwanted header is not found.
280     *    @param mixed $compare   Raw header block to search.
281     *    @return boolean         True if header present.
282     *    @access public
283     */
284    function test($compare) {
285        return ($this->_findHeader($compare) === false);
286    }
287   
288    /**
289     *    Returns a human readable test message.
290     *    @param mixed $compare      Raw header block to search.
291     *    @return string             Description of success
292     *                               or failure.
293     *    @access public
294     */
295    function testMessage($compare) {
296        $expectation = $this->_getExpectation();
297        if (is_string($line = $this->_findHeader($compare))) {
298            return "Found unwanted header [$expectation] with [$line]";
299        } else {
300            return "Did not find unwanted header [$expectation]";
301        }
302    }
303}
304
305/**
306 *    Test for a text substring.
307 *    @package SimpleTest
308 *    @subpackage UnitTester
309 */
310class TextExpectation extends SimpleExpectation {
311    var $_substring;
312   
313    /**
314     *    Sets the value to compare against.
315     *    @param string $substring  Text to search for.
316     *    @param string $message    Customised message on failure.
317     *    @access public
318     */
319    function TextExpectation($substring, $message = '%s') {
320        $this->SimpleExpectation($message);
321        $this->_substring = $substring;
322    }
323   
324    /**
325     *    Accessor for the substring.
326     *    @return string       Text to match.
327     *    @access protected
328     */
329    function _getSubstring() {
330        return $this->_substring;
331    }
332   
333    /**
334     *    Tests the expectation. True if the text contains the
335     *    substring.
336     *    @param string $compare        Comparison value.
337     *    @return boolean               True if correct.
338     *    @access public
339     */
340    function test($compare) {
341        return (strpos($compare, $this->_substring) !== false);
342    }
343   
344    /**
345     *    Returns a human readable test message.
346     *    @param mixed $compare      Comparison value.
347     *    @return string             Description of success
348     *                               or failure.
349     *    @access public
350     */
351    function testMessage($compare) {
352        if ($this->test($compare)) {
353            return $this->_describeTextMatch($this->_getSubstring(), $compare);
354        } else {
355            $dumper = &$this->_getDumper();
356            return "Text [" . $this->_getSubstring() .
357                    "] not detected in [" .
358                    $dumper->describeValue($compare) . "]";
359        }
360    }
361   
362    /**
363     *    Describes a pattern match including the string
364     *    found and it's position.
365     *    @param string $substring      Text to search for.
366     *    @param string $subject        Subject to search.
367     *    @access protected
368     */
369    function _describeTextMatch($substring, $subject) {
370        $position = strpos($subject, $substring);
371        $dumper = &$this->_getDumper();
372        return "Text [$substring] detected at character [$position] in [" .
373                $dumper->describeValue($subject) . "] in region [" .
374                $dumper->clipString($subject, 100, $position) . "]";
375    }
376}
377
378/**
379 *    Fail if a substring is detected within the
380 *    comparison text.
381 *    @package SimpleTest
382 *    @subpackage UnitTester
383 */
384class NoTextExpectation extends TextExpectation {
385   
386    /**
387     *    Sets the reject pattern
388     *    @param string $substring  Text to search for.
389     *    @param string $message    Customised message on failure.
390     *    @access public
391     */
392    function NoTextExpectation($substring, $message = '%s') {
393        $this->TextExpectation($substring, $message);
394    }
395   
396    /**
397     *    Tests the expectation. False if the substring appears
398     *    in the text.
399     *    @param string $compare        Comparison value.
400     *    @return boolean               True if correct.
401     *    @access public
402     */
403    function test($compare) {
404        return ! parent::test($compare);
405    }
406   
407    /**
408     *    Returns a human readable test message.
409     *    @param string $compare      Comparison value.
410     *    @return string              Description of success
411     *                                or failure.
412     *    @access public
413     */
414    function testMessage($compare) {
415        if ($this->test($compare)) {
416            $dumper = &$this->_getDumper();
417            return "Text [" . $this->_getSubstring() .
418                    "] not detected in [" .
419                    $dumper->describeValue($compare) . "]";
420        } else {
421            return $this->_describeTextMatch($this->_getSubstring(), $compare);
422        }
423    }
424}
425
426/**
427 *    Test case for testing of web pages. Allows
428 *    fetching of pages, parsing of HTML and
429 *    submitting forms.
430 *    @package SimpleTest
431 *    @subpackage WebTester
432 */
433class WebTestCase extends SimpleTestCase {
434    var $_browser;
435    var $_ignore_errors = false;
436   
437    /**
438     *    Creates an empty test case. Should be subclassed
439     *    with test methods for a functional test case.
440     *    @param string $label     Name of test case. Will use
441     *                             the class name if none specified.
442     *    @access public
443     */
444    function WebTestCase($label = false) {
445        $this->SimpleTestCase($label);
446    }
447   
448    /**
449     *    Announces the start of the test.
450     *    @param string $method    Test method just started.
451     *    @access public
452     */
453    function before($method) {
454        parent::before($method);
455        $this->setBrowser($this->createBrowser());
456    }
457
458    /**
459     *    Announces the end of the test. Includes private clean up.
460     *    @param string $method    Test method just finished.
461     *    @access public
462     */
463    function after($method) {
464        $this->unsetBrowser();
465        parent::after($method);
466    }
467   
468    /**
469     *    Gets a current browser reference for setting
470     *    special expectations or for detailed
471     *    examination of page fetches.
472     *    @return SimpleBrowser     Current test browser object.
473     *    @access public
474     */
475    function &getBrowser() {
476        return $this->_browser;
477    }
478   
479    /**
480     *    Gets a current browser reference for setting
481     *    special expectations or for detailed
482     *    examination of page fetches.
483     *    @param SimpleBrowser $browser    New test browser object.
484     *    @access public
485     */
486    function setBrowser(&$browser) {
487        return $this->_browser = &$browser;
488    }
489       
490    /**
491     *    Clears the current browser reference to help the
492     *    PHP garbage collector.
493     *    @access public
494     */
495    function unsetBrowser() {
496        unset($this->_browser);
497    }
498   
499    /**
500     *    Creates a new default web browser object.
501     *    Will be cleared at the end of the test method.
502     *    @return TestBrowser           New browser.
503     *    @access public
504     */
505    function &createBrowser() {
506        $browser = &new SimpleBrowser();
507        return $browser;
508    }
509   
510    /**
511     *    Gets the last response error.
512     *    @return string    Last low level HTTP error.
513     *    @access public
514     */
515    function getTransportError() {
516        return $this->_browser->getTransportError();
517    }
518       
519    /**
520     *    Accessor for the currently selected URL.
521     *    @return string        Current location or false if
522     *                          no page yet fetched.
523     *    @access public
524     */
525    function getUrl() {
526        return $this->_browser->getUrl();
527    }
528   
529    /**
530     *    Dumps the current request for debugging.
531     *    @access public
532     */
533    function showRequest() {
534        $this->dump($this->_browser->getRequest());
535    }
536   
537    /**
538     *    Dumps the current HTTP headers for debugging.
539     *    @access public
540     */
541    function showHeaders() {
542        $this->dump($this->_browser->getHeaders());
543    }
544   
545    /**
546     *    Dumps the current HTML source for debugging.
547     *    @access public
548     */
549    function showSource() {
550        $this->dump($this->_browser->getContent());
551    }
552   
553    /**
554     *    Dumps the visible text only for debugging.
555     *    @access public
556     */
557    function showText() {
558        $this->dump(wordwrap($this->_browser->getContentAsText(), 80));
559    }
560   
561    /**
562     *    Simulates the closing and reopening of the browser.
563     *    Temporary cookies will be discarded and timed
564     *    cookies will be expired if later than the
565     *    specified time.
566     *    @param string/integer $date Time when session restarted.
567     *                                If ommitted then all persistent
568     *                                cookies are kept. Time is either
569     *                                Cookie format string or timestamp.
570     *    @access public
571     */
572    function restart($date = false) {
573        if ($date === false) {
574            $date = time();
575        }
576        $this->_browser->restart($date);
577    }
578   
579    /**
580     *    Moves cookie expiry times back into the past.
581     *    Useful for testing timeouts and expiries.
582     *    @param integer $interval    Amount to age in seconds.
583     *    @access public
584     */
585    function ageCookies($interval) {
586        $this->_browser->ageCookies($interval);
587    }
588   
589    /**
590     *    Disables frames support. Frames will not be fetched
591     *    and the frameset page will be used instead.
592     *    @access public
593     */
594    function ignoreFrames() {
595        $this->_browser->ignoreFrames();
596    }
597   
598    /**
599     *    Switches off cookie sending and recieving.
600     *    @access public
601     */
602    function ignoreCookies() {
603        $this->_browser->ignoreCookies();
604    }
605   
606    /**
607     *    Skips errors for the next request only. You might
608     *    want to confirm that a page is unreachable for
609     *    example.
610     *    @access public
611     */
612    function ignoreErrors() {
613        $this->_ignore_errors = true;
614    }
615   
616    /**
617     *    Issues a fail if there is a transport error anywhere
618     *    in the current frameset. Only one such error is
619     *    reported.
620     *    @param string/boolean $result   HTML or failure.
621     *    @return string/boolean $result  Passes through result.
622     *    @access private
623     */
624    function _failOnError($result) {
625        if (! $this->_ignore_errors) {
626            if ($error = $this->_browser->getTransportError()) {
627                $this->fail($error);
628            }
629        }
630        $this->_ignore_errors = false;
631        return $result;
632    }
633
634    /**
635     *    Adds a header to every fetch.
636     *    @param string $header       Header line to add to every
637     *                                request until cleared.
638     *    @access public
639     */
640    function addHeader($header) {
641        $this->_browser->addHeader($header);
642    }
643   
644    /**
645     *    Sets the maximum number of redirects before
646     *    the web page is loaded regardless.
647     *    @param integer $max        Maximum hops.
648     *    @access public
649     */
650    function setMaximumRedirects($max) {
651        if (! $this->_browser) {
652            trigger_error(
653                    'Can only set maximum redirects in a test method, setUp() or tearDown()');
654        }
655        $this->_browser->setMaximumRedirects($max);
656    }
657   
658    /**
659     *    Sets the socket timeout for opening a connection and
660     *    receiving at least one byte of information.
661     *    @param integer $timeout      Maximum time in seconds.
662     *    @access public
663     */
664    function setConnectionTimeout($timeout) {
665        $this->_browser->setConnectionTimeout($timeout);
666    }
667   
668    /**
669     *    Sets proxy to use on all requests for when
670     *    testing from behind a firewall. Set URL
671     *    to false to disable.
672     *    @param string $proxy        Proxy URL.
673     *    @param string $username     Proxy username for authentication.
674     *    @param string $password     Proxy password for authentication.
675     *    @access public
676     */
677    function useProxy($proxy, $username = false, $password = false) {
678        $this->_browser->useProxy($proxy, $username, $password);
679    }
680   
681    /**
682     *    Fetches a page into the page buffer. If
683     *    there is no base for the URL then the
684     *    current base URL is used. After the fetch
685     *    the base URL reflects the new location.
686     *    @param string $url          URL to fetch.
687     *    @param hash $parameters     Optional additional GET data.
688     *    @return boolean/string      Raw page on success.
689     *    @access public
690     */
691    function get($url, $parameters = false) {
692        return $this->_failOnError($this->_browser->get($url, $parameters));
693    }
694   
695    /**
696     *    Fetches a page by POST into the page buffer.
697     *    If there is no base for the URL then the
698     *    current base URL is used. After the fetch
699     *    the base URL reflects the new location.
700     *    @param string $url          URL to fetch.
701     *    @param hash $parameters     Optional additional GET data.
702     *    @return boolean/string      Raw page on success.
703     *    @access public
704     */
705    function post($url, $parameters = false) {
706        return $this->_failOnError($this->_browser->post($url, $parameters));
707    }
708   
709    /**
710     *    Does a HTTP HEAD fetch, fetching only the page
711     *    headers. The current base URL is unchanged by this.
712     *    @param string $url          URL to fetch.
713     *    @param hash $parameters     Optional additional GET data.
714     *    @return boolean             True on success.
715     *    @access public
716     */
717    function head($url, $parameters = false) {
718        return $this->_failOnError($this->_browser->head($url, $parameters));
719    }
720   
721    /**
722     *    Equivalent to hitting the retry button on the
723     *    browser. Will attempt to repeat the page fetch.
724     *    @return boolean     True if fetch succeeded.
725     *    @access public
726     */
727    function retry() {
728        return $this->_failOnError($this->_browser->retry());
729    }
730   
731    /**
732     *    Equivalent to hitting the back button on the
733     *    browser.
734     *    @return boolean     True if history entry and
735     *                        fetch succeeded.
736     *    @access public
737     */
738    function back() {
739        return $this->_failOnError($this->_browser->back());
740    }
741   
742    /**
743     *    Equivalent to hitting the forward button on the
744     *    browser.
745     *    @return boolean     True if history entry and
746     *                        fetch succeeded.
747     *    @access public
748     */
749    function forward() {
750        return $this->_failOnError($this->_browser->forward());
751    }
752   
753    /**
754     *    Retries a request after setting the authentication
755     *    for the current realm.
756     *    @param string $username    Username for realm.
757     *    @param string $password    Password for realm.
758     *    @return boolean/string     HTML on successful fetch. Note
759     *                               that authentication may still have
760     *                               failed.
761     *    @access public
762     */
763    function authenticate($username, $password) {
764        return $this->_failOnError(
765                $this->_browser->authenticate($username, $password));
766    }
767   
768    /**
769     *    Gets the cookie value for the current browser context.
770     *    @param string $name          Name of cookie.
771     *    @return string               Value of cookie or false if unset.
772     *    @access public
773     */
774    function getCookie($name) {
775        return $this->_browser->getCurrentCookieValue($name);
776    }
777   
778    /**
779     *    Sets a cookie in the current browser.
780     *    @param string $name          Name of cookie.
781     *    @param string $value         Cookie value.
782     *    @param string $host          Host upon which the cookie is valid.
783     *    @param string $path          Cookie path if not host wide.
784     *    @param string $expiry        Expiry date.
785     *    @access public
786     */
787    function setCookie($name, $value, $host = false, $path = '/', $expiry = false) {
788        $this->_browser->setCookie($name, $value, $host, $path, $expiry);
789    }
790   
791    /**
792     *    Accessor for current frame focus. Will be
793     *    false if no frame has focus.
794     *    @return integer/string/boolean    Label if any, otherwise
795     *                                      the position in the frameset
796     *                                      or false if none.
797     *    @access public
798     */
799    function getFrameFocus() {
800        return $this->_browser->getFrameFocus();
801    }
802   
803    /**
804     *    Sets the focus by index. The integer index starts from 1.
805     *    @param integer $choice    Chosen frame.
806     *    @return boolean           True if frame exists.
807     *    @access public
808     */
809    function setFrameFocusByIndex($choice) {
810        return $this->_browser->setFrameFocusByIndex($choice);
811    }
812   
813    /**
814     *    Sets the focus by name.
815     *    @param string $name    Chosen frame.
816     *    @return boolean        True if frame exists.
817     *    @access public
818     */
819    function setFrameFocus($name) {
820        return $this->_browser->setFrameFocus($name);
821    }
822   
823    /**
824     *    Clears the frame focus. All frames will be searched
825     *    for content.
826     *    @access public
827     */
828    function clearFrameFocus() {
829        return $this->_browser->clearFrameFocus();
830    }
831   
832    /**
833     *    Clicks a visible text item. Will first try buttons,
834     *    then links and then images.
835     *    @param string $label        Visible text or alt text.
836     *    @return string/boolean      Raw page or false.
837     *    @access public
838     */
839    function click($label) {
840        return $this->_failOnError($this->_browser->click($label));
841    }
842   
843    /**
844     *    Checks for a click target.
845     *    @param string $label        Visible text or alt text.
846     *    @return boolean             True if click target.
847     *    @access public
848     */   
849    function assertClickable($label, $message = '%s') {
850        return $this->assertTrue(
851                $this->_browser->isClickable($label),
852                sprintf($message, "Click target [$label] should exist"));
853    }
854   
855    /**
856     *    Clicks the submit button by label. The owning
857     *    form will be submitted by this.
858     *    @param string $label    Button label. An unlabeled
859     *                            button can be triggered by 'Submit'.
860     *    @param hash $additional Additional form values.
861     *    @return boolean/string  Page on success, else false.
862     *    @access public
863     */
864    function clickSubmit($label = 'Submit', $additional = false) {
865        return $this->_failOnError(
866                $this->_browser->clickSubmit($label, $additional));
867    }
868   
869    /**
870     *    Clicks the submit button by name attribute. The owning
871     *    form will be submitted by this.
872     *    @param string $name     Name attribute of button.
873     *    @param hash $additional Additional form values.
874     *    @return boolean/string  Page on success.
875     *    @access public
876     */
877    function clickSubmitByName($name, $additional = false) {
878        return $this->_failOnError(
879                $this->_browser->clickSubmitByName($name, $additional));
880    }
881   
882    /**
883     *    Clicks the submit button by ID attribute. The owning
884     *    form will be submitted by this.
885     *    @param string $id       ID attribute of button.
886     *    @param hash $additional Additional form values.
887     *    @return boolean/string  Page on success.
888     *    @access public
889     */
890    function clickSubmitById($id, $additional = false) {
891        return $this->_failOnError(
892                $this->_browser->clickSubmitById($id, $additional));
893    }
894   
895    /**
896     *    Checks for a valid button label.
897     *    @param string $label        Visible text.
898     *    @return boolean             True if click target.
899     *    @access public
900     */   
901    function assertSubmit($label, $message = '%s') {
902        return $this->assertTrue(
903                $this->_browser->isSubmit($label),
904                sprintf($message, "Submit button [$label] should exist"));
905    }
906   
907    /**
908     *    Clicks the submit image by some kind of label. Usually
909     *    the alt tag or the nearest equivalent. The owning
910     *    form will be submitted by this. Clicking outside of
911     *    the boundary of the coordinates will result in
912     *    a failure.
913     *    @param string $label    Alt attribute of button.
914     *    @param integer $x       X-coordinate of imaginary click.
915     *    @param integer $y       Y-coordinate of imaginary click.
916     *    @param hash $additional Additional form values.
917     *    @return boolean/string  Page on success.
918     *    @access public
919     */
920    function clickImage($label, $x = 1, $y = 1, $additional = false) {
921        return $this->_failOnError(
922                $this->_browser->clickImage($label, $x, $y, $additional));
923    }
924   
925    /**
926     *    Clicks the submit image by the name. Usually
927     *    the alt tag or the nearest equivalent. The owning
928     *    form will be submitted by this. Clicking outside of
929     *    the boundary of the coordinates will result in
930     *    a failure.
931     *    @param string $name     Name attribute of button.
932     *    @param integer $x       X-coordinate of imaginary click.
933     *    @param integer $y       Y-coordinate of imaginary click.
934     *    @param hash $additional Additional form values.
935     *    @return boolean/string  Page on success.
936     *    @access public
937     */
938    function clickImageByName($name, $x = 1, $y = 1, $additional = false) {
939        return $this->_failOnError(
940                $this->_browser->clickImageByName($name, $x, $y, $additional));
941    }
942   
943    /**
944     *    Clicks the submit image by ID attribute. The owning
945     *    form will be submitted by this. Clicking outside of
946     *    the boundary of the coordinates will result in
947     *    a failure.
948     *    @param integer/string $id   ID attribute of button.
949     *    @param integer $x           X-coordinate of imaginary click.
950     *    @param integer $y           Y-coordinate of imaginary click.
951     *    @param hash $additional     Additional form values.
952     *    @return boolean/string      Page on success.
953     *    @access public
954     */
955    function clickImageById($id, $x = 1, $y = 1, $additional = false) {
956        return $this->_failOnError(
957                $this->_browser->clickImageById($id, $x, $y, $additional));
958    }
959   
960    /**
961     *    Checks for a valid image with atht alt text or title.
962     *    @param string $label        Visible text.
963     *    @return boolean             True if click target.
964     *    @access public
965     */   
966    function assertImage($label, $message = '%s') {
967        return $this->assertTrue(
968                $this->_browser->isImage($label),
969                sprintf($message, "Image with text [$label] should exist"));
970    }
971   
972    /**
973     *    Submits a form by the ID.
974     *    @param string $id       Form ID. No button information
975     *                            is submitted this way.
976     *    @return boolean/string  Page on success.
977     *    @access public
978     */
979    function submitFormById($id) {
980        return $this->_failOnError($this->_browser->submitFormById($id));
981    }
982   
983    /**
984     *    Follows a link by name. Will click the first link
985     *    found with this link text by default, or a later
986     *    one if an index is given. Match is case insensitive
987     *    with normalised space.
988     *    @param string $label     Text between the anchor tags.
989     *    @param integer $index    Link position counting from zero.
990     *    @return boolean/string   Page on success.
991     *    @access public
992     */
993    function clickLink($label, $index = 0) {
994        return $this->_failOnError($this->_browser->clickLink($label, $index));
995    }
996   
997    /**
998     *    Follows a link by id attribute.
999     *    @param string $id        ID attribute value.
1000     *    @return boolean/string   Page on success.
1001     *    @access public
1002     */
1003    function clickLinkById($id) {
1004        return $this->_failOnError($this->_browser->clickLinkById($id));
1005    }
1006   
1007    /**
1008     *    Tests for the presence of a link label. Match is
1009     *    case insensitive with normalised space.
1010     *    @param string $label     Text between the anchor tags.
1011     *    @param mixed $expected   Expected URL or expectation object.
1012     *    @param string $message   Message to display. Default
1013     *                             can be embedded with %s.
1014     *    @return boolean          True if link present.
1015     *    @access public
1016     */
1017    function assertLink($label, $expected = true, $message = '%s') {
1018        $url = $this->_browser->getLink($label);
1019        if ($expected === true || ($expected !== true && $url === false)) {
1020            return $this->assertTrue($url !== false, sprintf($message, "Link [$label] should exist"));
1021        }
1022        if (! SimpleExpectation::isExpectation($expected)) {
1023            $expected = new IdenticalExpectation($expected);
1024        }
1025        return $this->assert($expected, $url->asString(), sprintf($message, "Link [$label] should match"));
1026    }
1027
1028    /**
1029     *    Tests for the non-presence of a link label. Match is
1030     *    case insensitive with normalised space.
1031     *    @param string/integer $label    Text between the anchor tags
1032     *                                    or ID attribute.
1033     *    @param string $message          Message to display. Default
1034     *                                    can be embedded with %s.
1035     *    @return boolean                 True if link missing.
1036     *    @access public
1037     */
1038    function assertNoLink($label, $message = '%s') {
1039        return $this->assertTrue(
1040                $this->_browser->getLink($label) === false,
1041                sprintf($message, "Link [$label] should not exist"));
1042    }
1043   
1044    /**
1045     *    Tests for the presence of a link id attribute.
1046     *    @param string $id        Id attribute value.
1047     *    @param mixed $expected   Expected URL or expectation object.
1048     *    @param string $message   Message to display. Default
1049     *                             can be embedded with %s.
1050     *    @return boolean          True if link present.
1051     *    @access public
1052     */
1053    function assertLinkById($id, $expected = true, $message = '%s') {
1054        $url = $this->_browser->getLinkById($id);
1055        if ($expected === true) {
1056            return $this->assertTrue($url !== false, sprintf($message, "Link ID [$id] should exist"));
1057        }
1058        if (! SimpleExpectation::isExpectation($expected)) {
1059            $expected = new IdenticalExpectation($expected);
1060        }
1061        return $this->assert($expected, $url->asString(), sprintf($message, "Link ID [$id] should match"));
1062    }
1063
1064    /**
1065     *    Tests for the non-presence of a link label. Match is
1066     *    case insensitive with normalised space.
1067     *    @param string $id        Id attribute value.
1068     *    @param string $message   Message to display. Default
1069     *                             can be embedded with %s.
1070     *    @return boolean          True if link missing.
1071     *    @access public
1072     */
1073    function assertNoLinkById($id, $message = '%s') {
1074        return $this->assertTrue(
1075                $this->_browser->getLinkById($id) === false,
1076                sprintf($message, "Link ID [$id] should not exist"));
1077    }
1078   
1079    /**
1080     *    Sets all form fields with that label, or name if there
1081     *    is no label attached.
1082     *    @param string $name    Name of field in forms.
1083     *    @param string $value   New value of field.
1084     *    @return boolean        True if field exists, otherwise false.
1085     *    @access public
1086     */
1087    function setField($label, $value, $position=false) {
1088        return $this->_browser->setField($label, $value, $position);
1089    }
1090   
1091    /**
1092     *    Sets all form fields with that name.
1093     *    @param string $name    Name of field in forms.
1094     *    @param string $value   New value of field.
1095     *    @return boolean        True if field exists, otherwise false.
1096     *    @access public
1097     */
1098    function setFieldByName($name, $value, $position=false) {
1099        return $this->_browser->setFieldByName($name, $value, $position);
1100    }
1101       
1102    /**
1103     *    Sets all form fields with that id.
1104     *    @param string/integer $id   Id of field in forms.
1105     *    @param string $value        New value of field.
1106     *    @return boolean             True if field exists, otherwise false.
1107     *    @access public
1108     */
1109    function setFieldById($id, $value) {
1110        return $this->_browser->setFieldById($id, $value);
1111    }
1112   
1113    /**
1114     *    Confirms that the form element is currently set
1115     *    to the expected value. A missing form will always
1116     *    fail. If no value is given then only the existence
1117     *    of the field is checked.
1118     *    @param string $name       Name of field in forms.
1119     *    @param mixed $expected    Expected string/array value or
1120     *                              false for unset fields.
1121     *    @param string $message    Message to display. Default
1122     *                              can be embedded with %s.
1123     *    @return boolean           True if pass.
1124     *    @access public
1125     */
1126    function assertField($label, $expected = true, $message = '%s') {
1127        $value = $this->_browser->getField($label);
1128        return $this->_assertFieldValue($label, $value, $expected, $message);
1129    }
1130   
1131    /**
1132     *    Confirms that the form element is currently set
1133     *    to the expected value. A missing form element will always
1134     *    fail. If no value is given then only the existence
1135     *    of the field is checked.
1136     *    @param string $name       Name of field in forms.
1137     *    @param mixed $expected    Expected string/array value or
1138     *                              false for unset fields.
1139     *    @param string $message    Message to display. Default
1140     *                              can be embedded with %s.
1141     *    @return boolean           True if pass.
1142     *    @access public
1143     */
1144    function assertFieldByName($name, $expected = true, $message = '%s') {
1145        $value = $this->_browser->getFieldByName($name);
1146        return $this->_assertFieldValue($name, $value, $expected, $message);
1147    }
1148       
1149    /**
1150     *    Confirms that the form element is currently set
1151     *    to the expected value. A missing form will always
1152     *    fail. If no ID is given then only the existence
1153     *    of the field is checked.
1154     *    @param string/integer $id  Name of field in forms.
1155     *    @param mixed $expected     Expected string/array value or
1156     *                               false for unset fields.
1157     *    @param string $message     Message to display. Default
1158     *                               can be embedded with %s.
1159     *    @return boolean            True if pass.
1160     *    @access public
1161     */
1162    function assertFieldById($id, $expected = true, $message = '%s') {
1163        $value = $this->_browser->getFieldById($id);
1164        return $this->_assertFieldValue($id, $value, $expected, $message);
1165    }
1166   
1167    /**
1168     *    Tests the field value against the expectation.
1169     *    @param string $identifier      Name, ID or label.
1170     *    @param mixed $value            Current field value.
1171     *    @param mixed $expected         Expected value to match.
1172     *    @param string $message         Failure message.
1173     *    @return boolean                True if pass
1174     *    @access protected
1175     */
1176    function _assertFieldValue($identifier, $value, $expected, $message) {
1177        if ($expected === true) {
1178            return $this->assertTrue(
1179                    isset($value),
1180                    sprintf($message, "Field [$identifier] should exist"));
1181        }
1182        if (! SimpleExpectation::isExpectation($expected)) {
1183            $identifier = str_replace('%', '%%', $identifier);
1184            $expected = new FieldExpectation(
1185                    $expected,
1186                    "Field [$identifier] should match with [%s]");
1187        }
1188        return $this->assert($expected, $value, $message);
1189    }
1190   
1191    /**
1192     *    Checks the response code against a list
1193     *    of possible values.
1194     *    @param array $responses    Possible responses for a pass.
1195     *    @param string $message     Message to display. Default
1196     *                               can be embedded with %s.
1197     *    @return boolean            True if pass.
1198     *    @access public
1199     */
1200    function assertResponse($responses, $message = '%s') {
1201        $responses = (is_array($responses) ? $responses : array($responses));
1202        $code = $this->_browser->getResponseCode();
1203        $message = sprintf($message, "Expecting response in [" .
1204                implode(", ", $responses) . "] got [$code]");
1205        return $this->assertTrue(in_array($code, $responses), $message);
1206    }
1207   
1208    /**
1209     *    Checks the mime type against a list
1210     *    of possible values.
1211     *    @param array $types      Possible mime types for a pass.
1212     *    @param string $message   Message to display.
1213     *    @return boolean          True if pass.
1214     *    @access public
1215     */
1216    function assertMime($types, $message = '%s') {
1217        $types = (is_array($types) ? $types : array($types));
1218        $type = $this->_browser->getMimeType();
1219        $message = sprintf($message, "Expecting mime type in [" .
1220                implode(", ", $types) . "] got [$type]");
1221        return $this->assertTrue(in_array($type, $types), $message);
1222    }
1223   
1224    /**
1225     *    Attempt to match the authentication type within
1226     *    the security realm we are currently matching.
1227     *    @param string $authentication   Usually basic.
1228     *    @param string $message          Message to display.
1229     *    @return boolean                 True if pass.
1230     *    @access public
1231     */
1232    function assertAuthentication($authentication = false, $message = '%s') {
1233        if (! $authentication) {
1234            $message = sprintf($message, "Expected any authentication type, got [" .
1235                    $this->_browser->getAuthentication() . "]");
1236            return $this->assertTrue(
1237                    $this->_browser->getAuthentication(),
1238                    $message);
1239        } else {
1240            $message = sprintf($message, "Expected authentication [$authentication] got [" .
1241                    $this->_browser->getAuthentication() . "]");
1242            return $this->assertTrue(
1243                    strtolower($this->_browser->getAuthentication()) == strtolower($authentication),
1244                    $message);
1245        }
1246    }
1247   
1248    /**
1249     *    Checks that no authentication is necessary to view
1250     *    the desired page.
1251     *    @param string $message     Message to display.
1252     *    @return boolean            True if pass.
1253     *    @access public
1254     */
1255    function assertNoAuthentication($message = '%s') {
1256        $message = sprintf($message, "Expected no authentication type, got [" .
1257                $this->_browser->getAuthentication() . "]");
1258        return $this->assertFalse($this->_browser->getAuthentication(), $message);
1259    }
1260   
1261    /**
1262     *    Attempts to match the current security realm.
1263     *    @param string $realm     Name of security realm.
1264     *    @param string $message   Message to display.
1265     *    @return boolean          True if pass.
1266     *    @access public
1267     */
1268    function assertRealm($realm, $message = '%s') {
1269        if (! SimpleExpectation::isExpectation($realm)) {
1270            $realm = new EqualExpectation($realm);
1271        }
1272        return $this->assert(
1273                $realm,
1274                $this->_browser->getRealm(),
1275                "Expected realm -> $message");
1276    }
1277   
1278    /**
1279     *    Checks each header line for the required value. If no
1280     *    value is given then only an existence check is made.
1281     *    @param string $header    Case insensitive header name.
1282     *    @param mixed $value      Case sensitive trimmed string to
1283     *                             match against. An expectation object
1284     *                             can be used for pattern matching.
1285     *    @return boolean          True if pass.
1286     *    @access public
1287     */
1288    function assertHeader($header, $value = false, $message = '%s') {
1289        return $this->assert(
1290                new HttpHeaderExpectation($header, $value),
1291                $this->_browser->getHeaders(),
1292                $message);
1293    }
1294       
1295    /**
1296     *    @deprecated
1297     */
1298    function assertHeaderPattern($header, $pattern, $message = '%s') {
1299        return $this->assert(
1300                new HttpHeaderExpectation($header, new PatternExpectation($pattern)),
1301                $this->_browser->getHeaders(),
1302                $message);
1303    }
1304
1305    /**
1306     *    Confirms that the header type has not been received.
1307     *    Only the landing page is checked. If you want to check
1308     *    redirect pages, then you should limit redirects so
1309     *    as to capture the page you want.
1310     *    @param string $header    Case insensitive header name.
1311     *    @return boolean          True if pass.
1312     *    @access public
1313     */
1314    function assertNoHeader($header, $message = '%s') {
1315        return $this->assert(
1316                new NoHttpHeaderExpectation($header),
1317                $this->_browser->getHeaders(),
1318                $message);
1319    }
1320       
1321    /**
1322     *    @deprecated
1323     */
1324    function assertNoUnwantedHeader($header, $message = '%s') {
1325        return $this->assertNoHeader($header, $message);
1326    }
1327   
1328    /**
1329     *    Tests the text between the title tags.
1330     *    @param string/SimpleExpectation $title    Expected title.
1331     *    @param string $message                    Message to display.
1332     *    @return boolean                           True if pass.
1333     *    @access public
1334     */
1335    function assertTitle($title = false, $message = '%s') {
1336        if (! SimpleExpectation::isExpectation($title)) {
1337            $title = new EqualExpectation($title);
1338        }
1339        return $this->assert($title, $this->_browser->getTitle(), $message);
1340    }
1341   
1342    /**
1343     *    Will trigger a pass if the text is found in the plain
1344     *    text form of the page.
1345     *    @param string $text       Text to look for.
1346     *    @param string $message    Message to display.
1347     *    @return boolean           True if pass.
1348     *    @access public
1349     */
1350    function assertText($text, $message = '%s') {
1351        return $this->assert(
1352                new TextExpectation($text),
1353                $this->_browser->getContentAsText(),
1354                $message);
1355    }
1356   
1357    /**
1358     *    @deprecated
1359     */
1360    function assertWantedText($text, $message = '%s') {
1361        return $this->assertText($text, $message);
1362    }
1363   
1364    /**
1365     *    Will trigger a pass if the text is not found in the plain
1366     *    text form of the page.
1367     *    @param string $text       Text to look for.
1368     *    @param string $message    Message to display.
1369     *    @return boolean           True if pass.
1370     *    @access public
1371     */
1372    function assertNoText($text, $message = '%s') {
1373        return $this->assert(
1374                new NoTextExpectation($text),
1375                $this->_browser->getContentAsText(),
1376                $message);
1377    }
1378   
1379    /**
1380     *    @deprecated
1381     */
1382    function assertNoUnwantedText($text, $message = '%s') {
1383        return $this->assertNoText($text, $message);
1384    }
1385   
1386    /**
1387     *    Will trigger a pass if the Perl regex pattern
1388     *    is found in the raw content.
1389     *    @param string $pattern    Perl regex to look for including
1390     *                              the regex delimiters.
1391     *    @param string $message    Message to display.
1392     *    @return boolean           True if pass.
1393     *    @access public
1394     */
1395    function assertPattern($pattern, $message = '%s') {
1396        return $this->assert(
1397                new PatternExpectation($pattern),
1398                $this->_browser->getContent(),
1399                $message);
1400    }
1401   
1402    /**
1403     *    @deprecated
1404     */
1405    function assertWantedPattern($pattern, $message = '%s') {
1406        return $this->assertPattern($pattern, $message);
1407    }
1408   
1409    /**
1410     *    Will trigger a pass if the perl regex pattern
1411     *    is not present in raw content.
1412     *    @param string $pattern    Perl regex to look for including
1413     *                              the regex delimiters.
1414     *    @param string $message    Message to display.
1415     *    @return boolean           True if pass.
1416     *    @access public
1417     */
1418    function assertNoPattern($pattern, $message = '%s') {
1419        return $this->assert(
1420                new NoPatternExpectation($pattern),
1421                $this->_browser->getContent(),
1422                $message);
1423    }
1424   
1425    /**
1426     *    @deprecated
1427     */
1428    function assertNoUnwantedPattern($pattern, $message = '%s') {
1429        return $this->assertNoPattern($pattern, $message);
1430    }
1431   
1432    /**
1433     *    Checks that a cookie is set for the current page
1434     *    and optionally checks the value.
1435     *    @param string $name        Name of cookie to test.
1436     *    @param string $expected    Expected value as a string or
1437     *                               false if any value will do.
1438     *    @param string $message     Message to display.
1439     *    @return boolean            True if pass.
1440     *    @access public
1441     */
1442    function assertCookie($name, $expected = false, $message = '%s') {
1443        $value = $this->getCookie($name);
1444        if (! $expected) {
1445            return $this->assertTrue(
1446                    $value,
1447                    sprintf($message, "Expecting cookie [$name]"));
1448        }
1449        if (! SimpleExpectation::isExpectation($expected)) {
1450            $expected = new EqualExpectation($expected);
1451        }
1452        return $this->assert($expected, $value, "Expecting cookie [$name] -> $message");
1453    }
1454   
1455    /**
1456     *    Checks that no cookie is present or that it has
1457     *    been successfully cleared.
1458     *    @param string $name        Name of cookie to test.
1459     *    @param string $message     Message to display.
1460     *    @return boolean            True if pass.
1461     *    @access public
1462     */
1463    function assertNoCookie($name, $message = '%s') {
1464        return $this->assertTrue(
1465                $this->getCookie($name) === false,
1466                sprintf($message, "Not expecting cookie [$name]"));
1467    }
1468
1469    /**
1470     *    Called from within the test methods to register
1471     *    passes and failures.
1472     *    @param boolean $result    Pass on true.
1473     *    @param string $message    Message to display describing
1474     *                              the test state.
1475     *    @return boolean           True on pass
1476     *    @access public
1477     */
1478    function assertTrue($result, $message = false) {
1479        return $this->assert(new TrueExpectation(), $result, $message);
1480    }
1481
1482    /**
1483     *    Will be true on false and vice versa. False
1484     *    is the PHP definition of false, so that null,
1485     *    empty strings, zero and an empty array all count
1486     *    as false.
1487     *    @param boolean $result    Pass on false.
1488     *    @param string $message    Message to display.
1489     *    @return boolean           True on pass
1490     *    @access public
1491     */
1492    function assertFalse($result, $message = '%s') {
1493        return $this->assert(new FalseExpectation(), $result, $message);
1494    }
1495   
1496    /**
1497     *    Will trigger a pass if the two parameters have
1498     *    the same value only. Otherwise a fail. This
1499     *    is for testing hand extracted text, etc.
1500     *    @param mixed $first          Value to compare.
1501     *    @param mixed $second         Value to compare.
1502     *    @param string $message       Message to display.
1503     *    @return boolean              True on pass
1504     *    @access public
1505     */
1506    function assertEqual($first, $second, $message = '%s') {
1507        return $this->assert(
1508                new EqualExpectation($first),
1509                $second,
1510                $message);
1511    }
1512   
1513    /**
1514     *    Will trigger a pass if the two parameters have
1515     *    a different value. Otherwise a fail. This
1516     *    is for testing hand extracted text, etc.
1517     *    @param mixed $first           Value to compare.
1518     *    @param mixed $second          Value to compare.
1519     *    @param string $message        Message to display.
1520     *    @return boolean               True on pass
1521     *    @access public
1522     */
1523    function assertNotEqual($first, $second, $message = '%s') {
1524        return $this->assert(
1525                new NotEqualExpectation($first),
1526                $second,
1527                $message);
1528    }
1529
1530    /**
1531     *    Uses a stack trace to find the line of an assertion.
1532     *    @return string           Line number of first assert*
1533     *                             method embedded in format string.
1534     *    @access public
1535     */
1536    function getAssertionLine() {
1537        $trace = new SimpleStackTrace(array('assert', 'click', 'pass', 'fail'));
1538        return $trace->traceMethod();
1539    }
1540}
1541?>
Note: See TracBrowser for help on using the repository browser.