source: trunk/server/www/vendors/simpletest/frames.php @ 6

Last change on this file since 6 was 6, checked in by sander, 12 years ago

Added SimpleTest? test framework

File size: 18.2 KB
Line 
1<?php
2/**
3 *  Base include file for SimpleTest
4 *  @package    SimpleTest
5 *  @subpackage WebTester
6 *  @version    $Id: frames.php 1672 2008-03-02 04:47:34Z edwardzyang $
7 */
8
9/**#@+
10 *  include other SimpleTest class files
11 */
12require_once(dirname(__FILE__) . '/page.php');
13require_once(dirname(__FILE__) . '/user_agent.php');
14/**#@-*/
15
16/**
17 *    A composite page. Wraps a frameset page and
18 *    adds subframes. The original page will be
19 *    mostly ignored. Implements the SimplePage
20 *    interface so as to be interchangeable.
21 *    @package SimpleTest
22 *    @subpackage WebTester
23 */
24class SimpleFrameset {
25    var $_frameset;
26    var $_frames;
27    var $_focus;
28    var $_names;
29
30    /**
31     *    Stashes the frameset page. Will make use of the
32     *    browser to fetch the sub frames recursively.
33     *    @param SimplePage $page        Frameset page.
34     */
35    function SimpleFrameset(&$page) {
36        $this->_frameset = &$page;
37        $this->_frames = array();
38        $this->_focus = false;
39        $this->_names = array();
40    }
41
42    /**
43     *    Adds a parsed page to the frameset.
44     *    @param SimplePage $page    Frame page.
45     *    @param string $name        Name of frame in frameset.
46     *    @access public
47     */
48    function addFrame(&$page, $name = false) {
49        $this->_frames[] = &$page;
50        if ($name) {
51            $this->_names[$name] = count($this->_frames) - 1;
52        }
53    }
54
55    /**
56     *    Replaces existing frame with another. If the
57     *    frame is nested, then the call is passed down
58     *    one level.
59     *    @param array $path        Path of frame in frameset.
60     *    @param SimplePage $page   Frame source.
61     *    @access public
62     */
63    function setFrame($path, &$page) {
64        $name = array_shift($path);
65        if (isset($this->_names[$name])) {
66            $index = $this->_names[$name];
67        } else {
68            $index = $name - 1;
69        }
70        if (count($path) == 0) {
71            $this->_frames[$index] = &$page;
72            return;
73        }
74        $this->_frames[$index]->setFrame($path, $page);
75    }
76
77    /**
78     *    Accessor for current frame focus. Will be
79     *    false if no frame has focus. Will have the nested
80     *    frame focus if any.
81     *    @return array     Labels or indexes of nested frames.
82     *    @access public
83     */
84    function getFrameFocus() {
85        if ($this->_focus === false) {
86            return array();
87        }
88        return array_merge(
89                array($this->_getPublicNameFromIndex($this->_focus)),
90                $this->_frames[$this->_focus]->getFrameFocus());
91    }
92
93    /**
94     *    Turns an internal array index into the frames list
95     *    into a public name, or if none, then a one offset
96     *    index.
97     *    @param integer $subject    Internal index.
98     *    @return integer/string     Public name.
99     *    @access private
100     */
101    function _getPublicNameFromIndex($subject) {
102        foreach ($this->_names as $name => $index) {
103            if ($subject == $index) {
104                return $name;
105            }
106        }
107        return $subject + 1;
108    }
109
110    /**
111     *    Sets the focus by index. The integer index starts from 1.
112     *    If already focused and the target frame also has frames,
113     *    then the nested frame will be focused.
114     *    @param integer $choice    Chosen frame.
115     *    @return boolean           True if frame exists.
116     *    @access public
117     */
118    function setFrameFocusByIndex($choice) {
119        if (is_integer($this->_focus)) {
120            if ($this->_frames[$this->_focus]->hasFrames()) {
121                return $this->_frames[$this->_focus]->setFrameFocusByIndex($choice);
122            }
123        }
124        if (($choice < 1) || ($choice > count($this->_frames))) {
125            return false;
126        }
127        $this->_focus = $choice - 1;
128        return true;
129    }
130
131    /**
132     *    Sets the focus by name. If already focused and the
133     *    target frame also has frames, then the nested frame
134     *    will be focused.
135     *    @param string $name    Chosen frame.
136     *    @return boolean        True if frame exists.
137     *    @access public
138     */
139    function setFrameFocus($name) {
140        if (is_integer($this->_focus)) {
141            if ($this->_frames[$this->_focus]->hasFrames()) {
142                return $this->_frames[$this->_focus]->setFrameFocus($name);
143            }
144        }
145        if (in_array($name, array_keys($this->_names))) {
146            $this->_focus = $this->_names[$name];
147            return true;
148        }
149        return false;
150    }
151
152    /**
153     *    Clears the frame focus.
154     *    @access public
155     */
156    function clearFrameFocus() {
157        $this->_focus = false;
158        $this->_clearNestedFramesFocus();
159    }
160
161    /**
162     *    Clears the frame focus for any nested frames.
163     *    @access private
164     */
165    function _clearNestedFramesFocus() {
166        for ($i = 0; $i < count($this->_frames); $i++) {
167            $this->_frames[$i]->clearFrameFocus();
168        }
169    }
170
171    /**
172     *    Test for the presence of a frameset.
173     *    @return boolean        Always true.
174     *    @access public
175     */
176    function hasFrames() {
177        return true;
178    }
179
180    /**
181     *    Accessor for frames information.
182     *    @return array/string      Recursive hash of frame URL strings.
183     *                              The key is either a numerical
184     *                              index or the name attribute.
185     *    @access public
186     */
187    function getFrames() {
188        $report = array();
189        for ($i = 0; $i < count($this->_frames); $i++) {
190            $report[$this->_getPublicNameFromIndex($i)] =
191                    $this->_frames[$i]->getFrames();
192        }
193        return $report;
194    }
195
196    /**
197     *    Accessor for raw text of either all the pages or
198     *    the frame in focus.
199     *    @return string        Raw unparsed content.
200     *    @access public
201     */
202    function getRaw() {
203        if (is_integer($this->_focus)) {
204            return $this->_frames[$this->_focus]->getRaw();
205        }
206        $raw = '';
207        for ($i = 0; $i < count($this->_frames); $i++) {
208            $raw .= $this->_frames[$i]->getRaw();
209        }
210        return $raw;
211    }
212
213    /**
214     *    Accessor for plain text of either all the pages or
215     *    the frame in focus.
216     *    @return string        Plain text content.
217     *    @access public
218     */
219    function getText() {
220        if (is_integer($this->_focus)) {
221            return $this->_frames[$this->_focus]->getText();
222        }
223        $raw = '';
224        for ($i = 0; $i < count($this->_frames); $i++) {
225            $raw .= ' ' . $this->_frames[$i]->getText();
226        }
227        return trim($raw);
228    }
229
230    /**
231     *    Accessor for last error.
232     *    @return string        Error from last response.
233     *    @access public
234     */
235    function getTransportError() {
236        if (is_integer($this->_focus)) {
237            return $this->_frames[$this->_focus]->getTransportError();
238        }
239        return $this->_frameset->getTransportError();
240    }
241
242    /**
243     *    Request method used to fetch this frame.
244     *    @return string      GET, POST or HEAD.
245     *    @access public
246     */
247    function getMethod() {
248        if (is_integer($this->_focus)) {
249            return $this->_frames[$this->_focus]->getMethod();
250        }
251        return $this->_frameset->getMethod();
252    }
253
254    /**
255     *    Original resource name.
256     *    @return SimpleUrl        Current url.
257     *    @access public
258     */
259    function getUrl() {
260        if (is_integer($this->_focus)) {
261            $url = $this->_frames[$this->_focus]->getUrl();
262            $url->setTarget($this->_getPublicNameFromIndex($this->_focus));
263        } else {
264            $url = $this->_frameset->getUrl();
265        }
266        return $url;
267    }
268
269    /**
270     *    Page base URL.
271     *    @return SimpleUrl        Current url.
272     *    @access public
273     */
274    function getBaseUrl() {
275        if (is_integer($this->_focus)) {
276            $url = $this->_frames[$this->_focus]->getBaseUrl();
277        } else {
278            $url = $this->_frameset->getBaseUrl();
279        }
280        return $url;
281    }
282
283    /**
284     *    Expands expandomatic URLs into fully qualified
285     *    URLs for the frameset page.
286     *    @param SimpleUrl $url        Relative URL.
287     *    @return SimpleUrl            Absolute URL.
288     *    @access public
289     */
290    function expandUrl($url) {
291        return $this->_frameset->expandUrl($url);
292    }
293
294    /**
295     *    Original request data.
296     *    @return mixed              Sent content.
297     *    @access public
298     */
299    function getRequestData() {
300        if (is_integer($this->_focus)) {
301            return $this->_frames[$this->_focus]->getRequestData();
302        }
303        return $this->_frameset->getRequestData();
304    }
305
306    /**
307     *    Accessor for current MIME type.
308     *    @return string    MIME type as string; e.g. 'text/html'
309     *    @access public
310     */
311    function getMimeType() {
312        if (is_integer($this->_focus)) {
313            return $this->_frames[$this->_focus]->getMimeType();
314        }
315        return $this->_frameset->getMimeType();
316    }
317
318    /**
319     *    Accessor for last response code.
320     *    @return integer    Last HTTP response code received.
321     *    @access public
322     */
323    function getResponseCode() {
324        if (is_integer($this->_focus)) {
325            return $this->_frames[$this->_focus]->getResponseCode();
326        }
327        return $this->_frameset->getResponseCode();
328    }
329
330    /**
331     *    Accessor for last Authentication type. Only valid
332     *    straight after a challenge (401).
333     *    @return string    Description of challenge type.
334     *    @access public
335     */
336    function getAuthentication() {
337        if (is_integer($this->_focus)) {
338            return $this->_frames[$this->_focus]->getAuthentication();
339        }
340        return $this->_frameset->getAuthentication();
341    }
342
343    /**
344     *    Accessor for last Authentication realm. Only valid
345     *    straight after a challenge (401).
346     *    @return string    Name of security realm.
347     *    @access public
348     */
349    function getRealm() {
350        if (is_integer($this->_focus)) {
351            return $this->_frames[$this->_focus]->getRealm();
352        }
353        return $this->_frameset->getRealm();
354    }
355
356    /**
357     *    Accessor for outgoing header information.
358     *    @return string      Header block.
359     *    @access public
360     */
361    function getRequest() {
362        if (is_integer($this->_focus)) {
363            return $this->_frames[$this->_focus]->getRequest();
364        }
365        return $this->_frameset->getRequest();
366    }
367
368    /**
369     *    Accessor for raw header information.
370     *    @return string      Header block.
371     *    @access public
372     */
373    function getHeaders() {
374        if (is_integer($this->_focus)) {
375            return $this->_frames[$this->_focus]->getHeaders();
376        }
377        return $this->_frameset->getHeaders();
378    }
379
380    /**
381     *    Accessor for parsed title.
382     *    @return string     Title or false if no title is present.
383     *    @access public
384     */
385    function getTitle() {
386        return $this->_frameset->getTitle();
387    }
388
389    /**
390     *    Accessor for a list of all fixed links.
391     *    @return array   List of urls as strings.
392     *    @access public
393     */
394    function getUrls() {
395        if (is_integer($this->_focus)) {
396            return $this->_frames[$this->_focus]->getUrls();
397        }
398        $urls = array();
399        foreach ($this->_frames as $frame) {
400            $urls = array_merge($urls, $frame->getUrls());
401        }
402        return array_values(array_unique($urls));
403    }
404
405    /**
406     *    Accessor for URLs by the link label. Label will match
407     *    regardess of whitespace issues and case.
408     *    @param string $label    Text of link.
409     *    @return array           List of links with that label.
410     *    @access public
411     */
412    function getUrlsByLabel($label) {
413        if (is_integer($this->_focus)) {
414            return $this->_tagUrlsWithFrame(
415                    $this->_frames[$this->_focus]->getUrlsByLabel($label),
416                    $this->_focus);
417        }
418        $urls = array();
419        foreach ($this->_frames as $index => $frame) {
420            $urls = array_merge(
421                    $urls,
422                    $this->_tagUrlsWithFrame(
423                                $frame->getUrlsByLabel($label),
424                                $index));
425        }
426        return $urls;
427    }
428
429    /**
430     *    Accessor for a URL by the id attribute. If in a frameset
431     *    then the first link found with that ID attribute is
432     *    returned only. Focus on a frame if you want one from
433     *    a specific part of the frameset.
434     *    @param string $id       Id attribute of link.
435     *    @return string          URL with that id.
436     *    @access public
437     */
438    function getUrlById($id) {
439        foreach ($this->_frames as $index => $frame) {
440            if ($url = $frame->getUrlById($id)) {
441                if (! $url->gettarget()) {
442                    $url->setTarget($this->_getPublicNameFromIndex($index));
443                }
444                return $url;
445            }
446        }
447        return false;
448    }
449
450    /**
451     *    Attaches the intended frame index to a list of URLs.
452     *    @param array $urls        List of SimpleUrls.
453     *    @param string $frame      Name of frame or index.
454     *    @return array             List of tagged URLs.
455     *    @access private
456     */
457    function _tagUrlsWithFrame($urls, $frame) {
458        $tagged = array();
459        foreach ($urls as $url) {
460            if (! $url->getTarget()) {
461                $url->setTarget($this->_getPublicNameFromIndex($frame));
462            }
463            $tagged[] = $url;
464        }
465        return $tagged;
466    }
467
468    /**
469     *    Finds a held form by button label. Will only
470     *    search correctly built forms.
471     *    @param SimpleSelector $selector       Button finder.
472     *    @return SimpleForm                    Form object containing
473     *                                          the button.
474     *    @access public
475     */
476    function &getFormBySubmit($selector) {
477        $form = &$this->_findForm('getFormBySubmit', $selector);
478        return $form;
479    }
480
481    /**
482     *    Finds a held form by image using a selector.
483     *    Will only search correctly built forms. The first
484     *    form found either within the focused frame, or
485     *    across frames, will be the one returned.
486     *    @param SimpleSelector $selector  Image finder.
487     *    @return SimpleForm               Form object containing
488     *                                     the image.
489     *    @access public
490     */
491    function &getFormByImage($selector) {
492        $form = &$this->_findForm('getFormByImage', $selector);
493        return $form;
494    }
495
496    /**
497     *    Finds a held form by the form ID. A way of
498     *    identifying a specific form when we have control
499     *    of the HTML code. The first form found
500     *    either within the focused frame, or across frames,
501     *    will be the one returned.
502     *    @param string $id     Form label.
503     *    @return SimpleForm    Form object containing the matching ID.
504     *    @access public
505     */
506    function &getFormById($id) {
507        $form = &$this->_findForm('getFormById', $id);
508        return $form;
509    }
510
511    /**
512        *    General form finder. Will search all the frames or
513        *    just the one in focus.
514        *    @param string $method    Method to use to find in a page.
515        *    @param string $attribute Label, name or ID.
516        *    @return SimpleForm    Form object containing the matching ID.
517        *    @access private
518        */
519    function &_findForm($method, $attribute) {
520        if (is_integer($this->_focus)) {
521            $form = &$this->_findFormInFrame(
522                    $this->_frames[$this->_focus],
523                    $this->_focus,
524                    $method,
525                    $attribute);
526            return $form;
527        }
528        for ($i = 0; $i < count($this->_frames); $i++) {
529            $form = &$this->_findFormInFrame(
530                    $this->_frames[$i],
531                    $i,
532                    $method,
533                    $attribute);
534            if ($form) {
535                return $form;
536            }
537        }
538        $null = null;
539        return $null;
540    }
541
542    /**
543     *    Finds a form in a page using a form finding method. Will
544     *    also tag the form with the frame name it belongs in.
545     *    @param SimplePage $page  Page content of frame.
546     *    @param integer $index    Internal frame representation.
547     *    @param string $method    Method to use to find in a page.
548     *    @param string $attribute Label, name or ID.
549     *    @return SimpleForm       Form object containing the matching ID.
550     *    @access private
551     */
552    function &_findFormInFrame(&$page, $index, $method, $attribute) {
553        $form = &$this->_frames[$index]->$method($attribute);
554        if (isset($form)) {
555            $form->setDefaultTarget($this->_getPublicNameFromIndex($index));
556        }
557        return $form;
558    }
559
560    /**
561     *    Sets a field on each form in which the field is
562     *    available.
563     *    @param SimpleSelector $selector    Field finder.
564     *    @param string $value               Value to set field to.
565     *    @return boolean                    True if value is valid.
566     *    @access public
567     */
568    function setField($selector, $value) {
569        if (is_integer($this->_focus)) {
570            $this->_frames[$this->_focus]->setField($selector, $value);
571        } else {
572            for ($i = 0; $i < count($this->_frames); $i++) {
573                $this->_frames[$i]->setField($selector, $value);
574            }
575        }
576    }
577
578    /**
579     *    Accessor for a form element value within a page.
580     *    @param SimpleSelector $selector    Field finder.
581     *    @return string/boolean             A string if the field is
582     *                                       present, false if unchecked
583     *                                       and null if missing.
584     *    @access public
585     */
586    function getField($selector) {
587        for ($i = 0; $i < count($this->_frames); $i++) {
588            $value = $this->_frames[$i]->getField($selector);
589            if (isset($value)) {
590                return $value;
591            }
592        }
593        return null;
594    }
595}
596?>
Note: See TracBrowser for help on using the repository browser.