0337d704 |
1 | <?php |
2 | /** |
3 | * Base include file for SimpleTest |
4 | * @package SimpleTest |
5 | * @subpackage WebTester |
6 | * @version $Id: browser.php,v 1.133 2004/08/18 23:10:19 lastcraft Exp $ |
7 | */ |
8 | |
9 | /**#@+ |
10 | * include other SimpleTest class files |
11 | */ |
12 | require_once(dirname(__FILE__) . '/options.php'); |
13 | require_once(dirname(__FILE__) . '/http.php'); |
14 | require_once(dirname(__FILE__) . '/page.php'); |
15 | require_once(dirname(__FILE__) . '/frames.php'); |
16 | require_once(dirname(__FILE__) . '/user_agent.php'); |
17 | /**#@-*/ |
18 | |
19 | /** |
20 | * Browser history list. |
21 | * @package SimpleTest |
22 | * @subpackage WebTester |
23 | */ |
24 | class SimpleBrowserHistory { |
25 | var $_sequence; |
26 | var $_position; |
27 | |
28 | /** |
29 | * Starts empty. |
30 | * @access public |
31 | */ |
32 | function SimpleBrowserHistory() { |
33 | $this->_sequence = array(); |
34 | $this->_position = -1; |
35 | } |
36 | |
37 | /** |
38 | * Test for no entries yet. |
39 | * @return boolean True if empty. |
40 | * @access private |
41 | */ |
42 | function _isEmpty() { |
43 | return ($this->_position == -1); |
44 | } |
45 | |
46 | /** |
47 | * Test for being at the beginning. |
48 | * @return boolean True if first. |
49 | * @access private |
50 | */ |
51 | function _atBeginning() { |
52 | return ($this->_position == 0) && ! $this->_isEmpty(); |
53 | } |
54 | |
55 | /** |
56 | * Test for being at the last entry. |
57 | * @return boolean True if last. |
58 | * @access private |
59 | */ |
60 | function _atEnd() { |
61 | return ($this->_position + 1 >= count($this->_sequence)) && ! $this->_isEmpty(); |
62 | } |
63 | |
64 | /** |
65 | * Adds a successfully fetched page to the history. |
66 | * @param string $method GET or POST. |
67 | * @param SimpleUrl $url URL of fetch. |
68 | * @param array $parameters Any post data with the fetch. |
69 | * @access public |
70 | */ |
71 | function recordEntry($method, $url, $parameters) { |
72 | $this->_dropFuture(); |
73 | array_push( |
74 | $this->_sequence, |
75 | array('method' => $method, 'url' => $url, 'parameters' => $parameters)); |
76 | $this->_position++; |
77 | } |
78 | |
79 | /** |
80 | * Last fetching method for current history |
81 | * position. |
82 | * @return string GET or POST for this point in |
83 | * the history. |
84 | * @access public |
85 | */ |
86 | function getMethod() { |
87 | if ($this->_isEmpty()) { |
88 | return false; |
89 | } |
90 | return $this->_sequence[$this->_position]['method']; |
91 | } |
92 | |
93 | /** |
94 | * Last fully qualified URL for current history |
95 | * position. |
96 | * @return SimpleUrl URL for this position. |
97 | * @access public |
98 | */ |
99 | function getUrl() { |
100 | if ($this->_isEmpty()) { |
101 | return false; |
102 | } |
103 | return $this->_sequence[$this->_position]['url']; |
104 | } |
105 | |
106 | /** |
107 | * Parameters of last fetch from current history |
108 | * position. |
109 | * @return array Hash of post parameters. |
110 | * @access public |
111 | */ |
112 | function getParameters() { |
113 | if ($this->_isEmpty()) { |
114 | return false; |
115 | } |
116 | return $this->_sequence[$this->_position]['parameters']; |
117 | } |
118 | |
119 | /** |
120 | * Step back one place in the history. Stops at |
121 | * the first page. |
122 | * @return boolean True if any previous entries. |
123 | * @access public |
124 | */ |
125 | function back() { |
126 | if ($this->_isEmpty() || $this->_atBeginning()) { |
127 | return false; |
128 | } |
129 | $this->_position--; |
130 | return true; |
131 | } |
132 | |
133 | /** |
134 | * Step forward one place. If already at the |
135 | * latest entry then nothing will happen. |
136 | * @return boolean True if any future entries. |
137 | * @access public |
138 | */ |
139 | function forward() { |
140 | if ($this->_isEmpty() || $this->_atEnd()) { |
141 | return false; |
142 | } |
143 | $this->_position++; |
144 | return true; |
145 | } |
146 | |
147 | /** |
148 | * Ditches all future entries beyond the current |
149 | * point. |
150 | * @access private |
151 | */ |
152 | function _dropFuture() { |
153 | if ($this->_isEmpty()) { |
154 | return; |
155 | } |
156 | while (! $this->_atEnd()) { |
157 | array_pop($this->_sequence); |
158 | } |
159 | } |
160 | } |
161 | |
162 | /** |
163 | * Simulated web browser. This is an aggregate of |
164 | * the user agent, the HTML parsing, request history |
165 | * and the last header set. |
166 | * @package SimpleTest |
167 | * @subpackage WebTester |
168 | */ |
169 | class SimpleBrowser { |
170 | var $_user_agent; |
171 | var $_page; |
172 | var $_history; |
173 | var $_ignore_frames; |
174 | |
175 | /** |
176 | * Starts with a fresh browser with no |
177 | * cookie or any other state information. The |
178 | * exception is that a default proxy will be |
179 | * set up if specified in the options. |
180 | * @access public |
181 | */ |
182 | function SimpleBrowser() { |
183 | $this->_user_agent = &$this->_createUserAgent(); |
184 | $this->_user_agent->useProxy( |
185 | SimpleTestOptions::getDefaultProxy(), |
186 | SimpleTestOptions::getDefaultProxyUsername(), |
187 | SimpleTestOptions::getDefaultProxyPassword()); |
188 | $this->_page = &new SimplePage(); |
189 | $this->_history = &$this->_createHistory(); |
190 | $this->_ignore_frames = false; |
191 | } |
192 | |
193 | /** |
194 | * Creates the underlying user agent. |
195 | * @return SimpleFetcher Content fetcher. |
196 | * @access protected |
197 | */ |
198 | function &_createUserAgent() { |
199 | return new SimpleUserAgent(); |
200 | } |
201 | |
202 | /** |
203 | * Creates a new empty history list. |
204 | * @return SimpleBrowserHistory New list. |
205 | * @access protected |
206 | */ |
207 | function &_createHistory() { |
208 | return new SimpleBrowserHistory(); |
209 | } |
210 | |
211 | /** |
212 | * Disables frames support. Frames will not be fetched |
213 | * and the frameset page will be used instead. |
214 | * @access public |
215 | */ |
216 | function ignoreFrames() { |
217 | $this->_ignore_frames = true; |
218 | } |
219 | |
220 | /** |
221 | * Enables frames support. Frames will be fetched from |
222 | * now on. |
223 | * @access public |
224 | */ |
225 | function useFrames() { |
226 | $this->_ignore_frames = false; |
227 | } |
228 | |
229 | /** |
230 | * Parses the raw content into a page. Will load further |
231 | * frame pages unless frames are disabled. |
232 | * @param SimpleHttpResponse $response Response from fetch. |
233 | * @return SimplePage Parsed HTML. |
234 | * @access protected |
235 | */ |
236 | function &_parse($response) { |
237 | $builder = &new SimplePageBuilder(); |
238 | $page = &$builder->parse($response); |
239 | if ($this->_ignore_frames || ! $page->hasFrames()) { |
240 | return $page; |
241 | } |
242 | $frameset = &new SimpleFrameset($page); |
243 | foreach ($page->getFrameset() as $key => $url) { |
244 | $frame = &$this->_fetch('GET', $url, array()); |
245 | $frameset->addFrame($frame, $key); |
246 | } |
247 | return $frameset; |
248 | } |
249 | |
250 | /** |
251 | * Fetches a page. |
252 | * @param string $method GET or POST. |
253 | * @param string/SimpleUrl $url Target to fetch as string. |
254 | * @param hash $parameters POST parameters. |
255 | * @return SimplePage Parsed page. |
256 | * @access private |
257 | */ |
258 | function &_fetch($method, $url, $parameters) { |
259 | $response = &$this->_user_agent->fetchResponse($method, $url, $parameters); |
260 | if ($response->isError()) { |
261 | return new SimplePage($response); |
262 | } |
263 | return $this->_parse($response); |
264 | } |
265 | |
266 | /** |
267 | * Fetches a page or a single frame if that is the current |
268 | * focus. |
269 | * @param string $method GET or POST. |
270 | * @param string/SimpleUrl $url Target to fetch as string. |
271 | * @param hash $parameters POST parameters. |
272 | * @return string Raw content of page. |
273 | * @access private |
274 | */ |
275 | function _load($method, $url, $parameters = false) { |
276 | $frame = $url->getTarget(); |
277 | if (! $frame || (strtolower($frame) == '_top')) { |
278 | return $this->_loadPage($method, $url, $parameters); |
279 | } |
280 | return $this->_loadFrame(array($frame), $method, $url, $parameters); |
281 | } |
282 | |
283 | /** |
284 | * Fetches a page and makes it the current page/frame. |
285 | * @param string $method GET or POST. |
286 | * @param string/SimpleUrl $url Target to fetch as string. |
287 | * @param hash $parameters POST parameters. |
288 | * @return string Raw content of page. |
289 | * @access private |
290 | */ |
291 | function _loadPage($method, $url, $parameters = false) { |
292 | $this->_page = &$this->_fetch(strtoupper($method), $url, $parameters); |
293 | $this->_history->recordEntry( |
294 | $this->_page->getMethod(), |
295 | $this->_page->getUrl(), |
296 | $this->_page->getRequestData()); |
297 | return $this->_page->getRaw(); |
298 | } |
299 | |
300 | /** |
301 | * Fetches a frame into the existing frameset replacing the |
302 | * original. |
303 | * @param array $frames List of names to drill down. |
304 | * @param string $method GET or POST. |
305 | * @param string/SimpleUrl $url Target to fetch as string. |
306 | * @param hash $parameters POST parameters. |
307 | * @return string Raw content of page. |
308 | * @access private |
309 | */ |
310 | function _loadFrame($frames, $method, $url, $parameters = false) { |
311 | $page = &$this->_fetch(strtoupper($method), $url, $parameters); |
312 | $this->_page->setFrame($frames, $page); |
313 | } |
314 | |
315 | /** |
316 | * Removes expired and temporary cookies as if |
317 | * the browser was closed and re-opened. |
318 | * @param string/integer $date Time when session restarted. |
319 | * If omitted then all persistent |
320 | * cookies are kept. |
321 | * @access public |
322 | */ |
323 | function restartSession($date = false) { |
324 | $this->_user_agent->restartSession($date); |
325 | } |
326 | |
327 | /** |
328 | * Adds a header to every fetch. |
329 | * @param string $header Header line to add to every |
330 | * request until cleared. |
331 | * @access public |
332 | */ |
333 | function addHeader($header) { |
334 | $this->_user_agent->addHeader($header); |
335 | } |
336 | |
337 | /** |
338 | * Ages the cookies by the specified time. |
339 | * @param integer $interval Amount in seconds. |
340 | * @access public |
341 | */ |
342 | function ageCookies($interval) { |
343 | $this->_user_agent->ageCookies($interval); |
344 | } |
345 | |
346 | /** |
347 | * Sets an additional cookie. If a cookie has |
348 | * the same name and path it is replaced. |
349 | * @param string $name Cookie key. |
350 | * @param string $value Value of cookie. |
351 | * @param string $host Host upon which the cookie is valid. |
352 | * @param string $path Cookie path if not host wide. |
353 | * @param string $expiry Expiry date. |
354 | * @access public |
355 | */ |
356 | function setCookie($name, $value, $host = false, $path = '/', $expiry = false) { |
357 | $this->_user_agent->setCookie($name, $value, $host, $path, $expiry); |
358 | } |
359 | |
360 | /** |
361 | * Reads the most specific cookie value from the |
362 | * browser cookies. |
363 | * @param string $host Host to search. |
364 | * @param string $path Applicable path. |
365 | * @param string $name Name of cookie to read. |
366 | * @return string False if not present, else the |
367 | * value as a string. |
368 | * @access public |
369 | */ |
370 | function getCookieValue($host, $path, $name) { |
371 | return $this->_user_agent->getCookieValue($host, $path, $name); |
372 | } |
373 | |
374 | /** |
375 | * Reads the current cookies for the current URL. |
376 | * @param string $name Key of cookie to find. |
377 | * @return string Null if there is no current URL, false |
378 | * if the cookie is not set. |
379 | * @access public |
380 | */ |
381 | function getCurrentCookieValue($name) { |
382 | return $this->_user_agent->getBaseCookieValue($name, $this->_page->getUrl()); |
383 | } |
384 | |
385 | /** |
386 | * Sets the maximum number of redirects before |
387 | * a page will be loaded anyway. |
388 | * @param integer $max Most hops allowed. |
389 | * @access public |
390 | */ |
391 | function setMaximumRedirects($max) { |
392 | $this->_user_agent->setMaximumRedirects($max); |
393 | } |
394 | |
395 | /** |
396 | * Sets the socket timeout for opening a connection. |
397 | * @param integer $timeout Maximum time in seconds. |
398 | * @access public |
399 | */ |
400 | function setConnectionTimeout($timeout) { |
401 | $this->_user_agent->setConnectionTimeout($timeout); |
402 | } |
403 | |
404 | /** |
405 | * Sets proxy to use on all requests for when |
406 | * testing from behind a firewall. Set URL |
407 | * to false to disable. |
408 | * @param string $proxy Proxy URL. |
409 | * @param string $username Proxy username for authentication. |
410 | * @param string $password Proxy password for authentication. |
411 | * @access public |
412 | */ |
413 | function useProxy($proxy, $username = false, $password = false) { |
414 | $this->_user_agent->useProxy($proxy, $username, $password); |
415 | } |
416 | |
417 | /** |
418 | * Fetches the page content with a HEAD request. |
419 | * Will affect cookies, but will not change the base URL. |
420 | * @param string/SimpleUrl $url Target to fetch as string. |
421 | * @param hash $parameters Additional parameters for GET request. |
422 | * @return boolean True if successful. |
423 | * @access public |
424 | */ |
425 | function head($url, $parameters = false) { |
426 | if (! is_object($url)) { |
427 | $url = new SimpleUrl($url); |
428 | } |
429 | if ($this->getUrl()) { |
430 | $url = $url->makeAbsolute($this->getUrl()); |
431 | } |
432 | $response = &$this->_user_agent->fetchResponse( |
433 | 'HEAD', |
434 | $url, |
435 | $parameters); |
436 | return ! $response->isError(); |
437 | } |
438 | |
439 | /** |
440 | * Fetches the page content with a simple GET request. |
441 | * @param string/SimpleUrl $url Target to fetch. |
442 | * @param hash $parameters Additional parameters for GET request. |
443 | * @return string Content of page or false. |
444 | * @access public |
445 | */ |
446 | function get($url, $parameters = false) { |
447 | if (! is_object($url)) { |
448 | $url = new SimpleUrl($url); |
449 | } |
450 | if ($this->getUrl()) { |
451 | $url = $url->makeAbsolute($this->getUrl()); |
452 | } |
453 | return $this->_load('GET', $url, $parameters); |
454 | } |
455 | |
456 | /** |
457 | * Fetches the page content with a POST request. |
458 | * @param string/SimpleUrl $url Target to fetch as string. |
459 | * @param hash $parameters POST parameters. |
460 | * @return string Content of page. |
461 | * @access public |
462 | */ |
463 | function post($url, $parameters = false) { |
464 | if (! is_object($url)) { |
465 | $url = new SimpleUrl($url); |
466 | } |
467 | if ($this->getUrl()) { |
468 | $url = $url->makeAbsolute($this->getUrl()); |
469 | } |
470 | return $this->_load('POST', $url, $parameters); |
471 | } |
472 | |
473 | /** |
474 | * Equivalent to hitting the retry button on the |
475 | * browser. Will attempt to repeat the page fetch. If |
476 | * there is no history to repeat it will give false. |
477 | * @return string/boolean Content if fetch succeeded |
478 | * else false. |
479 | * @access public |
480 | */ |
481 | function retry() { |
482 | $frames = $this->_page->getFrameFocus(); |
483 | if (count($frames) > 0) { |
484 | $this->_loadFrame( |
485 | $frames, |
486 | $this->_page->getMethod(), |
487 | $this->_page->getUrl(), |
488 | $this->_page->getRequestData()); |
489 | return $this->_page->getRaw(); |
490 | } |
491 | if ($method = $this->_history->getMethod()) { |
492 | $this->_page = &$this->_fetch( |
493 | $method, |
494 | $this->_history->getUrl(), |
495 | $this->_history->getParameters()); |
496 | return $this->_page->getRaw(); |
497 | } |
498 | return false; |
499 | } |
500 | |
501 | /** |
502 | * Equivalent to hitting the back button on the |
503 | * browser. The browser history is unchanged on |
504 | * failure. |
505 | * @return boolean True if history entry and |
506 | * fetch succeeded |
507 | * @access public |
508 | */ |
509 | function back() { |
510 | if (! $this->_history->back()) { |
511 | return false; |
512 | } |
513 | $content = $this->retry(); |
514 | if (! $content) { |
515 | $this->_history->forward(); |
516 | } |
517 | return $content; |
518 | } |
519 | |
520 | /** |
521 | * Equivalent to hitting the forward button on the |
522 | * browser. The browser history is unchanged on |
523 | * failure. |
524 | * @return boolean True if history entry and |
525 | * fetch succeeded |
526 | * @access public |
527 | */ |
528 | function forward() { |
529 | if (! $this->_history->forward()) { |
530 | return false; |
531 | } |
532 | $content = $this->retry(); |
533 | if (! $content) { |
534 | $this->_history->back(); |
535 | } |
536 | return $content; |
537 | } |
538 | |
539 | /** |
540 | * Retries a request after setting the authentication |
541 | * for the current realm. |
542 | * @param string $username Username for realm. |
543 | * @param string $password Password for realm. |
544 | * @return boolean True if successful fetch. Note |
545 | * that authentication may still have |
546 | * failed. |
547 | * @access public |
548 | */ |
549 | function authenticate($username, $password) { |
550 | if (! $this->_page->getRealm()) { |
551 | return false; |
552 | } |
553 | $url = $this->_page->getUrl(); |
554 | if (! $url) { |
555 | return false; |
556 | } |
557 | $this->_user_agent->setIdentity( |
558 | $url->getHost(), |
559 | $this->_page->getRealm(), |
560 | $username, |
561 | $password); |
562 | return $this->retry(); |
563 | } |
564 | |
565 | /** |
566 | * Accessor for a breakdown of the frameset. |
567 | * @return array Hash tree of frames by name |
568 | * or index if no name. |
569 | * @access public |
570 | */ |
571 | function getFrames() { |
572 | return $this->_page->getFrames(); |
573 | } |
574 | |
575 | /** |
576 | * Accessor for current frame focus. Will be |
577 | * false if no frame has focus. |
578 | * @return integer/string/boolean Label if any, otherwise |
579 | * the position in the frameset |
580 | * or false if none. |
581 | * @access public |
582 | */ |
583 | function getFrameFocus() { |
584 | return $this->_page->getFrameFocus(); |
585 | } |
586 | |
587 | /** |
588 | * Sets the focus by index. The integer index starts from 1. |
589 | * @param integer $choice Chosen frame. |
590 | * @return boolean True if frame exists. |
591 | * @access public |
592 | */ |
593 | function setFrameFocusByIndex($choice) { |
594 | return $this->_page->setFrameFocusByIndex($choice); |
595 | } |
596 | |
597 | /** |
598 | * Sets the focus by name. |
599 | * @param string $name Chosen frame. |
600 | * @return boolean True if frame exists. |
601 | * @access public |
602 | */ |
603 | function setFrameFocus($name) { |
604 | return $this->_page->setFrameFocus($name); |
605 | } |
606 | |
607 | /** |
608 | * Clears the frame focus. All frames will be searched |
609 | * for content. |
610 | * @access public |
611 | */ |
612 | function clearFrameFocus() { |
613 | return $this->_page->clearFrameFocus(); |
614 | } |
615 | |
616 | /** |
617 | * Accessor for last error. |
618 | * @return string Error from last response. |
619 | * @access public |
620 | */ |
621 | function getTransportError() { |
622 | return $this->_page->getTransportError(); |
623 | } |
624 | |
625 | /** |
626 | * Accessor for current MIME type. |
627 | * @return string MIME type as string; e.g. 'text/html' |
628 | * @access public |
629 | */ |
630 | function getMimeType() { |
631 | return $this->_page->getMimeType(); |
632 | } |
633 | |
634 | /** |
635 | * Accessor for last response code. |
636 | * @return integer Last HTTP response code received. |
637 | * @access public |
638 | */ |
639 | function getResponseCode() { |
640 | return $this->_page->getResponseCode(); |
641 | } |
642 | |
643 | /** |
644 | * Accessor for last Authentication type. Only valid |
645 | * straight after a challenge (401). |
646 | * @return string Description of challenge type. |
647 | * @access public |
648 | */ |
649 | function getAuthentication() { |
650 | return $this->_page->getAuthentication(); |
651 | } |
652 | |
653 | /** |
654 | * Accessor for last Authentication realm. Only valid |
655 | * straight after a challenge (401). |
656 | * @return string Name of security realm. |
657 | * @access public |
658 | */ |
659 | function getRealm() { |
660 | return $this->_page->getRealm(); |
661 | } |
662 | |
663 | /** |
664 | * Accessor for current URL of page or frame if |
665 | * focused. |
666 | * @return string Location of current page or frame as |
667 | * a string. |
668 | */ |
669 | function getUrl() { |
670 | $url = $this->_page->getUrl(); |
671 | return $url ? $url->asString() : false; |
672 | } |
673 | |
674 | /** |
675 | * Accessor for raw bytes sent down the wire. |
676 | * @return string Original text sent. |
677 | * @access public |
678 | */ |
679 | function getRequest() { |
680 | return $this->_page->getRequest(); |
681 | } |
682 | |
683 | /** |
684 | * Accessor for raw page information. |
685 | * @return string Original text content of web page. |
686 | * @access public |
687 | */ |
688 | function getContent() { |
689 | return $this->_page->getRaw(); |
690 | } |
691 | |
692 | /** |
693 | * Accessor for raw header information. |
694 | * @return string Header block. |
695 | * @access public |
696 | */ |
697 | function getHeaders() { |
698 | return $this->_page->getHeaders(); |
699 | } |
700 | |
701 | /** |
702 | * Accessor for parsed title. |
703 | * @return string Title or false if no title is present. |
704 | * @access public |
705 | */ |
706 | function getTitle() { |
707 | return $this->_page->getTitle(); |
708 | } |
709 | |
710 | /** |
711 | * Accessor for a list of all fixed links in current page. |
712 | * @return array List of urls with scheme of |
713 | * http or https and hostname. |
714 | * @access public |
715 | */ |
716 | function getAbsoluteUrls() { |
717 | return $this->_page->getAbsoluteUrls(); |
718 | } |
719 | |
720 | /** |
721 | * Accessor for a list of all relative links. |
722 | * @return array List of urls without hostname. |
723 | * @access public |
724 | */ |
725 | function getRelativeUrls() { |
726 | return $this->_page->getRelativeUrls(); |
727 | } |
728 | |
729 | /** |
730 | * Sets all form fields with that name. |
731 | * @param string $name Name of field in forms. |
732 | * @param string $value New value of field. |
733 | * @return boolean True if field exists, otherwise false. |
734 | * @access public |
735 | */ |
736 | function setField($name, $value) { |
737 | return $this->_page->setField($name, $value); |
738 | } |
739 | |
740 | /** |
741 | * Sets all form fields with that name. |
742 | * @param string/integer $id Id of field in forms. |
743 | * @param string $value New value of field. |
744 | * @return boolean True if field exists, otherwise false. |
745 | * @access public |
746 | */ |
747 | function setFieldById($id, $value) { |
748 | return $this->_page->setFieldById($id, $value); |
749 | } |
750 | |
751 | /** |
752 | * Accessor for a form element value within the page. |
753 | * Finds the first match. |
754 | * @param string $name Field name. |
755 | * @return string/boolean A string if the field is |
756 | * present, false if unchecked |
757 | * and null if missing. |
758 | * @access public |
759 | */ |
760 | function getField($name) { |
761 | return $this->_page->getField($name); |
762 | } |
763 | |
764 | /** |
765 | * Accessor for a form element value within the page. |
766 | * @param string/integer $id Id of field in forms. |
767 | * @return string/boolean A string if the field is |
768 | * present, false if unchecked |
769 | * and null if missing. |
770 | * @access public |
771 | */ |
772 | function getFieldById($id) { |
773 | return $this->_page->getFieldById($id); |
774 | } |
775 | |
776 | /** |
777 | * Clicks the submit button by label. The owning |
778 | * form will be submitted by this. |
779 | * @param string $label Button label. An unlabeled |
780 | * button can be triggered by 'Submit'. |
781 | * @return boolean True on success. |
782 | * @access public |
783 | */ |
784 | function clickSubmit($label = 'Submit') { |
785 | if (! ($form = &$this->_page->getFormBySubmitLabel($label))) { |
786 | return false; |
787 | } |
788 | return $this->_load( |
789 | $form->getMethod(), |
790 | $form->getAction(), |
791 | $form->submitButtonByLabel($label)); |
792 | } |
793 | |
794 | /** |
795 | * Clicks the submit button by name attribute. The owning |
796 | * form will be submitted by this. |
797 | * @param string $name Button name. |
798 | * @return boolean True on success. |
799 | * @access public |
800 | */ |
801 | function clickSubmitByName($name) { |
802 | if (! ($form = &$this->_page->getFormBySubmitName($name))) { |
803 | return false; |
804 | } |
805 | return $this->_load( |
806 | $form->getMethod(), |
807 | $form->getAction(), |
808 | $form->submitButtonByName($name)); |
809 | } |
810 | |
811 | /** |
812 | * Clicks the submit button by ID attribute of the button |
813 | * itself. The owning form will be submitted by this. |
814 | * @param string $id Button ID. |
815 | * @return boolean True on success. |
816 | * @access public |
817 | */ |
818 | function clickSubmitById($id) { |
819 | if (! ($form = &$this->_page->getFormBySubmitId($id))) { |
820 | return false; |
821 | } |
822 | return $this->_load( |
823 | $form->getMethod(), |
824 | $form->getAction(), |
825 | $form->submitButtonById($id)); |
826 | } |
827 | |
828 | /** |
829 | * Clicks the submit image by some kind of label. Usually |
830 | * the alt tag or the nearest equivalent. The owning |
831 | * form will be submitted by this. Clicking outside of |
832 | * the boundary of the coordinates will result in |
833 | * a failure. |
834 | * @param string $label ID attribute of button. |
835 | * @param integer $x X-coordinate of imaginary click. |
836 | * @param integer $y Y-coordinate of imaginary click. |
837 | * @return boolean True on successful submit. |
838 | * @access public |
839 | */ |
840 | function clickImage($label, $x = 1, $y = 1) { |
841 | if (! ($form = &$this->_page->getFormByImageLabel($label))) { |
842 | return false; |
843 | } |
844 | return $this->_load( |
845 | $form->getMethod(), |
846 | $form->getAction(), |
847 | $form->submitImageByLabel($label, $x, $y)); |
848 | } |
849 | |
850 | /** |
851 | * Clicks the submit image by the name. Usually |
852 | * the alt tag or the nearest equivalent. The owning |
853 | * form will be submitted by this. Clicking outside of |
854 | * the boundary of the coordinates will result in |
855 | * a failure. |
856 | * @param string $name Name attribute of button. |
857 | * @param integer $x X-coordinate of imaginary click. |
858 | * @param integer $y Y-coordinate of imaginary click. |
859 | * @return boolean True on successful submit. |
860 | * @access public |
861 | */ |
862 | function clickImageByName($name, $x = 1, $y = 1) { |
863 | if (! ($form = &$this->_page->getFormByImageName($name))) { |
864 | return false; |
865 | } |
866 | return $this->_load( |
867 | $form->getMethod(), |
868 | $form->getAction(), |
869 | $form->submitImageByName($name, $x, $y)); |
870 | } |
871 | |
872 | /** |
873 | * Clicks the submit image by ID attribute. The owning |
874 | * form will be submitted by this. Clicking outside of |
875 | * the boundary of the coordinates will result in |
876 | * a failure. |
877 | * @param integer/string $id ID attribute of button. |
878 | * @param integer $x X-coordinate of imaginary click. |
879 | * @param integer $y Y-coordinate of imaginary click. |
880 | * @return boolean True on successful submit. |
881 | * @access public |
882 | */ |
883 | function clickImageById($id, $x = 1, $y = 1) { |
884 | if (! ($form = &$this->_page->getFormByImageId($id))) { |
885 | return false; |
886 | } |
887 | return $this->_load( |
888 | $form->getMethod(), |
889 | $form->getAction(), |
890 | $form->submitImageById($id, $x, $y)); |
891 | } |
892 | |
893 | /** |
894 | * Submits a form by the ID. |
895 | * @param string $id The form ID. No submit button value |
896 | * will be sent. |
897 | * @return boolean True on success. |
898 | * @access public |
899 | */ |
900 | function submitFormById($id) { |
901 | if (! ($form = &$this->_page->getFormById($id))) { |
902 | return false; |
903 | } |
904 | return $this->_load( |
905 | $form->getMethod(), |
906 | $form->getAction(), |
907 | $form->submit()); |
908 | } |
909 | |
910 | /** |
911 | * Follows a link by label. Will click the first link |
912 | * found with this link text by default, or a later |
913 | * one if an index is given. The match ignores case and |
914 | * white space issues. |
915 | * @param string $label Text between the anchor tags. |
916 | * @param integer $index Link position counting from zero. |
917 | * @return boolean True if link present. |
918 | * @access public |
919 | */ |
920 | function clickLink($label, $index = 0) { |
921 | $urls = $this->_page->getUrlsByLabel($label); |
922 | if (count($urls) == 0) { |
923 | return false; |
924 | } |
925 | if (count($urls) < $index + 1) { |
926 | return false; |
927 | } |
928 | $this->_load('GET', $urls[$index]); |
929 | return true; |
930 | } |
931 | |
932 | /** |
933 | * Tests to see if a link is present by label. |
934 | * @param string $label Text of value attribute. |
935 | * @return boolean True if link present. |
936 | * @access public |
937 | */ |
938 | function isLink($label) { |
939 | return (count($this->_page->getUrlsByLabel($label)) > 0); |
940 | } |
941 | |
942 | /** |
943 | * Follows a link by id attribute. |
944 | * @param string $id ID attribute value. |
945 | * @return boolean True if link present. |
946 | * @access public |
947 | */ |
948 | function clickLinkById($id) { |
949 | if (! ($url = $this->_page->getUrlById($id))) { |
950 | return false; |
951 | } |
952 | $this->_load('GET', $url); |
953 | return true; |
954 | } |
955 | |
956 | /** |
957 | * Tests to see if a link is present by ID attribute. |
958 | * @param string $id Text of id attribute. |
959 | * @return boolean True if link present. |
960 | * @access public |
961 | */ |
962 | function isLinkById($id) { |
963 | return (boolean)$this->_page->getUrlById($id); |
964 | } |
965 | } |
966 | ?> |