]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - tests/PHPUnit/Extensions/SeleniumTestCase/Driver.php
Added unit tests.
[Github/sugarcrm.git] / tests / PHPUnit / Extensions / SeleniumTestCase / Driver.php
1 <?php
2 /**
3  * PHPUnit
4  *
5  * Copyright (c) 2002-2009, Sebastian Bergmann <sb@sebastian-bergmann.de>.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  *   * Redistributions of source code must retain the above copyright
13  *     notice, this list of conditions and the following disclaimer.
14  *
15  *   * Redistributions in binary form must reproduce the above copyright
16  *     notice, this list of conditions and the following disclaimer in
17  *     the documentation and/or other materials provided with the
18  *     distribution.
19  *
20  *   * Neither the name of Sebastian Bergmann nor the names of his
21  *     contributors may be used to endorse or promote products derived
22  *     from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  *
37  * @category   Testing
38  * @package    PHPUnit
39  * @author     Sebastian Bergmann <sb@sebastian-bergmann.de>
40  * @copyright  2002-2009 Sebastian Bergmann <sb@sebastian-bergmann.de>
41  * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
42
43  * @link       http://www.phpunit.de/
44  * @since      File available since Release 3.3.0
45  */
46
47 require_once 'PHPUnit/Util/Filter.php';
48
49 PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
50
51 /**
52  * Implementation of the Selenium RC client/server protocol.
53  *
54  * @category   Testing
55  * @package    PHPUnit
56  * @author     Sebastian Bergmann <sb@sebastian-bergmann.de>
57  * @copyright  2002-2009 Sebastian Bergmann <sb@sebastian-bergmann.de>
58  * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
59  * @version    Release: 3.3.17
60  * @link       http://www.phpunit.de/
61  * @since      Class available since Release 3.3.0
62  */
63 class PHPUnit_Extensions_SeleniumTestCase_Driver
64 {
65     /**
66      * @var    PHPUnit_Extensions_SeleniumTestCase
67      */
68     protected $testCase;
69
70     /**
71      * @var    string
72      */
73     protected $testId;
74
75     /**
76      * @var    string
77      */
78     protected $name;
79
80     /**
81      * @var    string
82      */
83     protected $browser;
84
85     /**
86      * @var    string
87      */
88     protected $browserUrl;
89
90     /**
91      * @var    boolean
92      */
93     protected $collectCodeCoverageInformation = FALSE;
94
95     /**
96      * @var    string
97      */
98     protected $host = 'localhost';
99
100     /**
101      * @var    integer
102      */
103     protected $port = 4444;
104
105     /**
106      * @var    integer
107      */
108     protected $timeout = 30000;
109
110     /**
111      * @var    array
112      */
113     protected $sessionId;
114
115     /**
116      * @var    integer
117      */
118     protected $sleep = 0;
119
120     /**
121      * @var    boolean
122      */
123     protected $useWaitForPageToLoad = TRUE;
124
125     /**
126      * @var    boolean
127      */
128     protected $wait = 5;
129
130     /**
131      * @return string
132      */
133     public function start()
134     {
135         if ($this->browserUrl == NULL) {
136             throw new RuntimeException(
137               'setBrowserUrl() needs to be called before start().'
138             );
139         }
140
141         if (!isset($this->sessionId)) {
142             $this->sessionId = $this->getString(
143               'getNewBrowserSession',
144               array($this->browser, $this->browserUrl)
145             );
146
147             $this->doCommand('setTimeout', array($this->timeout));
148         }
149
150         return $this->sessionId;
151     }
152
153     /**
154      */
155     public function stop()
156     {
157         if (!isset($this->sessionId)) {
158             return;
159         }
160
161         $this->doCommand('testComplete');
162
163         $this->sessionId = NULL;
164     }
165
166     /**
167      * @param  boolean $flag
168      * @throws InvalidArgumentException
169      */
170     public function setCollectCodeCoverageInformation($flag)
171     {
172         if (!is_bool($flag)) {
173             throw new InvalidArgumentException;
174         }
175
176         $this->collectCodeCoverageInformation = $flag;
177     }
178
179     /**
180      * @param  PHPUnit_Extensions_SeleniumTestCase $testCase
181      */
182     public function setTestCase(PHPUnit_Extensions_SeleniumTestCase $testCase)
183     {
184         $this->testCase = $testCase;
185     }
186
187     /**
188      * @param  integer $testId
189      */
190     public function setTestId($testId)
191     {
192         $this->testId = $testId;
193     }
194
195     /**
196      * @param  string $name
197      * @throws InvalidArgumentException
198      */
199     public function setName($name)
200     {
201         if (!is_string($name)) {
202             throw new InvalidArgumentException;
203         }
204
205         $this->name = $name;
206     }
207
208     /**
209      * @param  string $browser
210      * @throws InvalidArgumentException
211      */
212     public function setBrowser($browser)
213     {
214         if (!is_string($browser)) {
215             throw new InvalidArgumentException;
216         }
217
218         $this->browser = $browser;
219     }
220
221     /**
222      * @param  string $browserUrl
223      * @throws InvalidArgumentException
224      */
225     public function setBrowserUrl($browserUrl)
226     {
227         if (!is_string($browserUrl)) {
228             throw new InvalidArgumentException;
229         }
230
231         $this->browserUrl = $browserUrl;
232     }
233
234     /**
235      * @param  string $host
236      * @throws InvalidArgumentException
237      */
238     public function setHost($host)
239     {
240         if (!is_string($host)) {
241             throw new InvalidArgumentException;
242         }
243
244         $this->host = $host;
245     }
246
247     /**
248      * @param  integer $port
249      * @throws InvalidArgumentException
250      */
251     public function setPort($port)
252     {
253         if (!is_int($port)) {
254             throw new InvalidArgumentException;
255         }
256
257         $this->port = $port;
258     }
259
260     /**
261      * @param  integer $timeout
262      * @throws InvalidArgumentException
263      */
264     public function setTimeout($timeout)
265     {
266         if (!is_int($timeout)) {
267             throw new InvalidArgumentException;
268         }
269
270         $this->timeout = $timeout;
271     }
272
273     /**
274      * @param  integer $seconds
275      * @throws InvalidArgumentException
276      */
277     public function setSleep($seconds)
278     {
279         if (!is_int($seconds)) {
280             throw new InvalidArgumentException;
281         }
282
283         $this->sleep = $seconds;
284     }
285
286     /**
287      * Sets the number of seconds to sleep() after *AndWait commands
288      * when setWaitForPageToLoad(FALSE) is used.
289      *
290      * @param  integer $seconds
291      * @throws InvalidArgumentException
292      */
293     public function setWait($seconds)
294     {
295         if (!is_int($seconds)) {
296             throw new InvalidArgumentException;
297         }
298
299         $this->wait = $seconds;
300     }
301
302     /**
303      * Sets whether waitForPageToLoad (TRUE) or sleep() (FALSE)
304      * is used after *AndWait commands.
305      *
306      * @param  boolean $flag
307      * @throws InvalidArgumentException
308      */
309     public function setWaitForPageToLoad($flag)
310     {
311         if (!is_bool($flag)) {
312             throw new InvalidArgumentException;
313         }
314
315         $this->useWaitForPageToLoad = $flag;
316     }
317
318     /**
319      * This method implements the Selenium RC protocol.
320      *
321      * @param  string $command
322      * @param  array  $arguments
323      * @return mixed
324      * @method unknown  addLocationStrategy()
325      * @method unknown  addSelection()
326      * @method unknown  addSelectionAndWait()
327      * @method unknown  allowNativeXpath()
328      * @method unknown  altKeyDown()
329      * @method unknown  altKeyDownAndWait()
330      * @method unknown  altKeyUp()
331      * @method unknown  altKeyUpAndWait()
332      * @method unknown  answerOnNextPrompt()
333      * @method unknown  assignId()
334      * @method unknown  break()
335      * @method unknown  captureEntirePageScreenshot()
336      * @method unknown  captureScreenshot()
337      * @method unknown  check()
338      * @method unknown  chooseCancelOnNextConfirmation()
339      * @method unknown  chooseOkOnNextConfirmation()
340      * @method unknown  click()
341      * @method unknown  clickAndWait()
342      * @method unknown  clickAt()
343      * @method unknown  clickAtAndWait()
344      * @method unknown  close()
345      * @method unknown  contextMenu()
346      * @method unknown  contextMenuAndWait()
347      * @method unknown  contextMenuAt()
348      * @method unknown  contextMenuAtAndWait()
349      * @method unknown  controlKeyDown()
350      * @method unknown  controlKeyDownAndWait()
351      * @method unknown  controlKeyUp()
352      * @method unknown  controlKeyUpAndWait()
353      * @method unknown  createCookie()
354      * @method unknown  createCookieAndWait()
355      * @method unknown  deleteAllVisibleCookies()
356      * @method unknown  deleteAllVisibleCookiesAndWait()
357      * @method unknown  deleteCookie()
358      * @method unknown  deleteCookieAndWait()
359      * @method unknown  doubleClick()
360      * @method unknown  doubleClickAndWait()
361      * @method unknown  doubleClickAt()
362      * @method unknown  doubleClickAtAndWait()
363      * @method unknown  dragAndDrop()
364      * @method unknown  dragAndDropAndWait()
365      * @method unknown  dragAndDropToObject()
366      * @method unknown  dragAndDropToObjectAndWait()
367      * @method unknown  dragDrop()
368      * @method unknown  dragDropAndWait()
369      * @method unknown  echo()
370      * @method unknown  fireEvent()
371      * @method unknown  fireEventAndWait()
372      * @method unknown  focus()
373      * @method string   getAlert()
374      * @method array    getAllButtons()
375      * @method array    getAllFields()
376      * @method array    getAllLinks()
377      * @method array    getAllWindowIds()
378      * @method array    getAllWindowNames()
379      * @method array    getAllWindowTitles()
380      * @method string   getAttribute()
381      * @method array    getAttributeFromAllWindows()
382      * @method string   getBodyText()
383      * @method string   getConfirmation()
384      * @method string   getCookie()
385      * @method integer  getCursorPosition()
386      * @method integer  getElementHeight()
387      * @method integer  getElementIndex()
388      * @method integer  getElementPositionLeft()
389      * @method integer  getElementPositionTop()
390      * @method integer  getElementWidth()
391      * @method string   getEval()
392      * @method string   getExpression()
393      * @method string   getHtmlSource()
394      * @method string   getLocation()
395      * @method string   getLogMessages()
396      * @method integer  getMouseSpeed()
397      * @method string   getPrompt()
398      * @method array    getSelectOptions()
399      * @method string   getSelectedId()
400      * @method array    getSelectedIds()
401      * @method string   getSelectedIndex()
402      * @method array    getSelectedIndexes()
403      * @method string   getSelectedLabel()
404      * @method array    getSelectedLabels()
405      * @method string   getSelectedValue()
406      * @method array    getSelectedValues()
407      * @method unknown  getSpeed()
408      * @method unknown  getSpeedAndWait()
409      * @method string   getTable()
410      * @method string   getText()
411      * @method string   getTitle()
412      * @method string   getValue()
413      * @method boolean  getWhetherThisFrameMatchFrameExpression()
414      * @method boolean  getWhetherThisWindowMatchWindowExpression()
415      * @method integer  getXpathCount()
416      * @method unknown  goBack()
417      * @method unknown  goBackAndWait()
418      * @method unknown  highlight()
419      * @method unknown  highlightAndWait()
420      * @method unknown  ignoreAttributesWithoutValue()
421      * @method boolean  isAlertPresent()
422      * @method boolean  isChecked()
423      * @method boolean  isConfirmationPresent()
424      * @method boolean  isEditable()
425      * @method boolean  isElementPresent()
426      * @method boolean  isOrdered()
427      * @method boolean  isPromptPresent()
428      * @method boolean  isSomethingSelected()
429      * @method boolean  isTextPresent()
430      * @method boolean  isVisible()
431      * @method unknown  keyDown()
432      * @method unknown  keyDownAndWait()
433      * @method unknown  keyPress()
434      * @method unknown  keyPressAndWait()
435      * @method unknown  keyUp()
436      * @method unknown  keyUpAndWait()
437      * @method unknown  metaKeyDown()
438      * @method unknown  metaKeyDownAndWait()
439      * @method unknown  metaKeyUp()
440      * @method unknown  metaKeyUpAndWait()
441      * @method unknown  mouseDown()
442      * @method unknown  mouseDownAndWait()
443      * @method unknown  mouseDownAt()
444      * @method unknown  mouseDownAtAndWait()
445      * @method unknown  mouseMove()
446      * @method unknown  mouseMoveAndWait()
447      * @method unknown  mouseMoveAt()
448      * @method unknown  mouseMoveAtAndWait()
449      * @method unknown  mouseOut()
450      * @method unknown  mouseOutAndWait()
451      * @method unknown  mouseOver()
452      * @method unknown  mouseOverAndWait()
453      * @method unknown  mouseUp()
454      * @method unknown  mouseUpAndWait()
455      * @method unknown  mouseUpAt()
456      * @method unknown  mouseUpAtAndWait()
457      * @method unknown  mouseUpRight()
458      * @method unknown  mouseUpRightAndWait()
459      * @method unknown  mouseUpRightAt()
460      * @method unknown  mouseUpRightAtAndWait()
461      * @method unknown  open()
462      * @method unknown  openWindow()
463      * @method unknown  openWindowAndWait()
464      * @method unknown  pause()
465      * @method unknown  refresh()
466      * @method unknown  refreshAndWait()
467      * @method unknown  removeAllSelections()
468      * @method unknown  removeAllSelectionsAndWait()
469      * @method unknown  removeSelection()
470      * @method unknown  removeSelectionAndWait()
471      * @method unknown  runScript()
472      * @method unknown  select()
473      * @method unknown  selectAndWait()
474      * @method unknown  selectFrame()
475      * @method unknown  selectWindow()
476      * @method unknown  setBrowserLogLevel()
477      * @method unknown  setContext()
478      * @method unknown  setCursorPosition()
479      * @method unknown  setCursorPositionAndWait()
480      * @method unknown  setMouseSpeed()
481      * @method unknown  setMouseSpeedAndWait()
482      * @method unknown  setSpeed()
483      * @method unknown  setSpeedAndWait()
484      * @method unknown  shiftKeyDown()
485      * @method unknown  shiftKeyDownAndWait()
486      * @method unknown  shiftKeyUp()
487      * @method unknown  shiftKeyUpAndWait()
488      * @method unknown  store()
489      * @method unknown  storeAlert()
490      * @method unknown  storeAlertPresent()
491      * @method unknown  storeAllButtons()
492      * @method unknown  storeAllFields()
493      * @method unknown  storeAllLinks()
494      * @method unknown  storeAllWindowIds()
495      * @method unknown  storeAllWindowNames()
496      * @method unknown  storeAllWindowTitle()s
497      * @method unknown  storeAttribute()
498      * @method unknown  storeAttributeFromAllWindows()
499      * @method unknown  storeBodyText()
500      * @method unknown  storeChecked()
501      * @method unknown  storeConfirmation()
502      * @method unknown  storeConfirmationPresent()
503      * @method unknown  storeCookie()
504      * @method unknown  storeCookieByName()
505      * @method unknown  storeCookiePresent()
506      * @method unknown  storeCursorPosition()
507      * @method unknown  storeEditable()
508      * @method unknown  storeElementHeight()
509      * @method unknown  storeElementIndex()
510      * @method unknown  storeElementPositionLeft()
511      * @method unknown  storeElementPositionTop()
512      * @method unknown  storeElementPresent()
513      * @method unknown  storeElementWidth()
514      * @method unknown  storeEval()
515      * @method unknown  storeExpression()
516      * @method unknown  storeHtmlSource()
517      * @method unknown  storeLocation()
518      * @method unknown  storeMouseSpeed()
519      * @method unknown  storeOrdered()
520      * @method unknown  storePrompt()
521      * @method unknown  storePromptPresent()
522      * @method unknown  storeSelectOptions()
523      * @method unknown  storeSelectedId()
524      * @method unknown  storeSelectedIds()
525      * @method unknown  storeSelectedIndex()
526      * @method unknown  storeSelectedIndexes()
527      * @method unknown  storeSelectedLabel()
528      * @method unknown  storeSelectedLabels()
529      * @method unknown  storeSelectedValue()
530      * @method unknown  storeSelectedValues()
531      * @method unknown  storeSomethingSelected()
532      * @method unknown  storeSpeed()
533      * @method unknown  storeTable()
534      * @method unknown  storeText()
535      * @method unknown  storeTextPresent()
536      * @method unknown  storeTitle()
537      * @method unknown  storeValue()
538      * @method unknown  storeVisible()
539      * @method unknown  storeWhetherThisFrameMatchFrameExpression()
540      * @method unknown  storeWhetherThisWindowMatchWindowExpression()
541      * @method unknown  storeXpathCount()
542      * @method unknown  submit()
543      * @method unknown  submitAndWait()
544      * @method unknown  type()
545      * @method unknown  typeAndWait()
546      * @method unknown  typeKeys()
547      * @method unknown  typeKeysAndWait()
548      * @method unknown  uncheck()
549      * @method unknown  uncheckAndWait()
550      * @method unknown  waitForCondition()
551      * @method unknown  waitForPageToLoad()
552      * @method unknown  waitForPopUp()
553      * @method unknown  windowFocus()
554      * @method unknown  windowMaximize()
555      */
556     public function __call($command, $arguments)
557     {
558         $wait = FALSE;
559
560         if (substr($command, -7, 7) == 'AndWait') {
561             $command = substr($command, 0, -7);
562             $wait    = TRUE;
563         }
564
565         switch ($command) {
566             case 'addLocationStrategy':
567             case 'addSelection':
568             case 'allowNativeXpath':
569             case 'altKeyDown':
570             case 'altKeyUp':
571             case 'answerOnNextPrompt':
572             case 'assignId':
573             case 'break':
574             case 'captureEntirePageScreenshot':
575             case 'captureScreenshot':
576             case 'check':
577             case 'chooseCancelOnNextConfirmation':
578             case 'chooseOkOnNextConfirmation':
579             case 'click':
580             case 'clickAt':
581             case 'close':
582             case 'contextMenu':
583             case 'contextMenuAt':
584             case 'controlKeyDown':
585             case 'controlKeyUp':
586             case 'createCookie':
587             case 'deleteAllVisibleCookies':
588             case 'deleteCookie':
589             case 'doubleClick':
590             case 'doubleClickAt':
591             case 'dragAndDrop':
592             case 'dragAndDropToObject':
593             case 'dragDrop':
594             case 'echo':
595             case 'fireEvent':
596             case 'focus':
597             case 'goBack':
598             case 'highlight':
599             case 'ignoreAttributesWithoutValue':
600             case 'keyDown':
601             case 'keyPress':
602             case 'keyUp':
603             case 'metaKeyDown':
604             case 'metaKeyUp':
605             case 'mouseDown':
606             case 'mouseDownAt':
607             case 'mouseMove':
608             case 'mouseMoveAt':
609             case 'mouseOut':
610             case 'mouseOver':
611             case 'mouseUp':
612             case 'mouseUpAt':
613             case 'mouseUpRight':
614             case 'mouseUpRightAt':
615             case 'open':
616             case 'openWindow':
617             case 'pause':
618             case 'refresh':
619             case 'removeAllSelections':
620             case 'removeSelection':
621             case 'runScript':
622             case 'select':
623             case 'selectFrame':
624             case 'selectWindow':
625             case 'setBrowserLogLevel':
626             case 'setContext':
627             case 'setCursorPosition':
628             case 'setMouseSpeed':
629             case 'setSpeed':
630             case 'shiftKeyDown':
631             case 'shiftKeyUp':
632             case 'store':
633             case 'storeAlert':
634             case 'storeAlertPresent':
635             case 'storeAllButtons':
636             case 'storeAllFields':
637             case 'storeAllLinks':
638             case 'storeAllWindowIds':
639             case 'storeAllWindowNames':
640             case 'storeAllWindowTitles':
641             case 'storeAttribute':
642             case 'storeAttributeFromAllWindows':
643             case 'storeBodyText':
644             case 'storeChecked':
645             case 'storeConfirmation':
646             case 'storeConfirmationPresent':
647             case 'storeCookie':
648             case 'storeCookieByName':
649             case 'storeCookiePresent':
650             case 'storeCursorPosition':
651             case 'storeEditable':
652             case 'storeElementHeight':
653             case 'storeElementIndex':
654             case 'storeElementPositionLeft':
655             case 'storeElementPositionTop':
656             case 'storeElementPresent':
657             case 'storeElementWidth':
658             case 'storeEval':
659             case 'storeExpression':
660             case 'storeHtmlSource':
661             case 'storeLocation':
662             case 'storeMouseSpeed':
663             case 'storeOrdered':
664             case 'storePrompt':
665             case 'storePromptPresent':
666             case 'storeSelectOptions':
667             case 'storeSelectedId':
668             case 'storeSelectedIds':
669             case 'storeSelectedIndex':
670             case 'storeSelectedIndexes':
671             case 'storeSelectedLabel':
672             case 'storeSelectedLabels':
673             case 'storeSelectedValue':
674             case 'storeSelectedValues':
675             case 'storeSomethingSelected':
676             case 'storeSpeed':
677             case 'storeTable':
678             case 'storeText':
679             case 'storeTextPresent':
680             case 'storeTitle':
681             case 'storeValue':
682             case 'storeVisible':
683             case 'storeWhetherThisFrameMatchFrameExpression':
684             case 'storeWhetherThisWindowMatchWindowExpression':
685             case 'storeXpathCount':
686             case 'submit':
687             case 'type':
688             case 'typeKeys':
689             case 'uncheck':
690             case 'windowFocus':
691             case 'windowMaximize': {
692                 // Pre-Command Actions
693                 switch ($command) {
694                     case 'open':
695                     case 'openWindow': {
696                         if ($this->collectCodeCoverageInformation) {
697                             $this->deleteCookie('PHPUNIT_SELENIUM_TEST_ID', 'path=/');
698
699                             $this->createCookie(
700                               'PHPUNIT_SELENIUM_TEST_ID=' . $this->testId,
701                               'path=/'
702                             );
703                         }
704                     }
705                     break;
706                 }
707
708                 $this->doCommand($command, $arguments);
709
710                 // Post-Command Actions
711                 switch ($command) {
712                     case 'addLocationStrategy':
713                     case 'allowNativeXpath':
714                     case 'assignId':
715                     case 'captureScreenshot': {
716                         // intentionally empty
717                     }
718                     break;
719
720                     default: {
721                         if ($wait) {
722                             if ($this->useWaitForPageToLoad) {
723                                 $this->waitForPageToLoad($this->timeout);
724                             } else {
725                                 sleep($this->wait);
726                             }
727                         }
728
729                         if ($this->sleep > 0) {
730                             sleep($this->sleep);
731                         }
732
733                         $this->testCase->runDefaultAssertions($command);
734                     }
735                 }
736             }
737             break;
738
739             case 'getWhetherThisFrameMatchFrameExpression':
740             case 'getWhetherThisWindowMatchWindowExpression':
741             case 'isAlertPresent':
742             case 'isChecked':
743             case 'isConfirmationPresent':
744             case 'isEditable':
745             case 'isElementPresent':
746             case 'isOrdered':
747             case 'isPromptPresent':
748             case 'isSomethingSelected':
749             case 'isTextPresent':
750             case 'isVisible': {
751                 return $this->getBoolean($command, $arguments);
752             }
753             break;
754
755             case 'getCursorPosition':
756             case 'getElementHeight':
757             case 'getElementIndex':
758             case 'getElementPositionLeft':
759             case 'getElementPositionTop':
760             case 'getElementWidth':
761             case 'getMouseSpeed':
762             case 'getSpeed':
763             case 'getXpathCount': {
764                 $result = $this->getNumber($command, $arguments);
765
766                 if ($wait) {
767                     $this->waitForPageToLoad($this->timeout);
768                 }
769
770                 return $result;
771             }
772             break;
773
774             case 'getAlert':
775             case 'getAttribute':
776             case 'getBodyText':
777             case 'getConfirmation':
778             case 'getCookie':
779             case 'getEval':
780             case 'getExpression':
781             case 'getHtmlSource':
782             case 'getLocation':
783             case 'getLogMessages':
784             case 'getPrompt':
785             case 'getSelectedId':
786             case 'getSelectedIndex':
787             case 'getSelectedLabel':
788             case 'getSelectedValue':
789             case 'getTable':
790             case 'getText':
791             case 'getTitle':
792             case 'getValue': {
793                 $result = $this->getString($command, $arguments);
794
795                 if ($wait) {
796                     $this->waitForPageToLoad($this->timeout);
797                 }
798
799                 return $result;
800             }
801             break;
802
803             case 'getAllButtons':
804             case 'getAllFields':
805             case 'getAllLinks':
806             case 'getAllWindowIds':
807             case 'getAllWindowNames':
808             case 'getAllWindowTitles':
809             case 'getAttributeFromAllWindows':
810             case 'getSelectedIds':
811             case 'getSelectedIndexes':
812             case 'getSelectedLabels':
813             case 'getSelectedValues':
814             case 'getSelectOptions': {
815                 $result = $this->getStringArray($command, $arguments);
816
817                 if ($wait) {
818                     $this->waitForPageToLoad($this->timeout);
819                 }
820
821                 return $result;
822             }
823             break;
824
825             case 'waitForCondition':
826             case 'waitForFrameToLoad':
827             case 'waitForPopUp': {
828                 if (count($arguments) == 1) {
829                     $arguments[] = $this->timeout;
830                 }
831
832                 $this->doCommand($command, $arguments);
833                 $this->testCase->runDefaultAssertions($command);
834             }
835             break;
836
837             case 'waitForPageToLoad': {
838                 if (empty($arguments)) {
839                     $arguments[] = $this->timeout;
840                 }
841
842                 $this->doCommand($command, $arguments);
843                 $this->testCase->runDefaultAssertions($command);
844             }
845             break;
846
847             default: {
848                 $this->stop();
849
850                 throw new BadMethodCallException(
851                   "Method $command not defined."
852                 );
853             }
854         }
855     }
856
857     /**
858      * Send a command to the Selenium RC server.
859      *
860      * @param  string $command
861      * @param  array  $arguments
862      * @return string
863      * @author Shin Ohno <ganchiku@gmail.com>
864      * @author Bjoern Schotte <schotte@mayflower.de>
865      */
866     protected function doCommand($command, array $arguments = array())
867     {
868         if (!ini_get('allow_url_fopen')) {
869             throw new RuntimeException(
870               'Could not connect to the Selenium RC server because allow_url_fopen is disabled.'
871             );
872         }
873
874         $url = sprintf(
875           'http://%s:%s/selenium-server/driver/?cmd=%s',
876           $this->host,
877           $this->port,
878           urlencode($command)
879         );
880
881         $numArguments = count($arguments);
882
883         for ($i = 0; $i < $numArguments; $i++) {
884             $argNum = strval($i + 1);
885             $url .= sprintf('&%s=%s', $argNum, urlencode(trim($arguments[$i])));
886         }
887
888         if (isset($this->sessionId)) {
889             $url .= sprintf('&%s=%s', 'sessionId', $this->sessionId);
890         }
891
892         $handle = @fopen($url, 'r');
893
894         if (!$handle) {
895             throw new RuntimeException(
896               'Could not connect to the Selenium RC server.'
897             );
898         }
899
900         stream_set_blocking($handle, 1);
901         stream_set_timeout($handle, 0, $this->timeout);
902
903         $info     = stream_get_meta_data($handle);
904         $response = '';
905
906         while (!$info['eof'] && !$info['timed_out']) {
907             $response .= fgets($handle, 4096);
908             $info = stream_get_meta_data($handle);
909         }
910
911         fclose($handle);
912
913         if (!preg_match('/^OK/', $response)) {
914             $this->stop();
915
916             throw new RuntimeException(
917               'The response from the Selenium RC server is invalid: ' . $response
918             );
919         }
920
921         return $response;
922     }
923
924     /**
925      * Send a command to the Selenium RC server and treat the result
926      * as a boolean.
927      *
928      * @param  string $command
929      * @param  array  $arguments
930      * @return boolean
931      * @author Shin Ohno <ganchiku@gmail.com>
932      * @author Bjoern Schotte <schotte@mayflower.de>
933      */
934     protected function getBoolean($command, array $arguments)
935     {
936         $result = $this->getString($command, $arguments);
937
938         switch ($result) {
939             case 'true':  return TRUE;
940
941             case 'false': return FALSE;
942
943             default: {
944                 $this->stop();
945
946                 throw new RuntimeException(
947                   'Result is neither "true" nor "false": ' . PHPUnit_Util_Type::toString($result, TRUE)
948                 );
949             }
950         }
951     }
952
953     /**
954      * Send a command to the Selenium RC server and treat the result
955      * as a number.
956      *
957      * @param  string $command
958      * @param  array  $arguments
959      * @return numeric
960      * @author Shin Ohno <ganchiku@gmail.com>
961      * @author Bjoern Schotte <schotte@mayflower.de>
962      */
963     protected function getNumber($command, array $arguments)
964     {
965         $result = $this->getString($command, $arguments);
966
967         if (!is_numeric($result)) {
968             $this->stop();
969
970             throw new RuntimeException(
971               'Result is not numeric: ' . PHPUnit_Util_Type::toString($result, TRUE)
972             );
973         }
974
975         return $result;
976     }
977
978     /**
979      * Send a command to the Selenium RC server and treat the result
980      * as a string.
981      *
982      * @param  string $command
983      * @param  array  $arguments
984      * @return string
985      * @author Shin Ohno <ganchiku@gmail.com>
986      * @author Bjoern Schotte <schotte@mayflower.de>
987      */
988     protected function getString($command, array $arguments)
989     {
990         try {
991             $result = $this->doCommand($command, $arguments);
992         }
993
994         catch (RuntimeException $e) {
995             $this->stop();
996
997             throw $e;
998         }
999
1000         return (strlen($result) > 3) ? substr($result, 3) : '';
1001     }
1002
1003     /**
1004      * Send a command to the Selenium RC server and treat the result
1005      * as an array of strings.
1006      *
1007      * @param  string $command
1008      * @param  array  $arguments
1009      * @return array
1010      * @author Shin Ohno <ganchiku@gmail.com>
1011      * @author Bjoern Schotte <schotte@mayflower.de>
1012      */
1013     protected function getStringArray($command, array $arguments)
1014     {
1015         $csv     = $this->getString($command, $arguments);
1016         $token   = '';
1017         $tokens  = array();
1018         $letters = preg_split('//', $csv, -1, PREG_SPLIT_NO_EMPTY);
1019         $count   = count($letters);
1020
1021         for ($i = 0; $i < $count; $i++) {
1022             $letter = $letters[$i];
1023
1024             switch($letter) {
1025                 case '\\': {
1026                     $letter = $letters[++$i];
1027                     $token .= $letter;
1028                 }
1029                 break;
1030
1031                 case ',': {
1032                     $tokens[] = $token;
1033                     $token    = '';
1034                 }
1035                 break;
1036
1037                 default: {
1038                     $token .= $letter;
1039                 }
1040             }
1041         }
1042
1043         $tokens[] = $token;
1044
1045         return $tokens;
1046     }
1047 }
1048 ?>