Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * PHPUnit
4
 *
5
 * Copyright (c) 2002-2010, 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-2010 Sebastian Bergmann <sb@sebastian-bergmann.de>
41
 * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
42
 * @link       http://www.phpunit.de/
43
 * @since      File available since Release 3.3.0
44
 */
45
 
46
require_once 'PHPUnit/Util/Filter.php';
47
 
48
PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
49
 
50
/**
51
 * Implementation of the Selenium RC client/server protocol.
52
 *
53
 * @category   Testing
54
 * @package    PHPUnit
55
 * @author     Sebastian Bergmann <sb@sebastian-bergmann.de>
56
 * @copyright  2002-2010 Sebastian Bergmann <sb@sebastian-bergmann.de>
57
 * @license    http://www.opensource.org/licenses/bsd-license.php  BSD License
58
 * @version    Release: 3.4.15
59
 * @link       http://www.phpunit.de/
60
 * @since      Class available since Release 3.3.0
61
 */
62
class PHPUnit_Extensions_SeleniumTestCase_Driver
63
{
64
    /**
65
     * @var    PHPUnit_Extensions_SeleniumTestCase
66
     */
67
    protected $testCase;
68
 
69
    /**
70
     * @var    string
71
     */
72
    protected $testId;
73
 
74
    /**
75
     * @var    string
76
     */
77
    protected $name;
78
 
79
    /**
80
     * @var    string
81
     */
82
    protected $browser;
83
 
84
    /**
85
     * @var    string
86
     */
87
    protected $browserUrl;
88
 
89
    /**
90
     * @var    boolean
91
     */
92
    protected $collectCodeCoverageInformation = FALSE;
93
 
94
    /**
95
     * @var    string
96
     */
97
    protected $host = 'localhost';
98
 
99
    /**
100
     * @var    integer
101
     */
102
    protected $port = 4444;
103
 
104
    /**
105
     * @var    integer
106
     */
107
    protected $httpTimeout = 45;
108
 
109
    /**
110
     * @var    integer
111
     */
112
    protected $seleniumTimeout = 30;
113
 
114
    /**
115
     * @var    array
116
     */
117
    protected $sessionId;
118
 
119
    /**
120
     * @var    integer
121
     */
122
    protected $sleep = 0;
123
 
124
    /**
125
     * @var    boolean
126
     */
127
    protected $useWaitForPageToLoad = TRUE;
128
 
129
    /**
130
     * @var    boolean
131
     */
132
    protected $wait = 5;
133
 
134
    /**
135
     * @var array
136
     */
137
    protected static $autoGeneratedCommands = array();
138
 
139
    /**
140
     * @var array
141
     */
142
    protected $commands = array();
143
 
144
    /**
145
     * @var array
146
     */
147
    protected $verificationErrors = array();
148
 
149
    public function __construct()
150
    {
151
        if (empty(self::$autoGeneratedCommands)) {
152
            self::autoGenerateCommands();
153
        }
154
    }
155
 
156
    /**
157
     * @return string
158
     */
159
    public function start()
160
    {
161
        if ($this->browserUrl == NULL) {
162
            throw new PHPUnit_Framework_Exception(
163
              'setBrowserUrl() needs to be called before start().'
164
            );
165
        }
166
 
167
        if (!isset($this->sessionId)) {
168
            $this->sessionId = $this->getString(
169
              'getNewBrowserSession',
170
              array($this->browser, $this->browserUrl)
171
            );
172
 
173
            $this->doCommand('setTimeout', array($this->seleniumTimeout * 1000));
174
        }
175
 
176
        return $this->sessionId;
177
    }
178
 
179
    /**
180
     */
181
    public function stop()
182
    {
183
        if (!isset($this->sessionId)) {
184
            return;
185
        }
186
 
187
        $this->doCommand('testComplete');
188
 
189
        $this->sessionId = NULL;
190
    }
191
 
192
    /**
193
     * @param  boolean $flag
194
     * @throws InvalidArgumentException
195
     */
196
    public function setCollectCodeCoverageInformation($flag)
197
    {
198
        if (!is_bool($flag)) {
199
            throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
200
        }
201
 
202
        $this->collectCodeCoverageInformation = $flag;
203
    }
204
 
205
    /**
206
     * @param  PHPUnit_Extensions_SeleniumTestCase $testCase
207
     */
208
    public function setTestCase(PHPUnit_Extensions_SeleniumTestCase $testCase)
209
    {
210
        $this->testCase = $testCase;
211
    }
212
 
213
    /**
214
     * @param  integer $testId
215
     */
216
    public function setTestId($testId)
217
    {
218
        $this->testId = $testId;
219
    }
220
 
221
    /**
222
     * @param  string $name
223
     * @throws InvalidArgumentException
224
     */
225
    public function setName($name)
226
    {
227
        if (!is_string($name)) {
228
            throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
229
        }
230
 
231
        $this->name = $name;
232
    }
233
 
234
    /**
235
     * @param  string $browser
236
     * @throws InvalidArgumentException
237
     */
238
    public function setBrowser($browser)
239
    {
240
        if (!is_string($browser)) {
241
            throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
242
        }
243
 
244
        $this->browser = $browser;
245
    }
246
 
247
    /**
248
     * @param  string $browserUrl
249
     * @throws InvalidArgumentException
250
     */
251
    public function setBrowserUrl($browserUrl)
252
    {
253
        if (!is_string($browserUrl)) {
254
            throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
255
        }
256
 
257
        $this->browserUrl = $browserUrl;
258
    }
259
 
260
    /**
261
     * @param  string $host
262
     * @throws InvalidArgumentException
263
     */
264
    public function setHost($host)
265
    {
266
        if (!is_string($host)) {
267
            throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'string');
268
        }
269
 
270
        $this->host = $host;
271
    }
272
 
273
    /**
274
     * @param  integer $port
275
     * @throws InvalidArgumentException
276
     */
277
    public function setPort($port)
278
    {
279
        if (!is_int($port)) {
280
            throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
281
        }
282
 
283
        $this->port = $port;
284
    }
285
 
286
    /**
287
     * @param  integer $timeout for Selenium RC in seconds
288
     * @throws InvalidArgumentException
289
     */
290
    public function setTimeout($timeout)
291
    {
292
        if (!is_int($timeout)) {
293
            throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
294
        }
295
 
296
        $this->seleniumTimeout = $timeout;
297
    }
298
 
299
    /**
300
     * @param  integer $timeout for HTTP connection to Selenium RC in seconds
301
     * @throws InvalidArgumentException
302
     */
303
    public function setHttpTimeout($timeout)
304
    {
305
        if (!is_int($timeout)) {
306
            throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
307
        }
308
 
309
        $this->httpTimeout = $timeout;
310
    }
311
 
312
    /**
313
     * @param  integer $seconds
314
     * @throws InvalidArgumentException
315
     */
316
    public function setSleep($seconds)
317
    {
318
        if (!is_int($seconds)) {
319
            throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
320
        }
321
 
322
        $this->sleep = $seconds;
323
    }
324
 
325
    /**
326
     * Sets the number of seconds to sleep() after *AndWait commands
327
     * when setWaitForPageToLoad(FALSE) is used.
328
     *
329
     * @param  integer $seconds
330
     * @throws InvalidArgumentException
331
     */
332
    public function setWait($seconds)
333
    {
334
        if (!is_int($seconds)) {
335
            throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'integer');
336
        }
337
 
338
        $this->wait = $seconds;
339
    }
340
 
341
    /**
342
     * Sets whether waitForPageToLoad (TRUE) or sleep() (FALSE)
343
     * is used after *AndWait commands.
344
     *
345
     * @param  boolean $flag
346
     * @throws InvalidArgumentException
347
     */
348
    public function setWaitForPageToLoad($flag)
349
    {
350
        if (!is_bool($flag)) {
351
            throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean');
352
        }
353
 
354
        $this->useWaitForPageToLoad = $flag;
355
    }
356
 
357
    /**
358
     * This method implements the Selenium RC protocol.
359
     *
360
     * @param  string $command
361
     * @param  array  $arguments
362
     * @return mixed
363
     * @method unknown  addLocationStrategy()
364
     * @method unknown  addLocationStrategyAndWait()
365
     * @method unknown  addScript()
366
     * @method unknown  addScriptAndWait()
367
     * @method unknown  addSelection()
368
     * @method unknown  addSelectionAndWait()
369
     * @method unknown  allowNativeXpath()
370
     * @method unknown  allowNativeXpathAndWait()
371
     * @method unknown  altKeyDown()
372
     * @method unknown  altKeyDownAndWait()
373
     * @method unknown  altKeyUp()
374
     * @method unknown  altKeyUpAndWait()
375
     * @method unknown  answerOnNextPrompt()
376
     * @method unknown  assignId()
377
     * @method unknown  assignIdAndWait()
378
     * @method unknown  attachFile()
379
     * @method unknown  break()
380
     * @method unknown  captureEntirePageScreenshot()
381
     * @method unknown  captureEntirePageScreenshotAndWait()
382
     * @method unknown  captureEntirePageScreenshotToStringAndWait()
383
     * @method unknown  captureScreenshotAndWait()
384
     * @method unknown  captureScreenshotToStringAndWait()
385
     * @method unknown  check()
386
     * @method unknown  checkAndWait()
387
     * @method unknown  chooseCancelOnNextConfirmation()
388
     * @method unknown  chooseCancelOnNextConfirmationAndWait()
389
     * @method unknown  chooseOkOnNextConfirmation()
390
     * @method unknown  chooseOkOnNextConfirmationAndWait()
391
     * @method unknown  click()
392
     * @method unknown  clickAndWait()
393
     * @method unknown  clickAt()
394
     * @method unknown  clickAtAndWait()
395
     * @method unknown  close()
396
     * @method unknown  contextMenu()
397
     * @method unknown  contextMenuAndWait()
398
     * @method unknown  contextMenuAt()
399
     * @method unknown  contextMenuAtAndWait()
400
     * @method unknown  controlKeyDown()
401
     * @method unknown  controlKeyDownAndWait()
402
     * @method unknown  controlKeyUp()
403
     * @method unknown  controlKeyUpAndWait()
404
     * @method unknown  createCookie()
405
     * @method unknown  createCookieAndWait()
406
     * @method unknown  deleteAllVisibleCookies()
407
     * @method unknown  deleteAllVisibleCookiesAndWait()
408
     * @method unknown  deleteCookie()
409
     * @method unknown  deleteCookieAndWait()
410
     * @method unknown  deselectPopUp()
411
     * @method unknown  deselectPopUpAndWait()
412
     * @method unknown  doubleClick()
413
     * @method unknown  doubleClickAndWait()
414
     * @method unknown  doubleClickAt()
415
     * @method unknown  doubleClickAtAndWait()
416
     * @method unknown  dragAndDrop()
417
     * @method unknown  dragAndDropAndWait()
418
     * @method unknown  dragAndDropToObject()
419
     * @method unknown  dragAndDropToObjectAndWait()
420
     * @method unknown  dragDrop()
421
     * @method unknown  dragDropAndWait()
422
     * @method unknown  echo()
423
     * @method unknown  fireEvent()
424
     * @method unknown  fireEventAndWait()
425
     * @method unknown  focus()
426
     * @method unknown  focusAndWait()
427
     * @method string   getAlert()
428
     * @method array    getAllButtons()
429
     * @method array    getAllFields()
430
     * @method array    getAllLinks()
431
     * @method array    getAllWindowIds()
432
     * @method array    getAllWindowNames()
433
     * @method array    getAllWindowTitles()
434
     * @method string   getAttribute()
435
     * @method array    getAttributeFromAllWindows()
436
     * @method string   getBodyText()
437
     * @method string   getConfirmation()
438
     * @method string   getCookie()
439
     * @method string   getCookieByName()
440
     * @method integer  getCursorPosition()
441
     * @method integer  getElementHeight()
442
     * @method integer  getElementIndex()
443
     * @method integer  getElementPositionLeft()
444
     * @method integer  getElementPositionTop()
445
     * @method integer  getElementWidth()
446
     * @method string   getEval()
447
     * @method string   getExpression()
448
     * @method string   getHtmlSource()
449
     * @method string   getLocation()
450
     * @method string   getLogMessages()
451
     * @method integer  getMouseSpeed()
452
     * @method string   getPrompt()
453
     * @method array    getSelectOptions()
454
     * @method string   getSelectedId()
455
     * @method array    getSelectedIds()
456
     * @method string   getSelectedIndex()
457
     * @method array    getSelectedIndexes()
458
     * @method string   getSelectedLabel()
459
     * @method array    getSelectedLabels()
460
     * @method string   getSelectedValue()
461
     * @method array    getSelectedValues()
462
     * @method unknown  getSpeed()
463
     * @method unknown  getSpeedAndWait()
464
     * @method string   getTable()
465
     * @method string   getText()
466
     * @method string   getTitle()
467
     * @method string   getValue()
468
     * @method boolean  getWhetherThisFrameMatchFrameExpression()
469
     * @method boolean  getWhetherThisWindowMatchWindowExpression()
470
     * @method integer  getXpathCount()
471
     * @method unknown  goBack()
472
     * @method unknown  goBackAndWait()
473
     * @method unknown  highlight()
474
     * @method unknown  highlightAndWait()
475
     * @method unknown  ignoreAttributesWithoutValue()
476
     * @method unknown  ignoreAttributesWithoutValueAndWait()
477
     * @method boolean  isAlertPresent()
478
     * @method boolean  isChecked()
479
     * @method boolean  isConfirmationPresent()
480
     * @method boolean  isCookiePresent()
481
     * @method boolean  isEditable()
482
     * @method boolean  isElementPresent()
483
     * @method boolean  isOrdered()
484
     * @method boolean  isPromptPresent()
485
     * @method boolean  isSomethingSelected()
486
     * @method boolean  isTextPresent()
487
     * @method boolean  isVisible()
488
     * @method unknown  keyDown()
489
     * @method unknown  keyDownAndWait()
490
     * @method unknown  keyDownNative()
491
     * @method unknown  keyDownNativeAndWait()
492
     * @method unknown  keyPress()
493
     * @method unknown  keyPressAndWait()
494
     * @method unknown  keyPressNative()
495
     * @method unknown  keyPressNativeAndWait()
496
     * @method unknown  keyUp()
497
     * @method unknown  keyUpAndWait()
498
     * @method unknown  keyUpNative()
499
     * @method unknown  keyUpNativeAndWait()
500
     * @method unknown  metaKeyDown()
501
     * @method unknown  metaKeyDownAndWait()
502
     * @method unknown  metaKeyUp()
503
     * @method unknown  metaKeyUpAndWait()
504
     * @method unknown  mouseDown()
505
     * @method unknown  mouseDownAndWait()
506
     * @method unknown  mouseDownAt()
507
     * @method unknown  mouseDownAtAndWait()
508
     * @method unknown  mouseMove()
509
     * @method unknown  mouseMoveAndWait()
510
     * @method unknown  mouseMoveAt()
511
     * @method unknown  mouseMoveAtAndWait()
512
     * @method unknown  mouseOut()
513
     * @method unknown  mouseOutAndWait()
514
     * @method unknown  mouseOver()
515
     * @method unknown  mouseOverAndWait()
516
     * @method unknown  mouseUp()
517
     * @method unknown  mouseUpAndWait()
518
     * @method unknown  mouseUpAt()
519
     * @method unknown  mouseUpAtAndWait()
520
     * @method unknown  mouseUpRight()
521
     * @method unknown  mouseUpRightAndWait()
522
     * @method unknown  mouseUpRightAt()
523
     * @method unknown  mouseUpRightAtAndWait()
524
     * @method unknown  open()
525
     * @method unknown  openWindow()
526
     * @method unknown  openWindowAndWait()
527
     * @method unknown  pause()
528
     * @method unknown  refresh()
529
     * @method unknown  refreshAndWait()
530
     * @method unknown  removeAllSelections()
531
     * @method unknown  removeAllSelectionsAndWait()
532
     * @method unknown  removeScript()
533
     * @method unknown  removeScriptAndWait()
534
     * @method unknown  removeSelection()
535
     * @method unknown  removeSelectionAndWait()
536
     * @method unknown  retrieveLastRemoteControlLogs()
537
     * @method unknown  rollup()
538
     * @method unknown  rollupAndWait()
539
     * @method unknown  runScript()
540
     * @method unknown  runScriptAndWait()
541
     * @method unknown  select()
542
     * @method unknown  selectAndWait()
543
     * @method unknown  selectFrame()
544
     * @method unknown  selectPopUp()
545
     * @method unknown  selectPopUpAndWait()
546
     * @method unknown  selectWindow()
547
     * @method unknown  setBrowserLogLevel()
548
     * @method unknown  setBrowserLogLevelAndWait()
549
     * @method unknown  setContext()
550
     * @method unknown  setCursorPosition()
551
     * @method unknown  setCursorPositionAndWait()
552
     * @method unknown  setMouseSpeed()
553
     * @method unknown  setMouseSpeedAndWait()
554
     * @method unknown  setSpeed()
555
     * @method unknown  setSpeedAndWait()
556
     * @method unknown  shiftKeyDown()
557
     * @method unknown  shiftKeyDownAndWait()
558
     * @method unknown  shiftKeyUp()
559
     * @method unknown  shiftKeyUpAndWait()
560
     * @method unknown  shutDownSeleniumServer()
561
     * @method unknown  store()
562
     * @method unknown  submit()
563
     * @method unknown  submitAndWait()
564
     * @method unknown  type()
565
     * @method unknown  typeAndWait()
566
     * @method unknown  typeKeys()
567
     * @method unknown  typeKeysAndWait()
568
     * @method unknown  uncheck()
569
     * @method unknown  uncheckAndWait()
570
     * @method unknown  useXpathLibrary()
571
     * @method unknown  useXpathLibraryAndWait()
572
     * @method unknown  waitForCondition()
573
     * @method unknown  waitForPageToLoad()
574
     * @method unknown  waitForPopUp()
575
     * @method unknown  windowFocus()
576
     * @method unknown  windowMaximize()
577
     */
578
    public function __call($command, $arguments)
579
    {
580
        $wait = FALSE;
581
 
582
        if (substr($command, -7, 7) == 'AndWait') {
583
            $command = substr($command, 0, -7);
584
            $wait    = TRUE;
585
        }
586
 
587
        switch ($command) {
588
            case 'addLocationStrategy':
589
            case 'addScript':
590
            case 'addSelection':
591
            case 'allowNativeXpath':
592
            case 'altKeyDown':
593
            case 'altKeyUp':
594
            case 'answerOnNextPrompt':
595
            case 'assignId':
596
            case 'attachFile':
597
            case 'break':
598
            case 'captureEntirePageScreenshot':
599
            case 'captureScreenshot':
600
            case 'check':
601
            case 'chooseCancelOnNextConfirmation':
602
            case 'chooseOkOnNextConfirmation':
603
            case 'click':
604
            case 'clickAt':
605
            case 'close':
606
            case 'contextMenu':
607
            case 'contextMenuAt':
608
            case 'controlKeyDown':
609
            case 'controlKeyUp':
610
            case 'createCookie':
611
            case 'deleteAllVisibleCookies':
612
            case 'deleteCookie':
613
            case 'deselectPopUp':
614
            case 'doubleClick':
615
            case 'doubleClickAt':
616
            case 'dragAndDrop':
617
            case 'dragAndDropToObject':
618
            case 'dragDrop':
619
            case 'echo':
620
            case 'fireEvent':
621
            case 'focus':
622
            case 'goBack':
623
            case 'highlight':
624
            case 'ignoreAttributesWithoutValue':
625
            case 'keyDown':
626
            case 'keyDownNative':
627
            case 'keyPress':
628
            case 'keyPressNative':
629
            case 'keyUp':
630
            case 'keyUpNative':
631
            case 'metaKeyDown':
632
            case 'metaKeyUp':
633
            case 'mouseDown':
634
            case 'mouseDownAt':
635
            case 'mouseMove':
636
            case 'mouseMoveAt':
637
            case 'mouseOut':
638
            case 'mouseOver':
639
            case 'mouseUp':
640
            case 'mouseUpAt':
641
            case 'mouseUpRight':
642
            case 'mouseUpRightAt':
643
            case 'open':
644
            case 'openWindow':
645
            case 'pause':
646
            case 'refresh':
647
            case 'removeAllSelections':
648
            case 'removeScript':
649
            case 'removeSelection':
650
            case 'retrieveLastRemoteControlLogs':
651
            case 'rollup':
652
            case 'runScript':
653
            case 'select':
654
            case 'selectFrame':
655
            case 'selectPopUp':
656
            case 'selectWindow':
657
            case 'setBrowserLogLevel':
658
            case 'setContext':
659
            case 'setCursorPosition':
660
            case 'setMouseSpeed':
661
            case 'setSpeed':
662
            case 'shiftKeyDown':
663
            case 'shiftKeyUp':
664
            case 'shutDownSeleniumServer':
665
            case 'store':
666
            case 'submit':
667
            case 'type':
668
            case 'typeKeys':
669
            case 'uncheck':
670
            case 'useXpathLibrary':
671
            case 'windowFocus':
672
            case 'windowMaximize':
673
            case isset(self::$autoGeneratedCommands[$command]): {
674
                // Pre-Command Actions
675
                switch ($command) {
676
                    case 'open':
677
                    case 'openWindow': {
678
                        if ($this->collectCodeCoverageInformation) {
679
                            $this->deleteCookie('PHPUNIT_SELENIUM_TEST_ID', 'path=/');
680
 
681
                            $this->createCookie(
682
                              'PHPUNIT_SELENIUM_TEST_ID=' . $this->testId,
683
                              'path=/'
684
                            );
685
                        }
686
                    }
687
                    break;
688
                    case 'store':
689
                        // store is a synonym of storeExpression
690
                        // and RC only understands storeExpression
691
                        $command = 'storeExpression';
692
                    break;
693
                }
694
 
695
                if (isset(self::$autoGeneratedCommands[$command]) && self::$autoGeneratedCommands[$command]['functionHelper']) {
696
                    $helperArguments = array($command, $arguments, self::$autoGeneratedCommands[$command]);
697
                    call_user_func_array(array($this, self::$autoGeneratedCommands[$command]['functionHelper']), $helperArguments);
698
                } else {
699
                    $this->doCommand($command, $arguments);
700
                }
701
 
702
                // Post-Command Actions
703
                switch ($command) {
704
                    case 'addLocationStrategy':
705
                    case 'allowNativeXpath':
706
                    case 'assignId':
707
                    case 'captureEntirePageScreenshot':
708
                    case 'captureScreenshot': {
709
                        // intentionally empty
710
                    }
711
                    break;
712
 
713
                    default: {
714
                        if ($wait) {
715
                            if ($this->useWaitForPageToLoad) {
716
                                $this->waitForPageToLoad($this->seleniumTimeout * 1000);
717
                            } else {
718
                                sleep($this->wait);
719
                            }
720
                        }
721
 
722
                        if ($this->sleep > 0) {
723
                            sleep($this->sleep);
724
                        }
725
 
726
                        $this->testCase->runDefaultAssertions($command);
727
                    }
728
                }
729
            }
730
            break;
731
 
732
            case 'getWhetherThisFrameMatchFrameExpression':
733
            case 'getWhetherThisWindowMatchWindowExpression':
734
            case 'isAlertPresent':
735
            case 'isChecked':
736
            case 'isConfirmationPresent':
737
            case 'isCookiePresent':
738
            case 'isEditable':
739
            case 'isElementPresent':
740
            case 'isOrdered':
741
            case 'isPromptPresent':
742
            case 'isSomethingSelected':
743
            case 'isTextPresent':
744
            case 'isVisible': {
745
                return $this->getBoolean($command, $arguments);
746
            }
747
            break;
748
 
749
            case 'getCursorPosition':
750
            case 'getElementHeight':
751
            case 'getElementIndex':
752
            case 'getElementPositionLeft':
753
            case 'getElementPositionTop':
754
            case 'getElementWidth':
755
            case 'getMouseSpeed':
756
            case 'getSpeed':
757
            case 'getXpathCount': {
758
                $result = $this->getNumber($command, $arguments);
759
 
760
                if ($wait) {
761
                    $this->waitForPageToLoad($this->seleniumTimeout * 1000);
762
                }
763
 
764
                return $result;
765
            }
766
            break;
767
 
768
            case 'getAlert':
769
            case 'getAttribute':
770
            case 'getBodyText':
771
            case 'getConfirmation':
772
            case 'getCookie':
773
            case 'getCookieByName':
774
            case 'getEval':
775
            case 'getExpression':
776
            case 'getHtmlSource':
777
            case 'getLocation':
778
            case 'getLogMessages':
779
            case 'getPrompt':
780
            case 'getSelectedId':
781
            case 'getSelectedIndex':
782
            case 'getSelectedLabel':
783
            case 'getSelectedValue':
784
            case 'getTable':
785
            case 'getText':
786
            case 'getTitle':
787
            case 'captureEntirePageScreenshotToString':
788
            case 'captureScreenshotToString':
789
            case 'getValue': {
790
                $result = $this->getString($command, $arguments);
791
 
792
                if ($wait) {
793
                    $this->waitForPageToLoad($this->seleniumTimeout * 1000);
794
                }
795
 
796
                return $result;
797
            }
798
            break;
799
 
800
            case 'getAllButtons':
801
            case 'getAllFields':
802
            case 'getAllLinks':
803
            case 'getAllWindowIds':
804
            case 'getAllWindowNames':
805
            case 'getAllWindowTitles':
806
            case 'getAttributeFromAllWindows':
807
            case 'getSelectedIds':
808
            case 'getSelectedIndexes':
809
            case 'getSelectedLabels':
810
            case 'getSelectedValues':
811
            case 'getSelectOptions': {
812
                $result = $this->getStringArray($command, $arguments);
813
 
814
                if ($wait) {
815
                    $this->waitForPageToLoad($this->seleniumTimeout * 1000);
816
                }
817
 
818
                return $result;
819
            }
820
            break;
821
 
822
            case 'waitForCondition':
823
            case 'waitForFrameToLoad':
824
            case 'waitForPopUp': {
825
                if (count($arguments) == 1) {
826
                    $arguments[] = $this->seleniumTimeout * 1000;
827
                }
828
 
829
                $this->doCommand($command, $arguments);
830
                $this->testCase->runDefaultAssertions($command);
831
            }
832
            break;
833
 
834
            case 'waitForPageToLoad': {
835
                if (empty($arguments)) {
836
                    $arguments[] = $this->seleniumTimeout * 1000;
837
                }
838
 
839
                $this->doCommand($command, $arguments);
840
                $this->testCase->runDefaultAssertions($command);
841
            }
842
            break;
843
 
844
            default: {
845
                $this->stop();
846
 
847
                throw new BadMethodCallException(
848
                  "Method $command not defined."
849
                );
850
            }
851
        }
852
    }
853
 
854
    /**
855
     * Send a command to the Selenium RC server.
856
     *
857
     * @param  string $command
858
     * @param  array  $arguments
859
     * @return string
860
     * @author Shin Ohno <ganchiku@gmail.com>
861
     * @author Bjoern Schotte <schotte@mayflower.de>
862
     */
863
    protected function doCommand($command, array $arguments = array())
864
    {
865
        if (!ini_get('allow_url_fopen')) {
866
            throw new PHPUnit_Framework_Exception(
867
              'Could not connect to the Selenium RC server because allow_url_fopen is disabled.'
868
            );
869
        }
870
 
871
        $url = sprintf(
872
          'http://%s:%s/selenium-server/driver/?cmd=%s',
873
          $this->host,
874
          $this->port,
875
          urlencode($command)
876
        );
877
 
878
        $numArguments = count($arguments);
879
 
880
        for ($i = 0; $i < $numArguments; $i++) {
881
            $argNum = strval($i + 1);
882
            $url .= sprintf('&%s=%s', $argNum, urlencode(trim($arguments[$i])));
883
        }
884
 
885
        if (isset($this->sessionId)) {
886
            $url .= sprintf('&%s=%s', 'sessionId', $this->sessionId);
887
        }
888
 
889
        $this->commands[] = sprintf('%s(%s)', $command, join(', ', $arguments));
890
 
891
        $context = stream_context_create(
892
          array(
893
            'http' => array(
894
              'timeout' => $this->httpTimeout
895
            )
896
          )
897
        );
898
 
899
        $handle = @fopen($url, 'r', FALSE, $context);
900
 
901
        if (!$handle) {
902
            throw new PHPUnit_Framework_Exception(
903
              'Could not connect to the Selenium RC server.'
904
            );
905
        }
906
 
907
        stream_set_blocking($handle, 1);
908
        stream_set_timeout($handle, 0, $this->httpTimeout * 1000);
909
 
910
        $info     = stream_get_meta_data($handle);
911
        $response = '';
912
 
913
        while (!$info['eof'] && !$info['timed_out']) {
914
            $response .= fgets($handle, 4096);
915
            $info = stream_get_meta_data($handle);
916
        }
917
 
918
        fclose($handle);
919
 
920
        if (!preg_match('/^OK/', $response)) {
921
            $this->stop();
922
 
923
            throw new PHPUnit_Framework_Exception(
924
              sprintf(
925
                "Response from Selenium RC server for %s.\n%s.\n",
926
                $this->commands[count($this->commands)-1],
927
                $response
928
              )
929
            );
930
        }
931
 
932
        return $response;
933
    }
934
 
935
    /**
936
     * Send a command to the Selenium RC server and treat the result
937
     * as a boolean.
938
     *
939
     * @param  string $command
940
     * @param  array  $arguments
941
     * @return boolean
942
     * @author Shin Ohno <ganchiku@gmail.com>
943
     * @author Bjoern Schotte <schotte@mayflower.de>
944
     */
945
    protected function getBoolean($command, array $arguments)
946
    {
947
        $result = $this->getString($command, $arguments);
948
 
949
        switch ($result) {
950
            case 'true':  return TRUE;
951
 
952
            case 'false': return FALSE;
953
 
954
            default: {
955
                $this->stop();
956
 
957
                throw new PHPUnit_Framework_Exception(
958
                  'Result is neither "true" nor "false": ' . PHPUnit_Util_Type::toString($result, TRUE)
959
                );
960
            }
961
        }
962
    }
963
 
964
    /**
965
     * Send a command to the Selenium RC server and treat the result
966
     * as a number.
967
     *
968
     * @param  string $command
969
     * @param  array  $arguments
970
     * @return numeric
971
     * @author Shin Ohno <ganchiku@gmail.com>
972
     * @author Bjoern Schotte <schotte@mayflower.de>
973
     */
974
    protected function getNumber($command, array $arguments)
975
    {
976
        $result = $this->getString($command, $arguments);
977
 
978
        if (!is_numeric($result)) {
979
            $this->stop();
980
 
981
            throw new PHPUnit_Framework_Exception(
982
              'Result is not numeric: ' . PHPUnit_Util_Type::toString($result, TRUE)
983
            );
984
        }
985
 
986
        return $result;
987
    }
988
 
989
    /**
990
     * Send a command to the Selenium RC server and treat the result
991
     * as a string.
992
     *
993
     * @param  string $command
994
     * @param  array  $arguments
995
     * @return string
996
     * @author Shin Ohno <ganchiku@gmail.com>
997
     * @author Bjoern Schotte <schotte@mayflower.de>
998
     */
999
    protected function getString($command, array $arguments)
1000
    {
1001
        try {
1002
            $result = $this->doCommand($command, $arguments);
1003
        }
1004
 
1005
        catch (RuntimeException $e) {
1006
            $this->stop();
1007
 
1008
            throw $e;
1009
        }
1010
 
1011
        return (strlen($result) > 3) ? substr($result, 3) : '';
1012
    }
1013
 
1014
    /**
1015
     * Send a command to the Selenium RC server and treat the result
1016
     * as an array of strings.
1017
     *
1018
     * @param  string $command
1019
     * @param  array  $arguments
1020
     * @return array
1021
     * @author Shin Ohno <ganchiku@gmail.com>
1022
     * @author Bjoern Schotte <schotte@mayflower.de>
1023
     */
1024
    protected function getStringArray($command, array $arguments)
1025
    {
1026
        $csv     = $this->getString($command, $arguments);
1027
        $token   = '';
1028
        $tokens  = array();
1029
        $letters = preg_split('//', $csv, -1, PREG_SPLIT_NO_EMPTY);
1030
        $count   = count($letters);
1031
 
1032
        for ($i = 0; $i < $count; $i++) {
1033
            $letter = $letters[$i];
1034
 
1035
            switch($letter) {
1036
                case '\\': {
1037
                    $letter = $letters[++$i];
1038
                    $token .= $letter;
1039
                }
1040
                break;
1041
 
1042
                case ',': {
1043
                    $tokens[] = $token;
1044
                    $token    = '';
1045
                }
1046
                break;
1047
 
1048
                default: {
1049
                    $token .= $letter;
1050
                }
1051
            }
1052
        }
1053
 
1054
        $tokens[] = $token;
1055
 
1056
        return $tokens;
1057
    }
1058
 
1059
    public function getVerificationErrors()
1060
    {
1061
        return $this->verificationErrors;
1062
    }
1063
 
1064
    public function clearVerificationErrors()
1065
    {
1066
        $this->verificationErrors = array();
1067
    }
1068
 
1069
    protected function assertCommand($command, $arguments, $info)
1070
    {
1071
        $method = $info['originalMethod'];
1072
        $result = $this->__call($method, $arguments);
1073
 
1074
        if ($info['isBoolean']) {
1075
            if (!isset($info['negative']) || !$info['negative']) {
1076
                PHPUnit_Framework_Assert::assertTrue($result);
1077
            } else {
1078
                PHPUnit_Framework_Assert::assertFalse($result);
1079
            }
1080
        } else {
1081
            $expected = array_pop($arguments);
1082
 
1083
            if (strpos($expected, 'exact:') === 0) {
1084
                $expected = substr($expected, strlen('exact:'));
1085
 
1086
                if (!isset($info['negative']) || !$info['negative']) {
1087
                    PHPUnit_Framework_Assert::assertEquals($expected, $result);
1088
                } else {
1089
                    PHPUnit_Framework_Assert::assertNotEquals($expected, $result);
1090
                }
1091
            } else {
1092
                if (strpos($expected, 'regexp:') === 0) {
1093
                    $expected = substr($expected, strlen('regexp:'));
1094
                } else {
1095
                    if (strpos($expected, 'glob:') === 0) {
1096
                        $expected = substr($expected, strlen('glob:'));
1097
                    }
1098
 
1099
                    $expected = str_replace(
1100
                      array('*', '?'), array('.*', '.?'), $expected
1101
                    );
1102
                }
1103
 
1104
                $expected = str_replace('/', '\/', $expected);
1105
 
1106
                if (!isset($info['negative']) || !$info['negative']) {
1107
                    PHPUnit_Framework_Assert::assertRegExp(
1108
                      '/' . $expected . '/', $result
1109
                    );
1110
                } else {
1111
                    PHPUnit_Framework_Assert::assertNotRegExp(
1112
                      '/' . $expected . '/', $result
1113
                    );
1114
                }
1115
            }
1116
        }
1117
    }
1118
 
1119
    protected function verifyCommand($command, $arguments, $info)
1120
    {
1121
        try {
1122
            $this->assertCommand($command, $arguments, $info);
1123
        }
1124
 
1125
        catch (PHPUnit_Framework_AssertionFailedError $e) {
1126
            array_push($this->verificationErrors, $e->toString());
1127
        }
1128
    }
1129
 
1130
    protected function waitForCommand($command, $arguments, $info)
1131
    {
1132
        for ($second = 0; ; $second++) {
1133
            if ($second > $this->httpTimeout) {
1134
                PHPUnit_Framework_Assert::fail('timeout');
1135
            }
1136
 
1137
            try {
1138
                $this->assertCommand($command, $arguments, $info);
1139
                return;
1140
            }
1141
 
1142
            catch (Exception $e) {
1143
            }
1144
 
1145
            sleep(1);
1146
        }
1147
    }
1148
 
1149
    /**
1150
     * Parses the docblock of PHPUnit_Extensions_SeleniumTestCase_Driver::__call
1151
     * for get*(), is*(), assert*(), verify*(), assertNot*(), verifyNot*(),
1152
     * store*(), waitFor*(), and waitForNot*() methods.
1153
     */
1154
    protected static function autoGenerateCommands()
1155
    {
1156
        $method     = new ReflectionMethod(__CLASS__, '__call');
1157
        $docComment = $method->getDocComment();
1158
 
1159
        if (preg_match_all('(@method\s+(\w+)\s+([\w]+)\(\))', $docComment, $matches)) {
1160
            foreach ($matches[2] as $method) {
1161
                if (preg_match('/^(get|is)([A-Z].+)$/', $method, $matches)) {
1162
                    $baseName  = $matches[2];
1163
                    $isBoolean = $matches[1] == 'is';
1164
 
1165
                    if (preg_match('/^(.*)Present$/', $baseName, $matches)) {
1166
                        $notBaseName = $matches[1].'NotPresent';
1167
                    } else {
1168
                        $notBaseName = 'Not'.$baseName;
1169
                    }
1170
 
1171
                    self::$autoGeneratedCommands['store' . $baseName] = array(
1172
                      'functionHelper' => FALSE
1173
                    );
1174
 
1175
                    self::$autoGeneratedCommands['assert' . $baseName] = array(
1176
                      'originalMethod' => $method,
1177
                      'isBoolean'      => $isBoolean,
1178
                      'functionHelper' => 'assertCommand'
1179
                    );
1180
 
1181
                    self::$autoGeneratedCommands['assert' . $notBaseName] = array(
1182
                      'originalMethod' => $method,
1183
                      'isBoolean'      => $isBoolean,
1184
                      'negative'       => TRUE,
1185
                      'functionHelper' => 'assertCommand'
1186
                    );
1187
 
1188
                    self::$autoGeneratedCommands['verify' . $baseName] = array(
1189
                      'originalMethod' => $method,
1190
                      'isBoolean'      => $isBoolean,
1191
                      'functionHelper' => 'verifyCommand'
1192
                    );
1193
 
1194
                    self::$autoGeneratedCommands['verify' . $notBaseName] = array(
1195
                      'originalMethod' => $method,
1196
                      'isBoolean'      => $isBoolean,
1197
                      'negative'       => TRUE,
1198
                      'functionHelper' => 'verifyCommand'
1199
                    );
1200
 
1201
                    self::$autoGeneratedCommands['waitFor' . $baseName] = array(
1202
                      'originalMethod' => $method,
1203
                      'isBoolean'      => $isBoolean,
1204
                      'functionHelper' => 'waitForCommand'
1205
                    );
1206
 
1207
                    self::$autoGeneratedCommands['waitFor' . $notBaseName] = array(
1208
                      'originalMethod' => $method,
1209
                      'isBoolean'      => $isBoolean,
1210
                      'negative'       => TRUE,
1211
                      'functionHelper' => 'waitForCommand'
1212
                    );
1213
                }
1214
            }
1215
        }
1216
    }
1217
}
1218
?>