adding some strings
[moodle-linuxchix.git] / lib / simpletestlib / browser.php
blob6b41d0b4b4c7fbbe893ab097e319208203d1155e
1 <?php
2 /**
3 * Base include file for SimpleTest
4 * @package SimpleTest
5 * @subpackage WebTester
6 * @version $Id$
7 */
9 /**#@+
10 * include other SimpleTest class files
12 require_once(dirname(__FILE__) . '/simpletest.php');
13 require_once(dirname(__FILE__) . '/http.php');
14 require_once(dirname(__FILE__) . '/encoding.php');
15 require_once(dirname(__FILE__) . '/page.php');
16 require_once(dirname(__FILE__) . '/selector.php');
17 require_once(dirname(__FILE__) . '/frames.php');
18 require_once(dirname(__FILE__) . '/user_agent.php');
19 /**#@-*/
21 if (!defined('DEFAULT_MAX_NESTED_FRAMES')) {
22 define('DEFAULT_MAX_NESTED_FRAMES', 3);
25 /**
26 * Browser history list.
27 * @package SimpleTest
28 * @subpackage WebTester
30 class SimpleBrowserHistory {
31 var $_sequence;
32 var $_position;
34 /**
35 * Starts empty.
36 * @access public
38 function SimpleBrowserHistory() {
39 $this->_sequence = array();
40 $this->_position = -1;
43 /**
44 * Test for no entries yet.
45 * @return boolean True if empty.
46 * @access private
48 function _isEmpty() {
49 return ($this->_position == -1);
52 /**
53 * Test for being at the beginning.
54 * @return boolean True if first.
55 * @access private
57 function _atBeginning() {
58 return ($this->_position == 0) && ! $this->_isEmpty();
61 /**
62 * Test for being at the last entry.
63 * @return boolean True if last.
64 * @access private
66 function _atEnd() {
67 return ($this->_position + 1 >= count($this->_sequence)) && ! $this->_isEmpty();
70 /**
71 * Adds a successfully fetched page to the history.
72 * @param SimpleUrl $url URL of fetch.
73 * @param SimpleEncoding $parameters Any post data with the fetch.
74 * @access public
76 function recordEntry($url, $parameters) {
77 $this->_dropFuture();
78 array_push(
79 $this->_sequence,
80 array('url' => $url, 'parameters' => $parameters));
81 $this->_position++;
84 /**
85 * Last fully qualified URL for current history
86 * position.
87 * @return SimpleUrl URL for this position.
88 * @access public
90 function getUrl() {
91 if ($this->_isEmpty()) {
92 return false;
94 return $this->_sequence[$this->_position]['url'];
97 /**
98 * Parameters of last fetch from current history
99 * position.
100 * @return SimpleFormEncoding Post parameters.
101 * @access public
103 function getParameters() {
104 if ($this->_isEmpty()) {
105 return false;
107 return $this->_sequence[$this->_position]['parameters'];
111 * Step back one place in the history. Stops at
112 * the first page.
113 * @return boolean True if any previous entries.
114 * @access public
116 function back() {
117 if ($this->_isEmpty() || $this->_atBeginning()) {
118 return false;
120 $this->_position--;
121 return true;
125 * Step forward one place. If already at the
126 * latest entry then nothing will happen.
127 * @return boolean True if any future entries.
128 * @access public
130 function forward() {
131 if ($this->_isEmpty() || $this->_atEnd()) {
132 return false;
134 $this->_position++;
135 return true;
139 * Ditches all future entries beyond the current
140 * point.
141 * @access private
143 function _dropFuture() {
144 if ($this->_isEmpty()) {
145 return;
147 while (! $this->_atEnd()) {
148 array_pop($this->_sequence);
154 * Simulated web browser. This is an aggregate of
155 * the user agent, the HTML parsing, request history
156 * and the last header set.
157 * @package SimpleTest
158 * @subpackage WebTester
160 class SimpleBrowser {
161 var $_user_agent;
162 var $_page;
163 var $_history;
164 var $_ignore_frames;
165 var $_maximum_nested_frames;
168 * Starts with a fresh browser with no
169 * cookie or any other state information. The
170 * exception is that a default proxy will be
171 * set up if specified in the options.
172 * @access public
174 function SimpleBrowser() {
175 $this->_user_agent = &$this->_createUserAgent();
176 $this->_user_agent->useProxy(
177 SimpleTest::getDefaultProxy(),
178 SimpleTest::getDefaultProxyUsername(),
179 SimpleTest::getDefaultProxyPassword());
180 $this->_page = &new SimplePage();
181 $this->_history = &$this->_createHistory();
182 $this->_ignore_frames = false;
183 $this->_maximum_nested_frames = DEFAULT_MAX_NESTED_FRAMES;
187 * Creates the underlying user agent.
188 * @return SimpleFetcher Content fetcher.
189 * @access protected
191 function &_createUserAgent() {
192 $user_agent = &new SimpleUserAgent();
193 return $user_agent;
197 * Creates a new empty history list.
198 * @return SimpleBrowserHistory New list.
199 * @access protected
201 function &_createHistory() {
202 $history = &new SimpleBrowserHistory();
203 return $history;
207 * Disables frames support. Frames will not be fetched
208 * and the frameset page will be used instead.
209 * @access public
211 function ignoreFrames() {
212 $this->_ignore_frames = true;
216 * Enables frames support. Frames will be fetched from
217 * now on.
218 * @access public
220 function useFrames() {
221 $this->_ignore_frames = false;
225 * Switches off cookie sending and recieving.
226 * @access public
228 function ignoreCookies() {
229 $this->_user_agent->ignoreCookies();
233 * Switches back on the cookie sending and recieving.
234 * @access public
236 function useCookies() {
237 $this->_user_agent->useCookies();
241 * Parses the raw content into a page. Will load further
242 * frame pages unless frames are disabled.
243 * @param SimpleHttpResponse $response Response from fetch.
244 * @param integer $depth Nested frameset depth.
245 * @return SimplePage Parsed HTML.
246 * @access private
248 function &_parse($response, $depth = 0) {
249 $page = &$this->_buildPage($response);
250 if ($this->_ignore_frames || ! $page->hasFrames() || ($depth > $this->_maximum_nested_frames)) {
251 return $page;
253 $frameset = &new SimpleFrameset($page);
254 foreach ($page->getFrameset() as $key => $url) {
255 $frame = &$this->_fetch($url, new SimpleGetEncoding(), $depth + 1);
256 $frameset->addFrame($frame, $key);
258 return $frameset;
262 * Assembles the parsing machinery and actually parses
263 * a single page. Frees all of the builder memory and so
264 * unjams the PHP memory management.
265 * @param SimpleHttpResponse $response Response from fetch.
266 * @return SimplePage Parsed top level page.
267 * @access protected
269 function &_buildPage($response) {
270 $builder = &new SimplePageBuilder();
271 $page = &$builder->parse($response);
272 $builder->free();
273 unset($builder);
274 return $page;
278 * Fetches a page. Jointly recursive with the _parse()
279 * method as it descends a frameset.
280 * @param string/SimpleUrl $url Target to fetch.
281 * @param SimpleEncoding $encoding GET/POST parameters.
282 * @param integer $depth Nested frameset depth protection.
283 * @return SimplePage Parsed page.
284 * @access private
286 function &_fetch($url, $encoding, $depth = 0) {
287 $response = &$this->_user_agent->fetchResponse($url, $encoding);
288 if ($response->isError()) {
289 $page = &new SimplePage($response);
290 } else {
291 $page = &$this->_parse($response, $depth);
293 return $page;
297 * Fetches a page or a single frame if that is the current
298 * focus.
299 * @param SimpleUrl $url Target to fetch.
300 * @param SimpleEncoding $parameters GET/POST parameters.
301 * @return string Raw content of page.
302 * @access private
304 function _load($url, $parameters) {
305 $frame = $url->getTarget();
306 if (! $frame || ! $this->_page->hasFrames() || (strtolower($frame) == '_top')) {
307 return $this->_loadPage($url, $parameters);
309 return $this->_loadFrame(array($frame), $url, $parameters);
313 * Fetches a page and makes it the current page/frame.
314 * @param string/SimpleUrl $url Target to fetch as string.
315 * @param SimplePostEncoding $parameters POST parameters.
316 * @return string Raw content of page.
317 * @access private
319 function _loadPage($url, $parameters) {
320 $this->_page = &$this->_fetch($url, $parameters);
321 $this->_history->recordEntry(
322 $this->_page->getUrl(),
323 $this->_page->getRequestData());
324 return $this->_page->getRaw();
328 * Fetches a frame into the existing frameset replacing the
329 * original.
330 * @param array $frames List of names to drill down.
331 * @param string/SimpleUrl $url Target to fetch as string.
332 * @param SimpleFormEncoding $parameters POST parameters.
333 * @return string Raw content of page.
334 * @access private
336 function _loadFrame($frames, $url, $parameters) {
337 $page = &$this->_fetch($url, $parameters);
338 $this->_page->setFrame($frames, $page);
342 * Removes expired and temporary cookies as if
343 * the browser was closed and re-opened.
344 * @param string/integer $date Time when session restarted.
345 * If omitted then all persistent
346 * cookies are kept.
347 * @access public
349 function restart($date = false) {
350 $this->_user_agent->restart($date);
354 * Adds a header to every fetch.
355 * @param string $header Header line to add to every
356 * request until cleared.
357 * @access public
359 function addHeader($header) {
360 $this->_user_agent->addHeader($header);
364 * Ages the cookies by the specified time.
365 * @param integer $interval Amount in seconds.
366 * @access public
368 function ageCookies($interval) {
369 $this->_user_agent->ageCookies($interval);
373 * Sets an additional cookie. If a cookie has
374 * the same name and path it is replaced.
375 * @param string $name Cookie key.
376 * @param string $value Value of cookie.
377 * @param string $host Host upon which the cookie is valid.
378 * @param string $path Cookie path if not host wide.
379 * @param string $expiry Expiry date.
380 * @access public
382 function setCookie($name, $value, $host = false, $path = '/', $expiry = false) {
383 $this->_user_agent->setCookie($name, $value, $host, $path, $expiry);
387 * Reads the most specific cookie value from the
388 * browser cookies.
389 * @param string $host Host to search.
390 * @param string $path Applicable path.
391 * @param string $name Name of cookie to read.
392 * @return string False if not present, else the
393 * value as a string.
394 * @access public
396 function getCookieValue($host, $path, $name) {
397 return $this->_user_agent->getCookieValue($host, $path, $name);
401 * Reads the current cookies for the current URL.
402 * @param string $name Key of cookie to find.
403 * @return string Null if there is no current URL, false
404 * if the cookie is not set.
405 * @access public
407 function getCurrentCookieValue($name) {
408 return $this->_user_agent->getBaseCookieValue($name, $this->_page->getUrl());
412 * Sets the maximum number of redirects before
413 * a page will be loaded anyway.
414 * @param integer $max Most hops allowed.
415 * @access public
417 function setMaximumRedirects($max) {
418 $this->_user_agent->setMaximumRedirects($max);
422 * Sets the maximum number of nesting of framed pages
423 * within a framed page to prevent loops.
424 * @param integer $max Highest depth allowed.
425 * @access public
427 function setMaximumNestedFrames($max) {
428 $this->_maximum_nested_frames = $max;
432 * Sets the socket timeout for opening a connection.
433 * @param integer $timeout Maximum time in seconds.
434 * @access public
436 function setConnectionTimeout($timeout) {
437 $this->_user_agent->setConnectionTimeout($timeout);
441 * Sets proxy to use on all requests for when
442 * testing from behind a firewall. Set URL
443 * to false to disable.
444 * @param string $proxy Proxy URL.
445 * @param string $username Proxy username for authentication.
446 * @param string $password Proxy password for authentication.
447 * @access public
449 function useProxy($proxy, $username = false, $password = false) {
450 $this->_user_agent->useProxy($proxy, $username, $password);
454 * Fetches the page content with a HEAD request.
455 * Will affect cookies, but will not change the base URL.
456 * @param string/SimpleUrl $url Target to fetch as string.
457 * @param hash/SimpleHeadEncoding $parameters Additional parameters for
458 * HEAD request.
459 * @return boolean True if successful.
460 * @access public
462 function head($url, $parameters = false) {
463 if (! is_object($url)) {
464 $url = new SimpleUrl($url);
466 if ($this->getUrl()) {
467 $url = $url->makeAbsolute($this->getUrl());
469 $response = &$this->_user_agent->fetchResponse($url, new SimpleHeadEncoding($parameters));
470 return ! $response->isError();
474 * Fetches the page content with a simple GET request.
475 * @param string/SimpleUrl $url Target to fetch.
476 * @param hash/SimpleFormEncoding $parameters Additional parameters for
477 * GET request.
478 * @return string Content of page or false.
479 * @access public
481 function get($url, $parameters = false) {
482 if (! is_object($url)) {
483 $url = new SimpleUrl($url);
485 if ($this->getUrl()) {
486 $url = $url->makeAbsolute($this->getUrl());
488 return $this->_load($url, new SimpleGetEncoding($parameters));
492 * Fetches the page content with a POST request.
493 * @param string/SimpleUrl $url Target to fetch as string.
494 * @param hash/SimpleFormEncoding $parameters POST parameters.
495 * @return string Content of page.
496 * @access public
498 function post($url, $parameters = false) {
499 if (! is_object($url)) {
500 $url = new SimpleUrl($url);
502 if ($this->getUrl()) {
503 $url = $url->makeAbsolute($this->getUrl());
505 return $this->_load($url, new SimplePostEncoding($parameters));
509 * Equivalent to hitting the retry button on the
510 * browser. Will attempt to repeat the page fetch. If
511 * there is no history to repeat it will give false.
512 * @return string/boolean Content if fetch succeeded
513 * else false.
514 * @access public
516 function retry() {
517 $frames = $this->_page->getFrameFocus();
518 if (count($frames) > 0) {
519 $this->_loadFrame(
520 $frames,
521 $this->_page->getUrl(),
522 $this->_page->getRequestData());
523 return $this->_page->getRaw();
525 if ($url = $this->_history->getUrl()) {
526 $this->_page = &$this->_fetch($url, $this->_history->getParameters());
527 return $this->_page->getRaw();
529 return false;
533 * Equivalent to hitting the back button on the
534 * browser. The browser history is unchanged on
535 * failure. The page content is refetched as there
536 * is no concept of content caching in SimpleTest.
537 * @return boolean True if history entry and
538 * fetch succeeded
539 * @access public
541 function back() {
542 if (! $this->_history->back()) {
543 return false;
545 $content = $this->retry();
546 if (! $content) {
547 $this->_history->forward();
549 return $content;
553 * Equivalent to hitting the forward button on the
554 * browser. The browser history is unchanged on
555 * failure. The page content is refetched as there
556 * is no concept of content caching in SimpleTest.
557 * @return boolean True if history entry and
558 * fetch succeeded
559 * @access public
561 function forward() {
562 if (! $this->_history->forward()) {
563 return false;
565 $content = $this->retry();
566 if (! $content) {
567 $this->_history->back();
569 return $content;
573 * Retries a request after setting the authentication
574 * for the current realm.
575 * @param string $username Username for realm.
576 * @param string $password Password for realm.
577 * @return boolean True if successful fetch. Note
578 * that authentication may still have
579 * failed.
580 * @access public
582 function authenticate($username, $password) {
583 if (! $this->_page->getRealm()) {
584 return false;
586 $url = $this->_page->getUrl();
587 if (! $url) {
588 return false;
590 $this->_user_agent->setIdentity(
591 $url->getHost(),
592 $this->_page->getRealm(),
593 $username,
594 $password);
595 return $this->retry();
599 * Accessor for a breakdown of the frameset.
600 * @return array Hash tree of frames by name
601 * or index if no name.
602 * @access public
604 function getFrames() {
605 return $this->_page->getFrames();
609 * Accessor for current frame focus. Will be
610 * false if no frame has focus.
611 * @return integer/string/boolean Label if any, otherwise
612 * the position in the frameset
613 * or false if none.
614 * @access public
616 function getFrameFocus() {
617 return $this->_page->getFrameFocus();
621 * Sets the focus by index. The integer index starts from 1.
622 * @param integer $choice Chosen frame.
623 * @return boolean True if frame exists.
624 * @access public
626 function setFrameFocusByIndex($choice) {
627 return $this->_page->setFrameFocusByIndex($choice);
631 * Sets the focus by name.
632 * @param string $name Chosen frame.
633 * @return boolean True if frame exists.
634 * @access public
636 function setFrameFocus($name) {
637 return $this->_page->setFrameFocus($name);
641 * Clears the frame focus. All frames will be searched
642 * for content.
643 * @access public
645 function clearFrameFocus() {
646 return $this->_page->clearFrameFocus();
650 * Accessor for last error.
651 * @return string Error from last response.
652 * @access public
654 function getTransportError() {
655 return $this->_page->getTransportError();
659 * Accessor for current MIME type.
660 * @return string MIME type as string; e.g. 'text/html'
661 * @access public
663 function getMimeType() {
664 return $this->_page->getMimeType();
668 * Accessor for last response code.
669 * @return integer Last HTTP response code received.
670 * @access public
672 function getResponseCode() {
673 return $this->_page->getResponseCode();
677 * Accessor for last Authentication type. Only valid
678 * straight after a challenge (401).
679 * @return string Description of challenge type.
680 * @access public
682 function getAuthentication() {
683 return $this->_page->getAuthentication();
687 * Accessor for last Authentication realm. Only valid
688 * straight after a challenge (401).
689 * @return string Name of security realm.
690 * @access public
692 function getRealm() {
693 return $this->_page->getRealm();
697 * Accessor for current URL of page or frame if
698 * focused.
699 * @return string Location of current page or frame as
700 * a string.
702 function getUrl() {
703 $url = $this->_page->getUrl();
704 return $url ? $url->asString() : false;
708 * Accessor for raw bytes sent down the wire.
709 * @return string Original text sent.
710 * @access public
712 function getRequest() {
713 return $this->_page->getRequest();
717 * Accessor for raw header information.
718 * @return string Header block.
719 * @access public
721 function getHeaders() {
722 return $this->_page->getHeaders();
726 * Accessor for raw page information.
727 * @return string Original text content of web page.
728 * @access public
730 function getContent() {
731 return $this->_page->getRaw();
735 * Accessor for plain text version of the page.
736 * @return string Normalised text representation.
737 * @access public
739 function getContentAsText() {
740 return $this->_page->getText();
744 * Accessor for parsed title.
745 * @return string Title or false if no title is present.
746 * @access public
748 function getTitle() {
749 return $this->_page->getTitle();
753 * Accessor for a list of all fixed links in current page.
754 * @return array List of urls with scheme of
755 * http or https and hostname.
756 * @access public
758 function getAbsoluteUrls() {
759 return $this->_page->getAbsoluteUrls();
763 * Accessor for a list of all relative links.
764 * @return array List of urls without hostname.
765 * @access public
767 function getRelativeUrls() {
768 return $this->_page->getRelativeUrls();
772 * Sets all form fields with that name.
773 * @param string $label Name or label of field in forms.
774 * @param string $value New value of field.
775 * @return boolean True if field exists, otherwise false.
776 * @access public
778 function setField($label, $value) {
779 return $this->_page->setField(new SimpleByLabelOrName($label), $value);
783 * Sets all form fields with that name. Will use label if
784 * one is available (not yet implemented).
785 * @param string $name Name of field in forms.
786 * @param string $value New value of field.
787 * @return boolean True if field exists, otherwise false.
788 * @access public
790 function setFieldByName($name, $value) {
791 return $this->_page->setField(new SimpleByName($name), $value);
795 * Sets all form fields with that id attribute.
796 * @param string/integer $id Id of field in forms.
797 * @param string $value New value of field.
798 * @return boolean True if field exists, otherwise false.
799 * @access public
801 function setFieldById($id, $value) {
802 return $this->_page->setField(new SimpleById($id), $value);
806 * Accessor for a form element value within the page.
807 * Finds the first match.
808 * @param string $label Field label.
809 * @return string/boolean A value if the field is
810 * present, false if unchecked
811 * and null if missing.
812 * @access public
814 function getField($label) {
815 return $this->_page->getField(new SimpleByLabelOrName($label));
819 * Accessor for a form element value within the page.
820 * Finds the first match.
821 * @param string $name Field name.
822 * @return string/boolean A string if the field is
823 * present, false if unchecked
824 * and null if missing.
825 * @access public
827 function getFieldByName($name) {
828 return $this->_page->getField(new SimpleByName($name));
832 * Accessor for a form element value within the page.
833 * @param string/integer $id Id of field in forms.
834 * @return string/boolean A string if the field is
835 * present, false if unchecked
836 * and null if missing.
837 * @access public
839 function getFieldById($id) {
840 return $this->_page->getField(new SimpleById($id));
844 * Clicks the submit button by label. The owning
845 * form will be submitted by this.
846 * @param string $label Button label. An unlabeled
847 * button can be triggered by 'Submit'.
848 * @param hash $additional Additional form data.
849 * @return string/boolean Page on success.
850 * @access public
852 function clickSubmit($label = 'Submit', $additional = false) {
853 if (! ($form = &$this->_page->getFormBySubmit(new SimpleByLabel($label)))) {
854 return false;
856 $success = $this->_load(
857 $form->getAction(),
858 $form->submitButton(new SimpleByLabel($label), $additional));
859 return ($success ? $this->getContent() : $success);
863 * Clicks the submit button by name attribute. The owning
864 * form will be submitted by this.
865 * @param string $name Button name.
866 * @param hash $additional Additional form data.
867 * @return string/boolean Page on success.
868 * @access public
870 function clickSubmitByName($name, $additional = false) {
871 if (! ($form = &$this->_page->getFormBySubmit(new SimpleByName($name)))) {
872 return false;
874 $success = $this->_load(
875 $form->getAction(),
876 $form->submitButton(new SimpleByName($name), $additional));
877 return ($success ? $this->getContent() : $success);
881 * Clicks the submit button by ID attribute of the button
882 * itself. The owning form will be submitted by this.
883 * @param string $id Button ID.
884 * @param hash $additional Additional form data.
885 * @return string/boolean Page on success.
886 * @access public
888 function clickSubmitById($id, $additional = false) {
889 if (! ($form = &$this->_page->getFormBySubmit(new SimpleById($id)))) {
890 return false;
892 $success = $this->_load(
893 $form->getAction(),
894 $form->submitButton(new SimpleById($id), $additional));
895 return ($success ? $this->getContent() : $success);
899 * Tests to see if a submit button exists with this
900 * label.
901 * @param string $label Button label.
902 * @return boolean True if present.
903 * @access public
905 function isSubmit($label) {
906 return (boolean)$this->_page->getFormBySubmit(new SimpleByLabel($label));
910 * Clicks the submit image by some kind of label. Usually
911 * the alt tag or the nearest equivalent. The owning
912 * form will be submitted by this. Clicking outside of
913 * the boundary of the coordinates will result in
914 * a failure.
915 * @param string $label ID attribute of button.
916 * @param integer $x X-coordinate of imaginary click.
917 * @param integer $y Y-coordinate of imaginary click.
918 * @param hash $additional Additional form data.
919 * @return string/boolean Page on success.
920 * @access public
922 function clickImage($label, $x = 1, $y = 1, $additional = false) {
923 if (! ($form = &$this->_page->getFormByImage(new SimpleByLabel($label)))) {
924 return false;
926 $success = $this->_load(
927 $form->getAction(),
928 $form->submitImage(new SimpleByLabel($label), $x, $y, $additional));
929 return ($success ? $this->getContent() : $success);
933 * Clicks the submit image by the name. Usually
934 * the alt tag or the nearest equivalent. The owning
935 * form will be submitted by this. Clicking outside of
936 * the boundary of the coordinates will result in
937 * a failure.
938 * @param string $name Name attribute of button.
939 * @param integer $x X-coordinate of imaginary click.
940 * @param integer $y Y-coordinate of imaginary click.
941 * @param hash $additional Additional form data.
942 * @return string/boolean Page on success.
943 * @access public
945 function clickImageByName($name, $x = 1, $y = 1, $additional = false) {
946 if (! ($form = &$this->_page->getFormByImage(new SimpleByName($name)))) {
947 return false;
949 $success = $this->_load(
950 $form->getAction(),
951 $form->submitImage(new SimpleByName($name), $x, $y, $additional));
952 return ($success ? $this->getContent() : $success);
956 * Clicks the submit image by ID attribute. The owning
957 * form will be submitted by this. Clicking outside of
958 * the boundary of the coordinates will result in
959 * a failure.
960 * @param integer/string $id ID attribute of button.
961 * @param integer $x X-coordinate of imaginary click.
962 * @param integer $y Y-coordinate of imaginary click.
963 * @param hash $additional Additional form data.
964 * @return string/boolean Page on success.
965 * @access public
967 function clickImageById($id, $x = 1, $y = 1, $additional = false) {
968 if (! ($form = &$this->_page->getFormByImage(new SimpleById($id)))) {
969 return false;
971 $success = $this->_load(
972 $form->getAction(),
973 $form->submitImage(new SimpleById($id), $x, $y, $additional));
974 return ($success ? $this->getContent() : $success);
978 * Tests to see if an image exists with this
979 * title or alt text.
980 * @param string $label Image text.
981 * @return boolean True if present.
982 * @access public
984 function isImage($label) {
985 return (boolean)$this->_page->getFormByImage(new SimpleByLabel($label));
989 * Submits a form by the ID.
990 * @param string $id The form ID. No submit button value
991 * will be sent.
992 * @return string/boolean Page on success.
993 * @access public
995 function submitFormById($id) {
996 if (! ($form = &$this->_page->getFormById($id))) {
997 return false;
999 $success = $this->_load(
1000 $form->getAction(),
1001 $form->submit());
1002 return ($success ? $this->getContent() : $success);
1006 * Finds a URL by label. Will find the first link
1007 * found with this link text by default, or a later
1008 * one if an index is given. The match ignores case and
1009 * white space issues.
1010 * @param string $label Text between the anchor tags.
1011 * @param integer $index Link position counting from zero.
1012 * @return string/boolean URL on success.
1013 * @access public
1015 function getLink($label, $index = 0) {
1016 $urls = $this->_page->getUrlsByLabel($label);
1017 if (count($urls) == 0) {
1018 return false;
1020 if (count($urls) < $index + 1) {
1021 return false;
1023 return $urls[$index];
1027 * Follows a link by label. Will click the first link
1028 * found with this link text by default, or a later
1029 * one if an index is given. The match ignores case and
1030 * white space issues.
1031 * @param string $label Text between the anchor tags.
1032 * @param integer $index Link position counting from zero.
1033 * @return string/boolean Page on success.
1034 * @access public
1036 function clickLink($label, $index = 0) {
1037 $url = $this->getLink($label, $index);
1038 if ($url === false) {
1039 return false;
1041 $this->_load($url, new SimpleGetEncoding());
1042 return $this->getContent();
1046 * Finds a link by id attribute.
1047 * @param string $id ID attribute value.
1048 * @return string/boolean URL on success.
1049 * @access public
1051 function getLinkById($id) {
1052 return $this->_page->getUrlById($id);
1056 * Follows a link by id attribute.
1057 * @param string $id ID attribute value.
1058 * @return string/boolean Page on success.
1059 * @access public
1061 function clickLinkById($id) {
1062 if (! ($url = $this->getLinkById($id))) {
1063 return false;
1065 $this->_load($url, new SimpleGetEncoding());
1066 return $this->getContent();
1070 * Clicks a visible text item. Will first try buttons,
1071 * then links and then images.
1072 * @param string $label Visible text or alt text.
1073 * @return string/boolean Raw page or false.
1074 * @access public
1076 function click($label) {
1077 $raw = $this->clickSubmit($label);
1078 if (! $raw) {
1079 $raw = $this->clickLink($label);
1081 if (! $raw) {
1082 $raw = $this->clickImage($label);
1084 return $raw;
1088 * Tests to see if a click target exists.
1089 * @param string $label Visible text or alt text.
1090 * @return boolean True if target present.
1091 * @access public
1093 function isClickable($label) {
1094 return $this->isSubmit($label) || ($this->getLink($label) !== false) || $this->isImage($label);