From add8a5c91e4a276926d17857f9acbf3ceccfd759 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daphn=C3=A9=20Popin?= Date: Mon, 20 Jan 2014 15:47:23 +0100 Subject: [PATCH 001/784] Remove typehint string in `frameToBeAvailableAndSwitchToIt` Type hints can not be used with scalar types such as int or string. [See PHP documentation](http://www.php.net/manual/en/language.oop5.typehinting.php) --- lib/WebDriverExpectedCondition.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index e00f5382e..5d9a6529b 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -192,8 +192,7 @@ function ($driver) use ($by, $text) { * @return WebDriverExpectedCondition object focused on new frame * when frame is found bool false otherwise */ - public static function frameToBeAvailableAndSwitchToIt( - string $frame_locator) { + public static function frameToBeAvailableAndSwitchToIt($frame_locator) { return new WebDriverExpectedCondition( function ($driver) use ($frame_locator) { try { From a6ae29aa0239cfd544bd68ba5ac6695d7902163d Mon Sep 17 00:00:00 2001 From: whhone Date: Tue, 21 Jan 2014 11:41:14 -0800 Subject: [PATCH 002/784] replace filesystem by tempnam --- lib/remote/RemoteWebElement.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/remote/RemoteWebElement.php b/lib/remote/RemoteWebElement.php index bb8864728..c7cfee7fa 100644 --- a/lib/remote/RemoteWebElement.php +++ b/lib/remote/RemoteWebElement.php @@ -281,9 +281,10 @@ private function upload($local_file) { throw new WebDriverException("You may only upload files: " . $local_file); } - $temp_zip = Filesystem::createTemporaryFile('WebDriverZip', 'true'); + // Create a temperary file in the system temp directory. + $temp_zip = tempnam('', 'WebDriverZip'); $zip = new ZipArchive(); - if ($zip->open($temp_zip, ZIPARCHIVE::CREATE) !== true) { + if ($zip->open($temp_zip, ZipArchive::CREATE) !== true) { return false; } $file_name = pathinfo($local_file)['basename']; From 7aeec8b593cc66a130fda44dca339d2a686a8d0f Mon Sep 17 00:00:00 2001 From: whhone Date: Tue, 21 Jan 2014 16:18:10 -0800 Subject: [PATCH 003/784] clean up temp file --- lib/remote/RemoteWebElement.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/remote/RemoteWebElement.php b/lib/remote/RemoteWebElement.php index c7cfee7fa..151c0f416 100644 --- a/lib/remote/RemoteWebElement.php +++ b/lib/remote/RemoteWebElement.php @@ -291,9 +291,11 @@ private function upload($local_file) { $zip->addFile($local_file, $file_name); $zip->close(); $params = array( - 'file' => base64_encode(Filesystem::readFile($temp_zip)), + 'file' => base64_encode(file_get_contents($temp_zip)), ); - return $this->executor->execute('sendFile', $params); + $remote_path = $this->executor->execute('sendFile', $params); + unlink($temp_zip); + return $remote_path; } /** From 2b9a7eba4c337989ef8f384dc94f25ac13ede3f5 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Wed, 22 Jan 2014 16:55:23 -0800 Subject: [PATCH 004/784] resolve php 5.3 pathinfo() issue --- lib/remote/RemoteWebElement.php | 3 +- tests/BasePHPWebDriverTestCase.php | 1 + tests/FileUploadTestCase.php | 44 ++++++++++++++++++++++++++ tests/files/FileUploadTestCaseFile.txt | 1 + tests/html/upload.html | 10 ++++++ 5 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 tests/FileUploadTestCase.php create mode 100644 tests/files/FileUploadTestCaseFile.txt create mode 100644 tests/html/upload.html diff --git a/lib/remote/RemoteWebElement.php b/lib/remote/RemoteWebElement.php index 151c0f416..b394d5590 100644 --- a/lib/remote/RemoteWebElement.php +++ b/lib/remote/RemoteWebElement.php @@ -287,7 +287,8 @@ private function upload($local_file) { if ($zip->open($temp_zip, ZipArchive::CREATE) !== true) { return false; } - $file_name = pathinfo($local_file)['basename']; + $info = pathinfo($local_file); + $file_name = $info['basename']; $zip->addFile($local_file, $file_name); $zip->close(); $params = array( diff --git a/tests/BasePHPWebDriverTestCase.php b/tests/BasePHPWebDriverTestCase.php index 6b49db2bb..1951651bb 100644 --- a/tests/BasePHPWebDriverTestCase.php +++ b/tests/BasePHPWebDriverTestCase.php @@ -25,6 +25,7 @@ protected function setUp() { 'http://localhost:4444/wd/hub', array( WebDriverCapabilityType::BROWSER_NAME + //=> WebDriverBrowserType::FIREFOX, => WebDriverBrowserType::HTMLUNIT, ) ); diff --git a/tests/FileUploadTestCase.php b/tests/FileUploadTestCase.php new file mode 100644 index 000000000..f88697dd9 --- /dev/null +++ b/tests/FileUploadTestCase.php @@ -0,0 +1,44 @@ +driver->get($this->getTestPath('upload.html')); + $file_input = $this->driver->findElement(WebDriverBy::id('upload')); + $file_input->setFileDetector(new LocalFileDetector()) + ->sendKeys(__DIR__ . '/files/FileUploadTestCaseFile.txt'); + self::assertNotEquals($this->getFilePath(), $file_input->getAttribute('value')); + } + + public function testUselessFileDetectorSendKeys() { + $this->driver->get($this->getTestPath('upload.html')); + $file_input = $this->driver->findElement(WebDriverBy::id('upload')); + $file_input->sendKeys($this->getFilePath()); + self::assertEquals($this->getFilePath(), $file_input->getAttribute('value')); + } + + private function getFilePath() { + return __DIR__ . '/files/FileUploadTestCaseFile.txt'; + } +} diff --git a/tests/files/FileUploadTestCaseFile.txt b/tests/files/FileUploadTestCaseFile.txt new file mode 100644 index 000000000..0ca232e37 --- /dev/null +++ b/tests/files/FileUploadTestCaseFile.txt @@ -0,0 +1 @@ +text file diff --git a/tests/html/upload.html b/tests/html/upload.html new file mode 100644 index 000000000..957514f3f --- /dev/null +++ b/tests/html/upload.html @@ -0,0 +1,10 @@ + + + Upload a file + + +
+ +
+ + From cb57c13a5cbe88b5040fd5ad00a06eab87c89219 Mon Sep 17 00:00:00 2001 From: christian Date: Sat, 25 Jan 2014 17:53:11 +0100 Subject: [PATCH 005/784] First unit test. --- README.md | 6 ++++ .../WebDriverButtonReleaseActionTest.php | 32 +++++++++++++++++++ tests/phpunit.xml | 21 ++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 tests/interactions/internal/WebDriverButtonReleaseActionTest.php create mode 100644 tests/phpunit.xml diff --git a/README.md b/README.md index f279f1f18..90c1597d7 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,12 @@ Install the library. * The $capabilities array lets you specify (among other things) which browser to use. See https://code.google.com/p/selenium/wiki/DesiredCapabilities for more details. +## RUN UNIT TESTS + +To run unit tests simply run: + +./vendor/bin/phpunit -c ./tests + ## MORE INFORMATION Check out the Selenium docs and wiki at http://docs.seleniumhq.org/docs/ and https://code.google.com/p/selenium/wiki diff --git a/tests/interactions/internal/WebDriverButtonReleaseActionTest.php b/tests/interactions/internal/WebDriverButtonReleaseActionTest.php new file mode 100644 index 000000000..383e3a2d1 --- /dev/null +++ b/tests/interactions/internal/WebDriverButtonReleaseActionTest.php @@ -0,0 +1,32 @@ +webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverButtonReleaseAction = new WebDriverButtonReleaseAction( + $this->webDriverMouse, + $this->locationProvider + ); + } + + public function testPerformSendsMouseUpCommand() + { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('mouseUp'); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverButtonReleaseAction->perform(); + } +} diff --git a/tests/phpunit.xml b/tests/phpunit.xml new file mode 100644 index 000000000..ceb0ce206 --- /dev/null +++ b/tests/phpunit.xml @@ -0,0 +1,21 @@ + + + + + + + + ./ + + + + From d7105521abb5ca4b051eca6ab99fa228713c2ef8 Mon Sep 17 00:00:00 2001 From: christian Date: Sat, 25 Jan 2014 17:55:22 +0100 Subject: [PATCH 006/784] Markdown fix for running unit tests --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 90c1597d7..fe517a0d2 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ Install the library. To run unit tests simply run: -./vendor/bin/phpunit -c ./tests + ./vendor/bin/phpunit -c ./tests ## MORE INFORMATION From c27197e5246a6e3ea34cbd64a73f33d79461a7b8 Mon Sep 17 00:00:00 2001 From: christian Date: Sat, 25 Jan 2014 18:19:38 +0100 Subject: [PATCH 007/784] Add unit test for WebDriverClickAction --- .../internal/WebDriverClickActionTest.php | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 tests/interactions/internal/WebDriverClickActionTest.php diff --git a/tests/interactions/internal/WebDriverClickActionTest.php b/tests/interactions/internal/WebDriverClickActionTest.php new file mode 100644 index 000000000..ca1ecb036 --- /dev/null +++ b/tests/interactions/internal/WebDriverClickActionTest.php @@ -0,0 +1,32 @@ +webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverClickAction = new WebDriverClickAction( + $this->webDriverMouse, + $this->locationProvider + ); + } + + public function testPerformSendsClickCommand() + { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('click'); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverClickAction->perform(); + } +} From 4fa42cc045075295016dc98ad4c2388aa9df8165 Mon Sep 17 00:00:00 2001 From: christian Date: Sat, 25 Jan 2014 18:29:38 +0100 Subject: [PATCH 008/784] Markdown fix for running unit tests --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fe517a0d2..6b4e15ea9 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ Install the library. To run unit tests simply run: - ./vendor/bin/phpunit -c ./tests + ./vendor/bin/phpunit -c ./tests ## MORE INFORMATION From 38ca99a5a7119600fb07c0d4c9e03f6e8b05b3c8 Mon Sep 17 00:00:00 2001 From: christian Date: Sat, 25 Jan 2014 18:34:37 +0100 Subject: [PATCH 009/784] Add unit test for WebDriverClickAndHoldAction --- .../WebDriverClickAndHoldActionTest.php | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 tests/interactions/internal/WebDriverClickAndHoldActionTest.php diff --git a/tests/interactions/internal/WebDriverClickAndHoldActionTest.php b/tests/interactions/internal/WebDriverClickAndHoldActionTest.php new file mode 100644 index 000000000..3bd805ed5 --- /dev/null +++ b/tests/interactions/internal/WebDriverClickAndHoldActionTest.php @@ -0,0 +1,32 @@ +webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverClickAction = new WebDriverClickAndHoldAction( + $this->webDriverMouse, + $this->locationProvider + ); + } + + public function testPerformSendsMouseDownCommand() + { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('mouseDown'); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverClickAction->perform(); + } +} From fbd824de9e9c9bb828122756a49a8ea4b306d2d1 Mon Sep 17 00:00:00 2001 From: christian Date: Sat, 25 Jan 2014 18:54:56 +0100 Subject: [PATCH 010/784] Add a bootstrap.php for phpunit. --- tests/bootstrap.php | 3 +++ .../interactions/internal/WebDriverButtonReleaseActionTest.php | 2 -- tests/interactions/internal/WebDriverClickActionTest.php | 2 -- .../interactions/internal/WebDriverClickAndHoldActionTest.php | 2 -- tests/phpunit.xml | 3 ++- 5 files changed, 5 insertions(+), 7 deletions(-) create mode 100644 tests/bootstrap.php diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 000000000..e98637e69 --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,3 @@ + + syntaxCheck = "false" + bootstrap = "bootstrap.php" > From bd65ff6666c229bea930b3cde3019352f948339d Mon Sep 17 00:00:00 2001 From: christian Date: Sat, 25 Jan 2014 19:37:36 +0100 Subject: [PATCH 011/784] Add unit test for WebDriverContextClickAction --- .../WebDriverContextClickActionTest.php | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 tests/interactions/internal/WebDriverContextClickActionTest.php diff --git a/tests/interactions/internal/WebDriverContextClickActionTest.php b/tests/interactions/internal/WebDriverContextClickActionTest.php new file mode 100644 index 000000000..21a91468b --- /dev/null +++ b/tests/interactions/internal/WebDriverContextClickActionTest.php @@ -0,0 +1,30 @@ +webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverContextClickAction = new WebDriverContextClickAction( + $this->webDriverMouse, + $this->locationProvider + ); + } + + public function testPerformSendsMouseDownCommand() + { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('contextClick'); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverContextClickAction->perform(); + } +} From 18e912aec09efb2e5c232cf5539f45c17b68ec66 Mon Sep 17 00:00:00 2001 From: christian Date: Sat, 25 Jan 2014 19:44:07 +0100 Subject: [PATCH 012/784] Fixed test method name --- tests/interactions/internal/WebDriverContextClickActionTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/interactions/internal/WebDriverContextClickActionTest.php b/tests/interactions/internal/WebDriverContextClickActionTest.php index 21a91468b..1b8f2fb54 100644 --- a/tests/interactions/internal/WebDriverContextClickActionTest.php +++ b/tests/interactions/internal/WebDriverContextClickActionTest.php @@ -20,7 +20,7 @@ public function setUp() ); } - public function testPerformSendsMouseDownCommand() + public function testPerformSendsContextClickCommand() { $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('contextClick'); From abc1bbae4ca9ce94ef0be7cc4b645c9b8294c074 Mon Sep 17 00:00:00 2001 From: christian Date: Tue, 28 Jan 2014 17:41:06 +0100 Subject: [PATCH 013/784] Fixed code style --- .../WebDriverButtonReleaseActionTest.php | 42 +++++++++---------- .../internal/WebDriverClickActionTest.php | 42 +++++++++---------- .../WebDriverClickAndHoldActionTest.php | 42 +++++++++---------- .../WebDriverContextClickActionTest.php | 42 +++++++++---------- 4 files changed, 80 insertions(+), 88 deletions(-) diff --git a/tests/interactions/internal/WebDriverButtonReleaseActionTest.php b/tests/interactions/internal/WebDriverButtonReleaseActionTest.php index a2966ca87..656a6a727 100644 --- a/tests/interactions/internal/WebDriverButtonReleaseActionTest.php +++ b/tests/interactions/internal/WebDriverButtonReleaseActionTest.php @@ -2,29 +2,27 @@ class WebDriverButtonReleaseActionTest extends PHPUnit_Framework_TestCase { - /** - * @type WebDriverButtonReleaseAction - */ - private $webDriverButtonReleaseAction; + /** + * @type WebDriverButtonReleaseAction + */ + private $webDriverButtonReleaseAction; - private $webDriverMouse; - private $locationProvider; + private $webDriverMouse; + private $locationProvider; - public function setUp() - { - $this->webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); - $this->webDriverButtonReleaseAction = new WebDriverButtonReleaseAction( - $this->webDriverMouse, - $this->locationProvider - ); - } + public function setUp() { + $this->webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverButtonReleaseAction = new WebDriverButtonReleaseAction( + $this->webDriverMouse, + $this->locationProvider + ); + } - public function testPerformSendsMouseUpCommand() - { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); - $this->webDriverMouse->expects($this->once())->method('mouseUp'); - $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); - $this->webDriverButtonReleaseAction->perform(); - } + public function testPerformSendsMouseUpCommand() { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('mouseUp'); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverButtonReleaseAction->perform(); + } } diff --git a/tests/interactions/internal/WebDriverClickActionTest.php b/tests/interactions/internal/WebDriverClickActionTest.php index 58f99fea8..b46d93713 100644 --- a/tests/interactions/internal/WebDriverClickActionTest.php +++ b/tests/interactions/internal/WebDriverClickActionTest.php @@ -2,29 +2,27 @@ class WebDriverClickActionTest extends PHPUnit_Framework_TestCase { - /** - * @type WebDriverButtonReleaseAction - */ - private $webDriverClickAction; + /** + * @type WebDriverButtonReleaseAction + */ + private $webDriverClickAction; - private $webDriverMouse; - private $locationProvider; + private $webDriverMouse; + private $locationProvider; - public function setUp() - { - $this->webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); - $this->webDriverClickAction = new WebDriverClickAction( - $this->webDriverMouse, - $this->locationProvider - ); - } + public function setUp() { + $this->webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverClickAction = new WebDriverClickAction( + $this->webDriverMouse, + $this->locationProvider + ); + } - public function testPerformSendsClickCommand() - { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); - $this->webDriverMouse->expects($this->once())->method('click'); - $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); - $this->webDriverClickAction->perform(); - } + public function testPerformSendsClickCommand() { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('click'); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverClickAction->perform(); + } } diff --git a/tests/interactions/internal/WebDriverClickAndHoldActionTest.php b/tests/interactions/internal/WebDriverClickAndHoldActionTest.php index 11867f480..414d4483e 100644 --- a/tests/interactions/internal/WebDriverClickAndHoldActionTest.php +++ b/tests/interactions/internal/WebDriverClickAndHoldActionTest.php @@ -2,29 +2,27 @@ class WebDriverClickAndHoldActionTest extends PHPUnit_Framework_TestCase { - /** - * @type WebDriverClickAndHoldAction - */ - private $webDriverClickAction; + /** + * @type WebDriverClickAndHoldAction + */ + private $webDriverClickAction; - private $webDriverMouse; - private $locationProvider; + private $webDriverMouse; + private $locationProvider; - public function setUp() - { - $this->webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); - $this->webDriverClickAction = new WebDriverClickAndHoldAction( - $this->webDriverMouse, - $this->locationProvider - ); - } + public function setUp() { + $this->webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverClickAction = new WebDriverClickAndHoldAction( + $this->webDriverMouse, + $this->locationProvider + ); + } - public function testPerformSendsMouseDownCommand() - { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); - $this->webDriverMouse->expects($this->once())->method('mouseDown'); - $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); - $this->webDriverClickAction->perform(); - } + public function testPerformSendsMouseDownCommand() { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('mouseDown'); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverClickAction->perform(); + } } diff --git a/tests/interactions/internal/WebDriverContextClickActionTest.php b/tests/interactions/internal/WebDriverContextClickActionTest.php index 1b8f2fb54..f63c144c6 100644 --- a/tests/interactions/internal/WebDriverContextClickActionTest.php +++ b/tests/interactions/internal/WebDriverContextClickActionTest.php @@ -2,29 +2,27 @@ class WebDriverContextClickActionTest extends PHPUnit_Framework_TestCase { - /** - * @type WebDriverContextClickAction - */ - private $webDriverContextClickAction; + /** + * @type WebDriverContextClickAction + */ + private $webDriverContextClickAction; - private $webDriverMouse; - private $locationProvider; + private $webDriverMouse; + private $locationProvider; - public function setUp() - { - $this->webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); - $this->webDriverContextClickAction = new WebDriverContextClickAction( - $this->webDriverMouse, - $this->locationProvider - ); - } + public function setUp() { + $this->webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverContextClickAction = new WebDriverContextClickAction( + $this->webDriverMouse, + $this->locationProvider + ); + } - public function testPerformSendsContextClickCommand() - { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); - $this->webDriverMouse->expects($this->once())->method('contextClick'); - $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); - $this->webDriverContextClickAction->perform(); - } + public function testPerformSendsContextClickCommand() { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('contextClick'); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverContextClickAction->perform(); + } } From d275ee1db6eceb3a0c9c5228cae72eb12867090d Mon Sep 17 00:00:00 2001 From: christian Date: Tue, 28 Jan 2014 20:04:06 +0100 Subject: [PATCH 014/784] Add tests for internal interactions --- .../WebDriverButtonReleaseActionTest.php | 2 +- .../internal/WebDriverClickActionTest.php | 4 +-- .../WebDriverClickAndHoldActionTest.php | 8 ++--- .../WebDriverContextClickActionTest.php | 2 +- .../internal/WebDriverCoordinatesTest.php | 26 ++++++++++++++ .../WebDriverDoubleClickActionTest.php | 28 +++++++++++++++ .../internal/WebDriverKeyDownActionTest.php | 32 +++++++++++++++++ .../internal/WebDriverKeyUpActionTest.php | 33 +++++++++++++++++ .../internal/WebDriverMouseMoveActionTest.php | 28 +++++++++++++++ .../WebDriverMouseToOffsetActionTest.php | 30 ++++++++++++++++ .../internal/WebDriverSendKeysActionTest.php | 35 +++++++++++++++++++ 11 files changed, 220 insertions(+), 8 deletions(-) create mode 100644 tests/interactions/internal/WebDriverCoordinatesTest.php create mode 100644 tests/interactions/internal/WebDriverDoubleClickActionTest.php create mode 100644 tests/interactions/internal/WebDriverKeyDownActionTest.php create mode 100644 tests/interactions/internal/WebDriverKeyUpActionTest.php create mode 100644 tests/interactions/internal/WebDriverMouseMoveActionTest.php create mode 100644 tests/interactions/internal/WebDriverMouseToOffsetActionTest.php create mode 100644 tests/interactions/internal/WebDriverSendKeysActionTest.php diff --git a/tests/interactions/internal/WebDriverButtonReleaseActionTest.php b/tests/interactions/internal/WebDriverButtonReleaseActionTest.php index 656a6a727..d6b6c0ba4 100644 --- a/tests/interactions/internal/WebDriverButtonReleaseActionTest.php +++ b/tests/interactions/internal/WebDriverButtonReleaseActionTest.php @@ -21,7 +21,7 @@ public function setUp() { public function testPerformSendsMouseUpCommand() { $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); - $this->webDriverMouse->expects($this->once())->method('mouseUp'); + $this->webDriverMouse->expects($this->once())->method('mouseUp')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverButtonReleaseAction->perform(); } diff --git a/tests/interactions/internal/WebDriverClickActionTest.php b/tests/interactions/internal/WebDriverClickActionTest.php index b46d93713..5ab22ebf6 100644 --- a/tests/interactions/internal/WebDriverClickActionTest.php +++ b/tests/interactions/internal/WebDriverClickActionTest.php @@ -3,7 +3,7 @@ class WebDriverClickActionTest extends PHPUnit_Framework_TestCase { /** - * @type WebDriverButtonReleaseAction + * @type WebDriverClickAction */ private $webDriverClickAction; @@ -21,7 +21,7 @@ public function setUp() { public function testPerformSendsClickCommand() { $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); - $this->webDriverMouse->expects($this->once())->method('click'); + $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverClickAction->perform(); } diff --git a/tests/interactions/internal/WebDriverClickAndHoldActionTest.php b/tests/interactions/internal/WebDriverClickAndHoldActionTest.php index 414d4483e..685198432 100644 --- a/tests/interactions/internal/WebDriverClickAndHoldActionTest.php +++ b/tests/interactions/internal/WebDriverClickAndHoldActionTest.php @@ -5,7 +5,7 @@ class WebDriverClickAndHoldActionTest extends PHPUnit_Framework_TestCase /** * @type WebDriverClickAndHoldAction */ - private $webDriverClickAction; + private $webDriverClickAndHoldAction; private $webDriverMouse; private $locationProvider; @@ -13,7 +13,7 @@ class WebDriverClickAndHoldActionTest extends PHPUnit_Framework_TestCase public function setUp() { $this->webDriverMouse = $this->getMock('WebDriverMouse'); $this->locationProvider = $this->getMock('WebDriverLocatable'); - $this->webDriverClickAction = new WebDriverClickAndHoldAction( + $this->webDriverClickAndHoldAction = new WebDriverClickAndHoldAction( $this->webDriverMouse, $this->locationProvider ); @@ -21,8 +21,8 @@ public function setUp() { public function testPerformSendsMouseDownCommand() { $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); - $this->webDriverMouse->expects($this->once())->method('mouseDown'); + $this->webDriverMouse->expects($this->once())->method('mouseDown')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); - $this->webDriverClickAction->perform(); + $this->webDriverClickAndHoldAction->perform(); } } diff --git a/tests/interactions/internal/WebDriverContextClickActionTest.php b/tests/interactions/internal/WebDriverContextClickActionTest.php index f63c144c6..e4b323644 100644 --- a/tests/interactions/internal/WebDriverContextClickActionTest.php +++ b/tests/interactions/internal/WebDriverContextClickActionTest.php @@ -21,7 +21,7 @@ public function setUp() { public function testPerformSendsContextClickCommand() { $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); - $this->webDriverMouse->expects($this->once())->method('contextClick'); + $this->webDriverMouse->expects($this->once())->method('contextClick')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverContextClickAction->perform(); } diff --git a/tests/interactions/internal/WebDriverCoordinatesTest.php b/tests/interactions/internal/WebDriverCoordinatesTest.php new file mode 100644 index 000000000..1bc2133c6 --- /dev/null +++ b/tests/interactions/internal/WebDriverCoordinatesTest.php @@ -0,0 +1,26 @@ +assertAttributeEquals(null, 'onScreen', $webDriverCoordinates); + $this->assertAttributeEquals($in_view_port, 'inViewPort', $webDriverCoordinates); + $this->assertAttributeEquals($on_page, 'onPage', $webDriverCoordinates); + $this->assertAttributeEquals('auxiliary', 'auxiliary', $webDriverCoordinates); + } + + public function testGetAuxiliary() + { + $in_view_port = function() { }; + $on_page = function() { }; + + $webDriverCoordinates = new WebDriverCoordinates(null, $in_view_port, $on_page, 'auxiliary'); + + $this->assertEquals('auxiliary', $webDriverCoordinates->getAuxiliary()); + } +} diff --git a/tests/interactions/internal/WebDriverDoubleClickActionTest.php b/tests/interactions/internal/WebDriverDoubleClickActionTest.php new file mode 100644 index 000000000..51961d640 --- /dev/null +++ b/tests/interactions/internal/WebDriverDoubleClickActionTest.php @@ -0,0 +1,28 @@ +webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverDoubleClickAction = new WebDriverDoubleClickAction( + $this->webDriverMouse, + $this->locationProvider + ); + } + + public function testPerformSendsDoubleClickCommand() { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('doubleClick')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverDoubleClickAction->perform(); + } +} diff --git a/tests/interactions/internal/WebDriverKeyDownActionTest.php b/tests/interactions/internal/WebDriverKeyDownActionTest.php new file mode 100644 index 000000000..e5bcc9ba1 --- /dev/null +++ b/tests/interactions/internal/WebDriverKeyDownActionTest.php @@ -0,0 +1,32 @@ +webDriverKeyboard = $this->getMock('WebDriverKeyboard'); + $this->webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverKeyDownAction = new WebDriverKeyDownAction( + $this->webDriverKeyboard, + $this->webDriverMouse, + $this->locationProvider + ); + } + + public function testPerformFocusesOnElementAndSendPressKeyCommand() { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('click')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverKeyboard->expects($this->once())->method('pressKey'); + $this->webDriverKeyDownAction->perform(); + } +} diff --git a/tests/interactions/internal/WebDriverKeyUpActionTest.php b/tests/interactions/internal/WebDriverKeyUpActionTest.php new file mode 100644 index 000000000..90494867a --- /dev/null +++ b/tests/interactions/internal/WebDriverKeyUpActionTest.php @@ -0,0 +1,33 @@ +webDriverKeyboard = $this->getMock('WebDriverKeyboard'); + $this->webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverKeyUpAction = new WebDriverKeyUpAction( + $this->webDriverKeyboard, + $this->webDriverMouse, + $this->locationProvider, + 'a' + ); + } + + public function testPerformFocusesOnElementAndSendPressKeyCommand() { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('click')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverKeyboard->expects($this->once())->method('releaseKey')->with('a'); + $this->webDriverKeyUpAction->perform(); + } +} diff --git a/tests/interactions/internal/WebDriverMouseMoveActionTest.php b/tests/interactions/internal/WebDriverMouseMoveActionTest.php new file mode 100644 index 000000000..98cd80060 --- /dev/null +++ b/tests/interactions/internal/WebDriverMouseMoveActionTest.php @@ -0,0 +1,28 @@ +webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverMouseMoveAction = new WebDriverMouseMoveAction( + $this->webDriverMouse, + $this->locationProvider + ); + } + + public function testPerformFocusesOnElementAndSendPressKeyCommand() { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('mouseMove')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverMouseMoveAction->perform(); + } +} diff --git a/tests/interactions/internal/WebDriverMouseToOffsetActionTest.php b/tests/interactions/internal/WebDriverMouseToOffsetActionTest.php new file mode 100644 index 000000000..278972c19 --- /dev/null +++ b/tests/interactions/internal/WebDriverMouseToOffsetActionTest.php @@ -0,0 +1,30 @@ +webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverMoveToOffsetAction = new WebDriverMoveToOffsetAction( + $this->webDriverMouse, + $this->locationProvider, + 150, + 200 + ); + } + + public function testPerformFocusesOnElementAndSendPressKeyCommand() { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('mouseMove')->with($coords, 150, 200); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverMoveToOffsetAction->perform(); + } +} diff --git a/tests/interactions/internal/WebDriverSendKeysActionTest.php b/tests/interactions/internal/WebDriverSendKeysActionTest.php new file mode 100644 index 000000000..47cd81a4e --- /dev/null +++ b/tests/interactions/internal/WebDriverSendKeysActionTest.php @@ -0,0 +1,35 @@ +webDriverKeyboard = $this->getMock('WebDriverKeyboard'); + $this->webDriverMouse = $this->getMock('WebDriverMouse'); + $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->keys = array('t', 'e', 's', 't'); + $this->webDriverSendKeysAction = new WebDriverSendKeysAction( + $this->webDriverKeyboard, + $this->webDriverMouse, + $this->locationProvider, + $this->keys + ); + } + + public function testPerformFocusesOnElementAndSendPressKeyCommand() { + $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $this->webDriverKeyboard->expects($this->once())->method('sendKeys')->with($this->keys); + $this->webDriverMouse->expects($this->once())->method('click')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverSendKeysAction->perform(); + } +} From 6b724d99f76df47d48a17b34cdd51ddded1a6a45 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Tue, 28 Jan 2014 17:54:25 -0800 Subject: [PATCH 015/784] add license header --- .../WebDriverButtonReleaseActionTest.php | 16 ++++++++++++++-- .../internal/WebDriverClickActionTest.php | 16 ++++++++++++++-- .../internal/WebDriverClickAndHoldActionTest.php | 16 ++++++++++++++-- .../internal/WebDriverContextClickActionTest.php | 16 ++++++++++++++-- .../internal/WebDriverCoordinatesTest.php | 16 ++++++++++++++-- .../internal/WebDriverDoubleClickActionTest.php | 16 ++++++++++++++-- .../internal/WebDriverKeyDownActionTest.php | 16 ++++++++++++++-- .../internal/WebDriverKeyUpActionTest.php | 16 ++++++++++++++-- .../internal/WebDriverMouseMoveActionTest.php | 16 ++++++++++++++-- .../WebDriverMouseToOffsetActionTest.php | 16 ++++++++++++++-- .../internal/WebDriverSendKeysActionTest.php | 16 ++++++++++++++-- 11 files changed, 154 insertions(+), 22 deletions(-) diff --git a/tests/interactions/internal/WebDriverButtonReleaseActionTest.php b/tests/interactions/internal/WebDriverButtonReleaseActionTest.php index d6b6c0ba4..609415846 100644 --- a/tests/interactions/internal/WebDriverButtonReleaseActionTest.php +++ b/tests/interactions/internal/WebDriverButtonReleaseActionTest.php @@ -1,7 +1,19 @@ Date: Wed, 29 Jan 2014 20:26:57 -0800 Subject: [PATCH 016/784] [standardize exception] The name of the exceptions in php-webdriver is not quite good because of a legacy reason. The new php-webdriver was rewritten but it reused the WebDriverException from the old version. This is bad to have non-standard exception names in many senses. Here is a common situation, when the test throws an exception, we might find that it is very hard to search for the solution via search engines because of the odd exceptions name. However, if we search it again using the standard name, we get more solutions and probably fix the bug immediately and easily. Try to google: 1) webdriver unknownserverexception 2) webdriver unhandledwebdrivererror The first one gives 10,800 results and it is the standard name. The second one gives 362 results and it is our bad name. again 1: 1) StaleElementReferenceException <-- 6900 results 2) ObsoleteElementWebDriverError <-- 196 results again 2 1) NoSuchElementWebDriverError <-- 194 results 2) NoSuchElementException <-- 324,000 results There are many solutions or blog posts talking about different tricky or common errors. We could reuse those resource by just renaming the exceptions. This will very beneficial in long term in terms of maintaining, debugging php-webdriver issue, for us and people using it outside facebook. --- lib/WebDriver.php | 2 +- lib/WebDriverElement.php | 2 +- lib/WebDriverExceptions.php | 140 ++++++++++++++--------------- lib/WebDriverExpectedCondition.php | 28 +++--- lib/WebDriverSearchContext.php | 2 +- lib/WebDriverSelect.php | 8 +- lib/WebDriverWait.php | 4 +- lib/WebDriverWindow.php | 4 +- lib/remote/RemoteWebDriver.php | 2 +- lib/remote/RemoteWebElement.php | 2 +- 10 files changed, 97 insertions(+), 97 deletions(-) diff --git a/lib/WebDriver.php b/lib/WebDriver.php index d82911fc8..23e68d78e 100755 --- a/lib/WebDriver.php +++ b/lib/WebDriver.php @@ -29,7 +29,7 @@ public function close(); * Find the first WebDriverElement using the given mechanism. * * @param WebDriverBy $locator - * @return WebDriverElement NoSuchElementWebDriverError is thrown in + * @return WebDriverElement NoSuchElementException is thrown in * HttpCommandExecutor if no element is found. * @see WebDriverBy */ diff --git a/lib/WebDriverElement.php b/lib/WebDriverElement.php index c530123f8..c3677b7a1 100644 --- a/lib/WebDriverElement.php +++ b/lib/WebDriverElement.php @@ -38,7 +38,7 @@ public function click(); * mechanism. * * @param WebDriverBy $locator - * @return WebDriverElement NoSuchElementWebDriverError is thrown in + * @return WebDriverElement NoSuchElementException is thrown in * HttpCommandExecutor if no element is found. * @see WebDriverBy */ diff --git a/lib/WebDriverExceptions.php b/lib/WebDriverExceptions.php index 923cae256..b0d1f47a1 100644 --- a/lib/WebDriverExceptions.php +++ b/lib/WebDriverExceptions.php @@ -41,116 +41,116 @@ public static function throwException($status_code, $message, $results) { // Success break; case 1: - throw new IndexOutOfBoundsWebDriverError($message, $results); + throw new IndexOutOfBoundsException($message, $results); case 2: - throw new NoCollectionWebDriverError($message, $results); + throw new NoCollectionException($message, $results); case 3: - throw new NoStringWebDriverError($message, $results); + throw new NoStringException($message, $results); case 4: - throw new NoStringLengthWebDriverError($message, $results); + throw new NoStringLengthException($message, $results); case 5: - throw new NoStringWrapperWebDriverError($message, $results); + throw new NoStringWrapperException($message, $results); case 6: - throw new NoSuchDriverWebDriverError($message, $results); + throw new NoSuchDriverException($message, $results); case 7: - throw new NoSuchElementWebDriverError($message, $results); + throw new NoSuchElementException($message, $results); case 8: - throw new NoSuchFrameWebDriverError($message, $results); + throw new NoSuchFrameException($message, $results); case 9: - throw new UnknownCommandWebDriverError($message, $results); + throw new UnknownCommandException($message, $results); case 10: - throw new ObsoleteElementWebDriverError($message, $results); + throw new StaleElementReferenceException($message, $results); case 11: - throw new ElementNotDisplayedWebDriverError($message, $results); + throw new ElementNotVisibleException($message, $results); case 12: - throw new InvalidElementStateWebDriverError($message, $results); + throw new InvalidElementStateException($message, $results); case 13: - throw new UnhandledWebDriverError($message, $results); + throw new UnknownServerException($message, $results); case 14: - throw new ExpectedWebDriverError($message, $results); + throw new ExpectedException($message, $results); case 15: - throw new ElementNotSelectableWebDriverError($message, $results); + throw new ElementNotSelectableException($message, $results); case 16: - throw new NoSuchDocumentWebDriverError($message, $results); + throw new NoSuchDocumentException($message, $results); case 17: - throw new UnexpectedJavascriptWebDriverError($message, $results); + throw new UnexpectedJavascriptException($message, $results); case 18: - throw new NoScriptResultWebDriverError($message, $results); + throw new NoScriptResultException($message, $results); case 19: - throw new XPathLookupWebDriverError($message, $results); + throw new XPathLookupException($message, $results); case 20: - throw new NoSuchCollectionWebDriverError($message, $results); + throw new NoSuchCollectionException($message, $results); case 21: - throw new TimeOutWebDriverError($message, $results); + throw new TimeOutException($message, $results); case 22: - throw new NullPointerWebDriverError($message, $results); + throw new NullPointerException($message, $results); case 23: - throw new NoSuchWindowWebDriverError($message, $results); + throw new NoSuchWindowException($message, $results); case 24: - throw new InvalidCookieDomainWebDriverError($message, $results); + throw new InvalidCookieDomainException($message, $results); case 25: - throw new UnableToSetCookieWebDriverError($message, $results); + throw new UnableToSetCookieException($message, $results); case 26: - throw new UnexpectedAlertOpenWebDriverError($message, $results); + throw new UnexpectedAlertOpenException($message, $results); case 27: - throw new NoAlertOpenWebDriverError($message, $results); + throw new NoAlertOpenException($message, $results); case 28: - throw new ScriptTimeoutWebDriverError($message, $results); + throw new ScriptTimeoutException($message, $results); case 29: - throw new InvalidElementCoordinatesWebDriverError($message, $results); + throw new InvalidCoordinatesException($message, $results); case 30: - throw new IMENotAvailableWebDriverError($message, $results); + throw new IMENotAvailableException($message, $results); case 31: - throw new IMEEngineActivationFailedWebDriverError($message, $results); + throw new IMEEngineActivationFailedException($message, $results); case 32: - throw new InvalidSelectorWebDriverError($message, $results); + throw new InvalidSelectorException($message, $results); case 33: - throw new SessionNotCreatedWebDriverError($message, $results); + throw new SessionNotCreatedException($message, $results); case 34: - throw new MoveTargetOutOfBoundsWebDriverError($message, $results); + throw new MoveTargetOutOfBoundsException($message, $results); default: - throw new UnrecognizedWebDriverErrorWebDriverError($message, $results); + throw new UnrecognizedExceptionException($message, $results); } } } -class IndexOutOfBoundsWebDriverError extends WebDriverException {} // 1 -class NoCollectionWebDriverError extends WebDriverException {} // 2 -class NoStringWebDriverError extends WebDriverException {} // 3 -class NoStringLengthWebDriverError extends WebDriverException {} // 4 -class NoStringWrapperWebDriverError extends WebDriverException {} // 5 -class NoSuchDriverWebDriverError extends WebDriverException {} // 6 -class NoSuchElementWebDriverError extends WebDriverException {} // 7 -class NoSuchFrameWebDriverError extends WebDriverException {} // 8 -class UnknownCommandWebDriverError extends WebDriverException {} // 9 -class ObsoleteElementWebDriverError extends WebDriverException {} // 10 -class ElementNotDisplayedWebDriverError extends WebDriverException {} // 11 -class InvalidElementStateWebDriverError extends WebDriverException {} // 12 -class UnhandledWebDriverError extends WebDriverException {} // 13 -class ExpectedWebDriverError extends WebDriverException {} // 14 -class ElementNotSelectableWebDriverError extends WebDriverException {} // 15 -class NoSuchDocumentWebDriverError extends WebDriverException {} // 16 -class UnexpectedJavascriptWebDriverError extends WebDriverException {} // 17 -class NoScriptResultWebDriverError extends WebDriverException {} // 18 -class XPathLookupWebDriverError extends WebDriverException {} // 19 -class NoSuchCollectionWebDriverError extends WebDriverException {} // 20 -class TimeOutWebDriverError extends WebDriverException {} // 21 -class NullPointerWebDriverError extends WebDriverException {} // 22 -class NoSuchWindowWebDriverError extends WebDriverException {} // 23 -class InvalidCookieDomainWebDriverError extends WebDriverException {} // 24 -class UnableToSetCookieWebDriverError extends WebDriverException {} // 25 -class UnexpectedAlertOpenWebDriverError extends WebDriverException {} // 26 -class NoAlertOpenWebDriverError extends WebDriverException {} // 27 -class ScriptTimeoutWebDriverError extends WebDriverException {} // 28 -class InvalidElementCoordinatesWebDriverError extends WebDriverException {}// 29 -class IMENotAvailableWebDriverError extends WebDriverException {} // 30 -class IMEEngineActivationFailedWebDriverError extends WebDriverException {}// 31 -class InvalidSelectorWebDriverError extends WebDriverException {} // 32 -class SessionNotCreatedWebDriverError extends WebDriverException {} // 33 -class MoveTargetOutOfBoundsWebDriverError extends WebDriverException {} // 34 +class IndexOutOfBoundsException extends WebDriverException {} // 1 +class NoCollectionException extends WebDriverException {} // 2 +class NoStringException extends WebDriverException {} // 3 +class NoStringLengthException extends WebDriverException {} // 4 +class NoStringWrapperException extends WebDriverException {} // 5 +class NoSuchDriverException extends WebDriverException {} // 6 +class NoSuchElementException extends WebDriverException {} // 7 +class NoSuchFrameException extends WebDriverException {} // 8 +class UnknownCommandException extends WebDriverException {} // 9 +class StaleElementReferenceException extends WebDriverException {} // 10 +class ElementNotVisibleException extends WebDriverException {} // 11 +class InvalidElementStateException extends WebDriverException {} // 12 +class UnknownServerException extends WebDriverException {} // 13 +class ExpectedException extends WebDriverException {} // 14 +class ElementNotSelectableException extends WebDriverException {} // 15 +class NoSuchDocumentException extends WebDriverException {} // 16 +class UnexpectedJavascriptException extends WebDriverException {} // 17 +class NoScriptResultException extends WebDriverException {} // 18 +class XPathLookupException extends WebDriverException {} // 19 +class NoSuchCollectionException extends WebDriverException {} // 20 +class TimeOutException extends WebDriverException {} // 21 +class NullPointerException extends WebDriverException {} // 22 +class NoSuchWindowException extends WebDriverException {} // 23 +class InvalidCookieDomainException extends WebDriverException {} // 24 +class UnableToSetCookieException extends WebDriverException {} // 25 +class UnexpectedAlertOpenException extends WebDriverException {} // 26 +class NoAlertOpenException extends WebDriverException {} // 27 +class ScriptTimeoutException extends WebDriverException {} // 28 +class InvalidCoordinatesException extends WebDriverException {}// 29 +class IMENotAvailableException extends WebDriverException {} // 30 +class IMEEngineActivationFailedException extends WebDriverException {}// 31 +class InvalidSelectorException extends WebDriverException {} // 32 +class SessionNotCreatedException extends WebDriverException {} // 33 +class MoveTargetOutOfBoundsException extends WebDriverException {} // 34 // Fallback -class UnrecognizedWebDriverErrorWebDriverError extends WebDriverException {} +class UnrecognizedExceptionException extends WebDriverException {} class UnexpectedTagNameException extends WebDriverException { diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index 5d9a6529b..945522c24 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -98,7 +98,7 @@ function ($driver) use ($by) { try { $element = $driver->findElement($by); return $element->isDisplayed() ? $element : null; - } catch (ObsoleteElementWebDriverError $e) { + } catch (StaleElementReferenceException $e) { return null; } } @@ -154,7 +154,7 @@ function ($driver) use ($by, $text) { try { $element_text = $driver->findElement($by)->getText(); return strpos($element_text, $text) !== false; - } catch (ObsoleteElementWebDriverError $e) { + } catch (StaleElementReferenceException $e) { return null; } } @@ -176,7 +176,7 @@ function ($driver) use ($by, $text) { try { $element_text = $driver->findElement($by)->getAttribute('value'); return strpos($element_text, $text) !== false; - } catch (ObsoleteElementWebDriverError $e) { + } catch (StaleElementReferenceException $e) { return null; } } @@ -197,7 +197,7 @@ public static function frameToBeAvailableAndSwitchToIt($frame_locator) { function ($driver) use ($frame_locator) { try { return $driver->switchTo()->frame($frame_locator); - } catch (NoSuchFrameWebDriverError $e) { + } catch (NoSuchFrameException $e) { return false; } } @@ -217,9 +217,9 @@ public static function invisibilityOfElementLocated(WebDriverBy $by) { function ($driver) use ($by) { try { return !($driver->findElement($by)->isDisplayed()); - } catch (NoSuchElementWebDriverError $e) { + } catch (NoSuchElementException $e) { return true; - } catch (ObsoleteElementWebDriverError $e) { + } catch (StaleElementReferenceException $e) { return true; } } @@ -241,9 +241,9 @@ public static function invisibilityOfElementWithText( function ($driver) use ($by, $text) { try { return !($driver->findElement($by)->getText() === $text); - } catch (NoSuchElementWebDriverError $e) { + } catch (NoSuchElementException $e) { return true; - } catch (ObsoleteElementWebDriverError $e) { + } catch (StaleElementReferenceException $e) { return true; } } @@ -273,7 +273,7 @@ function ($driver) use ($visibility_of_element_located) { } else { return null; } - } catch (ObsoleteElementWebDriverError $e) { + } catch (StaleElementReferenceException $e) { return null; } } @@ -293,7 +293,7 @@ function ($driver) use ($element) { try { $element->isEnabled(); return false; - } catch (ObsoleteElementWebDriverError $e) { + } catch (StaleElementReferenceException $e) { return true; } } @@ -306,7 +306,7 @@ function ($driver) use ($element) { * This works around the problem of conditions which have two parts: find an * element and then check for some condition on it. For these conditions it is * possible that an element is located and then subsequently it is redrawn on - * the client. When this happens a ObsoleteElementWebDriverError is thrown + * the client. When this happens a StaleElementReferenceException is thrown * when the second part of the condition is checked. * * @param WebDriverExpectedCondition $condition The condition wrapped. @@ -318,7 +318,7 @@ public static function refreshed(WebDriverExpectedCondition $condition) { function ($driver) use ($condition) { try { return call_user_func($condition->getApply(), $driver); - } catch (ObsoleteElementWebDriverError $e) { + } catch (StaleElementReferenceException $e) { return null; } } @@ -361,7 +361,7 @@ function ($driver) use ($element_or_by, $selected) { try { $element = $driver->findElement($element_or_by); return $element->isSelected === $selected; - } catch (ObsoleteElementWebDriverError $e) { + } catch (StaleElementReferenceException $e) { return null; } } @@ -385,7 +385,7 @@ function ($driver) { $alert = $driver->switchTo()->alert(); $alert->getText(); return $alert; - } catch (NoAlertOpenWebDriverError $e) { + } catch (NoAlertOpenException $e) { return null; } } diff --git a/lib/WebDriverSearchContext.php b/lib/WebDriverSearchContext.php index 2bcd7660e..dacea3f33 100644 --- a/lib/WebDriverSearchContext.php +++ b/lib/WebDriverSearchContext.php @@ -24,7 +24,7 @@ interface WebDriverSearchContext { * mechanism. * * @param WebDriverBy $locator - * @return WebDriverElement NoSuchElementWebDriverError is thrown in + * @return WebDriverElement NoSuchElementException is thrown in * HttpCommandExecutor if no element is found. * @see WebDriverBy */ diff --git a/lib/WebDriverSelect.php b/lib/WebDriverSelect.php index 0468675c6..09d15a56a 100644 --- a/lib/WebDriverSelect.php +++ b/lib/WebDriverSelect.php @@ -72,7 +72,7 @@ public function getFirstSelectedOption() { } } - throw new NoSuchElementWebDriverError('No options are selected'); + throw new NoSuchElementException('No options are selected'); } /** @@ -114,7 +114,7 @@ public function selectByIndex($index) { } } if (!$matched) { - throw new NoSuchElementWebDriverError( + throw new NoSuchElementException( sprintf('Cannot locate option with index: %d', $index) ); } @@ -145,7 +145,7 @@ public function selectByValue($value) { } if (!$matched) { - throw new NoSuchElementWebDriverError( + throw new NoSuchElementException( sprintf('Cannot locate option with value: %s', $value) ); } @@ -192,7 +192,7 @@ public function selectByVisibleText($text) { } if (!$matched) { - throw new NoSuchElementWebDriverError( + throw new NoSuchElementException( sprintf('Cannot locate option with text: %s', $text) ); } diff --git a/lib/WebDriverWait.php b/lib/WebDriverWait.php index 219cdc08e..c5f304e42 100644 --- a/lib/WebDriverWait.php +++ b/lib/WebDriverWait.php @@ -56,7 +56,7 @@ public function until($func_or_ec, $message = "") { if ($ret_val) { return $ret_val; } - } catch (NoSuchElementWebDriverError $e) { + } catch (NoSuchElementException $e) { $last_exception = $e; } usleep($this->interval * 1000); @@ -65,6 +65,6 @@ public function until($func_or_ec, $message = "") { if ($last_exception) { throw $last_exception; } - throw new TimeOutWebDriverError($message); + throw new TimeOutException($message); } } diff --git a/lib/WebDriverWindow.php b/lib/WebDriverWindow.php index 83571f52c..2cdca091e 100644 --- a/lib/WebDriverWindow.php +++ b/lib/WebDriverWindow.php @@ -123,12 +123,12 @@ public function getScreenOrientation() { * * @param string $orientation * @return WebDriverWindow The instance. - * @throws IndexOutOfBoundsWebDriverError + * @throws IndexOutOfBoundsException */ public function setScreenOrientation($orientation) { $orientation = strtoupper($orientation); if (!in_array($orientation, array('PORTRAIT', 'LANDSCAPE'))) { - throw new IndexOutOfBoundsWebDriverError( + throw new IndexOutOfBoundsException( "Orientation must be either PORTRAIT, or LANDSCAPE" ); } diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index b00dbd32c..c199155e0 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -91,7 +91,7 @@ public function close() { * Find the first WebDriverElement using the given mechanism. * * @param WebDriverBy $by - * @return WebDriverElement NoSuchElementWebDriverError is thrown in + * @return WebDriverElement NoSuchElementException is thrown in * HttpCommandExecutor if no element is found. * @see WebDriverBy */ diff --git a/lib/remote/RemoteWebElement.php b/lib/remote/RemoteWebElement.php index b394d5590..f7998f280 100644 --- a/lib/remote/RemoteWebElement.php +++ b/lib/remote/RemoteWebElement.php @@ -54,7 +54,7 @@ public function click() { * mechanism. * * @param WebDriverBy $by - * @return WebDriverElement NoSuchElementWebDriverError is thrown in + * @return WebDriverElement NoSuchElementException is thrown in * HttpCommandExecutor if no element is found. * @see WebDriverBy */ From 45ad3a3fb6f18bc9219c344bbfe77530224e42e8 Mon Sep 17 00:00:00 2001 From: christian Date: Sat, 1 Feb 2014 16:44:27 +0100 Subject: [PATCH 017/784] Add a second test suite for functional tests. Refactor (move method) RemoteWebDriver to provide testability. Add first unit test to RemoteWebDriver. Update README.md unit test section. --- README.md | 2 + lib/remote/RemoteWebDriver.php | 41 ++++++++++++---- tests/__init__.php | 16 ------- tests/bootstrap.php | 1 + .../BaseTest.php} | 18 ++----- .../FileUploadTest.php} | 8 ++-- .../WebDriverTestCase.php} | 3 +- .../files/FileUploadTestCaseFile.txt | 0 tests/{ => functional}/html/index.html | 0 tests/{ => functional}/html/upload.html | 0 tests/phpunit.xml | 7 ++- .../WebDriverButtonReleaseActionTest.php | 0 .../internal/WebDriverClickActionTest.php | 0 .../WebDriverClickAndHoldActionTest.php | 0 .../WebDriverContextClickActionTest.php | 0 .../internal/WebDriverCoordinatesTest.php | 0 .../WebDriverDoubleClickActionTest.php | 0 .../internal/WebDriverKeyDownActionTest.php | 0 .../internal/WebDriverKeyUpActionTest.php | 0 .../internal/WebDriverMouseMoveActionTest.php | 0 .../WebDriverMouseToOffsetActionTest.php | 0 .../internal/WebDriverSendKeysActionTest.php | 0 tests/unit/remote/RemoteWebDriverTest.php | 47 +++++++++++++++++++ 23 files changed, 96 insertions(+), 47 deletions(-) delete mode 100644 tests/__init__.php rename tests/{ExampleTestCase.php => functional/BaseTest.php} (72%) rename tests/{FileUploadTestCase.php => functional/FileUploadTest.php} (84%) rename tests/{BasePHPWebDriverTestCase.php => functional/WebDriverTestCase.php} (92%) rename tests/{ => functional}/files/FileUploadTestCaseFile.txt (100%) rename tests/{ => functional}/html/index.html (100%) rename tests/{ => functional}/html/upload.html (100%) rename tests/{ => unit}/interactions/internal/WebDriverButtonReleaseActionTest.php (100%) rename tests/{ => unit}/interactions/internal/WebDriverClickActionTest.php (100%) rename tests/{ => unit}/interactions/internal/WebDriverClickAndHoldActionTest.php (100%) rename tests/{ => unit}/interactions/internal/WebDriverContextClickActionTest.php (100%) rename tests/{ => unit}/interactions/internal/WebDriverCoordinatesTest.php (100%) rename tests/{ => unit}/interactions/internal/WebDriverDoubleClickActionTest.php (100%) rename tests/{ => unit}/interactions/internal/WebDriverKeyDownActionTest.php (100%) rename tests/{ => unit}/interactions/internal/WebDriverKeyUpActionTest.php (100%) rename tests/{ => unit}/interactions/internal/WebDriverMouseMoveActionTest.php (100%) rename tests/{ => unit}/interactions/internal/WebDriverMouseToOffsetActionTest.php (100%) rename tests/{ => unit}/interactions/internal/WebDriverSendKeysActionTest.php (100%) create mode 100644 tests/unit/remote/RemoteWebDriverTest.php diff --git a/README.md b/README.md index 6b4e15ea9..26f7717fa 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,8 @@ To run unit tests simply run: ./vendor/bin/phpunit -c ./tests +Note: For the functional test suite, a running selenium server is required. + ## MORE INFORMATION Check out the Selenium docs and wiki at http://docs.seleniumhq.org/docs/ and https://code.google.com/p/selenium/wiki diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index c199155e0..d78b4ef8f 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -41,18 +41,11 @@ public static function create( 'name' => 'newSession', 'parameters' => array('desiredCapabilities' => $desired_capabilities), ); - $response = HttpCommandExecutor::remoteExecute( - $command, - array( - CURLOPT_CONNECTTIMEOUT_MS => $timeout_in_ms, - ) - ); + $response = static::remoteExecuteHttpCommand($timeout_in_ms, $command); $driver = new static(); - $executor = new HttpCommandExecutor( - $url, - $response['sessionId'] - ); + $executor = static::createHttpCommandExecutor($url, $response); + return $driver->setCommandExecutor($executor); } @@ -76,6 +69,34 @@ public static function createBySessionID( return $driver; } + /** + * @param string $url + * @param array $response + * @return HttpCommandExecutor + */ + public static function createHttpCommandExecutor($url, $response) { + $executor = new HttpCommandExecutor( + $url, + $response['sessionId'] + ); + return $executor; + } + + /** + * @param int $timeout_in_ms + * @param array $command + * @return array + */ + public static function remoteExecuteHttpCommand($timeout_in_ms, $command) { + $response = HttpCommandExecutor::remoteExecute( + $command, + array( + CURLOPT_CONNECTTIMEOUT_MS => $timeout_in_ms, + ) + ); + return $response; + } + /** * Close the current window. * diff --git a/tests/__init__.php b/tests/__init__.php deleted file mode 100644 index d90f7b531..000000000 --- a/tests/__init__.php +++ /dev/null @@ -1,16 +0,0 @@ -driver->get($this->getTestPath('index.html')); - self::assertEquals( + $this->assertEquals( 'php-webdriver test page', $this->driver->getTitle() ); } - public function testTestPageWelcome() { + public function testGetText() { $this->driver->get($this->getTestPath('index.html')); - self::assertEquals( + $this->assertEquals( 'Welcome to the facebook/php-webdriver testing page.', $this->driver->findElement(WebDriverBy::id('welcome'))->getText() ); diff --git a/tests/FileUploadTestCase.php b/tests/functional/FileUploadTest.php similarity index 84% rename from tests/FileUploadTestCase.php rename to tests/functional/FileUploadTest.php index f88697dd9..21b046037 100644 --- a/tests/FileUploadTestCase.php +++ b/tests/functional/FileUploadTest.php @@ -13,29 +13,27 @@ // See the License for the specific language governing permissions and // limitations under the License. -require_once('__init__.php'); - /** * An example test case for php-webdriver. * * Try running it by * '../vendor/phpunit/phpunit/phpunit.php ExampleTestCase.php' */ -class ExampleTestCase extends BasePHPWebDriverTestCase { +class FileUploadTest extends WebDriverTestCase { public function testFileUploading() { $this->driver->get($this->getTestPath('upload.html')); $file_input = $this->driver->findElement(WebDriverBy::id('upload')); $file_input->setFileDetector(new LocalFileDetector()) ->sendKeys(__DIR__ . '/files/FileUploadTestCaseFile.txt'); - self::assertNotEquals($this->getFilePath(), $file_input->getAttribute('value')); + $this->assertNotEquals($this->getFilePath(), $file_input->getAttribute('value')); } public function testUselessFileDetectorSendKeys() { $this->driver->get($this->getTestPath('upload.html')); $file_input = $this->driver->findElement(WebDriverBy::id('upload')); $file_input->sendKeys($this->getFilePath()); - self::assertEquals($this->getFilePath(), $file_input->getAttribute('value')); + $this->assertEquals($this->getFilePath(), $file_input->getAttribute('value')); } private function getFilePath() { diff --git a/tests/BasePHPWebDriverTestCase.php b/tests/functional/WebDriverTestCase.php similarity index 92% rename from tests/BasePHPWebDriverTestCase.php rename to tests/functional/WebDriverTestCase.php index 1951651bb..92b017b34 100644 --- a/tests/BasePHPWebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -16,8 +16,9 @@ /** * The base class for test cases. */ -class BasePHPWebDriverTestCase extends PHPUnit_Framework_TestCase { +class WebDriverTestCase extends PHPUnit_Framework_TestCase { + /** @var RemoteWebDriver $driver */ protected $driver; protected function setUp() { diff --git a/tests/files/FileUploadTestCaseFile.txt b/tests/functional/files/FileUploadTestCaseFile.txt similarity index 100% rename from tests/files/FileUploadTestCaseFile.txt rename to tests/functional/files/FileUploadTestCaseFile.txt diff --git a/tests/html/index.html b/tests/functional/html/index.html similarity index 100% rename from tests/html/index.html rename to tests/functional/html/index.html diff --git a/tests/html/upload.html b/tests/functional/html/upload.html similarity index 100% rename from tests/html/upload.html rename to tests/functional/html/upload.html diff --git a/tests/phpunit.xml b/tests/phpunit.xml index 4b07ba9b6..88bf4dbde 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -14,8 +14,11 @@ bootstrap = "bootstrap.php" > - - ./ + + ./unit + + + ./functional diff --git a/tests/interactions/internal/WebDriverButtonReleaseActionTest.php b/tests/unit/interactions/internal/WebDriverButtonReleaseActionTest.php similarity index 100% rename from tests/interactions/internal/WebDriverButtonReleaseActionTest.php rename to tests/unit/interactions/internal/WebDriverButtonReleaseActionTest.php diff --git a/tests/interactions/internal/WebDriverClickActionTest.php b/tests/unit/interactions/internal/WebDriverClickActionTest.php similarity index 100% rename from tests/interactions/internal/WebDriverClickActionTest.php rename to tests/unit/interactions/internal/WebDriverClickActionTest.php diff --git a/tests/interactions/internal/WebDriverClickAndHoldActionTest.php b/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php similarity index 100% rename from tests/interactions/internal/WebDriverClickAndHoldActionTest.php rename to tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php diff --git a/tests/interactions/internal/WebDriverContextClickActionTest.php b/tests/unit/interactions/internal/WebDriverContextClickActionTest.php similarity index 100% rename from tests/interactions/internal/WebDriverContextClickActionTest.php rename to tests/unit/interactions/internal/WebDriverContextClickActionTest.php diff --git a/tests/interactions/internal/WebDriverCoordinatesTest.php b/tests/unit/interactions/internal/WebDriverCoordinatesTest.php similarity index 100% rename from tests/interactions/internal/WebDriverCoordinatesTest.php rename to tests/unit/interactions/internal/WebDriverCoordinatesTest.php diff --git a/tests/interactions/internal/WebDriverDoubleClickActionTest.php b/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php similarity index 100% rename from tests/interactions/internal/WebDriverDoubleClickActionTest.php rename to tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php diff --git a/tests/interactions/internal/WebDriverKeyDownActionTest.php b/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php similarity index 100% rename from tests/interactions/internal/WebDriverKeyDownActionTest.php rename to tests/unit/interactions/internal/WebDriverKeyDownActionTest.php diff --git a/tests/interactions/internal/WebDriverKeyUpActionTest.php b/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php similarity index 100% rename from tests/interactions/internal/WebDriverKeyUpActionTest.php rename to tests/unit/interactions/internal/WebDriverKeyUpActionTest.php diff --git a/tests/interactions/internal/WebDriverMouseMoveActionTest.php b/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php similarity index 100% rename from tests/interactions/internal/WebDriverMouseMoveActionTest.php rename to tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php diff --git a/tests/interactions/internal/WebDriverMouseToOffsetActionTest.php b/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php similarity index 100% rename from tests/interactions/internal/WebDriverMouseToOffsetActionTest.php rename to tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php diff --git a/tests/interactions/internal/WebDriverSendKeysActionTest.php b/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php similarity index 100% rename from tests/interactions/internal/WebDriverSendKeysActionTest.php rename to tests/unit/interactions/internal/WebDriverSendKeysActionTest.php diff --git a/tests/unit/remote/RemoteWebDriverTest.php b/tests/unit/remote/RemoteWebDriverTest.php new file mode 100644 index 000000000..e56a3178d --- /dev/null +++ b/tests/unit/remote/RemoteWebDriverTest.php @@ -0,0 +1,47 @@ +getMockBuilder('RemoteWebDriver') + ->disableOriginalConstructor() + ->setMethods(array('remoteExecuteHttpCommand', 'createHttpCommandExecutor')) + ->getMock() + ; + + $timeout = 1000; + $url = 'http://localhost:4444/wd/hub'; + $response = array('value' => 'someValue', 'info' => 'someInfo', 'sessionId' => 'someSessionId'); + $executor = $this->getMockBuilder('HttpCommandExecutor')->disableOriginalConstructor()->getMock(); + + $remoteWebDriver + ->staticExpects($this->once()) + ->method('remoteExecuteHttpCommand') + ->with($timeout, array('url' => $url, 'name' => 'newSession', 'parameters' => array('desiredCapabilities' => array()))) + ->will($this->returnValue($response)) + ; + + $remoteWebDriver + ->staticExpects($this->once()) + ->method('createHttpCommandExecutor') + ->with($url, $response) + ->will($this->returnValue($executor)) + ; + + $remoteWebDriver->create($url, array(), $timeout); + } +} + \ No newline at end of file From f9263790699265d380035fc46a09692e12cc2dc2 Mon Sep 17 00:00:00 2001 From: christian Date: Sat, 1 Feb 2014 21:04:25 +0100 Subject: [PATCH 018/784] Add functional test for WebDriverBy::id --- tests/functional/BaseTest.php | 8 ++++++++ tests/functional/html/index.html | 1 + 2 files changed, 9 insertions(+) diff --git a/tests/functional/BaseTest.php b/tests/functional/BaseTest.php index df9af06e5..fec069e4f 100644 --- a/tests/functional/BaseTest.php +++ b/tests/functional/BaseTest.php @@ -30,4 +30,12 @@ public function testGetText() { $this->driver->findElement(WebDriverBy::id('welcome'))->getText() ); } + + public function testGetById() { + $this->driver->get($this->getTestPath('index.html')); + $this->assertEquals( + 'Test by ID', + $this->driver->findElement(WebDriverBy::id('css_selector_test'))->getText() + ); + } } \ No newline at end of file diff --git a/tests/functional/html/index.html b/tests/functional/html/index.html index c8739903a..89bb12346 100644 --- a/tests/functional/html/index.html +++ b/tests/functional/html/index.html @@ -4,5 +4,6 @@

Welcome to the facebook/php-webdriver testing page.

+

Test by ID

\ No newline at end of file From 0059566aa5254acb6f8df8138db28e1087cce273 Mon Sep 17 00:00:00 2001 From: christian Date: Sat, 1 Feb 2014 21:14:46 +0100 Subject: [PATCH 019/784] Add functional test for WebDriverBy::id - Rename id --- tests/functional/BaseTest.php | 2 +- tests/functional/html/index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/functional/BaseTest.php b/tests/functional/BaseTest.php index fec069e4f..e999f11a2 100644 --- a/tests/functional/BaseTest.php +++ b/tests/functional/BaseTest.php @@ -35,7 +35,7 @@ public function testGetById() { $this->driver->get($this->getTestPath('index.html')); $this->assertEquals( 'Test by ID', - $this->driver->findElement(WebDriverBy::id('css_selector_test'))->getText() + $this->driver->findElement(WebDriverBy::id('id_test'))->getText() ); } } \ No newline at end of file diff --git a/tests/functional/html/index.html b/tests/functional/html/index.html index 89bb12346..17a5e9cc6 100644 --- a/tests/functional/html/index.html +++ b/tests/functional/html/index.html @@ -4,6 +4,6 @@

Welcome to the facebook/php-webdriver testing page.

-

Test by ID

+

Test by ID

\ No newline at end of file From ffa428aca9878a1fd0bb7f382c962711830e5152 Mon Sep 17 00:00:00 2001 From: christian Date: Wed, 5 Feb 2014 18:20:04 +0100 Subject: [PATCH 020/784] Use static::assert* instead of $this->assert* --- tests/functional/BaseTest.php | 6 +++--- tests/functional/FileUploadTest.php | 4 ++-- .../interactions/internal/WebDriverCoordinatesTest.php | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/functional/BaseTest.php b/tests/functional/BaseTest.php index e999f11a2..c73c9e6e2 100644 --- a/tests/functional/BaseTest.php +++ b/tests/functional/BaseTest.php @@ -17,7 +17,7 @@ class BaseTest extends WebDriverTestCase { public function testGetTitle() { $this->driver->get($this->getTestPath('index.html')); - $this->assertEquals( + self::assertEquals( 'php-webdriver test page', $this->driver->getTitle() ); @@ -25,7 +25,7 @@ public function testGetTitle() { public function testGetText() { $this->driver->get($this->getTestPath('index.html')); - $this->assertEquals( + self::assertEquals( 'Welcome to the facebook/php-webdriver testing page.', $this->driver->findElement(WebDriverBy::id('welcome'))->getText() ); @@ -33,7 +33,7 @@ public function testGetText() { public function testGetById() { $this->driver->get($this->getTestPath('index.html')); - $this->assertEquals( + self::assertEquals( 'Test by ID', $this->driver->findElement(WebDriverBy::id('id_test'))->getText() ); diff --git a/tests/functional/FileUploadTest.php b/tests/functional/FileUploadTest.php index 21b046037..84ec454e8 100644 --- a/tests/functional/FileUploadTest.php +++ b/tests/functional/FileUploadTest.php @@ -26,14 +26,14 @@ public function testFileUploading() { $file_input = $this->driver->findElement(WebDriverBy::id('upload')); $file_input->setFileDetector(new LocalFileDetector()) ->sendKeys(__DIR__ . '/files/FileUploadTestCaseFile.txt'); - $this->assertNotEquals($this->getFilePath(), $file_input->getAttribute('value')); + self::assertNotEquals($this->getFilePath(), $file_input->getAttribute('value')); } public function testUselessFileDetectorSendKeys() { $this->driver->get($this->getTestPath('upload.html')); $file_input = $this->driver->findElement(WebDriverBy::id('upload')); $file_input->sendKeys($this->getFilePath()); - $this->assertEquals($this->getFilePath(), $file_input->getAttribute('value')); + self::assertEquals($this->getFilePath(), $file_input->getAttribute('value')); } private function getFilePath() { diff --git a/tests/unit/interactions/internal/WebDriverCoordinatesTest.php b/tests/unit/interactions/internal/WebDriverCoordinatesTest.php index 5991c2157..cf4cc0d12 100644 --- a/tests/unit/interactions/internal/WebDriverCoordinatesTest.php +++ b/tests/unit/interactions/internal/WebDriverCoordinatesTest.php @@ -20,10 +20,10 @@ public function testConstruct() { $webDriverCoordinates = new WebDriverCoordinates(null, $in_view_port, $on_page, 'auxiliary'); - $this->assertAttributeEquals(null, 'onScreen', $webDriverCoordinates); - $this->assertAttributeEquals($in_view_port, 'inViewPort', $webDriverCoordinates); - $this->assertAttributeEquals($on_page, 'onPage', $webDriverCoordinates); - $this->assertAttributeEquals('auxiliary', 'auxiliary', $webDriverCoordinates); + self::assertAttributeEquals(null, 'onScreen', $webDriverCoordinates); + self::assertAttributeEquals($in_view_port, 'inViewPort', $webDriverCoordinates); + self::assertAttributeEquals($on_page, 'onPage', $webDriverCoordinates); + self::assertAttributeEquals('auxiliary', 'auxiliary', $webDriverCoordinates); } public function testGetAuxiliary() @@ -33,6 +33,6 @@ public function testGetAuxiliary() $webDriverCoordinates = new WebDriverCoordinates(null, $in_view_port, $on_page, 'auxiliary'); - $this->assertEquals('auxiliary', $webDriverCoordinates->getAuxiliary()); + self::assertEquals('auxiliary', $webDriverCoordinates->getAuxiliary()); } } From df9a00e9af80f64b0ed5742d3c95505c0fd5927c Mon Sep 17 00:00:00 2001 From: okrad Date: Mon, 17 Feb 2014 17:05:21 +0100 Subject: [PATCH 021/784] isSelected is a method and not a class property --- lib/WebDriverExpectedCondition.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index 945522c24..a08a37a58 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -352,7 +352,7 @@ public static function elementSelectionStateToBe( if ($element_or_by instanceof WebDriverElement) { return new WebDriverExpectedCondition( function ($driver) use ($element_or_by, $selected) { - return $element_or_by->isSelected === $selected; + return $element_or_by->isSelected() === $selected; } ); } else if ($element_or_by instanceof WebDriverBy) { @@ -360,7 +360,7 @@ function ($driver) use ($element_or_by, $selected) { function ($driver) use ($element_or_by, $selected) { try { $element = $driver->findElement($element_or_by); - return $element->isSelected === $selected; + return $element->isSelected() === $selected; } catch (StaleElementReferenceException $e) { return null; } From 5d65696ac64d4842bf015b95819e4ff374a6ddcc Mon Sep 17 00:00:00 2001 From: okrad Date: Mon, 17 Feb 2014 17:05:54 +0100 Subject: [PATCH 022/784] Splitted string into char array --- lib/WebDriverKeys.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/WebDriverKeys.php b/lib/WebDriverKeys.php index db043f81e..a4bf94063 100644 --- a/lib/WebDriverKeys.php +++ b/lib/WebDriverKeys.php @@ -90,8 +90,12 @@ class WebDriverKeys { * @return array */ public static function encode($keys) { + + if(is_numeric($keys)) + $keys = '' . $keys; + if (is_string($keys)) { - $keys = array($keys); + $keys = str_split($keys); } $encoded = array(); From c60fc3d5a3c2a3b3439d2987739697ecca7beb18 Mon Sep 17 00:00:00 2001 From: okrad Date: Mon, 17 Feb 2014 17:20:21 +0100 Subject: [PATCH 023/784] Bugfix for last commit --- lib/WebDriverKeys.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/WebDriverKeys.php b/lib/WebDriverKeys.php index a4bf94063..11712a8a7 100644 --- a/lib/WebDriverKeys.php +++ b/lib/WebDriverKeys.php @@ -95,7 +95,7 @@ public static function encode($keys) { $keys = '' . $keys; if (is_string($keys)) { - $keys = str_split($keys); + $keys = array($keys); } $encoded = array(); @@ -104,7 +104,8 @@ public static function encode($keys) { // handle modified keys $key = implode('', $key).self::NULL; } - $encoded[] = (string)$key; + //$encoded[] = (string)$key; + $encoded = array_merge($encoded, str_split((string)$key)); } return $encoded; From 8bde8d59e2aa50e81008efe0d34b5c8038cb4583 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Mon, 17 Feb 2014 20:30:26 -0800 Subject: [PATCH 024/784] move phpunit from require to require-dev in composer.json --- composer.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 108f2898f..3af7435c8 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,9 @@ "source": "https://github.com/facebook/php-webdriver" }, "require": { - "php": ">=5.3.19", + "php": ">=5.3.19" + }, + "require-dev": { "phpunit/phpunit": "3.7.*" }, "autoload": { From d9ba70407a1a11f2124232452e533e2182a75721 Mon Sep 17 00:00:00 2001 From: okrad Date: Tue, 18 Feb 2014 08:29:41 +0100 Subject: [PATCH 025/784] Removed comment --- lib/WebDriverKeys.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/WebDriverKeys.php b/lib/WebDriverKeys.php index 11712a8a7..1e7f7e5e1 100644 --- a/lib/WebDriverKeys.php +++ b/lib/WebDriverKeys.php @@ -104,7 +104,6 @@ public static function encode($keys) { // handle modified keys $key = implode('', $key).self::NULL; } - //$encoded[] = (string)$key; $encoded = array_merge($encoded, str_split((string)$key)); } From 9ab1af478d6bcc35e05ee1e9139493def2ff88ce Mon Sep 17 00:00:00 2001 From: christianbergau Date: Thu, 20 Feb 2014 17:37:02 +0100 Subject: [PATCH 026/784] Add functional test for WebDriverBy::className --- tests/functional/BaseTest.php | 8 ++++++++ tests/functional/html/index.html | 1 + 2 files changed, 9 insertions(+) diff --git a/tests/functional/BaseTest.php b/tests/functional/BaseTest.php index c73c9e6e2..f94662dee 100644 --- a/tests/functional/BaseTest.php +++ b/tests/functional/BaseTest.php @@ -38,4 +38,12 @@ public function testGetById() { $this->driver->findElement(WebDriverBy::id('id_test'))->getText() ); } + + public function testGetByClassName() { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Test by Class', + $this->driver->findElement(WebDriverBy::className('test_class'))->getText() + ); + } } \ No newline at end of file diff --git a/tests/functional/html/index.html b/tests/functional/html/index.html index 17a5e9cc6..876336ea1 100644 --- a/tests/functional/html/index.html +++ b/tests/functional/html/index.html @@ -5,5 +5,6 @@

Welcome to the facebook/php-webdriver testing page.

Test by ID

+

Test by Class

\ No newline at end of file From 2d7596fb3b3c8149fb6a6fdf105c53b38aa07f13 Mon Sep 17 00:00:00 2001 From: christianbergau Date: Thu, 20 Feb 2014 17:38:34 +0100 Subject: [PATCH 027/784] Add functional test for WebDriverBy::cssSelector --- tests/functional/BaseTest.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/functional/BaseTest.php b/tests/functional/BaseTest.php index f94662dee..54fc79026 100644 --- a/tests/functional/BaseTest.php +++ b/tests/functional/BaseTest.php @@ -46,4 +46,12 @@ public function testGetByClassName() { $this->driver->findElement(WebDriverBy::className('test_class'))->getText() ); } + + public function testGetByCssSelector() { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Test by Class', + $this->driver->findElement(WebDriverBy::cssSelector('.test_class'))->getText() + ); + } } \ No newline at end of file From 33ccaab9e898a6ac7133ed2a7bf9baff6488b067 Mon Sep 17 00:00:00 2001 From: christianbergau Date: Thu, 20 Feb 2014 17:40:53 +0100 Subject: [PATCH 028/784] Add functional test for WebDriverBy::linkText --- tests/functional/BaseTest.php | 8 ++++++++ tests/functional/html/index.html | 1 + 2 files changed, 9 insertions(+) diff --git a/tests/functional/BaseTest.php b/tests/functional/BaseTest.php index 54fc79026..83ac327f1 100644 --- a/tests/functional/BaseTest.php +++ b/tests/functional/BaseTest.php @@ -54,4 +54,12 @@ public function testGetByCssSelector() { $this->driver->findElement(WebDriverBy::cssSelector('.test_class'))->getText() ); } + + public function testGetByLinkText() { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Click here', + $this->driver->findElement(WebDriverBy::linkText('Click here'))->getText() + ); + } } \ No newline at end of file diff --git a/tests/functional/html/index.html b/tests/functional/html/index.html index 876336ea1..de143e6c3 100644 --- a/tests/functional/html/index.html +++ b/tests/functional/html/index.html @@ -6,5 +6,6 @@

Welcome to the facebook/php-webdriver testing page.

Test by ID

Test by Class

+ Click here \ No newline at end of file From ecd04521939e6b38e1f84c717e545bac4c91aede Mon Sep 17 00:00:00 2001 From: christianbergau Date: Thu, 20 Feb 2014 17:44:12 +0100 Subject: [PATCH 029/784] Add functional test for WebDriverBy::name --- tests/functional/BaseTest.php | 8 ++++++++ tests/functional/html/index.html | 1 + 2 files changed, 9 insertions(+) diff --git a/tests/functional/BaseTest.php b/tests/functional/BaseTest.php index 83ac327f1..bf5edbcf6 100644 --- a/tests/functional/BaseTest.php +++ b/tests/functional/BaseTest.php @@ -62,4 +62,12 @@ public function testGetByLinkText() { $this->driver->findElement(WebDriverBy::linkText('Click here'))->getText() ); } + + public function testGetByName() { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Test Value', + $this->driver->findElement(WebDriverBy::name('test_name'))->getAttribute('value') + ); + } } \ No newline at end of file diff --git a/tests/functional/html/index.html b/tests/functional/html/index.html index de143e6c3..6bafefdc9 100644 --- a/tests/functional/html/index.html +++ b/tests/functional/html/index.html @@ -7,5 +7,6 @@

Welcome to the facebook/php-webdriver testing page.

Test by ID

Test by Class

Click here + \ No newline at end of file From ac45e67cc2e08481a0154fbdbcbb6db0abf5aaea Mon Sep 17 00:00:00 2001 From: christianbergau Date: Thu, 20 Feb 2014 17:48:35 +0100 Subject: [PATCH 030/784] Add functional test for WebDriverBy::xpath --- tests/functional/BaseTest.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/functional/BaseTest.php b/tests/functional/BaseTest.php index bf5edbcf6..dfe8fe26d 100644 --- a/tests/functional/BaseTest.php +++ b/tests/functional/BaseTest.php @@ -70,4 +70,12 @@ public function testGetByName() { $this->driver->findElement(WebDriverBy::name('test_name'))->getAttribute('value') ); } + + public function testGetByXpath() { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Test Value', + $this->driver->findElement(WebDriverBy::xpath('//input[@name="test_name"]'))->getAttribute('value') + ); + } } \ No newline at end of file From c9d526520e47747c950b535e40da1e145047c84a Mon Sep 17 00:00:00 2001 From: christianbergau Date: Thu, 20 Feb 2014 17:50:18 +0100 Subject: [PATCH 031/784] Add functional test for WebDriverBy::partialLinkText --- tests/functional/BaseTest.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/functional/BaseTest.php b/tests/functional/BaseTest.php index dfe8fe26d..79b8f0141 100644 --- a/tests/functional/BaseTest.php +++ b/tests/functional/BaseTest.php @@ -78,4 +78,12 @@ public function testGetByXpath() { $this->driver->findElement(WebDriverBy::xpath('//input[@name="test_name"]'))->getAttribute('value') ); } + + public function testGetByPartialLinkText() { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Click here', + $this->driver->findElement(WebDriverBy::partialLinkText('Click'))->getText() + ); + } } \ No newline at end of file From 7fb2ed90fd687157c8d76a5d5dddcabb3058faa8 Mon Sep 17 00:00:00 2001 From: christianbergau Date: Thu, 20 Feb 2014 17:52:31 +0100 Subject: [PATCH 032/784] Add functional test for WebDriverBy::tagName --- tests/functional/BaseTest.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/functional/BaseTest.php b/tests/functional/BaseTest.php index 79b8f0141..69c076cbb 100644 --- a/tests/functional/BaseTest.php +++ b/tests/functional/BaseTest.php @@ -86,4 +86,12 @@ public function testGetByPartialLinkText() { $this->driver->findElement(WebDriverBy::partialLinkText('Click'))->getText() ); } + + public function testGetByTagName() { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Test Value', + $this->driver->findElement(WebDriverBy::tagName('input'))->getAttribute('value') + ); + } } \ No newline at end of file From 342df507312ea5ae5337be47e16e4268d7ed661f Mon Sep 17 00:00:00 2001 From: whhone Date: Fri, 21 Feb 2014 10:22:11 -0800 Subject: [PATCH 033/784] fix non-ascii keys --- lib/WebDriverKeys.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/WebDriverKeys.php b/lib/WebDriverKeys.php index 1e7f7e5e1..ae2b0875e 100644 --- a/lib/WebDriverKeys.php +++ b/lib/WebDriverKeys.php @@ -91,8 +91,9 @@ class WebDriverKeys { */ public static function encode($keys) { - if(is_numeric($keys)) + if (is_numeric($keys)) { $keys = '' . $keys; + } if (is_string($keys)) { $keys = array($keys); @@ -104,7 +105,7 @@ public static function encode($keys) { // handle modified keys $key = implode('', $key).self::NULL; } - $encoded = array_merge($encoded, str_split((string)$key)); + $encoded[] = (string)$key; } return $encoded; From 588a5fa7df3c99172428a3ee6dee1de2690a1e58 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Tue, 25 Feb 2014 20:08:43 -0800 Subject: [PATCH 034/784] add 2 methods --- lib/remote/HttpCommandExecutor.php | 7 +++++++ lib/remote/RemoteWebDriver.php | 25 +++++++++++++++++++---- tests/unit/remote/RemoteWebDriverTest.php | 4 ++-- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index 8c6f237cc..53d0e670a 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -255,6 +255,13 @@ protected static function curl( return array('value' => $value, 'info' => $info, 'sessionId' => $sessionId); } + /** + * @return string + */ + public function getAddressOfRemoteServer() { + return $this->url; + } + /** * @return string */ diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index d78b4ef8f..b21bea183 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -44,7 +44,7 @@ public static function create( $response = static::remoteExecuteHttpCommand($timeout_in_ms, $command); $driver = new static(); - $executor = static::createHttpCommandExecutor($url, $response); + $executor = static::createHttpCommandExecutor($url, $response['sessionId']); return $driver->setCommandExecutor($executor); } @@ -71,13 +71,13 @@ public static function createBySessionID( /** * @param string $url - * @param array $response + * @param string $session_id * @return HttpCommandExecutor */ - public static function createHttpCommandExecutor($url, $response) { + public static function createHttpCommandExecutor($url, $session_id) { $executor = new HttpCommandExecutor( $url, - $response['sessionId'] + $session_id ); return $executor; } @@ -394,8 +394,25 @@ public function getCommandExecutor() { return $this->executor; } + /** + * Set the session id of the RemoteWebDriver. + * + * @param string $session_id + * @return WebDriver + */ + public function setSessionID($session_id) { + $this->setCommandExecutor( + new HttpCommandExecutor( + $this->executor->getAddressOfRemoteServer(), + $session_id + ) + ); + return $this; + } + /** * Get current selenium sessionID + * * @return sessionID */ public function getSessionID() { diff --git a/tests/unit/remote/RemoteWebDriverTest.php b/tests/unit/remote/RemoteWebDriverTest.php index e56a3178d..3da28ae07 100644 --- a/tests/unit/remote/RemoteWebDriverTest.php +++ b/tests/unit/remote/RemoteWebDriverTest.php @@ -37,11 +37,11 @@ public function testCreate() { $remoteWebDriver ->staticExpects($this->once()) ->method('createHttpCommandExecutor') - ->with($url, $response) + ->with($url, $response['sessionId']) ->will($this->returnValue($executor)) ; $remoteWebDriver->create($url, array(), $timeout); } } - \ No newline at end of file + From 8a360e5a26cc1618c3ec086ac04f297bcb4f5c1c Mon Sep 17 00:00:00 2001 From: whhone Date: Fri, 28 Feb 2014 09:14:34 -0800 Subject: [PATCH 035/784] [executeAsyncScript] Implement executeAsyncScript in RemoteWebDriver. Add interface JavaScriptExecutor. This is done by our bootcamper, glh@fb! --- lib/JavaScriptExecutor.php | 47 +++++++++++++++++++++ lib/WebDriver.php | 11 ----- lib/__init__.php | 1 + lib/remote/HttpCommandExecutor.php | 1 + lib/remote/RemoteWebDriver.php | 26 ++++++++++-- lib/support/events/EventFiringWebDriver.php | 31 +++++++++++++- 6 files changed, 102 insertions(+), 15 deletions(-) create mode 100644 lib/JavaScriptExecutor.php diff --git a/lib/JavaScriptExecutor.php b/lib/JavaScriptExecutor.php new file mode 100644 index 000000000..783f0baa7 --- /dev/null +++ b/lib/JavaScriptExecutor.php @@ -0,0 +1,47 @@ + array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/element'), 'elementFindElements' => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/elements'), 'executeScript' => array('method' => 'POST', 'url' => '/session/:sessionId/execute'), + 'executeAsyncScript' => array('method' => 'POST', 'url' => '/session/:sessionId/execute_async'), 'findElement' => array('method' => 'POST', 'url' => '/session/:sessionId/element'), 'findElements' => array('method' => 'POST', 'url' => '/session/:sessionId/elements'), 'focusFrame' => array('method' => 'POST', 'url' => '/session/:sessionId/frame'), diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index b21bea183..3ec129ad7 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -class RemoteWebDriver implements WebDriver { +class RemoteWebDriver implements WebDriver, JavaScriptExecutor { protected $executor; protected $mouse; @@ -246,8 +246,28 @@ public function executeScript($script, array $arguments = array()) { 'script' => $script, 'args' => $this->prepareScriptArguments($arguments), ); - $response = $this->executor->execute('executeScript', $params); - return $response; + return $this->executor->execute('executeScript', $params); + } + + /** + * Inject a snippet of JavaScript into the page for asynchronous execution in + * the context of the currently selected frame. + * + * The driver will pass a callback as the last argument to the snippet, and + * block until the callback is invoked. + * + * @see WebDriverExecuteAsyncScriptTestCase + * + * @param string $script The script to inject. + * @param array $arguments The arguments of the script. + * @return mixed The value passed by the script to the callback. + */ + public function executeAsyncScript($script, array $arguments = array()) { + $params = array( + 'script' => $script, + 'args' => $this->prepareScriptArguments($arguments), + ); + return $this->executor->execute('executeAsyncScript', $params); } /** diff --git a/lib/support/events/EventFiringWebDriver.php b/lib/support/events/EventFiringWebDriver.php index f86a6c4d2..0ac1695e1 100644 --- a/lib/support/events/EventFiringWebDriver.php +++ b/lib/support/events/EventFiringWebDriver.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -class EventFiringWebDriver implements WebDriver { +class EventFiringWebDriver implements WebDriver, JavaScriptExecutor { /** * @var WebDriver @@ -134,6 +134,12 @@ public function findElement(WebDriverBy $by) { * @throws WebDriverException */ public function executeScript($script, array $arguments = array()) { + if (!$this->driver instanceof JavaScriptExecutor) { + throw new UnsupportedOperationException( + 'driver does not implement JavaScriptExecutor', + ); + } + $this->dispatch('beforeScript', $script, $this); try { $result = $this->driver->executeScript($script, $arguments); @@ -144,6 +150,29 @@ public function executeScript($script, array $arguments = array()) { return $result; } + /** + * @param $script + * @param array $arguments + * @return mixed + * @throws WebDriverException + */ + public function executeAsyncScript($script, array $arguments = array()) { + if (!$this->driver instanceof JavaScriptExecutor) { + throw new UnsupportedOperationException( + 'driver does not implement JavaScriptExecutor', + ); + } + + $this->dispatch('beforeScript', $script, $this); + try { + $result = $this->driver->executeAsyncScript($script, $arguments); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch('afterScript', $script, $this); + return $result; + } + /** * @return $this * @throws WebDriverException From e2d73c813c4e3d76a11793bad158a8a0ec26e8ea Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Fri, 28 Feb 2014 09:33:47 -0800 Subject: [PATCH 036/784] fix --- lib/JavaScriptExecutor.php | 2 +- lib/support/events/EventFiringWebDriver.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/JavaScriptExecutor.php b/lib/JavaScriptExecutor.php index 783f0baa7..131a7fef1 100644 --- a/lib/JavaScriptExecutor.php +++ b/lib/JavaScriptExecutor.php @@ -1,4 +1,4 @@ -driver instanceof JavaScriptExecutor) { throw new UnsupportedOperationException( - 'driver does not implement JavaScriptExecutor', + 'driver does not implement JavaScriptExecutor' ); } @@ -159,7 +159,7 @@ public function executeScript($script, array $arguments = array()) { public function executeAsyncScript($script, array $arguments = array()) { if (!$this->driver instanceof JavaScriptExecutor) { throw new UnsupportedOperationException( - 'driver does not implement JavaScriptExecutor', + 'driver does not implement JavaScriptExecutor' ); } From aeaab8a2228d55cec796b5fc66e9e9254537d152 Mon Sep 17 00:00:00 2001 From: Ling-Yi Kung Date: Tue, 11 Mar 2014 22:49:01 -0700 Subject: [PATCH 037/784] Check whether an array is associative for script arguments. --- lib/remote/RemoteWebDriver.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index 3ec129ad7..88c682d20 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -218,6 +218,11 @@ public function quit() { * @return array */ private function prepareScriptArguments(array $arguments) { + // If arguments is an associative array, don't do anything. + if ((bool)count(array_filter(array_keys($arguments), 'is_string'))) { + return $arguments; + } + $args = array(); foreach ($arguments as $arg) { if ($arg instanceof WebDriverElement) { From da65338d24a345cde741ebedf8c1a34981ba0b39 Mon Sep 17 00:00:00 2001 From: Ling-Yi Kung Date: Wed, 12 Mar 2014 11:48:05 -0700 Subject: [PATCH 038/784] Use foreach to check associative arrays. --- lib/remote/RemoteWebDriver.php | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index 88c682d20..9bb9f2c15 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -218,20 +218,15 @@ public function quit() { * @return array */ private function prepareScriptArguments(array $arguments) { - // If arguments is an associative array, don't do anything. - if ((bool)count(array_filter(array_keys($arguments), 'is_string'))) { - return $arguments; - } - $args = array(); - foreach ($arguments as $arg) { - if ($arg instanceof WebDriverElement) { - $args[] = array('ELEMENT'=>$arg->getID()); + foreach ($arguments as $key => $value) { + if ($value instanceof WebDriverElement) { + $args[$key] = array('ELEMENT'=>$value->getID()); } else { - if (is_array($arg)) { - $arg = $this->prepareScriptArguments($arg); + if (is_array($value)) { + $value = $this->prepareScriptArguments($value); } - $args[] = $arg; + $args[$key] = $value; } } return $args; From 2695367437710de164ed2ed6f17d29de2d1be438 Mon Sep 17 00:00:00 2001 From: Jordan Pickwell Date: Fri, 18 Apr 2014 10:40:46 -0500 Subject: [PATCH 039/784] Fix #141. Removed the redefined methods. --- lib/WebDriver.php | 21 --------------------- lib/WebDriverElement.php | 21 --------------------- 2 files changed, 42 deletions(-) diff --git a/lib/WebDriver.php b/lib/WebDriver.php index b49c71cec..6a87cbbcd 100755 --- a/lib/WebDriver.php +++ b/lib/WebDriver.php @@ -25,27 +25,6 @@ interface WebDriver extends WebDriverSearchContext { */ public function close(); - /** - * Find the first WebDriverElement using the given mechanism. - * - * @param WebDriverBy $locator - * @return WebDriverElement NoSuchElementException is thrown in - * HttpCommandExecutor if no element is found. - * @see WebDriverBy - */ - public function findElement(WebDriverBy $locator); - - /** - * Find all WebDriverElements within the current page using the given - * mechanism. - * - * @param WebDriverBy $locator - * @return array A list of all WebDriverElements, - * or an empty array if nothing matches - * @see WebDriverBy - */ - public function findElements(WebDriverBy $locator); - /** * Load a new web page in the current browser window. * diff --git a/lib/WebDriverElement.php b/lib/WebDriverElement.php index c3677b7a1..81bbbd5f6 100644 --- a/lib/WebDriverElement.php +++ b/lib/WebDriverElement.php @@ -33,27 +33,6 @@ public function clear(); */ public function click(); - /** - * Find the first WebDriverElement within this element using the given - * mechanism. - * - * @param WebDriverBy $locator - * @return WebDriverElement NoSuchElementException is thrown in - * HttpCommandExecutor if no element is found. - * @see WebDriverBy - */ - public function findElement(WebDriverBy $locator); - - /** - * Find all WebDriverElements within this element using the given mechanism. - * - * @param WebDriverBy $locator - * @return array A list of all WebDriverElements, or an empty array if - * nothing matches - * @see WebDriverBy - */ - public function findElements(WebDriverBy $locator); - /** * Get the value of a the given attribute of the element. * From ac4c46c9fc35bc9de49ec0a47ec6cdb747197811 Mon Sep 17 00:00:00 2001 From: whhone Date: Tue, 20 May 2014 08:59:24 -0700 Subject: [PATCH 040/784] DesiredCapabilities + WebDriverPlatform Make desired capabilities object-oriented. To start a RemoteWebDriver instance, we can use pre-defineded DesiredCapabilities instead of constructing an array everytime. For example, to start Chrome. ``` $driver = RemoteWebDriver::create($url, DesiredCapabilities::chrome()); ``` --- example.php | 2 +- lib/WebDriverCapabilities.php | 47 ++++++++ lib/WebDriverPlatform.php | 29 +++++ lib/__init__.php | 3 + lib/remote/DesiredCapabilities.php | 184 +++++++++++++++++++++++++++++ lib/remote/RemoteWebDriver.php | 11 +- 6 files changed, 273 insertions(+), 3 deletions(-) create mode 100644 lib/WebDriverCapabilities.php create mode 100644 lib/WebDriverPlatform.php create mode 100644 lib/remote/DesiredCapabilities.php diff --git a/example.php b/example.php index 39ffb5a96..a1e133b91 100644 --- a/example.php +++ b/example.php @@ -5,7 +5,7 @@ // start Firefox with 5 second timeout $host = 'http://localhost:4444/wd/hub'; // this is the default -$capabilities = array(WebDriverCapabilityType::BROWSER_NAME => 'firefox'); +$capabilities = DesiredCapabilities::firefox(); $driver = RemoteWebDriver::create($host, $capabilities, 5000); // navigate to 'http://docs.seleniumhq.org/' diff --git a/lib/WebDriverCapabilities.php b/lib/WebDriverCapabilities.php new file mode 100644 index 000000000..3eb65f474 --- /dev/null +++ b/lib/WebDriverCapabilities.php @@ -0,0 +1,47 @@ +capabilities = $capabilities; + } + + /** + * @return string The name of the browser. + */ + public function getBrowserName() { + return $this->get(WebDriverCapabilityType::BROWSER_NAME, ''); + } + + public function setBrowserName($browser_name) { + $this->set(WebDriverCapabilityType::BROWSER_NAME, $browser_name); + return $this; + } + + /** + * @return string The version of the browser. + */ + public function getVersion() { + return $this->get(WebDriverCapabilityType::VERSION, ''); + } + + public function setVersion($version) { + $this->set(WebDriverCapabilityType::VERSION, $version); + return $this; + } + + /** + * @return mixed The value of a capability. + */ + public function getCapability($name) { + $this->get($name); + } + + public function setCapability($name, $value) { + $this->set($name, $value); + return $this; + } + + /** + * @return string The name of the platform. + */ + public function getPlatform() { + return $this->get(WebDriverCapabilityType::PLATFORM, ''); + } + + public function setPlatform($platform) { + $this->set(WebDriverCapabilityType::PLATFORM, $platform); + return $this; + } + + + /** + * @return bool Whether the value is not null and not false. + */ + public function is($capability_name) { + return (bool)$this->get($capability_name); + } + + /** + * @return bool Whether javascript is enabled. + */ + public function isJavascriptEnabled() { + return $this->get(WebDriverCapabilityType::JAVASCRIPT_ENABLED, false); + } + + public function setJavascriptEnabled($enabled) { + $this->set(WebDriverCapabilityType::JAVASCRIPT_ENABLED, $enabled); + return $this; + } + + public function toArray() { + return $this->capabilities; + } + + private function set($key, $value) { + $this->capabilities[$key] = $value; + return $this; + } + + private function get($key, $default = null) { + return isset($this->capabilities[$key]) + ? $this->capabilities[$key] + : $default; + } + + public static function android() { + return new DesiredCapabilities(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::ANDROID, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANDROID, + )); + } + + public static function chrome() { + return new DesiredCapabilities(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::CHROME, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, + )); + } + + public static function firefox() { + return new DesiredCapabilities(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::FIREFOX, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, + )); + } + + public static function htmlUnit() { + return new DesiredCapabilities(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::HTMLUNIT, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, + )); + } + + public static function htmlUnitWithJS() { + $caps = new DesiredCapabilities(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::HTMLUNIT, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, + )); + return $caps->setJavascriptEnabled(true); + } + + public static function internetExplorer() { + return new DesiredCapabilities(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::IE, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::WINDOWS, + )); + } + + public static function iphone() { + return new DesiredCapabilities(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::IPHONE, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::MAC, + )); + } + + public static function ipad() { + return new DesiredCapabilities(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::IPAD, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::MAC, + )); + } + + public static function opera() { + return new DesiredCapabilities(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::OPERA, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, + )); + } + + public static function safari() { + return new DesiredCapabilities(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::SAFARI, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, + )); + } + + public static function phantomjs() { + return new DesiredCapabilities(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::PHANTOMJS, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, + )); + } +} diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index 9bb9f2c15..a04908f30 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -26,16 +26,23 @@ protected function __construct() {} * Construct the RemoteWebDriver by a desired capabilities. * * @param string $url The url of the remote server - * @param array $desired_capabilities The webdriver desired capabilities + * @param DesiredCapabilities $desired_capabilities The desired capabilities * @param int $timeout_in_ms * @return RemoteWebDriver */ public static function create( $url = 'http://localhost:4444/wd/hub', - $desired_capabilities = array(), + $desired_capabilities = null, $timeout_in_ms = 300000 ) { $url = preg_replace('#/+$#', '', $url); + + // Passing DesiredCapabilities as $desired_capabilities is encourged but + // array is also accepted for legacy reason. + if ($desired_capabilities instanceof DesiredCapabilities) { + $desired_capabilities = $desired_capabilities->toArray(); + } + $command = array( 'url' => $url, 'name' => 'newSession', From 80bb705533a760e5afc914374bbfbf1fd40e53c0 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Tue, 20 May 2014 09:51:58 -0700 Subject: [PATCH 041/784] Update README.md Migrate to DesiredCapabilities. --- README.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 26f7717fa..7b278f8fe 100644 --- a/README.md +++ b/README.md @@ -47,10 +47,22 @@ Install the library. // This would be the url of the host running the server-standalone.jar $host = 'http://localhost:4444/wd/hub'; // this is the default - $capabilities = array(WebDriverCapabilityType::BROWSER_NAME => 'firefox'); - $driver = RemoteWebDriver::create($host, $capabilities); -* The $capabilities array lets you specify (among other things) which browser to use. See https://code.google.com/p/selenium/wiki/DesiredCapabilities for more details. +* Launch Firefox + + $driver = RemoteWebDriver::create($host, DesiredCapabilities::firefox()); + +* Launch Chrome + + $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome()); + +* You can also customize the desired capabilities. + + $desired_capabilities = DesiredCapabilities::firefox(); + $desired_capabilities->setJavascriptEnabled(false); + RemoteWebDriver::create($host, $desired_capabilities); + +* See https://code.google.com/p/selenium/wiki/DesiredCapabilities for more details. ## RUN UNIT TESTS From cf29441ba713e249f49e58390b0608b360932180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=9A=D0=BE=D0=BB?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Wed, 21 May 2014 11:00:03 +0400 Subject: [PATCH 042/784] Fix phpdoc comments for FileDetector. --- lib/remote/FileDetector.php | 14 ++++++++------ lib/remote/LocalFileDetector.php | 8 ++++++-- lib/remote/UselessFileDetector.php | 8 ++++++-- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/lib/remote/FileDetector.php b/lib/remote/FileDetector.php index c452058c0..dc79cff1e 100644 --- a/lib/remote/FileDetector.php +++ b/lib/remote/FileDetector.php @@ -15,11 +15,13 @@ interface FileDetector { - /** - * Try to detect whether the given $file is a file or not. Return the path - * of the file. Otherwise, return null. - * - * @return ?string The path of the file. - */ + /** + * Try to detect whether the given $file is a file or not. Return the path + * of the file. Otherwise, return null. + * + * @param string $file + * + * @return string The path of the file. + */ public function getLocalFile($file); } diff --git a/lib/remote/LocalFileDetector.php b/lib/remote/LocalFileDetector.php index cf118b5ec..f0107b0ba 100644 --- a/lib/remote/LocalFileDetector.php +++ b/lib/remote/LocalFileDetector.php @@ -14,8 +14,12 @@ // limitations under the License. class LocalFileDetector implements FileDetector { - - public function getLocalFile($file) { + /** + * @param string $file + * + * @return null|string + */ + public function getLocalFile($file) { if (is_file($file)) { return $file; } diff --git a/lib/remote/UselessFileDetector.php b/lib/remote/UselessFileDetector.php index 8923c7694..f200990c6 100644 --- a/lib/remote/UselessFileDetector.php +++ b/lib/remote/UselessFileDetector.php @@ -14,8 +14,12 @@ // limitations under the License. class UselessFileDetector implements FileDetector { - - public function getLocalFile($file) { + /** + * @param string $file + * + * @return null + */ + public function getLocalFile($file) { return null; } } From 9c5944426b6dec10f4c009b8f2ca2ba68b6c1f32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=9A=D0=BE=D0=BB?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Wed, 21 May 2014 11:09:44 +0400 Subject: [PATCH 043/784] Fix phpdoc comments for RemoteWebDriver. --- .gitignore | 1 + lib/remote/RemoteWebDriver.php | 56 ++++++++++++++++++++++------------ 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index 7e4c563c5..88ca8c5ff 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ vendor *.DS_Store *~ *.swp +.idea \ No newline at end of file diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index 9bb9f2c15..e29772ae9 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -14,10 +14,21 @@ // limitations under the License. class RemoteWebDriver implements WebDriver, JavaScriptExecutor { - + /** + * @var HttpCommandExecutor + */ protected $executor; + /** + * @var RemoteMouse + */ protected $mouse; + /** + * @var RemoteKeyboard + */ protected $keyboard; + /** + * @var RemoteTouchScreen + */ protected $touch; protected function __construct() {} @@ -43,7 +54,7 @@ public static function create( ); $response = static::remoteExecuteHttpCommand($timeout_in_ms, $command); - $driver = new static(); + $driver = new self(); $executor = static::createHttpCommandExecutor($url, $response['sessionId']); return $driver->setCommandExecutor($executor); @@ -64,7 +75,7 @@ public static function createBySessionID( $session_id, $url = 'http://localhost:4444/wd/hub' ) { - $driver = new static(); + $driver = new self(); $driver->setCommandExecutor(new HttpCommandExecutor($url, $session_id)); return $driver; } @@ -100,7 +111,7 @@ public static function remoteExecuteHttpCommand($timeout_in_ms, $command) { /** * Close the current window. * - * @return WebDriver The current instance. + * @return RemoteWebDriver The current instance. */ public function close() { $this->executor->execute('closeCurrentWindow', array()); @@ -112,7 +123,7 @@ public function close() { * Find the first WebDriverElement using the given mechanism. * * @param WebDriverBy $by - * @return WebDriverElement NoSuchElementException is thrown in + * @return RemoteWebElement NoSuchElementException is thrown in * HttpCommandExecutor if no element is found. * @see WebDriverBy */ @@ -128,7 +139,7 @@ public function findElement(WebDriverBy $by) { * mechanism. * * @param WebDriverBy $by - * @return array A list of all WebDriverElements, or an empty array if + * @return RemoteWebElement[] A list of all WebDriverElements, or an empty array if * nothing matches * @see WebDriverBy */ @@ -143,11 +154,13 @@ public function findElements(WebDriverBy $by) { return $elements; } - /** - * Load a new web page in the current browser window. - * - * @return WebDriver The current instance. - */ + /** + * Load a new web page in the current browser window. + * + * @param string $url + * + * @return RemoteWebDriver The current instance. + */ public function get($url) { $params = array('url' => (string)$url); $this->executor->execute('get', $params); @@ -294,6 +307,9 @@ public function takeScreenshot($save_as = null) { * WebDriverExpectedCondition::titleIs('WebDriver Page') * ); * + * @param int $timeout_in_second + * @param int $interval_in_millisecond + * * @return WebDriverWait */ public function wait( @@ -336,7 +352,7 @@ public function switchTo() { } /** - * @return WebDriverMouse + * @return RemoteMouse */ public function getMouse() { if (!$this->mouse) { @@ -346,7 +362,7 @@ public function getMouse() { } /** - * @return WebDriverKeyboard + * @return RemoteKeyboard */ public function getKeyboard() { if (!$this->keyboard) { @@ -356,7 +372,7 @@ public function getKeyboard() { } /** - * @return WebDriverTouchScreen + * @return RemoteTouchScreen */ public function getTouch() { if (!$this->touch) { @@ -377,7 +393,7 @@ public function action() { /** * Get the element on the page that currently has focus. * - * @return WebDriverElement + * @return RemoteWebElement */ public function getActiveElement() { $response = $this->executor->execute('getActiveElement'); @@ -388,7 +404,7 @@ public function getActiveElement() { * Return the WebDriverElement with the given id. * * @param string $id The id of the element to be created. - * @return WebDriverElement + * @return RemoteWebElement */ private function newElement($id) { return new RemoteWebElement($this->executor, $id); @@ -398,7 +414,7 @@ private function newElement($id) { * Set the command executor of this RemoteWebdrver * * @param WebDriverCommandExecutor $executor - * @return WebDriver + * @return RemoteWebDriver */ public function setCommandExecutor(WebDriverCommandExecutor $executor) { $this->executor = $executor; @@ -408,7 +424,7 @@ public function setCommandExecutor(WebDriverCommandExecutor $executor) { /** * Set the command executor of this RemoteWebdriver * - * @return WebDriverCommandExecutor + * @return HttpCommandExecutor */ public function getCommandExecutor() { return $this->executor; @@ -418,7 +434,7 @@ public function getCommandExecutor() { * Set the session id of the RemoteWebDriver. * * @param string $session_id - * @return WebDriver + * @return RemoteWebDriver */ public function setSessionID($session_id) { $this->setCommandExecutor( @@ -433,7 +449,7 @@ public function setSessionID($session_id) { /** * Get current selenium sessionID * - * @return sessionID + * @return string sessionID */ public function getSessionID() { return $this->executor->getSessionID(); From 77bd9cee95b7b9885fa1f1ff3ea829b07ea56c1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=9A=D0=BE=D0=BB?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Wed, 21 May 2014 11:15:41 +0400 Subject: [PATCH 044/784] Fix phpdoc comments for HttpCommandExecutor. --- lib/remote/HttpCommandExecutor.php | 39 +++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index 93f916fd5..5d4325e75 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -98,16 +98,35 @@ class HttpCommandExecutor implements WebDriverCommandExecutor { 'touchUp' => array('method' => 'POST', 'url' => '/session/:sessionId/touch/up'), ); + /** + * @var string + */ protected $url; + /** + * @var string + */ protected $sessionID; + /** + * @var array + */ protected $capabilities; + /** + * @param string $url + * @param string $session_id + */ public function __construct($url, $session_id) { $this->url = $url; $this->sessionID = $session_id; $this->capabilities = $this->execute('getSession', array()); } + /** + * @param string $name + * @param array $params + * + * @return mixed + */ public function execute($name, array $params = array()) { $command = array( 'url' => $this->url, @@ -127,16 +146,17 @@ public function execute($name, array $params = array()) { * name : the name of the command * parameters : the parameters of the command required * - * @param command An array that contains + * @param array $command An array that contains * url : the url of the remote server * sessionId : the session id if needed * name : the name of the command * parameters : the parameters of the command required - * @param curl_opts An array of curl options. + * @param array $curl_opts An array of curl options. * * @return array The response of the command. + * @throws Exception */ - public static function remoteExecute($command, $curl_opts = array()) { + public static function remoteExecute(array $command, array $curl_opts = array()) { if (!isset(self::$commands[$command['name']])) { throw new Exception($command['name']." is not a valid command."); } @@ -157,17 +177,18 @@ public static function remoteExecute($command, $curl_opts = array()) { /** * Curl request to webdriver server. * - * @param http_method 'GET', 'POST', or 'DELETE' - * @param suffix What to append to the base URL. - * @param command The Command object, modelled as a hash. - * @param extra_opts key => value pairs of curl options for curl_setopt() + * @param string $http_method 'GET', 'POST', or 'DELETE' + * @param string $url + * @param array $command The Command object, modelled as a hash. + * @param array $extra_opts key => value pairs of curl options for curl_setopt() * @return array + * @throws Exception */ protected static function curl( $http_method, $url, - $command, - $extra_opts = array()) { + array $command, + array $extra_opts = array()) { $params = $command['parameters']; From d9c5dbf3637524de574b424b529a986d19f91f02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=9A=D0=BE=D0=BB?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Wed, 21 May 2014 11:17:39 +0400 Subject: [PATCH 045/784] Fix phpdoc comments for RemoteKeyboard. --- lib/remote/RemoteKeyboard.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/remote/RemoteKeyboard.php b/lib/remote/RemoteKeyboard.php index 27708163c..9aa204c27 100644 --- a/lib/remote/RemoteKeyboard.php +++ b/lib/remote/RemoteKeyboard.php @@ -18,9 +18,15 @@ */ class RemoteKeyboard implements WebDriverKeyboard { + /** + * @var WebDriverCommandExecutor + */ private $executor; - public function __construct($executor) { + /** + * @param WebDriverCommandExecutor $executor + */ + public function __construct(WebDriverCommandExecutor $executor) { $this->executor = $executor; } From e9f34e350fecb33a397a5f9dd8f95463915a7a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=9A=D0=BE=D0=BB?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Wed, 21 May 2014 11:21:04 +0400 Subject: [PATCH 046/784] Fix phpdoc comments for RemoteMouse. --- lib/remote/RemoteMouse.php | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/lib/remote/RemoteMouse.php b/lib/remote/RemoteMouse.php index 38d6ee695..faa560a5f 100644 --- a/lib/remote/RemoteMouse.php +++ b/lib/remote/RemoteMouse.php @@ -18,14 +18,22 @@ */ class RemoteMouse implements WebDriverMouse { + /** + * @var WebDriverCommandExecutor + */ private $executor; - public function __construct($executor) { - $this->executor = $executor; + /** + * @param WebDriverCommandExecutor $executor + */ + public function __construct(WebDriverCommandExecutor $executor) { + $this->executor = $executor; } /** - * @return WebDriverMouse + * @param WebDriverCoordinates $where + * + * @return RemoteMouse */ public function click(WebDriverCoordinates $where = null) { $this->moveIfNeeded($where); @@ -36,7 +44,9 @@ public function click(WebDriverCoordinates $where = null) { } /** - * @return WebDriverMouse + * @param WebDriverCoordinates $where + * + * @return RemoteMouse */ public function contextClick(WebDriverCoordinates $where = null) { $this->moveIfNeeded($where); @@ -47,7 +57,9 @@ public function contextClick(WebDriverCoordinates $where = null) { } /** - * @return WebDriverMouse + * @param WebDriverCoordinates $where + * + * @return RemoteMouse */ public function doubleClick(WebDriverCoordinates $where = null) { $this->moveIfNeeded($where); @@ -56,7 +68,9 @@ public function doubleClick(WebDriverCoordinates $where = null) { } /** - * @return WebDriverMouse + * @param WebDriverCoordinates $where + * + * @return RemoteMouse */ public function mouseDown(WebDriverCoordinates $where = null) { $this->moveIfNeeded($where); @@ -65,7 +79,11 @@ public function mouseDown(WebDriverCoordinates $where = null) { } /** - * @return WebDriverMouse + * @param WebDriverCoordinates $where + * @param int|null $x_offset + * @param int|null $y_offset + * + * @return RemoteMouse */ public function mouseMove(WebDriverCoordinates $where = null, $x_offset = null, @@ -85,7 +103,9 @@ public function mouseMove(WebDriverCoordinates $where = null, } /** - * @return WebDriverMouse + * @param WebDriverCoordinates $where + * + * @return RemoteMouse */ public function mouseUp(WebDriverCoordinates $where = null) { $this->moveIfNeeded($where); @@ -94,7 +114,7 @@ public function mouseUp(WebDriverCoordinates $where = null) { } /** - * @return void + * @param WebDriverCoordinates $where */ protected function moveIfNeeded(WebDriverCoordinates $where = null) { if ($where) { From 9d2ad574a4999e8a38d845ea9f24443627443261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=9A=D0=BE=D0=BB?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Wed, 21 May 2014 11:23:39 +0400 Subject: [PATCH 047/784] Fix phpdoc comments for RemoteTouchScreen. --- lib/remote/RemoteTouchScreen.php | 40 ++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/lib/remote/RemoteTouchScreen.php b/lib/remote/RemoteTouchScreen.php index fb99f01c8..382d5a383 100644 --- a/lib/remote/RemoteTouchScreen.php +++ b/lib/remote/RemoteTouchScreen.php @@ -18,13 +18,21 @@ */ class RemoteTouchScreen implements WebDriverTouchScreen { + /** + * @var WebDriverCommandExecutor + */ private $executor; - public function __construct($executor) { - $this->executor = $executor; + /** + * @param WebDriverCommandExecutor $executor + */ + public function __construct(WebDriverCommandExecutor $executor) { + $this->executor = $executor; } /** + * @param WebDriverElement $element + * * @return RemoteTouchScreen The instance. */ public function tap(WebDriverElement $element) { @@ -34,6 +42,8 @@ public function tap(WebDriverElement $element) { } /** + * @param WebDriverElement $element + * * @return RemoteTouchScreen The instance. */ public function doubleTap(WebDriverElement $element) { @@ -46,6 +56,9 @@ public function doubleTap(WebDriverElement $element) { } /** + * @param int $x + * @param int $y + * * @return RemoteTouchScreen The instance. */ public function down($x, $y) { @@ -59,6 +72,9 @@ public function down($x, $y) { /** + * @param int $xspeed + * @param int $yspeed + * * @return RemoteTouchScreen The instance. */ public function flick($xspeed, $yspeed) { @@ -71,6 +87,11 @@ public function flick($xspeed, $yspeed) { } /** + * @param WebDriverElement $element + * @param int $xoffset + * @param int $yoffset + * @param int $speed + * * @return RemoteTouchScreen The instance. */ public function flickFromElement( @@ -87,6 +108,8 @@ public function flickFromElement( } /** + * @param WebDriverElement $element + * * @return RemoteTouchScreen The instance. */ public function longPress(WebDriverElement $element) { @@ -99,6 +122,9 @@ public function longPress(WebDriverElement $element) { } /** + * @param int $x + * @param int $y + * * @return RemoteTouchScreen The instance. */ public function move($x, $y) { @@ -111,6 +137,9 @@ public function move($x, $y) { } /** + * @param int $xoffset + * @param int $yoffset + * * @return RemoteTouchScreen The instance. */ public function scroll($xoffset, $yoffset) { @@ -123,6 +152,10 @@ public function scroll($xoffset, $yoffset) { } /** + * @param WebDriverElement $element + * @param int $xoffset + * @param int $yoffset + * * @return RemoteTouchScreen The instance. */ public function scrollFromElement( @@ -139,6 +172,9 @@ public function scrollFromElement( /** + * @param int $x + * @param int $y + * * @return RemoteTouchScreen The instance. */ public function up($x, $y) { From d67051bee3fbb36e407d5177c1014153635cef83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=9A=D0=BE=D0=BB?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Wed, 21 May 2014 11:28:57 +0400 Subject: [PATCH 048/784] Fix phpdoc comments for RemoteWebElement. --- lib/remote/RemoteWebElement.php | 38 +++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/lib/remote/RemoteWebElement.php b/lib/remote/RemoteWebElement.php index f7998f280..d39cfc509 100644 --- a/lib/remote/RemoteWebElement.php +++ b/lib/remote/RemoteWebElement.php @@ -18,10 +18,23 @@ */ class RemoteWebElement implements WebDriverElement, WebDriverLocatable { + /** + * @var HttpCommandExecutor + */ protected $executor; + /** + * @var string + */ protected $id; + /** + * @var UselessFileDetector + */ protected $fileDetector; + /** + * @param HttpCommandExecutor $executor + * @param string $id + */ public function __construct(HttpCommandExecutor $executor, $id) { $this->executor = $executor; $this->id = $id; @@ -32,7 +45,7 @@ public function __construct(HttpCommandExecutor $executor, $id) { * If this element is a TEXTAREA or text INPUT element, this will clear the * value. * - * @return WebDriverElement The current instance. + * @return RemoteWebElement The current instance. */ public function clear() { $this->executor->execute('clear', array(':id' => $this->id)); @@ -42,7 +55,7 @@ public function clear() { /** * Click this element. * - * @return WebDriverElement The current instance. + * @return RemoteWebElement The current instance. */ public function click() { $this->executor->execute('clickElement', array(':id' => $this->id)); @@ -54,7 +67,7 @@ public function click() { * mechanism. * * @param WebDriverBy $by - * @return WebDriverElement NoSuchElementException is thrown in + * @return RemoteWebElement NoSuchElementException is thrown in * HttpCommandExecutor if no element is found. * @see WebDriverBy */ @@ -73,7 +86,7 @@ public function findElement(WebDriverBy $by) { * Find all WebDriverElements within this element using the given mechanism. * * @param WebDriverBy $by - * @return array A list of all WebDriverElements, or an empty array if + * @return RemoteWebElement[] A list of all WebDriverElements, or an empty array if * nothing matches * @see WebDriverBy */ @@ -123,7 +136,7 @@ public function getCSSValue($css_property_name) { /** * Get the location of element relative to the top-left corner of the page. * - * @return WebDriverLocation The location of the element. + * @return WebDriverPoint The location of the element. */ public function getLocation() { $location = $this->executor->execute( @@ -137,7 +150,7 @@ public function getLocation() { * Try scrolling the element into the view port and return the location of * element relative to the top-left corner of the page afterwards. * - * @return WebDriverLocation The location of the element. + * @return WebDriverPoint The location of the element. */ public function getLocationOnScreenOnceScrolledIntoView() { $location = $this->executor->execute( @@ -250,7 +263,7 @@ public function isSelected() { * Simulate typing into an element, which may set its value. * * @param mixed $value The data to be typed. - * @return WebDriverElement The current instance. + * @return RemoteWebElement The current instance. */ public function sendKeys($value) { $local_file = $this->fileDetector->getLocalFile($value); @@ -274,6 +287,9 @@ public function sendKeys($value) { /** * Upload a local file to the server * + * @param string $local_file + * + * @throws WebDriverException * @return string The remote path of the file. */ private function upload($local_file) { @@ -308,6 +324,8 @@ private function upload($local_file) { * * eg. $element->setFileDetector(new LocalFileDetector); * + * @param FileDetector $detector + * @return RemoteWebElement * @see FileDetector * @see LocalFileDetector * @see UselessFileDetector @@ -321,7 +339,7 @@ public function setFileDetector(FileDetector $detector) { * If this current element is a form, or an element within a form, then this * will be submitted to the remote server. * - * @return WebDriverElement The current instance. + * @return RemoteWebElement The current instance. */ public function submit() { $this->executor->execute('submitElement', array(':id' => $this->id)); @@ -354,7 +372,9 @@ public function equals(WebDriverElement $other) { /** * Return the WebDriverElement with $id * - * @return WebDriverElement + * @param string $id + * + * @return RemoteWebElement */ private function newElement($id) { return new RemoteWebElement($this->executor, $id); From 2fddfd9cc7c27130686eb1fb1d325e00447920c8 Mon Sep 17 00:00:00 2001 From: whhone Date: Tue, 20 May 2014 12:38:55 -0700 Subject: [PATCH 049/784] ChromeOptions - setBinary, addExtensions --- lib/__init__.php | 1 + lib/chrome/ChromeOptions.php | 102 +++++++++++++++++++++++++++++ lib/remote/DesiredCapabilities.php | 7 +- 3 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 lib/chrome/ChromeOptions.php diff --git a/lib/__init__.php b/lib/__init__.php index 41a32bb4c..d11df33a7 100755 --- a/lib/__init__.php +++ b/lib/__init__.php @@ -59,6 +59,7 @@ require_once('interactions/internal/WebDriverMouseMoveAction.php'); require_once('interactions/internal/WebDriverMoveToOffsetAction.php'); require_once('internal/WebDriverLocatable.php'); +require_once('chrome/ChromeOptions.php'); require_once('remote/LocalFileDetector.php'); require_once('remote/UselessFileDetector.php'); require_once('remote/RemoteMouse.php'); diff --git a/lib/chrome/ChromeOptions.php b/lib/chrome/ChromeOptions.php new file mode 100644 index 000000000..e17eeca58 --- /dev/null +++ b/lib/chrome/ChromeOptions.php @@ -0,0 +1,102 @@ +binary = $path; + return $this; + } + + /** + * Add a Chrome extension to install on browser startup. Each path should be a + * packed Chrome extension. + */ + public function addExtensions(array $paths) { + foreach ($paths as $path) { + $this->addExtension($path); + } + return $this; + } + + /** + * @param array encoded_extensions An array of base64 encoded of the + * extensions. + */ + public function addEncodedExtensions(array $encoded_extensions) { + foreach ($encoded_extensions as $encoded_extension) { + $this->addEncodedExtension($encoded_extension); + } + return $this; + } + + /** + * @return DesiredCapabilities The DesiredCapabilities for Chrome with this + * options. + */ + public function toCapabilities() { + $capabilities = DesiredCapabilities::chrome(); + $capabilities->setCapability(self::CAPABILITY, $this); + return $capabilities; + } + + public function toArray() { + $options = array(); + + if ($this->binary) { + $options['binary'] = $this->binary; + } + + if ($this->extensions) { + $options['extensions'] = $this->extensions; + } + + return $options; + } + + /** + * Add a Chrome extension to install on browser startup. Each path should be a + * packed Chrome extension. + */ + private function addExtension($path) { + $this->addEncodedExtension(base64_encode(file_get_contents($path))); + return $this; + } + + /** + * @param string encoded_extension Base64 encoded of the extension. + */ + private function addEncodedExtension($encoded_extension) { + $this->extension[] = $encoded_extension; + return $this; + } +} diff --git a/lib/remote/DesiredCapabilities.php b/lib/remote/DesiredCapabilities.php index 08035c3b5..acdc683e6 100644 --- a/lib/remote/DesiredCapabilities.php +++ b/lib/remote/DesiredCapabilities.php @@ -69,7 +69,6 @@ public function setPlatform($platform) { return $this; } - /** * @return bool Whether the value is not null and not false. */ @@ -90,6 +89,12 @@ public function setJavascriptEnabled($enabled) { } public function toArray() { + if (isset($this->capabilities[ChromeOptions::CAPABILITY]) && + $this->capabilities[ChromeOptions::CAPABILITY] instanceof ChromeOptions) { + $this->capabilities[ChromeOptions::CAPABILITY] = + $this->capabilities[ChromeOptions::CAPABILITY]->toArray(); + } + return $this->capabilities; } From f2f93d16802c884a673db4a41aa5fc5dc012f1d3 Mon Sep 17 00:00:00 2001 From: whhone Date: Wed, 21 May 2014 15:24:37 -0700 Subject: [PATCH 050/784] typo extension vs extensions --- lib/chrome/ChromeOptions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/chrome/ChromeOptions.php b/lib/chrome/ChromeOptions.php index e17eeca58..e453a75f0 100644 --- a/lib/chrome/ChromeOptions.php +++ b/lib/chrome/ChromeOptions.php @@ -96,7 +96,7 @@ private function addExtension($path) { * @param string encoded_extension Base64 encoded of the extension. */ private function addEncodedExtension($encoded_extension) { - $this->extension[] = $encoded_extension; + $this->extensions[] = $encoded_extension; return $this; } } From 8ea8fc69380093faa1db1283244f49a546409e52 Mon Sep 17 00:00:00 2001 From: whhone Date: Wed, 21 May 2014 15:32:55 -0700 Subject: [PATCH 051/784] phpdoc for ChromeOptions --- lib/chrome/ChromeOptions.php | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/lib/chrome/ChromeOptions.php b/lib/chrome/ChromeOptions.php index e453a75f0..73ef5fca8 100644 --- a/lib/chrome/ChromeOptions.php +++ b/lib/chrome/ChromeOptions.php @@ -25,12 +25,22 @@ class ChromeOptions { */ const CAPABILITY = "chromeOptions"; - private $binary = null; + /** + * @var string + */ + private $binary = ''; + + /** + * @var array + */ private $extensions = array(); /** * Sets the path of the Chrome executable. The path should be either absolute * or relative to the location running ChromeDriver server. + * + * @param string $path + * @return ChromeOptions */ public function setBinary($path) { $this->binary = $path; @@ -38,8 +48,11 @@ public function setBinary($path) { } /** - * Add a Chrome extension to install on browser startup. Each path should be a - * packed Chrome extension. + * Add a Chrome extension to install on browser startup. Each path should be + * a packed Chrome extension. + * + * @param array $paths + * @return ChromeOptions */ public function addExtensions(array $paths) { foreach ($paths as $path) { @@ -49,8 +62,8 @@ public function addExtensions(array $paths) { } /** - * @param array encoded_extensions An array of base64 encoded of the - * extensions. + * @param array $encoded_extensions An array of base64 encoded of the + * extensions. */ public function addEncodedExtensions(array $encoded_extensions) { foreach ($encoded_extensions as $encoded_extension) { @@ -69,6 +82,9 @@ public function toCapabilities() { return $capabilities; } + /** + * @return array + */ public function toArray() { $options = array(); @@ -86,6 +102,9 @@ public function toArray() { /** * Add a Chrome extension to install on browser startup. Each path should be a * packed Chrome extension. + * + * @param string $path + * @return ChromeOptions */ private function addExtension($path) { $this->addEncodedExtension(base64_encode(file_get_contents($path))); @@ -93,7 +112,8 @@ private function addExtension($path) { } /** - * @param string encoded_extension Base64 encoded of the extension. + * @param string $encoded_extension Base64 encoded of the extension. + * @return ChromeOptions */ private function addEncodedExtension($encoded_extension) { $this->extensions[] = $encoded_extension; From ff9269eab1a878e4deefdfcab67aa1447d4659e1 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Wed, 21 May 2014 15:38:25 -0700 Subject: [PATCH 052/784] allow empty chrome options --- lib/chrome/ChromeOptions.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/chrome/ChromeOptions.php b/lib/chrome/ChromeOptions.php index 73ef5fca8..5c1788ef3 100644 --- a/lib/chrome/ChromeOptions.php +++ b/lib/chrome/ChromeOptions.php @@ -88,9 +88,7 @@ public function toCapabilities() { public function toArray() { $options = array(); - if ($this->binary) { - $options['binary'] = $this->binary; - } + $options['binary'] = $this->binary; if ($this->extensions) { $options['extensions'] = $this->extensions; From 27be74080b07712c4f3a9e2840cfabf3be2beaec Mon Sep 17 00:00:00 2001 From: whhone Date: Thu, 22 May 2014 19:15:25 -0700 Subject: [PATCH 053/784] ChromeOptions: setExperimentalOptions, addArguments Start Chrome with arguments. Example, ``` $options = new ChromeOptions(); $options->addArguments(array('--window-size=300,900')); $caps = DesiredCapabilities::chrome(); $caps->setCapability(ChromeOptions::CAPABILITY, $options); $driver = RemoteWebDriver::create($url, $caps); ``` --- lib/chrome/ChromeOptions.php | 38 +++++++++++++++++++- lib/remote/DesiredCapabilities.php | 57 ++++++++++++++++++++++++++++++ lib/remote/RemoteMouse.php | 1 + 3 files changed, 95 insertions(+), 1 deletion(-) diff --git a/lib/chrome/ChromeOptions.php b/lib/chrome/ChromeOptions.php index 5c1788ef3..89939b1e2 100644 --- a/lib/chrome/ChromeOptions.php +++ b/lib/chrome/ChromeOptions.php @@ -25,6 +25,11 @@ class ChromeOptions { */ const CAPABILITY = "chromeOptions"; + /** + * @var array + */ + private $arguments = array(); + /** * @var string */ @@ -35,6 +40,11 @@ class ChromeOptions { */ private $extensions = array(); + /** + * @var array + */ + private $experimentalOptions = array(); + /** * Sets the path of the Chrome executable. The path should be either absolute * or relative to the location running ChromeDriver server. @@ -47,6 +57,15 @@ public function setBinary($path) { return $this; } + /** + * @param array $args + * @return ChromeOptions + */ + public function addArguments(array $arguments) { + $this->arguments = array_merge($this->arguments, $arguments); + return $this; + } + /** * Add a Chrome extension to install on browser startup. Each path should be * a packed Chrome extension. @@ -64,6 +83,7 @@ public function addExtensions(array $paths) { /** * @param array $encoded_extensions An array of base64 encoded of the * extensions. + * @return ChromeOptions */ public function addEncodedExtensions(array $encoded_extensions) { foreach ($encoded_extensions as $encoded_extension) { @@ -72,6 +92,18 @@ public function addEncodedExtensions(array $encoded_extensions) { return $this; } + /** + * Sets an experimental option which has not exposed officially. + * + * @param string $name + * @parma mixed $value + * @return ChromeOptions + */ + public function setExperimentalOption($name, $value) { + $this->experimentalOptions[$name] = $value; + return $this; + } + /** * @return DesiredCapabilities The DesiredCapabilities for Chrome with this * options. @@ -86,10 +118,14 @@ public function toCapabilities() { * @return array */ public function toArray() { - $options = array(); + $options = $this->experimentOptions; $options['binary'] = $this->binary; + if ($this->arguments) { + $options['args'] = $this->arguments; + } + if ($this->extensions) { $options['extensions'] = $this->extensions; } diff --git a/lib/remote/DesiredCapabilities.php b/lib/remote/DesiredCapabilities.php index acdc683e6..844deb1d5 100644 --- a/lib/remote/DesiredCapabilities.php +++ b/lib/remote/DesiredCapabilities.php @@ -28,6 +28,9 @@ public function getBrowserName() { return $this->get(WebDriverCapabilityType::BROWSER_NAME, ''); } + /** + * @return DesiredCapabilities + */ public function setBrowserName($browser_name) { $this->set(WebDriverCapabilityType::BROWSER_NAME, $browser_name); return $this; @@ -40,6 +43,9 @@ public function getVersion() { return $this->get(WebDriverCapabilityType::VERSION, ''); } + /** + * @return DesiredCapabilities + */ public function setVersion($version) { $this->set(WebDriverCapabilityType::VERSION, $version); return $this; @@ -52,6 +58,9 @@ public function getCapability($name) { $this->get($name); } + /** + * @return DesiredCapabilities + */ public function setCapability($name, $value) { $this->set($name, $value); return $this; @@ -64,6 +73,9 @@ public function getPlatform() { return $this->get(WebDriverCapabilityType::PLATFORM, ''); } + /** + * @return DesiredCapabilities + */ public function setPlatform($platform) { $this->set(WebDriverCapabilityType::PLATFORM, $platform); return $this; @@ -83,11 +95,17 @@ public function isJavascriptEnabled() { return $this->get(WebDriverCapabilityType::JAVASCRIPT_ENABLED, false); } + /** + * @return DesiredCapabilities + */ public function setJavascriptEnabled($enabled) { $this->set(WebDriverCapabilityType::JAVASCRIPT_ENABLED, $enabled); return $this; } + /** + * @return array + */ public function toArray() { if (isset($this->capabilities[ChromeOptions::CAPABILITY]) && $this->capabilities[ChromeOptions::CAPABILITY] instanceof ChromeOptions) { @@ -98,17 +116,26 @@ public function toArray() { return $this->capabilities; } + /** + * @return DesiredCapabilities + */ private function set($key, $value) { $this->capabilities[$key] = $value; return $this; } + /** + * @return mixed + */ private function get($key, $default = null) { return isset($this->capabilities[$key]) ? $this->capabilities[$key] : $default; } + /** + * @return DesiredCapabilities + */ public static function android() { return new DesiredCapabilities(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::ANDROID, @@ -116,6 +143,9 @@ public static function android() { )); } + /** + * @return DesiredCapabilities + */ public static function chrome() { return new DesiredCapabilities(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::CHROME, @@ -123,6 +153,9 @@ public static function chrome() { )); } + /** + * @return DesiredCapabilities + */ public static function firefox() { return new DesiredCapabilities(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::FIREFOX, @@ -130,6 +163,9 @@ public static function firefox() { )); } + /** + * @return DesiredCapabilities + */ public static function htmlUnit() { return new DesiredCapabilities(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::HTMLUNIT, @@ -137,6 +173,9 @@ public static function htmlUnit() { )); } + /** + * @return DesiredCapabilities + */ public static function htmlUnitWithJS() { $caps = new DesiredCapabilities(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::HTMLUNIT, @@ -145,6 +184,9 @@ public static function htmlUnitWithJS() { return $caps->setJavascriptEnabled(true); } + /** + * @return DesiredCapabilities + */ public static function internetExplorer() { return new DesiredCapabilities(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::IE, @@ -152,6 +194,9 @@ public static function internetExplorer() { )); } + /** + * @return DesiredCapabilities + */ public static function iphone() { return new DesiredCapabilities(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::IPHONE, @@ -159,6 +204,9 @@ public static function iphone() { )); } + /** + * @return DesiredCapabilities + */ public static function ipad() { return new DesiredCapabilities(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::IPAD, @@ -166,6 +214,9 @@ public static function ipad() { )); } + /** + * @return DesiredCapabilities + */ public static function opera() { return new DesiredCapabilities(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::OPERA, @@ -173,6 +224,9 @@ public static function opera() { )); } + /** + * @return DesiredCapabilities + */ public static function safari() { return new DesiredCapabilities(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::SAFARI, @@ -180,6 +234,9 @@ public static function safari() { )); } + /** + * @return DesiredCapabilities + */ public static function phantomjs() { return new DesiredCapabilities(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::PHANTOMJS, diff --git a/lib/remote/RemoteMouse.php b/lib/remote/RemoteMouse.php index 099b71f89..00ead06fa 100644 --- a/lib/remote/RemoteMouse.php +++ b/lib/remote/RemoteMouse.php @@ -115,6 +115,7 @@ public function mouseUp(WebDriverCoordinates $where = null) { /** * @param WebDriverCoordinates $where + * @return void */ protected function moveIfNeeded(WebDriverCoordinates $where = null) { if ($where) { From 773333dd1f4a6afd025ae86fa0d030a2e4f56fc5 Mon Sep 17 00:00:00 2001 From: whhone Date: Fri, 23 May 2014 11:01:07 -0700 Subject: [PATCH 054/784] DriverCommand --- lib/WebDriverAlert.php | 11 +- lib/WebDriverNavigation.php | 8 +- lib/WebDriverOptions.php | 18 ++- lib/WebDriverTargetLocator.php | 6 +- lib/WebDriverTimeouts.php | 6 +- lib/WebDriverWindow.php | 14 +-- lib/__init__.php | 1 + lib/remote/DriverCommand.php | 169 +++++++++++++++++++++++++++++ lib/remote/HttpCommandExecutor.php | 151 +++++++++++++------------- lib/remote/RemoteKeyboard.php | 6 +- lib/remote/RemoteMouse.php | 12 +- lib/remote/RemoteTouchScreen.php | 23 ++-- lib/remote/RemoteWebDriver.php | 42 ++++--- lib/remote/RemoteWebElement.php | 62 +++++++---- 14 files changed, 373 insertions(+), 156 deletions(-) create mode 100644 lib/remote/DriverCommand.php diff --git a/lib/WebDriverAlert.php b/lib/WebDriverAlert.php index 23b1285a8..aa731402d 100644 --- a/lib/WebDriverAlert.php +++ b/lib/WebDriverAlert.php @@ -30,7 +30,7 @@ public function __construct($executor) { * @return WebDriverAlert The instance. */ public function accept() { - $this->executor->execute('acceptAlert'); + $this->executor->execute(DriverCommand::ACCEPT_ALERT); return $this; } @@ -40,7 +40,7 @@ public function accept() { * @return WebDriverAlert The instance. */ public function dismiss() { - $this->executor->execute('dismissAlert'); + $this->executor->execute(DriverCommand::DISMISS_ALERT); return $this; } @@ -50,7 +50,7 @@ public function dismiss() { * @return string */ public function getText() { - return $this->executor->execute('getAlertText'); + return $this->executor->execute(DriverCommand::GET_ALERT_TEXT); } /** @@ -59,7 +59,10 @@ public function getText() { * @return WebDriverAlert */ public function sendKeys($value) { - $this->executor->execute('sendKeysToAlert', array('text' => $value)); + $this->executor->execute( + DriverCommand::SET_ALERT_VALUE, + array('text' => $value) + ); return $this; } diff --git a/lib/WebDriverNavigation.php b/lib/WebDriverNavigation.php index 551a49bed..6f3a2bb31 100644 --- a/lib/WebDriverNavigation.php +++ b/lib/WebDriverNavigation.php @@ -36,7 +36,7 @@ public function __construct(WebDriverCommandExecutor $executor) { * @return WebDriverNavigation The instance. */ public function back() { - $this->executor->execute('goBack'); + $this->executor->execute(DriverCommand::GO_BACK); return $this; } @@ -46,7 +46,7 @@ public function back() { * @return WebDriverNavigation The instance. */ public function forward() { - $this->executor->execute('goForward'); + $this->executor->execute(DriverCommand::GO_FORWARD); return $this; } @@ -56,7 +56,7 @@ public function forward() { * @return WebDriverNavigation The instance. */ public function refresh() { - $this->executor->execute('refreshPage'); + $this->executor->execute(DriverCommand::REFRESH); return $this; } @@ -67,7 +67,7 @@ public function refresh() { */ public function to($url) { $params = array('url' => (string)$url); - $this->executor->execute('get', $params); + $this->executor->execute(DriverCommand::GET, $params); return $this; } } diff --git a/lib/WebDriverOptions.php b/lib/WebDriverOptions.php index f6838897f..98dcb0a63 100644 --- a/lib/WebDriverOptions.php +++ b/lib/WebDriverOptions.php @@ -45,7 +45,10 @@ public function __construct(WebDriverCommandExecutor $executor) { */ public function addCookie(array $cookie) { $this->validate($cookie); - $this->executor->execute('addCookie', array('cookie' => $cookie)); + $this->executor->execute( + DriverCommand::ADD_COOKIE, + array('cookie' => $cookie) + ); return $this; } @@ -55,7 +58,7 @@ public function addCookie(array $cookie) { * @return WebDriverOptions The current instance. */ public function deleteAllCookies() { - $this->executor->execute('deleteAllCookies'); + $this->executor->execute(DriverCommand::DELETE_ALL_COOKIES); return $this; } @@ -65,7 +68,10 @@ public function deleteAllCookies() { * @return WebDriverOptions The current instance. */ public function deleteCookieNamed($name) { - $this->executor->execute('deleteCookie', array(':name' => $name)); + $this->executor->execute( + DriverCommand::DELETE_COOKIE, + array(':name' => $name) + ); return $this; } @@ -91,7 +97,7 @@ public function getCookieNamed($name) { * @return array The array of cookies presented. */ public function getCookies() { - return $this->executor->execute('getAllCookies'); + return $this->executor->execute(DriverCommand::GET_ALL_COOKIES); } private function validate(array $cookie) { @@ -141,7 +147,7 @@ public function window() { */ public function getLog($log_type) { return $this->executor->execute( - 'getLog', + DriverCommand::GET_LOG, array('type' => $log_type) ); } @@ -153,7 +159,7 @@ public function getLog($log_type) { * @see https://code.google.com/p/selenium/wiki/JsonWireProtocol#Log_Type */ public function getAvailableLogTypes() { - return $this->executor->execute('getAvailableLogTypes'); + return $this->executor->execute(DriverCommand::GET_AVAILABLE_LOG_TYPES); } } diff --git a/lib/WebDriverTargetLocator.php b/lib/WebDriverTargetLocator.php index 2e937991c..e330b151d 100644 --- a/lib/WebDriverTargetLocator.php +++ b/lib/WebDriverTargetLocator.php @@ -33,7 +33,7 @@ public function __construct($executor, $driver) { * @return WebDriver The driver focused on the top window or the first frame. */ public function defaultContent() { - $this->executor->execute('focusFrame', array()); + $this->executor->execute(DriverCommand::SWITCH_TO_FRAME, array()); return $this->driver; } @@ -53,7 +53,7 @@ public function frame($frame) { } $params = array('id' => $id); - $this->executor->execute('focusFrame', $params); + $this->executor->execute(DriverCommand::SWITCH_TO_FRAME, $params); return $this->driver; } @@ -67,7 +67,7 @@ public function frame($frame) { */ public function window($handle) { $params = array('name' => (string)$handle); - $this->executor->execute('focusWindow', $params); + $this->executor->execute(DriverCommand::SWITCH_TO_WINDOW, $params); return $this->driver; } diff --git a/lib/WebDriverTimeouts.php b/lib/WebDriverTimeouts.php index b86c5f4d5..885c5f190 100644 --- a/lib/WebDriverTimeouts.php +++ b/lib/WebDriverTimeouts.php @@ -33,7 +33,7 @@ public function __construct($executor) { */ public function implicitlyWait($seconds) { $this->executor->execute( - 'setImplicitWaitTimeout', + DriverCommand::IMPLICITLY_WAIT, array('ms' => $seconds * 1000) ); return $this; @@ -48,7 +48,7 @@ public function implicitlyWait($seconds) { */ public function setScriptTimeout($seconds) { $this->executor->execute( - 'setScriptTimeout', + DriverCommand::SET_SCRIPT_TIMEOUT, array('ms' => $seconds * 1000) ); return $this; @@ -62,7 +62,7 @@ public function setScriptTimeout($seconds) { * @return WebDriverTimeouts The current instance. */ public function pageLoadTimeout($seconds) { - $this->executor->execute('setPageLoadTimeout', array( + $this->executor->execute(DriverCommand::SET_TIMEOUT, array( 'type' => 'page load', 'ms' => $seconds * 1000, )); diff --git a/lib/WebDriverWindow.php b/lib/WebDriverWindow.php index 2cdca091e..e0b940042 100644 --- a/lib/WebDriverWindow.php +++ b/lib/WebDriverWindow.php @@ -32,7 +32,7 @@ public function __construct($executor) { */ public function getPosition() { $position = $this->executor->execute( - 'getWindowPosition', + DriverCommand::GET_WINDOW_POSITION, array(':windowHandle' => 'current') ); return new WebDriverPoint( @@ -49,7 +49,7 @@ public function getPosition() { */ public function getSize() { $size = $this->executor->execute( - 'getWindowSize', + DriverCommand::GET_WINDOW_SIZE, array(':windowHandle' => 'current') ); return new WebDriverDimension( @@ -65,7 +65,7 @@ public function getSize() { */ public function maximize() { $this->executor->execute( - 'maximizeWindow', + DriverCommand::MAXIMIZE_WINDOW, array(':windowHandle' => 'current') ); return $this; @@ -85,7 +85,7 @@ public function setSize(WebDriverDimension $size) { 'height' => $size->getHeight(), ':windowHandle' => 'current', ); - $this->executor->execute('setWindowSize', $params); + $this->executor->execute(DriverCommand::SET_WINDOW_SIZE, $params); return $this; } @@ -103,7 +103,7 @@ public function setPosition(WebDriverPoint $position) { 'y' => $position->getY(), ':windowHandle' => 'current', ); - $this->executor->execute('setWindowPosition', $params); + $this->executor->execute(DriverCommand::SET_WINDOW_POSITION, $params); return $this; } @@ -113,7 +113,7 @@ public function setPosition(WebDriverPoint $position) { * @return string Either LANDSCAPE|PORTRAIT */ public function getScreenOrientation() { - return $this->executor->execute('getScreenOrientation'); + return $this->executor->execute(DriverCommand::GET_SCREEN_ORIENTATION); } @@ -134,7 +134,7 @@ public function setScreenOrientation($orientation) { } $this->executor->execute( - 'setScreenOrientation', + DriverCommand::SET_SCREEN_ORIENTATION, array('orientation' => $orientation) ); diff --git a/lib/__init__.php b/lib/__init__.php index d11df33a7..517aec324 100755 --- a/lib/__init__.php +++ b/lib/__init__.php @@ -60,6 +60,7 @@ require_once('interactions/internal/WebDriverMoveToOffsetAction.php'); require_once('internal/WebDriverLocatable.php'); require_once('chrome/ChromeOptions.php'); +require_once('remote/DriverCommand.php'); require_once('remote/LocalFileDetector.php'); require_once('remote/UselessFileDetector.php'); require_once('remote/RemoteMouse.php'); diff --git a/lib/remote/DriverCommand.php b/lib/remote/DriverCommand.php new file mode 100644 index 000000000..837e5e9de --- /dev/null +++ b/lib/remote/DriverCommand.php @@ -0,0 +1,169 @@ + array('method' => 'POST', 'url' => '/session/:sessionId/accept_alert'), - 'addCookie' => array('method' => 'POST', 'url' => '/session/:sessionId/cookie'), - 'clear' => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/clear'), - 'clickElement' => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/click'), - 'closeCurrentWindow' => array('method' => 'DELETE', 'url' => '/session/:sessionId/window'), - 'deleteAllCookies' => array('method' => 'DELETE', 'url' => '/session/:sessionId/cookie'), - 'deleteCookie' => array('method' => 'DELETE', 'url' => '/session/:sessionId/cookie/:name'), - 'dismissAlert' => array('method' => 'POST', 'url' => '/session/:sessionId/dismiss_alert'), - 'elementEquals' => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/equals/:other'), - 'elementFindElement' => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/element'), - 'elementFindElements' => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/elements'), - 'executeScript' => array('method' => 'POST', 'url' => '/session/:sessionId/execute'), - 'executeAsyncScript' => array('method' => 'POST', 'url' => '/session/:sessionId/execute_async'), - 'findElement' => array('method' => 'POST', 'url' => '/session/:sessionId/element'), - 'findElements' => array('method' => 'POST', 'url' => '/session/:sessionId/elements'), - 'focusFrame' => array('method' => 'POST', 'url' => '/session/:sessionId/frame'), - 'focusWindow' => array('method' => 'POST', 'url' => '/session/:sessionId/window'), - 'get' => array('method' => 'POST', 'url' => '/session/:sessionId/url'), - 'getActiveElement' => array('method' => 'POST', 'url' => '/session/:sessionId/element/active'), - 'getAlertText' => array('method' => 'GET', 'url' => '/session/:sessionId/alert_text'), - 'getAllCookies' => array('method' => 'GET', 'url' => '/session/:sessionId/cookie'), - 'getAvailableLogTypes' => array('method' => 'GET', 'url' => '/session/:sessionId/log/types'), - 'getCurrentURL' => array('method' => 'GET', 'url' => '/session/:sessionId/url'), - 'getCurrentWindowHandle' => array('method' => 'GET', 'url' => '/session/:sessionId/window_handle'), - 'getElementAttribute' => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/attribute/:name'), - 'getElementCSSValue' => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/css/:propertyName'), - 'getElementLocation' => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/location'), - 'getElementLocationOnceScrolledIntoView' => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/location_in_view'), - 'getElementSize' => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/size'), - 'getElementTagName' => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/name'), - 'getElementText' => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/text'), - 'getLog' => array('method' => 'POST', 'url' => '/session/:sessionId/log'), - 'getPageSource' => array('method' => 'GET', 'url' => '/session/:sessionId/source'), - 'getScreenOrientation' => array('method' => 'GET', 'url' => '/session/:sessionId/orientation'), - 'getSession' => array('method' => 'GET', 'url' => '/session/:sessionId'), - 'getTitle' => array('method' => 'GET', 'url' => '/session/:sessionId/title'), - 'getWindowHandles' => array('method' => 'GET', 'url' => '/session/:sessionId/window_handles'), - 'getWindowPosition' => array('method' => 'GET', 'url' => '/session/:sessionId/window/:windowHandle/position'), - 'getWindowSize' => array('method' => 'GET', 'url' => '/session/:sessionId/window/:windowHandle/size'), - 'goBack' => array('method' => 'POST', 'url' => '/session/:sessionId/back'), - 'goForward' => array('method' => 'POST', 'url' => '/session/:sessionId/forward'), - 'isElementDisplayed'=> array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/displayed'), - 'isElementEnabled'=> array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/enabled'), - 'isElementSelected'=> array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/selected'), - 'maximizeWindow' => array('method' => 'POST', 'url' => '/session/:sessionId/window/:windowHandle/maximize'), - 'mouseButtonDown' => array('method' => 'POST', 'url' => '/session/:sessionId/buttondown'), - 'mouseButtonUp' => array('method' => 'POST', 'url' => '/session/:sessionId/buttonup'), - 'mouseClick' => array('method' => 'POST', 'url' => '/session/:sessionId/click'), - 'mouseDoubleClick' => array('method' => 'POST', 'url' => '/session/:sessionId/doubleclick'), - 'mouseMoveTo' => array('method' => 'POST', 'url' => '/session/:sessionId/moveto'), - 'newSession' => array('method' => 'POST', 'url' => '/session'), - 'quit' => array('method' => 'DELETE', 'url' => '/session/:sessionId'), - 'refreshPage' => array('method' => 'POST', 'url' => '/session/:sessionId/refresh'), - 'sendFile' => array('method' => 'POST', 'url' => '/session/:sessionId/file'), // undocumented - 'sendKeys' => array('method' => 'POST', 'url' => '/session/:sessionId/keys'), - 'sendKeysToAlert' => array('method' => 'POST', 'url' => '/session/:sessionId/alert_text'), - 'sendKeysToElement' => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/value'), - 'setImplicitWaitTimeout' => array('method' => 'POST', 'url' => '/session/:sessionId/timeouts/implicit_wait'), - 'setScreenOrientation' => array('method' => 'POST', 'url' => '/session/:sessionId/orientation'), - 'setPageLoadTimeout' => array('method' => 'POST', 'url' => '/session/:sessionId/timeouts'), - 'setScriptTimeout' => array('method' => 'POST', 'url' => '/session/:sessionId/timeouts/async_script'), - 'setWindowPosition' => array('method' => 'POST', 'url' => '/session/:sessionId/window/:windowHandle/position'), - 'setWindowSize' => array('method' => 'POST', 'url' => '/session/:sessionId/window/:windowHandle/size'), - 'submitElement' => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/submit'), - 'takeScreenshot' => array('method' => 'GET', 'url' => '/session/:sessionId/screenshot'), - 'touchTap' => array('method' => 'POST', 'url' => '/session/:sessionId/touch/click'), - 'touchDown' => array('method' => 'POST', 'url' => '/session/:sessionId/touch/down'), - 'touchDoubleTap' => array('method' => 'POST', 'url' => '/session/:sessionId/touch/doubleclick'), - 'touchFlick' => array('method' => 'POST', 'url' => '/session/:sessionId/touch/flick'), - 'touchLongPress' => array('method' => 'POST', 'url' => '/session/:sessionId/touch/longclick'), - 'touchMove' => array('method' => 'POST', 'url' => '/session/:sessionId/touch/move'), - 'touchScroll' => array('method' => 'POST', 'url' => '/session/:sessionId/touch/scroll'), - 'touchUp' => array('method' => 'POST', 'url' => '/session/:sessionId/touch/up'), + DriverCommand::ACCEPT_ALERT => array('method' => 'POST', 'url' => '/session/:sessionId/accept_alert'), + DriverCommand::ADD_COOKIE => array('method' => 'POST', 'url' => '/session/:sessionId/cookie'), + DriverCommand::CLEAR_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/clear'), + DriverCommand::CLICK_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/click'), + DriverCommand::CLOSE => array('method' => 'DELETE', 'url' => '/session/:sessionId/window'), + DriverCommand::DELETE_ALL_COOKIES => array('method' => 'DELETE', 'url' => '/session/:sessionId/cookie'), + DriverCommand::DELETE_COOKIE => array('method' => 'DELETE', 'url' => '/session/:sessionId/cookie/:name'), + DriverCommand::DISMISS_ALERT => array('method' => 'POST', 'url' => '/session/:sessionId/dismiss_alert'), + DriverCommand::ELEMENT_EQUALS => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/equals/:other'), + DriverCommand::FIND_CHILD_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/element'), + DriverCommand::FIND_CHILD_ELEMENTS => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/elements'), + DriverCommand::EXECUTE_SCRIPT => array('method' => 'POST', 'url' => '/session/:sessionId/execute'), + DriverCommand::EXECUTE_ASYNC_SCRIPT => array('method' => 'POST', 'url' => '/session/:sessionId/execute_async'), + DriverCommand::FIND_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element'), + DriverCommand::FIND_ELEMENTS => array('method' => 'POST', 'url' => '/session/:sessionId/elements'), + DriverCommand::SWITCH_TO_FRAME => array('method' => 'POST', 'url' => '/session/:sessionId/frame'), + DriverCommand::SWITCH_TO_WINDOW => array('method' => 'POST', 'url' => '/session/:sessionId/window'), + DriverCommand::GET => array('method' => 'POST', 'url' => '/session/:sessionId/url'), + DriverCommand::GET_ACTIVE_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/active'), + DriverCommand::GET_ALERT_TEXT => array('method' => 'GET', 'url' => '/session/:sessionId/alert_text'), + DriverCommand::GET_ALL_COOKIES => array('method' => 'GET', 'url' => '/session/:sessionId/cookie'), + DriverCommand::GET_AVAILABLE_LOG_TYPES => array('method' => 'GET', 'url' => '/session/:sessionId/log/types'), + DriverCommand::GET_CURRENT_URL => array('method' => 'GET', 'url' => '/session/:sessionId/url'), + DriverCommand::GET_CURRENT_WINDOW_HANDLE => array('method' => 'GET', 'url' => '/session/:sessionId/window_handle'), + DriverCommand::GET_ELEMENT_ATTRIBUTE => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/attribute/:name'), + DriverCommand::GET_ELEMENT_VALUE_OF_CSS_PROPERTY => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/css/:propertyName'), + DriverCommand::GET_ELEMENT_LOCATION => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/location'), + DriverCommand::GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/location_in_view'), + DriverCommand::GET_ELEMENT_SIZE => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/size'), + DriverCommand::GET_ELEMENT_TAG_NAME => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/name'), + DriverCommand::GET_ELEMENT_TEXT => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/text'), + DriverCommand::GET_LOG => array('method' => 'POST', 'url' => '/session/:sessionId/log'), + DriverCommand::GET_PAGE_SOURCE => array('method' => 'GET', 'url' => '/session/:sessionId/source'), + DriverCommand::GET_SCREEN_ORIENTATION => array('method' => 'GET', 'url' => '/session/:sessionId/orientation'), + DriverCommand::GET_CAPABILITIES => array('method' => 'GET', 'url' => '/session/:sessionId'), + DriverCommand::GET_TITLE => array('method' => 'GET', 'url' => '/session/:sessionId/title'), + DriverCommand::GET_WINDOW_HANDLES => array('method' => 'GET', 'url' => '/session/:sessionId/window_handles'), + DriverCommand::GET_WINDOW_POSITION => array('method' => 'GET', 'url' => '/session/:sessionId/window/:windowHandle/position'), + DriverCommand::GET_WINDOW_SIZE => array('method' => 'GET', 'url' => '/session/:sessionId/window/:windowHandle/size'), + DriverCommand::GO_BACK => array('method' => 'POST', 'url' => '/session/:sessionId/back'), + DriverCommand::GO_FORWARD => array('method' => 'POST', 'url' => '/session/:sessionId/forward'), + DriverCommand::IS_ELEMENT_DISPLAYED=> array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/displayed'), + DriverCommand::IS_ELEMENT_ENABLED=> array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/enabled'), + DriverCommand::IS_ELEMENT_SELECTED=> array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/selected'), + DriverCommand::MAXIMIZE_WINDOW => array('method' => 'POST', 'url' => '/session/:sessionId/window/:windowHandle/maximize'), + DriverCommand::MOUSE_DOWN => array('method' => 'POST', 'url' => '/session/:sessionId/buttondown'), + DriverCommand::MOUSE_UP => array('method' => 'POST', 'url' => '/session/:sessionId/buttonup'), + DriverCommand::CLICK => array('method' => 'POST', 'url' => '/session/:sessionId/click'), + DriverCommand::DOUBLE_CLICK => array('method' => 'POST', 'url' => '/session/:sessionId/doubleclick'), + DriverCommand::MOVE_TO => array('method' => 'POST', 'url' => '/session/:sessionId/moveto'), + DriverCommand::NEW_SESSION => array('method' => 'POST', 'url' => '/session'), + DriverCommand::QUIT => array('method' => 'DELETE', 'url' => '/session/:sessionId'), + DriverCommand::REFRESH => array('method' => 'POST', 'url' => '/session/:sessionId/refresh'), + DriverCommand::UPLOAD_FILE => array('method' => 'POST', 'url' => '/session/:sessionId/file'), // undocumented + DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/keys'), + DriverCommand::SET_ALERT_VALUE => array('method' => 'POST', 'url' => '/session/:sessionId/alert_text'), + DriverCommand::SEND_KEYS_TO_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/value'), + DriverCommand::IMPLICITLY_WAIT => array('method' => 'POST', 'url' => '/session/:sessionId/timeouts/implicit_wait'), + DriverCommand::SET_SCREEN_ORIENTATION => array('method' => 'POST', 'url' => '/session/:sessionId/orientation'), + DriverCommand::SET_TIMEOUT => array('method' => 'POST', 'url' => '/session/:sessionId/timeouts'), + DriverCommand::SET_SCRIPT_TIMEOUT => array('method' => 'POST', 'url' => '/session/:sessionId/timeouts/async_script'), + DriverCommand::SET_WINDOW_POSITION => array('method' => 'POST', 'url' => '/session/:sessionId/window/:windowHandle/position'), + DriverCommand::SET_WINDOW_SIZE => array('method' => 'POST', 'url' => '/session/:sessionId/window/:windowHandle/size'), + DriverCommand::SUBMIT_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/submit'), + DriverCommand::SCREENSHOT => array('method' => 'GET', 'url' => '/session/:sessionId/screenshot'), + DriverCommand::TOUCH_SINGLE_TAP => array('method' => 'POST', 'url' => '/session/:sessionId/touch/click'), + DriverCommand::TOUCH_DOWN => array('method' => 'POST', 'url' => '/session/:sessionId/touch/down'), + DriverCommand::TOUCH_DOUBLE_TAP => array('method' => 'POST', 'url' => '/session/:sessionId/touch/doubleclick'), + DriverCommand::TOUCH_FLICK => array('method' => 'POST', 'url' => '/session/:sessionId/touch/flick'), + DriverCommand::TOUCH_LONG_PRESS => array('method' => 'POST', 'url' => '/session/:sessionId/touch/longclick'), + DriverCommand::TOUCH_MOVE => array('method' => 'POST', 'url' => '/session/:sessionId/touch/move'), + DriverCommand::TOUCH_SCROLL => array('method' => 'POST', 'url' => '/session/:sessionId/touch/scroll'), + DriverCommand::TOUCH_UP => array('method' => 'POST', 'url' => '/session/:sessionId/touch/up'), ); /** @@ -118,7 +118,7 @@ class HttpCommandExecutor implements WebDriverCommandExecutor { public function __construct($url, $session_id) { $this->url = $url; $this->sessionID = $session_id; - $this->capabilities = $this->execute('getSession', array()); + $this->capabilities = $this->execute(DriverCommand::GET_CAPABILITIES); } /** @@ -165,7 +165,7 @@ public static function remoteExecute( } $raw = self::$commands[$command['name']]; - if ($command['name'] == 'newSession') { + if ($command['name'] == DriverCommand::NEW_SESSION) { $curl_opts[CURLOPT_FOLLOWLOCATION] = true; } @@ -294,5 +294,4 @@ public function getAddressOfRemoteServer() { public function getSessionID() { return $this->sessionID; } - } diff --git a/lib/remote/RemoteKeyboard.php b/lib/remote/RemoteKeyboard.php index 9aa204c27..116020545 100644 --- a/lib/remote/RemoteKeyboard.php +++ b/lib/remote/RemoteKeyboard.php @@ -36,7 +36,7 @@ public function __construct(WebDriverCommandExecutor $executor) { * @return $this */ public function sendKeys($keys) { - $this->executor->execute('sendKeys', array( + $this->executor->execute(DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT, array( 'value' => WebDriverKeys::encode($keys), )); return $this; @@ -50,7 +50,7 @@ public function sendKeys($keys) { * @return $this */ public function pressKey($key) { - $this->executor->execute('sendKeys', array( + $this->executor->execute(DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT, array( 'value' => array((string)$key), )); return $this; @@ -64,7 +64,7 @@ public function pressKey($key) { * @return $this */ public function releaseKey($key) { - $this->executor->execute('sendKeys', array( + $this->executor->execute(DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT, array( 'value' => array((string)$key), )); return $this; diff --git a/lib/remote/RemoteMouse.php b/lib/remote/RemoteMouse.php index 00ead06fa..cb0613e1e 100644 --- a/lib/remote/RemoteMouse.php +++ b/lib/remote/RemoteMouse.php @@ -37,7 +37,7 @@ public function __construct(WebDriverCommandExecutor $executor) { */ public function click(WebDriverCoordinates $where = null) { $this->moveIfNeeded($where); - $this->executor->execute('mouseClick', array( + $this->executor->execute(DriverCommand::CLICK, array( 'button' => 0, )); return $this; @@ -50,7 +50,7 @@ public function click(WebDriverCoordinates $where = null) { */ public function contextClick(WebDriverCoordinates $where = null) { $this->moveIfNeeded($where); - $this->executor->execute('mouseClick', array( + $this->executor->execute(DriverCommand::CLICK, array( 'button' => 2, )); return $this; @@ -63,7 +63,7 @@ public function contextClick(WebDriverCoordinates $where = null) { */ public function doubleClick(WebDriverCoordinates $where = null) { $this->moveIfNeeded($where); - $this->executor->execute('mouseDoubleClick'); + $this->executor->execute(DriverCommand::DOUBLE_CLICK); return $this; } @@ -74,7 +74,7 @@ public function doubleClick(WebDriverCoordinates $where = null) { */ public function mouseDown(WebDriverCoordinates $where = null) { $this->moveIfNeeded($where); - $this->executor->execute('mouseButtonDown'); + $this->executor->execute(DriverCommand::MOUSE_DOWN); return $this; } @@ -98,7 +98,7 @@ public function mouseMove(WebDriverCoordinates $where = null, if ($y_offset !== null) { $params['yoffset'] = $y_offset; } - $this->executor->execute('mouseMoveTo', $params); + $this->executor->execute(DriverCommand::MOVE_TO, $params); return $this; } @@ -109,7 +109,7 @@ public function mouseMove(WebDriverCoordinates $where = null, */ public function mouseUp(WebDriverCoordinates $where = null) { $this->moveIfNeeded($where); - $this->executor->execute('mouseButtonUp'); + $this->executor->execute(DriverCommand::MOUSE_UP); return $this; } diff --git a/lib/remote/RemoteTouchScreen.php b/lib/remote/RemoteTouchScreen.php index 382d5a383..de8dc539d 100644 --- a/lib/remote/RemoteTouchScreen.php +++ b/lib/remote/RemoteTouchScreen.php @@ -36,7 +36,10 @@ public function __construct(WebDriverCommandExecutor $executor) { * @return RemoteTouchScreen The instance. */ public function tap(WebDriverElement $element) { - $this->executor->execute('touchTap', array('element' => $element->getID())); + $this->executor->execute( + DriverCommand::TOUCH_SINGLE_TAP, + array('element' => $element->getID()) + ); return $this; } @@ -48,7 +51,7 @@ public function tap(WebDriverElement $element) { */ public function doubleTap(WebDriverElement $element) { $this->executor->execute( - 'touchDoubleTap', + DriverCommand::TOUCH_DOUBLE_TAP, array('element' => $element->getID()) ); @@ -62,7 +65,7 @@ public function doubleTap(WebDriverElement $element) { * @return RemoteTouchScreen The instance. */ public function down($x, $y) { - $this->executor->execute('touchDown', array( + $this->executor->execute(DriverCommand::TOUCH_DOWN, array( 'x' => $x, 'y' => $y, )); @@ -78,7 +81,7 @@ public function down($x, $y) { * @return RemoteTouchScreen The instance. */ public function flick($xspeed, $yspeed) { - $this->executor->execute('touchFlick', array( + $this->executor->execute(DriverCommand::TOUCH_FLICK, array( 'xspeed' => $xspeed, 'yspeed' => $yspeed, )); @@ -97,7 +100,7 @@ public function flick($xspeed, $yspeed) { public function flickFromElement( WebDriverElement $element, $xoffset, $yoffset, $speed ) { - $this->executor->execute('touchFlick', array( + $this->executor->execute(DriverCommand::TOUCH_FLICK, array( 'xoffset' => $xoffset, 'yoffset' => $yoffset, 'element' => $element->getID(), @@ -114,7 +117,7 @@ public function flickFromElement( */ public function longPress(WebDriverElement $element) { $this->executor->execute( - 'touchLongPress', + DriverCommand::TOUCH_LONG_PRESS, array('element' => $element->getID()) ); @@ -128,7 +131,7 @@ public function longPress(WebDriverElement $element) { * @return RemoteTouchScreen The instance. */ public function move($x, $y) { - $this->executor->execute('touchMove', array( + $this->executor->execute(DriverCommand::TOUCH_MOVE, array( 'x' => $x, 'y' => $y, )); @@ -143,7 +146,7 @@ public function move($x, $y) { * @return RemoteTouchScreen The instance. */ public function scroll($xoffset, $yoffset) { - $this->executor->execute('touchScroll', array( + $this->executor->execute(DriverCommand::TOUCH_SCROLL, array( 'xoffset' => $xoffset, 'yoffset' => $yoffset, )); @@ -161,7 +164,7 @@ public function scroll($xoffset, $yoffset) { public function scrollFromElement( WebDriverElement $element, $xoffset, $yoffset ) { - $this->executor->execute('touchScroll', array( + $this->executor->execute(DriverCommand::TOUCH_SCROLL, array( 'element' => $element->getID(), 'xoffset' => $xoffset, 'yoffset' => $yoffset, @@ -178,7 +181,7 @@ public function scrollFromElement( * @return RemoteTouchScreen The instance. */ public function up($x, $y) { - $this->executor->execute('touchUp', array( + $this->executor->execute(DriverCommand::TOUCH_UP, array( 'x' => $x, 'y' => $y, )); diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index 4fd773fd6..7bec1da87 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -56,7 +56,7 @@ public static function create( $command = array( 'url' => $url, - 'name' => 'newSession', + 'name' => DriverCommand::NEW_SESSION, 'parameters' => array('desiredCapabilities' => $desired_capabilities), ); @@ -121,7 +121,7 @@ public static function remoteExecuteHttpCommand($timeout_in_ms, $command) { * @return RemoteWebDriver The current instance. */ public function close() { - $this->executor->execute('closeCurrentWindow', array()); + $this->executor->execute(DriverCommand::CLOSE, array()); return $this; } @@ -136,7 +136,10 @@ public function close() { */ public function findElement(WebDriverBy $by) { $params = array('using' => $by->getMechanism(), 'value' => $by->getValue()); - $raw_element = $this->executor->execute('findElement', $params); + $raw_element = $this->executor->execute( + DriverCommand::FIND_ELEMENT, + $params + ); return $this->newElement($raw_element['ELEMENT']); } @@ -152,7 +155,10 @@ public function findElement(WebDriverBy $by) { */ public function findElements(WebDriverBy $by) { $params = array('using' => $by->getMechanism(), 'value' => $by->getValue()); - $raw_elements = $this->executor->execute('findElements', $params); + $raw_elements = $this->executor->execute( + DriverCommand::FIND_ELEMENTS, + $params + ); $elements = array(); foreach ($raw_elements as $raw_element) { @@ -170,7 +176,7 @@ public function findElements(WebDriverBy $by) { */ public function get($url) { $params = array('url' => (string)$url); - $this->executor->execute('get', $params); + $this->executor->execute(DriverCommand::GET, $params); return $this; } @@ -181,7 +187,7 @@ public function get($url) { * @return string The current URL. */ public function getCurrentURL() { - return $this->executor->execute('getCurrentURL'); + return $this->executor->execute(DriverCommand::GET_CURRENT_URL); } /** @@ -190,7 +196,7 @@ public function getCurrentURL() { * @return string The current page source. */ public function getPageSource() { - return $this->executor->execute('getPageSource'); + return $this->executor->execute(DriverCommand::GET_PAGE_SOURCE); } /** @@ -199,7 +205,7 @@ public function getPageSource() { * @return string The title of the current page. */ public function getTitle() { - return $this->executor->execute('getTitle'); + return $this->executor->execute(DriverCommand::GET_TITLE); } /** @@ -209,7 +215,10 @@ public function getTitle() { * @return string The current window handle. */ public function getWindowHandle() { - return $this->executor->execute('getCurrentWindowHandle', array()); + return $this->executor->execute( + DriverCommand::GET_CURRENT_WINDOW_HANDLE, + array() + ); } /** @@ -218,7 +227,7 @@ public function getWindowHandle() { * @return array An array of string containing all available window handles. */ public function getWindowHandles() { - return $this->executor->execute('getWindowHandles', array()); + return $this->executor->execute(DriverCommand::GET_WINDOW_HANDLES, array()); } /** @@ -227,7 +236,7 @@ public function getWindowHandles() { * @return void */ public function quit() { - $this->executor->execute('quit'); + $this->executor->execute(DriverCommand::QUIT); $this->executor = null; } @@ -266,7 +275,7 @@ public function executeScript($script, array $arguments = array()) { 'script' => $script, 'args' => $this->prepareScriptArguments($arguments), ); - return $this->executor->execute('executeScript', $params); + return $this->executor->execute(DriverCommand::EXECUTE_SCRIPT, $params); } /** @@ -287,7 +296,10 @@ public function executeAsyncScript($script, array $arguments = array()) { 'script' => $script, 'args' => $this->prepareScriptArguments($arguments), ); - return $this->executor->execute('executeAsyncScript', $params); + return $this->executor->execute( + DriverCommand::EXECUTE_ASYNC_SCRIPT, + $params + ); } /** @@ -298,7 +310,7 @@ public function executeAsyncScript($script, array $arguments = array()) { */ public function takeScreenshot($save_as = null) { $screenshot = base64_decode( - $this->executor->execute('takeScreenshot') + $this->executor->execute(DriverCommand::SCREENSHOT) ); if ($save_as) { file_put_contents($save_as, $screenshot); @@ -403,7 +415,7 @@ public function action() { * @return RemoteWebElement */ public function getActiveElement() { - $response = $this->executor->execute('getActiveElement'); + $response = $this->executor->execute(DriverCommand::GET_ACTIVE_ELEMENT); return $this->newElement($response['ELEMENT']); } diff --git a/lib/remote/RemoteWebElement.php b/lib/remote/RemoteWebElement.php index ba15f8835..cc5549228 100644 --- a/lib/remote/RemoteWebElement.php +++ b/lib/remote/RemoteWebElement.php @@ -48,7 +48,10 @@ public function __construct(HttpCommandExecutor $executor, $id) { * @return RemoteWebElement The current instance. */ public function clear() { - $this->executor->execute('clear', array(':id' => $this->id)); + $this->executor->execute( + DriverCommand::CLEAR_ELEMENT, + array(':id' => $this->id) + ); return $this; } @@ -58,7 +61,10 @@ public function clear() { * @return RemoteWebElement The current instance. */ public function click() { - $this->executor->execute('clickElement', array(':id' => $this->id)); + $this->executor->execute( + DriverCommand::CLICK_ELEMENT, + array(':id' => $this->id) + ); return $this; } @@ -77,7 +83,10 @@ public function findElement(WebDriverBy $by) { 'value' => $by->getValue(), ':id' => $this->id, ); - $raw_element = $this->executor->execute('elementFindElement', $params); + $raw_element = $this->executor->execute( + DriverCommand::FIND_CHILD_ELEMENT, + $params + ); return $this->newElement($raw_element['ELEMENT']); } @@ -96,7 +105,10 @@ public function findElements(WebDriverBy $by) { 'value' => $by->getValue(), ':id' => $this->id, ); - $raw_elements = $this->executor->execute('elementFindElements', $params); + $raw_elements = $this->executor->execute( + DriverCommand::FIND_CHILD_ELEMENTS, + $params + ); $elements = array(); foreach ($raw_elements as $raw_element) { @@ -116,7 +128,10 @@ public function getAttribute($attribute_name) { ':name' => $attribute_name, ':id' => $this->id, ); - return $this->executor->execute('getElementAttribute', $params); + return $this->executor->execute( + DriverCommand::GET_ELEMENT_ATTRIBUTE, + $params + ); } /** @@ -130,7 +145,10 @@ public function getCSSValue($css_property_name) { ':propertyName' => $css_property_name, ':id' => $this->id, ); - return $this->executor->execute('getElementCSSValue', $params); + return $this->executor->execute( + DriverCommand::GET_ELEMENT_VALUE_OF_CSS_PROPERTY, + $params + ); } /** @@ -140,7 +158,7 @@ public function getCSSValue($css_property_name) { */ public function getLocation() { $location = $this->executor->execute( - 'getElementLocation', + DriverCommand::GET_ELEMENT_LOCATION, array(':id' => $this->id) ); return new WebDriverPoint($location['x'], $location['y']); @@ -154,7 +172,7 @@ public function getLocation() { */ public function getLocationOnScreenOnceScrolledIntoView() { $location = $this->executor->execute( - 'getElementLocationOnceScrolledIntoView', + DriverCommand::GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW, array(':id' => $this->id) ); return new WebDriverPoint($location['x'], $location['y']); @@ -190,7 +208,7 @@ public function getCoordinates() { */ public function getSize() { $size = $this->executor->execute( - 'getElementSize', + DriverCommand::GET_ELEMENT_SIZE, array(':id' => $this->id) ); return new WebDriverDimension($size['width'], $size['height']); @@ -203,7 +221,7 @@ public function getSize() { */ public function getTagName() { return $this->executor->execute( - 'getElementTagName', + DriverCommand::GET_ELEMENT_TAG_NAME, array(':id' => $this->id) ); } @@ -216,7 +234,7 @@ public function getTagName() { */ public function getText() { return $this->executor->execute( - 'getElementText', + DriverCommand::GET_ELEMENT_TEXT, array(':id' => $this->id) ); } @@ -229,7 +247,7 @@ public function getText() { */ public function isDisplayed() { return $this->executor->execute( - 'isElementDisplayed', + DriverCommand::IS_ELEMENT_DISPLAYED, array(':id' => $this->id) ); } @@ -242,7 +260,7 @@ public function isDisplayed() { */ public function isEnabled() { return $this->executor->execute( - 'isElementEnabled', + DriverCommand::IS_ELEMENT_ENABLED, array(':id' => $this->id) ); } @@ -254,7 +272,7 @@ public function isEnabled() { */ public function isSelected() { return $this->executor->execute( - 'isElementSelected', + DriverCommand::IS_ELEMENT_SELECTED, array(':id' => $this->id) ); } @@ -272,14 +290,14 @@ public function sendKeys($value) { 'value' => WebDriverKeys::encode($value), ':id' => $this->id, ); - $this->executor->execute('sendKeysToElement', $params); + $this->executor->execute(DriverCommand::SEND_KEYS_TO_ELEMENT, $params); } else { $remote_path = $this->upload($local_file); $params = array( 'value' => WebDriverKeys::encode($remote_path), ':id' => $this->id, ); - $this->executor->execute('sendKeysToElement', $params); + $this->executor->execute(DriverCommand::SEND_KEYS_TO_ELEMENT, $params); } return $this; } @@ -310,7 +328,10 @@ private function upload($local_file) { $params = array( 'file' => base64_encode(file_get_contents($temp_zip)), ); - $remote_path = $this->executor->execute('sendFile', $params); + $remote_path = $this->executor->execute( + DriverCommand::UPLOAD_FILE, + $params + ); unlink($temp_zip); return $remote_path; } @@ -342,7 +363,10 @@ public function setFileDetector(FileDetector $detector) { * @return RemoteWebElement The current instance. */ public function submit() { - $this->executor->execute('submitElement', array(':id' => $this->id)); + $this->executor->execute( + DriverCommand::SUBMIT_ELEMENT, + array(':id' => $this->id) + ); return $this; } @@ -363,7 +387,7 @@ public function getID() { * @return bool */ public function equals(WebDriverElement $other) { - return $this->executor->execute('elementEquals', array( + return $this->executor->execute(DriverCommand::ELEMENT_EQUALS, array( ':id' => $this->id, ':other' => $other->getID(), )); From 0f210ae8c826d134c65d726e02587b8b03513401 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Tue, 27 May 2014 14:31:19 -0700 Subject: [PATCH 055/784] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7b278f8fe..897a2df48 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Install the library. ## GETTING STARTED -* All you need as the server for this client is the selenium-server-standalone-#.jar file provided here: http://code.google.com/p/selenium/downloads/list +* All you need as the server for this client is the selenium-server-standalone-#.jar file provided here: http://selenium-release.storage.googleapis.com/index.html * Download and run that file, replacing # with the current server version. From d63006322379e55e4223d6fbf2486d22780ac7a4 Mon Sep 17 00:00:00 2001 From: whhone Date: Tue, 27 May 2014 16:43:08 -0700 Subject: [PATCH 056/784] Standardize WebDriver Response --- lib/__init__.php | 1 + lib/remote/HttpCommandExecutor.php | 9 ++-- lib/remote/WebDriverResponse.php | 87 ++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 lib/remote/WebDriverResponse.php diff --git a/lib/__init__.php b/lib/__init__.php index 517aec324..d041cc4f2 100755 --- a/lib/__init__.php +++ b/lib/__init__.php @@ -70,6 +70,7 @@ require_once('remote/WebDriverBrowserType.php'); require_once('remote/WebDriverCapabilityType.php'); require_once('remote/DesiredCapabilities.php'); +require_once('remote/WebDriverResponse.php'); require_once('remote/HttpCommandExecutor.php'); require_once('interactions/internal/WebDriverSendKeysAction.php'); require_once('interactions/internal/WebDriverKeyDownAction.php'); diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index c42c53b0b..b869d868d 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -134,8 +134,8 @@ public function execute($name, array $params = array()) { 'name' => $name, 'parameters' => $params, ); - $raw = self::remoteExecute($command); - return $raw['value']; + $response = self::remoteExecute($command); + return $response->getValue(); } /** @@ -244,7 +244,6 @@ protected static function curl( } $raw_results = trim(curl_exec($curl)); - $info = curl_getinfo($curl); if ($error = curl_error($curl)) { $msg = sprintf( @@ -278,7 +277,9 @@ protected static function curl( $status = isset($results['status']) ? $results['status'] : 0; WebDriverException::throwException($status, $message, $results); - return array('value' => $value, 'info' => $info, 'sessionId' => $sessionId); + return (new WebDriverResponse($sessionId)) + ->setStatus($status) + ->setValue($value); } /** diff --git a/lib/remote/WebDriverResponse.php b/lib/remote/WebDriverResponse.php new file mode 100644 index 000000000..a42e3067c --- /dev/null +++ b/lib/remote/WebDriverResponse.php @@ -0,0 +1,87 @@ +sessionID = $session_id; + } + + /** + * @return null|int + */ + public function getStatus() { + return $this->status; + } + + /** + * @param int $status + * @return WebDriverResponse + */ + public function setStatus($status) { + $this->status = $status; + return $this; + } + + /** + * @return mixed + */ + public function getValue() { + return $this->value; + } + + /** + * @param mixed $value + * @return WebDriverResponse + */ + public function setValue($value) { + $this->value = $value; + return $this; + } + + /** + * @return null|string + */ + public function getSessionID() { + return $this->sessionID; + } + + /** + * @param mixed $session_id + * @return WebDriverResponse + */ + public function setSessionID($session_id) { + $this->sessionID = $session_id; + return $this; + } +} From 8667599b19e992cf14b904d8c743bc2e86334768 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Tue, 27 May 2014 16:46:24 -0700 Subject: [PATCH 057/784] fix --- lib/remote/RemoteWebDriver.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index 7bec1da87..de461e2af 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -62,7 +62,10 @@ public static function create( $response = static::remoteExecuteHttpCommand($timeout_in_ms, $command); $driver = new static(); - $executor = static::createHttpCommandExecutor($url, $response['sessionId']); + $executor = static::createHttpCommandExecutor( + $url, + $response->getSessionID() + ); return $driver->setCommandExecutor($executor); } From 5b1e3302f32352c52ebdd7dc23d9aa90f94170b1 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Tue, 27 May 2014 16:58:57 -0700 Subject: [PATCH 058/784] update test --- tests/unit/remote/RemoteWebDriverTest.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/unit/remote/RemoteWebDriverTest.php b/tests/unit/remote/RemoteWebDriverTest.php index 3da28ae07..c53b4fcbe 100644 --- a/tests/unit/remote/RemoteWebDriverTest.php +++ b/tests/unit/remote/RemoteWebDriverTest.php @@ -25,6 +25,10 @@ public function testCreate() { $timeout = 1000; $url = 'http://localhost:4444/wd/hub'; $response = array('value' => 'someValue', 'info' => 'someInfo', 'sessionId' => 'someSessionId'); + $response = (new WebDriverResponse('someSessionId')) + ->setStatus(0) + ->setValue('someValue'); + $executor = $this->getMockBuilder('HttpCommandExecutor')->disableOriginalConstructor()->getMock(); $remoteWebDriver @@ -37,7 +41,7 @@ public function testCreate() { $remoteWebDriver ->staticExpects($this->once()) ->method('createHttpCommandExecutor') - ->with($url, $response['sessionId']) + ->with($url, $response->getSessionID()) ->will($this->returnValue($executor)) ; From c58a324cf2683601885b430663a821ad34dd6709 Mon Sep 17 00:00:00 2001 From: TobiasLang Date: Wed, 28 May 2014 16:22:37 +0200 Subject: [PATCH 059/784] Update HttpCommandExecutor.php Bugfix, as current code breaks execution with PHP 5.3 (unsupported language feature). --- lib/remote/HttpCommandExecutor.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index b869d868d..bea23059c 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -277,7 +277,8 @@ protected static function curl( $status = isset($results['status']) ? $results['status'] : 0; WebDriverException::throwException($status, $message, $results); - return (new WebDriverResponse($sessionId)) + $response = new WebDriverResponse($sessionId); + return $response ->setStatus($status) ->setValue($value); } From f7175ff60768345c742e49e7cd13c3b25b76b3ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=9A=D0=BE=D0=BB?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Thu, 29 May 2014 13:14:30 +0400 Subject: [PATCH 060/784] Does not close connection manually. Update phpdoc. Init curl from RemoteWebDriver. --- lib/remote/HttpCommandExecutor.php | 42 +++++++++++++++++++----------- lib/remote/RemoteWebDriver.php | 5 +++- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index bea23059c..a11161b75 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -110,6 +110,10 @@ class HttpCommandExecutor implements WebDriverCommandExecutor { * @var array */ protected $capabilities; + /** + * @var resource + */ + protected static $curl; /** * @param string $url @@ -121,6 +125,15 @@ public function __construct($url, $session_id) { $this->capabilities = $this->execute(DriverCommand::GET_CAPABILITIES); } + /** + * Init curl. + */ + public static function initCurl() { + if (self::$curl === null) { + self::$curl = curl_init(); + } + } + /** * @param string $name * @param array $params @@ -153,7 +166,7 @@ public function execute($name, array $params = array()) { * parameters : the parameters of the command required * @param array $curl_opts An array of curl options. * - * @return array The response of the command. + * @return WebDriverResponse The response of the command. * @throws Exception */ public static function remoteExecute( @@ -185,7 +198,7 @@ public static function remoteExecute( * @param array $command The Command object, modelled as a hash. * @param array $extra_opts key => value pairs of curl options for * curl_setopt() - * @return array + * @return WebDriverResponse * @throws Exception */ protected static function curl( @@ -218,34 +231,33 @@ protected static function curl( json_encode($params))); } - $curl = curl_init($url); - - curl_setopt($curl, CURLOPT_TIMEOUT, 300); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); + curl_setopt(self::$curl, CURLOPT_URL, $url); + curl_setopt(self::$curl, CURLOPT_TIMEOUT, 300); + curl_setopt(self::$curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt(self::$curl, CURLOPT_FOLLOWLOCATION, true); curl_setopt( - $curl, + self::$curl, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json;charset=UTF-8', 'Accept: application/json')); if ($http_method === 'POST') { - curl_setopt($curl, CURLOPT_POST, true); + curl_setopt(self::$curl, CURLOPT_POST, true); if ($params && is_array($params)) { - curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($params)); + curl_setopt(self::$curl, CURLOPT_POSTFIELDS, json_encode($params)); } } else if ($http_method == 'DELETE') { - curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); + curl_setopt(self::$curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); } foreach ($extra_opts as $option => $value) { - curl_setopt($curl, $option, $value); + curl_setopt(self::$curl, $option, $value); } - $raw_results = trim(curl_exec($curl)); + $raw_results = trim(curl_exec(self::$curl)); - if ($error = curl_error($curl)) { + if ($error = curl_error(self::$curl)) { $msg = sprintf( 'Curl error thrown for http %s to %s', $http_method, @@ -255,7 +267,7 @@ protected static function curl( } WebDriverException::throwException(-1, $msg . "\n\n" . $error, array()); } - curl_close($curl); + curl_reset(self::$curl); $results = json_decode($raw_results, true); diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index de461e2af..d0fb8c550 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -61,6 +61,7 @@ public static function create( ); $response = static::remoteExecuteHttpCommand($timeout_in_ms, $command); + /** @var RemoteWebDriver $driver */ $driver = new static(); $executor = static::createHttpCommandExecutor( $url, @@ -85,6 +86,7 @@ public static function createBySessionID( $session_id, $url = 'http://localhost:4444/wd/hub' ) { + /** @var RemoteWebDriver $driver */ $driver = new static(); $driver->setCommandExecutor(new HttpCommandExecutor($url, $session_id)); return $driver; @@ -106,9 +108,10 @@ public static function createHttpCommandExecutor($url, $session_id) { /** * @param int $timeout_in_ms * @param array $command - * @return array + * @return WebDriverResponse */ public static function remoteExecuteHttpCommand($timeout_in_ms, $command) { + HttpCommandExecutor::initCurl(); $response = HttpCommandExecutor::remoteExecute( $command, array( From fe0a427fafa6e6a1c960f82b7fc5b7814947b9ad Mon Sep 17 00:00:00 2001 From: whhone Date: Thu, 29 May 2014 17:10:17 -0700 Subject: [PATCH 061/784] FirefoxProfile see https://github.com/facebook/php-webdriver/wiki/FirefoxProfile --- lib/__init__.php | 2 + lib/firefox/FirefoxDriver.php | 19 +++++ lib/firefox/FirefoxProfile.php | 123 +++++++++++++++++++++++++++++ lib/remote/DesiredCapabilities.php | 6 ++ 4 files changed, 150 insertions(+) create mode 100644 lib/firefox/FirefoxDriver.php create mode 100644 lib/firefox/FirefoxProfile.php diff --git a/lib/__init__.php b/lib/__init__.php index d041cc4f2..8235f973f 100755 --- a/lib/__init__.php +++ b/lib/__init__.php @@ -60,6 +60,8 @@ require_once('interactions/internal/WebDriverMoveToOffsetAction.php'); require_once('internal/WebDriverLocatable.php'); require_once('chrome/ChromeOptions.php'); +require_once('firefox/FirefoxDriver.php'); +require_once('firefox/FirefoxProfile.php'); require_once('remote/DriverCommand.php'); require_once('remote/LocalFileDetector.php'); require_once('remote/UselessFileDetector.php'); diff --git a/lib/firefox/FirefoxDriver.php b/lib/firefox/FirefoxDriver.php new file mode 100644 index 000000000..b1580baa6 --- /dev/null +++ b/lib/firefox/FirefoxDriver.php @@ -0,0 +1,19 @@ +extensions[] = $extension; + return $this; + } + + /** + * @param string $key + * @param string|bool|int $value + * @return FirefoxProfile + */ + public function setPreference($key, $value) { + if (is_string($value)) { + $value = sprintf('"%s"', $value); + } else if (is_int($value)) { + $value = sprintf('%d', $value); + } else if (is_bool($value)) { + $value = $value ? 'true' : 'false'; + } else { + throw new WebDriverException( + 'The value of the preference should be either a string, int or bool.'); + } + $this->preferences[$key] = $value; + return $this; + } + + /** + * @return string + */ + public function encode() { + $temp_dir = $this->createTempDirectory('WebDriverFirefoxProfile'); + + foreach ($this->extensions as $extension) { + $this->installExtension($extension, $temp_dir); + } + + $content = ""; + foreach ($this->preferences as $key => $value) { + $content .= sprintf("user_pref(\"%s\", %s);\n", $key, $value); + } + file_put_contents($temp_dir.'/user.js', $content); + + $zip = new ZipArchive(); + $temp_zip = tempnam('', 'WebDriverFirefoxProfileZip'); + $zip->open($temp_zip, ZipArchive::CREATE); + + $dir = new RecursiveDirectoryIterator($temp_dir); + $files = new RecursiveIteratorIterator($dir); + foreach ($files as $name => $object) { + $path = preg_replace("#^{$temp_dir}/#", "", $name); + $zip->addFile($name, $path); + } + $zip->close(); + + $profile = base64_encode(file_get_contents($temp_zip)); + return $profile; + } + + private function installExtension($extension, $profile_dir) { + $temp_dir = $this->createTempDirectory(); + + $this->extractTo($extension, $temp_dir); + + $install_rdf_path = $temp_dir.'/install.rdf'; + $xml = simplexml_load_string(file_get_contents($install_rdf_path)); + $ext_dir = $profile_dir.'/extensions/'.((string)($xml->Description->id)); + mkdir($ext_dir, 0777, true); + + $this->extractTo($extension, $ext_dir); + return $ext_dir; + } + + private function createTempDirectory($prefix = '') { + $temp_dir = tempnam('', $prefix); + if (file_exists($temp_dir)) { + unlink($temp_dir); + mkdir($temp_dir); + if (!is_dir($temp_dir)) { + throw new WebDriverException('Cannot create firefox profile.'); + } + } + return $temp_dir; + } + + private function extractTo($xpi, $target_dir) { + $zip = new ZipArchive(); + if ($zip->open($xpi)) { + $zip->extractTo($target_dir); + $zip->close(); + } else { + throw new Exception("Failed to open the firefox extension. '$xpi'"); + } + } +} diff --git a/lib/remote/DesiredCapabilities.php b/lib/remote/DesiredCapabilities.php index 844deb1d5..72e984317 100644 --- a/lib/remote/DesiredCapabilities.php +++ b/lib/remote/DesiredCapabilities.php @@ -113,6 +113,12 @@ public function toArray() { $this->capabilities[ChromeOptions::CAPABILITY]->toArray(); } + if (isset($this->capabilities[FirefoxDriver::PROFILE]) && + $this->capabilities[FirefoxDriver::PROFILE] instanceof FirefoxProfile) { + $this->capabilities[FirefoxDriver::PROFILE] = + $this->capabilities[FirefoxDriver::PROFILE]->encode(); + } + return $this->capabilities; } From fc3fb7762a15d9d6051a34a535e7da4da8dc3e1a Mon Sep 17 00:00:00 2001 From: whhone Date: Thu, 29 May 2014 17:12:23 -0700 Subject: [PATCH 062/784] FirefoxProfile see https://github.com/facebook/php-webdriver/wiki/FirefoxProfile --- lib/firefox/FirefoxProfile.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/firefox/FirefoxProfile.php b/lib/firefox/FirefoxProfile.php index 84e2de947..148a07fa1 100644 --- a/lib/firefox/FirefoxProfile.php +++ b/lib/firefox/FirefoxProfile.php @@ -76,6 +76,9 @@ public function encode() { $dir = new RecursiveDirectoryIterator($temp_dir); $files = new RecursiveIteratorIterator($dir); foreach ($files as $name => $object) { + if (is_dir($name)) { + continue; + } $path = preg_replace("#^{$temp_dir}/#", "", $name); $zip->addFile($name, $path); } @@ -91,8 +94,12 @@ private function installExtension($extension, $profile_dir) { $this->extractTo($extension, $temp_dir); $install_rdf_path = $temp_dir.'/install.rdf'; - $xml = simplexml_load_string(file_get_contents($install_rdf_path)); - $ext_dir = $profile_dir.'/extensions/'.((string)($xml->Description->id)); + // This is a hacky way to parse the id since there is no offical + // RDF parser library. + $xml = file_get_contents($install_rdf_path); + preg_match('#([^<]+)#', $xml, $matches); + $ext_dir = $profile_dir.'/extensions/'.$matches[1]; + mkdir($ext_dir, 0777, true); $this->extractTo($extension, $ext_dir); @@ -121,3 +128,4 @@ private function extractTo($xpi, $target_dir) { } } } + From 66fd950c5717f98fc14c2bb48d66b3b32adb3b96 Mon Sep 17 00:00:00 2001 From: whhone Date: Thu, 29 May 2014 17:25:54 -0700 Subject: [PATCH 063/784] phpdoc for firefox profile --- lib/firefox/FirefoxProfile.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/firefox/FirefoxProfile.php b/lib/firefox/FirefoxProfile.php index 148a07fa1..af2184464 100644 --- a/lib/firefox/FirefoxProfile.php +++ b/lib/firefox/FirefoxProfile.php @@ -27,6 +27,7 @@ class FirefoxProfile { /** * @param string $extension The path to the xpi extension. + * @return FirefoxProfile */ public function addExtension($extension) { $this->extensions[] = $extension; @@ -88,6 +89,11 @@ public function encode() { return $profile; } + /** + * @param string $extension The path to the extension. + * @param string $profile_dir The path to the profile directory. + * @return string The path to the directory of this extension. + */ private function installExtension($extension, $profile_dir) { $temp_dir = $this->createTempDirectory(); @@ -96,6 +102,7 @@ private function installExtension($extension, $profile_dir) { $install_rdf_path = $temp_dir.'/install.rdf'; // This is a hacky way to parse the id since there is no offical // RDF parser library. + $matches = array(); $xml = file_get_contents($install_rdf_path); preg_match('#([^<]+)#', $xml, $matches); $ext_dir = $profile_dir.'/extensions/'.$matches[1]; @@ -106,6 +113,10 @@ private function installExtension($extension, $profile_dir) { return $ext_dir; } + /** + * @param string $prefix Prefix of the temp directory. + * @return string The path to the temp directory created. + */ private function createTempDirectory($prefix = '') { $temp_dir = tempnam('', $prefix); if (file_exists($temp_dir)) { @@ -118,6 +129,11 @@ private function createTempDirectory($prefix = '') { return $temp_dir; } + /** + * @param string $xpi The path to the .xpi extension. + * @param string The path to the unzip directory. + * @return FirefoxProfile + */ private function extractTo($xpi, $target_dir) { $zip = new ZipArchive(); if ($zip->open($xpi)) { @@ -126,6 +142,6 @@ private function extractTo($xpi, $target_dir) { } else { throw new Exception("Failed to open the firefox extension. '$xpi'"); } + return $this; } } - From 336853bc6d124af386526aa877114a2bf38a3730 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=9A=D0=BE=D0=BB?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Fri, 30 May 2014 10:59:01 +0400 Subject: [PATCH 064/784] Reset curl without curl_reset(). --- lib/remote/HttpCommandExecutor.php | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index a11161b75..9947f774c 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -131,6 +131,15 @@ public function __construct($url, $session_id) { public static function initCurl() { if (self::$curl === null) { self::$curl = curl_init(); + curl_setopt(self::$curl, CURLOPT_TIMEOUT, 300); + curl_setopt(self::$curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt(self::$curl, CURLOPT_FOLLOWLOCATION, true); + curl_setopt( + self::$curl, + CURLOPT_HTTPHEADER, + array( + 'Content-Type: application/json;charset=UTF-8', + 'Accept: application/json')); } } @@ -232,17 +241,10 @@ protected static function curl( } curl_setopt(self::$curl, CURLOPT_URL, $url); - curl_setopt(self::$curl, CURLOPT_TIMEOUT, 300); - curl_setopt(self::$curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt(self::$curl, CURLOPT_FOLLOWLOCATION, true); - curl_setopt( - self::$curl, - CURLOPT_HTTPHEADER, - array( - 'Content-Type: application/json;charset=UTF-8', - 'Accept: application/json')); - if ($http_method === 'POST') { + if ($http_method === 'GET') { + curl_setopt(self::$curl, CURLOPT_HTTPGET, true); + } else if ($http_method === 'POST') { curl_setopt(self::$curl, CURLOPT_POST, true); if ($params && is_array($params)) { curl_setopt(self::$curl, CURLOPT_POSTFIELDS, json_encode($params)); @@ -267,7 +269,9 @@ protected static function curl( } WebDriverException::throwException(-1, $msg . "\n\n" . $error, array()); } - curl_reset(self::$curl); + + curl_setopt(self::$curl, CURLOPT_POSTFIELDS, null); + curl_setopt(self::$curl, CURLOPT_CUSTOMREQUEST, null); $results = json_decode($raw_results, true); From 37dc83f740b2c4758c995bc166b6a7bdeb085b6a Mon Sep 17 00:00:00 2001 From: whhone Date: Fri, 30 May 2014 17:37:27 -0700 Subject: [PATCH 065/784] fix bug in WebDriverWait --- lib/WebDriverWait.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/WebDriverWait.php b/lib/WebDriverWait.php index c5f304e42..23f20a033 100644 --- a/lib/WebDriverWait.php +++ b/lib/WebDriverWait.php @@ -43,10 +43,10 @@ public function __construct( * return mixed The return value of $func_or_ec */ public function until($func_or_ec, $message = "") { - $end = time() + $this->timeout; + $end = microtime(true) + $this->timeout; $last_exception = null; - while ($end > time()) { + while ($end > microtime(time)) { try { if ($func_or_ec instanceof WebDriverExpectedCondition) { $ret_val = call_user_func($func_or_ec->getApply(), $this->driver); From d4fb7cdc79c39972f4b494cd1a3822c4aad9526c Mon Sep 17 00:00:00 2001 From: whhone Date: Fri, 30 May 2014 17:38:56 -0700 Subject: [PATCH 066/784] typo --- lib/WebDriverWait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/WebDriverWait.php b/lib/WebDriverWait.php index 23f20a033..2ab2aad5a 100644 --- a/lib/WebDriverWait.php +++ b/lib/WebDriverWait.php @@ -46,7 +46,7 @@ public function until($func_or_ec, $message = "") { $end = microtime(true) + $this->timeout; $last_exception = null; - while ($end > microtime(time)) { + while ($end > microtime(true)) { try { if ($func_or_ec instanceof WebDriverExpectedCondition) { $ret_val = call_user_func($func_or_ec->getApply(), $this->driver); From 0b7141daf1dcad189b2de61ca2489e4b29e8b1ad Mon Sep 17 00:00:00 2001 From: whhone Date: Mon, 2 Jun 2014 12:52:59 -0700 Subject: [PATCH 067/784] refactor WebDriverCommand CommandExecutor should not hold the session id. Instead, the session id should be passed inside the command to the executor. --- lib/WebDriver.php | 7 ++ lib/WebDriverCommandExecutor.php | 3 +- lib/WebDriverNavigation.php | 2 +- lib/WebDriverOptions.php | 2 +- lib/__init__.php | 4 + lib/remote/ExecuteMethod.php | 24 ++++ lib/remote/HttpCommandExecutor.php | 70 +++-------- lib/remote/RemoteExecuteMethod.php | 36 ++++++ lib/remote/RemoteKeyboard.php | 6 +- lib/remote/RemoteMouse.php | 6 +- lib/remote/RemoteTouchScreen.php | 6 +- lib/remote/RemoteWebDriver.php | 121 +++++++++++--------- lib/remote/RemoteWebElement.php | 6 +- lib/remote/WebDriverCommand.php | 39 +++++++ lib/support/events/EventFiringWebDriver.php | 8 ++ 15 files changed, 220 insertions(+), 120 deletions(-) create mode 100644 lib/remote/ExecuteMethod.php create mode 100644 lib/remote/RemoteExecuteMethod.php create mode 100644 lib/remote/WebDriverCommand.php diff --git a/lib/WebDriver.php b/lib/WebDriver.php index 6a87cbbcd..2f4515774 100755 --- a/lib/WebDriver.php +++ b/lib/WebDriver.php @@ -121,4 +121,11 @@ public function navigate(); * @see WebDriverTargetLocator */ public function switchTo(); + + /** + * @param string $name + * @param array $params + * @return mixed + */ + public function execute($name, $params); } diff --git a/lib/WebDriverCommandExecutor.php b/lib/WebDriverCommandExecutor.php index b74bc4f67..481a9336a 100644 --- a/lib/WebDriverCommandExecutor.php +++ b/lib/WebDriverCommandExecutor.php @@ -18,9 +18,8 @@ */ interface WebDriverCommandExecutor { - // $command and $params will be merged to an command object in the future. /** * @return mixed */ - public function execute($command, array $params = array()); + public function execute(WebDriverCommand $command); } diff --git a/lib/WebDriverNavigation.php b/lib/WebDriverNavigation.php index 6f3a2bb31..13c662ad0 100644 --- a/lib/WebDriverNavigation.php +++ b/lib/WebDriverNavigation.php @@ -26,7 +26,7 @@ class WebDriverNavigation { protected $executor; - public function __construct(WebDriverCommandExecutor $executor) { + public function __construct(ExecuteMethod $executor) { $this->executor = $executor; } diff --git a/lib/WebDriverOptions.php b/lib/WebDriverOptions.php index 98dcb0a63..98a6d07c2 100644 --- a/lib/WebDriverOptions.php +++ b/lib/WebDriverOptions.php @@ -20,7 +20,7 @@ class WebDriverOptions { protected $executor; - public function __construct(WebDriverCommandExecutor $executor) { + public function __construct(ExecuteMethod $executor) { $this->executor = $executor; } diff --git a/lib/__init__.php b/lib/__init__.php index 8235f973f..f6843eefa 100755 --- a/lib/__init__.php +++ b/lib/__init__.php @@ -23,11 +23,14 @@ require_once('WebDriverEventListener.php'); require_once('remote/FileDetector.php'); require_once('WebDriverCapabilities.php'); +require_once('remote/ExecuteMethod.php'); // abstract class require_once('interactions/internal/WebDriverKeysRelatedAction.php'); require_once('interactions/internal/WebDriverSingleKeyAction.php'); +require_once('remote/WebDriverCommand.php'); + // class require_once('WebDriverAlert.php'); require_once('WebDriverBy.php'); @@ -69,6 +72,7 @@ require_once('remote/RemoteKeyboard.php'); require_once('remote/RemoteWebDriver.php'); require_once('remote/RemoteWebElement.php'); +require_once('remote/RemoteExecuteMethod.php'); require_once('remote/WebDriverBrowserType.php'); require_once('remote/WebDriverCapabilityType.php'); require_once('remote/DesiredCapabilities.php'); diff --git a/lib/remote/ExecuteMethod.php b/lib/remote/ExecuteMethod.php new file mode 100644 index 000000000..8d934bd32 --- /dev/null +++ b/lib/remote/ExecuteMethod.php @@ -0,0 +1,24 @@ +url = $url; - $this->sessionID = $session_id; - $this->capabilities = $this->execute(DriverCommand::GET_CAPABILITIES); } /** - * @param string $name - * @param array $params + * @param WebDriverCommand $command * * @return mixed */ - public function execute($name, array $params = array()) { - $command = array( - 'url' => $this->url, - 'sessionId' => $this->sessionID, - 'name' => $name, - 'parameters' => $params, - ); - $response = self::remoteExecute($command); - return $response->getValue(); + public function execute(WebDriverCommand $command) { + $response = self::remoteExecute($command, $this->url); + return $response; } /** - * Execute a command on a remote server. The command should be an array - * contains - * url : the url of the remote server - * sessionId : the session id if needed - * name : the name of the command - * parameters : the parameters of the command required + * This method is deprecated. + * Execute a command on a remote server. * - * @param array $command An array that contains - * url : the url of the remote server - * sessionId : the session id if needed - * name : the name of the command - * parameters : the parameters of the command required + * @param WebDriverCommand * @param array $curl_opts An array of curl options. * * @return array The response of the command. * @throws Exception */ public static function remoteExecute( - array $command, + WebDriverCommand $command, + string $url, array $curl_opts = array() ) { - if (!isset(self::$commands[$command['name']])) { - throw new Exception($command['name']." is not a valid command."); + if (!isset(self::$commands[$command->getName()])) { + throw new Exception($command->getName()." is not a valid command."); } - $raw = self::$commands[$command['name']]; + $raw = self::$commands[$command->getName()]; - if ($command['name'] == DriverCommand::NEW_SESSION) { + if ($command->getName() == DriverCommand::NEW_SESSION) { $curl_opts[CURLOPT_FOLLOWLOCATION] = true; } return self::curl( $raw['method'], - sprintf("%s%s", $command['url'], $raw['url']), + sprintf("%s%s", $url, $raw['url']), $command, $curl_opts ); @@ -191,10 +167,9 @@ public static function remoteExecute( protected static function curl( $http_method, $url, - array $command, + WebDriverCommand $command, array $extra_opts = array()) { - - $params = $command['parameters']; + $params = $command->getParameters(); foreach ($params as $name => $value) { if ($name[0] === ':') { @@ -205,8 +180,8 @@ protected static function curl( } } - if (isset($command['sessionId'])) { - $url = str_replace(':sessionId', $command['sessionId'], $url); + if ($command->getSessionID()) { + $url = str_replace(':sessionId', $command->getSessionID(), $url); } if ($params && is_array($params) && $http_method !== 'POST') { @@ -289,11 +264,4 @@ protected static function curl( public function getAddressOfRemoteServer() { return $this->url; } - - /** - * @return string - */ - public function getSessionID() { - return $this->sessionID; - } } diff --git a/lib/remote/RemoteExecuteMethod.php b/lib/remote/RemoteExecuteMethod.php new file mode 100644 index 000000000..cc97f19b3 --- /dev/null +++ b/lib/remote/RemoteExecuteMethod.php @@ -0,0 +1,36 @@ +driver = $driver; + } + + /** + * @return mixed + */ + public function execute( + $command_name, + array $parameters = array() + ) { + return $this->driver->execute($command_name, $parameters); + } +} diff --git a/lib/remote/RemoteKeyboard.php b/lib/remote/RemoteKeyboard.php index 116020545..2a3cc5477 100644 --- a/lib/remote/RemoteKeyboard.php +++ b/lib/remote/RemoteKeyboard.php @@ -19,14 +19,14 @@ class RemoteKeyboard implements WebDriverKeyboard { /** - * @var WebDriverCommandExecutor + * @var RemoteExecuteMethod */ private $executor; /** - * @param WebDriverCommandExecutor $executor + * @param RemoteExecuteMethod $executor */ - public function __construct(WebDriverCommandExecutor $executor) { + public function __construct(RemoteExecuteMethod $executor) { $this->executor = $executor; } diff --git a/lib/remote/RemoteMouse.php b/lib/remote/RemoteMouse.php index cb0613e1e..66d010252 100644 --- a/lib/remote/RemoteMouse.php +++ b/lib/remote/RemoteMouse.php @@ -19,14 +19,14 @@ class RemoteMouse implements WebDriverMouse { /** - * @var WebDriverCommandExecutor + * @var RemoteExecuteMethod */ private $executor; /** - * @param WebDriverCommandExecutor $executor + * @param RemoteExecuteMethod $executor */ - public function __construct(WebDriverCommandExecutor $executor) { + public function __construct(RemoteExecuteMethod $executor) { $this->executor = $executor; } diff --git a/lib/remote/RemoteTouchScreen.php b/lib/remote/RemoteTouchScreen.php index de8dc539d..652020dea 100644 --- a/lib/remote/RemoteTouchScreen.php +++ b/lib/remote/RemoteTouchScreen.php @@ -19,14 +19,14 @@ class RemoteTouchScreen implements WebDriverTouchScreen { /** - * @var WebDriverCommandExecutor + * @var RemoteExecuteMethod */ private $executor; /** - * @param WebDriverCommandExecutor $executor + * @param RemoteExecuteMethod $executor */ - public function __construct(WebDriverCommandExecutor $executor) { + public function __construct(RemoteExecuteMethod $executor) { $this->executor = $executor; } diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index de461e2af..daf0bdfbf 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -15,9 +15,13 @@ class RemoteWebDriver implements WebDriver, JavaScriptExecutor { /** - * @var HttpCommandExecutor - */ + * @var HttpCommandExecutor + */ protected $executor; + /** + * @var string + */ + protected $sessionID; /** * @var RemoteMouse */ @@ -30,6 +34,10 @@ class RemoteWebDriver implements WebDriver, JavaScriptExecutor { * @var RemoteTouchScreen */ protected $touch; + /** + * @var RemoteExecuteMethod + */ + protected $executeMethod; protected function __construct() {} @@ -54,19 +62,22 @@ public static function create( $desired_capabilities = $desired_capabilities->toArray(); } - $command = array( - 'url' => $url, - 'name' => DriverCommand::NEW_SESSION, - 'parameters' => array('desiredCapabilities' => $desired_capabilities), + $command = new WebDriverCommand( + null, + DriverCommand::NEW_SESSION, + array('desiredCapabilities' => $desired_capabilities) ); - $response = static::remoteExecuteHttpCommand($timeout_in_ms, $command); - $driver = new static(); - $executor = static::createHttpCommandExecutor( - $url, - $response->getSessionID() + $response = static::remoteExecuteHttpCommand( + $timeout_in_ms, + $command, + $url ); + $driver = new static(); + $driver->setSessionID($response->getSessionID()); + $executor = new HttpCommandExecutor($url); + return $driver->setCommandExecutor($executor); } @@ -86,31 +97,22 @@ public static function createBySessionID( $url = 'http://localhost:4444/wd/hub' ) { $driver = new static(); - $driver->setCommandExecutor(new HttpCommandExecutor($url, $session_id)); + $driver->setSessionID($session_id) + ->setCommandExecutor(new HttpCommandExecutor($url)); return $driver; } - /** - * @param string $url - * @param string $session_id - * @return HttpCommandExecutor - */ - public static function createHttpCommandExecutor($url, $session_id) { - $executor = new HttpCommandExecutor( - $url, - $session_id - ); - return $executor; - } - /** * @param int $timeout_in_ms * @param array $command * @return array */ - public static function remoteExecuteHttpCommand($timeout_in_ms, $command) { + public static function remoteExecuteHttpCommand( + $timeout_in_ms, $command, $url + ) { $response = HttpCommandExecutor::remoteExecute( $command, + $url, array( CURLOPT_CONNECTTIMEOUT_MS => $timeout_in_ms, ) @@ -124,7 +126,7 @@ public static function remoteExecuteHttpCommand($timeout_in_ms, $command) { * @return RemoteWebDriver The current instance. */ public function close() { - $this->executor->execute(DriverCommand::CLOSE, array()); + $this->execute(DriverCommand::CLOSE, array()); return $this; } @@ -139,7 +141,7 @@ public function close() { */ public function findElement(WebDriverBy $by) { $params = array('using' => $by->getMechanism(), 'value' => $by->getValue()); - $raw_element = $this->executor->execute( + $raw_element = $this->execute( DriverCommand::FIND_ELEMENT, $params ); @@ -158,7 +160,7 @@ public function findElement(WebDriverBy $by) { */ public function findElements(WebDriverBy $by) { $params = array('using' => $by->getMechanism(), 'value' => $by->getValue()); - $raw_elements = $this->executor->execute( + $raw_elements = $this->execute( DriverCommand::FIND_ELEMENTS, $params ); @@ -179,7 +181,7 @@ public function findElements(WebDriverBy $by) { */ public function get($url) { $params = array('url' => (string)$url); - $this->executor->execute(DriverCommand::GET, $params); + $this->execute(DriverCommand::GET, $params); return $this; } @@ -190,7 +192,7 @@ public function get($url) { * @return string The current URL. */ public function getCurrentURL() { - return $this->executor->execute(DriverCommand::GET_CURRENT_URL); + return $this->execute(DriverCommand::GET_CURRENT_URL); } /** @@ -199,7 +201,7 @@ public function getCurrentURL() { * @return string The current page source. */ public function getPageSource() { - return $this->executor->execute(DriverCommand::GET_PAGE_SOURCE); + return $this->execute(DriverCommand::GET_PAGE_SOURCE); } /** @@ -208,7 +210,7 @@ public function getPageSource() { * @return string The title of the current page. */ public function getTitle() { - return $this->executor->execute(DriverCommand::GET_TITLE); + return $this->execute(DriverCommand::GET_TITLE); } /** @@ -218,7 +220,7 @@ public function getTitle() { * @return string The current window handle. */ public function getWindowHandle() { - return $this->executor->execute( + return $this->execute( DriverCommand::GET_CURRENT_WINDOW_HANDLE, array() ); @@ -230,7 +232,7 @@ public function getWindowHandle() { * @return array An array of string containing all available window handles. */ public function getWindowHandles() { - return $this->executor->execute(DriverCommand::GET_WINDOW_HANDLES, array()); + return $this->execute(DriverCommand::GET_WINDOW_HANDLES, array()); } /** @@ -239,7 +241,7 @@ public function getWindowHandles() { * @return void */ public function quit() { - $this->executor->execute(DriverCommand::QUIT); + $this->execute(DriverCommand::QUIT); $this->executor = null; } @@ -278,7 +280,7 @@ public function executeScript($script, array $arguments = array()) { 'script' => $script, 'args' => $this->prepareScriptArguments($arguments), ); - return $this->executor->execute(DriverCommand::EXECUTE_SCRIPT, $params); + return $this->execute(DriverCommand::EXECUTE_SCRIPT, $params); } /** @@ -299,7 +301,7 @@ public function executeAsyncScript($script, array $arguments = array()) { 'script' => $script, 'args' => $this->prepareScriptArguments($arguments), ); - return $this->executor->execute( + return $this->execute( DriverCommand::EXECUTE_ASYNC_SCRIPT, $params ); @@ -313,7 +315,7 @@ public function executeAsyncScript($script, array $arguments = array()) { */ public function takeScreenshot($save_as = null) { $screenshot = base64_decode( - $this->executor->execute(DriverCommand::SCREENSHOT) + $this->execute(DriverCommand::SCREENSHOT) ); if ($save_as) { file_put_contents($save_as, $screenshot); @@ -349,7 +351,7 @@ public function wait( * @return WebDriverOptions */ public function manage() { - return new WebDriverOptions($this->executor); + return new WebDriverOptions($this->getExecuteMethod()); } /** @@ -360,7 +362,7 @@ public function manage() { * @see WebDriverNavigation */ public function navigate() { - return new WebDriverNavigation($this->executor); + return new WebDriverNavigation($this->getExecuteMethod()); } /** @@ -378,7 +380,7 @@ public function switchTo() { */ public function getMouse() { if (!$this->mouse) { - $this->mouse = new RemoteMouse($this->executor); + $this->mouse = new RemoteMouse($this->getExecuteMethod()); } return $this->mouse; } @@ -388,7 +390,7 @@ public function getMouse() { */ public function getKeyboard() { if (!$this->keyboard) { - $this->keyboard = new RemoteKeyboard($this->executor); + $this->keyboard = new RemoteKeyboard($this->getExecuteMethod()); } return $this->keyboard; } @@ -398,11 +400,18 @@ public function getKeyboard() { */ public function getTouch() { if (!$this->touch) { - $this->touch = new RemoteTouchScreen($this->executor); + $this->touch = new RemoteTouchScreen($this->getExecuteMethod()); } return $this->touch; } + protected function getExecuteMethod() { + if (!$this->executeMethod) { + $this->executeMethod = new RemoteExecuteMethod($this); + } + return $this->executeMethod; + } + /** * Construct a new action builder. * @@ -418,7 +427,7 @@ public function action() { * @return RemoteWebElement */ public function getActiveElement() { - $response = $this->executor->execute(DriverCommand::GET_ACTIVE_ELEMENT); + $response = $this->execute(DriverCommand::GET_ACTIVE_ELEMENT); return $this->newElement($response['ELEMENT']); } @@ -429,7 +438,7 @@ public function getActiveElement() { * @return RemoteWebElement */ private function newElement($id) { - return new RemoteWebElement($this->executor, $id); + return new RemoteWebElement($this->getExecuteMethod(), $id); } /** @@ -459,12 +468,7 @@ public function getCommandExecutor() { * @return RemoteWebDriver */ public function setSessionID($session_id) { - $this->setCommandExecutor( - new HttpCommandExecutor( - $this->executor->getAddressOfRemoteServer(), - $session_id - ) - ); + $this->sessionID = $session_id; return $this; } @@ -474,6 +478,17 @@ public function setSessionID($session_id) { * @return string sessionID */ public function getSessionID() { - return $this->executor->getSessionID(); + return $this->sessionID; + } + + public function execute($command_name, $params = array()) { + $command = new WebDriverCommand( + $this->sessionID, + $command_name, + $params + ); + + $response = $this->executor->execute($command); + return $response->getValue(); } } diff --git a/lib/remote/RemoteWebElement.php b/lib/remote/RemoteWebElement.php index cc5549228..19d0f377a 100644 --- a/lib/remote/RemoteWebElement.php +++ b/lib/remote/RemoteWebElement.php @@ -19,7 +19,7 @@ class RemoteWebElement implements WebDriverElement, WebDriverLocatable { /** - * @var HttpCommandExecutor + * @var RemoteExecuteMethod */ protected $executor; /** @@ -32,10 +32,10 @@ class RemoteWebElement implements WebDriverElement, WebDriverLocatable { protected $fileDetector; /** - * @param HttpCommandExecutor $executor + * @param RemoteExecuteMethod $executor * @param string $id */ - public function __construct(HttpCommandExecutor $executor, $id) { + public function __construct(RemoteExecuteMethod $executor, $id) { $this->executor = $executor; $this->id = $id; $this->fileDetector = new UselessFileDetector(); diff --git a/lib/remote/WebDriverCommand.php b/lib/remote/WebDriverCommand.php new file mode 100644 index 000000000..d9d94c909 --- /dev/null +++ b/lib/remote/WebDriverCommand.php @@ -0,0 +1,39 @@ +sessionID = $session_id; + $this->name = $name; + $this->parameters = $parameters; + } + + public function getName() { + return $this->name; + } + + public function getSessionID() { + return $this->sessionID; + } + + public function getParameters() { + return $this->parameters; + } +} diff --git a/lib/support/events/EventFiringWebDriver.php b/lib/support/events/EventFiringWebDriver.php index b2a9b8b8e..07d0990b1 100644 --- a/lib/support/events/EventFiringWebDriver.php +++ b/lib/support/events/EventFiringWebDriver.php @@ -353,4 +353,12 @@ private function dispatchOnException($exception) { $this->dispatch('onException', $exception, $this); throw $exception; } + + public function execute($name, $params) { + try { + return $this->driver->execute($name, $params); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } } From 586bf32884c1a975b6cad64bf02bade98da914e8 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Mon, 2 Jun 2014 12:57:35 -0700 Subject: [PATCH 068/784] compatibility issue --- lib/remote/HttpCommandExecutor.php | 2 +- lib/remote/RemoteExecuteMethod.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index 0f8dc85ce..5d0249897 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -133,7 +133,7 @@ public function execute(WebDriverCommand $command) { */ public static function remoteExecute( WebDriverCommand $command, - string $url, + $url, array $curl_opts = array() ) { if (!isset(self::$commands[$command->getName()])) { diff --git a/lib/remote/RemoteExecuteMethod.php b/lib/remote/RemoteExecuteMethod.php index cc97f19b3..248627e81 100644 --- a/lib/remote/RemoteExecuteMethod.php +++ b/lib/remote/RemoteExecuteMethod.php @@ -15,7 +15,7 @@ class RemoteExecuteMethod implements ExecuteMethod { - private RemoteWebDriver $driver; + private $driver; /** * @param RemoteWebDriver $driver From bb9c3903c508df7cf920bed85fd8934ec71fecf5 Mon Sep 17 00:00:00 2001 From: whhone Date: Mon, 2 Jun 2014 15:25:06 -0700 Subject: [PATCH 069/784] wrong parameter when constructing TargetLocator --- lib/remote/RemoteWebDriver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index daf0bdfbf..c2959a09a 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -372,7 +372,7 @@ public function navigate() { * @see WebDriverTargetLocator */ public function switchTo() { - return new WebDriverTargetLocator($this->executor, $this); + return new WebDriverTargetLocator($this->getExecuteMethod(), $this); } /** From ca96c06ea8ea47fe951cb84a92424dccb4f1a755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=9A=D0=BE=D0=BB?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Tue, 3 Jun 2014 18:12:02 +0400 Subject: [PATCH 070/784] Alternative implementation of WebDriverCommandExecutor. --- lib/remote/CurlCommandExecutor.php | 237 +++++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 lib/remote/CurlCommandExecutor.php diff --git a/lib/remote/CurlCommandExecutor.php b/lib/remote/CurlCommandExecutor.php new file mode 100644 index 000000000..d7e354bfd --- /dev/null +++ b/lib/remote/CurlCommandExecutor.php @@ -0,0 +1,237 @@ + array('POST' => '/session/:sessionId/accept_alert'), + DriverCommand::ADD_COOKIE => array('POST' => '/session/:sessionId/cookie'), + DriverCommand::CLEAR_ELEMENT => array('POST' => '/session/:sessionId/element/:id/clear'), + DriverCommand::CLICK_ELEMENT => array('POST' => '/session/:sessionId/element/:id/click'), + DriverCommand::CLOSE => array('DELETE' => '/session/:sessionId/window'), + DriverCommand::DELETE_ALL_COOKIES => array('DELETE' => '/session/:sessionId/cookie'), + DriverCommand::DELETE_COOKIE => array('DELETE' => '/session/:sessionId/cookie/:name'), + DriverCommand::DISMISS_ALERT => array('POST' => '/session/:sessionId/dismiss_alert'), + DriverCommand::ELEMENT_EQUALS => array('GET' => '/session/:sessionId/element/:id/equals/:other'), + DriverCommand::FIND_CHILD_ELEMENT => array('POST' => '/session/:sessionId/element/:id/element'), + DriverCommand::FIND_CHILD_ELEMENTS => array('POST' => '/session/:sessionId/element/:id/elements'), + DriverCommand::EXECUTE_SCRIPT => array('POST' => '/session/:sessionId/execute'), + DriverCommand::EXECUTE_ASYNC_SCRIPT => array('POST' => '/session/:sessionId/execute_async'), + DriverCommand::FIND_ELEMENT => array('POST' => '/session/:sessionId/element'), + DriverCommand::FIND_ELEMENTS => array('POST' => '/session/:sessionId/elements'), + DriverCommand::SWITCH_TO_FRAME => array('POST' => '/session/:sessionId/frame'), + DriverCommand::SWITCH_TO_WINDOW => array('POST' => '/session/:sessionId/window'), + DriverCommand::GET => array('POST' => '/session/:sessionId/url'), + DriverCommand::GET_ACTIVE_ELEMENT => array('POST' => '/session/:sessionId/element/active'), + DriverCommand::GET_ALERT_TEXT => array('GET' => '/session/:sessionId/alert_text'), + DriverCommand::GET_ALL_COOKIES => array('GET' => '/session/:sessionId/cookie'), + DriverCommand::GET_AVAILABLE_LOG_TYPES => array('GET' => '/session/:sessionId/log/types'), + DriverCommand::GET_CURRENT_URL => array('GET' => '/session/:sessionId/url'), + DriverCommand::GET_CURRENT_WINDOW_HANDLE => array('GET' => '/session/:sessionId/window_handle'), + DriverCommand::GET_ELEMENT_ATTRIBUTE => array('GET' => '/session/:sessionId/element/:id/attribute/:name'), + DriverCommand::GET_ELEMENT_VALUE_OF_CSS_PROPERTY => array('GET' => '/session/:sessionId/element/:id/css/:propertyName'), + DriverCommand::GET_ELEMENT_LOCATION => array('GET' => '/session/:sessionId/element/:id/location'), + DriverCommand::GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW => array('GET' => '/session/:sessionId/element/:id/location_in_view'), + DriverCommand::GET_ELEMENT_SIZE => array('GET' => '/session/:sessionId/element/:id/size'), + DriverCommand::GET_ELEMENT_TAG_NAME => array('GET' => '/session/:sessionId/element/:id/name'), + DriverCommand::GET_ELEMENT_TEXT => array('GET' => '/session/:sessionId/element/:id/text'), + DriverCommand::GET_LOG => array('POST' => '/session/:sessionId/log'), + DriverCommand::GET_PAGE_SOURCE => array('GET' => '/session/:sessionId/source'), + DriverCommand::GET_SCREEN_ORIENTATION => array('GET' => '/session/:sessionId/orientation'), + DriverCommand::GET_CAPABILITIES => array('GET' => '/session/:sessionId'), + DriverCommand::GET_TITLE => array('GET' => '/session/:sessionId/title'), + DriverCommand::GET_WINDOW_HANDLES => array('GET' => '/session/:sessionId/window_handles'), + DriverCommand::GET_WINDOW_POSITION => array('GET' => '/session/:sessionId/window/:windowHandle/position'), + DriverCommand::GET_WINDOW_SIZE => array('GET' => '/session/:sessionId/window/:windowHandle/size'), + DriverCommand::GO_BACK => array('POST' => '/session/:sessionId/back'), + DriverCommand::GO_FORWARD => array('POST' => '/session/:sessionId/forward'), + DriverCommand::IS_ELEMENT_DISPLAYED => array('GET' => '/session/:sessionId/element/:id/displayed'), + DriverCommand::IS_ELEMENT_ENABLED => array('GET' => '/session/:sessionId/element/:id/enabled'), + DriverCommand::IS_ELEMENT_SELECTED => array('GET' => '/session/:sessionId/element/:id/selected'), + DriverCommand::MAXIMIZE_WINDOW => array('POST' => '/session/:sessionId/window/:windowHandle/maximize'), + DriverCommand::MOUSE_DOWN => array('POST' => '/session/:sessionId/buttondown'), + DriverCommand::MOUSE_UP => array('POST' => '/session/:sessionId/buttonup'), + DriverCommand::CLICK => array('POST' => '/session/:sessionId/click'), + DriverCommand::DOUBLE_CLICK => array('POST' => '/session/:sessionId/doubleclick'), + DriverCommand::MOVE_TO => array('POST' => '/session/:sessionId/moveto'), + DriverCommand::NEW_SESSION => array('POST' => '/session'), + DriverCommand::QUIT => array('DELETE' => '/session/:sessionId'), + DriverCommand::REFRESH => array('POST' => '/session/:sessionId/refresh'), + DriverCommand::UPLOAD_FILE => array('POST' => '/session/:sessionId/file'), // undocumented + DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT => array('POST' => '/session/:sessionId/keys'), + DriverCommand::SET_ALERT_VALUE => array('POST' => '/session/:sessionId/alert_text'), + DriverCommand::SEND_KEYS_TO_ELEMENT => array('POST' => '/session/:sessionId/element/:id/value'), + DriverCommand::IMPLICITLY_WAIT => array('POST' => '/session/:sessionId/timeouts/implicit_wait'), + DriverCommand::SET_SCREEN_ORIENTATION => array('POST' => '/session/:sessionId/orientation'), + DriverCommand::SET_TIMEOUT => array('POST' => '/session/:sessionId/timeouts'), + DriverCommand::SET_SCRIPT_TIMEOUT => array('POST' => '/session/:sessionId/timeouts/async_script'), + DriverCommand::SET_WINDOW_POSITION => array('POST' => '/session/:sessionId/window/:windowHandle/position'), + DriverCommand::SET_WINDOW_SIZE => array('POST' => '/session/:sessionId/window/:windowHandle/size'), + DriverCommand::SUBMIT_ELEMENT => array('POST' => '/session/:sessionId/element/:id/submit'), + DriverCommand::SCREENSHOT => array('GET' => '/session/:sessionId/screenshot'), + DriverCommand::TOUCH_SINGLE_TAP => array('POST' => '/session/:sessionId/touch/click'), + DriverCommand::TOUCH_DOWN => array('POST' => '/session/:sessionId/touch/down'), + DriverCommand::TOUCH_DOUBLE_TAP => array('POST' => '/session/:sessionId/touch/doubleclick'), + DriverCommand::TOUCH_FLICK => array('POST' => '/session/:sessionId/touch/flick'), + DriverCommand::TOUCH_LONG_PRESS => array('POST' => '/session/:sessionId/touch/longclick'), + DriverCommand::TOUCH_MOVE => array('POST' => '/session/:sessionId/touch/move'), + DriverCommand::TOUCH_SCROLL => array('POST' => '/session/:sessionId/touch/scroll'), + DriverCommand::TOUCH_UP => array('POST' => '/session/:sessionId/touch/up'), + ); + + /** + * @var string + */ + protected $url; + /** + * @var string + */ + protected $sessionID; + /** + * @var resource + */ + protected $curl; + + /** + * @param string $url + */ + public function __construct($url = 'http://localhost:4444/wd/hub') + { + $this->url = $url; + $this->curl = curl_init(); + curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT_MS, 300000); + curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); + curl_setopt( + $this->curl, + CURLOPT_HTTPHEADER, + array('Content-Type: application/json;charset=UTF-8', 'Accept: application/json') + ); + } + + /** + * Set connection timeout in ms. + * + * @param int $timeout + */ + public function setTimeout($timeout) + { + curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT_MS, $timeout); + } + + /** + * @param string $sessionID + */ + public function setSessionID($sessionID) + { + $this->sessionID = $sessionID; + } + + /** + * @param $command + * @param array $params + * + * @throws InvalidArgumentException + * @throws BadMethodCallException + * @return mixed + */ + public function execute($command, array $params = array()) + { + if (empty($this->commands[$command])) { + throw new InvalidArgumentException(sprintf('Command %s is unknown.', $command)); + } + reset($this->commands[$command]); + list($method, $url) = each($this->commands[$command]); + $url = str_replace(':sessionId', $this->sessionID, $url); + foreach ($params as $name => $value) { + if ($name[0] === ':') { + $url = str_replace($name, $value, $url); + if ($method !== 'POST') { + unset($params[$name]); + } + } + } + if (!empty($params) && $method !== 'POST') { + throw new BadMethodCallException(sprintf( + 'The http method called for %s is %s but it has to be POST' . + ' if you want to pass the JSON params %s', + $url, + $method, + json_encode($params) + )); + } + curl_setopt($this->curl, CURLOPT_URL, $url); + + if ($method === 'GET') { + curl_setopt($this->curl, CURLOPT_HTTPGET, true); + } elseif ($method === 'POST') { + curl_setopt($this->curl, CURLOPT_POST, true); + if ($params && is_array($params)) { + curl_setopt($this->curl, CURLOPT_POSTFIELDS, json_encode($params)); + } + } elseif ($method == 'DELETE') { + curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); + } + + $raw_results = trim(curl_exec($this->curl)); + + if ($error = curl_error($this->curl)) { + $msg = sprintf( + 'Curl error thrown for http %s to %s', + $method, + $url + ); + if ($params && is_array($params)) { + $msg .= sprintf(' with params: %s', json_encode($params)); + } + WebDriverException::throwException(-1, $msg . "\n\n" . $error, array()); + } + + curl_setopt($this->curl, CURLOPT_POSTFIELDS, null); + curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, null); + + $results = json_decode($raw_results, true); + + $value = null; + if (is_array($results) && array_key_exists('value', $results)) { + $value = $results['value']; + } + + $message = null; + if (is_array($value) && array_key_exists('message', $value)) { + $message = $value['message']; + } + + $sessionId = null; + if (is_array($results) && array_key_exists('sessionId', $results)) { + $sessionId = $results['sessionId']; + } + + $status = isset($results['status']) ? $results['status'] : 0; + WebDriverException::throwException($status, $message, $results); + + $response = new WebDriverResponse($sessionId); + + return $response + ->setStatus($status) + ->setValue($value); + } +} From 94e58fec69aa9291ddba528c8e3ab18bd0e06e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=9A=D0=BE=D0=BB?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Tue, 3 Jun 2014 18:18:15 +0400 Subject: [PATCH 071/784] Update phpdoc. --- lib/remote/CurlCommandExecutor.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/remote/CurlCommandExecutor.php b/lib/remote/CurlCommandExecutor.php index d7e354bfd..c755adafa 100644 --- a/lib/remote/CurlCommandExecutor.php +++ b/lib/remote/CurlCommandExecutor.php @@ -151,7 +151,7 @@ public function setSessionID($sessionID) * * @throws InvalidArgumentException * @throws BadMethodCallException - * @return mixed + * @return WebDriverResponse */ public function execute($command, array $params = array()) { @@ -230,8 +230,6 @@ public function execute($command, array $params = array()) $response = new WebDriverResponse($sessionId); - return $response - ->setStatus($status) - ->setValue($value); + return $response->setStatus($status)->setValue($value); } } From 83f61b29bb858649094ec1ecbed43444086db558 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Tue, 10 Jun 2014 11:44:40 -0700 Subject: [PATCH 072/784] kill static method HttpCommandExecutor::remoteExcute --- lib/remote/HttpCommandExecutor.php | 28 +++++------------------- lib/remote/RemoteWebDriver.php | 34 ++++++++---------------------- 2 files changed, 14 insertions(+), 48 deletions(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index 5d0249897..08a6c685b 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -113,41 +113,23 @@ public function __construct($url) { /** * @param WebDriverCommand $command - * - * @return mixed - */ - public function execute(WebDriverCommand $command) { - $response = self::remoteExecute($command, $this->url); - return $response; - } - - /** - * This method is deprecated. - * Execute a command on a remote server. - * - * @param WebDriverCommand * @param array $curl_opts An array of curl options. * - * @return array The response of the command. - * @throws Exception + * @return mixed */ - public static function remoteExecute( - WebDriverCommand $command, - $url, - array $curl_opts = array() - ) { + public function execute(WebDriverCommand $command, $curl_opts = array()) { if (!isset(self::$commands[$command->getName()])) { throw new Exception($command->getName()." is not a valid command."); } $raw = self::$commands[$command->getName()]; - if ($command->getName() == DriverCommand::NEW_SESSION) { + if ($command->getName() === DriverCommand::NEW_SESSION) { $curl_opts[CURLOPT_FOLLOWLOCATION] = true; } return self::curl( $raw['method'], - sprintf("%s%s", $url, $raw['url']), + sprintf("%s%s", $this->url, $raw['url']), $command, $curl_opts ); @@ -210,7 +192,7 @@ protected static function curl( if ($params && is_array($params)) { curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($params)); } - } else if ($http_method == 'DELETE') { + } else if ($http_method === 'DELETE') { curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); } diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index c2959a09a..9d476cc64 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -62,23 +62,25 @@ public static function create( $desired_capabilities = $desired_capabilities->toArray(); } + $executor = new HttpCommandExecutor($url); + $command = new WebDriverCommand( null, DriverCommand::NEW_SESSION, array('desiredCapabilities' => $desired_capabilities) ); - $response = static::remoteExecuteHttpCommand( - $timeout_in_ms, + $response = $executor->execute( $command, - $url + array( + CURLOPT_CONNECTTIMEOUT_MS => $timeout_in_ms, + ) ); $driver = new static(); - $driver->setSessionID($response->getSessionID()); - $executor = new HttpCommandExecutor($url); - - return $driver->setCommandExecutor($executor); + $driver->setSessionID($response->getSessionID()) + ->setCommandExecutor($executor); + return $driver; } /** @@ -102,24 +104,6 @@ public static function createBySessionID( return $driver; } - /** - * @param int $timeout_in_ms - * @param array $command - * @return array - */ - public static function remoteExecuteHttpCommand( - $timeout_in_ms, $command, $url - ) { - $response = HttpCommandExecutor::remoteExecute( - $command, - $url, - array( - CURLOPT_CONNECTTIMEOUT_MS => $timeout_in_ms, - ) - ); - return $response; - } - /** * Close the current window. * From d626d8bd5460c07e4716972756876ba6bccf04f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=9A=D0=BE=D0=BB?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Wed, 11 Jun 2014 17:32:55 +0400 Subject: [PATCH 073/784] Fix URL. --- lib/remote/CurlCommandExecutor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/remote/CurlCommandExecutor.php b/lib/remote/CurlCommandExecutor.php index c755adafa..073ffd471 100644 --- a/lib/remote/CurlCommandExecutor.php +++ b/lib/remote/CurlCommandExecutor.php @@ -178,7 +178,7 @@ public function execute($command, array $params = array()) json_encode($params) )); } - curl_setopt($this->curl, CURLOPT_URL, $url); + curl_setopt($this->curl, CURLOPT_URL, $this->url . $url); if ($method === 'GET') { curl_setopt($this->curl, CURLOPT_HTTPGET, true); From a7250a37c0953ccabd521f8cb914eb793524fa26 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Wed, 11 Jun 2014 15:36:50 -0700 Subject: [PATCH 074/784] remove redundent curl options Thanks komex@github for pointing it out in pull request 150. --- lib/remote/HttpCommandExecutor.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index 08a6c685b..9b19f4948 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -123,10 +123,6 @@ public function execute(WebDriverCommand $command, $curl_opts = array()) { } $raw = self::$commands[$command->getName()]; - if ($command->getName() === DriverCommand::NEW_SESSION) { - $curl_opts[CURLOPT_FOLLOWLOCATION] = true; - } - return self::curl( $raw['method'], sprintf("%s%s", $this->url, $raw['url']), From 41d5e9f2f9c6c8f8efc2d146a9bde8809342a6f1 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Mon, 16 Jun 2014 11:29:11 -0700 Subject: [PATCH 075/784] ChromeDriver putenv("webdriver.chrome.driver=/path/to/the/chrome_driver"); $driver = new ChromeDriver(); --- lib/__init__.php | 11 ++ lib/chrome/ChromeDriver.php | 43 ++++++ lib/chrome/ChromeDriverService.php | 29 ++++ lib/net/URLChecker.php | 72 ++++++++++ lib/remote/HttpCommandExecutor.php | 1 - lib/remote/service/DriverCommandExecutor.php | 57 ++++++++ lib/remote/service/DriverService.php | 144 +++++++++++++++++++ 7 files changed, 356 insertions(+), 1 deletion(-) create mode 100644 lib/chrome/ChromeDriver.php create mode 100644 lib/chrome/ChromeDriverService.php create mode 100644 lib/net/URLChecker.php create mode 100644 lib/remote/service/DriverCommandExecutor.php create mode 100644 lib/remote/service/DriverService.php diff --git a/lib/__init__.php b/lib/__init__.php index f6843eefa..d10dd12ca 100755 --- a/lib/__init__.php +++ b/lib/__init__.php @@ -31,6 +31,8 @@ require_once('remote/WebDriverCommand.php'); +require_once('net/URLChecker.php'); + // class require_once('WebDriverAlert.php'); require_once('WebDriverBy.php'); @@ -70,14 +72,23 @@ require_once('remote/UselessFileDetector.php'); require_once('remote/RemoteMouse.php'); require_once('remote/RemoteKeyboard.php'); + +require_once('remote/service/DriverService.php'); +require_once('chrome/ChromeDriverService.php'); + require_once('remote/RemoteWebDriver.php'); +require_once('chrome/ChromeDriver.php'); + require_once('remote/RemoteWebElement.php'); require_once('remote/RemoteExecuteMethod.php'); require_once('remote/WebDriverBrowserType.php'); require_once('remote/WebDriverCapabilityType.php'); require_once('remote/DesiredCapabilities.php'); require_once('remote/WebDriverResponse.php'); + require_once('remote/HttpCommandExecutor.php'); +require_once('remote/service/DriverCommandExecutor.php'); + require_once('interactions/internal/WebDriverSendKeysAction.php'); require_once('interactions/internal/WebDriverKeyDownAction.php'); require_once('interactions/internal/WebDriverKeyUpAction.php'); diff --git a/lib/chrome/ChromeDriver.php b/lib/chrome/ChromeDriver.php new file mode 100644 index 000000000..fa7927f5b --- /dev/null +++ b/lib/chrome/ChromeDriver.php @@ -0,0 +1,43 @@ +setCommandExecutor($executor) + ->startSession($desired_capabilities); + return $driver; + } + + public function startSession($desired_capabilities) { + $command = new WebDriverCommand( + null, + DriverCommand::NEW_SESSION, + array( + 'desiredCapabilities' => $desired_capabilities->toArray(), + ) + ); + $response = $this->executor->execute($command); + $this->setSessionID($response->getSessionID()); + } +} diff --git a/lib/chrome/ChromeDriverService.php b/lib/chrome/ChromeDriverService.php new file mode 100644 index 000000000..c4de774e7 --- /dev/null +++ b/lib/chrome/ChromeDriverService.php @@ -0,0 +1,29 @@ + microtime(true)) { + if ($this->getHTTPResponseCode($timeout_in_ms, $url) === 200) { + return $this; + } + usleep(self::POLL_INTERVAL_MS); + } + + throw new TimeOutException(sprintf( + "Timed out waiting for %s to become available after %d ms.", + $url, + $timeout_in_ms + )); + + return $this; + } + + public function waitUntilUnavailable($timeout_in_ms, $url) { + $end = microtime(true) + $timeout_in_ms / 1000; + + while ($end > microtime(true)) { + if ($this->getHTTPResponseCode($timeout_in_ms, $url) !== 200) { + return $this; + } + usleep(self::POLL_INTERVAL_MS); + } + + throw new TimeOutException(sprintf( + "Timed out waiting for %s to become unavailable after %d ms.", + $url, + $timeout_in_ms + )); + } + + private function getHTTPResponseCode($timeout_in_ms, $url) { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, self::CONNECT_TIMEOUT_MS); + $code = null; + try { + curl_exec($ch); + $info = curl_getinfo($ch); + $code = $info['http_code']; + } catch (Exception $e) { + } + curl_close($ch); + return $code; + } +} diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index 9b19f4948..05335600a 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -105,7 +105,6 @@ class HttpCommandExecutor implements WebDriverCommandExecutor { /** * @param string $url - * @param string $session_id */ public function __construct($url) { $this->url = $url; diff --git a/lib/remote/service/DriverCommandExecutor.php b/lib/remote/service/DriverCommandExecutor.php new file mode 100644 index 000000000..51cdda466 --- /dev/null +++ b/lib/remote/service/DriverCommandExecutor.php @@ -0,0 +1,57 @@ +getURL()); + $this->service = $service; + } + + /** + * @param WebDriverCommand $command + * @param array $curl_opts + * + * @return mixed + */ + public function execute(WebDriverCommand $command, $curl_opts = array()) { + if ($command->getName() === DriverCommand::NEW_SESSION) { + $this->service->start(); + } + + try { + $value = parent::execute($command, $curl_opts); + if ($command->getName() === DriverCommand::QUIT) { + $this->service->stop(); + } + return $value; + } catch (Exception $e) { + if (!$this->service->isRunning()) { + throw new WebDriverException('The driver server has died.'); + } + throw $e; + } + } + +} diff --git a/lib/remote/service/DriverService.php b/lib/remote/service/DriverService.php new file mode 100644 index 000000000..b8ba78831 --- /dev/null +++ b/lib/remote/service/DriverService.php @@ -0,0 +1,144 @@ +executable = self::checkExecutable($executable); + $this->url = sprintf('http://localhost:%d', $port); + $this->args = $args; + + if ($environment === null) { + $this->environment = $_ENV; + } else { + $this->environment = $environment; + } + } + + /** + * @return string + */ + public function getURL() { + return $this->url; + } + + /** + * @return DriverService + */ + public function start() { + if ($this->process !== null) { + return $this; + } + + $pipes = array(); + $this->process = proc_open( + sprintf("%s %s", $this->executable, implode(' ', $this->args)), + $descriptorspec = array( + 0 => array('pipe', 'r'), // stdin + 1 => array('pipe', 'w'), // stdout + 2 => array('pipe', 'a'), // stderr + ), + $pipes, + null, + $this->environment + ); + + $checker = new URLChecker(); + $checker->waitUntilAvailable(20 * 1000, $this->url.'/status'); + + return $this; + } + + /** + * @return DriverService + */ + public function stop() { + if ($this->process === null) { + return $this; + } + + proc_terminate($this->process); + $this->process = null; + + $checker = new URLChecker(); + $checker->waitUntilUnAvailable(3 * 1000, $this->url.'/shutdown'); + + return $this; + } + + /** + * @return bool + */ + public function isRunning() { + if ($this->process === null) { + return false; + } + + $status = proc_get_status($this->process); + return $status['running']; + } + + /** + * Check if the executable is executable. + * + * @param string $executable + * @return string + * @throws Exception + */ + protected static function checkExecutable($executable) { + if (!is_file($executable)) { + throw new Exception("'$executable' is not a file."); + } else if (!is_executable($executable)) { + throw new Exception("'$executable' is not executable."); + } + return $executable; + } +} From 6e3a5b632b208da4c0c484d3fe885496b8d80a56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Wollse=CC=81n?= Date: Wed, 2 Jul 2014 16:12:36 +0300 Subject: [PATCH 076/784] Throw exception when json_decode() of remote response fails --- lib/remote/HttpCommandExecutor.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index 05335600a..8a68c99dd 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -211,6 +211,10 @@ protected static function curl( $results = json_decode($raw_results, true); + if ($results === null && json_last_error() !== JSON_ERROR_NONE) { + throw new WebDriverException('JSON decoding of remote response failed. The response: \'' . $raw_results . '\''); + } + $value = null; if (is_array($results) && array_key_exists('value', $results)) { $value = $results['value']; From 3e08f353b8cef15f23591bb50cf788514eaf34bd Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Mon, 7 Jul 2014 14:25:13 -0700 Subject: [PATCH 077/784] RemoteWebDriverTest with php 5.3 --- tests/unit/remote/RemoteWebDriverTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/unit/remote/RemoteWebDriverTest.php b/tests/unit/remote/RemoteWebDriverTest.php index c53b4fcbe..5221b7079 100644 --- a/tests/unit/remote/RemoteWebDriverTest.php +++ b/tests/unit/remote/RemoteWebDriverTest.php @@ -25,9 +25,9 @@ public function testCreate() { $timeout = 1000; $url = 'http://localhost:4444/wd/hub'; $response = array('value' => 'someValue', 'info' => 'someInfo', 'sessionId' => 'someSessionId'); - $response = (new WebDriverResponse('someSessionId')) - ->setStatus(0) - ->setValue('someValue'); + $response = new WebDriverResponse('someSessionId'); + $response->setStatus(0) + ->setValue('someValue'); $executor = $this->getMockBuilder('HttpCommandExecutor')->disableOriginalConstructor()->getMock(); From c3ccf9dc288851a5016d0a4b05541356609cc112 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Tue, 8 Jul 2014 09:48:16 -0700 Subject: [PATCH 078/784] php strict standards error in ChromeDriver ChromeDriver extends RemoteWebDriver. However, the create method is not compatible because ChromeDriver does not require the address of a remote server. phpfail.... In addition, throw exception when calling invalid parent method. --- lib/chrome/ChromeDriver.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/chrome/ChromeDriver.php b/lib/chrome/ChromeDriver.php index fa7927f5b..7f85d8a81 100644 --- a/lib/chrome/ChromeDriver.php +++ b/lib/chrome/ChromeDriver.php @@ -15,7 +15,7 @@ class ChromeDriver extends RemoteWebDriver { - public static function create( + public static function start( DesiredCapabilities $desired_capabilities = null ) { if ($desired_capabilities === null) { @@ -40,4 +40,12 @@ public function startSession($desired_capabilities) { $response = $this->executor->execute($command); $this->setSessionID($response->getSessionID()); } + + public static function create() { + throw new WebDriverException('Please use ChromeDriver::start() instead.'); + } + + public static function createBySessionID() { + throw new WebDriverException('Please use ChromeDriver::start() instead.'); + } } From d3a3544fc7f7419e4a02aa0507e154cb63cfb6e4 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Tue, 8 Jul 2014 09:50:26 -0700 Subject: [PATCH 079/784] removing unnecessary abstract method --- lib/interactions/internal/WebDriverSingleKeyAction.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/interactions/internal/WebDriverSingleKeyAction.php b/lib/interactions/internal/WebDriverSingleKeyAction.php index f8c96bb81..aa450e0d8 100644 --- a/lib/interactions/internal/WebDriverSingleKeyAction.php +++ b/lib/interactions/internal/WebDriverSingleKeyAction.php @@ -27,9 +27,4 @@ public function __construct( parent::__construct($keyboard, $mouse, $location_provider); $this->key = $key; } - - /** - * @return void - */ - abstract public function perform(); } From 1c1d056c49fcabbeb6afc6e66621983470ca42f1 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Tue, 8 Jul 2014 10:26:16 -0700 Subject: [PATCH 080/784] remove legacy test The methods to be tested are removed for a while. --- tests/unit/remote/RemoteWebDriverTest.php | 51 ----------------------- 1 file changed, 51 deletions(-) delete mode 100644 tests/unit/remote/RemoteWebDriverTest.php diff --git a/tests/unit/remote/RemoteWebDriverTest.php b/tests/unit/remote/RemoteWebDriverTest.php deleted file mode 100644 index 5221b7079..000000000 --- a/tests/unit/remote/RemoteWebDriverTest.php +++ /dev/null @@ -1,51 +0,0 @@ -getMockBuilder('RemoteWebDriver') - ->disableOriginalConstructor() - ->setMethods(array('remoteExecuteHttpCommand', 'createHttpCommandExecutor')) - ->getMock() - ; - - $timeout = 1000; - $url = 'http://localhost:4444/wd/hub'; - $response = array('value' => 'someValue', 'info' => 'someInfo', 'sessionId' => 'someSessionId'); - $response = new WebDriverResponse('someSessionId'); - $response->setStatus(0) - ->setValue('someValue'); - - $executor = $this->getMockBuilder('HttpCommandExecutor')->disableOriginalConstructor()->getMock(); - - $remoteWebDriver - ->staticExpects($this->once()) - ->method('remoteExecuteHttpCommand') - ->with($timeout, array('url' => $url, 'name' => 'newSession', 'parameters' => array('desiredCapabilities' => array()))) - ->will($this->returnValue($response)) - ; - - $remoteWebDriver - ->staticExpects($this->once()) - ->method('createHttpCommandExecutor') - ->with($url, $response->getSessionID()) - ->will($this->returnValue($executor)) - ; - - $remoteWebDriver->create($url, array(), $timeout); - } -} - From 9533d8048d07bd4a881fc5d4c51f4d5fe1786585 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Fri, 11 Jul 2014 21:04:06 -0700 Subject: [PATCH 081/784] use phpdoc to generate docs The documentation is hosted on facebook.github.io/php-webdriver --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 3af7435c8..6a22de87b 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,8 @@ "php": ">=5.3.19" }, "require-dev": { - "phpunit/phpunit": "3.7.*" + "phpunit/phpunit": "3.7.*", + ""phpdocumentor/phpdocumentor": "2.*"" }, "autoload": { "classmap": ["lib/"] From 1c36faa2823ddb8dab81d380032d7ead12c600e8 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Fri, 11 Jul 2014 21:08:38 -0700 Subject: [PATCH 082/784] Update README.md Link to documentation. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 897a2df48..d5272c4f4 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ php-webdriver -- WebDriver bindings for PHP This WebDriver client aims to be as close as possible to bindings in other languages. The concepts are very similar to the Java, .NET, Python and Ruby bindings for WebDriver. -Looking for documentation about Selenium WebDriver? See http://docs.seleniumhq.org/docs/ and https://code.google.com/p/selenium/wiki +Looking for documentation about php-webdriver? See http://facebook.github.io/php-webdriver/ The PHP client was rewritten from scratch. Using the old version? Check out Adam Goucher's fork of it at https://github.com/Element-34/php-webdriver From f117bbee7176ebb3552fffcd1c5a50430d28a12d Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Fri, 11 Jul 2014 22:21:40 -0700 Subject: [PATCH 083/784] fix --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 6a22de87b..00faaa7bf 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ }, "require-dev": { "phpunit/phpunit": "3.7.*", - ""phpdocumentor/phpdocumentor": "2.*"" + "phpdocumentor/phpdocumentor": "2.*" }, "autoload": { "classmap": ["lib/"] From 1096e1786b2733069c220ff9c7a7ebebe64afdc2 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Thu, 17 Jul 2014 16:24:21 -0700 Subject: [PATCH 084/784] use travis-ci --- .travis.yml | 8 ++++++++ tests/unit/bootstrap.php | 3 +++ tests/unit/phpunit.xml | 22 ++++++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 .travis.yml create mode 100644 tests/unit/bootstrap.php create mode 100644 tests/unit/phpunit.xml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..1342b9d4b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,8 @@ +language: php +php: + - 5.3 + - 5.4 + - 5.5 + - hhvm + +script: phpunit -c ./tests/unit diff --git a/tests/unit/bootstrap.php b/tests/unit/bootstrap.php new file mode 100644 index 000000000..562467964 --- /dev/null +++ b/tests/unit/bootstrap.php @@ -0,0 +1,3 @@ + + + + + + + + ../unit + + + + From 47ae4ab1e1ec1d301c1ab1a244b60cfcb6053e41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=9A=D0=BE=D0=BB?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Tue, 3 Jun 2014 18:12:02 +0400 Subject: [PATCH 085/784] Alternative implementation of WebDriverCommandExecutor. --- lib/remote/CurlCommandExecutor.php | 237 +++++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 lib/remote/CurlCommandExecutor.php diff --git a/lib/remote/CurlCommandExecutor.php b/lib/remote/CurlCommandExecutor.php new file mode 100644 index 000000000..d7e354bfd --- /dev/null +++ b/lib/remote/CurlCommandExecutor.php @@ -0,0 +1,237 @@ + array('POST' => '/session/:sessionId/accept_alert'), + DriverCommand::ADD_COOKIE => array('POST' => '/session/:sessionId/cookie'), + DriverCommand::CLEAR_ELEMENT => array('POST' => '/session/:sessionId/element/:id/clear'), + DriverCommand::CLICK_ELEMENT => array('POST' => '/session/:sessionId/element/:id/click'), + DriverCommand::CLOSE => array('DELETE' => '/session/:sessionId/window'), + DriverCommand::DELETE_ALL_COOKIES => array('DELETE' => '/session/:sessionId/cookie'), + DriverCommand::DELETE_COOKIE => array('DELETE' => '/session/:sessionId/cookie/:name'), + DriverCommand::DISMISS_ALERT => array('POST' => '/session/:sessionId/dismiss_alert'), + DriverCommand::ELEMENT_EQUALS => array('GET' => '/session/:sessionId/element/:id/equals/:other'), + DriverCommand::FIND_CHILD_ELEMENT => array('POST' => '/session/:sessionId/element/:id/element'), + DriverCommand::FIND_CHILD_ELEMENTS => array('POST' => '/session/:sessionId/element/:id/elements'), + DriverCommand::EXECUTE_SCRIPT => array('POST' => '/session/:sessionId/execute'), + DriverCommand::EXECUTE_ASYNC_SCRIPT => array('POST' => '/session/:sessionId/execute_async'), + DriverCommand::FIND_ELEMENT => array('POST' => '/session/:sessionId/element'), + DriverCommand::FIND_ELEMENTS => array('POST' => '/session/:sessionId/elements'), + DriverCommand::SWITCH_TO_FRAME => array('POST' => '/session/:sessionId/frame'), + DriverCommand::SWITCH_TO_WINDOW => array('POST' => '/session/:sessionId/window'), + DriverCommand::GET => array('POST' => '/session/:sessionId/url'), + DriverCommand::GET_ACTIVE_ELEMENT => array('POST' => '/session/:sessionId/element/active'), + DriverCommand::GET_ALERT_TEXT => array('GET' => '/session/:sessionId/alert_text'), + DriverCommand::GET_ALL_COOKIES => array('GET' => '/session/:sessionId/cookie'), + DriverCommand::GET_AVAILABLE_LOG_TYPES => array('GET' => '/session/:sessionId/log/types'), + DriverCommand::GET_CURRENT_URL => array('GET' => '/session/:sessionId/url'), + DriverCommand::GET_CURRENT_WINDOW_HANDLE => array('GET' => '/session/:sessionId/window_handle'), + DriverCommand::GET_ELEMENT_ATTRIBUTE => array('GET' => '/session/:sessionId/element/:id/attribute/:name'), + DriverCommand::GET_ELEMENT_VALUE_OF_CSS_PROPERTY => array('GET' => '/session/:sessionId/element/:id/css/:propertyName'), + DriverCommand::GET_ELEMENT_LOCATION => array('GET' => '/session/:sessionId/element/:id/location'), + DriverCommand::GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW => array('GET' => '/session/:sessionId/element/:id/location_in_view'), + DriverCommand::GET_ELEMENT_SIZE => array('GET' => '/session/:sessionId/element/:id/size'), + DriverCommand::GET_ELEMENT_TAG_NAME => array('GET' => '/session/:sessionId/element/:id/name'), + DriverCommand::GET_ELEMENT_TEXT => array('GET' => '/session/:sessionId/element/:id/text'), + DriverCommand::GET_LOG => array('POST' => '/session/:sessionId/log'), + DriverCommand::GET_PAGE_SOURCE => array('GET' => '/session/:sessionId/source'), + DriverCommand::GET_SCREEN_ORIENTATION => array('GET' => '/session/:sessionId/orientation'), + DriverCommand::GET_CAPABILITIES => array('GET' => '/session/:sessionId'), + DriverCommand::GET_TITLE => array('GET' => '/session/:sessionId/title'), + DriverCommand::GET_WINDOW_HANDLES => array('GET' => '/session/:sessionId/window_handles'), + DriverCommand::GET_WINDOW_POSITION => array('GET' => '/session/:sessionId/window/:windowHandle/position'), + DriverCommand::GET_WINDOW_SIZE => array('GET' => '/session/:sessionId/window/:windowHandle/size'), + DriverCommand::GO_BACK => array('POST' => '/session/:sessionId/back'), + DriverCommand::GO_FORWARD => array('POST' => '/session/:sessionId/forward'), + DriverCommand::IS_ELEMENT_DISPLAYED => array('GET' => '/session/:sessionId/element/:id/displayed'), + DriverCommand::IS_ELEMENT_ENABLED => array('GET' => '/session/:sessionId/element/:id/enabled'), + DriverCommand::IS_ELEMENT_SELECTED => array('GET' => '/session/:sessionId/element/:id/selected'), + DriverCommand::MAXIMIZE_WINDOW => array('POST' => '/session/:sessionId/window/:windowHandle/maximize'), + DriverCommand::MOUSE_DOWN => array('POST' => '/session/:sessionId/buttondown'), + DriverCommand::MOUSE_UP => array('POST' => '/session/:sessionId/buttonup'), + DriverCommand::CLICK => array('POST' => '/session/:sessionId/click'), + DriverCommand::DOUBLE_CLICK => array('POST' => '/session/:sessionId/doubleclick'), + DriverCommand::MOVE_TO => array('POST' => '/session/:sessionId/moveto'), + DriverCommand::NEW_SESSION => array('POST' => '/session'), + DriverCommand::QUIT => array('DELETE' => '/session/:sessionId'), + DriverCommand::REFRESH => array('POST' => '/session/:sessionId/refresh'), + DriverCommand::UPLOAD_FILE => array('POST' => '/session/:sessionId/file'), // undocumented + DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT => array('POST' => '/session/:sessionId/keys'), + DriverCommand::SET_ALERT_VALUE => array('POST' => '/session/:sessionId/alert_text'), + DriverCommand::SEND_KEYS_TO_ELEMENT => array('POST' => '/session/:sessionId/element/:id/value'), + DriverCommand::IMPLICITLY_WAIT => array('POST' => '/session/:sessionId/timeouts/implicit_wait'), + DriverCommand::SET_SCREEN_ORIENTATION => array('POST' => '/session/:sessionId/orientation'), + DriverCommand::SET_TIMEOUT => array('POST' => '/session/:sessionId/timeouts'), + DriverCommand::SET_SCRIPT_TIMEOUT => array('POST' => '/session/:sessionId/timeouts/async_script'), + DriverCommand::SET_WINDOW_POSITION => array('POST' => '/session/:sessionId/window/:windowHandle/position'), + DriverCommand::SET_WINDOW_SIZE => array('POST' => '/session/:sessionId/window/:windowHandle/size'), + DriverCommand::SUBMIT_ELEMENT => array('POST' => '/session/:sessionId/element/:id/submit'), + DriverCommand::SCREENSHOT => array('GET' => '/session/:sessionId/screenshot'), + DriverCommand::TOUCH_SINGLE_TAP => array('POST' => '/session/:sessionId/touch/click'), + DriverCommand::TOUCH_DOWN => array('POST' => '/session/:sessionId/touch/down'), + DriverCommand::TOUCH_DOUBLE_TAP => array('POST' => '/session/:sessionId/touch/doubleclick'), + DriverCommand::TOUCH_FLICK => array('POST' => '/session/:sessionId/touch/flick'), + DriverCommand::TOUCH_LONG_PRESS => array('POST' => '/session/:sessionId/touch/longclick'), + DriverCommand::TOUCH_MOVE => array('POST' => '/session/:sessionId/touch/move'), + DriverCommand::TOUCH_SCROLL => array('POST' => '/session/:sessionId/touch/scroll'), + DriverCommand::TOUCH_UP => array('POST' => '/session/:sessionId/touch/up'), + ); + + /** + * @var string + */ + protected $url; + /** + * @var string + */ + protected $sessionID; + /** + * @var resource + */ + protected $curl; + + /** + * @param string $url + */ + public function __construct($url = 'http://localhost:4444/wd/hub') + { + $this->url = $url; + $this->curl = curl_init(); + curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT_MS, 300000); + curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); + curl_setopt( + $this->curl, + CURLOPT_HTTPHEADER, + array('Content-Type: application/json;charset=UTF-8', 'Accept: application/json') + ); + } + + /** + * Set connection timeout in ms. + * + * @param int $timeout + */ + public function setTimeout($timeout) + { + curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT_MS, $timeout); + } + + /** + * @param string $sessionID + */ + public function setSessionID($sessionID) + { + $this->sessionID = $sessionID; + } + + /** + * @param $command + * @param array $params + * + * @throws InvalidArgumentException + * @throws BadMethodCallException + * @return mixed + */ + public function execute($command, array $params = array()) + { + if (empty($this->commands[$command])) { + throw new InvalidArgumentException(sprintf('Command %s is unknown.', $command)); + } + reset($this->commands[$command]); + list($method, $url) = each($this->commands[$command]); + $url = str_replace(':sessionId', $this->sessionID, $url); + foreach ($params as $name => $value) { + if ($name[0] === ':') { + $url = str_replace($name, $value, $url); + if ($method !== 'POST') { + unset($params[$name]); + } + } + } + if (!empty($params) && $method !== 'POST') { + throw new BadMethodCallException(sprintf( + 'The http method called for %s is %s but it has to be POST' . + ' if you want to pass the JSON params %s', + $url, + $method, + json_encode($params) + )); + } + curl_setopt($this->curl, CURLOPT_URL, $url); + + if ($method === 'GET') { + curl_setopt($this->curl, CURLOPT_HTTPGET, true); + } elseif ($method === 'POST') { + curl_setopt($this->curl, CURLOPT_POST, true); + if ($params && is_array($params)) { + curl_setopt($this->curl, CURLOPT_POSTFIELDS, json_encode($params)); + } + } elseif ($method == 'DELETE') { + curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); + } + + $raw_results = trim(curl_exec($this->curl)); + + if ($error = curl_error($this->curl)) { + $msg = sprintf( + 'Curl error thrown for http %s to %s', + $method, + $url + ); + if ($params && is_array($params)) { + $msg .= sprintf(' with params: %s', json_encode($params)); + } + WebDriverException::throwException(-1, $msg . "\n\n" . $error, array()); + } + + curl_setopt($this->curl, CURLOPT_POSTFIELDS, null); + curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, null); + + $results = json_decode($raw_results, true); + + $value = null; + if (is_array($results) && array_key_exists('value', $results)) { + $value = $results['value']; + } + + $message = null; + if (is_array($value) && array_key_exists('message', $value)) { + $message = $value['message']; + } + + $sessionId = null; + if (is_array($results) && array_key_exists('sessionId', $results)) { + $sessionId = $results['sessionId']; + } + + $status = isset($results['status']) ? $results['status'] : 0; + WebDriverException::throwException($status, $message, $results); + + $response = new WebDriverResponse($sessionId); + + return $response + ->setStatus($status) + ->setValue($value); + } +} From 0e5db656518d98e574d914d5a2c44562872255d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=9A=D0=BE=D0=BB?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Tue, 3 Jun 2014 18:18:15 +0400 Subject: [PATCH 086/784] Update phpdoc. --- lib/remote/CurlCommandExecutor.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/remote/CurlCommandExecutor.php b/lib/remote/CurlCommandExecutor.php index d7e354bfd..c755adafa 100644 --- a/lib/remote/CurlCommandExecutor.php +++ b/lib/remote/CurlCommandExecutor.php @@ -151,7 +151,7 @@ public function setSessionID($sessionID) * * @throws InvalidArgumentException * @throws BadMethodCallException - * @return mixed + * @return WebDriverResponse */ public function execute($command, array $params = array()) { @@ -230,8 +230,6 @@ public function execute($command, array $params = array()) $response = new WebDriverResponse($sessionId); - return $response - ->setStatus($status) - ->setValue($value); + return $response->setStatus($status)->setValue($value); } } From 36f84ba0fed44a437b88dd88fec775e7bf3e229d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=9A=D0=BE=D0=BB?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Wed, 11 Jun 2014 17:32:55 +0400 Subject: [PATCH 087/784] Fix URL. --- lib/remote/CurlCommandExecutor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/remote/CurlCommandExecutor.php b/lib/remote/CurlCommandExecutor.php index c755adafa..073ffd471 100644 --- a/lib/remote/CurlCommandExecutor.php +++ b/lib/remote/CurlCommandExecutor.php @@ -178,7 +178,7 @@ public function execute($command, array $params = array()) json_encode($params) )); } - curl_setopt($this->curl, CURLOPT_URL, $url); + curl_setopt($this->curl, CURLOPT_URL, $this->url . $url); if ($method === 'GET') { curl_setopt($this->curl, CURLOPT_HTTPGET, true); From 5aac4dcaf5aa377b74ee4c4c4864e2f1031b5b91 Mon Sep 17 00:00:00 2001 From: Andrey Kolchenko Date: Mon, 21 Jul 2014 17:25:27 +0400 Subject: [PATCH 088/784] Fix bug with curl (PHP < 5.5) --- lib/remote/CurlCommandExecutor.php | 162 ++++++++++++++--------------- 1 file changed, 79 insertions(+), 83 deletions(-) diff --git a/lib/remote/CurlCommandExecutor.php b/lib/remote/CurlCommandExecutor.php index 073ffd471..5a0734f3c 100644 --- a/lib/remote/CurlCommandExecutor.php +++ b/lib/remote/CurlCommandExecutor.php @@ -22,79 +22,79 @@ class CurlCommandExecutor implements WebDriverCommandExecutor * @see http://code.google.com/p/selenium/wiki/JsonWireProtocol#Command_Reference */ protected $commands = array( - DriverCommand::ACCEPT_ALERT => array('POST' => '/session/:sessionId/accept_alert'), - DriverCommand::ADD_COOKIE => array('POST' => '/session/:sessionId/cookie'), - DriverCommand::CLEAR_ELEMENT => array('POST' => '/session/:sessionId/element/:id/clear'), - DriverCommand::CLICK_ELEMENT => array('POST' => '/session/:sessionId/element/:id/click'), - DriverCommand::CLOSE => array('DELETE' => '/session/:sessionId/window'), - DriverCommand::DELETE_ALL_COOKIES => array('DELETE' => '/session/:sessionId/cookie'), - DriverCommand::DELETE_COOKIE => array('DELETE' => '/session/:sessionId/cookie/:name'), - DriverCommand::DISMISS_ALERT => array('POST' => '/session/:sessionId/dismiss_alert'), - DriverCommand::ELEMENT_EQUALS => array('GET' => '/session/:sessionId/element/:id/equals/:other'), - DriverCommand::FIND_CHILD_ELEMENT => array('POST' => '/session/:sessionId/element/:id/element'), - DriverCommand::FIND_CHILD_ELEMENTS => array('POST' => '/session/:sessionId/element/:id/elements'), - DriverCommand::EXECUTE_SCRIPT => array('POST' => '/session/:sessionId/execute'), - DriverCommand::EXECUTE_ASYNC_SCRIPT => array('POST' => '/session/:sessionId/execute_async'), - DriverCommand::FIND_ELEMENT => array('POST' => '/session/:sessionId/element'), - DriverCommand::FIND_ELEMENTS => array('POST' => '/session/:sessionId/elements'), - DriverCommand::SWITCH_TO_FRAME => array('POST' => '/session/:sessionId/frame'), - DriverCommand::SWITCH_TO_WINDOW => array('POST' => '/session/:sessionId/window'), - DriverCommand::GET => array('POST' => '/session/:sessionId/url'), - DriverCommand::GET_ACTIVE_ELEMENT => array('POST' => '/session/:sessionId/element/active'), - DriverCommand::GET_ALERT_TEXT => array('GET' => '/session/:sessionId/alert_text'), - DriverCommand::GET_ALL_COOKIES => array('GET' => '/session/:sessionId/cookie'), - DriverCommand::GET_AVAILABLE_LOG_TYPES => array('GET' => '/session/:sessionId/log/types'), - DriverCommand::GET_CURRENT_URL => array('GET' => '/session/:sessionId/url'), - DriverCommand::GET_CURRENT_WINDOW_HANDLE => array('GET' => '/session/:sessionId/window_handle'), - DriverCommand::GET_ELEMENT_ATTRIBUTE => array('GET' => '/session/:sessionId/element/:id/attribute/:name'), - DriverCommand::GET_ELEMENT_VALUE_OF_CSS_PROPERTY => array('GET' => '/session/:sessionId/element/:id/css/:propertyName'), - DriverCommand::GET_ELEMENT_LOCATION => array('GET' => '/session/:sessionId/element/:id/location'), - DriverCommand::GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW => array('GET' => '/session/:sessionId/element/:id/location_in_view'), - DriverCommand::GET_ELEMENT_SIZE => array('GET' => '/session/:sessionId/element/:id/size'), - DriverCommand::GET_ELEMENT_TAG_NAME => array('GET' => '/session/:sessionId/element/:id/name'), - DriverCommand::GET_ELEMENT_TEXT => array('GET' => '/session/:sessionId/element/:id/text'), - DriverCommand::GET_LOG => array('POST' => '/session/:sessionId/log'), - DriverCommand::GET_PAGE_SOURCE => array('GET' => '/session/:sessionId/source'), - DriverCommand::GET_SCREEN_ORIENTATION => array('GET' => '/session/:sessionId/orientation'), - DriverCommand::GET_CAPABILITIES => array('GET' => '/session/:sessionId'), - DriverCommand::GET_TITLE => array('GET' => '/session/:sessionId/title'), - DriverCommand::GET_WINDOW_HANDLES => array('GET' => '/session/:sessionId/window_handles'), - DriverCommand::GET_WINDOW_POSITION => array('GET' => '/session/:sessionId/window/:windowHandle/position'), - DriverCommand::GET_WINDOW_SIZE => array('GET' => '/session/:sessionId/window/:windowHandle/size'), - DriverCommand::GO_BACK => array('POST' => '/session/:sessionId/back'), - DriverCommand::GO_FORWARD => array('POST' => '/session/:sessionId/forward'), - DriverCommand::IS_ELEMENT_DISPLAYED => array('GET' => '/session/:sessionId/element/:id/displayed'), - DriverCommand::IS_ELEMENT_ENABLED => array('GET' => '/session/:sessionId/element/:id/enabled'), - DriverCommand::IS_ELEMENT_SELECTED => array('GET' => '/session/:sessionId/element/:id/selected'), - DriverCommand::MAXIMIZE_WINDOW => array('POST' => '/session/:sessionId/window/:windowHandle/maximize'), - DriverCommand::MOUSE_DOWN => array('POST' => '/session/:sessionId/buttondown'), - DriverCommand::MOUSE_UP => array('POST' => '/session/:sessionId/buttonup'), - DriverCommand::CLICK => array('POST' => '/session/:sessionId/click'), - DriverCommand::DOUBLE_CLICK => array('POST' => '/session/:sessionId/doubleclick'), - DriverCommand::MOVE_TO => array('POST' => '/session/:sessionId/moveto'), - DriverCommand::NEW_SESSION => array('POST' => '/session'), - DriverCommand::QUIT => array('DELETE' => '/session/:sessionId'), - DriverCommand::REFRESH => array('POST' => '/session/:sessionId/refresh'), - DriverCommand::UPLOAD_FILE => array('POST' => '/session/:sessionId/file'), // undocumented - DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT => array('POST' => '/session/:sessionId/keys'), - DriverCommand::SET_ALERT_VALUE => array('POST' => '/session/:sessionId/alert_text'), - DriverCommand::SEND_KEYS_TO_ELEMENT => array('POST' => '/session/:sessionId/element/:id/value'), - DriverCommand::IMPLICITLY_WAIT => array('POST' => '/session/:sessionId/timeouts/implicit_wait'), - DriverCommand::SET_SCREEN_ORIENTATION => array('POST' => '/session/:sessionId/orientation'), - DriverCommand::SET_TIMEOUT => array('POST' => '/session/:sessionId/timeouts'), - DriverCommand::SET_SCRIPT_TIMEOUT => array('POST' => '/session/:sessionId/timeouts/async_script'), - DriverCommand::SET_WINDOW_POSITION => array('POST' => '/session/:sessionId/window/:windowHandle/position'), - DriverCommand::SET_WINDOW_SIZE => array('POST' => '/session/:sessionId/window/:windowHandle/size'), - DriverCommand::SUBMIT_ELEMENT => array('POST' => '/session/:sessionId/element/:id/submit'), - DriverCommand::SCREENSHOT => array('GET' => '/session/:sessionId/screenshot'), - DriverCommand::TOUCH_SINGLE_TAP => array('POST' => '/session/:sessionId/touch/click'), - DriverCommand::TOUCH_DOWN => array('POST' => '/session/:sessionId/touch/down'), - DriverCommand::TOUCH_DOUBLE_TAP => array('POST' => '/session/:sessionId/touch/doubleclick'), - DriverCommand::TOUCH_FLICK => array('POST' => '/session/:sessionId/touch/flick'), - DriverCommand::TOUCH_LONG_PRESS => array('POST' => '/session/:sessionId/touch/longclick'), - DriverCommand::TOUCH_MOVE => array('POST' => '/session/:sessionId/touch/move'), - DriverCommand::TOUCH_SCROLL => array('POST' => '/session/:sessionId/touch/scroll'), - DriverCommand::TOUCH_UP => array('POST' => '/session/:sessionId/touch/up'), + DriverCommand::ACCEPT_ALERT => array('POST', '/session/:sessionId/accept_alert'), + DriverCommand::ADD_COOKIE => array('POST', '/session/:sessionId/cookie'), + DriverCommand::CLEAR_ELEMENT => array('POST', '/session/:sessionId/element/:id/clear'), + DriverCommand::CLICK_ELEMENT => array('POST', '/session/:sessionId/element/:id/click'), + DriverCommand::CLOSE => array('DELETE', '/session/:sessionId/window'), + DriverCommand::DELETE_ALL_COOKIES => array('DELETE', '/session/:sessionId/cookie'), + DriverCommand::DELETE_COOKIE => array('DELETE', '/session/:sessionId/cookie/:name'), + DriverCommand::DISMISS_ALERT => array('POST', '/session/:sessionId/dismiss_alert'), + DriverCommand::ELEMENT_EQUALS => array('GET', '/session/:sessionId/element/:id/equals/:other'), + DriverCommand::FIND_CHILD_ELEMENT => array('POST', '/session/:sessionId/element/:id/element'), + DriverCommand::FIND_CHILD_ELEMENTS => array('POST', '/session/:sessionId/element/:id/elements'), + DriverCommand::EXECUTE_SCRIPT => array('POST', '/session/:sessionId/execute'), + DriverCommand::EXECUTE_ASYNC_SCRIPT => array('POST', '/session/:sessionId/execute_async'), + DriverCommand::FIND_ELEMENT => array('POST', '/session/:sessionId/element'), + DriverCommand::FIND_ELEMENTS => array('POST', '/session/:sessionId/elements'), + DriverCommand::SWITCH_TO_FRAME => array('POST', '/session/:sessionId/frame'), + DriverCommand::SWITCH_TO_WINDOW => array('POST', '/session/:sessionId/window'), + DriverCommand::GET => array('POST', '/session/:sessionId/url'), + DriverCommand::GET_ACTIVE_ELEMENT => array('POST', '/session/:sessionId/element/active'), + DriverCommand::GET_ALERT_TEXT => array('GET', '/session/:sessionId/alert_text'), + DriverCommand::GET_ALL_COOKIES => array('GET', '/session/:sessionId/cookie'), + DriverCommand::GET_AVAILABLE_LOG_TYPES => array('GET', '/session/:sessionId/log/types'), + DriverCommand::GET_CURRENT_URL => array('GET', '/session/:sessionId/url'), + DriverCommand::GET_CURRENT_WINDOW_HANDLE => array('GET', '/session/:sessionId/window_handle'), + DriverCommand::GET_ELEMENT_ATTRIBUTE => array('GET', '/session/:sessionId/element/:id/attribute/:name'), + DriverCommand::GET_ELEMENT_VALUE_OF_CSS_PROPERTY => array('GET', '/session/:sessionId/element/:id/css/:propertyName'), + DriverCommand::GET_ELEMENT_LOCATION => array('GET', '/session/:sessionId/element/:id/location'), + DriverCommand::GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW => array('GET', '/session/:sessionId/element/:id/location_in_view'), + DriverCommand::GET_ELEMENT_SIZE => array('GET', '/session/:sessionId/element/:id/size'), + DriverCommand::GET_ELEMENT_TAG_NAME => array('GET', '/session/:sessionId/element/:id/name'), + DriverCommand::GET_ELEMENT_TEXT => array('GET', '/session/:sessionId/element/:id/text'), + DriverCommand::GET_LOG => array('POST', '/session/:sessionId/log'), + DriverCommand::GET_PAGE_SOURCE => array('GET', '/session/:sessionId/source'), + DriverCommand::GET_SCREEN_ORIENTATION => array('GET', '/session/:sessionId/orientation'), + DriverCommand::GET_CAPABILITIES => array('GET', '/session/:sessionId'), + DriverCommand::GET_TITLE => array('GET', '/session/:sessionId/title'), + DriverCommand::GET_WINDOW_HANDLES => array('GET', '/session/:sessionId/window_handles'), + DriverCommand::GET_WINDOW_POSITION => array('GET', '/session/:sessionId/window/:windowHandle/position'), + DriverCommand::GET_WINDOW_SIZE => array('GET', '/session/:sessionId/window/:windowHandle/size'), + DriverCommand::GO_BACK => array('POST', '/session/:sessionId/back'), + DriverCommand::GO_FORWARD => array('POST', '/session/:sessionId/forward'), + DriverCommand::IS_ELEMENT_DISPLAYED => array('GET', '/session/:sessionId/element/:id/displayed'), + DriverCommand::IS_ELEMENT_ENABLED => array('GET', '/session/:sessionId/element/:id/enabled'), + DriverCommand::IS_ELEMENT_SELECTED => array('GET', '/session/:sessionId/element/:id/selected'), + DriverCommand::MAXIMIZE_WINDOW => array('POST', '/session/:sessionId/window/:windowHandle/maximize'), + DriverCommand::MOUSE_DOWN => array('POST', '/session/:sessionId/buttondown'), + DriverCommand::MOUSE_UP => array('POST', '/session/:sessionId/buttonup'), + DriverCommand::CLICK => array('POST', '/session/:sessionId/click'), + DriverCommand::DOUBLE_CLICK => array('POST', '/session/:sessionId/doubleclick'), + DriverCommand::MOVE_TO => array('POST', '/session/:sessionId/moveto'), + DriverCommand::NEW_SESSION => array('POST', '/session'), + DriverCommand::QUIT => array('DELETE', '/session/:sessionId'), + DriverCommand::REFRESH => array('POST', '/session/:sessionId/refresh'), + DriverCommand::UPLOAD_FILE => array('POST', '/session/:sessionId/file'), // undocumented + DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT => array('POST', '/session/:sessionId/keys'), + DriverCommand::SET_ALERT_VALUE => array('POST', '/session/:sessionId/alert_text'), + DriverCommand::SEND_KEYS_TO_ELEMENT => array('POST', '/session/:sessionId/element/:id/value'), + DriverCommand::IMPLICITLY_WAIT => array('POST', '/session/:sessionId/timeouts/implicit_wait'), + DriverCommand::SET_SCREEN_ORIENTATION => array('POST', '/session/:sessionId/orientation'), + DriverCommand::SET_TIMEOUT => array('POST', '/session/:sessionId/timeouts'), + DriverCommand::SET_SCRIPT_TIMEOUT => array('POST', '/session/:sessionId/timeouts/async_script'), + DriverCommand::SET_WINDOW_POSITION => array('POST', '/session/:sessionId/window/:windowHandle/position'), + DriverCommand::SET_WINDOW_SIZE => array('POST', '/session/:sessionId/window/:windowHandle/size'), + DriverCommand::SUBMIT_ELEMENT => array('POST', '/session/:sessionId/element/:id/submit'), + DriverCommand::SCREENSHOT => array('GET', '/session/:sessionId/screenshot'), + DriverCommand::TOUCH_SINGLE_TAP => array('POST', '/session/:sessionId/touch/click'), + DriverCommand::TOUCH_DOWN => array('POST', '/session/:sessionId/touch/down'), + DriverCommand::TOUCH_DOUBLE_TAP => array('POST', '/session/:sessionId/touch/doubleclick'), + DriverCommand::TOUCH_FLICK => array('POST', '/session/:sessionId/touch/flick'), + DriverCommand::TOUCH_LONG_PRESS => array('POST', '/session/:sessionId/touch/longclick'), + DriverCommand::TOUCH_MOVE => array('POST', '/session/:sessionId/touch/move'), + DriverCommand::TOUCH_SCROLL => array('POST', '/session/:sessionId/touch/scroll'), + DriverCommand::TOUCH_UP => array('POST', '/session/:sessionId/touch/up'), ); /** @@ -146,21 +146,20 @@ public function setSessionID($sessionID) } /** - * @param $command - * @param array $params + * @param WebDriverCommand $command * * @throws InvalidArgumentException * @throws BadMethodCallException * @return WebDriverResponse */ - public function execute($command, array $params = array()) + public function execute(WebDriverCommand $command) { - if (empty($this->commands[$command])) { - throw new InvalidArgumentException(sprintf('Command %s is unknown.', $command)); + if (empty($this->commands[$command->getName()])) { + throw new InvalidArgumentException(sprintf('Command %s is unknown.', $command->getName())); } - reset($this->commands[$command]); - list($method, $url) = each($this->commands[$command]); + list($method, $url) = $this->commands[$command->getName()]; $url = str_replace(':sessionId', $this->sessionID, $url); + $params = $command->getParameters(); foreach ($params as $name => $value) { if ($name[0] === ':') { $url = str_replace($name, $value, $url); @@ -205,9 +204,6 @@ public function execute($command, array $params = array()) WebDriverException::throwException(-1, $msg . "\n\n" . $error, array()); } - curl_setopt($this->curl, CURLOPT_POSTFIELDS, null); - curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, null); - $results = json_decode($raw_results, true); $value = null; From 985c40cd835a2e1cab7c79f6ae9b244ff4b84462 Mon Sep 17 00:00:00 2001 From: Yannick Chabbert Date: Tue, 22 Jul 2014 13:28:36 +0200 Subject: [PATCH 089/784] fix typo error in ChromeOptions --- lib/chrome/ChromeOptions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/chrome/ChromeOptions.php b/lib/chrome/ChromeOptions.php index 89939b1e2..cef9b04f8 100644 --- a/lib/chrome/ChromeOptions.php +++ b/lib/chrome/ChromeOptions.php @@ -118,7 +118,7 @@ public function toCapabilities() { * @return array */ public function toArray() { - $options = $this->experimentOptions; + $options = $this->experimentalOptions; $options['binary'] = $this->binary; From fb6c90fd49b262fec690128db3ca8dc9d4a8c456 Mon Sep 17 00:00:00 2001 From: Andrey Kolchenko Date: Sat, 26 Jul 2014 13:14:52 +0400 Subject: [PATCH 090/784] Use CURLOPT_CUSTOMREQUEST option for fixing bug with HTTP method. --- lib/remote/CurlCommandExecutor.php | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/lib/remote/CurlCommandExecutor.php b/lib/remote/CurlCommandExecutor.php index 5a0734f3c..36ac6df10 100644 --- a/lib/remote/CurlCommandExecutor.php +++ b/lib/remote/CurlCommandExecutor.php @@ -178,17 +178,13 @@ public function execute(WebDriverCommand $command) )); } curl_setopt($this->curl, CURLOPT_URL, $this->url . $url); - - if ($method === 'GET') { - curl_setopt($this->curl, CURLOPT_HTTPGET, true); - } elseif ($method === 'POST') { - curl_setopt($this->curl, CURLOPT_POST, true); - if ($params && is_array($params)) { - curl_setopt($this->curl, CURLOPT_POSTFIELDS, json_encode($params)); - } - } elseif ($method == 'DELETE') { - curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); + curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $method); + if ($method === 'POST' && $params && is_array($params)) { + $encoded_params = json_encode($params); + } else { + $encoded_params = null; } + curl_setopt($this->curl, CURLOPT_POSTFIELDS, $encoded_params); $raw_results = trim(curl_exec($this->curl)); From d089ddfbba7968770ac1789f37eff79a37efea17 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Thu, 31 Jul 2014 20:38:58 -0700 Subject: [PATCH 091/784] Throw exception if the browser is not 'htmlunit'. --- lib/remote/DesiredCapabilities.php | 11 +++++++++++ lib/remote/HttpCommandExecutor.php | 1 - lib/remote/RemoteWebElement.php | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/remote/DesiredCapabilities.php b/lib/remote/DesiredCapabilities.php index 72e984317..d0942d112 100644 --- a/lib/remote/DesiredCapabilities.php +++ b/lib/remote/DesiredCapabilities.php @@ -96,9 +96,20 @@ public function isJavascriptEnabled() { } /** + * This is a htmlUnit-only option. + * * @return DesiredCapabilities + * @see https://code.google.com/p/selenium/wiki/DesiredCapabilities#Read-write_capabilities */ public function setJavascriptEnabled($enabled) { + $browser = $this->getBrowserName(); + if ($browser && $browser !== WebDriverBrowserType::HTMLUNIT) { + throw new Exception( + 'isJavascriptEnable() is a htmlunit-only option. '. + 'See https://code.google.com/p/selenium/wiki/DesiredCapabilities#Read-write_capabilities.' + ); + } + $this->set(WebDriverCapabilityType::JAVASCRIPT_ENABLED, $enabled); return $this; } diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index bcc6aa2bf..d7ab430b7 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -237,4 +237,3 @@ public function getAddressOfRemoteServer() { return $this->url; } } - diff --git a/lib/remote/RemoteWebElement.php b/lib/remote/RemoteWebElement.php index 19d0f377a..d702cc601 100644 --- a/lib/remote/RemoteWebElement.php +++ b/lib/remote/RemoteWebElement.php @@ -121,7 +121,7 @@ public function findElements(WebDriverBy $by) { * Get the value of a the given attribute of the element. * * @param string $attribute_name The name of the attribute. - * @return string The value of the attribute. + * @return string|null The value of the attribute. */ public function getAttribute($attribute_name) { $params = array( From 39d8be53309457458c4e023a9899a603c9be36d2 Mon Sep 17 00:00:00 2001 From: Yannick Chabbert Date: Sat, 2 Aug 2014 13:07:20 +0200 Subject: [PATCH 092/784] fix chrome driver php5.4 interface signatures --- lib/chrome/ChromeDriver.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/chrome/ChromeDriver.php b/lib/chrome/ChromeDriver.php index 7f85d8a81..186e0341e 100644 --- a/lib/chrome/ChromeDriver.php +++ b/lib/chrome/ChromeDriver.php @@ -41,11 +41,18 @@ public function startSession($desired_capabilities) { $this->setSessionID($response->getSessionID()); } - public static function create() { + public static function create( + $url = 'http://localhost:4444/wd/hub', + $desired_capabilities = null, + $timeout_in_ms = 300000 + ) { throw new WebDriverException('Please use ChromeDriver::start() instead.'); } - public static function createBySessionID() { + public static function createBySessionID( + $session_id, + $url = 'http://localhost:4444/wd/hub' + ) { throw new WebDriverException('Please use ChromeDriver::start() instead.'); } } From 7483c3524784257769ac25c9b0c3f7dbf9ed8429 Mon Sep 17 00:00:00 2001 From: Yannick Chabbert Date: Sun, 21 Sep 2014 21:17:58 +0200 Subject: [PATCH 093/784] temporary fix for opera to force tag name lowercase --- lib/remote/RemoteWebElement.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/remote/RemoteWebElement.php b/lib/remote/RemoteWebElement.php index d702cc601..98b7d5f9c 100644 --- a/lib/remote/RemoteWebElement.php +++ b/lib/remote/RemoteWebElement.php @@ -220,10 +220,14 @@ public function getSize() { * @return string The tag name. */ public function getTagName() { - return $this->executor->execute( + // Force tag name to be lowercase as expected by protocol for Opera driver + // until this issue is not resolved : + // https://github.com/operasoftware/operadriver/issues/102 + // Remove it when fixed to be consistent with the protocol. + return strtolower($this->executor->execute( DriverCommand::GET_ELEMENT_TAG_NAME, array(':id' => $this->id) - ); + )); } /** From 81f7716e33d9c9c604f2163daad7ca54a4f5918e Mon Sep 17 00:00:00 2001 From: MartyIX Date: Wed, 1 Oct 2014 17:25:02 +0200 Subject: [PATCH 094/784] Update WebDriverWait.php typo --- lib/WebDriverWait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/WebDriverWait.php b/lib/WebDriverWait.php index 2ab2aad5a..68b7b46f7 100644 --- a/lib/WebDriverWait.php +++ b/lib/WebDriverWait.php @@ -40,7 +40,7 @@ public function __construct( * value is not falsey. * * @param (closure|WebDriverExpectedCondition) - * return mixed The return value of $func_or_ec + * @return mixed The return value of $func_or_ec */ public function until($func_or_ec, $message = "") { $end = microtime(true) + $this->timeout; From 0ce0687c627881e663a073582cf974cd769c06bf Mon Sep 17 00:00:00 2001 From: Janos Pasztor Date: Tue, 14 Oct 2014 22:24:35 +0200 Subject: [PATCH 095/784] Moved the webdriver to a namespace (see issue #169 on the original repo) --- example.php | 2 ++ lib/JavaScriptExecutor.php | 2 ++ lib/WebDriver.php | 2 ++ lib/WebDriverAction.php | 2 ++ lib/WebDriverAlert.php | 2 ++ lib/WebDriverBy.php | 2 ++ lib/WebDriverCapabilities.php | 2 ++ lib/WebDriverCommandExecutor.php | 2 ++ lib/WebDriverDimension.php | 2 ++ lib/WebDriverDispatcher.php | 2 ++ lib/WebDriverElement.php | 2 ++ lib/WebDriverEventListener.php | 2 ++ lib/WebDriverExceptions.php | 4 ++++ lib/WebDriverExpectedCondition.php | 2 ++ lib/WebDriverHasInputDevices.php | 2 ++ lib/WebDriverKeyboard.php | 2 ++ lib/WebDriverKeys.php | 2 ++ lib/WebDriverMouse.php | 2 ++ lib/WebDriverNavigation.php | 2 ++ lib/WebDriverOptions.php | 2 ++ lib/WebDriverPlatform.php | 2 ++ lib/WebDriverPoint.php | 2 ++ lib/WebDriverSearchContext.php | 2 ++ lib/WebDriverSelect.php | 2 ++ lib/WebDriverTargetLocator.php | 2 ++ lib/WebDriverTimeouts.php | 2 ++ lib/WebDriverWait.php | 2 ++ lib/WebDriverWindow.php | 2 ++ lib/chrome/ChromeDriver.php | 2 ++ lib/chrome/ChromeDriverService.php | 2 ++ lib/chrome/ChromeOptions.php | 2 ++ lib/firefox/FirefoxDriver.php | 2 ++ lib/firefox/FirefoxProfile.php | 4 ++++ lib/interactions/WebDriverActions.php | 2 ++ lib/interactions/WebDriverCompositeAction.php | 2 ++ lib/interactions/WebDriverTouchActions.php | 2 ++ lib/interactions/WebDriverTouchScreen.php | 2 ++ .../internal/WebDriverButtonReleaseAction.php | 2 ++ lib/interactions/internal/WebDriverClickAction.php | 2 ++ .../internal/WebDriverClickAndHoldAction.php | 2 ++ .../internal/WebDriverContextClickAction.php | 2 ++ lib/interactions/internal/WebDriverCoordinates.php | 4 ++++ .../internal/WebDriverDoubleClickAction.php | 2 ++ lib/interactions/internal/WebDriverKeyDownAction.php | 2 ++ lib/interactions/internal/WebDriverKeyUpAction.php | 2 ++ .../internal/WebDriverKeysRelatedAction.php | 2 ++ lib/interactions/internal/WebDriverMouseAction.php | 2 ++ .../internal/WebDriverMouseMoveAction.php | 2 ++ .../internal/WebDriverMoveToOffsetAction.php | 2 ++ .../internal/WebDriverSendKeysAction.php | 2 ++ .../internal/WebDriverSingleKeyAction.php | 2 ++ lib/interactions/touch/WebDriverDoubleTapAction.php | 2 ++ lib/interactions/touch/WebDriverDownAction.php | 2 ++ lib/interactions/touch/WebDriverFlickAction.php | 2 ++ .../touch/WebDriverFlickFromElementAction.php | 2 ++ lib/interactions/touch/WebDriverLongPressAction.php | 2 ++ lib/interactions/touch/WebDriverMoveAction.php | 2 ++ lib/interactions/touch/WebDriverScrollAction.php | 2 ++ .../touch/WebDriverScrollFromElementAction.php | 2 ++ lib/interactions/touch/WebDriverTapAction.php | 2 ++ lib/interactions/touch/WebDriverTouchAction.php | 2 ++ lib/interactions/touch/WebDriverUpAction.php | 2 ++ lib/internal/WebDriverLocatable.php | 2 ++ lib/net/URLChecker.php | 2 ++ lib/remote/DesiredCapabilities.php | 2 ++ lib/remote/DriverCommand.php | 2 ++ lib/remote/ExecuteMethod.php | 2 ++ lib/remote/FileDetector.php | 2 ++ lib/remote/HttpCommandExecutor.php | 2 ++ lib/remote/LocalFileDetector.php | 2 ++ lib/remote/RemoteExecuteMethod.php | 2 ++ lib/remote/RemoteKeyboard.php | 2 ++ lib/remote/RemoteMouse.php | 2 ++ lib/remote/RemoteTouchScreen.php | 2 ++ lib/remote/RemoteWebDriver.php | 2 ++ lib/remote/RemoteWebElement.php | 4 ++++ lib/remote/UselessFileDetector.php | 2 ++ lib/remote/WebDriverBrowserType.php | 2 ++ lib/remote/WebDriverCapabilityType.php | 2 ++ lib/remote/WebDriverCommand.php | 2 ++ lib/remote/WebDriverResponse.php | 2 ++ lib/remote/service/DriverCommandExecutor.php | 2 ++ lib/remote/service/DriverService.php | 2 ++ lib/support/events/EventFiringWebDriver.php | 2 ++ .../events/EventFiringWebDriverNavigation.php | 2 ++ lib/support/events/EventFiringWebElement.php | 2 ++ tests/bootstrap.php | 2 ++ tests/functional/BaseTest.php | 4 +++- tests/functional/FileUploadTest.php | 2 ++ tests/functional/WebDriverTestCase.php | 4 +++- tests/unit/bootstrap.php | 2 ++ .../internal/WebDriverButtonReleaseActionTest.php | 10 ++++++---- .../internal/WebDriverClickActionTest.php | 10 ++++++---- .../internal/WebDriverClickAndHoldActionTest.php | 10 ++++++---- .../internal/WebDriverContextClickActionTest.php | 10 ++++++---- .../internal/WebDriverCoordinatesTest.php | 4 +++- .../internal/WebDriverDoubleClickActionTest.php | 10 ++++++---- .../internal/WebDriverKeyDownActionTest.php | 12 +++++++----- .../internal/WebDriverKeyUpActionTest.php | 12 +++++++----- .../internal/WebDriverMouseMoveActionTest.php | 10 ++++++---- .../internal/WebDriverMouseToOffsetActionTest.php | 10 ++++++---- .../internal/WebDriverSendKeysActionTest.php | 12 +++++++----- 102 files changed, 258 insertions(+), 46 deletions(-) diff --git a/example.php b/example.php index a1e133b91..8cfac7461 100644 --- a/example.php +++ b/example.php @@ -1,6 +1,8 @@ driver->findElement(WebDriverBy::tagName('input'))->getAttribute('value') ); } -} \ No newline at end of file +} diff --git a/tests/functional/FileUploadTest.php b/tests/functional/FileUploadTest.php index 84ec454e8..7f09aa8f0 100644 --- a/tests/functional/FileUploadTest.php +++ b/tests/functional/FileUploadTest.php @@ -13,6 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +namespace Selenium\WebDriver; + /** * An example test case for php-webdriver. * diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index 92b017b34..53e031ac9 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -13,10 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +namespace Selenium\WebDriver; + /** * The base class for test cases. */ -class WebDriverTestCase extends PHPUnit_Framework_TestCase { +class WebDriverTestCase extends \PHPUnit_Framework_TestCase { /** @var RemoteWebDriver $driver */ protected $driver; diff --git a/tests/unit/bootstrap.php b/tests/unit/bootstrap.php index 562467964..80da4bb38 100644 --- a/tests/unit/bootstrap.php +++ b/tests/unit/bootstrap.php @@ -1,3 +1,5 @@ webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); $this->webDriverButtonReleaseAction = new WebDriverButtonReleaseAction( $this->webDriverMouse, $this->locationProvider @@ -32,7 +34,7 @@ public function setUp() { } public function testPerformSendsMouseUpCommand() { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseUp')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverButtonReleaseAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverClickActionTest.php b/tests/unit/interactions/internal/WebDriverClickActionTest.php index 98fd39197..ca60ae668 100644 --- a/tests/unit/interactions/internal/WebDriverClickActionTest.php +++ b/tests/unit/interactions/internal/WebDriverClickActionTest.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -class WebDriverClickActionTest extends PHPUnit_Framework_TestCase { +namespace Selenium\WebDriver; + +class WebDriverClickActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverClickAction */ @@ -23,8 +25,8 @@ class WebDriverClickActionTest extends PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); $this->webDriverClickAction = new WebDriverClickAction( $this->webDriverMouse, $this->locationProvider @@ -32,7 +34,7 @@ public function setUp() { } public function testPerformSendsClickCommand() { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverClickAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php b/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php index fe1826ee0..78781fae6 100644 --- a/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php +++ b/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -class WebDriverClickAndHoldActionTest extends PHPUnit_Framework_TestCase { +namespace Selenium\WebDriver; + +class WebDriverClickAndHoldActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverClickAndHoldAction */ @@ -23,8 +25,8 @@ class WebDriverClickAndHoldActionTest extends PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); $this->webDriverClickAndHoldAction = new WebDriverClickAndHoldAction( $this->webDriverMouse, $this->locationProvider @@ -32,7 +34,7 @@ public function setUp() { } public function testPerformSendsMouseDownCommand() { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseDown')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverClickAndHoldAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverContextClickActionTest.php b/tests/unit/interactions/internal/WebDriverContextClickActionTest.php index 7ac3162cc..ece8f3488 100644 --- a/tests/unit/interactions/internal/WebDriverContextClickActionTest.php +++ b/tests/unit/interactions/internal/WebDriverContextClickActionTest.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -class WebDriverContextClickActionTest extends PHPUnit_Framework_TestCase { +namespace Selenium\WebDriver; + +class WebDriverContextClickActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverContextClickAction */ @@ -23,8 +25,8 @@ class WebDriverContextClickActionTest extends PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); $this->webDriverContextClickAction = new WebDriverContextClickAction( $this->webDriverMouse, $this->locationProvider @@ -32,7 +34,7 @@ public function setUp() { } public function testPerformSendsContextClickCommand() { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('contextClick')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverContextClickAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverCoordinatesTest.php b/tests/unit/interactions/internal/WebDriverCoordinatesTest.php index cf4cc0d12..f339e5044 100644 --- a/tests/unit/interactions/internal/WebDriverCoordinatesTest.php +++ b/tests/unit/interactions/internal/WebDriverCoordinatesTest.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -class WebDriverCoordinatesTest extends PHPUnit_Framework_TestCase { +namespace Selenium\WebDriver; + +class WebDriverCoordinatesTest extends \PHPUnit_Framework_TestCase { public function testConstruct() { $in_view_port = function() { }; $on_page = function() { }; diff --git a/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php b/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php index a0c85ac0d..ae45d169b 100644 --- a/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php +++ b/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -class WebDriverDoubleClickActionTest extends PHPUnit_Framework_TestCase { +namespace Selenium\WebDriver; + +class WebDriverDoubleClickActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverDoubleClickAction */ @@ -23,8 +25,8 @@ class WebDriverDoubleClickActionTest extends PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); $this->webDriverDoubleClickAction = new WebDriverDoubleClickAction( $this->webDriverMouse, $this->locationProvider @@ -32,7 +34,7 @@ public function setUp() { } public function testPerformSendsDoubleClickCommand() { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('doubleClick')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverDoubleClickAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php b/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php index f82b25cb1..0cc5cb5cd 100644 --- a/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php +++ b/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -class WebDriverKeyDownActionTest extends PHPUnit_Framework_TestCase { +namespace Selenium\WebDriver; + +class WebDriverKeyDownActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverKeyDownAction */ @@ -24,9 +26,9 @@ class WebDriverKeyDownActionTest extends PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverKeyboard = $this->getMock('WebDriverKeyboard'); - $this->webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverKeyboard = $this->getMock('Selenium\WebDriver\WebDriverKeyboard'); + $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); $this->webDriverKeyDownAction = new WebDriverKeyDownAction( $this->webDriverKeyboard, $this->webDriverMouse, @@ -35,7 +37,7 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverKeyboard->expects($this->once())->method('pressKey'); diff --git a/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php b/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php index e35277bd7..daf7bfc06 100644 --- a/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php +++ b/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -class WebDriverKeyUpActionTest extends PHPUnit_Framework_TestCase { +namespace Selenium\WebDriver; + +class WebDriverKeyUpActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverKeyUpAction */ @@ -24,9 +26,9 @@ class WebDriverKeyUpActionTest extends PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverKeyboard = $this->getMock('WebDriverKeyboard'); - $this->webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverKeyboard = $this->getMock('Selenium\WebDriver\WebDriverKeyboard'); + $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); $this->webDriverKeyUpAction = new WebDriverKeyUpAction( $this->webDriverKeyboard, $this->webDriverMouse, @@ -36,7 +38,7 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverKeyboard->expects($this->once())->method('releaseKey')->with('a'); diff --git a/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php b/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php index aec3444d3..2c6ee400e 100644 --- a/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php +++ b/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -class WebDriverMouseMoveActionTest extends PHPUnit_Framework_TestCase { +namespace Selenium\WebDriver; + +class WebDriverMouseMoveActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverMouseMoveAction */ @@ -23,8 +25,8 @@ class WebDriverMouseMoveActionTest extends PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); $this->webDriverMouseMoveAction = new WebDriverMouseMoveAction( $this->webDriverMouse, $this->locationProvider @@ -32,7 +34,7 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseMove')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverMouseMoveAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php b/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php index 2cd2bc75d..c6066d051 100644 --- a/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php +++ b/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -class WebDriverMouseToOffsetActionTest extends PHPUnit_Framework_TestCase { +namespace Selenium\WebDriver; + +class WebDriverMouseToOffsetActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverMoveToOffsetAction */ @@ -23,8 +25,8 @@ class WebDriverMouseToOffsetActionTest extends PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); $this->webDriverMoveToOffsetAction = new WebDriverMoveToOffsetAction( $this->webDriverMouse, $this->locationProvider, @@ -34,7 +36,7 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseMove')->with($coords, 150, 200); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverMoveToOffsetAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php b/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php index 9f9cad84b..6a51f8934 100644 --- a/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php +++ b/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -class WebDriverSendKeysActionTest extends PHPUnit_Framework_TestCase { +namespace Selenium\WebDriver; + +class WebDriverSendKeysActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverSendKeysAction */ @@ -25,9 +27,9 @@ class WebDriverSendKeysActionTest extends PHPUnit_Framework_TestCase { private $keys; public function setUp() { - $this->webDriverKeyboard = $this->getMock('WebDriverKeyboard'); - $this->webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverKeyboard = $this->getMock('Selenium\WebDriver\WebDriverKeyboard'); + $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); $this->keys = array('t', 'e', 's', 't'); $this->webDriverSendKeysAction = new WebDriverSendKeysAction( $this->webDriverKeyboard, @@ -38,7 +40,7 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverKeyboard->expects($this->once())->method('sendKeys')->with($this->keys); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); From fab0b484142430f4f598baef45680f945a60eb4f Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Tue, 28 Oct 2014 13:04:04 -0700 Subject: [PATCH 096/784] CURLOPT_CONNECTTIMEOUT_MS is undefined in some versions of PHP For some reasons, CURLOPT_CONNECTTIMEOUT_MS is undefined and it is a bug in some versions of php. Bug reports, https://www.mail-archive.com/wikibugs-l@lists.wikimedia.org/msg312672.html Issue on facebook/php-webdriver, https://github.com/facebook/php-webdriver/issues/154 Issue on Codeception/Codeception, https://github.com/Codeception/Codeception/issues/1116 --- lib/net/URLChecker.php | 6 ++++++ lib/remote/HttpCommandExecutor.php | 5 +++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/net/URLChecker.php b/lib/net/URLChecker.php index 6223dfc28..894c2ca37 100644 --- a/lib/net/URLChecker.php +++ b/lib/net/URLChecker.php @@ -59,6 +59,12 @@ private function getHTTPResponseCode($timeout_in_ms, $url) { curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, self::CONNECT_TIMEOUT_MS); + // There is a PHP bug in some versions which didn't define the constant. + curl_setopt( + $ch, + 156, // CURLOPT_CONNECTTIMEOUT_MS + self::CONNECT_TIMEOUT_MS + ); $code = null; try { curl_exec($ch); diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index d7ab430b7..f01bec8cb 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -113,7 +113,6 @@ class HttpCommandExecutor implements WebDriverCommandExecutor { public function __construct($url) { $this->url = $url; $this->curl = curl_init(); - curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT_MS, 300000); curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); curl_setopt( @@ -124,6 +123,7 @@ public function __construct($url) { 'Accept: application/json', ) ); + $this->setTimeout(300000); } /** @@ -131,7 +131,8 @@ public function __construct($url) { * @return HttpCommandExecutor */ public function setTimeout($timeout) { - curl_setopt($this->curl, CURLOPT_CONNECTTIMEOUT_MS, $timeout); + // There is a PHP bug in some versions which didn't define the constant. + curl_setopt($this->curl, /* CURLOPT_CONNECTTIMEOUT_MS */ 156, $timeout); return $this; } From bcc76d8166957ce43947324201343571218ad669 Mon Sep 17 00:00:00 2001 From: Vernier Slenter Date: Thu, 30 Oct 2014 10:33:27 +0100 Subject: [PATCH 097/784] merged HTTP auth with latest version --- lib/remote/HttpCommandExecutor.php | 4 +++- lib/remote/RemoteWebDriver.php | 12 ++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index f01bec8cb..c88641981 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -110,11 +110,13 @@ class HttpCommandExecutor implements WebDriverCommandExecutor { /** * @param string $url */ - public function __construct($url) { + public function __construct($url, $auth_method, $auth_creds) { $this->url = $url; $this->curl = curl_init(); curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($this->curl, CURLOPT_HTTPAUTH, $auth_method); + curl_setopt($this->curl, CURLOPT_USERPWD, $auth_creds); curl_setopt( $this->curl, CURLOPT_HTTPHEADER, diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index 3675d5953..4896376ac 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -52,7 +52,9 @@ protected function __construct() {} public static function create( $url = 'http://localhost:4444/wd/hub', $desired_capabilities = null, - $timeout_in_ms = 300000 + $timeout_in_ms = 300000, + $auth_method = null, + $auth_creds = null ) { $url = preg_replace('#/+$#', '', $url); @@ -62,7 +64,7 @@ public static function create( $desired_capabilities = $desired_capabilities->toArray(); } - $executor = new HttpCommandExecutor($url); + $executor = new HttpCommandExecutor($url, $auth_method, $auth_creds); $executor->setTimeout($timeout_in_ms); $command = new WebDriverCommand( @@ -92,11 +94,13 @@ public static function create( */ public static function createBySessionID( $session_id, - $url = 'http://localhost:4444/wd/hub' + $url = 'http://localhost:4444/wd/hub', + $auth_method = CURLAUTH_ANY, + $auth_creds = null ) { $driver = new static(); $driver->setSessionID($session_id) - ->setCommandExecutor(new HttpCommandExecutor($url)); + ->setCommandExecutor(new HttpCommandExecutor($url, $auth_method, $auth_creds)); return $driver; } From 2dad5561e4a6ecc0d220bc739921bab4fbce0a6e Mon Sep 17 00:00:00 2001 From: Vernier Slenter Date: Thu, 30 Oct 2014 10:37:07 +0100 Subject: [PATCH 098/784] set default auth to none --- lib/remote/RemoteWebDriver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index 4896376ac..9bc9769ec 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -95,7 +95,7 @@ public static function create( public static function createBySessionID( $session_id, $url = 'http://localhost:4444/wd/hub', - $auth_method = CURLAUTH_ANY, + $auth_method = null, $auth_creds = null ) { $driver = new static(); From f711b6623043ed2f39713e7211eef9ce288c48d9 Mon Sep 17 00:00:00 2001 From: Vernier Slenter Date: Thu, 30 Oct 2014 10:41:09 +0100 Subject: [PATCH 099/784] space instead of tab indentation --- lib/remote/RemoteWebDriver.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index 9bc9769ec..638c44432 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -95,8 +95,8 @@ public static function create( public static function createBySessionID( $session_id, $url = 'http://localhost:4444/wd/hub', - $auth_method = null, - $auth_creds = null + $auth_method = null, + $auth_creds = null ) { $driver = new static(); $driver->setSessionID($session_id) From 8873e3b4eeb6e1d46a3ffa64ccb3a2ecdbb8e7f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1nos=20P=C3=A1sztor?= Date: Fri, 31 Oct 2014 11:28:10 +0100 Subject: [PATCH 100/784] Update composer.json Updated composer.json for packagist publishing --- composer.json | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 00faaa7bf..24f37c8fd 100644 --- a/composer.json +++ b/composer.json @@ -1,14 +1,13 @@ { - "name": "facebook/webdriver", - "description": "A php client for WebDriver", - "keywords": ["webdriver", "selenium", "php", "facebook"], - "homepage": "https://github.com/facebook/php-webdriver", + "name": "janoszen/webdriver", + "description": "A php client for WebDriver (fork of facebook/webdriver)", + "keywords": ["webdriver", "selenium", "php"], + "homepage": "https://github.com/janoszen/php-webdriver", "type": "library", "license": "Apache-2.0", "support": { - "issues": "https://github.com/facebook/php-webdriver/issues", - "forum": "https://www.facebook.com/groups/phpwebdriver/", - "source": "https://github.com/facebook/php-webdriver" + "issues": "https://github.com/janoszen/php-webdriver/issues", + "source": "https://github.com/janoszen/php-webdriver" }, "require": { "php": ">=5.3.19" From f88c2744bb0c722f345ec12df4691e3c673443e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1nos=20P=C3=A1sztor?= Date: Fri, 31 Oct 2014 11:29:26 +0100 Subject: [PATCH 101/784] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d5272c4f4..85047203d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ php-webdriver -- WebDriver bindings for PHP =========================================== +Attention! This is a fork of facebook/webdriver and has been altered to include namespacing to avoid naming collisions. + ## DESCRIPTION This WebDriver client aims to be as close as possible to bindings in other languages. The concepts are very similar to the Java, .NET, Python and Ruby bindings for WebDriver. From 1f3fb9d9736e73839d0328fa2d05e4147c5999e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1nos=20P=C3=A1sztor?= Date: Fri, 31 Oct 2014 11:30:48 +0100 Subject: [PATCH 102/784] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 85047203d..657d6ad73 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,11 @@ Any complaint, question, idea? You can post it on the user group https://www.fac git clone git@github.com:facebook/php-webdriver.git ### Packagist -Add the dependency. https://packagist.org/packages/facebook/webdriver +Add the dependency. https://packagist.org/packages/janoszen/webdriver { "require": { - "facebook/webdriver": "dev-master" + "janoszen/webdriver": "dev-master" } } @@ -100,8 +100,8 @@ If you're reading this you've already found our Github repository. If you have a We love to have your help to make php-webdriver better. Feel free to -* open an [issue](https://github.com/facebook/php-webdriver/issues) if you run into any problem. -* fork the project and submit [pull request](https://github.com/facebook/php-webdriver/pulls). Before the pull requests can be accepted, a [Contributors Licensing Agreement](http://developers.facebook.com/opensource/cla) must be signed. +* open an [issue](https://github.com/janoszen/php-webdriver/issues) if you run into any problem. +* fork the project and submit [pull request](https://github.com/janoszen/php-webdriver/pulls). Before the pull requests can be accepted, a [Contributors Licensing Agreement](http://developers.facebook.com/opensource/cla) must be signed. When you are going to contribute, please keep in mind that this webdriver client aims to be as close as possible to other languages Java/Ruby/Python/C#. FYI, here is the overview of [the official Java API](http://selenium.googlecode.com/svn/trunk/docs/api/java/index.html?overview-summary.html) From 85c149dd60f526ad712c80ea51c6f0f0e0aa2bcb Mon Sep 17 00:00:00 2001 From: Vernier Slenter Date: Fri, 31 Oct 2014 11:42:45 +0100 Subject: [PATCH 103/784] try to get credentias from url using regex --- lib/remote/HttpCommandExecutor.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index c88641981..9dbd200ea 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -111,11 +111,17 @@ class HttpCommandExecutor implements WebDriverCommandExecutor { * @param string $url */ public function __construct($url, $auth_method, $auth_creds) { - $this->url = $url; + + preg_match("/^http[s]?//(.*):(.*)@.*/", $url, $matches); + + print "matches:\n" + print_r($matches); + + $this->url = $url; $this->curl = curl_init(); curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($this->curl, CURLOPT_HTTPAUTH, $auth_method); + curl_setopt($this->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); curl_setopt($this->curl, CURLOPT_USERPWD, $auth_creds); curl_setopt( $this->curl, From 456a6ddecfa6ba57b404261681b9c411fd2503a4 Mon Sep 17 00:00:00 2001 From: Vernier Slenter Date: Fri, 31 Oct 2014 11:44:35 +0100 Subject: [PATCH 104/784] syntax error --- lib/remote/HttpCommandExecutor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index 9dbd200ea..b41c4780b 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -114,7 +114,7 @@ public function __construct($url, $auth_method, $auth_creds) { preg_match("/^http[s]?//(.*):(.*)@.*/", $url, $matches); - print "matches:\n" + print "matches:\n"; print_r($matches); $this->url = $url; From 17d668425c68d14743d517f7f0a931c474117219 Mon Sep 17 00:00:00 2001 From: Vernier Slenter Date: Fri, 31 Oct 2014 11:46:09 +0100 Subject: [PATCH 105/784] escaping error in regex --- lib/remote/HttpCommandExecutor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index b41c4780b..f5b8c5e74 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -112,7 +112,7 @@ class HttpCommandExecutor implements WebDriverCommandExecutor { */ public function __construct($url, $auth_method, $auth_creds) { - preg_match("/^http[s]?//(.*):(.*)@.*/", $url, $matches); + preg_match("/^http[s]?\/\/(.*):(.*)@.*/", $url, $matches); print "matches:\n"; print_r($matches); From 4f47b3fcb16e15ffd33e56712f8a3e7760fa9391 Mon Sep 17 00:00:00 2001 From: Vernier Slenter Date: Fri, 31 Oct 2014 12:07:19 +0100 Subject: [PATCH 106/784] fixed regex --- lib/remote/HttpCommandExecutor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index f5b8c5e74..8e85ca084 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -112,7 +112,7 @@ class HttpCommandExecutor implements WebDriverCommandExecutor { */ public function __construct($url, $auth_method, $auth_creds) { - preg_match("/^http[s]?\/\/(.*):(.*)@.*/", $url, $matches); + preg_match("/^https?:\/\/(.*):(.*)@.*/U", $url, $matches); print "matches:\n"; print_r($matches); From a72065a13639c3d5eb4ff1555433a4567ed15845 Mon Sep 17 00:00:00 2001 From: Vernier Slenter Date: Fri, 31 Oct 2014 12:10:03 +0100 Subject: [PATCH 107/784] debug --- lib/remote/HttpCommandExecutor.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index 8e85ca084..87d92cb62 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -114,6 +114,7 @@ public function __construct($url, $auth_method, $auth_creds) { preg_match("/^https?:\/\/(.*):(.*)@.*/U", $url, $matches); + print "url:\n$url\n"; print "matches:\n"; print_r($matches); From be999f3555e93ac55f2e88dcf2fcad11f543ac1f Mon Sep 17 00:00:00 2001 From: Vernier Slenter Date: Fri, 31 Oct 2014 12:13:29 +0100 Subject: [PATCH 108/784] tweaked the regex some more --- lib/remote/HttpCommandExecutor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index 87d92cb62..e11d23764 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -112,7 +112,7 @@ class HttpCommandExecutor implements WebDriverCommandExecutor { */ public function __construct($url, $auth_method, $auth_creds) { - preg_match("/^https?:\/\/(.*):(.*)@.*/U", $url, $matches); + preg_match("/^(https?:\/\/)(.*):(.*)@(.*)/U", $url, $matches); print "url:\n$url\n"; print "matches:\n"; From d35fd19c845a0731e47d36fc84552b08e73da10f Mon Sep 17 00:00:00 2001 From: Vernier Slenter Date: Fri, 31 Oct 2014 13:30:08 +0100 Subject: [PATCH 109/784] fix regex --- lib/remote/HttpCommandExecutor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index e11d23764..2ef953bdb 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -112,7 +112,7 @@ class HttpCommandExecutor implements WebDriverCommandExecutor { */ public function __construct($url, $auth_method, $auth_creds) { - preg_match("/^(https?:\/\/)(.*):(.*)@(.*)/U", $url, $matches); + preg_match("/^(https?:\/\/)(.*):(.*)@(.*?)/U", $url, $matches); print "url:\n$url\n"; print "matches:\n"; From 386f7f9957a9a0416276af6c842ba9339c908d22 Mon Sep 17 00:00:00 2001 From: Vernier Slenter Date: Fri, 31 Oct 2014 13:34:14 +0100 Subject: [PATCH 110/784] get the creds from regex --- lib/remote/HttpCommandExecutor.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index 2ef953bdb..a06c68064 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -113,10 +113,11 @@ class HttpCommandExecutor implements WebDriverCommandExecutor { public function __construct($url, $auth_method, $auth_creds) { preg_match("/^(https?:\/\/)(.*):(.*)@(.*?)/U", $url, $matches); - + $url = $matches[1].$matches[4]; + $auth_creds = $matches[2].":".$matches[3]; print "url:\n$url\n"; - print "matches:\n"; - print_r($matches); + //print "matches:\n"; + //print_r($matches); $this->url = $url; $this->curl = curl_init(); From 4304bcec899ee7053ff2ac6621f458d7d45ba460 Mon Sep 17 00:00:00 2001 From: Vernier Slenter Date: Fri, 31 Oct 2014 13:38:04 +0100 Subject: [PATCH 111/784] removed auth arguments --- lib/remote/HttpCommandExecutor.php | 3 ++- lib/remote/RemoteWebDriver.php | 12 ++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index a06c68064..1300f4131 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -110,8 +110,9 @@ class HttpCommandExecutor implements WebDriverCommandExecutor { /** * @param string $url */ - public function __construct($url, $auth_method, $auth_creds) { + public function __construct($url) { + // Get credentials from $url (if any) preg_match("/^(https?:\/\/)(.*):(.*)@(.*?)/U", $url, $matches); $url = $matches[1].$matches[4]; $auth_creds = $matches[2].":".$matches[3]; diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index 638c44432..3675d5953 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -52,9 +52,7 @@ protected function __construct() {} public static function create( $url = 'http://localhost:4444/wd/hub', $desired_capabilities = null, - $timeout_in_ms = 300000, - $auth_method = null, - $auth_creds = null + $timeout_in_ms = 300000 ) { $url = preg_replace('#/+$#', '', $url); @@ -64,7 +62,7 @@ public static function create( $desired_capabilities = $desired_capabilities->toArray(); } - $executor = new HttpCommandExecutor($url, $auth_method, $auth_creds); + $executor = new HttpCommandExecutor($url); $executor->setTimeout($timeout_in_ms); $command = new WebDriverCommand( @@ -94,13 +92,11 @@ public static function create( */ public static function createBySessionID( $session_id, - $url = 'http://localhost:4444/wd/hub', - $auth_method = null, - $auth_creds = null + $url = 'http://localhost:4444/wd/hub' ) { $driver = new static(); $driver->setSessionID($session_id) - ->setCommandExecutor(new HttpCommandExecutor($url, $auth_method, $auth_creds)); + ->setCommandExecutor(new HttpCommandExecutor($url)); return $driver; } From d477c2c664a7f45b70b2947ea88250e09c926363 Mon Sep 17 00:00:00 2001 From: Vernier Slenter Date: Fri, 31 Oct 2014 13:45:39 +0100 Subject: [PATCH 112/784] check if creds have been found --- lib/remote/HttpCommandExecutor.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index 1300f4131..bf661b27e 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -114,11 +114,13 @@ public function __construct($url) { // Get credentials from $url (if any) preg_match("/^(https?:\/\/)(.*):(.*)@(.*?)/U", $url, $matches); - $url = $matches[1].$matches[4]; - $auth_creds = $matches[2].":".$matches[3]; + if(array_key_exists($matches[4])){ + $url = $matches[1].$matches[4]; + $auth_creds = $matches[2].":".$matches[3]; + } print "url:\n$url\n"; - //print "matches:\n"; - //print_r($matches); + print "matches:\n"; + print_r($matches); $this->url = $url; $this->curl = curl_init(); From a9849d8d86c6c5602a412e042c4b2dab275ec379 Mon Sep 17 00:00:00 2001 From: Vernier Slenter Date: Fri, 31 Oct 2014 13:47:03 +0100 Subject: [PATCH 113/784] whoopsie --- lib/remote/HttpCommandExecutor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index bf661b27e..451fd83e7 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -114,7 +114,7 @@ public function __construct($url) { // Get credentials from $url (if any) preg_match("/^(https?:\/\/)(.*):(.*)@(.*?)/U", $url, $matches); - if(array_key_exists($matches[4])){ + if(array_key_exists(4, $matches)){ $url = $matches[1].$matches[4]; $auth_creds = $matches[2].":".$matches[3]; } From cc18cb2a391ae6936b9e3289507aa3cece3b90ca Mon Sep 17 00:00:00 2001 From: Vernier Slenter Date: Fri, 31 Oct 2014 13:52:53 +0100 Subject: [PATCH 114/784] cleanup --- lib/remote/HttpCommandExecutor.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index 451fd83e7..eb4521814 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -118,16 +118,15 @@ public function __construct($url) { $url = $matches[1].$matches[4]; $auth_creds = $matches[2].":".$matches[3]; } - print "url:\n$url\n"; - print "matches:\n"; - print_r($matches); $this->url = $url; $this->curl = curl_init(); curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($this->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_setopt($this->curl, CURLOPT_USERPWD, $auth_creds); + if(strlen($auth_creds) > 0){ + curl_setopt($this->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_setopt($this->curl, CURLOPT_USERPWD, $auth_creds); + } curl_setopt( $this->curl, CURLOPT_HTTPHEADER, From 46d14c74cf0851ff96178e691dada0f5bfa65988 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Fri, 31 Oct 2014 16:42:19 -0700 Subject: [PATCH 115/784] FirefoxProfile on Windows Windows uses \ as the DIRECTORY_SEPARATOR which is not compatible with the regex matching in FirefoxProfile. --- lib/firefox/FirefoxProfile.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/firefox/FirefoxProfile.php b/lib/firefox/FirefoxProfile.php index af2184464..4e0c063bb 100644 --- a/lib/firefox/FirefoxProfile.php +++ b/lib/firefox/FirefoxProfile.php @@ -80,7 +80,12 @@ public function encode() { if (is_dir($name)) { continue; } - $path = preg_replace("#^{$temp_dir}/#", "", $name); + $dir_prefix = preg_replace( + '#\\\\#', + '\\\\\\\\', + $temp_dir.DIRECTORY_SEPARATOR + ); + $path = preg_replace("#^{$dir_prefix}#", "", $name); $zip->addFile($name, $path); } $zip->close(); From f666d1d41aebc9b663ed20a2ffe748d9a34a29f5 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Tue, 4 Nov 2014 14:06:19 -0800 Subject: [PATCH 116/784] Fix a curl connect timeout issue We are seeing error like this. `'WebDriverCurlException' with message 'Curl error thrown for http POST to /session/38719813-dd76-4d78-838c-491016a2f4cf/url with params: {"url":"https:\/\/www.facebook.com\/"}` This is because the default value for CURLOPT_TIMEOUT_MS is too small. Change it to a reasonable value. --- lib/remote/HttpCommandExecutor.php | 5 +++-- lib/remote/RemoteWebDriver.php | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index 51b0870fb..5942a632d 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -133,14 +133,15 @@ public function __construct($url) { 'Accept: application/json', ) ); - $this->setTimeout(300000); + curl_setopt($this->curl, CURLOPT_TIMEOUT_MS, 300000); + $this->setConnectionTimeout(300000); } /** * @param int $timeout * @return HttpCommandExecutor */ - public function setTimeout($timeout) { + public function setConnectionTimeout($timeout) { // There is a PHP bug in some versions which didn't define the constant. curl_setopt($this->curl, /* CURLOPT_CONNECTTIMEOUT_MS */ 156, $timeout); return $this; diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index 3675d5953..881ccc9aa 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -63,7 +63,7 @@ public static function create( } $executor = new HttpCommandExecutor($url); - $executor->setTimeout($timeout_in_ms); + $executor->setConnectionTimeout($timeout_in_ms); $command = new WebDriverCommand( null, From 98894fc72f370e7a190a933f29f03f2c3f2323c0 Mon Sep 17 00:00:00 2001 From: Gabriel Preston Date: Tue, 4 Nov 2014 14:47:55 -0800 Subject: [PATCH 117/784] Fix for creating a new session New sessions should follow up a 300 level redirect with a GET instead of forcing another POST. --- lib/remote/HttpCommandExecutor.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index 5942a632d..359d6a0e9 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -184,7 +184,13 @@ public function execute(WebDriverCommand $command) { } curl_setopt($this->curl, CURLOPT_URL, $this->url . $url); - curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $http_method); + switch ($command->getName()) { + case 'newSession': + curl_setopt($this->curl, CURLOPT_POST, 1); + break; + default: + curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $http_method); + } $encoded_params = null; if ($http_method === 'POST' && $params && is_array($params)) { $encoded_params = json_encode($params); From ad8cedc34488626307b0e4e380899182600a2655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Mon, 10 Nov 2014 10:33:18 +0100 Subject: [PATCH 118/784] Fix missing return in DesiredCapabilities getter --- lib/remote/DesiredCapabilities.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/remote/DesiredCapabilities.php b/lib/remote/DesiredCapabilities.php index d0942d112..82fadf244 100644 --- a/lib/remote/DesiredCapabilities.php +++ b/lib/remote/DesiredCapabilities.php @@ -55,7 +55,7 @@ public function setVersion($version) { * @return mixed The value of a capability. */ public function getCapability($name) { - $this->get($name); + return $this->get($name); } /** From ae5df3a41cf7a316fc52d0c7dec30761e95eabc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=83=D0=BD=D0=B4=D1=83=D0=BA=D0=BE=D0=B2=20=D0=90?= =?UTF-8?q?=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B9?= Date: Thu, 20 Nov 2014 12:53:18 +0400 Subject: [PATCH 119/784] Add get all sessions method --- lib/remote/HttpCommandExecutor.php | 1 + lib/remote/RemoteWebDriver.php | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index a8428d3f5..f8f104511 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -23,6 +23,7 @@ class HttpCommandExecutor implements WebDriverCommandExecutor { * http://code.google.com/p/selenium/wiki/JsonWireProtocol#Command_Reference */ protected static $commands = array( + DriverCommand::GET_ALL_SESSIONS => array('method' => 'GET', 'url' => '/sessions'), DriverCommand::ACCEPT_ALERT => array('method' => 'POST', 'url' => '/session/:sessionId/accept_alert'), DriverCommand::ADD_COOKIE => array('method' => 'POST', 'url' => '/session/:sessionId/cookie'), DriverCommand::CLEAR_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/clear'), diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index 881ccc9aa..4d40a8831 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -461,6 +461,29 @@ public function getSessionID() { return $this->sessionID; } + /** + * Get all selenium sessions. + * + * @param string $url The url of the remote server + * @param int $timeout_in_ms + * @return array + */ + public static function getAllSessions( + $url = 'http://localhost:4444/wd/hub', + $timeout_in_ms = 300000 + ) { + $executor = new HttpCommandExecutor($url); + $executor->setConnectionTimeout($timeout_in_ms); + + $command = new WebDriverCommand( + null, + DriverCommand::GET_ALL_SESSIONS, + array() + ); + + return $executor->execute($command)->getValue(); + } + public function execute($command_name, $params = array()) { $command = new WebDriverCommand( $this->sessionID, From b474dec77d0998d1eec1cce606c7e63a3a626342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 21 Nov 2014 12:14:31 +0100 Subject: [PATCH 120/784] Do not hardcode CURL's request timeout, added ability to set custom timeout. --- lib/remote/HttpCommandExecutor.php | 25 +++++++++++++++++++------ lib/remote/RemoteWebDriver.php | 1 + 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index a8428d3f5..78dd95d85 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -133,24 +133,37 @@ public function __construct($url) { 'Accept: application/json', ) ); - curl_setopt($this->curl, CURLOPT_TIMEOUT_MS, 300000); + + $this->setRequestTimeout(300000); $this->setConnectionTimeout(300000); } /** - * @param int $timeout + * Set timeout for the connect phase + * + * @param int $timeout_in_ms Timeout in milliseconds * @return HttpCommandExecutor */ - public function setConnectionTimeout($timeout) { + public function setConnectionTimeout($timeout_in_ms) { // There is a PHP bug in some versions which didn't define the constant. - curl_setopt($this->curl, /* CURLOPT_CONNECTTIMEOUT_MS */ 156, $timeout); + curl_setopt($this->curl, /* CURLOPT_CONNECTTIMEOUT_MS */ 156, $timeout_in_ms); return $this; } /** - * @param WebDriverCommand $command - * @param array $curl_opts An array of curl options. + * Set maximum time the request is allowed to take * + * @param int $timeout_in_ms Timeout in milliseconds + * @return HttpCommandExecutor + */ + public function setRequestTimeout($timeout_in_ms) + { + curl_setopt($this->curl, CURLOPT_TIMEOUT_MS, $timeout_in_ms); + return $this; + } + + /** + * @param WebDriverCommand $command * @return mixed */ public function execute(WebDriverCommand $command) { diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index 881ccc9aa..e589c04cb 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -64,6 +64,7 @@ public static function create( $executor = new HttpCommandExecutor($url); $executor->setConnectionTimeout($timeout_in_ms); + $executor->setRequestTimeout($timeout_in_ms); $command = new WebDriverCommand( null, From b4a697243597da8686c82563e6b97c03e11b90ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 26 Nov 2014 01:00:44 +0100 Subject: [PATCH 121/784] Improve PHPDoc - missing @params, variable types, inconsistencies, typos etc. --- lib/WebDriver.php | 3 ++ lib/WebDriverAlert.php | 1 + lib/WebDriverBy.php | 9 ++++++ lib/WebDriverCapabilities.php | 2 ++ lib/WebDriverCommandExecutor.php | 1 + lib/WebDriverElement.php | 4 +-- lib/WebDriverExceptions.php | 19 ++++++++++-- lib/WebDriverExpectedCondition.php | 8 ++--- lib/WebDriverKeys.php | 2 +- lib/WebDriverMouse.php | 8 +++++ lib/WebDriverNavigation.php | 1 + lib/WebDriverOptions.php | 4 ++- lib/WebDriverPoint.php | 4 +++ lib/WebDriverWait.php | 1 + lib/WebDriverWindow.php | 6 ++-- lib/chrome/ChromeOptions.php | 4 +-- lib/firefox/FirefoxProfile.php | 2 +- lib/interactions/WebDriverActions.php | 30 +++++++++++++++++++ lib/interactions/WebDriverCompositeAction.php | 1 + lib/interactions/WebDriverTouchActions.php | 20 +++++++++++++ lib/interactions/WebDriverTouchScreen.php | 3 +- .../internal/WebDriverKeysRelatedAction.php | 5 ++++ .../internal/WebDriverSendKeysAction.php | 6 ++++ .../touch/WebDriverDownAction.php | 5 ++++ .../touch/WebDriverFlickAction.php | 5 ++++ .../touch/WebDriverFlickFromElementAction.php | 7 +++++ .../touch/WebDriverMoveAction.php | 5 ++++ .../touch/WebDriverScrollAction.php | 5 ++++ .../WebDriverScrollFromElementAction.php | 6 ++++ .../touch/WebDriverTouchAction.php | 4 +++ lib/interactions/touch/WebDriverUpAction.php | 5 ++++ lib/net/URLChecker.php | 2 -- lib/remote/DesiredCapabilities.php | 14 ++++++++- lib/remote/HttpCommandExecutor.php | 2 -- lib/remote/RemoteExecuteMethod.php | 2 ++ lib/support/events/EventFiringWebDriver.php | 2 +- lib/support/events/EventFiringWebElement.php | 4 +-- tests/functional/WebDriverTestCase.php | 3 ++ tests/functional/html/upload.html | 2 +- 39 files changed, 190 insertions(+), 27 deletions(-) diff --git a/lib/WebDriver.php b/lib/WebDriver.php index 2f4515774..6c8ea3ea0 100755 --- a/lib/WebDriver.php +++ b/lib/WebDriver.php @@ -28,6 +28,7 @@ public function close(); /** * Load a new web page in the current browser window. * + * @param string $url * @return WebDriver The current instance. */ public function get($url); @@ -91,6 +92,8 @@ public function takeScreenshot($save_as = null); * WebDriverExpectedCondition::titleIs('WebDriver Page') * ); * + * @param int $timeout_in_second + * @param int $interval_in_millisecond * @return WebDriverWait */ public function wait( diff --git a/lib/WebDriverAlert.php b/lib/WebDriverAlert.php index aa731402d..5a735371b 100644 --- a/lib/WebDriverAlert.php +++ b/lib/WebDriverAlert.php @@ -56,6 +56,7 @@ public function getText() { /** * Send keystrokes to javascript prompt() dialog * + * @param string $value * @return WebDriverAlert */ public function sendKeys($value) { diff --git a/lib/WebDriverBy.php b/lib/WebDriverBy.php index 7e0e9cce0..3409afd25 100644 --- a/lib/WebDriverBy.php +++ b/lib/WebDriverBy.php @@ -48,6 +48,7 @@ public function getValue() { * Locates elements whose class name contains the search value; compound class * names are not permitted. * + * @param string $class_name * @return WebDriverBy */ public static function className($class_name) { @@ -57,6 +58,7 @@ public static function className($class_name) { /** * Locates elements matching a CSS selector. * + * @param string $css_selector * @return WebDriverBy */ public static function cssSelector($css_selector) { @@ -66,6 +68,7 @@ public static function cssSelector($css_selector) { /** * Locates elements whose ID attribute matches the search value. * + * @param string $id * @return WebDriverBy */ public static function id($id) { @@ -74,6 +77,8 @@ public static function id($id) { /** * Locates elements whose NAME attribute matches the search value. + * + * @param string $name * @return WebDriverBy */ public static function name($name) { @@ -83,6 +88,7 @@ public static function name($name) { /** * Locates anchor elements whose visible text matches the search value. * + * @param string $link_text * @return WebDriverBy */ public static function linkText($link_text) { @@ -93,6 +99,7 @@ public static function linkText($link_text) { * Locates anchor elements whose visible text partially matches the search * value. * + * @param string $partial_link_text * @return WebDriverBy */ public static function partialLinkText($partial_link_text) { @@ -102,6 +109,7 @@ public static function partialLinkText($partial_link_text) { /** * Locates elements whose tag name matches the search value. * + * @param string $tag_name * @return WebDriverBy */ public static function tagName($tag_name) { @@ -111,6 +119,7 @@ public static function tagName($tag_name) { /** * Locates elements matching an XPath expression. * + * @param string $xpath * @return WebDriverBy */ public static function xpath($xpath) { diff --git a/lib/WebDriverCapabilities.php b/lib/WebDriverCapabilities.php index 3eb65f474..1e70efb2c 100644 --- a/lib/WebDriverCapabilities.php +++ b/lib/WebDriverCapabilities.php @@ -21,6 +21,7 @@ interface WebDriverCapabilities { public function getBrowserName(); /** + * @param string $name * @return mixed The value of a capability. */ public function getCapability($name); @@ -36,6 +37,7 @@ public function getPlatform(); public function getVersion(); /** + * @param string $capability_name * @return bool Whether the value is not null and not false. */ public function is($capability_name); diff --git a/lib/WebDriverCommandExecutor.php b/lib/WebDriverCommandExecutor.php index 481a9336a..ea1864f49 100644 --- a/lib/WebDriverCommandExecutor.php +++ b/lib/WebDriverCommandExecutor.php @@ -19,6 +19,7 @@ interface WebDriverCommandExecutor { /** + * @param WebDriverCommand $command * @return mixed */ public function execute(WebDriverCommand $command); diff --git a/lib/WebDriverElement.php b/lib/WebDriverElement.php index 81bbbd5f6..62a0a1543 100644 --- a/lib/WebDriverElement.php +++ b/lib/WebDriverElement.php @@ -52,7 +52,7 @@ public function getCSSValue($css_property_name); /** * Get the location of element relative to the top-left corner of the page. * - * @return WebDriverLocation The location of the element. + * @return WebDriverPoint The location of the element. */ public function getLocation(); @@ -60,7 +60,7 @@ public function getLocation(); * Try scrolling the element into the view port and return the location of * element relative to the top-left corner of the page afterwards. * - * @return WebDriverLocation The location of the element. + * @return WebDriverPoint The location of the element. */ public function getLocationOnScreenOnceScrolledIntoView(); diff --git a/lib/WebDriverExceptions.php b/lib/WebDriverExceptions.php index b0d1f47a1..a098ec7f5 100644 --- a/lib/WebDriverExceptions.php +++ b/lib/WebDriverExceptions.php @@ -19,11 +19,18 @@ class WebDriverException extends Exception { private $results; + /** + * @param string $message + * @param mixed $results + */ public function __construct($message, $results = null) { parent::__construct($message); $this->results = $results; } + /** + * @return mixed + */ public function getResults() { return $this->results; } @@ -32,6 +39,10 @@ public function getResults() { * Throw WebDriverExceptions. * For $status_code >= 0, they are errors defined in the json wired protocol. * For $status_code < 0, they are errors defined in php-webdriver. + * + * @param int $status_code + * @param string $message + * @param mixed $results */ public static function throwException($status_code, $message, $results) { switch ($status_code) { @@ -154,9 +165,13 @@ class UnrecognizedExceptionException extends WebDriverException {} class UnexpectedTagNameException extends WebDriverException { + /** + * @param string $expected_tag_name + * @param string $actual_tag_name + */ public function __construct( - string $expected_tag_name, - string $actual_tag_name) { + $expected_tag_name, + $actual_tag_name) { parent::__construct( sprintf( "Element should have been \"%s\" but was \"%s\"", diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index a08a37a58..283db89e0 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -40,7 +40,7 @@ protected function __construct($apply) { /** * An expectation for checking the title of a page. * - * @param string title The expected title, which must be an exact match. + * @param string $title The expected title, which must be an exact match. * @return WebDriverExpectedCondition True when the title matches, * false otherwise. */ @@ -55,7 +55,7 @@ function ($driver) use ($title) { /** * An expectation for checking substring of a page Title. * - * @param string title The expected substring of Title. + * @param string $title The expected substring of Title. * @return WebDriverExpectedCondition True when in title, * false otherwise. */ @@ -187,7 +187,7 @@ function ($driver) use ($by, $text) { * Expectation for checking if iFrame exists. * If iFrame exists switches driver's focus to the iFrame * - * @param string frame_locator The locator used to find the iFrame + * @param string $frame_locator The locator used to find the iFrame * expected to be either the id or name value of the i/frame * @return WebDriverExpectedCondition object focused on new frame * when frame is found bool false otherwise @@ -328,7 +328,7 @@ function ($driver) use ($condition) { /** * An expectation for checking if the given element is selected. * - * @param mixed element_or_by Either the element or the locator. + * @param mixed $element_or_by Either the element or the locator. * @return WebDriverExpectedCondition whether the element is selected. */ public static function elementToBeSelected($element_or_by) { diff --git a/lib/WebDriverKeys.php b/lib/WebDriverKeys.php index ae2b0875e..a471ead1b 100644 --- a/lib/WebDriverKeys.php +++ b/lib/WebDriverKeys.php @@ -86,7 +86,7 @@ class WebDriverKeys { /** * Encode input of `sendKeys()`. - * @params string|array $keys + * @param string|array $keys * @return array */ public static function encode($keys) { diff --git a/lib/WebDriverMouse.php b/lib/WebDriverMouse.php index fce57601d..624a25c34 100644 --- a/lib/WebDriverMouse.php +++ b/lib/WebDriverMouse.php @@ -19,26 +19,33 @@ interface WebDriverMouse { /** + * @param WebDriverCoordinates $where * @return WebDriverMouse */ public function click(WebDriverCoordinates $where); /** + * @param WebDriverCoordinates $where * @return WebDriverMouse */ public function contextClick(WebDriverCoordinates $where); /** + * @param WebDriverCoordinates $where * @return WebDriverMouse */ public function doubleClick(WebDriverCoordinates $where); /** + * @param WebDriverCoordinates $where * @return WebDriverMouse */ public function mouseDown(WebDriverCoordinates $where); /** + * @param WebDriverCoordinates $where + * @param int $x_offset + * @param int $y_offset * @return WebDriverMouse */ public function mouseMove(WebDriverCoordinates $where, @@ -46,6 +53,7 @@ public function mouseMove(WebDriverCoordinates $where, $y_offset = null); /** + * @param WebDriverCoordinates $where * @return WebDriverMouse */ public function mouseUp(WebDriverCoordinates $where); diff --git a/lib/WebDriverNavigation.php b/lib/WebDriverNavigation.php index 13c662ad0..919232efe 100644 --- a/lib/WebDriverNavigation.php +++ b/lib/WebDriverNavigation.php @@ -63,6 +63,7 @@ public function refresh() { /** * Navigate to the given URL. * + * @param string $url * @return WebDriverNavigation The instance. */ public function to($url) { diff --git a/lib/WebDriverOptions.php b/lib/WebDriverOptions.php index 98a6d07c2..61b5eb16f 100644 --- a/lib/WebDriverOptions.php +++ b/lib/WebDriverOptions.php @@ -65,6 +65,7 @@ public function deleteAllCookies() { /** * Delete the cookie with the give name. * + * @param string $name * @return WebDriverOptions The current instance. */ public function deleteCookieNamed($name) { @@ -78,6 +79,7 @@ public function deleteCookieNamed($name) { /** * Get the cookie with a given name. * + * @param string $name * @return array The cookie, or null if no cookie with the given name is * presented. */ @@ -141,7 +143,7 @@ public function window() { /** * Get the log for a given log type. Log buffer is reset after each request. * - * @param $logType The log type. + * @param string $log_type The log type. * @return array The list of log entries. * @see https://code.google.com/p/selenium/wiki/JsonWireProtocol#Log_Type */ diff --git a/lib/WebDriverPoint.php b/lib/WebDriverPoint.php index 74f78d74f..6992c15c7 100644 --- a/lib/WebDriverPoint.php +++ b/lib/WebDriverPoint.php @@ -46,6 +46,8 @@ public function getY() { /** * Set the point to a new position. * + * @param int $new_x + * @param int $new_y * @return WebDriverPoint The same instance with updated coordinates. */ public function move($new_x, $new_y) { @@ -57,6 +59,8 @@ public function move($new_x, $new_y) { /** * Move the current by offsets. * + * @param int $x_offset + * @param int $y_offset * @return WebDriverPoint The same instance with updated coordinates. */ public function moveBy($x_offset, $y_offset) { diff --git a/lib/WebDriverWait.php b/lib/WebDriverWait.php index 68b7b46f7..34d573552 100644 --- a/lib/WebDriverWait.php +++ b/lib/WebDriverWait.php @@ -40,6 +40,7 @@ public function __construct( * value is not falsey. * * @param (closure|WebDriverExpectedCondition) + * @param string $message * @return mixed The return value of $func_or_ec */ public function until($func_or_ec, $message = "") { diff --git a/lib/WebDriverWindow.php b/lib/WebDriverWindow.php index e0b940042..0bf86388b 100644 --- a/lib/WebDriverWindow.php +++ b/lib/WebDriverWindow.php @@ -75,8 +75,7 @@ public function maximize() { * Set the size of the current window. This will change the outer window * dimension, not just the view port. * - * @param int $width The target window width. - * @param int $height The target height height. + * @param WebDriverDimension $size * @return WebDriverWindow The instance. */ public function setSize(WebDriverDimension $size) { @@ -93,8 +92,7 @@ public function setSize(WebDriverDimension $size) { * Set the position of the current window. This is relative to the upper left * corner of the screen. * - * @param int $width The target window width. - * @param int $height The target height height. + * @param WebDriverPoint $position * @return WebDriverWindow The instance. */ public function setPosition(WebDriverPoint $position) { diff --git a/lib/chrome/ChromeOptions.php b/lib/chrome/ChromeOptions.php index cef9b04f8..54562d602 100644 --- a/lib/chrome/ChromeOptions.php +++ b/lib/chrome/ChromeOptions.php @@ -58,7 +58,7 @@ public function setBinary($path) { } /** - * @param array $args + * @param array $arguments * @return ChromeOptions */ public function addArguments(array $arguments) { @@ -96,7 +96,7 @@ public function addEncodedExtensions(array $encoded_extensions) { * Sets an experimental option which has not exposed officially. * * @param string $name - * @parma mixed $value + * @param mixed $value * @return ChromeOptions */ public function setExperimentalOption($name, $value) { diff --git a/lib/firefox/FirefoxProfile.php b/lib/firefox/FirefoxProfile.php index 4e0c063bb..203592168 100644 --- a/lib/firefox/FirefoxProfile.php +++ b/lib/firefox/FirefoxProfile.php @@ -136,7 +136,7 @@ private function createTempDirectory($prefix = '') { /** * @param string $xpi The path to the .xpi extension. - * @param string The path to the unzip directory. + * @param string $target_dir The path to the unzip directory. * @return FirefoxProfile */ private function extractTo($xpi, $target_dir) { diff --git a/lib/interactions/WebDriverActions.php b/lib/interactions/WebDriverActions.php index 301f1821a..e560db92b 100644 --- a/lib/interactions/WebDriverActions.php +++ b/lib/interactions/WebDriverActions.php @@ -41,6 +41,8 @@ public function perform() { /** * Mouse click. * If $element is provided, move to the middle of the element first. + * + * @param WebDriverElement $element * @return WebDriverActions */ public function click(WebDriverElement $element = null) { @@ -53,6 +55,8 @@ public function click(WebDriverElement $element = null) { /** * Mouse click and hold. * If $element is provided, move to the middle of the element first. + * + * @param WebDriverElement $element * @return WebDriverActions */ public function clickAndHold(WebDriverElement $element = null) { @@ -65,6 +69,8 @@ public function clickAndHold(WebDriverElement $element = null) { /** * Context-click (right click). * If $element is provided, move to the middle of the element first. + * + * @param WebDriverElement $element * @return WebDriverActions */ public function contextClick(WebDriverElement $element = null) { @@ -77,6 +83,8 @@ public function contextClick(WebDriverElement $element = null) { /** * Double click. * If $element is provided, move to the middle of the element first. + * + * @param WebDriverElement $element * @return WebDriverActions */ public function doubleClick(WebDriverElement $element = null) { @@ -88,6 +96,9 @@ public function doubleClick(WebDriverElement $element = null) { /** * Drag and drop from $source to $target. + * + * @param WebDriverElement $source + * @param WebDriverElement $target * @return WebDriverActions */ public function dragAndDrop(WebDriverElement $source, @@ -106,6 +117,10 @@ public function dragAndDrop(WebDriverElement $source, /** * Drag $source and drop by offset ($x_offset, $y_offset). + * + * @param WebDriverElement $source + * @param int $x_offset + * @param int $y_offset * @return WebDriverActions */ public function dragAndDropBy(WebDriverElement $source, @@ -125,6 +140,9 @@ public function dragAndDropBy(WebDriverElement $source, /** * Mouse move by offset. + * + * @param int $x_offset + * @param int $y_offset * @return WebDriverActions */ public function moveByOffset($x_offset, $y_offset) { @@ -137,6 +155,10 @@ public function moveByOffset($x_offset, $y_offset) { /** * Move to the middle of the given WebDriverElement. If offset are provided, * move the an offset from the top-left cornerof that element. + * + * @param WebDriverElement $element + * @param int $x_offset + * @param int $y_offset * @return WebDriverActions */ public function moveToElement(WebDriverElement $element, @@ -151,6 +173,8 @@ public function moveToElement(WebDriverElement $element, /** * Release the mouse button. * If $element is provided, move to the middle of the element first. + * + * @param WebDriverElement $element * @return WebDriverActions */ public function release(WebDriverElement $element = null) { @@ -165,6 +189,8 @@ public function release(WebDriverElement $element = null) { * If $element is provided, focus on that element first. * * @see WebDriverKeys for special keys like CONTROL, ALT, etc. + * @param WebDriverElement $element + * @param string $key * @return WebDriverActions */ public function keyDown(WebDriverElement $element = null, $key = null) { @@ -179,6 +205,8 @@ public function keyDown(WebDriverElement $element = null, $key = null) { * If $element is provided, focus on that element first. * * @see WebDriverKeys for special keys like CONTROL, ALT, etc. + * @param WebDriverElement $element + * @param string $key * @return WebDriverActions */ public function keyUp(WebDriverElement $element = null, $key = null) { @@ -193,6 +221,8 @@ public function keyUp(WebDriverElement $element = null, $key = null) { * If $element is provided, focus on that element first. * * @see WebDriverKeys for special keys like CONTROL, ALT, etc. + * @param WebDriverElement $element + * @param string $keys * @return WebDriverActions */ public function sendKeys(WebDriverElement $element = null, $keys = null) { diff --git a/lib/interactions/WebDriverCompositeAction.php b/lib/interactions/WebDriverCompositeAction.php index a8a7c9a34..8cb204b72 100644 --- a/lib/interactions/WebDriverCompositeAction.php +++ b/lib/interactions/WebDriverCompositeAction.php @@ -23,6 +23,7 @@ class WebDriverCompositeAction implements WebDriverAction { /** * Add an WebDriverAction to the sequence. * + * @param WebDriverAction $action * @return WebDriverCompositeAction The current instance. */ public function addAction(WebDriverAction $action) { diff --git a/lib/interactions/WebDriverTouchActions.php b/lib/interactions/WebDriverTouchActions.php index 31bfc7dde..38a5e76e4 100644 --- a/lib/interactions/WebDriverTouchActions.php +++ b/lib/interactions/WebDriverTouchActions.php @@ -52,6 +52,7 @@ public function __construct(WebDriver $driver) { } /** + * @param WebDriverElement $element * @return WebDriverTouchActions */ public function tap(WebDriverElement $element) { @@ -62,6 +63,8 @@ public function tap(WebDriverElement $element) { } /** + * @param int $x + * @param int $y * @return WebDriverTouchActions */ public function down($x, $y) { @@ -72,6 +75,8 @@ public function down($x, $y) { } /** + * @param int $x + * @param int $y * @return WebDriverTouchActions */ public function up($x, $y) { @@ -82,6 +87,8 @@ public function up($x, $y) { } /** + * @param int $x + * @param int $y * @return WebDriverTouchActions */ public function move($x, $y) { @@ -92,6 +99,8 @@ public function move($x, $y) { } /** + * @param int $x + * @param int $y * @return WebDriverTouchActions */ public function scroll($x, $y) { @@ -102,6 +111,9 @@ public function scroll($x, $y) { } /** + * @param WebDriverElement $element + * @param int $x + * @param int $y * @return WebDriverTouchActions */ public function scrollFromElement(WebDriverElement $element, $x, $y) { @@ -112,6 +124,7 @@ public function scrollFromElement(WebDriverElement $element, $x, $y) { } /** + * @param WebDriverElement $element * @return WebDriverTouchActions */ public function doubleTap(WebDriverElement $element) { @@ -122,6 +135,7 @@ public function doubleTap(WebDriverElement $element) { } /** + * @param WebDriverElement $element * @return WebDriverTouchActions */ public function longPress(WebDriverElement $element) { @@ -132,6 +146,8 @@ public function longPress(WebDriverElement $element) { } /** + * @param int $x + * @param int $y * @return WebDriverTouchActions */ public function flick($x, $y) { @@ -142,6 +158,10 @@ public function flick($x, $y) { } /** + * @param WebDriverElement $element + * @param int $x + * @param int $y + * @param int $speed * @return WebDriverTouchActions */ public function flickFromElement(WebDriverElement $element, $x, $y, $speed) { diff --git a/lib/interactions/WebDriverTouchScreen.php b/lib/interactions/WebDriverTouchScreen.php index 0b739f13b..d38a8bccf 100644 --- a/lib/interactions/WebDriverTouchScreen.php +++ b/lib/interactions/WebDriverTouchScreen.php @@ -47,7 +47,7 @@ public function down($x, $y); * Flick on the touch screen using finger motion events. Use this flick * command if you don't care where the flick starts on the screen. * - * @param int $xpeed + * @param int $xspeed * @param int $yspeed * @return $this */ @@ -69,6 +69,7 @@ public function flickFromElement( /** * Long press on the touch screen using finger motion events. * + * @param WebDriverElement $element * @return $this */ public function longPress(WebDriverElement $element); diff --git a/lib/interactions/internal/WebDriverKeysRelatedAction.php b/lib/interactions/internal/WebDriverKeysRelatedAction.php index 1e334fb22..c97069d87 100644 --- a/lib/interactions/internal/WebDriverKeysRelatedAction.php +++ b/lib/interactions/internal/WebDriverKeysRelatedAction.php @@ -22,6 +22,11 @@ abstract class WebDriverKeysRelatedAction { protected $mouse; protected $locationProvider; + /** + * @param WebDriverKeyboard $keyboard + * @param WebDriverMouse $mouse + * @param WebDriverLocatable $location_provider + */ public function __construct( WebDriverKeyboard $keyboard, WebDriverMouse $mouse, diff --git a/lib/interactions/internal/WebDriverSendKeysAction.php b/lib/interactions/internal/WebDriverSendKeysAction.php index a75e2817f..8dcc69183 100644 --- a/lib/interactions/internal/WebDriverSendKeysAction.php +++ b/lib/interactions/internal/WebDriverSendKeysAction.php @@ -19,6 +19,12 @@ class WebDriverSendKeysAction private $keys; + /** + * @param WebDriverKeyboard $keyboard + * @param WebDriverMouse $mouse + * @param WebDriverLocatable $location_provider + * @param string $keys + */ public function __construct( WebDriverKeyboard $keyboard, WebDriverMouse $mouse, diff --git a/lib/interactions/touch/WebDriverDownAction.php b/lib/interactions/touch/WebDriverDownAction.php index b3e5e35fe..43c4ed08d 100644 --- a/lib/interactions/touch/WebDriverDownAction.php +++ b/lib/interactions/touch/WebDriverDownAction.php @@ -20,6 +20,11 @@ class WebDriverDownAction private $x; private $y; + /** + * @param WebDriverTouchScreen $touch_screen + * @param int $x + * @param int $y + */ public function __construct(WebDriverTouchScreen $touch_screen, $x, $y) { $this->x = $x; $this->y = $y; diff --git a/lib/interactions/touch/WebDriverFlickAction.php b/lib/interactions/touch/WebDriverFlickAction.php index 96333ec38..76337c468 100644 --- a/lib/interactions/touch/WebDriverFlickAction.php +++ b/lib/interactions/touch/WebDriverFlickAction.php @@ -17,6 +17,11 @@ class WebDriverFlickAction extends WebDriverTouchAction implements WebDriverAction { + /** + * @param WebDriverTouchScreen $touch_screen + * @param int $x + * @param int $y + */ public function __construct(WebDriverTouchScreen $touch_screen, $x, $y) { $this->x = $x; $this->y = $y; diff --git a/lib/interactions/touch/WebDriverFlickFromElementAction.php b/lib/interactions/touch/WebDriverFlickFromElementAction.php index 6cb1d6ec9..f361f1c29 100644 --- a/lib/interactions/touch/WebDriverFlickFromElementAction.php +++ b/lib/interactions/touch/WebDriverFlickFromElementAction.php @@ -21,6 +21,13 @@ class WebDriverFlickFromElementAction private $y; private $speed; + /** + * @param WebDriverTouchScreen $touch_screen + * @param WebDriverElement $element + * @param int $x + * @param int $y + * @param int $speed + */ public function __construct( WebDriverTouchScreen $touch_screen, WebDriverElement $element, $x, $y, $speed diff --git a/lib/interactions/touch/WebDriverMoveAction.php b/lib/interactions/touch/WebDriverMoveAction.php index b0237bdab..2c089a343 100644 --- a/lib/interactions/touch/WebDriverMoveAction.php +++ b/lib/interactions/touch/WebDriverMoveAction.php @@ -20,6 +20,11 @@ class WebDriverMoveAction private $x; private $y; + /** + * @param WebDriverTouchScreen $touch_screen + * @param int $x + * @param int $y + */ public function __construct(WebDriverTouchScreen $touch_screen, $x, $y) { $this->x = $x; $this->y = $y; diff --git a/lib/interactions/touch/WebDriverScrollAction.php b/lib/interactions/touch/WebDriverScrollAction.php index 9b5eeb583..082b1acaf 100644 --- a/lib/interactions/touch/WebDriverScrollAction.php +++ b/lib/interactions/touch/WebDriverScrollAction.php @@ -20,6 +20,11 @@ class WebDriverScrollAction private $x; private $y; + /** + * @param WebDriverTouchScreen $touch_screen + * @param int $x + * @param int $y + */ public function __construct(WebDriverTouchScreen $touch_screen, $x, $y) { $this->x = $x; $this->y = $y; diff --git a/lib/interactions/touch/WebDriverScrollFromElementAction.php b/lib/interactions/touch/WebDriverScrollFromElementAction.php index aa6c3da7f..3c985b6bd 100644 --- a/lib/interactions/touch/WebDriverScrollFromElementAction.php +++ b/lib/interactions/touch/WebDriverScrollFromElementAction.php @@ -20,6 +20,12 @@ class WebDriverScrollFromElementAction private $x; private $y; + /** + * @param WebDriverTouchScreen $touch_screen + * @param WebDriverElement $element + * @param int $x + * @param int $y + */ public function __construct( WebDriverTouchScreen $touch_screen, WebDriverElement $element, $x, $y ) { diff --git a/lib/interactions/touch/WebDriverTouchAction.php b/lib/interactions/touch/WebDriverTouchAction.php index 1f1cabe82..99abced9c 100644 --- a/lib/interactions/touch/WebDriverTouchAction.php +++ b/lib/interactions/touch/WebDriverTouchAction.php @@ -28,6 +28,10 @@ abstract class WebDriverTouchAction { */ protected $locationProvider; + /** + * @param WebDriverTouchScreen $touch_screen + * @param WebDriverLocatable $location_provider + */ public function __construct( WebDriverTouchScreen $touch_screen, WebDriverLocatable $location_provider = null diff --git a/lib/interactions/touch/WebDriverUpAction.php b/lib/interactions/touch/WebDriverUpAction.php index b9fa26649..298302769 100644 --- a/lib/interactions/touch/WebDriverUpAction.php +++ b/lib/interactions/touch/WebDriverUpAction.php @@ -20,6 +20,11 @@ class WebDriverUpAction private $x; private $y; + /** + * @param WebDriverTouchScreen $touch_screen + * @param int $x + * @param int $y + */ public function __construct(WebDriverTouchScreen $touch_screen, $x, $y) { $this->x = $x; $this->y = $y; diff --git a/lib/net/URLChecker.php b/lib/net/URLChecker.php index 894c2ca37..97ca7c874 100644 --- a/lib/net/URLChecker.php +++ b/lib/net/URLChecker.php @@ -33,8 +33,6 @@ public function waitUntilAvailable($timeout_in_ms, $url) { $url, $timeout_in_ms )); - - return $this; } public function waitUntilUnavailable($timeout_in_ms, $url) { diff --git a/lib/remote/DesiredCapabilities.php b/lib/remote/DesiredCapabilities.php index 82fadf244..191837371 100644 --- a/lib/remote/DesiredCapabilities.php +++ b/lib/remote/DesiredCapabilities.php @@ -29,6 +29,7 @@ public function getBrowserName() { } /** + * @param string $browser_name * @return DesiredCapabilities */ public function setBrowserName($browser_name) { @@ -44,6 +45,7 @@ public function getVersion() { } /** + * @param string $version * @return DesiredCapabilities */ public function setVersion($version) { @@ -52,6 +54,7 @@ public function setVersion($version) { } /** + * @param string $name * @return mixed The value of a capability. */ public function getCapability($name) { @@ -59,6 +62,8 @@ public function getCapability($name) { } /** + * @param string $name + * @param mixed $value * @return DesiredCapabilities */ public function setCapability($name, $value) { @@ -74,6 +79,7 @@ public function getPlatform() { } /** + * @param string $platform * @return DesiredCapabilities */ public function setPlatform($platform) { @@ -82,10 +88,11 @@ public function setPlatform($platform) { } /** + * @param string $capability_name * @return bool Whether the value is not null and not false. */ public function is($capability_name) { - return (bool)$this->get($capability_name); + return (bool) $this->get($capability_name); } /** @@ -98,6 +105,7 @@ public function isJavascriptEnabled() { /** * This is a htmlUnit-only option. * + * @param bool $enabled * @return DesiredCapabilities * @see https://code.google.com/p/selenium/wiki/DesiredCapabilities#Read-write_capabilities */ @@ -134,6 +142,8 @@ public function toArray() { } /** + * @param string $key + * @param mixed $value * @return DesiredCapabilities */ private function set($key, $value) { @@ -142,6 +152,8 @@ private function set($key, $value) { } /** + * @param string $key + * @param mixed $default * @return mixed */ private function get($key, $default = null) { diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index a8428d3f5..96b39a717 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -149,8 +149,6 @@ public function setConnectionTimeout($timeout) { /** * @param WebDriverCommand $command - * @param array $curl_opts An array of curl options. - * * @return mixed */ public function execute(WebDriverCommand $command) { diff --git a/lib/remote/RemoteExecuteMethod.php b/lib/remote/RemoteExecuteMethod.php index 248627e81..1c06470b9 100644 --- a/lib/remote/RemoteExecuteMethod.php +++ b/lib/remote/RemoteExecuteMethod.php @@ -25,6 +25,8 @@ public function __construct(RemoteWebDriver $driver) { } /** + * @param string $command_name + * @param array $parameters * @return mixed */ public function execute( diff --git a/lib/support/events/EventFiringWebDriver.php b/lib/support/events/EventFiringWebDriver.php index 07d0990b1..b51c88e70 100644 --- a/lib/support/events/EventFiringWebDriver.php +++ b/lib/support/events/EventFiringWebDriver.php @@ -26,7 +26,7 @@ class EventFiringWebDriver implements WebDriver, JavaScriptExecutor { protected $dispatcher; /** - * @param WebDriver $webdriver + * @param WebDriver $driver * @param WebDriverDispatcher $dispatcher */ public function __construct(WebDriver $driver, diff --git a/lib/support/events/EventFiringWebElement.php b/lib/support/events/EventFiringWebElement.php index 162aeca9c..1e0e499af 100644 --- a/lib/support/events/EventFiringWebElement.php +++ b/lib/support/events/EventFiringWebElement.php @@ -198,7 +198,7 @@ public function getCSSValue($css_property_name) { } /** - * @return WebDriverLocation + * @return WebDriverPoint * @throws WebDriverException */ public function getLocation() { @@ -210,7 +210,7 @@ public function getLocation() { } /** - * @return WebDriverLocation + * @return WebDriverPoint * @throws WebDriverException */ public function getLocationOnScreenOnceScrolledIntoView() { diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index 92b017b34..4a5b77f6c 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -38,6 +38,9 @@ protected function tearDown() { /** * Get the URL of the test html. + * + * @param $path + * @return string */ protected function getTestPath($path) { return 'file:///'.dirname(__FILE__).'/html/'.$path; diff --git a/tests/functional/html/upload.html b/tests/functional/html/upload.html index 957514f3f..d542ad04f 100644 --- a/tests/functional/html/upload.html +++ b/tests/functional/html/upload.html @@ -3,7 +3,7 @@ Upload a file -
+
From 2e5479c6362f1369f059d85036e41ddad722eb16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 26 Nov 2014 01:14:12 +0100 Subject: [PATCH 122/784] Fix private property name and visibility --- lib/interactions/internal/WebDriverSingleKeyAction.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/interactions/internal/WebDriverSingleKeyAction.php b/lib/interactions/internal/WebDriverSingleKeyAction.php index aa450e0d8..7d06cd330 100644 --- a/lib/interactions/internal/WebDriverSingleKeyAction.php +++ b/lib/interactions/internal/WebDriverSingleKeyAction.php @@ -17,7 +17,7 @@ abstract class WebDriverSingleKeyAction extends WebDriverKeysRelatedAction implements WebDriverAction { - private $keys; + protected $key; public function __construct( WebDriverKeyboard $keyboard, From e51fef9653343e93ce2f0eff06ac18f3e2582e6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 26 Nov 2014 01:19:30 +0100 Subject: [PATCH 123/784] Fix minor phpdoc typos --- lib/WebDriverExpectedCondition.php | 2 +- lib/remote/RemoteWebDriver.php | 2 +- lib/remote/RemoteWebElement.php | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index 283db89e0..256039e0c 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -396,7 +396,7 @@ function ($driver) { * An expectation with the logical opposite condition of the given condition. * * @param WebDriverExpectedCondition $condition The condition to be negated. - * @return mixed The nagation of the result of the given condition. + * @return mixed The negation of the result of the given condition. */ public static function not(WebDriverExpectedCondition $condition) { return new WebDriverExpectedCondition( diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index 881ccc9aa..89af3b212 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -422,7 +422,7 @@ private function newElement($id) { } /** - * Set the command executor of this RemoteWebdrver + * Set the command executor of this RemoteWebdriver * * @param WebDriverCommandExecutor $executor * @return RemoteWebDriver diff --git a/lib/remote/RemoteWebElement.php b/lib/remote/RemoteWebElement.php index 98b7d5f9c..ea4d1b992 100644 --- a/lib/remote/RemoteWebElement.php +++ b/lib/remote/RemoteWebElement.php @@ -319,7 +319,7 @@ private function upload($local_file) { throw new WebDriverException("You may only upload files: " . $local_file); } - // Create a temperary file in the system temp directory. + // Create a temporary file in the system temp directory. $temp_zip = tempnam('', 'WebDriverZip'); $zip = new ZipArchive(); if ($zip->open($temp_zip, ZipArchive::CREATE) !== true) { @@ -344,7 +344,7 @@ private function upload($local_file) { * Set the fileDetector in order to let the RemoteWebElement to know that * you are going to upload a file. * - * Bascially, if you want WebDriver trying to send a file, set the fileDector + * Basically, if you want WebDriver trying to send a file, set the fileDetector * to be LocalFileDetector. Otherwise, keep it UselessFileDetector. * * eg. $element->setFileDetector(new LocalFileDetector); From c06f562598cddaea1bcf397adce4ca5aab1b4b39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 26 Nov 2014 01:24:49 +0100 Subject: [PATCH 124/784] Replace java-like types defintion with PHPDoc format --- lib/WebDriverExpectedCondition.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index 256039e0c..ca9f4df7c 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -41,7 +41,7 @@ protected function __construct($apply) { * An expectation for checking the title of a page. * * @param string $title The expected title, which must be an exact match. - * @return WebDriverExpectedCondition True when the title matches, + * @return bool WebDriverExpectedCondition True when the title matches, * false otherwise. */ public static function titleIs($title) { @@ -56,7 +56,7 @@ function ($driver) use ($title) { * An expectation for checking substring of a page Title. * * @param string $title The expected substring of Title. - * @return WebDriverExpectedCondition True when in title, + * @return bool WebDriverExpectedCondition True when in title, * false otherwise. */ public static function titleContains($title) { @@ -145,7 +145,7 @@ function ($driver) use ($by) { * * @param WebDriverBy $by The locator used to find the element. * @param string $text The text to be presented in the element. - * @return WebDriverExpectedCondition Whether the text is presented. + * @return bool WebDriverExpectedCondition Whether the text is presented. */ public static function textToBePresentInElement( WebDriverBy $by, $text) { @@ -167,7 +167,7 @@ function ($driver) use ($by, $text) { * * @param WebDriverBy $by The locator used to find the element. * @param string $text The text to be presented in the element value. - * @return WebDriverExpectedCondition Whether the text is presented. + * @return bool WebDriverExpectedCondition Whether the text is presented. */ public static function textToBePresentInElementValue( WebDriverBy $by, $text) { @@ -209,7 +209,7 @@ function ($driver) use ($frame_locator) { * present on the DOM. * * @param WebDriverBy $by The locator used to find the element. - * @return WebDriverExpectedCondition Whether there is no element + * @return bool WebDriverExpectedCondition Whether there is no element * located. */ public static function invisibilityOfElementLocated(WebDriverBy $by) { @@ -232,7 +232,7 @@ function ($driver) use ($by) { * * @param WebdriverBy $by The locator used to find the element. * @param string $text The text of the element. - * @return WebDriverExpectedCondition Whether the text is found in the + * @return bool WebDriverExpectedCondition Whether the text is found in the * element located. */ public static function invisibilityOfElementWithText( @@ -284,7 +284,7 @@ function ($driver) use ($visibility_of_element_located) { * Wait until an element is no longer attached to the DOM. * * @param WebDriverElement $element The element to wait for. - * @return WebDriverExpectedCondition false if the element is still + * @return bool WebDriverExpectedCondition false if the element is still * attached to the DOM, true otherwise. */ public static function stalenessOf(WebDriverElement $element) { @@ -329,7 +329,7 @@ function ($driver) use ($condition) { * An expectation for checking if the given element is selected. * * @param mixed $element_or_by Either the element or the locator. - * @return WebDriverExpectedCondition whether the element is selected. + * @return bool WebDriverExpectedCondition whether the element is selected. */ public static function elementToBeSelected($element_or_by) { return WebDriverExpectedCondition::elementSelectionStateToBe( @@ -343,7 +343,7 @@ public static function elementToBeSelected($element_or_by) { * * @param mixed $element_or_by Either the element or the locator. * @param bool $selected The required state. - * @return WebDriverExpectedCondition Whether the element is selected. + * @return bool WebDriverExpectedCondition Whether the element is selected. */ public static function elementSelectionStateToBe( $element_or_by, From 1454bf15eedada8e230fa39b1c0b9c52cd1a2da7 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Tue, 2 Dec 2014 11:15:41 +0800 Subject: [PATCH 125/784] An explanation to issue 188 --- lib/chrome/ChromeOptions.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/chrome/ChromeOptions.php b/lib/chrome/ChromeOptions.php index cef9b04f8..92a769d71 100644 --- a/lib/chrome/ChromeOptions.php +++ b/lib/chrome/ChromeOptions.php @@ -120,6 +120,10 @@ public function toCapabilities() { public function toArray() { $options = $this->experimentalOptions; + // The selenium server expects a 'dictionary' instead of a 'list' when + // reading the chrome option. However, an empty array in PHP will be + // converted to a 'list' instead of a 'dictionary'. To fix it, we always + // set the 'binary' to avoid returning an empty array. $options['binary'] = $this->binary; if ($this->arguments) { From 8a6526617639cda65be1d237e1da21e27378ade8 Mon Sep 17 00:00:00 2001 From: Yannick Chabbert Date: Wed, 3 Dec 2014 14:23:29 +0100 Subject: [PATCH 126/784] review TouchActions to be performed and compliant with java --- lib/interactions/WebDriverTouchActions.php | 27 ++-------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/lib/interactions/WebDriverTouchActions.php b/lib/interactions/WebDriverTouchActions.php index 31bfc7dde..108ef081a 100644 --- a/lib/interactions/WebDriverTouchActions.php +++ b/lib/interactions/WebDriverTouchActions.php @@ -16,39 +16,16 @@ /** * WebDriver action builder for touch events */ -class WebDriverTouchActions { +class WebDriverTouchActions extends WebDriverActions { /** * @var WebDriverTouchScreen */ protected $touchScreen; - /** - * @var WebDriver - */ - protected $driver; - - /** - * @var WebDriverKeyboard - */ - protected $keyboard; - - /** - * @var WebDriverMouse - */ - protected $mouse; - - /** - * @var WebDriverCompositeAction - */ - protected $action; - public function __construct(WebDriver $driver) { - $this->driver = $driver; - $this->keyboard = $driver->getKeyboard(); - $this->mouse = $driver->getMouse(); + parent::__construct($driver); $this->touchScreen = $driver->getTouch(); - $this->action = new WebDriverCompositeAction(); } /** From c46d7230c4a20db978bbdbc34217b724f6832345 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Fri, 5 Dec 2014 10:04:55 -0800 Subject: [PATCH 127/784] keep the commands in order --- lib/remote/HttpCommandExecutor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index a773b91f9..f2dbcf2e6 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -23,7 +23,6 @@ class HttpCommandExecutor implements WebDriverCommandExecutor { * http://code.google.com/p/selenium/wiki/JsonWireProtocol#Command_Reference */ protected static $commands = array( - DriverCommand::GET_ALL_SESSIONS => array('method' => 'GET', 'url' => '/sessions'), DriverCommand::ACCEPT_ALERT => array('method' => 'POST', 'url' => '/session/:sessionId/accept_alert'), DriverCommand::ADD_COOKIE => array('method' => 'POST', 'url' => '/session/:sessionId/cookie'), DriverCommand::CLEAR_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/clear'), @@ -45,6 +44,7 @@ class HttpCommandExecutor implements WebDriverCommandExecutor { DriverCommand::GET_ACTIVE_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/active'), DriverCommand::GET_ALERT_TEXT => array('method' => 'GET', 'url' => '/session/:sessionId/alert_text'), DriverCommand::GET_ALL_COOKIES => array('method' => 'GET', 'url' => '/session/:sessionId/cookie'), + DriverCommand::GET_ALL_SESSIONS => array('method' => 'GET', 'url' => '/sessions'), DriverCommand::GET_AVAILABLE_LOG_TYPES => array('method' => 'GET', 'url' => '/session/:sessionId/log/types'), DriverCommand::GET_CURRENT_URL => array('method' => 'GET', 'url' => '/session/:sessionId/url'), DriverCommand::GET_CURRENT_WINDOW_HANDLE => array('method' => 'GET', 'url' => '/session/:sessionId/window_handle'), From 925ba2180b8e0037ef9dcf08e352d9c46ee89fc2 Mon Sep 17 00:00:00 2001 From: Yannick Chabbert Date: Sun, 7 Dec 2014 21:00:38 +0100 Subject: [PATCH 128/784] Add ChromeDriverService parameter in ChromeDriver constructor --- lib/chrome/ChromeDriver.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/chrome/ChromeDriver.php b/lib/chrome/ChromeDriver.php index 186e0341e..71059171b 100644 --- a/lib/chrome/ChromeDriver.php +++ b/lib/chrome/ChromeDriver.php @@ -16,12 +16,13 @@ class ChromeDriver extends RemoteWebDriver { public static function start( - DesiredCapabilities $desired_capabilities = null + DesiredCapabilities $desired_capabilities = null, + ChromeDriverService $service = null ) { if ($desired_capabilities === null) { $desired_capabilities = DesiredCapabilities::chrome(); } - $service = ChromeDriverService::createDefaultService(); + $service = $service ? $service : ChromeDriverService::createDefaultService(); $executor = new DriverCommandExecutor($service); $driver = new static(); $driver->setCommandExecutor($executor) From 7a8a8d69d7d0d04fc4681499fe1458510de3d322 Mon Sep 17 00:00:00 2001 From: Yannick Chabbert Date: Sun, 14 Dec 2014 21:18:37 +0100 Subject: [PATCH 129/784] fix switch to main document --- lib/WebDriverTargetLocator.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/WebDriverTargetLocator.php b/lib/WebDriverTargetLocator.php index e330b151d..bc2d50cb3 100644 --- a/lib/WebDriverTargetLocator.php +++ b/lib/WebDriverTargetLocator.php @@ -33,7 +33,8 @@ public function __construct($executor, $driver) { * @return WebDriver The driver focused on the top window or the first frame. */ public function defaultContent() { - $this->executor->execute(DriverCommand::SWITCH_TO_FRAME, array()); + $params = array('id' => null); + $this->executor->execute(DriverCommand::SWITCH_TO_FRAME, $params); return $this->driver; } From 03aca1f21cfea477221df490a37f31bdd8806389 Mon Sep 17 00:00:00 2001 From: James HD Date: Fri, 19 Dec 2014 16:17:04 +0000 Subject: [PATCH 130/784] trying out php 5.3.3 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 00faaa7bf..03545733b 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ "source": "https://github.com/facebook/php-webdriver" }, "require": { - "php": ">=5.3.19" + "php": ">=5.3.3" }, "require-dev": { "phpunit/phpunit": "3.7.*", From 05bb0c62d3ec80fc60df62028b718628b9edc639 Mon Sep 17 00:00:00 2001 From: Wai Hon Law Date: Fri, 2 Jan 2015 18:44:06 -0800 Subject: [PATCH 131/784] Getting the active element $active_element = $driver->switchTo()->activeElement(); --- lib/WebDriverTargetLocator.php | 50 +++-------- lib/__init__.php | 3 +- lib/chrome/ChromeDriver.php | 2 +- lib/remote/RemoteTargetLocator.php | 96 +++++++++++++++++++++ lib/remote/RemoteWebDriver.php | 16 +--- lib/support/events/EventFiringWebDriver.php | 13 --- 6 files changed, 116 insertions(+), 64 deletions(-) create mode 100644 lib/remote/RemoteTargetLocator.php diff --git a/lib/WebDriverTargetLocator.php b/lib/WebDriverTargetLocator.php index e330b151d..9b23df527 100644 --- a/lib/WebDriverTargetLocator.php +++ b/lib/WebDriverTargetLocator.php @@ -16,15 +16,7 @@ /** * Used to locate a given frame or window. */ -class WebDriverTargetLocator { - - protected $executor; - protected $driver; - - public function __construct($executor, $driver) { - $this->executor = $executor; - $this->driver = $driver; - } +interface WebDriverTargetLocator { /** * Switch to the main document if the page contains iframes. Otherwise, switch @@ -32,31 +24,16 @@ public function __construct($executor, $driver) { * * @return WebDriver The driver focused on the top window or the first frame. */ - public function defaultContent() { - $this->executor->execute(DriverCommand::SWITCH_TO_FRAME, array()); - - return $this->driver; - } + public function defaultContent(); /** * Switch to the iframe by its id or name. * * @param WebDriverElement|string $frame The WebDriverElement, - the id or the name of the frame. + * the id or the name of the frame. * @return WebDriver The driver focused on the given frame. */ - public function frame($frame) { - if ($frame instanceof WebDriverElement) { - $id = array('ELEMENT' => $frame->getID()); - } else { - $id = (string)$frame; - } - - $params = array('id' => $id); - $this->executor->execute(DriverCommand::SWITCH_TO_FRAME, $params); - - return $this->driver; - } + public function frame($frame); /** * Switch the focus to another window by its handle. @@ -65,12 +42,7 @@ public function frame($frame) { * @return WebDriver Tge driver focused on the given window. * @see WebDriver::getWindowHandles */ - public function window($handle) { - $params = array('name' => (string)$handle); - $this->executor->execute(DriverCommand::SWITCH_TO_WINDOW, $params); - - return $this->driver; - } + public function window($handle); /** * Switch to the currently active modal dialog for this particular driver @@ -78,7 +50,13 @@ public function window($handle) { * * @return WebDriverAlert */ - public function alert() { - return new WebDriverAlert($this->executor); - } + public function alert(); + + /** + * Switches to the element that currently has focus within the document + * currently "switched to", or the body element if this cannot be detected. + * + * @return WebDriverElement + */ + public function activeElement(); } diff --git a/lib/__init__.php b/lib/__init__.php index d10dd12ca..55219b491 100755 --- a/lib/__init__.php +++ b/lib/__init__.php @@ -24,6 +24,7 @@ require_once('remote/FileDetector.php'); require_once('WebDriverCapabilities.php'); require_once('remote/ExecuteMethod.php'); +require_once('WebDriverTargetLocator.php'); // abstract class require_once('interactions/internal/WebDriverKeysRelatedAction.php'); @@ -48,7 +49,6 @@ require_once('WebDriverPlatform.php'); require_once('WebDriverPoint.php'); require_once('WebDriverSelect.php'); -require_once('WebDriverTargetLocator.php'); require_once('WebDriverTimeouts.php'); require_once('WebDriverWait.php'); require_once('WebDriverWindow.php'); @@ -85,6 +85,7 @@ require_once('remote/WebDriverCapabilityType.php'); require_once('remote/DesiredCapabilities.php'); require_once('remote/WebDriverResponse.php'); +require_once('remote/RemoteTargetLocator.php'); require_once('remote/HttpCommandExecutor.php'); require_once('remote/service/DriverCommandExecutor.php'); diff --git a/lib/chrome/ChromeDriver.php b/lib/chrome/ChromeDriver.php index cf2d21ccd..b1194628e 100644 --- a/lib/chrome/ChromeDriver.php +++ b/lib/chrome/ChromeDriver.php @@ -23,7 +23,7 @@ public static function start( $desired_capabilities = DesiredCapabilities::chrome(); } if ($service === null) { - $service = ChromeDriverService::createDefaultService(); + $service = ChromeDriverService::createDefaultService(); } $executor = new DriverCommandExecutor($service); $driver = new static(); diff --git a/lib/remote/RemoteTargetLocator.php b/lib/remote/RemoteTargetLocator.php new file mode 100644 index 000000000..86b61453e --- /dev/null +++ b/lib/remote/RemoteTargetLocator.php @@ -0,0 +1,96 @@ +executor = $executor; + $this->driver = $driver; + } + + /** + * Switch to the main document if the page contains iframes. Otherwise, switch + * to the first frame on the page. + * + * @return WebDriver The driver focused on the top window or the first frame. + */ + public function defaultContent() { + $this->executor->execute(DriverCommand::SWITCH_TO_FRAME, array()); + + return $this->driver; + } + + /** + * Switch to the iframe by its id or name. + * + * @param WebDriverElement|string $frame The WebDriverElement, + the id or the name of the frame. + * @return WebDriver The driver focused on the given frame. + */ + public function frame($frame) { + if ($frame instanceof WebDriverElement) { + $id = array('ELEMENT' => $frame->getID()); + } else { + $id = (string)$frame; + } + + $params = array('id' => $id); + $this->executor->execute(DriverCommand::SWITCH_TO_FRAME, $params); + + return $this->driver; + } + + /** + * Switch the focus to another window by its handle. + * + * @param string $handle The handle of the window to be focused on. + * @return WebDriver Tge driver focused on the given window. + * @see WebDriver::getWindowHandles + */ + public function window($handle) { + $params = array('name' => (string)$handle); + $this->executor->execute(DriverCommand::SWITCH_TO_WINDOW, $params); + + return $this->driver; + } + + /** + * Switch to the currently active modal dialog for this particular driver + * instance. + * + * @return WebDriverAlert + */ + public function alert() { + return new WebDriverAlert($this->executor); + } + + /** + * Switches to the element that currently has focus within the document + * currently "switched to", or the body element if this cannot be detected. + * + * @return RemoteWebElement + */ + public function activeElement() { + $response = $this->driver->execute(DriverCommand::GET_ACTIVE_ELEMENT); + $method = new RemoteExecuteMethod($this->driver); + return new RemoteWebElement($method, $response['ELEMENT']); + } +} diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index efa0e5f0d..ff944d1c4 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -348,11 +348,11 @@ public function navigate() { /** * Switch to a different window or frame. * - * @return WebDriverTargetLocator - * @see WebDriverTargetLocator + * @return RemoteTargetLocator + * @see RemoteTargetLocator */ public function switchTo() { - return new WebDriverTargetLocator($this->getExecuteMethod(), $this); + return new RemoteTargetLocator($this->getExecuteMethod(), $this); } /** @@ -401,16 +401,6 @@ public function action() { return new WebDriverActions($this); } - /** - * Get the element on the page that currently has focus. - * - * @return RemoteWebElement - */ - public function getActiveElement() { - $response = $this->execute(DriverCommand::GET_ACTIVE_ELEMENT); - return $this->newElement($response['ELEMENT']); - } - /** * Return the WebDriverElement with the given id. * diff --git a/lib/support/events/EventFiringWebDriver.php b/lib/support/events/EventFiringWebDriver.php index b51c88e70..5f09493eb 100644 --- a/lib/support/events/EventFiringWebDriver.php +++ b/lib/support/events/EventFiringWebDriver.php @@ -336,19 +336,6 @@ public function getTouch() { } } - /** - * Get the element on the page that currently has focus. - * - * @return WebDriverElement - */ - public function getActiveElement() { - try { - return $this->driver->getActiveElement(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); - } - } - private function dispatchOnException($exception) { $this->dispatch('onException', $exception, $this); throw $exception; From c84d655aec4f5e8db298ce1991da097180686203 Mon Sep 17 00:00:00 2001 From: Daniel Beardsley Date: Tue, 6 Jan 2015 17:46:15 -0700 Subject: [PATCH 132/784] RemoteWebDriver: Allow specifying request timeout Previously you could only set the request timeout after the first request (NEW_SESSION) was sent. If you want to alter the timeout, you presumably want to affect the first request too. --- lib/chrome/ChromeDriver.php | 3 ++- lib/remote/RemoteWebDriver.php | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/chrome/ChromeDriver.php b/lib/chrome/ChromeDriver.php index b1194628e..bf500f2d7 100644 --- a/lib/chrome/ChromeDriver.php +++ b/lib/chrome/ChromeDriver.php @@ -47,7 +47,8 @@ public function startSession($desired_capabilities) { public static function create( $url = 'http://localhost:4444/wd/hub', $desired_capabilities = null, - $timeout_in_ms = 300000 + $timeout_in_ms = 300000, + $request_timeout_in_ms = 300000 ) { throw new WebDriverException('Please use ChromeDriver::start() instead.'); } diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index ff944d1c4..3f1032eed 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -47,12 +47,14 @@ protected function __construct() {} * @param string $url The url of the remote server * @param DesiredCapabilities $desired_capabilities The desired capabilities * @param int $connection_timeout_in_ms + * @param int $request_timeout_in_ms * @return RemoteWebDriver */ public static function create( $url = 'http://localhost:4444/wd/hub', $desired_capabilities = null, - $connection_timeout_in_ms = 300000 + $connection_timeout_in_ms = 300000, + $request_timeout_in_ms = 300000 ) { $url = preg_replace('#/+$#', '', $url); @@ -64,6 +66,7 @@ public static function create( $executor = new HttpCommandExecutor($url); $executor->setConnectionTimeout($connection_timeout_in_ms); + $executor->setRequestTimeout($request_timeout_in_ms); $command = new WebDriverCommand( null, From c4efbaf67b5b2cb00ab0d1230997fdbce160f930 Mon Sep 17 00:00:00 2001 From: jameshd Date: Thu, 8 Jan 2015 09:40:58 +0000 Subject: [PATCH 133/784] replaced constant with int value --- lib/remote/HttpCommandExecutor.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index f2dbcf2e6..3fb1fd540 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -161,7 +161,11 @@ public function setConnectionTimeout($timeout_in_ms) { * @return HttpCommandExecutor */ public function setRequestTimeout($timeout_in_ms) { - curl_setopt($this->curl, CURLOPT_TIMEOUT_MS, $timeout_in_ms); + curl_setopt( + $this->curl, + /*CURLOPT_TIMEOUT_MS*/ 155, + $timeout_in_ms + ); return $this; } From fcecaa3c5bbcf695045b25718f1c45216df158fe Mon Sep 17 00:00:00 2001 From: James HD Date: Thu, 8 Jan 2015 09:44:15 +0000 Subject: [PATCH 134/784] reverts to FB version of PHP --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 03545733b..00faaa7bf 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ "source": "https://github.com/facebook/php-webdriver" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.19" }, "require-dev": { "phpunit/phpunit": "3.7.*", From 3c4fec875fe172a1c12525393e02547404f3772c Mon Sep 17 00:00:00 2001 From: jameshd Date: Fri, 16 Jan 2015 16:21:53 +0000 Subject: [PATCH 135/784] downgrading php requirement --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 00faaa7bf..03545733b 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ "source": "https://github.com/facebook/php-webdriver" }, "require": { - "php": ">=5.3.19" + "php": ">=5.3.3" }, "require-dev": { "phpunit/phpunit": "3.7.*", From c78f868f98aa46092fbcee83ae043b8dc11530b3 Mon Sep 17 00:00:00 2001 From: jameshd Date: Tue, 20 Jan 2015 16:02:59 +0000 Subject: [PATCH 136/784] corrected timeout typo --- lib/remote/HttpCommandExecutor.php | 4 ++-- lib/remote/RemoteWebDriver.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index b1a52482d..3ef9955bb 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -134,8 +134,8 @@ public function __construct($url) { 'Accept: application/json', ) ); - $this->setRequestTimeout(300000); - $this->setConnectionTimeout(300000); + $this->setRequestTimeout(30000); + $this->setConnectionTimeout(30000); } /** diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index 1e61a0f68..2b0969f07 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -467,7 +467,7 @@ public function getSessionID() { */ public static function getAllSessions( $url = 'http://localhost:4444/wd/hub', - $timeout_in_ms = 300000 + $timeout_in_ms = 30000 ) { $executor = new HttpCommandExecutor($url); $executor->setConnectionTimeout($timeout_in_ms); From f76e0c5983b3a6264998f690209f53140f75dbbd Mon Sep 17 00:00:00 2001 From: James HD Date: Tue, 20 Jan 2015 16:04:42 +0000 Subject: [PATCH 137/784] reverts to FB version of PHP --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 03545733b..00faaa7bf 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ "source": "https://github.com/facebook/php-webdriver" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.19" }, "require-dev": { "phpunit/phpunit": "3.7.*", From 38d89d873e6c2dfdf40c8c40ba8c78c00dd249bb Mon Sep 17 00:00:00 2001 From: Arian Date: Sat, 7 Feb 2015 18:08:50 -0800 Subject: [PATCH 138/784] Fixed strpos: ending parentheses is in incorrect location Fixed the current implementation of strpos, it currently looked like this `strpos($to_escape, "'" != false))` incorrectly passes `"'" != false` as the second argument. Changed it to `if (strpos($to_escape, '"') !== false && strpos($to_escape, "'") !== false) {` --- lib/WebDriverSelect.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/WebDriverSelect.php b/lib/WebDriverSelect.php index 09d15a56a..dc42d8f0f 100644 --- a/lib/WebDriverSelect.php +++ b/lib/WebDriverSelect.php @@ -259,7 +259,7 @@ public function deselectByVisibleText($text) { * @return string The escaped string. */ protected function escapeQuotes($to_escape) { - if (strpos($to_escape, '"') !== false && strpos($to_escape, "'" != false)) { + if (strpos($to_escape, '"') !== false && strpos($to_escape, "'") !== false) { $substrings = explode('"', $to_escape); $escaped = "concat("; @@ -274,7 +274,7 @@ protected function escapeQuotes($to_escape) { return $escaped; } - if (strpos($to_escape, '"' !== false)) { + if (strpos($to_escape, '"') !== false) { return sprintf("'%s'", $to_escape); } From 0ee0fb672aae6137a49b570a8108ec22d07a56ef Mon Sep 17 00:00:00 2001 From: Janos Pasztor Date: Wed, 22 Apr 2015 17:04:59 +0200 Subject: [PATCH 139/784] Updated webdriver from Facebook --- composer.json | 3 ++- lib/remote/RemoteTargetLocator.php | 2 ++ lib/remote/RemoteWebDriver.php | 2 +- tests/functional/WebDriverTestCase.php | 4 +++- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 24f37c8fd..4b5622180 100644 --- a/composer.json +++ b/composer.json @@ -18,5 +18,6 @@ }, "autoload": { "classmap": ["lib/"] - } + }, + "minimum-stability": "dev" } diff --git a/lib/remote/RemoteTargetLocator.php b/lib/remote/RemoteTargetLocator.php index 949836675..841c4acf1 100644 --- a/lib/remote/RemoteTargetLocator.php +++ b/lib/remote/RemoteTargetLocator.php @@ -13,6 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +namespace Selenium\WebDriver; + /** * Used to locate a given frame or window for RemoteWebDriver. */ diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index aafbb4b2f..246a7adfa 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -47,7 +47,7 @@ protected function __construct() {} * Construct the RemoteWebDriver by a desired capabilities. * * @param string $url The url of the remote server - * @param DesiredCapabilities $desired_capabilities The desired capabilities + * @param DesiredCapabilities|array $desired_capabilities The desired capabilities * @param int|null $connection_timeout_in_ms * @param int|null $request_timeout_in_ms * @return RemoteWebDriver diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index db4248964..e4ef9db7c 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -35,7 +35,9 @@ protected function setUp() { } protected function tearDown() { - $this->driver->quit(); + if ($this->driver) { + $this->driver->quit(); + } } /** From a5941cfd149a6563643341dfff57fd178253f009 Mon Sep 17 00:00:00 2001 From: Janos Pasztor Date: Wed, 22 Apr 2015 17:08:46 +0200 Subject: [PATCH 140/784] Updated package name --- composer.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 4b5622180..41b0fce1e 100644 --- a/composer.json +++ b/composer.json @@ -1,13 +1,13 @@ { - "name": "janoszen/webdriver", + "name": "opsbears/webdriver", "description": "A php client for WebDriver (fork of facebook/webdriver)", "keywords": ["webdriver", "selenium", "php"], - "homepage": "https://github.com/janoszen/php-webdriver", + "homepage": "https://github.com/opsbears/php-webdriver", "type": "library", "license": "Apache-2.0", "support": { - "issues": "https://github.com/janoszen/php-webdriver/issues", - "source": "https://github.com/janoszen/php-webdriver" + "issues": "https://github.com/opsbears/php-webdriver/issues", + "source": "https://github.com/opsbears/php-webdriver" }, "require": { "php": ">=5.3.19" From 6f61273b119c276fbdeb868b61d57f157a4673ba Mon Sep 17 00:00:00 2001 From: Janos Pasztor Date: Mon, 18 May 2015 14:44:29 +0200 Subject: [PATCH 141/784] Issue facebook/php-webdriver#212 - Moving forward Implemented namespacing as discussed (needs testing) --- composer.json | 14 ++- example.php | 4 +- lib/{chrome => }/ChromeDriver.php | 4 +- lib/{chrome => }/ChromeDriverService.php | 2 +- lib/{chrome => }/ChromeOptions.php | 2 +- lib/{remote => }/DesiredCapabilities.php | 4 +- lib/{remote => }/DriverCommand.php | 2 +- .../service => }/DriverCommandExecutor.php | 5 +- lib/{remote/service => }/DriverService.php | 4 +- .../events => }/EventFiringWebDriver.php | 5 +- .../EventFiringWebDriverNavigation.php | 4 +- .../events => }/EventFiringWebElement.php | 4 +- .../ElementNotSelectableException.php | 21 ++++ lib/Exception/ElementNotVisibleException.php | 20 +++ lib/Exception/ExpectedException.php | 21 ++++ .../IMEEngineActivationFailedException.php | 21 ++++ lib/Exception/IMENotAvailableException.php | 21 ++++ lib/Exception/IndexOutOfBoundsException.php | 7 ++ .../InvalidCookieDomainException.php | 20 +++ lib/Exception/InvalidCoordinatesException.php | 21 ++++ .../InvalidElementStateException.php | 20 +++ lib/Exception/InvalidSelectorException.php | 21 ++++ .../MoveTargetOutOfBoundsException.php | 21 ++++ lib/Exception/NoAlertOpenException.php | 20 +++ lib/Exception/NoCollectionException.php | 7 ++ lib/Exception/NoScriptResultException.php | 20 +++ lib/Exception/NoStringException.php | 7 ++ lib/Exception/NoStringLengthException.php | 20 +++ lib/Exception/NoStringWrapperException.php | 20 +++ lib/Exception/NoSuchCollectionException.php | 20 +++ lib/Exception/NoSuchDocumentException.php | 21 ++++ lib/Exception/NoSuchDriverException.php | 20 +++ lib/Exception/NoSuchElementException.php | 20 +++ lib/Exception/NoSuchFrameException.php | 20 +++ lib/Exception/NoSuchWindowException.php | 20 +++ lib/Exception/NullPointerException.php | 21 ++++ lib/Exception/ScriptTimeoutException.php | 21 ++++ lib/Exception/SessionNotCreatedException.php | 21 ++++ .../StaleElementReferenceException.php | 20 +++ lib/Exception/TimeOutException.php | 20 +++ lib/Exception/UnableToSetCookieException.php | 20 +++ .../UnexpectedAlertOpenException.php | 20 +++ .../UnexpectedJavascriptException.php | 20 +++ lib/Exception/UnexpectedTagNameException.php | 34 +++++ lib/Exception/UnknownCommandException.php | 20 +++ lib/Exception/UnknownServerException.php | 20 +++ .../UnrecognizedExceptionException.php | 21 ++++ .../UnsupportedOperationException.php | 21 ++++ lib/Exception/WebDriverCurlException.php | 21 ++++ .../WebDriverException.php} | 64 +--------- lib/Exception/XPathLookupException.php | 20 +++ lib/{remote => }/ExecuteMethod.php | 2 +- lib/{remote => }/FileDetector.php | 2 +- lib/{firefox => }/FirefoxDriver.php | 2 +- lib/{firefox => }/FirefoxProfile.php | 7 +- lib/{remote => }/HttpCommandExecutor.php | 5 +- lib/JavaScriptExecutor.php | 2 +- lib/{remote => }/LocalFileDetector.php | 2 +- lib/{remote => }/RemoteExecuteMethod.php | 2 +- lib/{remote => }/RemoteKeyboard.php | 2 +- lib/{remote => }/RemoteMouse.php | 2 +- lib/{remote => }/RemoteTargetLocator.php | 2 +- lib/{remote => }/RemoteTouchScreen.php | 2 +- lib/{remote => }/RemoteWebDriver.php | 2 +- lib/{remote => }/RemoteWebElement.php | 3 +- lib/{net => }/URLChecker.php | 5 +- lib/{remote => }/UselessFileDetector.php | 2 +- lib/WebDriver.php | 2 +- lib/WebDriverAction.php | 2 +- lib/{interactions => }/WebDriverActions.php | 2 +- lib/WebDriverAlert.php | 2 +- lib/{remote => }/WebDriverBrowserType.php | 2 +- .../WebDriverButtonReleaseAction.php | 2 +- lib/WebDriverBy.php | 2 +- lib/WebDriverCapabilities.php | 2 +- lib/{remote => }/WebDriverCapabilityType.php | 2 +- .../internal => }/WebDriverClickAction.php | 2 +- .../WebDriverClickAndHoldAction.php | 2 +- lib/{remote => }/WebDriverCommand.php | 2 +- lib/WebDriverCommandExecutor.php | 2 +- .../WebDriverCompositeAction.php | 2 +- .../WebDriverContextClickAction.php | 2 +- .../internal => }/WebDriverCoordinates.php | 3 +- lib/WebDriverDimension.php | 2 +- lib/WebDriverDispatcher.php | 2 +- .../WebDriverDoubleClickAction.php | 2 +- .../touch => }/WebDriverDoubleTapAction.php | 2 +- .../touch => }/WebDriverDownAction.php | 2 +- lib/WebDriverElement.php | 2 +- lib/WebDriverEventListener.php | 4 +- lib/WebDriverExpectedCondition.php | 6 +- .../touch => }/WebDriverFlickAction.php | 2 +- .../WebDriverFlickFromElementAction.php | 2 +- lib/WebDriverHasInputDevices.php | 2 +- .../internal => }/WebDriverKeyDownAction.php | 2 +- .../internal => }/WebDriverKeyUpAction.php | 2 +- lib/WebDriverKeyboard.php | 2 +- lib/WebDriverKeys.php | 2 +- .../WebDriverKeysRelatedAction.php | 2 +- lib/{internal => }/WebDriverLocatable.php | 2 +- .../touch => }/WebDriverLongPressAction.php | 2 +- lib/WebDriverMouse.php | 2 +- .../internal => }/WebDriverMouseAction.php | 2 +- .../WebDriverMouseMoveAction.php | 2 +- .../touch => }/WebDriverMoveAction.php | 2 +- .../WebDriverMoveToOffsetAction.php | 2 +- lib/WebDriverNavigation.php | 2 +- lib/WebDriverOptions.php | 3 +- lib/WebDriverPlatform.php | 2 +- lib/WebDriverPoint.php | 2 +- lib/{remote => }/WebDriverResponse.php | 2 +- .../touch => }/WebDriverScrollAction.php | 2 +- .../WebDriverScrollFromElementAction.php | 2 +- lib/WebDriverSearchContext.php | 2 +- lib/WebDriverSelect.php | 5 +- .../internal => }/WebDriverSendKeysAction.php | 2 +- .../WebDriverSingleKeyAction.php | 2 +- .../touch => }/WebDriverTapAction.php | 2 +- lib/WebDriverTargetLocator.php | 2 +- lib/WebDriverTimeouts.php | 2 +- .../touch => }/WebDriverTouchAction.php | 2 +- .../WebDriverTouchActions.php | 2 +- .../WebDriverTouchScreen.php | 2 +- .../touch => }/WebDriverUpAction.php | 2 +- lib/WebDriverWait.php | 4 +- lib/WebDriverWindow.php | 3 +- lib/__init__.php | 116 ------------------ tests/bootstrap.php | 4 +- tests/functional/BaseTest.php | 2 +- tests/functional/FileUploadTest.php | 2 +- tests/functional/WebDriverTestCase.php | 2 +- tests/unit/bootstrap.php | 2 +- .../WebDriverButtonReleaseActionTest.php | 8 +- .../internal/WebDriverClickActionTest.php | 8 +- .../WebDriverClickAndHoldActionTest.php | 8 +- .../WebDriverContextClickActionTest.php | 8 +- .../internal/WebDriverCoordinatesTest.php | 2 +- .../WebDriverDoubleClickActionTest.php | 8 +- .../internal/WebDriverKeyDownActionTest.php | 10 +- .../internal/WebDriverKeyUpActionTest.php | 10 +- .../internal/WebDriverMouseMoveActionTest.php | 8 +- .../WebDriverMouseToOffsetActionTest.php | 8 +- .../internal/WebDriverSendKeysActionTest.php | 10 +- 143 files changed, 936 insertions(+), 323 deletions(-) rename lib/{chrome => }/ChromeDriver.php (96%) rename lib/{chrome => }/ChromeDriverService.php (97%) rename lib/{chrome => }/ChromeOptions.php (99%) rename lib/{remote => }/DesiredCapabilities.php (99%) rename lib/{remote => }/DriverCommand.php (99%) rename lib/{remote/service => }/DriverCommandExecutor.php (93%) rename lib/{remote/service => }/DriverService.php (98%) rename lib/{support/events => }/EventFiringWebDriver.php (98%) rename lib/{support/events => }/EventFiringWebDriverNavigation.php (97%) rename lib/{support/events => }/EventFiringWebElement.php (98%) create mode 100644 lib/Exception/ElementNotSelectableException.php create mode 100644 lib/Exception/ElementNotVisibleException.php create mode 100644 lib/Exception/ExpectedException.php create mode 100644 lib/Exception/IMEEngineActivationFailedException.php create mode 100644 lib/Exception/IMENotAvailableException.php create mode 100644 lib/Exception/IndexOutOfBoundsException.php create mode 100644 lib/Exception/InvalidCookieDomainException.php create mode 100644 lib/Exception/InvalidCoordinatesException.php create mode 100644 lib/Exception/InvalidElementStateException.php create mode 100644 lib/Exception/InvalidSelectorException.php create mode 100644 lib/Exception/MoveTargetOutOfBoundsException.php create mode 100644 lib/Exception/NoAlertOpenException.php create mode 100644 lib/Exception/NoCollectionException.php create mode 100644 lib/Exception/NoScriptResultException.php create mode 100644 lib/Exception/NoStringException.php create mode 100644 lib/Exception/NoStringLengthException.php create mode 100644 lib/Exception/NoStringWrapperException.php create mode 100644 lib/Exception/NoSuchCollectionException.php create mode 100644 lib/Exception/NoSuchDocumentException.php create mode 100644 lib/Exception/NoSuchDriverException.php create mode 100644 lib/Exception/NoSuchElementException.php create mode 100644 lib/Exception/NoSuchFrameException.php create mode 100644 lib/Exception/NoSuchWindowException.php create mode 100644 lib/Exception/NullPointerException.php create mode 100644 lib/Exception/ScriptTimeoutException.php create mode 100644 lib/Exception/SessionNotCreatedException.php create mode 100644 lib/Exception/StaleElementReferenceException.php create mode 100644 lib/Exception/TimeOutException.php create mode 100644 lib/Exception/UnableToSetCookieException.php create mode 100644 lib/Exception/UnexpectedAlertOpenException.php create mode 100644 lib/Exception/UnexpectedJavascriptException.php create mode 100644 lib/Exception/UnexpectedTagNameException.php create mode 100644 lib/Exception/UnknownCommandException.php create mode 100644 lib/Exception/UnknownServerException.php create mode 100644 lib/Exception/UnrecognizedExceptionException.php create mode 100644 lib/Exception/UnsupportedOperationException.php create mode 100644 lib/Exception/WebDriverCurlException.php rename lib/{WebDriverExceptions.php => Exception/WebDriverException.php} (59%) create mode 100644 lib/Exception/XPathLookupException.php rename lib/{remote => }/ExecuteMethod.php (96%) rename lib/{remote => }/FileDetector.php (96%) rename lib/{firefox => }/FirefoxDriver.php (95%) rename lib/{firefox => }/FirefoxProfile.php (95%) rename lib/{remote => }/HttpCommandExecutor.php (99%) rename lib/{remote => }/LocalFileDetector.php (96%) rename lib/{remote => }/RemoteExecuteMethod.php (97%) rename lib/{remote => }/RemoteKeyboard.php (98%) rename lib/{remote => }/RemoteMouse.php (99%) rename lib/{remote => }/RemoteTargetLocator.php (99%) rename lib/{remote => }/RemoteTouchScreen.php (99%) rename lib/{remote => }/RemoteWebDriver.php (99%) rename lib/{remote => }/RemoteWebElement.php (99%) rename lib/{net => }/URLChecker.php (95%) rename lib/{remote => }/UselessFileDetector.php (96%) rename lib/{interactions => }/WebDriverActions.php (99%) rename lib/{remote => }/WebDriverBrowserType.php (97%) rename lib/{interactions/internal => }/WebDriverButtonReleaseAction.php (96%) rename lib/{remote => }/WebDriverCapabilityType.php (98%) rename lib/{interactions/internal => }/WebDriverClickAction.php (96%) rename lib/{interactions/internal => }/WebDriverClickAndHoldAction.php (96%) rename lib/{remote => }/WebDriverCommand.php (97%) rename lib/{interactions => }/WebDriverCompositeAction.php (97%) rename lib/{interactions/internal => }/WebDriverContextClickAction.php (96%) rename lib/{interactions/internal => }/WebDriverCoordinates.php (94%) rename lib/{interactions/internal => }/WebDriverDoubleClickAction.php (96%) rename lib/{interactions/touch => }/WebDriverDoubleTapAction.php (96%) rename lib/{interactions/touch => }/WebDriverDownAction.php (97%) rename lib/{interactions/touch => }/WebDriverFlickAction.php (97%) rename lib/{interactions/touch => }/WebDriverFlickFromElementAction.php (97%) rename lib/{interactions/internal => }/WebDriverKeyDownAction.php (96%) rename lib/{interactions/internal => }/WebDriverKeyUpAction.php (96%) rename lib/{interactions/internal => }/WebDriverKeysRelatedAction.php (97%) rename lib/{internal => }/WebDriverLocatable.php (96%) rename lib/{interactions/touch => }/WebDriverLongPressAction.php (96%) rename lib/{interactions/internal => }/WebDriverMouseAction.php (97%) rename lib/{interactions/internal => }/WebDriverMouseMoveAction.php (96%) rename lib/{interactions/touch => }/WebDriverMoveAction.php (97%) rename lib/{interactions/internal => }/WebDriverMoveToOffsetAction.php (97%) rename lib/{remote => }/WebDriverResponse.php (98%) rename lib/{interactions/touch => }/WebDriverScrollAction.php (97%) rename lib/{interactions/touch => }/WebDriverScrollFromElementAction.php (97%) rename lib/{interactions/internal => }/WebDriverSendKeysAction.php (97%) rename lib/{interactions/internal => }/WebDriverSingleKeyAction.php (97%) rename lib/{interactions/touch => }/WebDriverTapAction.php (96%) rename lib/{interactions/touch => }/WebDriverTouchAction.php (97%) rename lib/{interactions => }/WebDriverTouchActions.php (99%) rename lib/{interactions => }/WebDriverTouchScreen.php (99%) rename lib/{interactions/touch => }/WebDriverUpAction.php (97%) delete mode 100755 lib/__init__.php diff --git a/composer.json b/composer.json index 41b0fce1e..7b57541f4 100644 --- a/composer.json +++ b/composer.json @@ -1,13 +1,13 @@ { - "name": "opsbears/webdriver", - "description": "A php client for WebDriver (fork of facebook/webdriver)", + "name": "facebook/webdriver", + "description": "A php client for WebDriver", "keywords": ["webdriver", "selenium", "php"], - "homepage": "https://github.com/opsbears/php-webdriver", + "homepage": "https://github.com/facebook/php-webdriver", "type": "library", "license": "Apache-2.0", "support": { - "issues": "https://github.com/opsbears/php-webdriver/issues", - "source": "https://github.com/opsbears/php-webdriver" + "issues": "https://github.com/facebook/php-webdriver/issues", + "source": "https://github.com/facebook/php-webdriver" }, "require": { "php": ">=5.3.19" @@ -17,7 +17,9 @@ "phpdocumentor/phpdocumentor": "2.*" }, "autoload": { - "classmap": ["lib/"] + "psr-4": { + "Facebook\\WebDriver\\": "lib/" + } }, "minimum-stability": "dev" } diff --git a/example.php b/example.php index 8cfac7461..b4834146c 100644 --- a/example.php +++ b/example.php @@ -1,9 +1,9 @@ service->stop(); } return $value; - } catch (Exception $e) { + } catch (\Exception $e) { if (!$this->service->isRunning()) { throw new WebDriverException('The driver server has died.'); } diff --git a/lib/remote/service/DriverService.php b/lib/DriverService.php similarity index 98% rename from lib/remote/service/DriverService.php rename to lib/DriverService.php index 0b707403e..6a573afe5 100644 --- a/lib/remote/service/DriverService.php +++ b/lib/DriverService.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; + +use Exception; class DriverService { diff --git a/lib/support/events/EventFiringWebDriver.php b/lib/EventFiringWebDriver.php similarity index 98% rename from lib/support/events/EventFiringWebDriver.php rename to lib/EventFiringWebDriver.php index cefe6d987..ebd5b9b7c 100644 --- a/lib/support/events/EventFiringWebDriver.php +++ b/lib/EventFiringWebDriver.php @@ -13,7 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; + +use Facebook\WebDriver\Exception\UnsupportedOperationException; +use Facebook\WebDriver\Exception\WebDriverException; class EventFiringWebDriver implements WebDriver, JavaScriptExecutor { diff --git a/lib/support/events/EventFiringWebDriverNavigation.php b/lib/EventFiringWebDriverNavigation.php similarity index 97% rename from lib/support/events/EventFiringWebDriverNavigation.php rename to lib/EventFiringWebDriverNavigation.php index 7f1e71b0a..c3feea060 100644 --- a/lib/support/events/EventFiringWebDriverNavigation.php +++ b/lib/EventFiringWebDriverNavigation.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; + +use Facebook\WebDriver\Exception\WebDriverException; class EventFiringWebDriverNavigation { diff --git a/lib/support/events/EventFiringWebElement.php b/lib/EventFiringWebElement.php similarity index 98% rename from lib/support/events/EventFiringWebElement.php rename to lib/EventFiringWebElement.php index f0b317cef..a955c59d6 100644 --- a/lib/support/events/EventFiringWebElement.php +++ b/lib/EventFiringWebElement.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; + +use Facebook\WebDriver\Exception\WebDriverException; class EventFiringWebElement implements WebDriverElement, WebDriverLocatable { diff --git a/lib/Exception/ElementNotSelectableException.php b/lib/Exception/ElementNotSelectableException.php new file mode 100644 index 000000000..9acfb88f2 --- /dev/null +++ b/lib/Exception/ElementNotSelectableException.php @@ -0,0 +1,21 @@ +extractTo($target_dir); $zip->close(); } else { - throw new Exception("Failed to open the firefox extension. '$xpi'"); + throw new \Exception("Failed to open the firefox extension. '$xpi'"); } return $this; } diff --git a/lib/remote/HttpCommandExecutor.php b/lib/HttpCommandExecutor.php similarity index 99% rename from lib/remote/HttpCommandExecutor.php rename to lib/HttpCommandExecutor.php index 7e8b16a88..c3c76fb9f 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/HttpCommandExecutor.php @@ -13,7 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; +use Facebook\WebDriver\Exception\WebDriverException; +use InvalidArgumentException; +use BadMethodCallException; /** * Command executor talking to the standalone server via HTTP. diff --git a/lib/JavaScriptExecutor.php b/lib/JavaScriptExecutor.php index 18cba7866..3e0db1302 100644 --- a/lib/JavaScriptExecutor.php +++ b/lib/JavaScriptExecutor.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * WebDriver interface implemented by drivers that support JavaScript. diff --git a/lib/remote/LocalFileDetector.php b/lib/LocalFileDetector.php similarity index 96% rename from lib/remote/LocalFileDetector.php rename to lib/LocalFileDetector.php index d8cac906e..a9a7488ce 100644 --- a/lib/remote/LocalFileDetector.php +++ b/lib/LocalFileDetector.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class LocalFileDetector implements FileDetector { /** diff --git a/lib/remote/RemoteExecuteMethod.php b/lib/RemoteExecuteMethod.php similarity index 97% rename from lib/remote/RemoteExecuteMethod.php rename to lib/RemoteExecuteMethod.php index 4d874179c..3ab0a60ae 100644 --- a/lib/remote/RemoteExecuteMethod.php +++ b/lib/RemoteExecuteMethod.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class RemoteExecuteMethod implements ExecuteMethod { diff --git a/lib/remote/RemoteKeyboard.php b/lib/RemoteKeyboard.php similarity index 98% rename from lib/remote/RemoteKeyboard.php rename to lib/RemoteKeyboard.php index 9831b74f4..d7d3ebbdb 100644 --- a/lib/remote/RemoteKeyboard.php +++ b/lib/RemoteKeyboard.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Execute keyboard commands for RemoteWebDriver. diff --git a/lib/remote/RemoteMouse.php b/lib/RemoteMouse.php similarity index 99% rename from lib/remote/RemoteMouse.php rename to lib/RemoteMouse.php index 93168abf8..deb2164fd 100644 --- a/lib/remote/RemoteMouse.php +++ b/lib/RemoteMouse.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Execute mouse commands for RemoteWebDriver. diff --git a/lib/remote/RemoteTargetLocator.php b/lib/RemoteTargetLocator.php similarity index 99% rename from lib/remote/RemoteTargetLocator.php rename to lib/RemoteTargetLocator.php index 841c4acf1..c33bd2c71 100644 --- a/lib/remote/RemoteTargetLocator.php +++ b/lib/RemoteTargetLocator.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Used to locate a given frame or window for RemoteWebDriver. diff --git a/lib/remote/RemoteTouchScreen.php b/lib/RemoteTouchScreen.php similarity index 99% rename from lib/remote/RemoteTouchScreen.php rename to lib/RemoteTouchScreen.php index 6ef5d35d5..3ca3c19bd 100644 --- a/lib/remote/RemoteTouchScreen.php +++ b/lib/RemoteTouchScreen.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Execute touch commands for RemoteWebDriver. diff --git a/lib/remote/RemoteWebDriver.php b/lib/RemoteWebDriver.php similarity index 99% rename from lib/remote/RemoteWebDriver.php rename to lib/RemoteWebDriver.php index 246a7adfa..86d9e0d8b 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/RemoteWebDriver.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class RemoteWebDriver implements WebDriver, JavaScriptExecutor { /** diff --git a/lib/remote/RemoteWebElement.php b/lib/RemoteWebElement.php similarity index 99% rename from lib/remote/RemoteWebElement.php rename to lib/RemoteWebElement.php index 5b92cebfe..178397165 100644 --- a/lib/remote/RemoteWebElement.php +++ b/lib/RemoteWebElement.php @@ -13,8 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; +use Facebook\WebDriver\Exception\WebDriverException; use ZipArchive; /** diff --git a/lib/net/URLChecker.php b/lib/URLChecker.php similarity index 95% rename from lib/net/URLChecker.php rename to lib/URLChecker.php index 13588203b..657488dbf 100644 --- a/lib/net/URLChecker.php +++ b/lib/URLChecker.php @@ -13,7 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; + +use Exception; +use Facebook\WebDriver\Exception\TimeOutException; class URLChecker { diff --git a/lib/remote/UselessFileDetector.php b/lib/UselessFileDetector.php similarity index 96% rename from lib/remote/UselessFileDetector.php rename to lib/UselessFileDetector.php index f21df9e64..ce4c55fc9 100644 --- a/lib/remote/UselessFileDetector.php +++ b/lib/UselessFileDetector.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class UselessFileDetector implements FileDetector { /** diff --git a/lib/WebDriver.php b/lib/WebDriver.php index 14e102b92..b143583ca 100755 --- a/lib/WebDriver.php +++ b/lib/WebDriver.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * The interface for WebDriver. diff --git a/lib/WebDriverAction.php b/lib/WebDriverAction.php index cff1ca9ae..a5d2d32d8 100644 --- a/lib/WebDriverAction.php +++ b/lib/WebDriverAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Interface representing a single user-interaction action. diff --git a/lib/interactions/WebDriverActions.php b/lib/WebDriverActions.php similarity index 99% rename from lib/interactions/WebDriverActions.php rename to lib/WebDriverActions.php index eac0d14ae..37537e2b9 100644 --- a/lib/interactions/WebDriverActions.php +++ b/lib/WebDriverActions.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * WebDriver action builder. It implements the builder pattern. diff --git a/lib/WebDriverAlert.php b/lib/WebDriverAlert.php index 84bc202c8..2f92ec4c4 100644 --- a/lib/WebDriverAlert.php +++ b/lib/WebDriverAlert.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * An abstraction allowing the driver to manipulate the javascript alerts diff --git a/lib/remote/WebDriverBrowserType.php b/lib/WebDriverBrowserType.php similarity index 97% rename from lib/remote/WebDriverBrowserType.php rename to lib/WebDriverBrowserType.php index 8db21c0a5..bbb9a529e 100644 --- a/lib/remote/WebDriverBrowserType.php +++ b/lib/WebDriverBrowserType.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * All the browsers supported by selenium diff --git a/lib/interactions/internal/WebDriverButtonReleaseAction.php b/lib/WebDriverButtonReleaseAction.php similarity index 96% rename from lib/interactions/internal/WebDriverButtonReleaseAction.php rename to lib/WebDriverButtonReleaseAction.php index ea518877a..444632265 100644 --- a/lib/interactions/internal/WebDriverButtonReleaseAction.php +++ b/lib/WebDriverButtonReleaseAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Move to the location and then release the mouse key. diff --git a/lib/WebDriverBy.php b/lib/WebDriverBy.php index ce25f308e..c409768a8 100644 --- a/lib/WebDriverBy.php +++ b/lib/WebDriverBy.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * The basic 8 mechanisms supported by webdriver to locate a web element. diff --git a/lib/WebDriverCapabilities.php b/lib/WebDriverCapabilities.php index 3ccc30ee6..721db82e6 100644 --- a/lib/WebDriverCapabilities.php +++ b/lib/WebDriverCapabilities.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; interface WebDriverCapabilities { diff --git a/lib/remote/WebDriverCapabilityType.php b/lib/WebDriverCapabilityType.php similarity index 98% rename from lib/remote/WebDriverCapabilityType.php rename to lib/WebDriverCapabilityType.php index a7499d9e0..558abb4ab 100644 --- a/lib/remote/WebDriverCapabilityType.php +++ b/lib/WebDriverCapabilityType.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * WebDriverCapabilityType contains all constants defined in the WebDriver diff --git a/lib/interactions/internal/WebDriverClickAction.php b/lib/WebDriverClickAction.php similarity index 96% rename from lib/interactions/internal/WebDriverClickAction.php rename to lib/WebDriverClickAction.php index 54adb4a6f..cc9263c17 100644 --- a/lib/interactions/internal/WebDriverClickAction.php +++ b/lib/WebDriverClickAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverClickAction extends WebDriverMouseAction diff --git a/lib/interactions/internal/WebDriverClickAndHoldAction.php b/lib/WebDriverClickAndHoldAction.php similarity index 96% rename from lib/interactions/internal/WebDriverClickAndHoldAction.php rename to lib/WebDriverClickAndHoldAction.php index 30169ff5b..6bc8d049b 100644 --- a/lib/interactions/internal/WebDriverClickAndHoldAction.php +++ b/lib/WebDriverClickAndHoldAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Move the the location, click and hold. diff --git a/lib/remote/WebDriverCommand.php b/lib/WebDriverCommand.php similarity index 97% rename from lib/remote/WebDriverCommand.php rename to lib/WebDriverCommand.php index 2300ce373..06660dadf 100644 --- a/lib/remote/WebDriverCommand.php +++ b/lib/WebDriverCommand.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverCommand { diff --git a/lib/WebDriverCommandExecutor.php b/lib/WebDriverCommandExecutor.php index 7a3eb20fd..5f99a1d16 100644 --- a/lib/WebDriverCommandExecutor.php +++ b/lib/WebDriverCommandExecutor.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Interface for all command executor. diff --git a/lib/interactions/WebDriverCompositeAction.php b/lib/WebDriverCompositeAction.php similarity index 97% rename from lib/interactions/WebDriverCompositeAction.php rename to lib/WebDriverCompositeAction.php index 261dde15d..de80c787f 100644 --- a/lib/interactions/WebDriverCompositeAction.php +++ b/lib/WebDriverCompositeAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * An action for aggregating actions and triggering all of them afterwards. diff --git a/lib/interactions/internal/WebDriverContextClickAction.php b/lib/WebDriverContextClickAction.php similarity index 96% rename from lib/interactions/internal/WebDriverContextClickAction.php rename to lib/WebDriverContextClickAction.php index e1c3f96ad..5e2638dca 100644 --- a/lib/interactions/internal/WebDriverContextClickAction.php +++ b/lib/WebDriverContextClickAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * You can call it 'Right Click' if you like. diff --git a/lib/interactions/internal/WebDriverCoordinates.php b/lib/WebDriverCoordinates.php similarity index 94% rename from lib/interactions/internal/WebDriverCoordinates.php rename to lib/WebDriverCoordinates.php index 980051bac..e43b7fb75 100644 --- a/lib/interactions/internal/WebDriverCoordinates.php +++ b/lib/WebDriverCoordinates.php @@ -13,9 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; use Closure; +use Facebook\WebDriver\Exception\UnsupportedOperationException; /** * Interface representing basic mouse operations. diff --git a/lib/WebDriverDimension.php b/lib/WebDriverDimension.php index a2572ecbf..c66278931 100644 --- a/lib/WebDriverDimension.php +++ b/lib/WebDriverDimension.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Represent a dimension. diff --git a/lib/WebDriverDispatcher.php b/lib/WebDriverDispatcher.php index 693763b70..ae9e5e8f7 100644 --- a/lib/WebDriverDispatcher.php +++ b/lib/WebDriverDispatcher.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverDispatcher { diff --git a/lib/interactions/internal/WebDriverDoubleClickAction.php b/lib/WebDriverDoubleClickAction.php similarity index 96% rename from lib/interactions/internal/WebDriverDoubleClickAction.php rename to lib/WebDriverDoubleClickAction.php index d720e0d20..15c9e422c 100644 --- a/lib/interactions/internal/WebDriverDoubleClickAction.php +++ b/lib/WebDriverDoubleClickAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverDoubleClickAction extends WebDriverMouseAction diff --git a/lib/interactions/touch/WebDriverDoubleTapAction.php b/lib/WebDriverDoubleTapAction.php similarity index 96% rename from lib/interactions/touch/WebDriverDoubleTapAction.php rename to lib/WebDriverDoubleTapAction.php index c4bf374d6..c2cc7d381 100644 --- a/lib/interactions/touch/WebDriverDoubleTapAction.php +++ b/lib/WebDriverDoubleTapAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverDoubleTapAction extends WebDriverTouchAction diff --git a/lib/interactions/touch/WebDriverDownAction.php b/lib/WebDriverDownAction.php similarity index 97% rename from lib/interactions/touch/WebDriverDownAction.php rename to lib/WebDriverDownAction.php index 155e67eef..67fc73e55 100644 --- a/lib/interactions/touch/WebDriverDownAction.php +++ b/lib/WebDriverDownAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverDownAction extends WebDriverTouchAction diff --git a/lib/WebDriverElement.php b/lib/WebDriverElement.php index e060aa094..d49190604 100644 --- a/lib/WebDriverElement.php +++ b/lib/WebDriverElement.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Interface for an HTML element in the WebDriver framework. diff --git a/lib/WebDriverEventListener.php b/lib/WebDriverEventListener.php index 21c7f9002..4b458f649 100644 --- a/lib/WebDriverEventListener.php +++ b/lib/WebDriverEventListener.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; + +use Facebook\WebDriver\Exception\WebDriverException; interface WebDriverEventListener { diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index cb7526a43..ac1924a31 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -13,7 +13,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; +use Facebook\WebDriver\Exception\StaleElementReferenceException; +use Facebook\WebDriver\Exception\NoSuchFrameException; +use Facebook\WebDriver\Exception\NoSuchElementException; +use Facebook\WebDriver\Exception\NoAlertOpenException; /** * Canned ExpectedConditions which are generally useful within webdriver tests. diff --git a/lib/interactions/touch/WebDriverFlickAction.php b/lib/WebDriverFlickAction.php similarity index 97% rename from lib/interactions/touch/WebDriverFlickAction.php rename to lib/WebDriverFlickAction.php index 8b80cf127..446340718 100644 --- a/lib/interactions/touch/WebDriverFlickAction.php +++ b/lib/WebDriverFlickAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverFlickAction extends WebDriverTouchAction diff --git a/lib/interactions/touch/WebDriverFlickFromElementAction.php b/lib/WebDriverFlickFromElementAction.php similarity index 97% rename from lib/interactions/touch/WebDriverFlickFromElementAction.php rename to lib/WebDriverFlickFromElementAction.php index 478b3e0ab..3781d6c0e 100644 --- a/lib/interactions/touch/WebDriverFlickFromElementAction.php +++ b/lib/WebDriverFlickFromElementAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverFlickFromElementAction extends WebDriverTouchAction diff --git a/lib/WebDriverHasInputDevices.php b/lib/WebDriverHasInputDevices.php index 67fb80947..76c82dddc 100644 --- a/lib/WebDriverHasInputDevices.php +++ b/lib/WebDriverHasInputDevices.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Interface implemented by each driver that allows access to the input devices. diff --git a/lib/interactions/internal/WebDriverKeyDownAction.php b/lib/WebDriverKeyDownAction.php similarity index 96% rename from lib/interactions/internal/WebDriverKeyDownAction.php rename to lib/WebDriverKeyDownAction.php index 70f5421eb..5d5aa2afe 100644 --- a/lib/interactions/internal/WebDriverKeyDownAction.php +++ b/lib/WebDriverKeyDownAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverKeyDownAction extends WebDriverSingleKeyAction diff --git a/lib/interactions/internal/WebDriverKeyUpAction.php b/lib/WebDriverKeyUpAction.php similarity index 96% rename from lib/interactions/internal/WebDriverKeyUpAction.php rename to lib/WebDriverKeyUpAction.php index 24b5150f3..d41a5a2d8 100644 --- a/lib/interactions/internal/WebDriverKeyUpAction.php +++ b/lib/WebDriverKeyUpAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverKeyUpAction extends WebDriverSingleKeyAction diff --git a/lib/WebDriverKeyboard.php b/lib/WebDriverKeyboard.php index 06e6091dd..042e47108 100644 --- a/lib/WebDriverKeyboard.php +++ b/lib/WebDriverKeyboard.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; interface WebDriverKeyboard { diff --git a/lib/WebDriverKeys.php b/lib/WebDriverKeys.php index 64c76edd3..b946cec9f 100644 --- a/lib/WebDriverKeys.php +++ b/lib/WebDriverKeys.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Representations of pressable keys that aren't text. diff --git a/lib/interactions/internal/WebDriverKeysRelatedAction.php b/lib/WebDriverKeysRelatedAction.php similarity index 97% rename from lib/interactions/internal/WebDriverKeysRelatedAction.php rename to lib/WebDriverKeysRelatedAction.php index 779718496..bcd45f7f7 100644 --- a/lib/interactions/internal/WebDriverKeysRelatedAction.php +++ b/lib/WebDriverKeysRelatedAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Base class for all keyboard-related actions. diff --git a/lib/internal/WebDriverLocatable.php b/lib/WebDriverLocatable.php similarity index 96% rename from lib/internal/WebDriverLocatable.php rename to lib/WebDriverLocatable.php index d315387a1..bb2aa9035 100644 --- a/lib/internal/WebDriverLocatable.php +++ b/lib/WebDriverLocatable.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Interface representing basic mouse operations. diff --git a/lib/interactions/touch/WebDriverLongPressAction.php b/lib/WebDriverLongPressAction.php similarity index 96% rename from lib/interactions/touch/WebDriverLongPressAction.php rename to lib/WebDriverLongPressAction.php index a34de2e10..5fc2b519e 100644 --- a/lib/interactions/touch/WebDriverLongPressAction.php +++ b/lib/WebDriverLongPressAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverLongPressAction extends WebDriverTouchAction diff --git a/lib/WebDriverMouse.php b/lib/WebDriverMouse.php index 5b79fcf76..5c90fa199 100644 --- a/lib/WebDriverMouse.php +++ b/lib/WebDriverMouse.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Interface representing basic mouse operations. diff --git a/lib/interactions/internal/WebDriverMouseAction.php b/lib/WebDriverMouseAction.php similarity index 97% rename from lib/interactions/internal/WebDriverMouseAction.php rename to lib/WebDriverMouseAction.php index 0d7b21309..5038daa45 100644 --- a/lib/interactions/internal/WebDriverMouseAction.php +++ b/lib/WebDriverMouseAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Base class for all mouse-related actions. diff --git a/lib/interactions/internal/WebDriverMouseMoveAction.php b/lib/WebDriverMouseMoveAction.php similarity index 96% rename from lib/interactions/internal/WebDriverMouseMoveAction.php rename to lib/WebDriverMouseMoveAction.php index 01e5c28bf..b24948daf 100644 --- a/lib/interactions/internal/WebDriverMouseMoveAction.php +++ b/lib/WebDriverMouseMoveAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverMouseMoveAction extends WebDriverMouseAction diff --git a/lib/interactions/touch/WebDriverMoveAction.php b/lib/WebDriverMoveAction.php similarity index 97% rename from lib/interactions/touch/WebDriverMoveAction.php rename to lib/WebDriverMoveAction.php index dae6e8ef1..32c324de7 100644 --- a/lib/interactions/touch/WebDriverMoveAction.php +++ b/lib/WebDriverMoveAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverMoveAction extends WebDriverTouchAction diff --git a/lib/interactions/internal/WebDriverMoveToOffsetAction.php b/lib/WebDriverMoveToOffsetAction.php similarity index 97% rename from lib/interactions/internal/WebDriverMoveToOffsetAction.php rename to lib/WebDriverMoveToOffsetAction.php index bdf41629e..fe1b0bfc2 100644 --- a/lib/interactions/internal/WebDriverMoveToOffsetAction.php +++ b/lib/WebDriverMoveToOffsetAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverMoveToOffsetAction extends WebDriverMouseAction diff --git a/lib/WebDriverNavigation.php b/lib/WebDriverNavigation.php index 75baa18d5..f572b6f92 100644 --- a/lib/WebDriverNavigation.php +++ b/lib/WebDriverNavigation.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * An abstraction allowing the driver to access the browser's history and to diff --git a/lib/WebDriverOptions.php b/lib/WebDriverOptions.php index 10f59d937..d673603b2 100644 --- a/lib/WebDriverOptions.php +++ b/lib/WebDriverOptions.php @@ -13,7 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; +use InvalidArgumentException; /** * Managing stuff you would do in a browser. diff --git a/lib/WebDriverPlatform.php b/lib/WebDriverPlatform.php index a16a4cb2a..4954bf56e 100644 --- a/lib/WebDriverPlatform.php +++ b/lib/WebDriverPlatform.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * The platforms supported by WebDriver. diff --git a/lib/WebDriverPoint.php b/lib/WebDriverPoint.php index ae8dbd667..0653eb988 100644 --- a/lib/WebDriverPoint.php +++ b/lib/WebDriverPoint.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Represent a point. diff --git a/lib/remote/WebDriverResponse.php b/lib/WebDriverResponse.php similarity index 98% rename from lib/remote/WebDriverResponse.php rename to lib/WebDriverResponse.php index 71b934074..a2d4dd244 100644 --- a/lib/remote/WebDriverResponse.php +++ b/lib/WebDriverResponse.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverResponse { diff --git a/lib/interactions/touch/WebDriverScrollAction.php b/lib/WebDriverScrollAction.php similarity index 97% rename from lib/interactions/touch/WebDriverScrollAction.php rename to lib/WebDriverScrollAction.php index 817ed26aa..e7e183b31 100644 --- a/lib/interactions/touch/WebDriverScrollAction.php +++ b/lib/WebDriverScrollAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverScrollAction extends WebDriverTouchAction diff --git a/lib/interactions/touch/WebDriverScrollFromElementAction.php b/lib/WebDriverScrollFromElementAction.php similarity index 97% rename from lib/interactions/touch/WebDriverScrollFromElementAction.php rename to lib/WebDriverScrollFromElementAction.php index 96109712a..63be82c48 100644 --- a/lib/interactions/touch/WebDriverScrollFromElementAction.php +++ b/lib/WebDriverScrollFromElementAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverScrollFromElementAction extends WebDriverTouchAction diff --git a/lib/WebDriverSearchContext.php b/lib/WebDriverSearchContext.php index 17f3417a4..07f7bbccc 100644 --- a/lib/WebDriverSearchContext.php +++ b/lib/WebDriverSearchContext.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * The interface for WebDriver and WebDriverElement which is able to search for diff --git a/lib/WebDriverSelect.php b/lib/WebDriverSelect.php index 85aabe832..cebeba364 100644 --- a/lib/WebDriverSelect.php +++ b/lib/WebDriverSelect.php @@ -13,7 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; +use Facebook\WebDriver\Exception\UnexpectedTagNameException; +use Facebook\WebDriver\Exception\NoSuchElementException; +use Facebook\WebDriver\Exception\UnsupportedOperationException; /** * Models a SELECT tag, providing helper methods to select and deselect options. diff --git a/lib/interactions/internal/WebDriverSendKeysAction.php b/lib/WebDriverSendKeysAction.php similarity index 97% rename from lib/interactions/internal/WebDriverSendKeysAction.php rename to lib/WebDriverSendKeysAction.php index 889a2f91b..9b371a551 100644 --- a/lib/interactions/internal/WebDriverSendKeysAction.php +++ b/lib/WebDriverSendKeysAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverSendKeysAction extends WebDriverKeysRelatedAction diff --git a/lib/interactions/internal/WebDriverSingleKeyAction.php b/lib/WebDriverSingleKeyAction.php similarity index 97% rename from lib/interactions/internal/WebDriverSingleKeyAction.php rename to lib/WebDriverSingleKeyAction.php index 5b6c3c62d..a9280afe1 100644 --- a/lib/interactions/internal/WebDriverSingleKeyAction.php +++ b/lib/WebDriverSingleKeyAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; abstract class WebDriverSingleKeyAction extends WebDriverKeysRelatedAction diff --git a/lib/interactions/touch/WebDriverTapAction.php b/lib/WebDriverTapAction.php similarity index 96% rename from lib/interactions/touch/WebDriverTapAction.php rename to lib/WebDriverTapAction.php index b61056e99..27ef9627f 100644 --- a/lib/interactions/touch/WebDriverTapAction.php +++ b/lib/WebDriverTapAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverTapAction extends WebDriverTouchAction diff --git a/lib/WebDriverTargetLocator.php b/lib/WebDriverTargetLocator.php index 53efb59ca..86e0939b8 100644 --- a/lib/WebDriverTargetLocator.php +++ b/lib/WebDriverTargetLocator.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Used to locate a given frame or window. diff --git a/lib/WebDriverTimeouts.php b/lib/WebDriverTimeouts.php index f4732f708..aac26c146 100644 --- a/lib/WebDriverTimeouts.php +++ b/lib/WebDriverTimeouts.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Managing timeout behavior for WebDriver instances. diff --git a/lib/interactions/touch/WebDriverTouchAction.php b/lib/WebDriverTouchAction.php similarity index 97% rename from lib/interactions/touch/WebDriverTouchAction.php rename to lib/WebDriverTouchAction.php index a885467fe..06ba9fdab 100644 --- a/lib/interactions/touch/WebDriverTouchAction.php +++ b/lib/WebDriverTouchAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Base class for all touch-related actions. diff --git a/lib/interactions/WebDriverTouchActions.php b/lib/WebDriverTouchActions.php similarity index 99% rename from lib/interactions/WebDriverTouchActions.php rename to lib/WebDriverTouchActions.php index 83281e839..a223f269d 100644 --- a/lib/interactions/WebDriverTouchActions.php +++ b/lib/WebDriverTouchActions.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * WebDriver action builder for touch events diff --git a/lib/interactions/WebDriverTouchScreen.php b/lib/WebDriverTouchScreen.php similarity index 99% rename from lib/interactions/WebDriverTouchScreen.php rename to lib/WebDriverTouchScreen.php index be9a2474a..46f989013 100644 --- a/lib/interactions/WebDriverTouchScreen.php +++ b/lib/WebDriverTouchScreen.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Interface representing touch screen operations. diff --git a/lib/interactions/touch/WebDriverUpAction.php b/lib/WebDriverUpAction.php similarity index 97% rename from lib/interactions/touch/WebDriverUpAction.php rename to lib/WebDriverUpAction.php index 8745eb4c7..9e0035d1a 100644 --- a/lib/interactions/touch/WebDriverUpAction.php +++ b/lib/WebDriverUpAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverUpAction extends WebDriverTouchAction diff --git a/lib/WebDriverWait.php b/lib/WebDriverWait.php index 5d351c3eb..2b4464fba 100644 --- a/lib/WebDriverWait.php +++ b/lib/WebDriverWait.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; +use Facebook\WebDriver\Exception\NoSuchElementException; +use Facebook\WebDriver\Exception\TimeOutException; /** * A utility class, designed to help the user to wait until a condition turns diff --git a/lib/WebDriverWindow.php b/lib/WebDriverWindow.php index b4f649b77..c29deb06c 100644 --- a/lib/WebDriverWindow.php +++ b/lib/WebDriverWindow.php @@ -13,7 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; +use Facebook\WebDriver\Exception\IndexOutOfBoundsException; /** * An abstraction allowing the driver to manipulate the browser's window diff --git a/lib/__init__.php b/lib/__init__.php deleted file mode 100755 index 55219b491..000000000 --- a/lib/__init__.php +++ /dev/null @@ -1,116 +0,0 @@ -webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); $this->webDriverButtonReleaseAction = new WebDriverButtonReleaseAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +34,7 @@ public function setUp() { } public function testPerformSendsMouseUpCommand() { - $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseUp')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverButtonReleaseAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverClickActionTest.php b/tests/unit/interactions/internal/WebDriverClickActionTest.php index ca60ae668..fd1ece96f 100644 --- a/tests/unit/interactions/internal/WebDriverClickActionTest.php +++ b/tests/unit/interactions/internal/WebDriverClickActionTest.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverClickActionTest extends \PHPUnit_Framework_TestCase { /** @@ -25,8 +25,8 @@ class WebDriverClickActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); $this->webDriverClickAction = new WebDriverClickAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +34,7 @@ public function setUp() { } public function testPerformSendsClickCommand() { - $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverClickAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php b/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php index 78781fae6..bf9a4cdea 100644 --- a/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php +++ b/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverClickAndHoldActionTest extends \PHPUnit_Framework_TestCase { /** @@ -25,8 +25,8 @@ class WebDriverClickAndHoldActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); $this->webDriverClickAndHoldAction = new WebDriverClickAndHoldAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +34,7 @@ public function setUp() { } public function testPerformSendsMouseDownCommand() { - $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseDown')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverClickAndHoldAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverContextClickActionTest.php b/tests/unit/interactions/internal/WebDriverContextClickActionTest.php index ece8f3488..2ca80a538 100644 --- a/tests/unit/interactions/internal/WebDriverContextClickActionTest.php +++ b/tests/unit/interactions/internal/WebDriverContextClickActionTest.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverContextClickActionTest extends \PHPUnit_Framework_TestCase { /** @@ -25,8 +25,8 @@ class WebDriverContextClickActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); $this->webDriverContextClickAction = new WebDriverContextClickAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +34,7 @@ public function setUp() { } public function testPerformSendsContextClickCommand() { - $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('contextClick')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverContextClickAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverCoordinatesTest.php b/tests/unit/interactions/internal/WebDriverCoordinatesTest.php index f339e5044..a7fa52549 100644 --- a/tests/unit/interactions/internal/WebDriverCoordinatesTest.php +++ b/tests/unit/interactions/internal/WebDriverCoordinatesTest.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverCoordinatesTest extends \PHPUnit_Framework_TestCase { public function testConstruct() { diff --git a/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php b/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php index ae45d169b..bae50645d 100644 --- a/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php +++ b/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverDoubleClickActionTest extends \PHPUnit_Framework_TestCase { /** @@ -25,8 +25,8 @@ class WebDriverDoubleClickActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); $this->webDriverDoubleClickAction = new WebDriverDoubleClickAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +34,7 @@ public function setUp() { } public function testPerformSendsDoubleClickCommand() { - $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('doubleClick')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverDoubleClickAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php b/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php index 0cc5cb5cd..af9ce8e0e 100644 --- a/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php +++ b/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverKeyDownActionTest extends \PHPUnit_Framework_TestCase { /** @@ -26,9 +26,9 @@ class WebDriverKeyDownActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverKeyboard = $this->getMock('Selenium\WebDriver\WebDriverKeyboard'); - $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); + $this->webDriverKeyboard = $this->getMock('Facebook\WebDriver\WebDriverKeyboard'); + $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); $this->webDriverKeyDownAction = new WebDriverKeyDownAction( $this->webDriverKeyboard, $this->webDriverMouse, @@ -37,7 +37,7 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverKeyboard->expects($this->once())->method('pressKey'); diff --git a/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php b/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php index daf7bfc06..98d4cf27d 100644 --- a/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php +++ b/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverKeyUpActionTest extends \PHPUnit_Framework_TestCase { /** @@ -26,9 +26,9 @@ class WebDriverKeyUpActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverKeyboard = $this->getMock('Selenium\WebDriver\WebDriverKeyboard'); - $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); + $this->webDriverKeyboard = $this->getMock('Facebook\WebDriver\WebDriverKeyboard'); + $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); $this->webDriverKeyUpAction = new WebDriverKeyUpAction( $this->webDriverKeyboard, $this->webDriverMouse, @@ -38,7 +38,7 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverKeyboard->expects($this->once())->method('releaseKey')->with('a'); diff --git a/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php b/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php index 2c6ee400e..bbd306640 100644 --- a/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php +++ b/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverMouseMoveActionTest extends \PHPUnit_Framework_TestCase { /** @@ -25,8 +25,8 @@ class WebDriverMouseMoveActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); $this->webDriverMouseMoveAction = new WebDriverMouseMoveAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +34,7 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseMove')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverMouseMoveAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php b/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php index c6066d051..3fbc3b130 100644 --- a/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php +++ b/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverMouseToOffsetActionTest extends \PHPUnit_Framework_TestCase { /** @@ -25,8 +25,8 @@ class WebDriverMouseToOffsetActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); $this->webDriverMoveToOffsetAction = new WebDriverMoveToOffsetAction( $this->webDriverMouse, $this->locationProvider, @@ -36,7 +36,7 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseMove')->with($coords, 150, 200); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverMoveToOffsetAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php b/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php index 6a51f8934..77fd71587 100644 --- a/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php +++ b/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverSendKeysActionTest extends \PHPUnit_Framework_TestCase { /** @@ -27,9 +27,9 @@ class WebDriverSendKeysActionTest extends \PHPUnit_Framework_TestCase { private $keys; public function setUp() { - $this->webDriverKeyboard = $this->getMock('Selenium\WebDriver\WebDriverKeyboard'); - $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); + $this->webDriverKeyboard = $this->getMock('Facebook\WebDriver\WebDriverKeyboard'); + $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); $this->keys = array('t', 'e', 's', 't'); $this->webDriverSendKeysAction = new WebDriverSendKeysAction( $this->webDriverKeyboard, @@ -40,7 +40,7 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverKeyboard->expects($this->once())->method('sendKeys')->with($this->keys); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); From 891331c6bbc6abf96c03194a456df97f6127d1f5 Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 18 May 2015 21:34:46 -0300 Subject: [PATCH 142/784] Few improvements, avoiding some elses --- lib/WebDriverWait.php | 5 ++--- lib/interactions/internal/WebDriverMouseAction.php | 4 ++-- lib/remote/HttpCommandExecutor.php | 12 ++++++------ lib/remote/service/DriverService.php | 12 +++++------- 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/lib/WebDriverWait.php b/lib/WebDriverWait.php index 34d573552..55ace62af 100644 --- a/lib/WebDriverWait.php +++ b/lib/WebDriverWait.php @@ -30,9 +30,8 @@ public function __construct( $timeout_in_second = null, $interval_in_millisecond = null) { $this->driver = $driver; - $this->timeout = ($timeout_in_second) ? $timeout_in_second : 30; - $this->interval = - ($interval_in_millisecond) ? $interval_in_millisecond : 250; + $this->timeout = $timeout_in_second ?: 30; + $this->interval = $interval_in_millisecond ?: 250; } /** diff --git a/lib/interactions/internal/WebDriverMouseAction.php b/lib/interactions/internal/WebDriverMouseAction.php index 0bbdf0bf5..4c16a7b39 100644 --- a/lib/interactions/internal/WebDriverMouseAction.php +++ b/lib/interactions/internal/WebDriverMouseAction.php @@ -34,9 +34,9 @@ public function __construct( protected function getActionLocation() { if ($this->locationProvider !== null) { return $this->locationProvider->getCoordinates(); - } else { - return null; } + + return null; } /** diff --git a/lib/remote/HttpCommandExecutor.php b/lib/remote/HttpCommandExecutor.php index 3ef9955bb..193031ddc 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/remote/HttpCommandExecutor.php @@ -208,18 +208,18 @@ public function execute(WebDriverCommand $command) { curl_setopt($this->curl, CURLOPT_URL, $this->url . $url); // https://github.com/facebook/php-webdriver/issues/173 - switch ($command->getName()) { - case DriverCommand::NEW_SESSION: - curl_setopt($this->curl, CURLOPT_POST, 1); - break; - default: - curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $http_method); + if ($command->getName() === DriverCommand::NEW_SESSION) { + curl_setopt($this->curl, CURLOPT_POST, 1); + } else { + curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $http_method); } $encoded_params = null; + if ($http_method === 'POST' && $params && is_array($params)) { $encoded_params = json_encode($params); } + curl_setopt($this->curl, CURLOPT_POSTFIELDS, $encoded_params); $raw_results = trim(curl_exec($this->curl)); diff --git a/lib/remote/service/DriverService.php b/lib/remote/service/DriverService.php index b8ba78831..607bf8fb8 100644 --- a/lib/remote/service/DriverService.php +++ b/lib/remote/service/DriverService.php @@ -55,12 +55,7 @@ public function __construct( $this->executable = self::checkExecutable($executable); $this->url = sprintf('http://localhost:%d', $port); $this->args = $args; - - if ($environment === null) { - $this->environment = $_ENV; - } else { - $this->environment = $environment; - } + $this->environment = $environment ?: $_ENV; } /** @@ -136,9 +131,12 @@ public function isRunning() { protected static function checkExecutable($executable) { if (!is_file($executable)) { throw new Exception("'$executable' is not a file."); - } else if (!is_executable($executable)) { + } + + if (!is_executable($executable)) { throw new Exception("'$executable' is not executable."); } + return $executable; } } From 0ad98e98fa22d21c7fa591fa4feb6e2b79e3246d Mon Sep 17 00:00:00 2001 From: Janos Pasztor Date: Tue, 19 May 2015 12:29:22 +0200 Subject: [PATCH 143/784] Issue facebook/php-webdriver#212 - Moved classes to subnamespaces (needs manual testing) --- example.php | 3 ++ lib/{ => Chrome}/ChromeDriver.php | 25 +++++++++-- lib/{ => Chrome}/ChromeDriverService.php | 4 +- lib/{ => Chrome}/ChromeOptions.php | 4 +- lib/Exception/WebDriverException.php | 41 ++++++++++++++++++- lib/{ => Firefox}/FirefoxDriver.php | 2 +- lib/{ => Firefox}/FirefoxProfile.php | 8 +++- .../WebDriverButtonReleaseAction.php | 4 +- .../Internal}/WebDriverClickAction.php | 4 +- .../Internal}/WebDriverClickAndHoldAction.php | 4 +- .../Internal}/WebDriverContextClickAction.php | 4 +- .../Internal}/WebDriverCoordinates.php | 4 +- .../Internal}/WebDriverDoubleClickAction.php | 4 +- .../Internal}/WebDriverKeyDownAction.php | 4 +- .../Internal}/WebDriverKeyUpAction.php | 4 +- .../Internal}/WebDriverKeysRelatedAction.php | 6 ++- .../Internal}/WebDriverMouseAction.php | 12 +++++- .../Internal}/WebDriverMouseMoveAction.php | 4 +- .../Internal}/WebDriverMoveToOffsetAction.php | 6 ++- .../Internal}/WebDriverSendKeysAction.php | 7 +++- .../Internal}/WebDriverSingleKeyAction.php | 7 +++- .../Touch}/WebDriverDoubleTapAction.php | 4 +- .../Touch}/WebDriverDownAction.php | 4 +- .../Touch}/WebDriverFlickAction.php | 4 +- .../WebDriverFlickFromElementAction.php | 5 ++- .../Touch}/WebDriverLongPressAction.php | 4 +- .../Touch}/WebDriverMoveAction.php | 4 +- .../Touch}/WebDriverScrollAction.php | 4 +- .../WebDriverScrollFromElementAction.php | 5 ++- .../Touch}/WebDriverTapAction.php | 4 +- .../Touch}/WebDriverTouchAction.php | 5 ++- .../Touch}/WebDriverTouchScreen.php | 4 +- lib/{ => Interactions}/WebDriverActions.php | 15 ++++++- .../WebDriverCompositeAction.php | 4 +- .../WebDriverTouchActions.php | 16 +++++++- lib/Internal/WebDriverLocatable.php | 29 +++++++++++++ lib/{ => Net}/URLChecker.php | 2 +- lib/{ => Remote}/DesiredCapabilities.php | 7 +++- lib/{ => Remote}/DriverCommand.php | 2 +- lib/{ => Remote}/ExecuteMethod.php | 4 +- lib/{ => Remote}/FileDetector.php | 2 +- lib/{ => Remote}/HttpCommandExecutor.php | 7 +++- lib/{ => Remote}/LocalFileDetector.php | 4 +- lib/{ => Remote}/RemoteExecuteMethod.php | 2 +- lib/{ => Remote}/RemoteKeyboard.php | 5 ++- lib/{ => Remote}/RemoteMouse.php | 5 ++- lib/{ => Remote}/RemoteTargetLocator.php | 7 +++- lib/{ => Remote}/RemoteTouchScreen.php | 5 ++- lib/{ => Remote}/RemoteWebDriver.php | 12 +++++- lib/{ => Remote}/RemoteWebElement.php | 9 +++- .../Service}/DriverCommandExecutor.php | 10 ++++- lib/{ => Remote/Service}/DriverService.php | 3 +- lib/{ => Remote}/UselessFileDetector.php | 2 +- lib/{ => Remote}/WebDriverBrowserType.php | 2 +- lib/{ => Remote}/WebDriverCapabilityType.php | 2 +- lib/{ => Remote}/WebDriverCommand.php | 2 +- lib/{ => Remote}/WebDriverResponse.php | 2 +- .../Events}/EventFiringWebDriver.php | 11 ++++- .../EventFiringWebDriverNavigation.php | 4 +- .../Events}/EventFiringWebElement.php | 9 +++- lib/WebDriverAlert.php | 2 + lib/WebDriverCommandExecutor.php | 3 ++ lib/WebDriverDispatcher.php | 2 + lib/WebDriverEventListener.php | 2 + lib/WebDriverExpectedCondition.php | 1 + lib/WebDriverLocatable.php | 27 ------------ lib/WebDriverMouse.php | 2 + lib/WebDriverNavigation.php | 3 ++ lib/WebDriverOptions.php | 3 ++ lib/WebDriverSelect.php | 1 + lib/WebDriverTimeouts.php | 2 + lib/WebDriverUpAction.php | 3 ++ lib/WebDriverWait.php | 6 +++ lib/WebDriverWindow.php | 2 + tests/functional/FileUploadTest.php | 2 + tests/functional/WebDriverTestCase.php | 4 ++ tests/unit/bootstrap.php | 2 +- .../WebDriverButtonReleaseActionTest.php | 7 +++- .../internal/WebDriverClickActionTest.php | 7 +++- .../WebDriverClickAndHoldActionTest.php | 7 +++- .../WebDriverContextClickActionTest.php | 7 +++- .../internal/WebDriverCoordinatesTest.php | 2 + .../WebDriverDoubleClickActionTest.php | 7 +++- .../internal/WebDriverKeyDownActionTest.php | 8 +++- .../internal/WebDriverKeyUpActionTest.php | 8 +++- .../internal/WebDriverMouseMoveActionTest.php | 8 +++- .../WebDriverMouseToOffsetActionTest.php | 8 +++- .../internal/WebDriverSendKeysActionTest.php | 8 +++- 88 files changed, 424 insertions(+), 112 deletions(-) rename lib/{ => Chrome}/ChromeDriver.php (72%) rename lib/{ => Chrome}/ChromeDriverService.php (92%) rename lib/{ => Chrome}/ChromeOptions.php (97%) rename lib/{ => Firefox}/FirefoxDriver.php (94%) rename lib/{ => Firefox}/FirefoxProfile.php (96%) rename lib/{ => Interactions/Internal}/WebDriverButtonReleaseAction.php (90%) rename lib/{ => Interactions/Internal}/WebDriverClickAction.php (89%) rename lib/{ => Interactions/Internal}/WebDriverClickAndHoldAction.php (90%) rename lib/{ => Interactions/Internal}/WebDriverContextClickAction.php (90%) rename lib/{ => Interactions/Internal}/WebDriverCoordinates.php (92%) rename lib/{ => Interactions/Internal}/WebDriverDoubleClickAction.php (89%) rename lib/{ => Interactions/Internal}/WebDriverKeyDownAction.php (89%) rename lib/{ => Interactions/Internal}/WebDriverKeyUpAction.php (89%) rename lib/{ => Interactions/Internal}/WebDriverKeysRelatedAction.php (88%) rename lib/{ => Interactions/Internal}/WebDriverMouseAction.php (85%) rename lib/{ => Interactions/Internal}/WebDriverMouseMoveAction.php (89%) rename lib/{ => Interactions/Internal}/WebDriverMoveToOffsetAction.php (87%) rename lib/{ => Interactions/Internal}/WebDriverSendKeysAction.php (84%) rename lib/{ => Interactions/Internal}/WebDriverSingleKeyAction.php (81%) rename lib/{ => Interactions/Touch}/WebDriverDoubleTapAction.php (90%) rename lib/{ => Interactions/Touch}/WebDriverDownAction.php (92%) rename lib/{ => Interactions/Touch}/WebDriverFlickAction.php (92%) rename lib/{ => Interactions/Touch}/WebDriverFlickFromElementAction.php (91%) rename lib/{ => Interactions/Touch}/WebDriverLongPressAction.php (90%) rename lib/{ => Interactions/Touch}/WebDriverMoveAction.php (92%) rename lib/{ => Interactions/Touch}/WebDriverScrollAction.php (92%) rename lib/{ => Interactions/Touch}/WebDriverScrollFromElementAction.php (90%) rename lib/{ => Interactions/Touch}/WebDriverTapAction.php (89%) rename lib/{ => Interactions/Touch}/WebDriverTouchAction.php (89%) rename lib/{ => Interactions/Touch}/WebDriverTouchScreen.php (97%) rename lib/{ => Interactions}/WebDriverActions.php (88%) rename lib/{ => Interactions}/WebDriverCompositeAction.php (94%) rename lib/{ => Interactions}/WebDriverTouchActions.php (81%) create mode 100644 lib/Internal/WebDriverLocatable.php rename lib/{ => Net}/URLChecker.php (98%) rename lib/{ => Remote}/DesiredCapabilities.php (96%) rename lib/{ => Remote}/DriverCommand.php (99%) rename lib/{ => Remote}/ExecuteMethod.php (90%) rename lib/{ => Remote}/FileDetector.php (96%) rename lib/{ => Remote}/HttpCommandExecutor.php (99%) rename lib/{ => Remote}/LocalFileDetector.php (91%) rename lib/{ => Remote}/RemoteExecuteMethod.php (96%) rename lib/{ => Remote}/RemoteKeyboard.php (93%) rename lib/{ => Remote}/RemoteMouse.php (95%) rename lib/{ => Remote}/RemoteTargetLocator.php (93%) rename lib/{ => Remote}/RemoteTouchScreen.php (96%) rename lib/{ => Remote}/RemoteWebDriver.php (96%) rename lib/{ => Remote}/RemoteWebElement.php (96%) rename lib/{ => Remote/Service}/DriverCommandExecutor.php (85%) rename lib/{ => Remote/Service}/DriverService.php (97%) rename lib/{ => Remote}/UselessFileDetector.php (95%) rename lib/{ => Remote}/WebDriverBrowserType.php (97%) rename lib/{ => Remote}/WebDriverCapabilityType.php (97%) rename lib/{ => Remote}/WebDriverCommand.php (96%) rename lib/{ => Remote}/WebDriverResponse.php (97%) rename lib/{ => Support/Events}/EventFiringWebDriver.php (95%) rename lib/{ => Support/Events}/EventFiringWebDriverNavigation.php (96%) rename lib/{ => Support/Events}/EventFiringWebElement.php (95%) delete mode 100644 lib/WebDriverLocatable.php diff --git a/example.php b/example.php index b4834146c..556a100a0 100644 --- a/example.php +++ b/example.php @@ -3,6 +3,9 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Remote\DesiredCapabilities; +use Facebook\WebDriver\Remote\RemoteWebDriver; + require_once('vendor/autoload.php'); // start Firefox with 5 second timeout diff --git a/lib/ChromeDriver.php b/lib/Chrome/ChromeDriver.php similarity index 72% rename from lib/ChromeDriver.php rename to lib/Chrome/ChromeDriver.php index 3fb84ad58..67427205d 100644 --- a/lib/ChromeDriver.php +++ b/lib/Chrome/ChromeDriver.php @@ -13,9 +13,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Chrome; +use Facebook\WebDriver\Remote\DesiredCapabilities; +use Facebook\WebDriver\Remote\DriverCommand; +use Facebook\WebDriver\Remote\Service\DriverCommandExecutor; use Facebook\WebDriver\Exception\WebDriverException; +use Facebook\WebDriver\Remote\RemoteWebDriver; +use Facebook\WebDriver\Remote\WebDriverCommand; class ChromeDriver extends RemoteWebDriver { @@ -49,10 +54,14 @@ public function startSession($desired_capabilities) { } /** - * @param string $url The url of the remote server + * Always throws an exception. Use ChromeDriver::start() instead. + * + * @param string $url The url of the remote server * @param DesiredCapabilities $desired_capabilities The desired capabilities - * @param int|null $connection_timeout_in_ms - * @param int|null $request_timeout_in_ms + * @param int|null $timeout_in_ms + * @param int|null $request_timeout_in_ms + * + * @throws WebDriverException */ public static function create( $url = 'http://localhost:4444/wd/hub', @@ -63,6 +72,14 @@ public static function create( throw new WebDriverException('Please use ChromeDriver::start() instead.'); } + /** + * Always throws an exception. Use ChromeDriver::start() instead. + * + * @param string $session_id The existing session id + * @param string $url The url of the remote server + * + * @throws WebDriverException + */ public static function createBySessionID( $session_id, $url = 'http://localhost:4444/wd/hub' diff --git a/lib/ChromeDriverService.php b/lib/Chrome/ChromeDriverService.php similarity index 92% rename from lib/ChromeDriverService.php rename to lib/Chrome/ChromeDriverService.php index 9494bfd1a..d60f376a6 100644 --- a/lib/ChromeDriverService.php +++ b/lib/Chrome/ChromeDriverService.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Chrome; + +use Facebook\WebDriver\Remote\Service\DriverService; class ChromeDriverService extends DriverService { diff --git a/lib/ChromeOptions.php b/lib/Chrome/ChromeOptions.php similarity index 97% rename from lib/ChromeOptions.php rename to lib/Chrome/ChromeOptions.php index eb2f92e8c..5cc125f56 100644 --- a/lib/ChromeOptions.php +++ b/lib/Chrome/ChromeOptions.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Chrome; + +use Facebook\WebDriver\Remote\DesiredCapabilities; /** * The class manages the capabilities in ChromeDriver. diff --git a/lib/Exception/WebDriverException.php b/lib/Exception/WebDriverException.php index af90b7cf7..a23f42103 100644 --- a/lib/Exception/WebDriverException.php +++ b/lib/Exception/WebDriverException.php @@ -42,9 +42,46 @@ public function getResults() { * For $status_code >= 0, they are errors defined in the json wired protocol. * For $status_code < 0, they are errors defined in php-webdriver. * - * @param int $status_code + * @param int $status_code * @param string $message - * @param mixed $results + * @param mixed $results + * + * @throws ElementNotSelectableException + * @throws ElementNotVisibleException + * @throws ExpectedException + * @throws IMEEngineActivationFailedException + * @throws IMENotAvailableException + * @throws IndexOutOfBoundsException + * @throws InvalidCookieDomainException + * @throws InvalidCoordinatesException + * @throws InvalidElementStateException + * @throws InvalidSelectorException + * @throws MoveTargetOutOfBoundsException + * @throws NoAlertOpenException + * @throws NoCollectionException + * @throws NoScriptResultException + * @throws NoStringException + * @throws NoStringLengthException + * @throws NoStringWrapperException + * @throws NoSuchCollectionException + * @throws NoSuchDocumentException + * @throws NoSuchDriverException + * @throws NoSuchElementException + * @throws NoSuchFrameException + * @throws NoSuchWindowException + * @throws NullPointerException + * @throws ScriptTimeoutException + * @throws SessionNotCreatedException + * @throws StaleElementReferenceException + * @throws TimeOutException + * @throws UnableToSetCookieException + * @throws UnexpectedAlertOpenException + * @throws UnexpectedJavascriptException + * @throws UnknownCommandException + * @throws UnknownServerException + * @throws UnrecognizedExceptionException + * @throws WebDriverCurlException + * @throws XPathLookupException */ public static function throwException($status_code, $message, $results) { switch ($status_code) { diff --git a/lib/FirefoxDriver.php b/lib/Firefox/FirefoxDriver.php similarity index 94% rename from lib/FirefoxDriver.php rename to lib/Firefox/FirefoxDriver.php index 019064e71..8afbe0c2d 100644 --- a/lib/FirefoxDriver.php +++ b/lib/Firefox/FirefoxDriver.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Firefox; class FirefoxDriver { diff --git a/lib/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php similarity index 96% rename from lib/FirefoxProfile.php rename to lib/Firefox/FirefoxProfile.php index d72fc06c1..d15d9556e 100644 --- a/lib/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Firefox; use Facebook\WebDriver\Exception\WebDriverException; use RecursiveDirectoryIterator; @@ -127,7 +127,9 @@ private function installExtension($extension, $profile_dir) { /** * @param string $prefix Prefix of the temp directory. + * * @return string The path to the temp directory created. + * @throws WebDriverException */ private function createTempDirectory($prefix = '') { $temp_dir = tempnam('', $prefix); @@ -142,9 +144,11 @@ private function createTempDirectory($prefix = '') { } /** - * @param string $xpi The path to the .xpi extension. + * @param string $xpi The path to the .xpi extension. * @param string $target_dir The path to the unzip directory. + * * @return FirefoxProfile + * @throws \Exception */ private function extractTo($xpi, $target_dir) { $zip = new ZipArchive(); diff --git a/lib/WebDriverButtonReleaseAction.php b/lib/Interactions/Internal/WebDriverButtonReleaseAction.php similarity index 90% rename from lib/WebDriverButtonReleaseAction.php rename to lib/Interactions/Internal/WebDriverButtonReleaseAction.php index 444632265..a63570ae6 100644 --- a/lib/WebDriverButtonReleaseAction.php +++ b/lib/Interactions/Internal/WebDriverButtonReleaseAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverAction; /** * Move to the location and then release the mouse key. diff --git a/lib/WebDriverClickAction.php b/lib/Interactions/Internal/WebDriverClickAction.php similarity index 89% rename from lib/WebDriverClickAction.php rename to lib/Interactions/Internal/WebDriverClickAction.php index cc9263c17..f110d34bd 100644 --- a/lib/WebDriverClickAction.php +++ b/lib/Interactions/Internal/WebDriverClickAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverAction; class WebDriverClickAction extends WebDriverMouseAction diff --git a/lib/WebDriverClickAndHoldAction.php b/lib/Interactions/Internal/WebDriverClickAndHoldAction.php similarity index 90% rename from lib/WebDriverClickAndHoldAction.php rename to lib/Interactions/Internal/WebDriverClickAndHoldAction.php index 6bc8d049b..264d1503f 100644 --- a/lib/WebDriverClickAndHoldAction.php +++ b/lib/Interactions/Internal/WebDriverClickAndHoldAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverAction; /** * Move the the location, click and hold. diff --git a/lib/WebDriverContextClickAction.php b/lib/Interactions/Internal/WebDriverContextClickAction.php similarity index 90% rename from lib/WebDriverContextClickAction.php rename to lib/Interactions/Internal/WebDriverContextClickAction.php index 5e2638dca..d431173e9 100644 --- a/lib/WebDriverContextClickAction.php +++ b/lib/Interactions/Internal/WebDriverContextClickAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverAction; /** * You can call it 'Right Click' if you like. diff --git a/lib/WebDriverCoordinates.php b/lib/Interactions/Internal/WebDriverCoordinates.php similarity index 92% rename from lib/WebDriverCoordinates.php rename to lib/Interactions/Internal/WebDriverCoordinates.php index e43b7fb75..89aae19bb 100644 --- a/lib/WebDriverCoordinates.php +++ b/lib/Interactions/Internal/WebDriverCoordinates.php @@ -13,10 +13,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; use Closure; use Facebook\WebDriver\Exception\UnsupportedOperationException; +use Facebook\WebDriver\WebDriverPoint; /** * Interface representing basic mouse operations. @@ -43,6 +44,7 @@ public function __construct( /** * @return WebDriverPoint + * @throws UnsupportedOperationException */ public function onScreen() { throw new UnsupportedOperationException( diff --git a/lib/WebDriverDoubleClickAction.php b/lib/Interactions/Internal/WebDriverDoubleClickAction.php similarity index 89% rename from lib/WebDriverDoubleClickAction.php rename to lib/Interactions/Internal/WebDriverDoubleClickAction.php index 15c9e422c..218a05b5e 100644 --- a/lib/WebDriverDoubleClickAction.php +++ b/lib/Interactions/Internal/WebDriverDoubleClickAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverAction; class WebDriverDoubleClickAction extends WebDriverMouseAction diff --git a/lib/WebDriverKeyDownAction.php b/lib/Interactions/Internal/WebDriverKeyDownAction.php similarity index 89% rename from lib/WebDriverKeyDownAction.php rename to lib/Interactions/Internal/WebDriverKeyDownAction.php index 5d5aa2afe..29350e484 100644 --- a/lib/WebDriverKeyDownAction.php +++ b/lib/Interactions/Internal/WebDriverKeyDownAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverAction; class WebDriverKeyDownAction extends WebDriverSingleKeyAction diff --git a/lib/WebDriverKeyUpAction.php b/lib/Interactions/Internal/WebDriverKeyUpAction.php similarity index 89% rename from lib/WebDriverKeyUpAction.php rename to lib/Interactions/Internal/WebDriverKeyUpAction.php index d41a5a2d8..9b89747eb 100644 --- a/lib/WebDriverKeyUpAction.php +++ b/lib/Interactions/Internal/WebDriverKeyUpAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverAction; class WebDriverKeyUpAction extends WebDriverSingleKeyAction diff --git a/lib/WebDriverKeysRelatedAction.php b/lib/Interactions/Internal/WebDriverKeysRelatedAction.php similarity index 88% rename from lib/WebDriverKeysRelatedAction.php rename to lib/Interactions/Internal/WebDriverKeysRelatedAction.php index bcd45f7f7..77892cc25 100644 --- a/lib/WebDriverKeysRelatedAction.php +++ b/lib/Interactions/Internal/WebDriverKeysRelatedAction.php @@ -13,7 +13,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverMouse; +use Facebook\WebDriver\WebDriverKeyboard; /** * Base class for all keyboard-related actions. diff --git a/lib/WebDriverMouseAction.php b/lib/Interactions/Internal/WebDriverMouseAction.php similarity index 85% rename from lib/WebDriverMouseAction.php rename to lib/Interactions/Internal/WebDriverMouseAction.php index 5038daa45..e261cc9b5 100644 --- a/lib/WebDriverMouseAction.php +++ b/lib/Interactions/Internal/WebDriverMouseAction.php @@ -13,14 +13,24 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverMouse; +use Facebook\WebDriver\Internal\WebDriverLocatable; /** * Base class for all mouse-related actions. */ class WebDriverMouseAction { + /** + * @var WebDriverMouse + */ protected $mouse; + + /** + * @var WebDriverLocatable + */ protected $locationProvider; public function __construct( diff --git a/lib/WebDriverMouseMoveAction.php b/lib/Interactions/Internal/WebDriverMouseMoveAction.php similarity index 89% rename from lib/WebDriverMouseMoveAction.php rename to lib/Interactions/Internal/WebDriverMouseMoveAction.php index b24948daf..d229904fc 100644 --- a/lib/WebDriverMouseMoveAction.php +++ b/lib/Interactions/Internal/WebDriverMouseMoveAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverAction; class WebDriverMouseMoveAction extends WebDriverMouseAction diff --git a/lib/WebDriverMoveToOffsetAction.php b/lib/Interactions/Internal/WebDriverMoveToOffsetAction.php similarity index 87% rename from lib/WebDriverMoveToOffsetAction.php rename to lib/Interactions/Internal/WebDriverMoveToOffsetAction.php index fe1b0bfc2..f1e0270f8 100644 --- a/lib/WebDriverMoveToOffsetAction.php +++ b/lib/Interactions/Internal/WebDriverMoveToOffsetAction.php @@ -13,7 +13,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverAction; +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverMouse; class WebDriverMoveToOffsetAction extends WebDriverMouseAction diff --git a/lib/WebDriverSendKeysAction.php b/lib/Interactions/Internal/WebDriverSendKeysAction.php similarity index 84% rename from lib/WebDriverSendKeysAction.php rename to lib/Interactions/Internal/WebDriverSendKeysAction.php index 9b371a551..2c9512dd3 100644 --- a/lib/WebDriverSendKeysAction.php +++ b/lib/Interactions/Internal/WebDriverSendKeysAction.php @@ -13,7 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverAction; +use Facebook\WebDriver\WebDriverKeyboard; +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverMouse; class WebDriverSendKeysAction extends WebDriverKeysRelatedAction diff --git a/lib/WebDriverSingleKeyAction.php b/lib/Interactions/Internal/WebDriverSingleKeyAction.php similarity index 81% rename from lib/WebDriverSingleKeyAction.php rename to lib/Interactions/Internal/WebDriverSingleKeyAction.php index a9280afe1..86cd74936 100644 --- a/lib/WebDriverSingleKeyAction.php +++ b/lib/Interactions/Internal/WebDriverSingleKeyAction.php @@ -13,7 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverAction; +use Facebook\WebDriver\WebDriverKeyboard; +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverMouse; abstract class WebDriverSingleKeyAction extends WebDriverKeysRelatedAction diff --git a/lib/WebDriverDoubleTapAction.php b/lib/Interactions/Touch/WebDriverDoubleTapAction.php similarity index 90% rename from lib/WebDriverDoubleTapAction.php rename to lib/Interactions/Touch/WebDriverDoubleTapAction.php index c2cc7d381..92ccfa222 100644 --- a/lib/WebDriverDoubleTapAction.php +++ b/lib/Interactions/Touch/WebDriverDoubleTapAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Touch; + +use Facebook\WebDriver\WebDriverAction; class WebDriverDoubleTapAction extends WebDriverTouchAction diff --git a/lib/WebDriverDownAction.php b/lib/Interactions/Touch/WebDriverDownAction.php similarity index 92% rename from lib/WebDriverDownAction.php rename to lib/Interactions/Touch/WebDriverDownAction.php index 67fc73e55..eb946008f 100644 --- a/lib/WebDriverDownAction.php +++ b/lib/Interactions/Touch/WebDriverDownAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Touch; + +use Facebook\WebDriver\WebDriverAction; class WebDriverDownAction extends WebDriverTouchAction diff --git a/lib/WebDriverFlickAction.php b/lib/Interactions/Touch/WebDriverFlickAction.php similarity index 92% rename from lib/WebDriverFlickAction.php rename to lib/Interactions/Touch/WebDriverFlickAction.php index 446340718..575c3eb4d 100644 --- a/lib/WebDriverFlickAction.php +++ b/lib/Interactions/Touch/WebDriverFlickAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Touch; + +use Facebook\WebDriver\WebDriverAction; class WebDriverFlickAction extends WebDriverTouchAction diff --git a/lib/WebDriverFlickFromElementAction.php b/lib/Interactions/Touch/WebDriverFlickFromElementAction.php similarity index 91% rename from lib/WebDriverFlickFromElementAction.php rename to lib/Interactions/Touch/WebDriverFlickFromElementAction.php index 3781d6c0e..afd13ab8c 100644 --- a/lib/WebDriverFlickFromElementAction.php +++ b/lib/Interactions/Touch/WebDriverFlickFromElementAction.php @@ -13,7 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Touch; + +use Facebook\WebDriver\WebDriverAction; +use Facebook\WebDriver\WebDriverElement; class WebDriverFlickFromElementAction extends WebDriverTouchAction diff --git a/lib/WebDriverLongPressAction.php b/lib/Interactions/Touch/WebDriverLongPressAction.php similarity index 90% rename from lib/WebDriverLongPressAction.php rename to lib/Interactions/Touch/WebDriverLongPressAction.php index 5fc2b519e..c46770d86 100644 --- a/lib/WebDriverLongPressAction.php +++ b/lib/Interactions/Touch/WebDriverLongPressAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Touch; + +use Facebook\WebDriver\WebDriverAction; class WebDriverLongPressAction extends WebDriverTouchAction diff --git a/lib/WebDriverMoveAction.php b/lib/Interactions/Touch/WebDriverMoveAction.php similarity index 92% rename from lib/WebDriverMoveAction.php rename to lib/Interactions/Touch/WebDriverMoveAction.php index 32c324de7..330783271 100644 --- a/lib/WebDriverMoveAction.php +++ b/lib/Interactions/Touch/WebDriverMoveAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Touch; + +use Facebook\WebDriver\WebDriverAction; class WebDriverMoveAction extends WebDriverTouchAction diff --git a/lib/WebDriverScrollAction.php b/lib/Interactions/Touch/WebDriverScrollAction.php similarity index 92% rename from lib/WebDriverScrollAction.php rename to lib/Interactions/Touch/WebDriverScrollAction.php index e7e183b31..8dc1f14b7 100644 --- a/lib/WebDriverScrollAction.php +++ b/lib/Interactions/Touch/WebDriverScrollAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Touch; + +use Facebook\WebDriver\WebDriverAction; class WebDriverScrollAction extends WebDriverTouchAction diff --git a/lib/WebDriverScrollFromElementAction.php b/lib/Interactions/Touch/WebDriverScrollFromElementAction.php similarity index 90% rename from lib/WebDriverScrollFromElementAction.php rename to lib/Interactions/Touch/WebDriverScrollFromElementAction.php index 63be82c48..df31f13b0 100644 --- a/lib/WebDriverScrollFromElementAction.php +++ b/lib/Interactions/Touch/WebDriverScrollFromElementAction.php @@ -13,7 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Touch; + +use Facebook\WebDriver\WebDriverAction; +use Facebook\WebDriver\WebDriverElement; class WebDriverScrollFromElementAction extends WebDriverTouchAction diff --git a/lib/WebDriverTapAction.php b/lib/Interactions/Touch/WebDriverTapAction.php similarity index 89% rename from lib/WebDriverTapAction.php rename to lib/Interactions/Touch/WebDriverTapAction.php index 27ef9627f..835acc848 100644 --- a/lib/WebDriverTapAction.php +++ b/lib/Interactions/Touch/WebDriverTapAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Touch; + +use Facebook\WebDriver\WebDriverAction; class WebDriverTapAction extends WebDriverTouchAction diff --git a/lib/WebDriverTouchAction.php b/lib/Interactions/Touch/WebDriverTouchAction.php similarity index 89% rename from lib/WebDriverTouchAction.php rename to lib/Interactions/Touch/WebDriverTouchAction.php index 06ba9fdab..e267f1ab3 100644 --- a/lib/WebDriverTouchAction.php +++ b/lib/Interactions/Touch/WebDriverTouchAction.php @@ -13,7 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Touch; + +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates; /** * Base class for all touch-related actions. diff --git a/lib/WebDriverTouchScreen.php b/lib/Interactions/Touch/WebDriverTouchScreen.php similarity index 97% rename from lib/WebDriverTouchScreen.php rename to lib/Interactions/Touch/WebDriverTouchScreen.php index 46f989013..cb753cd0d 100644 --- a/lib/WebDriverTouchScreen.php +++ b/lib/Interactions/Touch/WebDriverTouchScreen.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Touch; + +use Facebook\WebDriver\WebDriverElement; /** * Interface representing touch screen operations. diff --git a/lib/WebDriverActions.php b/lib/Interactions/WebDriverActions.php similarity index 88% rename from lib/WebDriverActions.php rename to lib/Interactions/WebDriverActions.php index 37537e2b9..4d8a623d8 100644 --- a/lib/WebDriverActions.php +++ b/lib/Interactions/WebDriverActions.php @@ -13,7 +13,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions; + +use Facebook\WebDriver\Interactions\Internal\WebDriverClickAndHoldAction; +use Facebook\WebDriver\Interactions\Internal\WebDriverMoveToOffsetAction; +use Facebook\WebDriver\Interactions\Internal\WebDriverButtonReleaseAction; +use Facebook\WebDriver\Interactions\Internal\WebDriverDoubleClickAction; +use Facebook\WebDriver\Interactions\Internal\WebDriverSendKeysAction; +use Facebook\WebDriver\Interactions\Internal\WebDriverClickAction; +use Facebook\WebDriver\Interactions\Internal\WebDriverKeyDownAction; +use Facebook\WebDriver\Interactions\Internal\WebDriverContextClickAction; +use Facebook\WebDriver\Interactions\Internal\WebDriverKeyUpAction; +use Facebook\WebDriver\Interactions\Internal\WebDriverMouseMoveAction; +use Facebook\WebDriver\WebDriverElement; +use Facebook\WebDriver\WebDriver; /** * WebDriver action builder. It implements the builder pattern. diff --git a/lib/WebDriverCompositeAction.php b/lib/Interactions/WebDriverCompositeAction.php similarity index 94% rename from lib/WebDriverCompositeAction.php rename to lib/Interactions/WebDriverCompositeAction.php index de80c787f..63d9863d7 100644 --- a/lib/WebDriverCompositeAction.php +++ b/lib/Interactions/WebDriverCompositeAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions; + +use Facebook\WebDriver\WebDriverAction; /** * An action for aggregating actions and triggering all of them afterwards. diff --git a/lib/WebDriverTouchActions.php b/lib/Interactions/WebDriverTouchActions.php similarity index 81% rename from lib/WebDriverTouchActions.php rename to lib/Interactions/WebDriverTouchActions.php index a223f269d..ec77242fc 100644 --- a/lib/WebDriverTouchActions.php +++ b/lib/Interactions/WebDriverTouchActions.php @@ -13,7 +13,21 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions; + +use Facebook\WebDriver\Interactions\Touch\WebDriverTouchScreen; +use Facebook\WebDriver\Interactions\Touch\WebDriverDoubleTapAction; +use Facebook\WebDriver\Interactions\Touch\WebDriverFlickAction; +use Facebook\WebDriver\Interactions\Touch\WebDriverFlickFromElementAction; +use Facebook\WebDriver\Interactions\Touch\WebDriverLongPressAction; +use Facebook\WebDriver\Interactions\Touch\WebDriverTapAction; +use Facebook\WebDriver\Interactions\Touch\WebDriverScrollFromElementAction; +use Facebook\WebDriver\Interactions\Touch\WebDriverDownAction; +use Facebook\WebDriver\Interactions\Touch\WebDriverMoveAction; +use Facebook\WebDriver\Interactions\Touch\WebDriverScrollAction; +use Facebook\WebDriver\WebDriverUpAction; +use Facebook\WebDriver\WebDriverElement; +use Facebook\WebDriver\WebDriver; /** * WebDriver action builder for touch events diff --git a/lib/Internal/WebDriverLocatable.php b/lib/Internal/WebDriverLocatable.php new file mode 100644 index 000000000..1523c35c0 --- /dev/null +++ b/lib/Internal/WebDriverLocatable.php @@ -0,0 +1,29 @@ +getName()])) { diff --git a/lib/LocalFileDetector.php b/lib/Remote/LocalFileDetector.php similarity index 91% rename from lib/LocalFileDetector.php rename to lib/Remote/LocalFileDetector.php index a9a7488ce..c6d44f78c 100644 --- a/lib/LocalFileDetector.php +++ b/lib/Remote/LocalFileDetector.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; + +use Facebook\WebDriver\Remote\FileDetector; class LocalFileDetector implements FileDetector { /** diff --git a/lib/RemoteExecuteMethod.php b/lib/Remote/RemoteExecuteMethod.php similarity index 96% rename from lib/RemoteExecuteMethod.php rename to lib/Remote/RemoteExecuteMethod.php index 3ab0a60ae..e0ded1032 100644 --- a/lib/RemoteExecuteMethod.php +++ b/lib/Remote/RemoteExecuteMethod.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; class RemoteExecuteMethod implements ExecuteMethod { diff --git a/lib/RemoteKeyboard.php b/lib/Remote/RemoteKeyboard.php similarity index 93% rename from lib/RemoteKeyboard.php rename to lib/Remote/RemoteKeyboard.php index d7d3ebbdb..2b297d1d9 100644 --- a/lib/RemoteKeyboard.php +++ b/lib/Remote/RemoteKeyboard.php @@ -13,7 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; + +use Facebook\WebDriver\WebDriverKeys; +use Facebook\WebDriver\WebDriverKeyboard; /** * Execute keyboard commands for RemoteWebDriver. diff --git a/lib/RemoteMouse.php b/lib/Remote/RemoteMouse.php similarity index 95% rename from lib/RemoteMouse.php rename to lib/Remote/RemoteMouse.php index deb2164fd..c2e0d2263 100644 --- a/lib/RemoteMouse.php +++ b/lib/Remote/RemoteMouse.php @@ -13,7 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; + +use Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates; +use Facebook\WebDriver\WebDriverMouse; /** * Execute mouse commands for RemoteWebDriver. diff --git a/lib/RemoteTargetLocator.php b/lib/Remote/RemoteTargetLocator.php similarity index 93% rename from lib/RemoteTargetLocator.php rename to lib/Remote/RemoteTargetLocator.php index c33bd2c71..e2f5a0aea 100644 --- a/lib/RemoteTargetLocator.php +++ b/lib/Remote/RemoteTargetLocator.php @@ -13,7 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; + +use Facebook\WebDriver\WebDriverTargetLocator; +use Facebook\WebDriver\WebDriverElement; +use Facebook\WebDriver\WebDriverAlert; +use Facebook\WebDriver\WebDriver; /** * Used to locate a given frame or window for RemoteWebDriver. diff --git a/lib/RemoteTouchScreen.php b/lib/Remote/RemoteTouchScreen.php similarity index 96% rename from lib/RemoteTouchScreen.php rename to lib/Remote/RemoteTouchScreen.php index 3ca3c19bd..7929d5db3 100644 --- a/lib/RemoteTouchScreen.php +++ b/lib/Remote/RemoteTouchScreen.php @@ -13,7 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; + +use Facebook\WebDriver\Interactions\Touch\WebDriverTouchScreen; +use Facebook\WebDriver\WebDriverElement; /** * Execute touch commands for RemoteWebDriver. diff --git a/lib/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php similarity index 96% rename from lib/RemoteWebDriver.php rename to lib/Remote/RemoteWebDriver.php index 86d9e0d8b..4f3be385e 100644 --- a/lib/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -13,7 +13,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; + +use Facebook\WebDriver\Interactions\WebDriverActions; +use Facebook\WebDriver\JavaScriptExecutor; +use Facebook\WebDriver\WebDriver; +use Facebook\WebDriver\WebDriverBy; +use Facebook\WebDriver\WebDriverCommandExecutor; +use Facebook\WebDriver\WebDriverElement; +use Facebook\WebDriver\WebDriverNavigation; +use Facebook\WebDriver\WebDriverOptions; +use Facebook\WebDriver\WebDriverWait; class RemoteWebDriver implements WebDriver, JavaScriptExecutor { /** diff --git a/lib/RemoteWebElement.php b/lib/Remote/RemoteWebElement.php similarity index 96% rename from lib/RemoteWebElement.php rename to lib/Remote/RemoteWebElement.php index 178397165..4de82eab5 100644 --- a/lib/RemoteWebElement.php +++ b/lib/Remote/RemoteWebElement.php @@ -13,9 +13,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; use Facebook\WebDriver\Exception\WebDriverException; +use Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates; +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverBy; +use Facebook\WebDriver\WebDriverDimension; +use Facebook\WebDriver\WebDriverElement; +use Facebook\WebDriver\WebDriverKeys; +use Facebook\WebDriver\WebDriverPoint; use ZipArchive; /** diff --git a/lib/DriverCommandExecutor.php b/lib/Remote/Service/DriverCommandExecutor.php similarity index 85% rename from lib/DriverCommandExecutor.php rename to lib/Remote/Service/DriverCommandExecutor.php index 228f21b4d..f4857e933 100644 --- a/lib/DriverCommandExecutor.php +++ b/lib/Remote/Service/DriverCommandExecutor.php @@ -13,8 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote\Service; + use Facebook\WebDriver\Exception\WebDriverException; +use Facebook\WebDriver\Remote\DriverCommand; +use Facebook\WebDriver\Remote\HttpCommandExecutor; +use Facebook\WebDriver\Remote\WebDriverCommand; /** * A HttpCommandExecutor that talks to a local driver service instead of @@ -34,9 +38,11 @@ public function __construct(DriverService $service) { /** * @param WebDriverCommand $command - * @param array $curl_opts + * @param array $curl_opts * * @return mixed + * @throws WebDriverException + * @throws \Exception */ public function execute(WebDriverCommand $command, $curl_opts = array()) { if ($command->getName() === DriverCommand::NEW_SESSION) { diff --git a/lib/DriverService.php b/lib/Remote/Service/DriverService.php similarity index 97% rename from lib/DriverService.php rename to lib/Remote/Service/DriverService.php index 6a573afe5..2dc660202 100644 --- a/lib/DriverService.php +++ b/lib/Remote/Service/DriverService.php @@ -13,9 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote\Service; use Exception; +use Facebook\WebDriver\Net\URLChecker; class DriverService { diff --git a/lib/UselessFileDetector.php b/lib/Remote/UselessFileDetector.php similarity index 95% rename from lib/UselessFileDetector.php rename to lib/Remote/UselessFileDetector.php index ce4c55fc9..9a8090038 100644 --- a/lib/UselessFileDetector.php +++ b/lib/Remote/UselessFileDetector.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; class UselessFileDetector implements FileDetector { /** diff --git a/lib/WebDriverBrowserType.php b/lib/Remote/WebDriverBrowserType.php similarity index 97% rename from lib/WebDriverBrowserType.php rename to lib/Remote/WebDriverBrowserType.php index bbb9a529e..5ab1df391 100644 --- a/lib/WebDriverBrowserType.php +++ b/lib/Remote/WebDriverBrowserType.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; /** * All the browsers supported by selenium diff --git a/lib/WebDriverCapabilityType.php b/lib/Remote/WebDriverCapabilityType.php similarity index 97% rename from lib/WebDriverCapabilityType.php rename to lib/Remote/WebDriverCapabilityType.php index 558abb4ab..552db09be 100644 --- a/lib/WebDriverCapabilityType.php +++ b/lib/Remote/WebDriverCapabilityType.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; /** * WebDriverCapabilityType contains all constants defined in the WebDriver diff --git a/lib/WebDriverCommand.php b/lib/Remote/WebDriverCommand.php similarity index 96% rename from lib/WebDriverCommand.php rename to lib/Remote/WebDriverCommand.php index 06660dadf..303af3cfb 100644 --- a/lib/WebDriverCommand.php +++ b/lib/Remote/WebDriverCommand.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; class WebDriverCommand { diff --git a/lib/WebDriverResponse.php b/lib/Remote/WebDriverResponse.php similarity index 97% rename from lib/WebDriverResponse.php rename to lib/Remote/WebDriverResponse.php index a2d4dd244..d3fcdadcb 100644 --- a/lib/WebDriverResponse.php +++ b/lib/Remote/WebDriverResponse.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; class WebDriverResponse { diff --git a/lib/EventFiringWebDriver.php b/lib/Support/Events/EventFiringWebDriver.php similarity index 95% rename from lib/EventFiringWebDriver.php rename to lib/Support/Events/EventFiringWebDriver.php index ebd5b9b7c..d21c224c8 100644 --- a/lib/EventFiringWebDriver.php +++ b/lib/Support/Events/EventFiringWebDriver.php @@ -13,10 +13,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Support\Events; use Facebook\WebDriver\Exception\UnsupportedOperationException; use Facebook\WebDriver\Exception\WebDriverException; +use Facebook\WebDriver\Interactions\Touch\WebDriverTouchScreen; +use Facebook\WebDriver\JavaScriptExecutor; +use Facebook\WebDriver\WebDriver; +use Facebook\WebDriver\WebDriverBy; +use Facebook\WebDriver\WebDriverDispatcher; +use Facebook\WebDriver\WebDriverElement; +use Facebook\WebDriver\WebDriverOptions; +use Facebook\WebDriver\WebDriverTargetLocator; +use Facebook\WebDriver\WebDriverWait; class EventFiringWebDriver implements WebDriver, JavaScriptExecutor { diff --git a/lib/EventFiringWebDriverNavigation.php b/lib/Support/Events/EventFiringWebDriverNavigation.php similarity index 96% rename from lib/EventFiringWebDriverNavigation.php rename to lib/Support/Events/EventFiringWebDriverNavigation.php index c3feea060..56341e2c2 100644 --- a/lib/EventFiringWebDriverNavigation.php +++ b/lib/Support/Events/EventFiringWebDriverNavigation.php @@ -13,9 +13,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Support\Events; use Facebook\WebDriver\Exception\WebDriverException; +use Facebook\WebDriver\WebDriverDispatcher; +use Facebook\WebDriver\WebDriverNavigation; class EventFiringWebDriverNavigation { diff --git a/lib/EventFiringWebElement.php b/lib/Support/Events/EventFiringWebElement.php similarity index 95% rename from lib/EventFiringWebElement.php rename to lib/Support/Events/EventFiringWebElement.php index a955c59d6..3084ec1b5 100644 --- a/lib/EventFiringWebElement.php +++ b/lib/Support/Events/EventFiringWebElement.php @@ -13,9 +13,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Support\Events; use Facebook\WebDriver\Exception\WebDriverException; +use Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates; +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverBy; +use Facebook\WebDriver\WebDriverDimension; +use Facebook\WebDriver\WebDriverDispatcher; +use Facebook\WebDriver\WebDriverElement; +use Facebook\WebDriver\WebDriverPoint; class EventFiringWebElement implements WebDriverElement, WebDriverLocatable { diff --git a/lib/WebDriverAlert.php b/lib/WebDriverAlert.php index 2f92ec4c4..8bef6d846 100644 --- a/lib/WebDriverAlert.php +++ b/lib/WebDriverAlert.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Remote\DriverCommand; + /** * An abstraction allowing the driver to manipulate the javascript alerts */ diff --git a/lib/WebDriverCommandExecutor.php b/lib/WebDriverCommandExecutor.php index 5f99a1d16..d58998f70 100644 --- a/lib/WebDriverCommandExecutor.php +++ b/lib/WebDriverCommandExecutor.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Remote\WebDriverCommand; + /** * Interface for all command executor. */ @@ -22,6 +24,7 @@ interface WebDriverCommandExecutor { /** * @param WebDriverCommand $command + * * @return mixed */ public function execute(WebDriverCommand $command); diff --git a/lib/WebDriverDispatcher.php b/lib/WebDriverDispatcher.php index ae9e5e8f7..c8caea4d9 100644 --- a/lib/WebDriverDispatcher.php +++ b/lib/WebDriverDispatcher.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Support\Events\EventFiringWebDriver; + class WebDriverDispatcher { /** diff --git a/lib/WebDriverEventListener.php b/lib/WebDriverEventListener.php index 4b458f649..afea9c0fd 100644 --- a/lib/WebDriverEventListener.php +++ b/lib/WebDriverEventListener.php @@ -16,6 +16,8 @@ namespace Facebook\WebDriver; use Facebook\WebDriver\Exception\WebDriverException; +use Facebook\WebDriver\Support\Events\EventFiringWebDriver; +use Facebook\WebDriver\Support\Events\EventFiringWebElement; interface WebDriverEventListener { diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index ac1924a31..3de9a9731 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -14,6 +14,7 @@ // limitations under the License. namespace Facebook\WebDriver; + use Facebook\WebDriver\Exception\StaleElementReferenceException; use Facebook\WebDriver\Exception\NoSuchFrameException; use Facebook\WebDriver\Exception\NoSuchElementException; diff --git a/lib/WebDriverLocatable.php b/lib/WebDriverLocatable.php deleted file mode 100644 index bb2aa9035..000000000 --- a/lib/WebDriverLocatable.php +++ /dev/null @@ -1,27 +0,0 @@ -timeout; diff --git a/lib/WebDriverWindow.php b/lib/WebDriverWindow.php index c29deb06c..dcfa19534 100644 --- a/lib/WebDriverWindow.php +++ b/lib/WebDriverWindow.php @@ -14,7 +14,9 @@ // limitations under the License. namespace Facebook\WebDriver; + use Facebook\WebDriver\Exception\IndexOutOfBoundsException; +use Facebook\WebDriver\Remote\DriverCommand; /** * An abstraction allowing the driver to manipulate the browser's window diff --git a/tests/functional/FileUploadTest.php b/tests/functional/FileUploadTest.php index 8e7289973..0ab233a14 100644 --- a/tests/functional/FileUploadTest.php +++ b/tests/functional/FileUploadTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Remote\LocalFileDetector; + /** * An example test case for php-webdriver. * diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index 2c0793815..73b3c2b58 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -15,6 +15,10 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Remote\RemoteWebDriver; +use Facebook\WebDriver\Remote\WebDriverBrowserType; +use Facebook\WebDriver\Remote\WebDriverCapabilityType; + /** * The base class for test cases. */ diff --git a/tests/unit/bootstrap.php b/tests/unit/bootstrap.php index 77ad6b219..db3b0d958 100644 --- a/tests/unit/bootstrap.php +++ b/tests/unit/bootstrap.php @@ -2,4 +2,4 @@ namespace Facebook\WebDriver; -require_once __DIR__ . '/../../lib/__init__.php'; +require_once __DIR__ . '/../../vendor/autoload.php'; diff --git a/tests/unit/interactions/internal/WebDriverButtonReleaseActionTest.php b/tests/unit/interactions/internal/WebDriverButtonReleaseActionTest.php index 645a85963..3a4779855 100644 --- a/tests/unit/interactions/internal/WebDriverButtonReleaseActionTest.php +++ b/tests/unit/interactions/internal/WebDriverButtonReleaseActionTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Internal\WebDriverButtonReleaseAction; + class WebDriverButtonReleaseActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverButtonReleaseAction @@ -26,7 +28,7 @@ class WebDriverButtonReleaseActionTest extends \PHPUnit_Framework_TestCase { public function setUp() { $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); $this->webDriverButtonReleaseAction = new WebDriverButtonReleaseAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +36,8 @@ public function setUp() { } public function testPerformSendsMouseUpCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseUp')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverButtonReleaseAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverClickActionTest.php b/tests/unit/interactions/internal/WebDriverClickActionTest.php index fd1ece96f..07dd8e5c2 100644 --- a/tests/unit/interactions/internal/WebDriverClickActionTest.php +++ b/tests/unit/interactions/internal/WebDriverClickActionTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Internal\WebDriverClickAction; + class WebDriverClickActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverClickAction @@ -26,7 +28,7 @@ class WebDriverClickActionTest extends \PHPUnit_Framework_TestCase { public function setUp() { $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); $this->webDriverClickAction = new WebDriverClickAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +36,8 @@ public function setUp() { } public function testPerformSendsClickCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverClickAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php b/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php index bf9a4cdea..7bcefd0d5 100644 --- a/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php +++ b/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Internal\WebDriverClickAndHoldAction; + class WebDriverClickAndHoldActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverClickAndHoldAction @@ -26,7 +28,7 @@ class WebDriverClickAndHoldActionTest extends \PHPUnit_Framework_TestCase { public function setUp() { $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); $this->webDriverClickAndHoldAction = new WebDriverClickAndHoldAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +36,8 @@ public function setUp() { } public function testPerformSendsMouseDownCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseDown')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverClickAndHoldAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverContextClickActionTest.php b/tests/unit/interactions/internal/WebDriverContextClickActionTest.php index 2ca80a538..b85a1d7db 100644 --- a/tests/unit/interactions/internal/WebDriverContextClickActionTest.php +++ b/tests/unit/interactions/internal/WebDriverContextClickActionTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Internal\WebDriverContextClickAction; + class WebDriverContextClickActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverContextClickAction @@ -26,7 +28,7 @@ class WebDriverContextClickActionTest extends \PHPUnit_Framework_TestCase { public function setUp() { $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); $this->webDriverContextClickAction = new WebDriverContextClickAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +36,8 @@ public function setUp() { } public function testPerformSendsContextClickCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('contextClick')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverContextClickAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverCoordinatesTest.php b/tests/unit/interactions/internal/WebDriverCoordinatesTest.php index a7fa52549..6002c58bd 100644 --- a/tests/unit/interactions/internal/WebDriverCoordinatesTest.php +++ b/tests/unit/interactions/internal/WebDriverCoordinatesTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates; + class WebDriverCoordinatesTest extends \PHPUnit_Framework_TestCase { public function testConstruct() { $in_view_port = function() { }; diff --git a/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php b/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php index bae50645d..958c2e3cf 100644 --- a/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php +++ b/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Internal\WebDriverDoubleClickAction; + class WebDriverDoubleClickActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverDoubleClickAction @@ -26,7 +28,7 @@ class WebDriverDoubleClickActionTest extends \PHPUnit_Framework_TestCase { public function setUp() { $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); $this->webDriverDoubleClickAction = new WebDriverDoubleClickAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +36,8 @@ public function setUp() { } public function testPerformSendsDoubleClickCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('doubleClick')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverDoubleClickAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php b/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php index af9ce8e0e..2f0ddf593 100644 --- a/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php +++ b/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Internal\WebDriverKeyDownAction; + class WebDriverKeyDownActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverKeyDownAction @@ -28,7 +30,8 @@ class WebDriverKeyDownActionTest extends \PHPUnit_Framework_TestCase { public function setUp() { $this->webDriverKeyboard = $this->getMock('Facebook\WebDriver\WebDriverKeyboard'); $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); + $this->webDriverKeyDownAction = new WebDriverKeyDownAction( $this->webDriverKeyboard, $this->webDriverMouse, @@ -37,7 +40,8 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverKeyboard->expects($this->once())->method('pressKey'); diff --git a/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php b/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php index 98d4cf27d..51c3a9548 100644 --- a/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php +++ b/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Internal\WebDriverKeyUpAction; + class WebDriverKeyUpActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverKeyUpAction @@ -28,7 +30,8 @@ class WebDriverKeyUpActionTest extends \PHPUnit_Framework_TestCase { public function setUp() { $this->webDriverKeyboard = $this->getMock('Facebook\WebDriver\WebDriverKeyboard'); $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); + $this->webDriverKeyUpAction = new WebDriverKeyUpAction( $this->webDriverKeyboard, $this->webDriverMouse, @@ -38,7 +41,8 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverKeyboard->expects($this->once())->method('releaseKey')->with('a'); diff --git a/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php b/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php index bbd306640..1b8f89f78 100644 --- a/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php +++ b/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Internal\WebDriverMouseMoveAction; + class WebDriverMouseMoveActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverMouseMoveAction @@ -26,7 +28,8 @@ class WebDriverMouseMoveActionTest extends \PHPUnit_Framework_TestCase { public function setUp() { $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); + $this->webDriverMouseMoveAction = new WebDriverMouseMoveAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +37,8 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseMove')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverMouseMoveAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php b/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php index 3fbc3b130..cca46496d 100644 --- a/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php +++ b/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Internal\WebDriverMoveToOffsetAction; + class WebDriverMouseToOffsetActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverMoveToOffsetAction @@ -26,7 +28,8 @@ class WebDriverMouseToOffsetActionTest extends \PHPUnit_Framework_TestCase { public function setUp() { $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); + $this->webDriverMoveToOffsetAction = new WebDriverMoveToOffsetAction( $this->webDriverMouse, $this->locationProvider, @@ -36,7 +39,8 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseMove')->with($coords, 150, 200); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverMoveToOffsetAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php b/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php index 77fd71587..e5782b9c3 100644 --- a/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php +++ b/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Internal\WebDriverSendKeysAction; + class WebDriverSendKeysActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverSendKeysAction @@ -29,7 +31,8 @@ class WebDriverSendKeysActionTest extends \PHPUnit_Framework_TestCase { public function setUp() { $this->webDriverKeyboard = $this->getMock('Facebook\WebDriver\WebDriverKeyboard'); $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); + $this->keys = array('t', 'e', 's', 't'); $this->webDriverSendKeysAction = new WebDriverSendKeysAction( $this->webDriverKeyboard, @@ -40,7 +43,8 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); $this->webDriverKeyboard->expects($this->once())->method('sendKeys')->with($this->keys); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); From 35ff1cb1a8533a03eb47c56b35c477a7913d3356 Mon Sep 17 00:00:00 2001 From: 0x20h Date: Tue, 19 May 2015 23:26:21 +0200 Subject: [PATCH 144/784] test setup - moved phpunit to project directory and renamed to standard .dist - removed namespace from bootstrap.php - removed unnecessary bootstrap/phpunit config from tests/unit - moved tests/unit files --- .travis.yml | 15 ++++++++++- README.md | 10 +++----- composer.json | 13 +++++++--- tests/unit/phpunit.xml => phpunit.xml.dist | 10 +++++--- tests/bootstrap.php | 4 --- tests/phpunit.xml | 25 ------------------- .../WebDriverButtonReleaseActionTest.php | 0 .../WebDriverClickActionTest.php | 0 .../WebDriverClickAndHoldActionTest.php | 0 .../WebDriverContextClickActionTest.php | 0 .../WebDriverCoordinatesTest.php | 0 .../WebDriverDoubleClickActionTest.php | 0 .../WebDriverKeyDownActionTest.php | 0 .../WebDriverKeyUpActionTest.php | 0 .../WebDriverMouseMoveActionTest.php | 0 .../WebDriverMouseToOffsetActionTest.php | 0 .../WebDriverSendKeysActionTest.php | 0 tests/unit/bootstrap.php | 5 ---- 18 files changed, 34 insertions(+), 48 deletions(-) rename tests/unit/phpunit.xml => phpunit.xml.dist (69%) delete mode 100644 tests/phpunit.xml rename tests/unit/{interactions/internal => }/WebDriverButtonReleaseActionTest.php (100%) rename tests/unit/{interactions/internal => }/WebDriverClickActionTest.php (100%) rename tests/unit/{interactions/internal => }/WebDriverClickAndHoldActionTest.php (100%) rename tests/unit/{interactions/internal => }/WebDriverContextClickActionTest.php (100%) rename tests/unit/{interactions/internal => }/WebDriverCoordinatesTest.php (100%) rename tests/unit/{interactions/internal => }/WebDriverDoubleClickActionTest.php (100%) rename tests/unit/{interactions/internal => }/WebDriverKeyDownActionTest.php (100%) rename tests/unit/{interactions/internal => }/WebDriverKeyUpActionTest.php (100%) rename tests/unit/{interactions/internal => }/WebDriverMouseMoveActionTest.php (100%) rename tests/unit/{interactions/internal => }/WebDriverMouseToOffsetActionTest.php (100%) rename tests/unit/{interactions/internal => }/WebDriverSendKeysActionTest.php (100%) delete mode 100644 tests/unit/bootstrap.php diff --git a/.travis.yml b/.travis.yml index 1342b9d4b..8b74804b4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,21 @@ language: php + php: - 5.3 - 5.4 - 5.5 - hhvm -script: phpunit -c ./tests/unit +before_script: + - composer self-update + - composer install --no-interaction --prefer-source + - export DISPLAY=:99.0 + - sh -e /etc/init.d/xvfb start + - wget -q -t 3 http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar + - java -jar selenium-server-standalone-2.45.0.jar -log selenium.log & + - sleep 3 + +script: ./vendor/bin/phpunit + +after_script: + - cat selenium.log diff --git a/README.md b/README.md index 657d6ad73..d5272c4f4 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ php-webdriver -- WebDriver bindings for PHP =========================================== -Attention! This is a fork of facebook/webdriver and has been altered to include namespacing to avoid naming collisions. - ## DESCRIPTION This WebDriver client aims to be as close as possible to bindings in other languages. The concepts are very similar to the Java, .NET, Python and Ruby bindings for WebDriver. @@ -19,11 +17,11 @@ Any complaint, question, idea? You can post it on the user group https://www.fac git clone git@github.com:facebook/php-webdriver.git ### Packagist -Add the dependency. https://packagist.org/packages/janoszen/webdriver +Add the dependency. https://packagist.org/packages/facebook/webdriver { "require": { - "janoszen/webdriver": "dev-master" + "facebook/webdriver": "dev-master" } } @@ -100,8 +98,8 @@ If you're reading this you've already found our Github repository. If you have a We love to have your help to make php-webdriver better. Feel free to -* open an [issue](https://github.com/janoszen/php-webdriver/issues) if you run into any problem. -* fork the project and submit [pull request](https://github.com/janoszen/php-webdriver/pulls). Before the pull requests can be accepted, a [Contributors Licensing Agreement](http://developers.facebook.com/opensource/cla) must be signed. +* open an [issue](https://github.com/facebook/php-webdriver/issues) if you run into any problem. +* fork the project and submit [pull request](https://github.com/facebook/php-webdriver/pulls). Before the pull requests can be accepted, a [Contributors Licensing Agreement](http://developers.facebook.com/opensource/cla) must be signed. When you are going to contribute, please keep in mind that this webdriver client aims to be as close as possible to other languages Java/Ruby/Python/C#. FYI, here is the overview of [the official Java API](http://selenium.googlecode.com/svn/trunk/docs/api/java/index.html?overview-summary.html) diff --git a/composer.json b/composer.json index 7b57541f4..53e36c14d 100644 --- a/composer.json +++ b/composer.json @@ -1,19 +1,22 @@ { "name": "facebook/webdriver", "description": "A php client for WebDriver", - "keywords": ["webdriver", "selenium", "php"], + "keywords": ["webdriver", "selenium", "php", "facebook"], "homepage": "https://github.com/facebook/php-webdriver", "type": "library", "license": "Apache-2.0", "support": { "issues": "https://github.com/facebook/php-webdriver/issues", + "forum": "https://www.facebook.com/groups/phpwebdriver/", "source": "https://github.com/facebook/php-webdriver" }, "require": { "php": ">=5.3.19" }, "require-dev": { - "phpunit/phpunit": "3.7.*", + "phpunit/phpunit": "3.7.*" + }, + "suggest": { "phpdocumentor/phpdocumentor": "2.*" }, "autoload": { @@ -21,5 +24,9 @@ "Facebook\\WebDriver\\": "lib/" } }, - "minimum-stability": "dev" + "autoload-dev": { + "psr-4": { + "Facebook\\WebDriver\\": "tests/functional" + } + } } diff --git a/tests/unit/phpunit.xml b/phpunit.xml.dist similarity index 69% rename from tests/unit/phpunit.xml rename to phpunit.xml.dist index 0338c9327..4dfdec0a7 100644 --- a/tests/unit/phpunit.xml +++ b/phpunit.xml.dist @@ -11,12 +11,14 @@ processIsolation = "false" stopOnFailure = "false" syntaxCheck = "false" - bootstrap = "bootstrap.php" > + bootstrap = "tests/bootstrap.php" > - - ../unit + + tests/unit + + + tests/functional/ - diff --git a/tests/bootstrap.php b/tests/bootstrap.php index c12f2a118..f9e62ac66 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,6 +1,2 @@ - - - - - - - ./unit - - - ./functional - - - - diff --git a/tests/unit/interactions/internal/WebDriverButtonReleaseActionTest.php b/tests/unit/WebDriverButtonReleaseActionTest.php similarity index 100% rename from tests/unit/interactions/internal/WebDriverButtonReleaseActionTest.php rename to tests/unit/WebDriverButtonReleaseActionTest.php diff --git a/tests/unit/interactions/internal/WebDriverClickActionTest.php b/tests/unit/WebDriverClickActionTest.php similarity index 100% rename from tests/unit/interactions/internal/WebDriverClickActionTest.php rename to tests/unit/WebDriverClickActionTest.php diff --git a/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php b/tests/unit/WebDriverClickAndHoldActionTest.php similarity index 100% rename from tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php rename to tests/unit/WebDriverClickAndHoldActionTest.php diff --git a/tests/unit/interactions/internal/WebDriverContextClickActionTest.php b/tests/unit/WebDriverContextClickActionTest.php similarity index 100% rename from tests/unit/interactions/internal/WebDriverContextClickActionTest.php rename to tests/unit/WebDriverContextClickActionTest.php diff --git a/tests/unit/interactions/internal/WebDriverCoordinatesTest.php b/tests/unit/WebDriverCoordinatesTest.php similarity index 100% rename from tests/unit/interactions/internal/WebDriverCoordinatesTest.php rename to tests/unit/WebDriverCoordinatesTest.php diff --git a/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php b/tests/unit/WebDriverDoubleClickActionTest.php similarity index 100% rename from tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php rename to tests/unit/WebDriverDoubleClickActionTest.php diff --git a/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php b/tests/unit/WebDriverKeyDownActionTest.php similarity index 100% rename from tests/unit/interactions/internal/WebDriverKeyDownActionTest.php rename to tests/unit/WebDriverKeyDownActionTest.php diff --git a/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php b/tests/unit/WebDriverKeyUpActionTest.php similarity index 100% rename from tests/unit/interactions/internal/WebDriverKeyUpActionTest.php rename to tests/unit/WebDriverKeyUpActionTest.php diff --git a/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php b/tests/unit/WebDriverMouseMoveActionTest.php similarity index 100% rename from tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php rename to tests/unit/WebDriverMouseMoveActionTest.php diff --git a/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php b/tests/unit/WebDriverMouseToOffsetActionTest.php similarity index 100% rename from tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php rename to tests/unit/WebDriverMouseToOffsetActionTest.php diff --git a/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php b/tests/unit/WebDriverSendKeysActionTest.php similarity index 100% rename from tests/unit/interactions/internal/WebDriverSendKeysActionTest.php rename to tests/unit/WebDriverSendKeysActionTest.php diff --git a/tests/unit/bootstrap.php b/tests/unit/bootstrap.php deleted file mode 100644 index db3b0d958..000000000 --- a/tests/unit/bootstrap.php +++ /dev/null @@ -1,5 +0,0 @@ - Date: Wed, 20 May 2015 00:22:27 +0200 Subject: [PATCH 145/784] Changed code formating for composer.json --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 53e36c14d..486f17678 100644 --- a/composer.json +++ b/composer.json @@ -21,8 +21,8 @@ }, "autoload": { "psr-4": { - "Facebook\\WebDriver\\": "lib/" - } + "Facebook\\WebDriver\\": "lib/" + } }, "autoload-dev": { "psr-4": { From 56a0666b92a651bed2c31e11a83543aaec2bd622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 20 May 2015 02:02:10 +0200 Subject: [PATCH 146/784] Upgrade PHPUnit to latest 4.6 --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 486f17678..8d4095415 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "facebook/webdriver", - "description": "A php client for WebDriver", + "description": "A PHP client for WebDriver", "keywords": ["webdriver", "selenium", "php", "facebook"], "homepage": "https://github.com/facebook/php-webdriver", "type": "library", @@ -14,7 +14,7 @@ "php": ">=5.3.19" }, "require-dev": { - "phpunit/phpunit": "3.7.*" + "phpunit/phpunit": "4.6.*" }, "suggest": { "phpdocumentor/phpdocumentor": "2.*" From 586a35d5afcbe38e7940e26276da361c4a09a5cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 20 May 2015 02:02:46 +0200 Subject: [PATCH 147/784] Run tests on PHP 5.6 and PHP 7 --- .travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8b74804b4..a54d35732 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,11 +4,15 @@ php: - 5.3 - 5.4 - 5.5 + - 5.6 + - 7 - hhvm -before_script: +install: - composer self-update - composer install --no-interaction --prefer-source + +before_script: - export DISPLAY=:99.0 - sh -e /etc/init.d/xvfb start - wget -q -t 3 http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar From c9332a4320a32c3b99040f52a8a24f3a9d28b10e Mon Sep 17 00:00:00 2001 From: 0x20h Date: Fri, 22 May 2015 21:59:45 +0200 Subject: [PATCH 148/784] Fix flaky build. Just wait until we can connect to the server, then start the tests. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a54d35732..e973cacd3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ before_script: - sh -e /etc/init.d/xvfb start - wget -q -t 3 http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar - java -jar selenium-server-standalone-2.45.0.jar -log selenium.log & - - sleep 3 + - until $(echo | nc localhost 4444); do sleep 1; echo waiting for selenium-server...; done; script: ./vendor/bin/phpunit From 6cc1d7a54b89767aee50daae408e3afda103cb03 Mon Sep 17 00:00:00 2001 From: Jeroen Versteeg Date: Wed, 27 May 2015 15:51:49 +0200 Subject: [PATCH 149/784] Made RemoteWebElement extendable by having newElement use subclass constructor An alternative would have been to make the method protected (it is now private). This change enables users to extend the RemoteWebElement API by subclassing it. --- lib/remote/RemoteWebElement.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/remote/RemoteWebElement.php b/lib/remote/RemoteWebElement.php index ea4d1b992..59cc7e4c3 100644 --- a/lib/remote/RemoteWebElement.php +++ b/lib/remote/RemoteWebElement.php @@ -405,6 +405,7 @@ public function equals(WebDriverElement $other) { * @return RemoteWebElement */ private function newElement($id) { - return new RemoteWebElement($this->executor, $id); + $class = get_class($this); + return new $class($this->executor, $id); } } From fb1ea62d34596fc2f4675511cd30e603de2ec034 Mon Sep 17 00:00:00 2001 From: Janos Pasztor Date: Tue, 14 Oct 2014 22:24:35 +0200 Subject: [PATCH 150/784] Moved the webdriver to a namespace (see issue #169 on the original repo) --- example.php | 2 ++ lib/JavaScriptExecutor.php | 2 ++ lib/WebDriver.php | 2 ++ lib/WebDriverAction.php | 2 ++ lib/WebDriverAlert.php | 2 ++ lib/WebDriverBy.php | 2 ++ lib/WebDriverCapabilities.php | 2 ++ lib/WebDriverCommandExecutor.php | 2 ++ lib/WebDriverDimension.php | 2 ++ lib/WebDriverDispatcher.php | 2 ++ lib/WebDriverElement.php | 2 ++ lib/WebDriverEventListener.php | 2 ++ lib/WebDriverExceptions.php | 4 ++++ lib/WebDriverExpectedCondition.php | 2 ++ lib/WebDriverHasInputDevices.php | 2 ++ lib/WebDriverKeyboard.php | 2 ++ lib/WebDriverKeys.php | 2 ++ lib/WebDriverMouse.php | 2 ++ lib/WebDriverNavigation.php | 2 ++ lib/WebDriverOptions.php | 2 ++ lib/WebDriverPlatform.php | 2 ++ lib/WebDriverPoint.php | 2 ++ lib/WebDriverSearchContext.php | 2 ++ lib/WebDriverSelect.php | 2 ++ lib/WebDriverTargetLocator.php | 2 ++ lib/WebDriverTimeouts.php | 2 ++ lib/WebDriverWait.php | 2 ++ lib/WebDriverWindow.php | 2 ++ lib/chrome/ChromeDriver.php | 2 ++ lib/chrome/ChromeDriverService.php | 2 ++ lib/chrome/ChromeOptions.php | 2 ++ lib/firefox/FirefoxDriver.php | 2 ++ lib/firefox/FirefoxProfile.php | 4 ++++ lib/interactions/WebDriverActions.php | 2 ++ lib/interactions/WebDriverCompositeAction.php | 2 ++ lib/interactions/WebDriverTouchActions.php | 2 ++ lib/interactions/WebDriverTouchScreen.php | 2 ++ .../internal/WebDriverButtonReleaseAction.php | 2 ++ lib/interactions/internal/WebDriverClickAction.php | 2 ++ .../internal/WebDriverClickAndHoldAction.php | 2 ++ .../internal/WebDriverContextClickAction.php | 2 ++ lib/interactions/internal/WebDriverCoordinates.php | 4 ++++ .../internal/WebDriverDoubleClickAction.php | 2 ++ lib/interactions/internal/WebDriverKeyDownAction.php | 2 ++ lib/interactions/internal/WebDriverKeyUpAction.php | 2 ++ .../internal/WebDriverKeysRelatedAction.php | 2 ++ lib/interactions/internal/WebDriverMouseAction.php | 2 ++ .../internal/WebDriverMouseMoveAction.php | 2 ++ .../internal/WebDriverMoveToOffsetAction.php | 2 ++ .../internal/WebDriverSendKeysAction.php | 2 ++ .../internal/WebDriverSingleKeyAction.php | 2 ++ lib/interactions/touch/WebDriverDoubleTapAction.php | 2 ++ lib/interactions/touch/WebDriverDownAction.php | 2 ++ lib/interactions/touch/WebDriverFlickAction.php | 2 ++ .../touch/WebDriverFlickFromElementAction.php | 2 ++ lib/interactions/touch/WebDriverLongPressAction.php | 2 ++ lib/interactions/touch/WebDriverMoveAction.php | 2 ++ lib/interactions/touch/WebDriverScrollAction.php | 2 ++ .../touch/WebDriverScrollFromElementAction.php | 2 ++ lib/interactions/touch/WebDriverTapAction.php | 2 ++ lib/interactions/touch/WebDriverTouchAction.php | 2 ++ lib/interactions/touch/WebDriverUpAction.php | 2 ++ lib/internal/WebDriverLocatable.php | 2 ++ lib/net/URLChecker.php | 2 ++ lib/remote/DesiredCapabilities.php | 2 ++ lib/remote/DriverCommand.php | 2 ++ lib/remote/ExecuteMethod.php | 2 ++ lib/remote/FileDetector.php | 2 ++ lib/remote/HttpCommandExecutor.php | 2 ++ lib/remote/LocalFileDetector.php | 2 ++ lib/remote/RemoteExecuteMethod.php | 2 ++ lib/remote/RemoteKeyboard.php | 2 ++ lib/remote/RemoteMouse.php | 2 ++ lib/remote/RemoteTouchScreen.php | 2 ++ lib/remote/RemoteWebDriver.php | 2 ++ lib/remote/RemoteWebElement.php | 4 ++++ lib/remote/UselessFileDetector.php | 2 ++ lib/remote/WebDriverBrowserType.php | 2 ++ lib/remote/WebDriverCapabilityType.php | 2 ++ lib/remote/WebDriverCommand.php | 2 ++ lib/remote/WebDriverResponse.php | 2 ++ lib/remote/service/DriverCommandExecutor.php | 2 ++ lib/remote/service/DriverService.php | 2 ++ lib/support/events/EventFiringWebDriver.php | 2 ++ .../events/EventFiringWebDriverNavigation.php | 2 ++ lib/support/events/EventFiringWebElement.php | 2 ++ tests/bootstrap.php | 2 ++ tests/functional/BaseTest.php | 4 +++- tests/functional/FileUploadTest.php | 2 ++ tests/functional/WebDriverTestCase.php | 4 +++- tests/unit/bootstrap.php | 2 ++ .../internal/WebDriverButtonReleaseActionTest.php | 10 ++++++---- .../internal/WebDriverClickActionTest.php | 10 ++++++---- .../internal/WebDriverClickAndHoldActionTest.php | 10 ++++++---- .../internal/WebDriverContextClickActionTest.php | 10 ++++++---- .../internal/WebDriverCoordinatesTest.php | 4 +++- .../internal/WebDriverDoubleClickActionTest.php | 10 ++++++---- .../internal/WebDriverKeyDownActionTest.php | 12 +++++++----- .../internal/WebDriverKeyUpActionTest.php | 12 +++++++----- .../internal/WebDriverMouseMoveActionTest.php | 10 ++++++---- .../internal/WebDriverMouseToOffsetActionTest.php | 10 ++++++---- .../internal/WebDriverSendKeysActionTest.php | 12 +++++++----- 102 files changed, 258 insertions(+), 46 deletions(-) diff --git a/example.php b/example.php index a1e133b91..8cfac7461 100644 --- a/example.php +++ b/example.php @@ -1,6 +1,8 @@ driver->findElement(WebDriverBy::tagName('input'))->getAttribute('value') ); } -} \ No newline at end of file +} diff --git a/tests/functional/FileUploadTest.php b/tests/functional/FileUploadTest.php index 84ec454e8..7f09aa8f0 100644 --- a/tests/functional/FileUploadTest.php +++ b/tests/functional/FileUploadTest.php @@ -13,6 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +namespace Selenium\WebDriver; + /** * An example test case for php-webdriver. * diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index 4a5b77f6c..db4248964 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -13,10 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +namespace Selenium\WebDriver; + /** * The base class for test cases. */ -class WebDriverTestCase extends PHPUnit_Framework_TestCase { +class WebDriverTestCase extends \PHPUnit_Framework_TestCase { /** @var RemoteWebDriver $driver */ protected $driver; diff --git a/tests/unit/bootstrap.php b/tests/unit/bootstrap.php index 562467964..80da4bb38 100644 --- a/tests/unit/bootstrap.php +++ b/tests/unit/bootstrap.php @@ -1,3 +1,5 @@ webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); $this->webDriverButtonReleaseAction = new WebDriverButtonReleaseAction( $this->webDriverMouse, $this->locationProvider @@ -32,7 +34,7 @@ public function setUp() { } public function testPerformSendsMouseUpCommand() { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseUp')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverButtonReleaseAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverClickActionTest.php b/tests/unit/interactions/internal/WebDriverClickActionTest.php index 98fd39197..ca60ae668 100644 --- a/tests/unit/interactions/internal/WebDriverClickActionTest.php +++ b/tests/unit/interactions/internal/WebDriverClickActionTest.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -class WebDriverClickActionTest extends PHPUnit_Framework_TestCase { +namespace Selenium\WebDriver; + +class WebDriverClickActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverClickAction */ @@ -23,8 +25,8 @@ class WebDriverClickActionTest extends PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); $this->webDriverClickAction = new WebDriverClickAction( $this->webDriverMouse, $this->locationProvider @@ -32,7 +34,7 @@ public function setUp() { } public function testPerformSendsClickCommand() { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverClickAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php b/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php index fe1826ee0..78781fae6 100644 --- a/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php +++ b/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -class WebDriverClickAndHoldActionTest extends PHPUnit_Framework_TestCase { +namespace Selenium\WebDriver; + +class WebDriverClickAndHoldActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverClickAndHoldAction */ @@ -23,8 +25,8 @@ class WebDriverClickAndHoldActionTest extends PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); $this->webDriverClickAndHoldAction = new WebDriverClickAndHoldAction( $this->webDriverMouse, $this->locationProvider @@ -32,7 +34,7 @@ public function setUp() { } public function testPerformSendsMouseDownCommand() { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseDown')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverClickAndHoldAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverContextClickActionTest.php b/tests/unit/interactions/internal/WebDriverContextClickActionTest.php index 7ac3162cc..ece8f3488 100644 --- a/tests/unit/interactions/internal/WebDriverContextClickActionTest.php +++ b/tests/unit/interactions/internal/WebDriverContextClickActionTest.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -class WebDriverContextClickActionTest extends PHPUnit_Framework_TestCase { +namespace Selenium\WebDriver; + +class WebDriverContextClickActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverContextClickAction */ @@ -23,8 +25,8 @@ class WebDriverContextClickActionTest extends PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); $this->webDriverContextClickAction = new WebDriverContextClickAction( $this->webDriverMouse, $this->locationProvider @@ -32,7 +34,7 @@ public function setUp() { } public function testPerformSendsContextClickCommand() { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('contextClick')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverContextClickAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverCoordinatesTest.php b/tests/unit/interactions/internal/WebDriverCoordinatesTest.php index cf4cc0d12..f339e5044 100644 --- a/tests/unit/interactions/internal/WebDriverCoordinatesTest.php +++ b/tests/unit/interactions/internal/WebDriverCoordinatesTest.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -class WebDriverCoordinatesTest extends PHPUnit_Framework_TestCase { +namespace Selenium\WebDriver; + +class WebDriverCoordinatesTest extends \PHPUnit_Framework_TestCase { public function testConstruct() { $in_view_port = function() { }; $on_page = function() { }; diff --git a/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php b/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php index a0c85ac0d..ae45d169b 100644 --- a/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php +++ b/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -class WebDriverDoubleClickActionTest extends PHPUnit_Framework_TestCase { +namespace Selenium\WebDriver; + +class WebDriverDoubleClickActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverDoubleClickAction */ @@ -23,8 +25,8 @@ class WebDriverDoubleClickActionTest extends PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); $this->webDriverDoubleClickAction = new WebDriverDoubleClickAction( $this->webDriverMouse, $this->locationProvider @@ -32,7 +34,7 @@ public function setUp() { } public function testPerformSendsDoubleClickCommand() { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('doubleClick')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverDoubleClickAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php b/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php index f82b25cb1..0cc5cb5cd 100644 --- a/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php +++ b/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -class WebDriverKeyDownActionTest extends PHPUnit_Framework_TestCase { +namespace Selenium\WebDriver; + +class WebDriverKeyDownActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverKeyDownAction */ @@ -24,9 +26,9 @@ class WebDriverKeyDownActionTest extends PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverKeyboard = $this->getMock('WebDriverKeyboard'); - $this->webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverKeyboard = $this->getMock('Selenium\WebDriver\WebDriverKeyboard'); + $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); $this->webDriverKeyDownAction = new WebDriverKeyDownAction( $this->webDriverKeyboard, $this->webDriverMouse, @@ -35,7 +37,7 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverKeyboard->expects($this->once())->method('pressKey'); diff --git a/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php b/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php index e35277bd7..daf7bfc06 100644 --- a/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php +++ b/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -class WebDriverKeyUpActionTest extends PHPUnit_Framework_TestCase { +namespace Selenium\WebDriver; + +class WebDriverKeyUpActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverKeyUpAction */ @@ -24,9 +26,9 @@ class WebDriverKeyUpActionTest extends PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverKeyboard = $this->getMock('WebDriverKeyboard'); - $this->webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverKeyboard = $this->getMock('Selenium\WebDriver\WebDriverKeyboard'); + $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); $this->webDriverKeyUpAction = new WebDriverKeyUpAction( $this->webDriverKeyboard, $this->webDriverMouse, @@ -36,7 +38,7 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverKeyboard->expects($this->once())->method('releaseKey')->with('a'); diff --git a/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php b/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php index aec3444d3..2c6ee400e 100644 --- a/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php +++ b/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -class WebDriverMouseMoveActionTest extends PHPUnit_Framework_TestCase { +namespace Selenium\WebDriver; + +class WebDriverMouseMoveActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverMouseMoveAction */ @@ -23,8 +25,8 @@ class WebDriverMouseMoveActionTest extends PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); $this->webDriverMouseMoveAction = new WebDriverMouseMoveAction( $this->webDriverMouse, $this->locationProvider @@ -32,7 +34,7 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseMove')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverMouseMoveAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php b/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php index 2cd2bc75d..c6066d051 100644 --- a/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php +++ b/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -class WebDriverMouseToOffsetActionTest extends PHPUnit_Framework_TestCase { +namespace Selenium\WebDriver; + +class WebDriverMouseToOffsetActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverMoveToOffsetAction */ @@ -23,8 +25,8 @@ class WebDriverMouseToOffsetActionTest extends PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); $this->webDriverMoveToOffsetAction = new WebDriverMoveToOffsetAction( $this->webDriverMouse, $this->locationProvider, @@ -34,7 +36,7 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseMove')->with($coords, 150, 200); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverMoveToOffsetAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php b/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php index 9f9cad84b..6a51f8934 100644 --- a/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php +++ b/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -class WebDriverSendKeysActionTest extends PHPUnit_Framework_TestCase { +namespace Selenium\WebDriver; + +class WebDriverSendKeysActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverSendKeysAction */ @@ -25,9 +27,9 @@ class WebDriverSendKeysActionTest extends PHPUnit_Framework_TestCase { private $keys; public function setUp() { - $this->webDriverKeyboard = $this->getMock('WebDriverKeyboard'); - $this->webDriverMouse = $this->getMock('WebDriverMouse'); - $this->locationProvider = $this->getMock('WebDriverLocatable'); + $this->webDriverKeyboard = $this->getMock('Selenium\WebDriver\WebDriverKeyboard'); + $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); $this->keys = array('t', 'e', 's', 't'); $this->webDriverSendKeysAction = new WebDriverSendKeysAction( $this->webDriverKeyboard, @@ -38,7 +40,7 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverKeyboard->expects($this->once())->method('sendKeys')->with($this->keys); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); From ea0c8dfaec0363624a314b5a46b9d69ab26c29f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1nos=20P=C3=A1sztor?= Date: Fri, 31 Oct 2014 11:28:10 +0100 Subject: [PATCH 151/784] Update composer.json Updated composer.json for packagist publishing --- composer.json | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 00faaa7bf..24f37c8fd 100644 --- a/composer.json +++ b/composer.json @@ -1,14 +1,13 @@ { - "name": "facebook/webdriver", - "description": "A php client for WebDriver", - "keywords": ["webdriver", "selenium", "php", "facebook"], - "homepage": "https://github.com/facebook/php-webdriver", + "name": "janoszen/webdriver", + "description": "A php client for WebDriver (fork of facebook/webdriver)", + "keywords": ["webdriver", "selenium", "php"], + "homepage": "https://github.com/janoszen/php-webdriver", "type": "library", "license": "Apache-2.0", "support": { - "issues": "https://github.com/facebook/php-webdriver/issues", - "forum": "https://www.facebook.com/groups/phpwebdriver/", - "source": "https://github.com/facebook/php-webdriver" + "issues": "https://github.com/janoszen/php-webdriver/issues", + "source": "https://github.com/janoszen/php-webdriver" }, "require": { "php": ">=5.3.19" From 6bcd3c529e981518103da553d908f6ece4c14fed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1nos=20P=C3=A1sztor?= Date: Fri, 31 Oct 2014 11:29:26 +0100 Subject: [PATCH 152/784] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d5272c4f4..85047203d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ php-webdriver -- WebDriver bindings for PHP =========================================== +Attention! This is a fork of facebook/webdriver and has been altered to include namespacing to avoid naming collisions. + ## DESCRIPTION This WebDriver client aims to be as close as possible to bindings in other languages. The concepts are very similar to the Java, .NET, Python and Ruby bindings for WebDriver. From c28f0d3ccd7dbb6518f2499872fd47ecb79b02f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1nos=20P=C3=A1sztor?= Date: Fri, 31 Oct 2014 11:30:48 +0100 Subject: [PATCH 153/784] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 85047203d..657d6ad73 100644 --- a/README.md +++ b/README.md @@ -19,11 +19,11 @@ Any complaint, question, idea? You can post it on the user group https://www.fac git clone git@github.com:facebook/php-webdriver.git ### Packagist -Add the dependency. https://packagist.org/packages/facebook/webdriver +Add the dependency. https://packagist.org/packages/janoszen/webdriver { "require": { - "facebook/webdriver": "dev-master" + "janoszen/webdriver": "dev-master" } } @@ -100,8 +100,8 @@ If you're reading this you've already found our Github repository. If you have a We love to have your help to make php-webdriver better. Feel free to -* open an [issue](https://github.com/facebook/php-webdriver/issues) if you run into any problem. -* fork the project and submit [pull request](https://github.com/facebook/php-webdriver/pulls). Before the pull requests can be accepted, a [Contributors Licensing Agreement](http://developers.facebook.com/opensource/cla) must be signed. +* open an [issue](https://github.com/janoszen/php-webdriver/issues) if you run into any problem. +* fork the project and submit [pull request](https://github.com/janoszen/php-webdriver/pulls). Before the pull requests can be accepted, a [Contributors Licensing Agreement](http://developers.facebook.com/opensource/cla) must be signed. When you are going to contribute, please keep in mind that this webdriver client aims to be as close as possible to other languages Java/Ruby/Python/C#. FYI, here is the overview of [the official Java API](http://selenium.googlecode.com/svn/trunk/docs/api/java/index.html?overview-summary.html) From 213167e5f124a6103789a7736c71aff0191f386a Mon Sep 17 00:00:00 2001 From: Janos Pasztor Date: Wed, 22 Apr 2015 17:04:59 +0200 Subject: [PATCH 154/784] Updated webdriver from Facebook --- composer.json | 3 ++- lib/remote/RemoteTargetLocator.php | 2 ++ lib/remote/RemoteWebDriver.php | 2 +- tests/functional/WebDriverTestCase.php | 4 +++- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 24f37c8fd..4b5622180 100644 --- a/composer.json +++ b/composer.json @@ -18,5 +18,6 @@ }, "autoload": { "classmap": ["lib/"] - } + }, + "minimum-stability": "dev" } diff --git a/lib/remote/RemoteTargetLocator.php b/lib/remote/RemoteTargetLocator.php index 949836675..841c4acf1 100644 --- a/lib/remote/RemoteTargetLocator.php +++ b/lib/remote/RemoteTargetLocator.php @@ -13,6 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +namespace Selenium\WebDriver; + /** * Used to locate a given frame or window for RemoteWebDriver. */ diff --git a/lib/remote/RemoteWebDriver.php b/lib/remote/RemoteWebDriver.php index aafbb4b2f..246a7adfa 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/remote/RemoteWebDriver.php @@ -47,7 +47,7 @@ protected function __construct() {} * Construct the RemoteWebDriver by a desired capabilities. * * @param string $url The url of the remote server - * @param DesiredCapabilities $desired_capabilities The desired capabilities + * @param DesiredCapabilities|array $desired_capabilities The desired capabilities * @param int|null $connection_timeout_in_ms * @param int|null $request_timeout_in_ms * @return RemoteWebDriver diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index db4248964..e4ef9db7c 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -35,7 +35,9 @@ protected function setUp() { } protected function tearDown() { - $this->driver->quit(); + if ($this->driver) { + $this->driver->quit(); + } } /** From 311fdcf87fd5ad17241cc6b87d9bc344bf65fad3 Mon Sep 17 00:00:00 2001 From: Janos Pasztor Date: Wed, 22 Apr 2015 17:08:46 +0200 Subject: [PATCH 155/784] Updated package name --- composer.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 4b5622180..41b0fce1e 100644 --- a/composer.json +++ b/composer.json @@ -1,13 +1,13 @@ { - "name": "janoszen/webdriver", + "name": "opsbears/webdriver", "description": "A php client for WebDriver (fork of facebook/webdriver)", "keywords": ["webdriver", "selenium", "php"], - "homepage": "https://github.com/janoszen/php-webdriver", + "homepage": "https://github.com/opsbears/php-webdriver", "type": "library", "license": "Apache-2.0", "support": { - "issues": "https://github.com/janoszen/php-webdriver/issues", - "source": "https://github.com/janoszen/php-webdriver" + "issues": "https://github.com/opsbears/php-webdriver/issues", + "source": "https://github.com/opsbears/php-webdriver" }, "require": { "php": ">=5.3.19" From ac6d82f1a3272398650701bd1c9d5a28bfc7f7b5 Mon Sep 17 00:00:00 2001 From: Janos Pasztor Date: Mon, 18 May 2015 14:44:29 +0200 Subject: [PATCH 156/784] Issue facebook/php-webdriver#212 - Moving forward Implemented namespacing as discussed (needs testing) --- composer.json | 14 ++- example.php | 4 +- lib/{chrome => }/ChromeDriver.php | 4 +- lib/{chrome => }/ChromeDriverService.php | 2 +- lib/{chrome => }/ChromeOptions.php | 2 +- lib/{remote => }/DesiredCapabilities.php | 4 +- lib/{remote => }/DriverCommand.php | 2 +- .../service => }/DriverCommandExecutor.php | 5 +- lib/{remote/service => }/DriverService.php | 4 +- .../events => }/EventFiringWebDriver.php | 5 +- .../EventFiringWebDriverNavigation.php | 4 +- .../events => }/EventFiringWebElement.php | 4 +- .../ElementNotSelectableException.php | 21 ++++ lib/Exception/ElementNotVisibleException.php | 20 +++ lib/Exception/ExpectedException.php | 21 ++++ .../IMEEngineActivationFailedException.php | 21 ++++ lib/Exception/IMENotAvailableException.php | 21 ++++ lib/Exception/IndexOutOfBoundsException.php | 7 ++ .../InvalidCookieDomainException.php | 20 +++ lib/Exception/InvalidCoordinatesException.php | 21 ++++ .../InvalidElementStateException.php | 20 +++ lib/Exception/InvalidSelectorException.php | 21 ++++ .../MoveTargetOutOfBoundsException.php | 21 ++++ lib/Exception/NoAlertOpenException.php | 20 +++ lib/Exception/NoCollectionException.php | 7 ++ lib/Exception/NoScriptResultException.php | 20 +++ lib/Exception/NoStringException.php | 7 ++ lib/Exception/NoStringLengthException.php | 20 +++ lib/Exception/NoStringWrapperException.php | 20 +++ lib/Exception/NoSuchCollectionException.php | 20 +++ lib/Exception/NoSuchDocumentException.php | 21 ++++ lib/Exception/NoSuchDriverException.php | 20 +++ lib/Exception/NoSuchElementException.php | 20 +++ lib/Exception/NoSuchFrameException.php | 20 +++ lib/Exception/NoSuchWindowException.php | 20 +++ lib/Exception/NullPointerException.php | 21 ++++ lib/Exception/ScriptTimeoutException.php | 21 ++++ lib/Exception/SessionNotCreatedException.php | 21 ++++ .../StaleElementReferenceException.php | 20 +++ lib/Exception/TimeOutException.php | 20 +++ lib/Exception/UnableToSetCookieException.php | 20 +++ .../UnexpectedAlertOpenException.php | 20 +++ .../UnexpectedJavascriptException.php | 20 +++ lib/Exception/UnexpectedTagNameException.php | 34 +++++ lib/Exception/UnknownCommandException.php | 20 +++ lib/Exception/UnknownServerException.php | 20 +++ .../UnrecognizedExceptionException.php | 21 ++++ .../UnsupportedOperationException.php | 21 ++++ lib/Exception/WebDriverCurlException.php | 21 ++++ .../WebDriverException.php} | 64 +--------- lib/Exception/XPathLookupException.php | 20 +++ lib/{remote => }/ExecuteMethod.php | 2 +- lib/{remote => }/FileDetector.php | 2 +- lib/{firefox => }/FirefoxDriver.php | 2 +- lib/{firefox => }/FirefoxProfile.php | 7 +- lib/{remote => }/HttpCommandExecutor.php | 5 +- lib/JavaScriptExecutor.php | 2 +- lib/{remote => }/LocalFileDetector.php | 2 +- lib/{remote => }/RemoteExecuteMethod.php | 2 +- lib/{remote => }/RemoteKeyboard.php | 2 +- lib/{remote => }/RemoteMouse.php | 2 +- lib/{remote => }/RemoteTargetLocator.php | 2 +- lib/{remote => }/RemoteTouchScreen.php | 2 +- lib/{remote => }/RemoteWebDriver.php | 2 +- lib/{remote => }/RemoteWebElement.php | 3 +- lib/{net => }/URLChecker.php | 5 +- lib/{remote => }/UselessFileDetector.php | 2 +- lib/WebDriver.php | 2 +- lib/WebDriverAction.php | 2 +- lib/{interactions => }/WebDriverActions.php | 2 +- lib/WebDriverAlert.php | 2 +- lib/{remote => }/WebDriverBrowserType.php | 2 +- .../WebDriverButtonReleaseAction.php | 2 +- lib/WebDriverBy.php | 2 +- lib/WebDriverCapabilities.php | 2 +- lib/{remote => }/WebDriverCapabilityType.php | 2 +- .../internal => }/WebDriverClickAction.php | 2 +- .../WebDriverClickAndHoldAction.php | 2 +- lib/{remote => }/WebDriverCommand.php | 2 +- lib/WebDriverCommandExecutor.php | 2 +- .../WebDriverCompositeAction.php | 2 +- .../WebDriverContextClickAction.php | 2 +- .../internal => }/WebDriverCoordinates.php | 3 +- lib/WebDriverDimension.php | 2 +- lib/WebDriverDispatcher.php | 2 +- .../WebDriverDoubleClickAction.php | 2 +- .../touch => }/WebDriverDoubleTapAction.php | 2 +- .../touch => }/WebDriverDownAction.php | 2 +- lib/WebDriverElement.php | 2 +- lib/WebDriverEventListener.php | 4 +- lib/WebDriverExpectedCondition.php | 6 +- .../touch => }/WebDriverFlickAction.php | 2 +- .../WebDriverFlickFromElementAction.php | 2 +- lib/WebDriverHasInputDevices.php | 2 +- .../internal => }/WebDriverKeyDownAction.php | 2 +- .../internal => }/WebDriverKeyUpAction.php | 2 +- lib/WebDriverKeyboard.php | 2 +- lib/WebDriverKeys.php | 2 +- .../WebDriverKeysRelatedAction.php | 2 +- lib/{internal => }/WebDriverLocatable.php | 2 +- .../touch => }/WebDriverLongPressAction.php | 2 +- lib/WebDriverMouse.php | 2 +- .../internal => }/WebDriverMouseAction.php | 2 +- .../WebDriverMouseMoveAction.php | 2 +- .../touch => }/WebDriverMoveAction.php | 2 +- .../WebDriverMoveToOffsetAction.php | 2 +- lib/WebDriverNavigation.php | 2 +- lib/WebDriverOptions.php | 3 +- lib/WebDriverPlatform.php | 2 +- lib/WebDriverPoint.php | 2 +- lib/{remote => }/WebDriverResponse.php | 2 +- .../touch => }/WebDriverScrollAction.php | 2 +- .../WebDriverScrollFromElementAction.php | 2 +- lib/WebDriverSearchContext.php | 2 +- lib/WebDriverSelect.php | 5 +- .../internal => }/WebDriverSendKeysAction.php | 2 +- .../WebDriverSingleKeyAction.php | 2 +- .../touch => }/WebDriverTapAction.php | 2 +- lib/WebDriverTargetLocator.php | 2 +- lib/WebDriverTimeouts.php | 2 +- .../touch => }/WebDriverTouchAction.php | 2 +- .../WebDriverTouchActions.php | 2 +- .../WebDriverTouchScreen.php | 2 +- .../touch => }/WebDriverUpAction.php | 2 +- lib/WebDriverWait.php | 4 +- lib/WebDriverWindow.php | 3 +- lib/__init__.php | 116 ------------------ tests/bootstrap.php | 4 +- tests/functional/BaseTest.php | 2 +- tests/functional/FileUploadTest.php | 2 +- tests/functional/WebDriverTestCase.php | 2 +- tests/unit/bootstrap.php | 2 +- .../WebDriverButtonReleaseActionTest.php | 8 +- .../internal/WebDriverClickActionTest.php | 8 +- .../WebDriverClickAndHoldActionTest.php | 8 +- .../WebDriverContextClickActionTest.php | 8 +- .../internal/WebDriverCoordinatesTest.php | 2 +- .../WebDriverDoubleClickActionTest.php | 8 +- .../internal/WebDriverKeyDownActionTest.php | 10 +- .../internal/WebDriverKeyUpActionTest.php | 10 +- .../internal/WebDriverMouseMoveActionTest.php | 8 +- .../WebDriverMouseToOffsetActionTest.php | 8 +- .../internal/WebDriverSendKeysActionTest.php | 10 +- 143 files changed, 936 insertions(+), 323 deletions(-) rename lib/{chrome => }/ChromeDriver.php (96%) rename lib/{chrome => }/ChromeDriverService.php (97%) rename lib/{chrome => }/ChromeOptions.php (99%) rename lib/{remote => }/DesiredCapabilities.php (99%) rename lib/{remote => }/DriverCommand.php (99%) rename lib/{remote/service => }/DriverCommandExecutor.php (93%) rename lib/{remote/service => }/DriverService.php (98%) rename lib/{support/events => }/EventFiringWebDriver.php (98%) rename lib/{support/events => }/EventFiringWebDriverNavigation.php (97%) rename lib/{support/events => }/EventFiringWebElement.php (98%) create mode 100644 lib/Exception/ElementNotSelectableException.php create mode 100644 lib/Exception/ElementNotVisibleException.php create mode 100644 lib/Exception/ExpectedException.php create mode 100644 lib/Exception/IMEEngineActivationFailedException.php create mode 100644 lib/Exception/IMENotAvailableException.php create mode 100644 lib/Exception/IndexOutOfBoundsException.php create mode 100644 lib/Exception/InvalidCookieDomainException.php create mode 100644 lib/Exception/InvalidCoordinatesException.php create mode 100644 lib/Exception/InvalidElementStateException.php create mode 100644 lib/Exception/InvalidSelectorException.php create mode 100644 lib/Exception/MoveTargetOutOfBoundsException.php create mode 100644 lib/Exception/NoAlertOpenException.php create mode 100644 lib/Exception/NoCollectionException.php create mode 100644 lib/Exception/NoScriptResultException.php create mode 100644 lib/Exception/NoStringException.php create mode 100644 lib/Exception/NoStringLengthException.php create mode 100644 lib/Exception/NoStringWrapperException.php create mode 100644 lib/Exception/NoSuchCollectionException.php create mode 100644 lib/Exception/NoSuchDocumentException.php create mode 100644 lib/Exception/NoSuchDriverException.php create mode 100644 lib/Exception/NoSuchElementException.php create mode 100644 lib/Exception/NoSuchFrameException.php create mode 100644 lib/Exception/NoSuchWindowException.php create mode 100644 lib/Exception/NullPointerException.php create mode 100644 lib/Exception/ScriptTimeoutException.php create mode 100644 lib/Exception/SessionNotCreatedException.php create mode 100644 lib/Exception/StaleElementReferenceException.php create mode 100644 lib/Exception/TimeOutException.php create mode 100644 lib/Exception/UnableToSetCookieException.php create mode 100644 lib/Exception/UnexpectedAlertOpenException.php create mode 100644 lib/Exception/UnexpectedJavascriptException.php create mode 100644 lib/Exception/UnexpectedTagNameException.php create mode 100644 lib/Exception/UnknownCommandException.php create mode 100644 lib/Exception/UnknownServerException.php create mode 100644 lib/Exception/UnrecognizedExceptionException.php create mode 100644 lib/Exception/UnsupportedOperationException.php create mode 100644 lib/Exception/WebDriverCurlException.php rename lib/{WebDriverExceptions.php => Exception/WebDriverException.php} (59%) create mode 100644 lib/Exception/XPathLookupException.php rename lib/{remote => }/ExecuteMethod.php (96%) rename lib/{remote => }/FileDetector.php (96%) rename lib/{firefox => }/FirefoxDriver.php (95%) rename lib/{firefox => }/FirefoxProfile.php (95%) rename lib/{remote => }/HttpCommandExecutor.php (99%) rename lib/{remote => }/LocalFileDetector.php (96%) rename lib/{remote => }/RemoteExecuteMethod.php (97%) rename lib/{remote => }/RemoteKeyboard.php (98%) rename lib/{remote => }/RemoteMouse.php (99%) rename lib/{remote => }/RemoteTargetLocator.php (99%) rename lib/{remote => }/RemoteTouchScreen.php (99%) rename lib/{remote => }/RemoteWebDriver.php (99%) rename lib/{remote => }/RemoteWebElement.php (99%) rename lib/{net => }/URLChecker.php (95%) rename lib/{remote => }/UselessFileDetector.php (96%) rename lib/{interactions => }/WebDriverActions.php (99%) rename lib/{remote => }/WebDriverBrowserType.php (97%) rename lib/{interactions/internal => }/WebDriverButtonReleaseAction.php (96%) rename lib/{remote => }/WebDriverCapabilityType.php (98%) rename lib/{interactions/internal => }/WebDriverClickAction.php (96%) rename lib/{interactions/internal => }/WebDriverClickAndHoldAction.php (96%) rename lib/{remote => }/WebDriverCommand.php (97%) rename lib/{interactions => }/WebDriverCompositeAction.php (97%) rename lib/{interactions/internal => }/WebDriverContextClickAction.php (96%) rename lib/{interactions/internal => }/WebDriverCoordinates.php (94%) rename lib/{interactions/internal => }/WebDriverDoubleClickAction.php (96%) rename lib/{interactions/touch => }/WebDriverDoubleTapAction.php (96%) rename lib/{interactions/touch => }/WebDriverDownAction.php (97%) rename lib/{interactions/touch => }/WebDriverFlickAction.php (97%) rename lib/{interactions/touch => }/WebDriverFlickFromElementAction.php (97%) rename lib/{interactions/internal => }/WebDriverKeyDownAction.php (96%) rename lib/{interactions/internal => }/WebDriverKeyUpAction.php (96%) rename lib/{interactions/internal => }/WebDriverKeysRelatedAction.php (97%) rename lib/{internal => }/WebDriverLocatable.php (96%) rename lib/{interactions/touch => }/WebDriverLongPressAction.php (96%) rename lib/{interactions/internal => }/WebDriverMouseAction.php (97%) rename lib/{interactions/internal => }/WebDriverMouseMoveAction.php (96%) rename lib/{interactions/touch => }/WebDriverMoveAction.php (97%) rename lib/{interactions/internal => }/WebDriverMoveToOffsetAction.php (97%) rename lib/{remote => }/WebDriverResponse.php (98%) rename lib/{interactions/touch => }/WebDriverScrollAction.php (97%) rename lib/{interactions/touch => }/WebDriverScrollFromElementAction.php (97%) rename lib/{interactions/internal => }/WebDriverSendKeysAction.php (97%) rename lib/{interactions/internal => }/WebDriverSingleKeyAction.php (97%) rename lib/{interactions/touch => }/WebDriverTapAction.php (96%) rename lib/{interactions/touch => }/WebDriverTouchAction.php (97%) rename lib/{interactions => }/WebDriverTouchActions.php (99%) rename lib/{interactions => }/WebDriverTouchScreen.php (99%) rename lib/{interactions/touch => }/WebDriverUpAction.php (97%) delete mode 100755 lib/__init__.php diff --git a/composer.json b/composer.json index 41b0fce1e..7b57541f4 100644 --- a/composer.json +++ b/composer.json @@ -1,13 +1,13 @@ { - "name": "opsbears/webdriver", - "description": "A php client for WebDriver (fork of facebook/webdriver)", + "name": "facebook/webdriver", + "description": "A php client for WebDriver", "keywords": ["webdriver", "selenium", "php"], - "homepage": "https://github.com/opsbears/php-webdriver", + "homepage": "https://github.com/facebook/php-webdriver", "type": "library", "license": "Apache-2.0", "support": { - "issues": "https://github.com/opsbears/php-webdriver/issues", - "source": "https://github.com/opsbears/php-webdriver" + "issues": "https://github.com/facebook/php-webdriver/issues", + "source": "https://github.com/facebook/php-webdriver" }, "require": { "php": ">=5.3.19" @@ -17,7 +17,9 @@ "phpdocumentor/phpdocumentor": "2.*" }, "autoload": { - "classmap": ["lib/"] + "psr-4": { + "Facebook\\WebDriver\\": "lib/" + } }, "minimum-stability": "dev" } diff --git a/example.php b/example.php index 8cfac7461..b4834146c 100644 --- a/example.php +++ b/example.php @@ -1,9 +1,9 @@ service->stop(); } return $value; - } catch (Exception $e) { + } catch (\Exception $e) { if (!$this->service->isRunning()) { throw new WebDriverException('The driver server has died.'); } diff --git a/lib/remote/service/DriverService.php b/lib/DriverService.php similarity index 98% rename from lib/remote/service/DriverService.php rename to lib/DriverService.php index c8a9bdb9c..77384b9d0 100644 --- a/lib/remote/service/DriverService.php +++ b/lib/DriverService.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; + +use Exception; class DriverService { diff --git a/lib/support/events/EventFiringWebDriver.php b/lib/EventFiringWebDriver.php similarity index 98% rename from lib/support/events/EventFiringWebDriver.php rename to lib/EventFiringWebDriver.php index cefe6d987..ebd5b9b7c 100644 --- a/lib/support/events/EventFiringWebDriver.php +++ b/lib/EventFiringWebDriver.php @@ -13,7 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; + +use Facebook\WebDriver\Exception\UnsupportedOperationException; +use Facebook\WebDriver\Exception\WebDriverException; class EventFiringWebDriver implements WebDriver, JavaScriptExecutor { diff --git a/lib/support/events/EventFiringWebDriverNavigation.php b/lib/EventFiringWebDriverNavigation.php similarity index 97% rename from lib/support/events/EventFiringWebDriverNavigation.php rename to lib/EventFiringWebDriverNavigation.php index 7f1e71b0a..c3feea060 100644 --- a/lib/support/events/EventFiringWebDriverNavigation.php +++ b/lib/EventFiringWebDriverNavigation.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; + +use Facebook\WebDriver\Exception\WebDriverException; class EventFiringWebDriverNavigation { diff --git a/lib/support/events/EventFiringWebElement.php b/lib/EventFiringWebElement.php similarity index 98% rename from lib/support/events/EventFiringWebElement.php rename to lib/EventFiringWebElement.php index f0b317cef..a955c59d6 100644 --- a/lib/support/events/EventFiringWebElement.php +++ b/lib/EventFiringWebElement.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; + +use Facebook\WebDriver\Exception\WebDriverException; class EventFiringWebElement implements WebDriverElement, WebDriverLocatable { diff --git a/lib/Exception/ElementNotSelectableException.php b/lib/Exception/ElementNotSelectableException.php new file mode 100644 index 000000000..9acfb88f2 --- /dev/null +++ b/lib/Exception/ElementNotSelectableException.php @@ -0,0 +1,21 @@ +extractTo($target_dir); $zip->close(); } else { - throw new Exception("Failed to open the firefox extension. '$xpi'"); + throw new \Exception("Failed to open the firefox extension. '$xpi'"); } return $this; } diff --git a/lib/remote/HttpCommandExecutor.php b/lib/HttpCommandExecutor.php similarity index 99% rename from lib/remote/HttpCommandExecutor.php rename to lib/HttpCommandExecutor.php index 0a45c0052..4e3bc085f 100644 --- a/lib/remote/HttpCommandExecutor.php +++ b/lib/HttpCommandExecutor.php @@ -13,7 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; +use Facebook\WebDriver\Exception\WebDriverException; +use InvalidArgumentException; +use BadMethodCallException; /** * Command executor talking to the standalone server via HTTP. diff --git a/lib/JavaScriptExecutor.php b/lib/JavaScriptExecutor.php index 18cba7866..3e0db1302 100644 --- a/lib/JavaScriptExecutor.php +++ b/lib/JavaScriptExecutor.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * WebDriver interface implemented by drivers that support JavaScript. diff --git a/lib/remote/LocalFileDetector.php b/lib/LocalFileDetector.php similarity index 96% rename from lib/remote/LocalFileDetector.php rename to lib/LocalFileDetector.php index d8cac906e..a9a7488ce 100644 --- a/lib/remote/LocalFileDetector.php +++ b/lib/LocalFileDetector.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class LocalFileDetector implements FileDetector { /** diff --git a/lib/remote/RemoteExecuteMethod.php b/lib/RemoteExecuteMethod.php similarity index 97% rename from lib/remote/RemoteExecuteMethod.php rename to lib/RemoteExecuteMethod.php index 4d874179c..3ab0a60ae 100644 --- a/lib/remote/RemoteExecuteMethod.php +++ b/lib/RemoteExecuteMethod.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class RemoteExecuteMethod implements ExecuteMethod { diff --git a/lib/remote/RemoteKeyboard.php b/lib/RemoteKeyboard.php similarity index 98% rename from lib/remote/RemoteKeyboard.php rename to lib/RemoteKeyboard.php index 9831b74f4..d7d3ebbdb 100644 --- a/lib/remote/RemoteKeyboard.php +++ b/lib/RemoteKeyboard.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Execute keyboard commands for RemoteWebDriver. diff --git a/lib/remote/RemoteMouse.php b/lib/RemoteMouse.php similarity index 99% rename from lib/remote/RemoteMouse.php rename to lib/RemoteMouse.php index 93168abf8..deb2164fd 100644 --- a/lib/remote/RemoteMouse.php +++ b/lib/RemoteMouse.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Execute mouse commands for RemoteWebDriver. diff --git a/lib/remote/RemoteTargetLocator.php b/lib/RemoteTargetLocator.php similarity index 99% rename from lib/remote/RemoteTargetLocator.php rename to lib/RemoteTargetLocator.php index 841c4acf1..c33bd2c71 100644 --- a/lib/remote/RemoteTargetLocator.php +++ b/lib/RemoteTargetLocator.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Used to locate a given frame or window for RemoteWebDriver. diff --git a/lib/remote/RemoteTouchScreen.php b/lib/RemoteTouchScreen.php similarity index 99% rename from lib/remote/RemoteTouchScreen.php rename to lib/RemoteTouchScreen.php index 6ef5d35d5..3ca3c19bd 100644 --- a/lib/remote/RemoteTouchScreen.php +++ b/lib/RemoteTouchScreen.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Execute touch commands for RemoteWebDriver. diff --git a/lib/remote/RemoteWebDriver.php b/lib/RemoteWebDriver.php similarity index 99% rename from lib/remote/RemoteWebDriver.php rename to lib/RemoteWebDriver.php index 246a7adfa..86d9e0d8b 100644 --- a/lib/remote/RemoteWebDriver.php +++ b/lib/RemoteWebDriver.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class RemoteWebDriver implements WebDriver, JavaScriptExecutor { /** diff --git a/lib/remote/RemoteWebElement.php b/lib/RemoteWebElement.php similarity index 99% rename from lib/remote/RemoteWebElement.php rename to lib/RemoteWebElement.php index 3f78d1cc1..98d6cca07 100644 --- a/lib/remote/RemoteWebElement.php +++ b/lib/RemoteWebElement.php @@ -13,8 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; +use Facebook\WebDriver\Exception\WebDriverException; use ZipArchive; /** diff --git a/lib/net/URLChecker.php b/lib/URLChecker.php similarity index 95% rename from lib/net/URLChecker.php rename to lib/URLChecker.php index 13588203b..657488dbf 100644 --- a/lib/net/URLChecker.php +++ b/lib/URLChecker.php @@ -13,7 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; + +use Exception; +use Facebook\WebDriver\Exception\TimeOutException; class URLChecker { diff --git a/lib/remote/UselessFileDetector.php b/lib/UselessFileDetector.php similarity index 96% rename from lib/remote/UselessFileDetector.php rename to lib/UselessFileDetector.php index f21df9e64..ce4c55fc9 100644 --- a/lib/remote/UselessFileDetector.php +++ b/lib/UselessFileDetector.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class UselessFileDetector implements FileDetector { /** diff --git a/lib/WebDriver.php b/lib/WebDriver.php index 14e102b92..b143583ca 100755 --- a/lib/WebDriver.php +++ b/lib/WebDriver.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * The interface for WebDriver. diff --git a/lib/WebDriverAction.php b/lib/WebDriverAction.php index cff1ca9ae..a5d2d32d8 100644 --- a/lib/WebDriverAction.php +++ b/lib/WebDriverAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Interface representing a single user-interaction action. diff --git a/lib/interactions/WebDriverActions.php b/lib/WebDriverActions.php similarity index 99% rename from lib/interactions/WebDriverActions.php rename to lib/WebDriverActions.php index eac0d14ae..37537e2b9 100644 --- a/lib/interactions/WebDriverActions.php +++ b/lib/WebDriverActions.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * WebDriver action builder. It implements the builder pattern. diff --git a/lib/WebDriverAlert.php b/lib/WebDriverAlert.php index 84bc202c8..2f92ec4c4 100644 --- a/lib/WebDriverAlert.php +++ b/lib/WebDriverAlert.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * An abstraction allowing the driver to manipulate the javascript alerts diff --git a/lib/remote/WebDriverBrowserType.php b/lib/WebDriverBrowserType.php similarity index 97% rename from lib/remote/WebDriverBrowserType.php rename to lib/WebDriverBrowserType.php index 8db21c0a5..bbb9a529e 100644 --- a/lib/remote/WebDriverBrowserType.php +++ b/lib/WebDriverBrowserType.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * All the browsers supported by selenium diff --git a/lib/interactions/internal/WebDriverButtonReleaseAction.php b/lib/WebDriverButtonReleaseAction.php similarity index 96% rename from lib/interactions/internal/WebDriverButtonReleaseAction.php rename to lib/WebDriverButtonReleaseAction.php index ea518877a..444632265 100644 --- a/lib/interactions/internal/WebDriverButtonReleaseAction.php +++ b/lib/WebDriverButtonReleaseAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Move to the location and then release the mouse key. diff --git a/lib/WebDriverBy.php b/lib/WebDriverBy.php index ce25f308e..c409768a8 100644 --- a/lib/WebDriverBy.php +++ b/lib/WebDriverBy.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * The basic 8 mechanisms supported by webdriver to locate a web element. diff --git a/lib/WebDriverCapabilities.php b/lib/WebDriverCapabilities.php index 3ccc30ee6..721db82e6 100644 --- a/lib/WebDriverCapabilities.php +++ b/lib/WebDriverCapabilities.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; interface WebDriverCapabilities { diff --git a/lib/remote/WebDriverCapabilityType.php b/lib/WebDriverCapabilityType.php similarity index 98% rename from lib/remote/WebDriverCapabilityType.php rename to lib/WebDriverCapabilityType.php index a7499d9e0..558abb4ab 100644 --- a/lib/remote/WebDriverCapabilityType.php +++ b/lib/WebDriverCapabilityType.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * WebDriverCapabilityType contains all constants defined in the WebDriver diff --git a/lib/interactions/internal/WebDriverClickAction.php b/lib/WebDriverClickAction.php similarity index 96% rename from lib/interactions/internal/WebDriverClickAction.php rename to lib/WebDriverClickAction.php index 54adb4a6f..cc9263c17 100644 --- a/lib/interactions/internal/WebDriverClickAction.php +++ b/lib/WebDriverClickAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverClickAction extends WebDriverMouseAction diff --git a/lib/interactions/internal/WebDriverClickAndHoldAction.php b/lib/WebDriverClickAndHoldAction.php similarity index 96% rename from lib/interactions/internal/WebDriverClickAndHoldAction.php rename to lib/WebDriverClickAndHoldAction.php index 30169ff5b..6bc8d049b 100644 --- a/lib/interactions/internal/WebDriverClickAndHoldAction.php +++ b/lib/WebDriverClickAndHoldAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Move the the location, click and hold. diff --git a/lib/remote/WebDriverCommand.php b/lib/WebDriverCommand.php similarity index 97% rename from lib/remote/WebDriverCommand.php rename to lib/WebDriverCommand.php index 2300ce373..06660dadf 100644 --- a/lib/remote/WebDriverCommand.php +++ b/lib/WebDriverCommand.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverCommand { diff --git a/lib/WebDriverCommandExecutor.php b/lib/WebDriverCommandExecutor.php index 7a3eb20fd..5f99a1d16 100644 --- a/lib/WebDriverCommandExecutor.php +++ b/lib/WebDriverCommandExecutor.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Interface for all command executor. diff --git a/lib/interactions/WebDriverCompositeAction.php b/lib/WebDriverCompositeAction.php similarity index 97% rename from lib/interactions/WebDriverCompositeAction.php rename to lib/WebDriverCompositeAction.php index 261dde15d..de80c787f 100644 --- a/lib/interactions/WebDriverCompositeAction.php +++ b/lib/WebDriverCompositeAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * An action for aggregating actions and triggering all of them afterwards. diff --git a/lib/interactions/internal/WebDriverContextClickAction.php b/lib/WebDriverContextClickAction.php similarity index 96% rename from lib/interactions/internal/WebDriverContextClickAction.php rename to lib/WebDriverContextClickAction.php index e1c3f96ad..5e2638dca 100644 --- a/lib/interactions/internal/WebDriverContextClickAction.php +++ b/lib/WebDriverContextClickAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * You can call it 'Right Click' if you like. diff --git a/lib/interactions/internal/WebDriverCoordinates.php b/lib/WebDriverCoordinates.php similarity index 94% rename from lib/interactions/internal/WebDriverCoordinates.php rename to lib/WebDriverCoordinates.php index 980051bac..e43b7fb75 100644 --- a/lib/interactions/internal/WebDriverCoordinates.php +++ b/lib/WebDriverCoordinates.php @@ -13,9 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; use Closure; +use Facebook\WebDriver\Exception\UnsupportedOperationException; /** * Interface representing basic mouse operations. diff --git a/lib/WebDriverDimension.php b/lib/WebDriverDimension.php index a2572ecbf..c66278931 100644 --- a/lib/WebDriverDimension.php +++ b/lib/WebDriverDimension.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Represent a dimension. diff --git a/lib/WebDriverDispatcher.php b/lib/WebDriverDispatcher.php index 693763b70..ae9e5e8f7 100644 --- a/lib/WebDriverDispatcher.php +++ b/lib/WebDriverDispatcher.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverDispatcher { diff --git a/lib/interactions/internal/WebDriverDoubleClickAction.php b/lib/WebDriverDoubleClickAction.php similarity index 96% rename from lib/interactions/internal/WebDriverDoubleClickAction.php rename to lib/WebDriverDoubleClickAction.php index d720e0d20..15c9e422c 100644 --- a/lib/interactions/internal/WebDriverDoubleClickAction.php +++ b/lib/WebDriverDoubleClickAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverDoubleClickAction extends WebDriverMouseAction diff --git a/lib/interactions/touch/WebDriverDoubleTapAction.php b/lib/WebDriverDoubleTapAction.php similarity index 96% rename from lib/interactions/touch/WebDriverDoubleTapAction.php rename to lib/WebDriverDoubleTapAction.php index c4bf374d6..c2cc7d381 100644 --- a/lib/interactions/touch/WebDriverDoubleTapAction.php +++ b/lib/WebDriverDoubleTapAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverDoubleTapAction extends WebDriverTouchAction diff --git a/lib/interactions/touch/WebDriverDownAction.php b/lib/WebDriverDownAction.php similarity index 97% rename from lib/interactions/touch/WebDriverDownAction.php rename to lib/WebDriverDownAction.php index 155e67eef..67fc73e55 100644 --- a/lib/interactions/touch/WebDriverDownAction.php +++ b/lib/WebDriverDownAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverDownAction extends WebDriverTouchAction diff --git a/lib/WebDriverElement.php b/lib/WebDriverElement.php index e060aa094..d49190604 100644 --- a/lib/WebDriverElement.php +++ b/lib/WebDriverElement.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Interface for an HTML element in the WebDriver framework. diff --git a/lib/WebDriverEventListener.php b/lib/WebDriverEventListener.php index 21c7f9002..4b458f649 100644 --- a/lib/WebDriverEventListener.php +++ b/lib/WebDriverEventListener.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; + +use Facebook\WebDriver\Exception\WebDriverException; interface WebDriverEventListener { diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index cb7526a43..ac1924a31 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -13,7 +13,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; +use Facebook\WebDriver\Exception\StaleElementReferenceException; +use Facebook\WebDriver\Exception\NoSuchFrameException; +use Facebook\WebDriver\Exception\NoSuchElementException; +use Facebook\WebDriver\Exception\NoAlertOpenException; /** * Canned ExpectedConditions which are generally useful within webdriver tests. diff --git a/lib/interactions/touch/WebDriverFlickAction.php b/lib/WebDriverFlickAction.php similarity index 97% rename from lib/interactions/touch/WebDriverFlickAction.php rename to lib/WebDriverFlickAction.php index 8b80cf127..446340718 100644 --- a/lib/interactions/touch/WebDriverFlickAction.php +++ b/lib/WebDriverFlickAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverFlickAction extends WebDriverTouchAction diff --git a/lib/interactions/touch/WebDriverFlickFromElementAction.php b/lib/WebDriverFlickFromElementAction.php similarity index 97% rename from lib/interactions/touch/WebDriverFlickFromElementAction.php rename to lib/WebDriverFlickFromElementAction.php index 478b3e0ab..3781d6c0e 100644 --- a/lib/interactions/touch/WebDriverFlickFromElementAction.php +++ b/lib/WebDriverFlickFromElementAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverFlickFromElementAction extends WebDriverTouchAction diff --git a/lib/WebDriverHasInputDevices.php b/lib/WebDriverHasInputDevices.php index 67fb80947..76c82dddc 100644 --- a/lib/WebDriverHasInputDevices.php +++ b/lib/WebDriverHasInputDevices.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Interface implemented by each driver that allows access to the input devices. diff --git a/lib/interactions/internal/WebDriverKeyDownAction.php b/lib/WebDriverKeyDownAction.php similarity index 96% rename from lib/interactions/internal/WebDriverKeyDownAction.php rename to lib/WebDriverKeyDownAction.php index 70f5421eb..5d5aa2afe 100644 --- a/lib/interactions/internal/WebDriverKeyDownAction.php +++ b/lib/WebDriverKeyDownAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverKeyDownAction extends WebDriverSingleKeyAction diff --git a/lib/interactions/internal/WebDriverKeyUpAction.php b/lib/WebDriverKeyUpAction.php similarity index 96% rename from lib/interactions/internal/WebDriverKeyUpAction.php rename to lib/WebDriverKeyUpAction.php index 24b5150f3..d41a5a2d8 100644 --- a/lib/interactions/internal/WebDriverKeyUpAction.php +++ b/lib/WebDriverKeyUpAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverKeyUpAction extends WebDriverSingleKeyAction diff --git a/lib/WebDriverKeyboard.php b/lib/WebDriverKeyboard.php index 06e6091dd..042e47108 100644 --- a/lib/WebDriverKeyboard.php +++ b/lib/WebDriverKeyboard.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; interface WebDriverKeyboard { diff --git a/lib/WebDriverKeys.php b/lib/WebDriverKeys.php index 64c76edd3..b946cec9f 100644 --- a/lib/WebDriverKeys.php +++ b/lib/WebDriverKeys.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Representations of pressable keys that aren't text. diff --git a/lib/interactions/internal/WebDriverKeysRelatedAction.php b/lib/WebDriverKeysRelatedAction.php similarity index 97% rename from lib/interactions/internal/WebDriverKeysRelatedAction.php rename to lib/WebDriverKeysRelatedAction.php index 779718496..bcd45f7f7 100644 --- a/lib/interactions/internal/WebDriverKeysRelatedAction.php +++ b/lib/WebDriverKeysRelatedAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Base class for all keyboard-related actions. diff --git a/lib/internal/WebDriverLocatable.php b/lib/WebDriverLocatable.php similarity index 96% rename from lib/internal/WebDriverLocatable.php rename to lib/WebDriverLocatable.php index d315387a1..bb2aa9035 100644 --- a/lib/internal/WebDriverLocatable.php +++ b/lib/WebDriverLocatable.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Interface representing basic mouse operations. diff --git a/lib/interactions/touch/WebDriverLongPressAction.php b/lib/WebDriverLongPressAction.php similarity index 96% rename from lib/interactions/touch/WebDriverLongPressAction.php rename to lib/WebDriverLongPressAction.php index a34de2e10..5fc2b519e 100644 --- a/lib/interactions/touch/WebDriverLongPressAction.php +++ b/lib/WebDriverLongPressAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverLongPressAction extends WebDriverTouchAction diff --git a/lib/WebDriverMouse.php b/lib/WebDriverMouse.php index 5b79fcf76..5c90fa199 100644 --- a/lib/WebDriverMouse.php +++ b/lib/WebDriverMouse.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Interface representing basic mouse operations. diff --git a/lib/interactions/internal/WebDriverMouseAction.php b/lib/WebDriverMouseAction.php similarity index 97% rename from lib/interactions/internal/WebDriverMouseAction.php rename to lib/WebDriverMouseAction.php index d02b638f4..8c3c1cb2a 100644 --- a/lib/interactions/internal/WebDriverMouseAction.php +++ b/lib/WebDriverMouseAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Base class for all mouse-related actions. diff --git a/lib/interactions/internal/WebDriverMouseMoveAction.php b/lib/WebDriverMouseMoveAction.php similarity index 96% rename from lib/interactions/internal/WebDriverMouseMoveAction.php rename to lib/WebDriverMouseMoveAction.php index 01e5c28bf..b24948daf 100644 --- a/lib/interactions/internal/WebDriverMouseMoveAction.php +++ b/lib/WebDriverMouseMoveAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverMouseMoveAction extends WebDriverMouseAction diff --git a/lib/interactions/touch/WebDriverMoveAction.php b/lib/WebDriverMoveAction.php similarity index 97% rename from lib/interactions/touch/WebDriverMoveAction.php rename to lib/WebDriverMoveAction.php index dae6e8ef1..32c324de7 100644 --- a/lib/interactions/touch/WebDriverMoveAction.php +++ b/lib/WebDriverMoveAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverMoveAction extends WebDriverTouchAction diff --git a/lib/interactions/internal/WebDriverMoveToOffsetAction.php b/lib/WebDriverMoveToOffsetAction.php similarity index 97% rename from lib/interactions/internal/WebDriverMoveToOffsetAction.php rename to lib/WebDriverMoveToOffsetAction.php index bdf41629e..fe1b0bfc2 100644 --- a/lib/interactions/internal/WebDriverMoveToOffsetAction.php +++ b/lib/WebDriverMoveToOffsetAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverMoveToOffsetAction extends WebDriverMouseAction diff --git a/lib/WebDriverNavigation.php b/lib/WebDriverNavigation.php index 75baa18d5..f572b6f92 100644 --- a/lib/WebDriverNavigation.php +++ b/lib/WebDriverNavigation.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * An abstraction allowing the driver to access the browser's history and to diff --git a/lib/WebDriverOptions.php b/lib/WebDriverOptions.php index 10f59d937..d673603b2 100644 --- a/lib/WebDriverOptions.php +++ b/lib/WebDriverOptions.php @@ -13,7 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; +use InvalidArgumentException; /** * Managing stuff you would do in a browser. diff --git a/lib/WebDriverPlatform.php b/lib/WebDriverPlatform.php index a16a4cb2a..4954bf56e 100644 --- a/lib/WebDriverPlatform.php +++ b/lib/WebDriverPlatform.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * The platforms supported by WebDriver. diff --git a/lib/WebDriverPoint.php b/lib/WebDriverPoint.php index ae8dbd667..0653eb988 100644 --- a/lib/WebDriverPoint.php +++ b/lib/WebDriverPoint.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Represent a point. diff --git a/lib/remote/WebDriverResponse.php b/lib/WebDriverResponse.php similarity index 98% rename from lib/remote/WebDriverResponse.php rename to lib/WebDriverResponse.php index 71b934074..a2d4dd244 100644 --- a/lib/remote/WebDriverResponse.php +++ b/lib/WebDriverResponse.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverResponse { diff --git a/lib/interactions/touch/WebDriverScrollAction.php b/lib/WebDriverScrollAction.php similarity index 97% rename from lib/interactions/touch/WebDriverScrollAction.php rename to lib/WebDriverScrollAction.php index 817ed26aa..e7e183b31 100644 --- a/lib/interactions/touch/WebDriverScrollAction.php +++ b/lib/WebDriverScrollAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverScrollAction extends WebDriverTouchAction diff --git a/lib/interactions/touch/WebDriverScrollFromElementAction.php b/lib/WebDriverScrollFromElementAction.php similarity index 97% rename from lib/interactions/touch/WebDriverScrollFromElementAction.php rename to lib/WebDriverScrollFromElementAction.php index 96109712a..63be82c48 100644 --- a/lib/interactions/touch/WebDriverScrollFromElementAction.php +++ b/lib/WebDriverScrollFromElementAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverScrollFromElementAction extends WebDriverTouchAction diff --git a/lib/WebDriverSearchContext.php b/lib/WebDriverSearchContext.php index 17f3417a4..07f7bbccc 100644 --- a/lib/WebDriverSearchContext.php +++ b/lib/WebDriverSearchContext.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * The interface for WebDriver and WebDriverElement which is able to search for diff --git a/lib/WebDriverSelect.php b/lib/WebDriverSelect.php index 85aabe832..cebeba364 100644 --- a/lib/WebDriverSelect.php +++ b/lib/WebDriverSelect.php @@ -13,7 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; +use Facebook\WebDriver\Exception\UnexpectedTagNameException; +use Facebook\WebDriver\Exception\NoSuchElementException; +use Facebook\WebDriver\Exception\UnsupportedOperationException; /** * Models a SELECT tag, providing helper methods to select and deselect options. diff --git a/lib/interactions/internal/WebDriverSendKeysAction.php b/lib/WebDriverSendKeysAction.php similarity index 97% rename from lib/interactions/internal/WebDriverSendKeysAction.php rename to lib/WebDriverSendKeysAction.php index 889a2f91b..9b371a551 100644 --- a/lib/interactions/internal/WebDriverSendKeysAction.php +++ b/lib/WebDriverSendKeysAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverSendKeysAction extends WebDriverKeysRelatedAction diff --git a/lib/interactions/internal/WebDriverSingleKeyAction.php b/lib/WebDriverSingleKeyAction.php similarity index 97% rename from lib/interactions/internal/WebDriverSingleKeyAction.php rename to lib/WebDriverSingleKeyAction.php index 5b6c3c62d..a9280afe1 100644 --- a/lib/interactions/internal/WebDriverSingleKeyAction.php +++ b/lib/WebDriverSingleKeyAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; abstract class WebDriverSingleKeyAction extends WebDriverKeysRelatedAction diff --git a/lib/interactions/touch/WebDriverTapAction.php b/lib/WebDriverTapAction.php similarity index 96% rename from lib/interactions/touch/WebDriverTapAction.php rename to lib/WebDriverTapAction.php index b61056e99..27ef9627f 100644 --- a/lib/interactions/touch/WebDriverTapAction.php +++ b/lib/WebDriverTapAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverTapAction extends WebDriverTouchAction diff --git a/lib/WebDriverTargetLocator.php b/lib/WebDriverTargetLocator.php index 53efb59ca..86e0939b8 100644 --- a/lib/WebDriverTargetLocator.php +++ b/lib/WebDriverTargetLocator.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Used to locate a given frame or window. diff --git a/lib/WebDriverTimeouts.php b/lib/WebDriverTimeouts.php index f4732f708..aac26c146 100644 --- a/lib/WebDriverTimeouts.php +++ b/lib/WebDriverTimeouts.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Managing timeout behavior for WebDriver instances. diff --git a/lib/interactions/touch/WebDriverTouchAction.php b/lib/WebDriverTouchAction.php similarity index 97% rename from lib/interactions/touch/WebDriverTouchAction.php rename to lib/WebDriverTouchAction.php index a885467fe..06ba9fdab 100644 --- a/lib/interactions/touch/WebDriverTouchAction.php +++ b/lib/WebDriverTouchAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Base class for all touch-related actions. diff --git a/lib/interactions/WebDriverTouchActions.php b/lib/WebDriverTouchActions.php similarity index 99% rename from lib/interactions/WebDriverTouchActions.php rename to lib/WebDriverTouchActions.php index 83281e839..a223f269d 100644 --- a/lib/interactions/WebDriverTouchActions.php +++ b/lib/WebDriverTouchActions.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * WebDriver action builder for touch events diff --git a/lib/interactions/WebDriverTouchScreen.php b/lib/WebDriverTouchScreen.php similarity index 99% rename from lib/interactions/WebDriverTouchScreen.php rename to lib/WebDriverTouchScreen.php index be9a2474a..46f989013 100644 --- a/lib/interactions/WebDriverTouchScreen.php +++ b/lib/WebDriverTouchScreen.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; /** * Interface representing touch screen operations. diff --git a/lib/interactions/touch/WebDriverUpAction.php b/lib/WebDriverUpAction.php similarity index 97% rename from lib/interactions/touch/WebDriverUpAction.php rename to lib/WebDriverUpAction.php index 8745eb4c7..9e0035d1a 100644 --- a/lib/interactions/touch/WebDriverUpAction.php +++ b/lib/WebDriverUpAction.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverUpAction extends WebDriverTouchAction diff --git a/lib/WebDriverWait.php b/lib/WebDriverWait.php index c4264f49a..3ee5cb46f 100644 --- a/lib/WebDriverWait.php +++ b/lib/WebDriverWait.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; +use Facebook\WebDriver\Exception\NoSuchElementException; +use Facebook\WebDriver\Exception\TimeOutException; /** * A utility class, designed to help the user to wait until a condition turns diff --git a/lib/WebDriverWindow.php b/lib/WebDriverWindow.php index b4f649b77..c29deb06c 100644 --- a/lib/WebDriverWindow.php +++ b/lib/WebDriverWindow.php @@ -13,7 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; +use Facebook\WebDriver\Exception\IndexOutOfBoundsException; /** * An abstraction allowing the driver to manipulate the browser's window diff --git a/lib/__init__.php b/lib/__init__.php deleted file mode 100755 index 55219b491..000000000 --- a/lib/__init__.php +++ /dev/null @@ -1,116 +0,0 @@ -webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); $this->webDriverButtonReleaseAction = new WebDriverButtonReleaseAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +34,7 @@ public function setUp() { } public function testPerformSendsMouseUpCommand() { - $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseUp')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverButtonReleaseAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverClickActionTest.php b/tests/unit/interactions/internal/WebDriverClickActionTest.php index ca60ae668..fd1ece96f 100644 --- a/tests/unit/interactions/internal/WebDriverClickActionTest.php +++ b/tests/unit/interactions/internal/WebDriverClickActionTest.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverClickActionTest extends \PHPUnit_Framework_TestCase { /** @@ -25,8 +25,8 @@ class WebDriverClickActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); $this->webDriverClickAction = new WebDriverClickAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +34,7 @@ public function setUp() { } public function testPerformSendsClickCommand() { - $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverClickAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php b/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php index 78781fae6..bf9a4cdea 100644 --- a/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php +++ b/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverClickAndHoldActionTest extends \PHPUnit_Framework_TestCase { /** @@ -25,8 +25,8 @@ class WebDriverClickAndHoldActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); $this->webDriverClickAndHoldAction = new WebDriverClickAndHoldAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +34,7 @@ public function setUp() { } public function testPerformSendsMouseDownCommand() { - $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseDown')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverClickAndHoldAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverContextClickActionTest.php b/tests/unit/interactions/internal/WebDriverContextClickActionTest.php index ece8f3488..2ca80a538 100644 --- a/tests/unit/interactions/internal/WebDriverContextClickActionTest.php +++ b/tests/unit/interactions/internal/WebDriverContextClickActionTest.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverContextClickActionTest extends \PHPUnit_Framework_TestCase { /** @@ -25,8 +25,8 @@ class WebDriverContextClickActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); $this->webDriverContextClickAction = new WebDriverContextClickAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +34,7 @@ public function setUp() { } public function testPerformSendsContextClickCommand() { - $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('contextClick')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverContextClickAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverCoordinatesTest.php b/tests/unit/interactions/internal/WebDriverCoordinatesTest.php index f339e5044..a7fa52549 100644 --- a/tests/unit/interactions/internal/WebDriverCoordinatesTest.php +++ b/tests/unit/interactions/internal/WebDriverCoordinatesTest.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverCoordinatesTest extends \PHPUnit_Framework_TestCase { public function testConstruct() { diff --git a/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php b/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php index ae45d169b..bae50645d 100644 --- a/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php +++ b/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverDoubleClickActionTest extends \PHPUnit_Framework_TestCase { /** @@ -25,8 +25,8 @@ class WebDriverDoubleClickActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); $this->webDriverDoubleClickAction = new WebDriverDoubleClickAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +34,7 @@ public function setUp() { } public function testPerformSendsDoubleClickCommand() { - $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('doubleClick')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverDoubleClickAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php b/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php index 0cc5cb5cd..af9ce8e0e 100644 --- a/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php +++ b/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverKeyDownActionTest extends \PHPUnit_Framework_TestCase { /** @@ -26,9 +26,9 @@ class WebDriverKeyDownActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverKeyboard = $this->getMock('Selenium\WebDriver\WebDriverKeyboard'); - $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); + $this->webDriverKeyboard = $this->getMock('Facebook\WebDriver\WebDriverKeyboard'); + $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); $this->webDriverKeyDownAction = new WebDriverKeyDownAction( $this->webDriverKeyboard, $this->webDriverMouse, @@ -37,7 +37,7 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverKeyboard->expects($this->once())->method('pressKey'); diff --git a/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php b/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php index daf7bfc06..98d4cf27d 100644 --- a/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php +++ b/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverKeyUpActionTest extends \PHPUnit_Framework_TestCase { /** @@ -26,9 +26,9 @@ class WebDriverKeyUpActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverKeyboard = $this->getMock('Selenium\WebDriver\WebDriverKeyboard'); - $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); + $this->webDriverKeyboard = $this->getMock('Facebook\WebDriver\WebDriverKeyboard'); + $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); $this->webDriverKeyUpAction = new WebDriverKeyUpAction( $this->webDriverKeyboard, $this->webDriverMouse, @@ -38,7 +38,7 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverKeyboard->expects($this->once())->method('releaseKey')->with('a'); diff --git a/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php b/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php index 2c6ee400e..bbd306640 100644 --- a/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php +++ b/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverMouseMoveActionTest extends \PHPUnit_Framework_TestCase { /** @@ -25,8 +25,8 @@ class WebDriverMouseMoveActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); $this->webDriverMouseMoveAction = new WebDriverMouseMoveAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +34,7 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseMove')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverMouseMoveAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php b/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php index c6066d051..3fbc3b130 100644 --- a/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php +++ b/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverMouseToOffsetActionTest extends \PHPUnit_Framework_TestCase { /** @@ -25,8 +25,8 @@ class WebDriverMouseToOffsetActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); + $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); $this->webDriverMoveToOffsetAction = new WebDriverMoveToOffsetAction( $this->webDriverMouse, $this->locationProvider, @@ -36,7 +36,7 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseMove')->with($coords, 150, 200); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverMoveToOffsetAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php b/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php index 6a51f8934..77fd71587 100644 --- a/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php +++ b/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Selenium\WebDriver; +namespace Facebook\WebDriver; class WebDriverSendKeysActionTest extends \PHPUnit_Framework_TestCase { /** @@ -27,9 +27,9 @@ class WebDriverSendKeysActionTest extends \PHPUnit_Framework_TestCase { private $keys; public function setUp() { - $this->webDriverKeyboard = $this->getMock('Selenium\WebDriver\WebDriverKeyboard'); - $this->webDriverMouse = $this->getMock('Selenium\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Selenium\WebDriver\WebDriverLocatable'); + $this->webDriverKeyboard = $this->getMock('Facebook\WebDriver\WebDriverKeyboard'); + $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); $this->keys = array('t', 'e', 's', 't'); $this->webDriverSendKeysAction = new WebDriverSendKeysAction( $this->webDriverKeyboard, @@ -40,7 +40,7 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Selenium\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); $this->webDriverKeyboard->expects($this->once())->method('sendKeys')->with($this->keys); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); From b4151c3041a816acbb303fe55c5cbf04ce3145e3 Mon Sep 17 00:00:00 2001 From: Janos Pasztor Date: Tue, 19 May 2015 12:29:22 +0200 Subject: [PATCH 157/784] Issue facebook/php-webdriver#212 - Moved classes to subnamespaces (needs manual testing) --- example.php | 3 ++ lib/{ => Chrome}/ChromeDriver.php | 25 +++++++++-- lib/{ => Chrome}/ChromeDriverService.php | 4 +- lib/{ => Chrome}/ChromeOptions.php | 4 +- lib/Exception/WebDriverException.php | 41 ++++++++++++++++++- lib/{ => Firefox}/FirefoxDriver.php | 2 +- lib/{ => Firefox}/FirefoxProfile.php | 8 +++- .../WebDriverButtonReleaseAction.php | 4 +- .../Internal}/WebDriverClickAction.php | 4 +- .../Internal}/WebDriverClickAndHoldAction.php | 4 +- .../Internal}/WebDriverContextClickAction.php | 4 +- .../Internal}/WebDriverCoordinates.php | 4 +- .../Internal}/WebDriverDoubleClickAction.php | 4 +- .../Internal}/WebDriverKeyDownAction.php | 4 +- .../Internal}/WebDriverKeyUpAction.php | 4 +- .../Internal}/WebDriverKeysRelatedAction.php | 6 ++- .../Internal}/WebDriverMouseAction.php | 12 +++++- .../Internal}/WebDriverMouseMoveAction.php | 4 +- .../Internal}/WebDriverMoveToOffsetAction.php | 6 ++- .../Internal}/WebDriverSendKeysAction.php | 7 +++- .../Internal}/WebDriverSingleKeyAction.php | 7 +++- .../Touch}/WebDriverDoubleTapAction.php | 4 +- .../Touch}/WebDriverDownAction.php | 4 +- .../Touch}/WebDriverFlickAction.php | 4 +- .../WebDriverFlickFromElementAction.php | 5 ++- .../Touch}/WebDriverLongPressAction.php | 4 +- .../Touch}/WebDriverMoveAction.php | 4 +- .../Touch}/WebDriverScrollAction.php | 4 +- .../WebDriverScrollFromElementAction.php | 5 ++- .../Touch}/WebDriverTapAction.php | 4 +- .../Touch}/WebDriverTouchAction.php | 5 ++- .../Touch}/WebDriverTouchScreen.php | 4 +- lib/{ => Interactions}/WebDriverActions.php | 15 ++++++- .../WebDriverCompositeAction.php | 4 +- .../WebDriverTouchActions.php | 16 +++++++- lib/Internal/WebDriverLocatable.php | 29 +++++++++++++ lib/{ => Net}/URLChecker.php | 2 +- lib/{ => Remote}/DesiredCapabilities.php | 7 +++- lib/{ => Remote}/DriverCommand.php | 2 +- lib/{ => Remote}/ExecuteMethod.php | 4 +- lib/{ => Remote}/FileDetector.php | 2 +- lib/{ => Remote}/HttpCommandExecutor.php | 7 +++- lib/{ => Remote}/LocalFileDetector.php | 4 +- lib/{ => Remote}/RemoteExecuteMethod.php | 2 +- lib/{ => Remote}/RemoteKeyboard.php | 5 ++- lib/{ => Remote}/RemoteMouse.php | 5 ++- lib/{ => Remote}/RemoteTargetLocator.php | 7 +++- lib/{ => Remote}/RemoteTouchScreen.php | 5 ++- lib/{ => Remote}/RemoteWebDriver.php | 12 +++++- lib/{ => Remote}/RemoteWebElement.php | 9 +++- .../Service}/DriverCommandExecutor.php | 10 ++++- lib/{ => Remote/Service}/DriverService.php | 3 +- lib/{ => Remote}/UselessFileDetector.php | 2 +- lib/{ => Remote}/WebDriverBrowserType.php | 2 +- lib/{ => Remote}/WebDriverCapabilityType.php | 2 +- lib/{ => Remote}/WebDriverCommand.php | 2 +- lib/{ => Remote}/WebDriverResponse.php | 2 +- .../Events}/EventFiringWebDriver.php | 11 ++++- .../EventFiringWebDriverNavigation.php | 4 +- .../Events}/EventFiringWebElement.php | 9 +++- lib/WebDriverAlert.php | 2 + lib/WebDriverCommandExecutor.php | 3 ++ lib/WebDriverDispatcher.php | 2 + lib/WebDriverEventListener.php | 2 + lib/WebDriverExpectedCondition.php | 1 + lib/WebDriverLocatable.php | 27 ------------ lib/WebDriverMouse.php | 2 + lib/WebDriverNavigation.php | 3 ++ lib/WebDriverOptions.php | 3 ++ lib/WebDriverSelect.php | 1 + lib/WebDriverTimeouts.php | 2 + lib/WebDriverUpAction.php | 3 ++ lib/WebDriverWait.php | 6 +++ lib/WebDriverWindow.php | 2 + tests/functional/FileUploadTest.php | 2 + tests/functional/WebDriverTestCase.php | 4 ++ tests/unit/bootstrap.php | 2 +- .../WebDriverButtonReleaseActionTest.php | 7 +++- .../internal/WebDriverClickActionTest.php | 7 +++- .../WebDriverClickAndHoldActionTest.php | 7 +++- .../WebDriverContextClickActionTest.php | 7 +++- .../internal/WebDriverCoordinatesTest.php | 2 + .../WebDriverDoubleClickActionTest.php | 7 +++- .../internal/WebDriverKeyDownActionTest.php | 8 +++- .../internal/WebDriverKeyUpActionTest.php | 8 +++- .../internal/WebDriverMouseMoveActionTest.php | 8 +++- .../WebDriverMouseToOffsetActionTest.php | 8 +++- .../internal/WebDriverSendKeysActionTest.php | 8 +++- 88 files changed, 424 insertions(+), 112 deletions(-) rename lib/{ => Chrome}/ChromeDriver.php (72%) rename lib/{ => Chrome}/ChromeDriverService.php (92%) rename lib/{ => Chrome}/ChromeOptions.php (97%) rename lib/{ => Firefox}/FirefoxDriver.php (94%) rename lib/{ => Firefox}/FirefoxProfile.php (96%) rename lib/{ => Interactions/Internal}/WebDriverButtonReleaseAction.php (90%) rename lib/{ => Interactions/Internal}/WebDriverClickAction.php (89%) rename lib/{ => Interactions/Internal}/WebDriverClickAndHoldAction.php (90%) rename lib/{ => Interactions/Internal}/WebDriverContextClickAction.php (90%) rename lib/{ => Interactions/Internal}/WebDriverCoordinates.php (92%) rename lib/{ => Interactions/Internal}/WebDriverDoubleClickAction.php (89%) rename lib/{ => Interactions/Internal}/WebDriverKeyDownAction.php (89%) rename lib/{ => Interactions/Internal}/WebDriverKeyUpAction.php (89%) rename lib/{ => Interactions/Internal}/WebDriverKeysRelatedAction.php (88%) rename lib/{ => Interactions/Internal}/WebDriverMouseAction.php (85%) rename lib/{ => Interactions/Internal}/WebDriverMouseMoveAction.php (89%) rename lib/{ => Interactions/Internal}/WebDriverMoveToOffsetAction.php (87%) rename lib/{ => Interactions/Internal}/WebDriverSendKeysAction.php (84%) rename lib/{ => Interactions/Internal}/WebDriverSingleKeyAction.php (81%) rename lib/{ => Interactions/Touch}/WebDriverDoubleTapAction.php (90%) rename lib/{ => Interactions/Touch}/WebDriverDownAction.php (92%) rename lib/{ => Interactions/Touch}/WebDriverFlickAction.php (92%) rename lib/{ => Interactions/Touch}/WebDriverFlickFromElementAction.php (91%) rename lib/{ => Interactions/Touch}/WebDriverLongPressAction.php (90%) rename lib/{ => Interactions/Touch}/WebDriverMoveAction.php (92%) rename lib/{ => Interactions/Touch}/WebDriverScrollAction.php (92%) rename lib/{ => Interactions/Touch}/WebDriverScrollFromElementAction.php (90%) rename lib/{ => Interactions/Touch}/WebDriverTapAction.php (89%) rename lib/{ => Interactions/Touch}/WebDriverTouchAction.php (89%) rename lib/{ => Interactions/Touch}/WebDriverTouchScreen.php (97%) rename lib/{ => Interactions}/WebDriverActions.php (88%) rename lib/{ => Interactions}/WebDriverCompositeAction.php (94%) rename lib/{ => Interactions}/WebDriverTouchActions.php (81%) create mode 100644 lib/Internal/WebDriverLocatable.php rename lib/{ => Net}/URLChecker.php (98%) rename lib/{ => Remote}/DesiredCapabilities.php (96%) rename lib/{ => Remote}/DriverCommand.php (99%) rename lib/{ => Remote}/ExecuteMethod.php (90%) rename lib/{ => Remote}/FileDetector.php (96%) rename lib/{ => Remote}/HttpCommandExecutor.php (99%) rename lib/{ => Remote}/LocalFileDetector.php (91%) rename lib/{ => Remote}/RemoteExecuteMethod.php (96%) rename lib/{ => Remote}/RemoteKeyboard.php (93%) rename lib/{ => Remote}/RemoteMouse.php (95%) rename lib/{ => Remote}/RemoteTargetLocator.php (93%) rename lib/{ => Remote}/RemoteTouchScreen.php (96%) rename lib/{ => Remote}/RemoteWebDriver.php (96%) rename lib/{ => Remote}/RemoteWebElement.php (96%) rename lib/{ => Remote/Service}/DriverCommandExecutor.php (85%) rename lib/{ => Remote/Service}/DriverService.php (97%) rename lib/{ => Remote}/UselessFileDetector.php (95%) rename lib/{ => Remote}/WebDriverBrowserType.php (97%) rename lib/{ => Remote}/WebDriverCapabilityType.php (97%) rename lib/{ => Remote}/WebDriverCommand.php (96%) rename lib/{ => Remote}/WebDriverResponse.php (97%) rename lib/{ => Support/Events}/EventFiringWebDriver.php (95%) rename lib/{ => Support/Events}/EventFiringWebDriverNavigation.php (96%) rename lib/{ => Support/Events}/EventFiringWebElement.php (95%) delete mode 100644 lib/WebDriverLocatable.php diff --git a/example.php b/example.php index b4834146c..556a100a0 100644 --- a/example.php +++ b/example.php @@ -3,6 +3,9 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Remote\DesiredCapabilities; +use Facebook\WebDriver\Remote\RemoteWebDriver; + require_once('vendor/autoload.php'); // start Firefox with 5 second timeout diff --git a/lib/ChromeDriver.php b/lib/Chrome/ChromeDriver.php similarity index 72% rename from lib/ChromeDriver.php rename to lib/Chrome/ChromeDriver.php index 3fb84ad58..67427205d 100644 --- a/lib/ChromeDriver.php +++ b/lib/Chrome/ChromeDriver.php @@ -13,9 +13,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Chrome; +use Facebook\WebDriver\Remote\DesiredCapabilities; +use Facebook\WebDriver\Remote\DriverCommand; +use Facebook\WebDriver\Remote\Service\DriverCommandExecutor; use Facebook\WebDriver\Exception\WebDriverException; +use Facebook\WebDriver\Remote\RemoteWebDriver; +use Facebook\WebDriver\Remote\WebDriverCommand; class ChromeDriver extends RemoteWebDriver { @@ -49,10 +54,14 @@ public function startSession($desired_capabilities) { } /** - * @param string $url The url of the remote server + * Always throws an exception. Use ChromeDriver::start() instead. + * + * @param string $url The url of the remote server * @param DesiredCapabilities $desired_capabilities The desired capabilities - * @param int|null $connection_timeout_in_ms - * @param int|null $request_timeout_in_ms + * @param int|null $timeout_in_ms + * @param int|null $request_timeout_in_ms + * + * @throws WebDriverException */ public static function create( $url = 'http://localhost:4444/wd/hub', @@ -63,6 +72,14 @@ public static function create( throw new WebDriverException('Please use ChromeDriver::start() instead.'); } + /** + * Always throws an exception. Use ChromeDriver::start() instead. + * + * @param string $session_id The existing session id + * @param string $url The url of the remote server + * + * @throws WebDriverException + */ public static function createBySessionID( $session_id, $url = 'http://localhost:4444/wd/hub' diff --git a/lib/ChromeDriverService.php b/lib/Chrome/ChromeDriverService.php similarity index 92% rename from lib/ChromeDriverService.php rename to lib/Chrome/ChromeDriverService.php index 9494bfd1a..d60f376a6 100644 --- a/lib/ChromeDriverService.php +++ b/lib/Chrome/ChromeDriverService.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Chrome; + +use Facebook\WebDriver\Remote\Service\DriverService; class ChromeDriverService extends DriverService { diff --git a/lib/ChromeOptions.php b/lib/Chrome/ChromeOptions.php similarity index 97% rename from lib/ChromeOptions.php rename to lib/Chrome/ChromeOptions.php index eb2f92e8c..5cc125f56 100644 --- a/lib/ChromeOptions.php +++ b/lib/Chrome/ChromeOptions.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Chrome; + +use Facebook\WebDriver\Remote\DesiredCapabilities; /** * The class manages the capabilities in ChromeDriver. diff --git a/lib/Exception/WebDriverException.php b/lib/Exception/WebDriverException.php index af90b7cf7..a23f42103 100644 --- a/lib/Exception/WebDriverException.php +++ b/lib/Exception/WebDriverException.php @@ -42,9 +42,46 @@ public function getResults() { * For $status_code >= 0, they are errors defined in the json wired protocol. * For $status_code < 0, they are errors defined in php-webdriver. * - * @param int $status_code + * @param int $status_code * @param string $message - * @param mixed $results + * @param mixed $results + * + * @throws ElementNotSelectableException + * @throws ElementNotVisibleException + * @throws ExpectedException + * @throws IMEEngineActivationFailedException + * @throws IMENotAvailableException + * @throws IndexOutOfBoundsException + * @throws InvalidCookieDomainException + * @throws InvalidCoordinatesException + * @throws InvalidElementStateException + * @throws InvalidSelectorException + * @throws MoveTargetOutOfBoundsException + * @throws NoAlertOpenException + * @throws NoCollectionException + * @throws NoScriptResultException + * @throws NoStringException + * @throws NoStringLengthException + * @throws NoStringWrapperException + * @throws NoSuchCollectionException + * @throws NoSuchDocumentException + * @throws NoSuchDriverException + * @throws NoSuchElementException + * @throws NoSuchFrameException + * @throws NoSuchWindowException + * @throws NullPointerException + * @throws ScriptTimeoutException + * @throws SessionNotCreatedException + * @throws StaleElementReferenceException + * @throws TimeOutException + * @throws UnableToSetCookieException + * @throws UnexpectedAlertOpenException + * @throws UnexpectedJavascriptException + * @throws UnknownCommandException + * @throws UnknownServerException + * @throws UnrecognizedExceptionException + * @throws WebDriverCurlException + * @throws XPathLookupException */ public static function throwException($status_code, $message, $results) { switch ($status_code) { diff --git a/lib/FirefoxDriver.php b/lib/Firefox/FirefoxDriver.php similarity index 94% rename from lib/FirefoxDriver.php rename to lib/Firefox/FirefoxDriver.php index 019064e71..8afbe0c2d 100644 --- a/lib/FirefoxDriver.php +++ b/lib/Firefox/FirefoxDriver.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Firefox; class FirefoxDriver { diff --git a/lib/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php similarity index 96% rename from lib/FirefoxProfile.php rename to lib/Firefox/FirefoxProfile.php index d72fc06c1..d15d9556e 100644 --- a/lib/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Firefox; use Facebook\WebDriver\Exception\WebDriverException; use RecursiveDirectoryIterator; @@ -127,7 +127,9 @@ private function installExtension($extension, $profile_dir) { /** * @param string $prefix Prefix of the temp directory. + * * @return string The path to the temp directory created. + * @throws WebDriverException */ private function createTempDirectory($prefix = '') { $temp_dir = tempnam('', $prefix); @@ -142,9 +144,11 @@ private function createTempDirectory($prefix = '') { } /** - * @param string $xpi The path to the .xpi extension. + * @param string $xpi The path to the .xpi extension. * @param string $target_dir The path to the unzip directory. + * * @return FirefoxProfile + * @throws \Exception */ private function extractTo($xpi, $target_dir) { $zip = new ZipArchive(); diff --git a/lib/WebDriverButtonReleaseAction.php b/lib/Interactions/Internal/WebDriverButtonReleaseAction.php similarity index 90% rename from lib/WebDriverButtonReleaseAction.php rename to lib/Interactions/Internal/WebDriverButtonReleaseAction.php index 444632265..a63570ae6 100644 --- a/lib/WebDriverButtonReleaseAction.php +++ b/lib/Interactions/Internal/WebDriverButtonReleaseAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverAction; /** * Move to the location and then release the mouse key. diff --git a/lib/WebDriverClickAction.php b/lib/Interactions/Internal/WebDriverClickAction.php similarity index 89% rename from lib/WebDriverClickAction.php rename to lib/Interactions/Internal/WebDriverClickAction.php index cc9263c17..f110d34bd 100644 --- a/lib/WebDriverClickAction.php +++ b/lib/Interactions/Internal/WebDriverClickAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverAction; class WebDriverClickAction extends WebDriverMouseAction diff --git a/lib/WebDriverClickAndHoldAction.php b/lib/Interactions/Internal/WebDriverClickAndHoldAction.php similarity index 90% rename from lib/WebDriverClickAndHoldAction.php rename to lib/Interactions/Internal/WebDriverClickAndHoldAction.php index 6bc8d049b..264d1503f 100644 --- a/lib/WebDriverClickAndHoldAction.php +++ b/lib/Interactions/Internal/WebDriverClickAndHoldAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverAction; /** * Move the the location, click and hold. diff --git a/lib/WebDriverContextClickAction.php b/lib/Interactions/Internal/WebDriverContextClickAction.php similarity index 90% rename from lib/WebDriverContextClickAction.php rename to lib/Interactions/Internal/WebDriverContextClickAction.php index 5e2638dca..d431173e9 100644 --- a/lib/WebDriverContextClickAction.php +++ b/lib/Interactions/Internal/WebDriverContextClickAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverAction; /** * You can call it 'Right Click' if you like. diff --git a/lib/WebDriverCoordinates.php b/lib/Interactions/Internal/WebDriverCoordinates.php similarity index 92% rename from lib/WebDriverCoordinates.php rename to lib/Interactions/Internal/WebDriverCoordinates.php index e43b7fb75..89aae19bb 100644 --- a/lib/WebDriverCoordinates.php +++ b/lib/Interactions/Internal/WebDriverCoordinates.php @@ -13,10 +13,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; use Closure; use Facebook\WebDriver\Exception\UnsupportedOperationException; +use Facebook\WebDriver\WebDriverPoint; /** * Interface representing basic mouse operations. @@ -43,6 +44,7 @@ public function __construct( /** * @return WebDriverPoint + * @throws UnsupportedOperationException */ public function onScreen() { throw new UnsupportedOperationException( diff --git a/lib/WebDriverDoubleClickAction.php b/lib/Interactions/Internal/WebDriverDoubleClickAction.php similarity index 89% rename from lib/WebDriverDoubleClickAction.php rename to lib/Interactions/Internal/WebDriverDoubleClickAction.php index 15c9e422c..218a05b5e 100644 --- a/lib/WebDriverDoubleClickAction.php +++ b/lib/Interactions/Internal/WebDriverDoubleClickAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverAction; class WebDriverDoubleClickAction extends WebDriverMouseAction diff --git a/lib/WebDriverKeyDownAction.php b/lib/Interactions/Internal/WebDriverKeyDownAction.php similarity index 89% rename from lib/WebDriverKeyDownAction.php rename to lib/Interactions/Internal/WebDriverKeyDownAction.php index 5d5aa2afe..29350e484 100644 --- a/lib/WebDriverKeyDownAction.php +++ b/lib/Interactions/Internal/WebDriverKeyDownAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverAction; class WebDriverKeyDownAction extends WebDriverSingleKeyAction diff --git a/lib/WebDriverKeyUpAction.php b/lib/Interactions/Internal/WebDriverKeyUpAction.php similarity index 89% rename from lib/WebDriverKeyUpAction.php rename to lib/Interactions/Internal/WebDriverKeyUpAction.php index d41a5a2d8..9b89747eb 100644 --- a/lib/WebDriverKeyUpAction.php +++ b/lib/Interactions/Internal/WebDriverKeyUpAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverAction; class WebDriverKeyUpAction extends WebDriverSingleKeyAction diff --git a/lib/WebDriverKeysRelatedAction.php b/lib/Interactions/Internal/WebDriverKeysRelatedAction.php similarity index 88% rename from lib/WebDriverKeysRelatedAction.php rename to lib/Interactions/Internal/WebDriverKeysRelatedAction.php index bcd45f7f7..77892cc25 100644 --- a/lib/WebDriverKeysRelatedAction.php +++ b/lib/Interactions/Internal/WebDriverKeysRelatedAction.php @@ -13,7 +13,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverMouse; +use Facebook\WebDriver\WebDriverKeyboard; /** * Base class for all keyboard-related actions. diff --git a/lib/WebDriverMouseAction.php b/lib/Interactions/Internal/WebDriverMouseAction.php similarity index 85% rename from lib/WebDriverMouseAction.php rename to lib/Interactions/Internal/WebDriverMouseAction.php index 8c3c1cb2a..f6a115f43 100644 --- a/lib/WebDriverMouseAction.php +++ b/lib/Interactions/Internal/WebDriverMouseAction.php @@ -13,14 +13,24 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverMouse; +use Facebook\WebDriver\Internal\WebDriverLocatable; /** * Base class for all mouse-related actions. */ class WebDriverMouseAction { + /** + * @var WebDriverMouse + */ protected $mouse; + + /** + * @var WebDriverLocatable + */ protected $locationProvider; public function __construct( diff --git a/lib/WebDriverMouseMoveAction.php b/lib/Interactions/Internal/WebDriverMouseMoveAction.php similarity index 89% rename from lib/WebDriverMouseMoveAction.php rename to lib/Interactions/Internal/WebDriverMouseMoveAction.php index b24948daf..d229904fc 100644 --- a/lib/WebDriverMouseMoveAction.php +++ b/lib/Interactions/Internal/WebDriverMouseMoveAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverAction; class WebDriverMouseMoveAction extends WebDriverMouseAction diff --git a/lib/WebDriverMoveToOffsetAction.php b/lib/Interactions/Internal/WebDriverMoveToOffsetAction.php similarity index 87% rename from lib/WebDriverMoveToOffsetAction.php rename to lib/Interactions/Internal/WebDriverMoveToOffsetAction.php index fe1b0bfc2..f1e0270f8 100644 --- a/lib/WebDriverMoveToOffsetAction.php +++ b/lib/Interactions/Internal/WebDriverMoveToOffsetAction.php @@ -13,7 +13,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverAction; +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverMouse; class WebDriverMoveToOffsetAction extends WebDriverMouseAction diff --git a/lib/WebDriverSendKeysAction.php b/lib/Interactions/Internal/WebDriverSendKeysAction.php similarity index 84% rename from lib/WebDriverSendKeysAction.php rename to lib/Interactions/Internal/WebDriverSendKeysAction.php index 9b371a551..2c9512dd3 100644 --- a/lib/WebDriverSendKeysAction.php +++ b/lib/Interactions/Internal/WebDriverSendKeysAction.php @@ -13,7 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverAction; +use Facebook\WebDriver\WebDriverKeyboard; +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverMouse; class WebDriverSendKeysAction extends WebDriverKeysRelatedAction diff --git a/lib/WebDriverSingleKeyAction.php b/lib/Interactions/Internal/WebDriverSingleKeyAction.php similarity index 81% rename from lib/WebDriverSingleKeyAction.php rename to lib/Interactions/Internal/WebDriverSingleKeyAction.php index a9280afe1..86cd74936 100644 --- a/lib/WebDriverSingleKeyAction.php +++ b/lib/Interactions/Internal/WebDriverSingleKeyAction.php @@ -13,7 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\WebDriverAction; +use Facebook\WebDriver\WebDriverKeyboard; +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverMouse; abstract class WebDriverSingleKeyAction extends WebDriverKeysRelatedAction diff --git a/lib/WebDriverDoubleTapAction.php b/lib/Interactions/Touch/WebDriverDoubleTapAction.php similarity index 90% rename from lib/WebDriverDoubleTapAction.php rename to lib/Interactions/Touch/WebDriverDoubleTapAction.php index c2cc7d381..92ccfa222 100644 --- a/lib/WebDriverDoubleTapAction.php +++ b/lib/Interactions/Touch/WebDriverDoubleTapAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Touch; + +use Facebook\WebDriver\WebDriverAction; class WebDriverDoubleTapAction extends WebDriverTouchAction diff --git a/lib/WebDriverDownAction.php b/lib/Interactions/Touch/WebDriverDownAction.php similarity index 92% rename from lib/WebDriverDownAction.php rename to lib/Interactions/Touch/WebDriverDownAction.php index 67fc73e55..eb946008f 100644 --- a/lib/WebDriverDownAction.php +++ b/lib/Interactions/Touch/WebDriverDownAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Touch; + +use Facebook\WebDriver\WebDriverAction; class WebDriverDownAction extends WebDriverTouchAction diff --git a/lib/WebDriverFlickAction.php b/lib/Interactions/Touch/WebDriverFlickAction.php similarity index 92% rename from lib/WebDriverFlickAction.php rename to lib/Interactions/Touch/WebDriverFlickAction.php index 446340718..575c3eb4d 100644 --- a/lib/WebDriverFlickAction.php +++ b/lib/Interactions/Touch/WebDriverFlickAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Touch; + +use Facebook\WebDriver\WebDriverAction; class WebDriverFlickAction extends WebDriverTouchAction diff --git a/lib/WebDriverFlickFromElementAction.php b/lib/Interactions/Touch/WebDriverFlickFromElementAction.php similarity index 91% rename from lib/WebDriverFlickFromElementAction.php rename to lib/Interactions/Touch/WebDriverFlickFromElementAction.php index 3781d6c0e..afd13ab8c 100644 --- a/lib/WebDriverFlickFromElementAction.php +++ b/lib/Interactions/Touch/WebDriverFlickFromElementAction.php @@ -13,7 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Touch; + +use Facebook\WebDriver\WebDriverAction; +use Facebook\WebDriver\WebDriverElement; class WebDriverFlickFromElementAction extends WebDriverTouchAction diff --git a/lib/WebDriverLongPressAction.php b/lib/Interactions/Touch/WebDriverLongPressAction.php similarity index 90% rename from lib/WebDriverLongPressAction.php rename to lib/Interactions/Touch/WebDriverLongPressAction.php index 5fc2b519e..c46770d86 100644 --- a/lib/WebDriverLongPressAction.php +++ b/lib/Interactions/Touch/WebDriverLongPressAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Touch; + +use Facebook\WebDriver\WebDriverAction; class WebDriverLongPressAction extends WebDriverTouchAction diff --git a/lib/WebDriverMoveAction.php b/lib/Interactions/Touch/WebDriverMoveAction.php similarity index 92% rename from lib/WebDriverMoveAction.php rename to lib/Interactions/Touch/WebDriverMoveAction.php index 32c324de7..330783271 100644 --- a/lib/WebDriverMoveAction.php +++ b/lib/Interactions/Touch/WebDriverMoveAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Touch; + +use Facebook\WebDriver\WebDriverAction; class WebDriverMoveAction extends WebDriverTouchAction diff --git a/lib/WebDriverScrollAction.php b/lib/Interactions/Touch/WebDriverScrollAction.php similarity index 92% rename from lib/WebDriverScrollAction.php rename to lib/Interactions/Touch/WebDriverScrollAction.php index e7e183b31..8dc1f14b7 100644 --- a/lib/WebDriverScrollAction.php +++ b/lib/Interactions/Touch/WebDriverScrollAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Touch; + +use Facebook\WebDriver\WebDriverAction; class WebDriverScrollAction extends WebDriverTouchAction diff --git a/lib/WebDriverScrollFromElementAction.php b/lib/Interactions/Touch/WebDriverScrollFromElementAction.php similarity index 90% rename from lib/WebDriverScrollFromElementAction.php rename to lib/Interactions/Touch/WebDriverScrollFromElementAction.php index 63be82c48..df31f13b0 100644 --- a/lib/WebDriverScrollFromElementAction.php +++ b/lib/Interactions/Touch/WebDriverScrollFromElementAction.php @@ -13,7 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Touch; + +use Facebook\WebDriver\WebDriverAction; +use Facebook\WebDriver\WebDriverElement; class WebDriverScrollFromElementAction extends WebDriverTouchAction diff --git a/lib/WebDriverTapAction.php b/lib/Interactions/Touch/WebDriverTapAction.php similarity index 89% rename from lib/WebDriverTapAction.php rename to lib/Interactions/Touch/WebDriverTapAction.php index 27ef9627f..835acc848 100644 --- a/lib/WebDriverTapAction.php +++ b/lib/Interactions/Touch/WebDriverTapAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Touch; + +use Facebook\WebDriver\WebDriverAction; class WebDriverTapAction extends WebDriverTouchAction diff --git a/lib/WebDriverTouchAction.php b/lib/Interactions/Touch/WebDriverTouchAction.php similarity index 89% rename from lib/WebDriverTouchAction.php rename to lib/Interactions/Touch/WebDriverTouchAction.php index 06ba9fdab..e267f1ab3 100644 --- a/lib/WebDriverTouchAction.php +++ b/lib/Interactions/Touch/WebDriverTouchAction.php @@ -13,7 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Touch; + +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates; /** * Base class for all touch-related actions. diff --git a/lib/WebDriverTouchScreen.php b/lib/Interactions/Touch/WebDriverTouchScreen.php similarity index 97% rename from lib/WebDriverTouchScreen.php rename to lib/Interactions/Touch/WebDriverTouchScreen.php index 46f989013..cb753cd0d 100644 --- a/lib/WebDriverTouchScreen.php +++ b/lib/Interactions/Touch/WebDriverTouchScreen.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions\Touch; + +use Facebook\WebDriver\WebDriverElement; /** * Interface representing touch screen operations. diff --git a/lib/WebDriverActions.php b/lib/Interactions/WebDriverActions.php similarity index 88% rename from lib/WebDriverActions.php rename to lib/Interactions/WebDriverActions.php index 37537e2b9..4d8a623d8 100644 --- a/lib/WebDriverActions.php +++ b/lib/Interactions/WebDriverActions.php @@ -13,7 +13,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions; + +use Facebook\WebDriver\Interactions\Internal\WebDriverClickAndHoldAction; +use Facebook\WebDriver\Interactions\Internal\WebDriverMoveToOffsetAction; +use Facebook\WebDriver\Interactions\Internal\WebDriverButtonReleaseAction; +use Facebook\WebDriver\Interactions\Internal\WebDriverDoubleClickAction; +use Facebook\WebDriver\Interactions\Internal\WebDriverSendKeysAction; +use Facebook\WebDriver\Interactions\Internal\WebDriverClickAction; +use Facebook\WebDriver\Interactions\Internal\WebDriverKeyDownAction; +use Facebook\WebDriver\Interactions\Internal\WebDriverContextClickAction; +use Facebook\WebDriver\Interactions\Internal\WebDriverKeyUpAction; +use Facebook\WebDriver\Interactions\Internal\WebDriverMouseMoveAction; +use Facebook\WebDriver\WebDriverElement; +use Facebook\WebDriver\WebDriver; /** * WebDriver action builder. It implements the builder pattern. diff --git a/lib/WebDriverCompositeAction.php b/lib/Interactions/WebDriverCompositeAction.php similarity index 94% rename from lib/WebDriverCompositeAction.php rename to lib/Interactions/WebDriverCompositeAction.php index de80c787f..63d9863d7 100644 --- a/lib/WebDriverCompositeAction.php +++ b/lib/Interactions/WebDriverCompositeAction.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions; + +use Facebook\WebDriver\WebDriverAction; /** * An action for aggregating actions and triggering all of them afterwards. diff --git a/lib/WebDriverTouchActions.php b/lib/Interactions/WebDriverTouchActions.php similarity index 81% rename from lib/WebDriverTouchActions.php rename to lib/Interactions/WebDriverTouchActions.php index a223f269d..ec77242fc 100644 --- a/lib/WebDriverTouchActions.php +++ b/lib/Interactions/WebDriverTouchActions.php @@ -13,7 +13,21 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Interactions; + +use Facebook\WebDriver\Interactions\Touch\WebDriverTouchScreen; +use Facebook\WebDriver\Interactions\Touch\WebDriverDoubleTapAction; +use Facebook\WebDriver\Interactions\Touch\WebDriverFlickAction; +use Facebook\WebDriver\Interactions\Touch\WebDriverFlickFromElementAction; +use Facebook\WebDriver\Interactions\Touch\WebDriverLongPressAction; +use Facebook\WebDriver\Interactions\Touch\WebDriverTapAction; +use Facebook\WebDriver\Interactions\Touch\WebDriverScrollFromElementAction; +use Facebook\WebDriver\Interactions\Touch\WebDriverDownAction; +use Facebook\WebDriver\Interactions\Touch\WebDriverMoveAction; +use Facebook\WebDriver\Interactions\Touch\WebDriverScrollAction; +use Facebook\WebDriver\WebDriverUpAction; +use Facebook\WebDriver\WebDriverElement; +use Facebook\WebDriver\WebDriver; /** * WebDriver action builder for touch events diff --git a/lib/Internal/WebDriverLocatable.php b/lib/Internal/WebDriverLocatable.php new file mode 100644 index 000000000..1523c35c0 --- /dev/null +++ b/lib/Internal/WebDriverLocatable.php @@ -0,0 +1,29 @@ +getName()])) { diff --git a/lib/LocalFileDetector.php b/lib/Remote/LocalFileDetector.php similarity index 91% rename from lib/LocalFileDetector.php rename to lib/Remote/LocalFileDetector.php index a9a7488ce..c6d44f78c 100644 --- a/lib/LocalFileDetector.php +++ b/lib/Remote/LocalFileDetector.php @@ -13,7 +13,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; + +use Facebook\WebDriver\Remote\FileDetector; class LocalFileDetector implements FileDetector { /** diff --git a/lib/RemoteExecuteMethod.php b/lib/Remote/RemoteExecuteMethod.php similarity index 96% rename from lib/RemoteExecuteMethod.php rename to lib/Remote/RemoteExecuteMethod.php index 3ab0a60ae..e0ded1032 100644 --- a/lib/RemoteExecuteMethod.php +++ b/lib/Remote/RemoteExecuteMethod.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; class RemoteExecuteMethod implements ExecuteMethod { diff --git a/lib/RemoteKeyboard.php b/lib/Remote/RemoteKeyboard.php similarity index 93% rename from lib/RemoteKeyboard.php rename to lib/Remote/RemoteKeyboard.php index d7d3ebbdb..2b297d1d9 100644 --- a/lib/RemoteKeyboard.php +++ b/lib/Remote/RemoteKeyboard.php @@ -13,7 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; + +use Facebook\WebDriver\WebDriverKeys; +use Facebook\WebDriver\WebDriverKeyboard; /** * Execute keyboard commands for RemoteWebDriver. diff --git a/lib/RemoteMouse.php b/lib/Remote/RemoteMouse.php similarity index 95% rename from lib/RemoteMouse.php rename to lib/Remote/RemoteMouse.php index deb2164fd..c2e0d2263 100644 --- a/lib/RemoteMouse.php +++ b/lib/Remote/RemoteMouse.php @@ -13,7 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; + +use Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates; +use Facebook\WebDriver\WebDriverMouse; /** * Execute mouse commands for RemoteWebDriver. diff --git a/lib/RemoteTargetLocator.php b/lib/Remote/RemoteTargetLocator.php similarity index 93% rename from lib/RemoteTargetLocator.php rename to lib/Remote/RemoteTargetLocator.php index c33bd2c71..e2f5a0aea 100644 --- a/lib/RemoteTargetLocator.php +++ b/lib/Remote/RemoteTargetLocator.php @@ -13,7 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; + +use Facebook\WebDriver\WebDriverTargetLocator; +use Facebook\WebDriver\WebDriverElement; +use Facebook\WebDriver\WebDriverAlert; +use Facebook\WebDriver\WebDriver; /** * Used to locate a given frame or window for RemoteWebDriver. diff --git a/lib/RemoteTouchScreen.php b/lib/Remote/RemoteTouchScreen.php similarity index 96% rename from lib/RemoteTouchScreen.php rename to lib/Remote/RemoteTouchScreen.php index 3ca3c19bd..7929d5db3 100644 --- a/lib/RemoteTouchScreen.php +++ b/lib/Remote/RemoteTouchScreen.php @@ -13,7 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; + +use Facebook\WebDriver\Interactions\Touch\WebDriverTouchScreen; +use Facebook\WebDriver\WebDriverElement; /** * Execute touch commands for RemoteWebDriver. diff --git a/lib/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php similarity index 96% rename from lib/RemoteWebDriver.php rename to lib/Remote/RemoteWebDriver.php index 86d9e0d8b..4f3be385e 100644 --- a/lib/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -13,7 +13,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; + +use Facebook\WebDriver\Interactions\WebDriverActions; +use Facebook\WebDriver\JavaScriptExecutor; +use Facebook\WebDriver\WebDriver; +use Facebook\WebDriver\WebDriverBy; +use Facebook\WebDriver\WebDriverCommandExecutor; +use Facebook\WebDriver\WebDriverElement; +use Facebook\WebDriver\WebDriverNavigation; +use Facebook\WebDriver\WebDriverOptions; +use Facebook\WebDriver\WebDriverWait; class RemoteWebDriver implements WebDriver, JavaScriptExecutor { /** diff --git a/lib/RemoteWebElement.php b/lib/Remote/RemoteWebElement.php similarity index 96% rename from lib/RemoteWebElement.php rename to lib/Remote/RemoteWebElement.php index 98d6cca07..53fc1e908 100644 --- a/lib/RemoteWebElement.php +++ b/lib/Remote/RemoteWebElement.php @@ -13,9 +13,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; use Facebook\WebDriver\Exception\WebDriverException; +use Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates; +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverBy; +use Facebook\WebDriver\WebDriverDimension; +use Facebook\WebDriver\WebDriverElement; +use Facebook\WebDriver\WebDriverKeys; +use Facebook\WebDriver\WebDriverPoint; use ZipArchive; /** diff --git a/lib/DriverCommandExecutor.php b/lib/Remote/Service/DriverCommandExecutor.php similarity index 85% rename from lib/DriverCommandExecutor.php rename to lib/Remote/Service/DriverCommandExecutor.php index 228f21b4d..f4857e933 100644 --- a/lib/DriverCommandExecutor.php +++ b/lib/Remote/Service/DriverCommandExecutor.php @@ -13,8 +13,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote\Service; + use Facebook\WebDriver\Exception\WebDriverException; +use Facebook\WebDriver\Remote\DriverCommand; +use Facebook\WebDriver\Remote\HttpCommandExecutor; +use Facebook\WebDriver\Remote\WebDriverCommand; /** * A HttpCommandExecutor that talks to a local driver service instead of @@ -34,9 +38,11 @@ public function __construct(DriverService $service) { /** * @param WebDriverCommand $command - * @param array $curl_opts + * @param array $curl_opts * * @return mixed + * @throws WebDriverException + * @throws \Exception */ public function execute(WebDriverCommand $command, $curl_opts = array()) { if ($command->getName() === DriverCommand::NEW_SESSION) { diff --git a/lib/DriverService.php b/lib/Remote/Service/DriverService.php similarity index 97% rename from lib/DriverService.php rename to lib/Remote/Service/DriverService.php index 77384b9d0..09ad7c815 100644 --- a/lib/DriverService.php +++ b/lib/Remote/Service/DriverService.php @@ -13,9 +13,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote\Service; use Exception; +use Facebook\WebDriver\Net\URLChecker; class DriverService { diff --git a/lib/UselessFileDetector.php b/lib/Remote/UselessFileDetector.php similarity index 95% rename from lib/UselessFileDetector.php rename to lib/Remote/UselessFileDetector.php index ce4c55fc9..9a8090038 100644 --- a/lib/UselessFileDetector.php +++ b/lib/Remote/UselessFileDetector.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; class UselessFileDetector implements FileDetector { /** diff --git a/lib/WebDriverBrowserType.php b/lib/Remote/WebDriverBrowserType.php similarity index 97% rename from lib/WebDriverBrowserType.php rename to lib/Remote/WebDriverBrowserType.php index bbb9a529e..5ab1df391 100644 --- a/lib/WebDriverBrowserType.php +++ b/lib/Remote/WebDriverBrowserType.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; /** * All the browsers supported by selenium diff --git a/lib/WebDriverCapabilityType.php b/lib/Remote/WebDriverCapabilityType.php similarity index 97% rename from lib/WebDriverCapabilityType.php rename to lib/Remote/WebDriverCapabilityType.php index 558abb4ab..552db09be 100644 --- a/lib/WebDriverCapabilityType.php +++ b/lib/Remote/WebDriverCapabilityType.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; /** * WebDriverCapabilityType contains all constants defined in the WebDriver diff --git a/lib/WebDriverCommand.php b/lib/Remote/WebDriverCommand.php similarity index 96% rename from lib/WebDriverCommand.php rename to lib/Remote/WebDriverCommand.php index 06660dadf..303af3cfb 100644 --- a/lib/WebDriverCommand.php +++ b/lib/Remote/WebDriverCommand.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; class WebDriverCommand { diff --git a/lib/WebDriverResponse.php b/lib/Remote/WebDriverResponse.php similarity index 97% rename from lib/WebDriverResponse.php rename to lib/Remote/WebDriverResponse.php index a2d4dd244..d3fcdadcb 100644 --- a/lib/WebDriverResponse.php +++ b/lib/Remote/WebDriverResponse.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Remote; class WebDriverResponse { diff --git a/lib/EventFiringWebDriver.php b/lib/Support/Events/EventFiringWebDriver.php similarity index 95% rename from lib/EventFiringWebDriver.php rename to lib/Support/Events/EventFiringWebDriver.php index ebd5b9b7c..d21c224c8 100644 --- a/lib/EventFiringWebDriver.php +++ b/lib/Support/Events/EventFiringWebDriver.php @@ -13,10 +13,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Support\Events; use Facebook\WebDriver\Exception\UnsupportedOperationException; use Facebook\WebDriver\Exception\WebDriverException; +use Facebook\WebDriver\Interactions\Touch\WebDriverTouchScreen; +use Facebook\WebDriver\JavaScriptExecutor; +use Facebook\WebDriver\WebDriver; +use Facebook\WebDriver\WebDriverBy; +use Facebook\WebDriver\WebDriverDispatcher; +use Facebook\WebDriver\WebDriverElement; +use Facebook\WebDriver\WebDriverOptions; +use Facebook\WebDriver\WebDriverTargetLocator; +use Facebook\WebDriver\WebDriverWait; class EventFiringWebDriver implements WebDriver, JavaScriptExecutor { diff --git a/lib/EventFiringWebDriverNavigation.php b/lib/Support/Events/EventFiringWebDriverNavigation.php similarity index 96% rename from lib/EventFiringWebDriverNavigation.php rename to lib/Support/Events/EventFiringWebDriverNavigation.php index c3feea060..56341e2c2 100644 --- a/lib/EventFiringWebDriverNavigation.php +++ b/lib/Support/Events/EventFiringWebDriverNavigation.php @@ -13,9 +13,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Support\Events; use Facebook\WebDriver\Exception\WebDriverException; +use Facebook\WebDriver\WebDriverDispatcher; +use Facebook\WebDriver\WebDriverNavigation; class EventFiringWebDriverNavigation { diff --git a/lib/EventFiringWebElement.php b/lib/Support/Events/EventFiringWebElement.php similarity index 95% rename from lib/EventFiringWebElement.php rename to lib/Support/Events/EventFiringWebElement.php index a955c59d6..3084ec1b5 100644 --- a/lib/EventFiringWebElement.php +++ b/lib/Support/Events/EventFiringWebElement.php @@ -13,9 +13,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; +namespace Facebook\WebDriver\Support\Events; use Facebook\WebDriver\Exception\WebDriverException; +use Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates; +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverBy; +use Facebook\WebDriver\WebDriverDimension; +use Facebook\WebDriver\WebDriverDispatcher; +use Facebook\WebDriver\WebDriverElement; +use Facebook\WebDriver\WebDriverPoint; class EventFiringWebElement implements WebDriverElement, WebDriverLocatable { diff --git a/lib/WebDriverAlert.php b/lib/WebDriverAlert.php index 2f92ec4c4..8bef6d846 100644 --- a/lib/WebDriverAlert.php +++ b/lib/WebDriverAlert.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Remote\DriverCommand; + /** * An abstraction allowing the driver to manipulate the javascript alerts */ diff --git a/lib/WebDriverCommandExecutor.php b/lib/WebDriverCommandExecutor.php index 5f99a1d16..d58998f70 100644 --- a/lib/WebDriverCommandExecutor.php +++ b/lib/WebDriverCommandExecutor.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Remote\WebDriverCommand; + /** * Interface for all command executor. */ @@ -22,6 +24,7 @@ interface WebDriverCommandExecutor { /** * @param WebDriverCommand $command + * * @return mixed */ public function execute(WebDriverCommand $command); diff --git a/lib/WebDriverDispatcher.php b/lib/WebDriverDispatcher.php index ae9e5e8f7..c8caea4d9 100644 --- a/lib/WebDriverDispatcher.php +++ b/lib/WebDriverDispatcher.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Support\Events\EventFiringWebDriver; + class WebDriverDispatcher { /** diff --git a/lib/WebDriverEventListener.php b/lib/WebDriverEventListener.php index 4b458f649..afea9c0fd 100644 --- a/lib/WebDriverEventListener.php +++ b/lib/WebDriverEventListener.php @@ -16,6 +16,8 @@ namespace Facebook\WebDriver; use Facebook\WebDriver\Exception\WebDriverException; +use Facebook\WebDriver\Support\Events\EventFiringWebDriver; +use Facebook\WebDriver\Support\Events\EventFiringWebElement; interface WebDriverEventListener { diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index ac1924a31..3de9a9731 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -14,6 +14,7 @@ // limitations under the License. namespace Facebook\WebDriver; + use Facebook\WebDriver\Exception\StaleElementReferenceException; use Facebook\WebDriver\Exception\NoSuchFrameException; use Facebook\WebDriver\Exception\NoSuchElementException; diff --git a/lib/WebDriverLocatable.php b/lib/WebDriverLocatable.php deleted file mode 100644 index bb2aa9035..000000000 --- a/lib/WebDriverLocatable.php +++ /dev/null @@ -1,27 +0,0 @@ -timeout; diff --git a/lib/WebDriverWindow.php b/lib/WebDriverWindow.php index c29deb06c..dcfa19534 100644 --- a/lib/WebDriverWindow.php +++ b/lib/WebDriverWindow.php @@ -14,7 +14,9 @@ // limitations under the License. namespace Facebook\WebDriver; + use Facebook\WebDriver\Exception\IndexOutOfBoundsException; +use Facebook\WebDriver\Remote\DriverCommand; /** * An abstraction allowing the driver to manipulate the browser's window diff --git a/tests/functional/FileUploadTest.php b/tests/functional/FileUploadTest.php index 8e7289973..0ab233a14 100644 --- a/tests/functional/FileUploadTest.php +++ b/tests/functional/FileUploadTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Remote\LocalFileDetector; + /** * An example test case for php-webdriver. * diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index 2c0793815..73b3c2b58 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -15,6 +15,10 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Remote\RemoteWebDriver; +use Facebook\WebDriver\Remote\WebDriverBrowserType; +use Facebook\WebDriver\Remote\WebDriverCapabilityType; + /** * The base class for test cases. */ diff --git a/tests/unit/bootstrap.php b/tests/unit/bootstrap.php index 77ad6b219..db3b0d958 100644 --- a/tests/unit/bootstrap.php +++ b/tests/unit/bootstrap.php @@ -2,4 +2,4 @@ namespace Facebook\WebDriver; -require_once __DIR__ . '/../../lib/__init__.php'; +require_once __DIR__ . '/../../vendor/autoload.php'; diff --git a/tests/unit/interactions/internal/WebDriverButtonReleaseActionTest.php b/tests/unit/interactions/internal/WebDriverButtonReleaseActionTest.php index 645a85963..3a4779855 100644 --- a/tests/unit/interactions/internal/WebDriverButtonReleaseActionTest.php +++ b/tests/unit/interactions/internal/WebDriverButtonReleaseActionTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Internal\WebDriverButtonReleaseAction; + class WebDriverButtonReleaseActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverButtonReleaseAction @@ -26,7 +28,7 @@ class WebDriverButtonReleaseActionTest extends \PHPUnit_Framework_TestCase { public function setUp() { $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); $this->webDriverButtonReleaseAction = new WebDriverButtonReleaseAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +36,8 @@ public function setUp() { } public function testPerformSendsMouseUpCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseUp')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverButtonReleaseAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverClickActionTest.php b/tests/unit/interactions/internal/WebDriverClickActionTest.php index fd1ece96f..07dd8e5c2 100644 --- a/tests/unit/interactions/internal/WebDriverClickActionTest.php +++ b/tests/unit/interactions/internal/WebDriverClickActionTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Internal\WebDriverClickAction; + class WebDriverClickActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverClickAction @@ -26,7 +28,7 @@ class WebDriverClickActionTest extends \PHPUnit_Framework_TestCase { public function setUp() { $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); $this->webDriverClickAction = new WebDriverClickAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +36,8 @@ public function setUp() { } public function testPerformSendsClickCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverClickAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php b/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php index bf9a4cdea..7bcefd0d5 100644 --- a/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php +++ b/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Internal\WebDriverClickAndHoldAction; + class WebDriverClickAndHoldActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverClickAndHoldAction @@ -26,7 +28,7 @@ class WebDriverClickAndHoldActionTest extends \PHPUnit_Framework_TestCase { public function setUp() { $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); $this->webDriverClickAndHoldAction = new WebDriverClickAndHoldAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +36,8 @@ public function setUp() { } public function testPerformSendsMouseDownCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseDown')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverClickAndHoldAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverContextClickActionTest.php b/tests/unit/interactions/internal/WebDriverContextClickActionTest.php index 2ca80a538..b85a1d7db 100644 --- a/tests/unit/interactions/internal/WebDriverContextClickActionTest.php +++ b/tests/unit/interactions/internal/WebDriverContextClickActionTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Internal\WebDriverContextClickAction; + class WebDriverContextClickActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverContextClickAction @@ -26,7 +28,7 @@ class WebDriverContextClickActionTest extends \PHPUnit_Framework_TestCase { public function setUp() { $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); $this->webDriverContextClickAction = new WebDriverContextClickAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +36,8 @@ public function setUp() { } public function testPerformSendsContextClickCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('contextClick')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverContextClickAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverCoordinatesTest.php b/tests/unit/interactions/internal/WebDriverCoordinatesTest.php index a7fa52549..6002c58bd 100644 --- a/tests/unit/interactions/internal/WebDriverCoordinatesTest.php +++ b/tests/unit/interactions/internal/WebDriverCoordinatesTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates; + class WebDriverCoordinatesTest extends \PHPUnit_Framework_TestCase { public function testConstruct() { $in_view_port = function() { }; diff --git a/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php b/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php index bae50645d..958c2e3cf 100644 --- a/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php +++ b/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Internal\WebDriverDoubleClickAction; + class WebDriverDoubleClickActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverDoubleClickAction @@ -26,7 +28,7 @@ class WebDriverDoubleClickActionTest extends \PHPUnit_Framework_TestCase { public function setUp() { $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); $this->webDriverDoubleClickAction = new WebDriverDoubleClickAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +36,8 @@ public function setUp() { } public function testPerformSendsDoubleClickCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('doubleClick')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverDoubleClickAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php b/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php index af9ce8e0e..2f0ddf593 100644 --- a/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php +++ b/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Internal\WebDriverKeyDownAction; + class WebDriverKeyDownActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverKeyDownAction @@ -28,7 +30,8 @@ class WebDriverKeyDownActionTest extends \PHPUnit_Framework_TestCase { public function setUp() { $this->webDriverKeyboard = $this->getMock('Facebook\WebDriver\WebDriverKeyboard'); $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); + $this->webDriverKeyDownAction = new WebDriverKeyDownAction( $this->webDriverKeyboard, $this->webDriverMouse, @@ -37,7 +40,8 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverKeyboard->expects($this->once())->method('pressKey'); diff --git a/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php b/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php index 98d4cf27d..51c3a9548 100644 --- a/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php +++ b/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Internal\WebDriverKeyUpAction; + class WebDriverKeyUpActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverKeyUpAction @@ -28,7 +30,8 @@ class WebDriverKeyUpActionTest extends \PHPUnit_Framework_TestCase { public function setUp() { $this->webDriverKeyboard = $this->getMock('Facebook\WebDriver\WebDriverKeyboard'); $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); + $this->webDriverKeyUpAction = new WebDriverKeyUpAction( $this->webDriverKeyboard, $this->webDriverMouse, @@ -38,7 +41,8 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverKeyboard->expects($this->once())->method('releaseKey')->with('a'); diff --git a/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php b/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php index bbd306640..1b8f89f78 100644 --- a/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php +++ b/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Internal\WebDriverMouseMoveAction; + class WebDriverMouseMoveActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverMouseMoveAction @@ -26,7 +28,8 @@ class WebDriverMouseMoveActionTest extends \PHPUnit_Framework_TestCase { public function setUp() { $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); + $this->webDriverMouseMoveAction = new WebDriverMouseMoveAction( $this->webDriverMouse, $this->locationProvider @@ -34,7 +37,8 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseMove')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverMouseMoveAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php b/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php index 3fbc3b130..cca46496d 100644 --- a/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php +++ b/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Internal\WebDriverMoveToOffsetAction; + class WebDriverMouseToOffsetActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverMoveToOffsetAction @@ -26,7 +28,8 @@ class WebDriverMouseToOffsetActionTest extends \PHPUnit_Framework_TestCase { public function setUp() { $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); + $this->webDriverMoveToOffsetAction = new WebDriverMoveToOffsetAction( $this->webDriverMouse, $this->locationProvider, @@ -36,7 +39,8 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseMove')->with($coords, 150, 200); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); $this->webDriverMoveToOffsetAction->perform(); diff --git a/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php b/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php index 77fd71587..e5782b9c3 100644 --- a/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php +++ b/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Internal\WebDriverSendKeysAction; + class WebDriverSendKeysActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverSendKeysAction @@ -29,7 +31,8 @@ class WebDriverSendKeysActionTest extends \PHPUnit_Framework_TestCase { public function setUp() { $this->webDriverKeyboard = $this->getMock('Facebook\WebDriver\WebDriverKeyboard'); $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\WebDriverLocatable'); + $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); + $this->keys = array('t', 'e', 's', 't'); $this->webDriverSendKeysAction = new WebDriverSendKeysAction( $this->webDriverKeyboard, @@ -40,7 +43,8 @@ public function setUp() { } public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\WebDriverCoordinates')->disableOriginalConstructor()->getMock(); + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); $this->webDriverKeyboard->expects($this->once())->method('sendKeys')->with($this->keys); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); From 647442075fb9395b61b8ba3d52369d9b351340f4 Mon Sep 17 00:00:00 2001 From: 0x20h Date: Tue, 19 May 2015 23:26:21 +0200 Subject: [PATCH 158/784] test setup - moved phpunit to project directory and renamed to standard .dist - removed namespace from bootstrap.php - removed unnecessary bootstrap/phpunit config from tests/unit - moved tests/unit files --- .travis.yml | 15 ++++++++++- README.md | 10 +++----- composer.json | 13 +++++++--- tests/unit/phpunit.xml => phpunit.xml.dist | 10 +++++--- tests/bootstrap.php | 4 --- tests/phpunit.xml | 25 ------------------- .../WebDriverButtonReleaseActionTest.php | 0 .../WebDriverClickActionTest.php | 0 .../WebDriverClickAndHoldActionTest.php | 0 .../WebDriverContextClickActionTest.php | 0 .../WebDriverCoordinatesTest.php | 0 .../WebDriverDoubleClickActionTest.php | 0 .../WebDriverKeyDownActionTest.php | 0 .../WebDriverKeyUpActionTest.php | 0 .../WebDriverMouseMoveActionTest.php | 0 .../WebDriverMouseToOffsetActionTest.php | 0 .../WebDriverSendKeysActionTest.php | 0 tests/unit/bootstrap.php | 5 ---- 18 files changed, 34 insertions(+), 48 deletions(-) rename tests/unit/phpunit.xml => phpunit.xml.dist (69%) delete mode 100644 tests/phpunit.xml rename tests/unit/{interactions/internal => }/WebDriverButtonReleaseActionTest.php (100%) rename tests/unit/{interactions/internal => }/WebDriverClickActionTest.php (100%) rename tests/unit/{interactions/internal => }/WebDriverClickAndHoldActionTest.php (100%) rename tests/unit/{interactions/internal => }/WebDriverContextClickActionTest.php (100%) rename tests/unit/{interactions/internal => }/WebDriverCoordinatesTest.php (100%) rename tests/unit/{interactions/internal => }/WebDriverDoubleClickActionTest.php (100%) rename tests/unit/{interactions/internal => }/WebDriverKeyDownActionTest.php (100%) rename tests/unit/{interactions/internal => }/WebDriverKeyUpActionTest.php (100%) rename tests/unit/{interactions/internal => }/WebDriverMouseMoveActionTest.php (100%) rename tests/unit/{interactions/internal => }/WebDriverMouseToOffsetActionTest.php (100%) rename tests/unit/{interactions/internal => }/WebDriverSendKeysActionTest.php (100%) delete mode 100644 tests/unit/bootstrap.php diff --git a/.travis.yml b/.travis.yml index 1342b9d4b..8b74804b4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,21 @@ language: php + php: - 5.3 - 5.4 - 5.5 - hhvm -script: phpunit -c ./tests/unit +before_script: + - composer self-update + - composer install --no-interaction --prefer-source + - export DISPLAY=:99.0 + - sh -e /etc/init.d/xvfb start + - wget -q -t 3 http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar + - java -jar selenium-server-standalone-2.45.0.jar -log selenium.log & + - sleep 3 + +script: ./vendor/bin/phpunit + +after_script: + - cat selenium.log diff --git a/README.md b/README.md index 657d6ad73..d5272c4f4 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ php-webdriver -- WebDriver bindings for PHP =========================================== -Attention! This is a fork of facebook/webdriver and has been altered to include namespacing to avoid naming collisions. - ## DESCRIPTION This WebDriver client aims to be as close as possible to bindings in other languages. The concepts are very similar to the Java, .NET, Python and Ruby bindings for WebDriver. @@ -19,11 +17,11 @@ Any complaint, question, idea? You can post it on the user group https://www.fac git clone git@github.com:facebook/php-webdriver.git ### Packagist -Add the dependency. https://packagist.org/packages/janoszen/webdriver +Add the dependency. https://packagist.org/packages/facebook/webdriver { "require": { - "janoszen/webdriver": "dev-master" + "facebook/webdriver": "dev-master" } } @@ -100,8 +98,8 @@ If you're reading this you've already found our Github repository. If you have a We love to have your help to make php-webdriver better. Feel free to -* open an [issue](https://github.com/janoszen/php-webdriver/issues) if you run into any problem. -* fork the project and submit [pull request](https://github.com/janoszen/php-webdriver/pulls). Before the pull requests can be accepted, a [Contributors Licensing Agreement](http://developers.facebook.com/opensource/cla) must be signed. +* open an [issue](https://github.com/facebook/php-webdriver/issues) if you run into any problem. +* fork the project and submit [pull request](https://github.com/facebook/php-webdriver/pulls). Before the pull requests can be accepted, a [Contributors Licensing Agreement](http://developers.facebook.com/opensource/cla) must be signed. When you are going to contribute, please keep in mind that this webdriver client aims to be as close as possible to other languages Java/Ruby/Python/C#. FYI, here is the overview of [the official Java API](http://selenium.googlecode.com/svn/trunk/docs/api/java/index.html?overview-summary.html) diff --git a/composer.json b/composer.json index 7b57541f4..53e36c14d 100644 --- a/composer.json +++ b/composer.json @@ -1,19 +1,22 @@ { "name": "facebook/webdriver", "description": "A php client for WebDriver", - "keywords": ["webdriver", "selenium", "php"], + "keywords": ["webdriver", "selenium", "php", "facebook"], "homepage": "https://github.com/facebook/php-webdriver", "type": "library", "license": "Apache-2.0", "support": { "issues": "https://github.com/facebook/php-webdriver/issues", + "forum": "https://www.facebook.com/groups/phpwebdriver/", "source": "https://github.com/facebook/php-webdriver" }, "require": { "php": ">=5.3.19" }, "require-dev": { - "phpunit/phpunit": "3.7.*", + "phpunit/phpunit": "3.7.*" + }, + "suggest": { "phpdocumentor/phpdocumentor": "2.*" }, "autoload": { @@ -21,5 +24,9 @@ "Facebook\\WebDriver\\": "lib/" } }, - "minimum-stability": "dev" + "autoload-dev": { + "psr-4": { + "Facebook\\WebDriver\\": "tests/functional" + } + } } diff --git a/tests/unit/phpunit.xml b/phpunit.xml.dist similarity index 69% rename from tests/unit/phpunit.xml rename to phpunit.xml.dist index 0338c9327..4dfdec0a7 100644 --- a/tests/unit/phpunit.xml +++ b/phpunit.xml.dist @@ -11,12 +11,14 @@ processIsolation = "false" stopOnFailure = "false" syntaxCheck = "false" - bootstrap = "bootstrap.php" > + bootstrap = "tests/bootstrap.php" > - - ../unit + + tests/unit + + + tests/functional/ - diff --git a/tests/bootstrap.php b/tests/bootstrap.php index c12f2a118..f9e62ac66 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,6 +1,2 @@ - - - - - - - ./unit - - - ./functional - - - - diff --git a/tests/unit/interactions/internal/WebDriverButtonReleaseActionTest.php b/tests/unit/WebDriverButtonReleaseActionTest.php similarity index 100% rename from tests/unit/interactions/internal/WebDriverButtonReleaseActionTest.php rename to tests/unit/WebDriverButtonReleaseActionTest.php diff --git a/tests/unit/interactions/internal/WebDriverClickActionTest.php b/tests/unit/WebDriverClickActionTest.php similarity index 100% rename from tests/unit/interactions/internal/WebDriverClickActionTest.php rename to tests/unit/WebDriverClickActionTest.php diff --git a/tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php b/tests/unit/WebDriverClickAndHoldActionTest.php similarity index 100% rename from tests/unit/interactions/internal/WebDriverClickAndHoldActionTest.php rename to tests/unit/WebDriverClickAndHoldActionTest.php diff --git a/tests/unit/interactions/internal/WebDriverContextClickActionTest.php b/tests/unit/WebDriverContextClickActionTest.php similarity index 100% rename from tests/unit/interactions/internal/WebDriverContextClickActionTest.php rename to tests/unit/WebDriverContextClickActionTest.php diff --git a/tests/unit/interactions/internal/WebDriverCoordinatesTest.php b/tests/unit/WebDriverCoordinatesTest.php similarity index 100% rename from tests/unit/interactions/internal/WebDriverCoordinatesTest.php rename to tests/unit/WebDriverCoordinatesTest.php diff --git a/tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php b/tests/unit/WebDriverDoubleClickActionTest.php similarity index 100% rename from tests/unit/interactions/internal/WebDriverDoubleClickActionTest.php rename to tests/unit/WebDriverDoubleClickActionTest.php diff --git a/tests/unit/interactions/internal/WebDriverKeyDownActionTest.php b/tests/unit/WebDriverKeyDownActionTest.php similarity index 100% rename from tests/unit/interactions/internal/WebDriverKeyDownActionTest.php rename to tests/unit/WebDriverKeyDownActionTest.php diff --git a/tests/unit/interactions/internal/WebDriverKeyUpActionTest.php b/tests/unit/WebDriverKeyUpActionTest.php similarity index 100% rename from tests/unit/interactions/internal/WebDriverKeyUpActionTest.php rename to tests/unit/WebDriverKeyUpActionTest.php diff --git a/tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php b/tests/unit/WebDriverMouseMoveActionTest.php similarity index 100% rename from tests/unit/interactions/internal/WebDriverMouseMoveActionTest.php rename to tests/unit/WebDriverMouseMoveActionTest.php diff --git a/tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php b/tests/unit/WebDriverMouseToOffsetActionTest.php similarity index 100% rename from tests/unit/interactions/internal/WebDriverMouseToOffsetActionTest.php rename to tests/unit/WebDriverMouseToOffsetActionTest.php diff --git a/tests/unit/interactions/internal/WebDriverSendKeysActionTest.php b/tests/unit/WebDriverSendKeysActionTest.php similarity index 100% rename from tests/unit/interactions/internal/WebDriverSendKeysActionTest.php rename to tests/unit/WebDriverSendKeysActionTest.php diff --git a/tests/unit/bootstrap.php b/tests/unit/bootstrap.php deleted file mode 100644 index db3b0d958..000000000 --- a/tests/unit/bootstrap.php +++ /dev/null @@ -1,5 +0,0 @@ - Date: Wed, 20 May 2015 00:22:27 +0200 Subject: [PATCH 159/784] Changed code formating for composer.json --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 53e36c14d..486f17678 100644 --- a/composer.json +++ b/composer.json @@ -21,8 +21,8 @@ }, "autoload": { "psr-4": { - "Facebook\\WebDriver\\": "lib/" - } + "Facebook\\WebDriver\\": "lib/" + } }, "autoload-dev": { "psr-4": { From 2e80326a1ccf093cf2ddbdb43287917d0206b528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 20 May 2015 02:02:10 +0200 Subject: [PATCH 160/784] Upgrade PHPUnit to latest 4.6 --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 486f17678..8d4095415 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "facebook/webdriver", - "description": "A php client for WebDriver", + "description": "A PHP client for WebDriver", "keywords": ["webdriver", "selenium", "php", "facebook"], "homepage": "https://github.com/facebook/php-webdriver", "type": "library", @@ -14,7 +14,7 @@ "php": ">=5.3.19" }, "require-dev": { - "phpunit/phpunit": "3.7.*" + "phpunit/phpunit": "4.6.*" }, "suggest": { "phpdocumentor/phpdocumentor": "2.*" From 617d041962a2e31997f3b8535e8b7d39cd96ea13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 20 May 2015 02:02:46 +0200 Subject: [PATCH 161/784] Run tests on PHP 5.6 and PHP 7 --- .travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8b74804b4..a54d35732 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,11 +4,15 @@ php: - 5.3 - 5.4 - 5.5 + - 5.6 + - 7 - hhvm -before_script: +install: - composer self-update - composer install --no-interaction --prefer-source + +before_script: - export DISPLAY=:99.0 - sh -e /etc/init.d/xvfb start - wget -q -t 3 http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar From dabaf2c24cad52c86f2bca787d7b7fab68e00ace Mon Sep 17 00:00:00 2001 From: 0x20h Date: Fri, 22 May 2015 21:59:45 +0200 Subject: [PATCH 162/784] Fix flaky build. Just wait until we can connect to the server, then start the tests. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a54d35732..e973cacd3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ before_script: - sh -e /etc/init.d/xvfb start - wget -q -t 3 http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar - java -jar selenium-server-standalone-2.45.0.jar -log selenium.log & - - sleep 3 + - until $(echo | nc localhost 4444); do sleep 1; echo waiting for selenium-server...; done; script: ./vendor/bin/phpunit From 7ea23b83df640ab93a25d12476480852add5fb9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Mo=CC=88ller?= Date: Tue, 7 Jul 2015 00:17:55 -0400 Subject: [PATCH 163/784] Fix: Update Composer binary in before_install section --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e973cacd3..738b38f8b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,8 +8,10 @@ php: - 7 - hhvm -install: +before_install: - composer self-update + +install: - composer install --no-interaction --prefer-source before_script: From 0b2754b1620689b3041d2bced77cd2e8eaffcc45 Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Wed, 8 Jul 2015 14:18:06 -0700 Subject: [PATCH 164/784] Updated composer require --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d5272c4f4..bda69e9a3 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Add the dependency. https://packagist.org/packages/facebook/webdriver { "require": { - "facebook/webdriver": "dev-master" + "facebook/webdriver": "~1.0" } } From 63480bac5287c0faa63a792c2ad5e427c0fb07e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Mo=CC=88ller?= Date: Tue, 7 Jul 2015 00:21:28 -0400 Subject: [PATCH 165/784] Enhancement: Cache dependencies installed with Composer between builds --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 738b38f8b..5c40b8b93 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,10 @@ php: - 7 - hhvm +cache: + directories: + - $HOME/.composer/cache + before_install: - composer self-update From 64177ae824c73b14a82b9df7e93f260c2fd1fb01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Mo=CC=88ller?= Date: Tue, 7 Jul 2015 00:23:28 -0400 Subject: [PATCH 166/784] Enhancement: Direct builds to container-based infrastructure --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 5c40b8b93..d3e71c8a3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,7 @@ language: php +sudo: false + php: - 5.3 - 5.4 From 691bb162a6cd833936f32d14d9f273c146ada0b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Mo=CC=88ller?= Date: Tue, 7 Jul 2015 00:25:33 -0400 Subject: [PATCH 167/784] Enhancement: Specify environment variable in env section --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d3e71c8a3..20d852e96 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,10 @@ php: - 7 - hhvm +env: + global: + - DISPLAY=:99.0 + cache: directories: - $HOME/.composer/cache @@ -21,7 +25,6 @@ install: - composer install --no-interaction --prefer-source before_script: - - export DISPLAY=:99.0 - sh -e /etc/init.d/xvfb start - wget -q -t 3 http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar - java -jar selenium-server-standalone-2.45.0.jar -log selenium.log & From 1201e6693eeddf2a7c1e88aef60ee8600c91dbb4 Mon Sep 17 00:00:00 2001 From: Jenna Quindica Date: Wed, 15 Jul 2015 16:30:23 -0700 Subject: [PATCH 168/784] Added http proxy and port vars to support tests running on a remote server that's behind a proxy --- lib/Remote/HttpCommandExecutor.php | 11 ++++++++++- lib/Remote/RemoteWebDriver.php | 8 ++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/lib/Remote/HttpCommandExecutor.php b/lib/Remote/HttpCommandExecutor.php index 7ad9092f8..ebd47357e 100644 --- a/lib/Remote/HttpCommandExecutor.php +++ b/lib/Remote/HttpCommandExecutor.php @@ -117,11 +117,20 @@ class HttpCommandExecutor implements WebDriverCommandExecutor { /** * @param string $url + * @param string|null $http_proxy + * @param int|null $http_proxy_port */ - public function __construct($url) { + public function __construct($url, $http_proxy = null, $http_proxy_port = null) { $this->url = $url; $this->curl = curl_init(); + if (!empty($http_proxy)) { + curl_setopt($this->curl, CURLOPT_PROXY, $http_proxy); + if (!empty($http_proxy_port)) { + curl_setopt($this->curl, CURLOPT_PROXYPORT, $http_proxy_port); + } + } + // Get credentials from $url (if any) $matches = null; if (preg_match("/^(https?:\/\/)(.*):(.*)@(.*?)/U", $url, $matches)) { diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index 4f3be385e..9d8a6a76a 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -60,13 +60,17 @@ protected function __construct() {} * @param DesiredCapabilities|array $desired_capabilities The desired capabilities * @param int|null $connection_timeout_in_ms * @param int|null $request_timeout_in_ms + * @param string|null $http_proxy The proxy to tunnel requests through + * @param int|null $http_proxy_port * @return RemoteWebDriver */ public static function create( $url = 'http://localhost:4444/wd/hub', $desired_capabilities = null, $connection_timeout_in_ms = null, - $request_timeout_in_ms = null + $request_timeout_in_ms = null, + $http_proxy = null, + $http_proxy_port = null ) { $url = preg_replace('#/+$#', '', $url); @@ -76,7 +80,7 @@ public static function create( $desired_capabilities = $desired_capabilities->toArray(); } - $executor = new HttpCommandExecutor($url); + $executor = new HttpCommandExecutor($url, $http_proxy, $http_proxy_port); if ($connection_timeout_in_ms !== null) { $executor->setConnectionTimeout($connection_timeout_in_ms); } From 2223ea5df8c1f806ee0088f8e0c34bd7e7ac4bcc Mon Sep 17 00:00:00 2001 From: Jeroen Versteeg Date: Thu, 16 Jul 2015 14:07:58 +0200 Subject: [PATCH 169/784] improved some @return type docs --- lib/WebDriverSearchContext.php | 2 +- lib/WebDriverSelect.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/WebDriverSearchContext.php b/lib/WebDriverSearchContext.php index 07f7bbccc..d9cff1038 100644 --- a/lib/WebDriverSearchContext.php +++ b/lib/WebDriverSearchContext.php @@ -36,7 +36,7 @@ public function findElement(WebDriverBy $locator); * Find all WebDriverElements within this element using the given mechanism. * * @param WebDriverBy $locator - * @return array A list of all WebDriverElements, or an empty array if + * @return WebDriverElement[] A list of all WebDriverElements, or an empty array if * nothing matches * @see WebDriverBy */ diff --git a/lib/WebDriverSelect.php b/lib/WebDriverSelect.php index 80e434caa..cc09a1ac6 100644 --- a/lib/WebDriverSelect.php +++ b/lib/WebDriverSelect.php @@ -48,14 +48,14 @@ public function isMultiple() { } /** - * @return array All options belonging to this select tag. + * @return WebDriverElement[] All options belonging to this select tag. */ public function getOptions() { return $this->element->findElements(WebDriverBy::tagName('option')); } /** - * @return array All selected options belonging to this select tag. + * @return WebDriverElement[] All selected options belonging to this select tag. */ public function getAllSelectedOptions() { $selected_options = array(); From 252e5ac7403b3686dd10a27ac563858bd1f37ba9 Mon Sep 17 00:00:00 2001 From: Jeroen Versteeg Date: Thu, 23 Jul 2015 11:10:12 +0200 Subject: [PATCH 170/784] DesiredCapabilities factory for Firefox disables Reader View help tooltip This tooltip can hide window.document elements, which can break tests. See http://stackoverflow.com/questions/30764805/how-to-disable-reader-view-in-firefox-using-webdriver --- lib/Remote/DesiredCapabilities.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/Remote/DesiredCapabilities.php b/lib/Remote/DesiredCapabilities.php index 4fe5dfaf4..08ff2b978 100644 --- a/lib/Remote/DesiredCapabilities.php +++ b/lib/Remote/DesiredCapabilities.php @@ -195,10 +195,17 @@ public static function chrome() { * @return DesiredCapabilities */ public static function firefox() { - return new DesiredCapabilities(array( + $caps = new DesiredCapabilities(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::FIREFOX, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, )); + + // disable the "Reader View" help tooltip, which can hide elements in the window.document + $profile = new FirefoxProfile(); + $profile->setPreference('reader.parse-on-load.enabled', false); + $caps->setCapability(FirefoxDriver::PROFILE, $profile); + + return $caps; } /** From 6034d7120c42158f5772a7cf62c1ceb93e5eeabd Mon Sep 17 00:00:00 2001 From: Fredrik Forsmo Date: Tue, 28 Jul 2015 15:22:59 +0200 Subject: [PATCH 171/784] Added syntax highlighting to readme --- README.md | 47 +++++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index bda69e9a3..8c0719969 100644 --- a/README.md +++ b/README.md @@ -19,12 +19,14 @@ Any complaint, question, idea? You can post it on the user group https://www.fac ### Packagist Add the dependency. https://packagist.org/packages/facebook/webdriver - { - "require": { - "facebook/webdriver": "~1.0" - } - } - +```json +{ + "require": { + "facebook/webdriver": "~1.0" + } +} +``` + Download the composer.phar curl -sS https://getcomposer.org/installer | php @@ -32,8 +34,7 @@ Download the composer.phar Install the library. php composer.phar install - - + ## GETTING STARTED @@ -41,26 +42,36 @@ Install the library. * Download and run that file, replacing # with the current server version. - java -jar selenium-server-standalone-#.jar + ``` + java -jar selenium-server-standalone-#.jar + ``` * Then when you create a session, be sure to pass the url to where your server is running. - // This would be the url of the host running the server-standalone.jar - $host = 'http://localhost:4444/wd/hub'; // this is the default + ```php + // This would be the url of the host running the server-standalone.jar + $host = 'http://localhost:4444/wd/hub'; // this is the default + ``` * Launch Firefox - $driver = RemoteWebDriver::create($host, DesiredCapabilities::firefox()); - + ```php + $driver = RemoteWebDriver::create($host, DesiredCapabilities::firefox()); + ``` + * Launch Chrome - $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome()); + ```php + $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome()); + ``` -* You can also customize the desired capabilities. +* You can also customize the desired capabilities. - $desired_capabilities = DesiredCapabilities::firefox(); - $desired_capabilities->setJavascriptEnabled(false); - RemoteWebDriver::create($host, $desired_capabilities); + ```php + $desired_capabilities = DesiredCapabilities::firefox(); + $desired_capabilities->setJavascriptEnabled(false); + RemoteWebDriver::create($host, $desired_capabilities); + ``` * See https://code.google.com/p/selenium/wiki/DesiredCapabilities for more details. From c90b3a9f6bf833526c2069bf6a74c332f670a324 Mon Sep 17 00:00:00 2001 From: EvanCoh Date: Mon, 3 Aug 2015 23:06:54 +0300 Subject: [PATCH 172/784] unit tests wrong namespace deletion --- tests/unit/WebDriverButtonReleaseActionTest.php | 2 -- tests/unit/WebDriverClickActionTest.php | 2 -- tests/unit/WebDriverClickAndHoldActionTest.php | 2 -- tests/unit/WebDriverContextClickActionTest.php | 2 -- tests/unit/WebDriverCoordinatesTest.php | 2 -- tests/unit/WebDriverDoubleClickActionTest.php | 2 -- tests/unit/WebDriverKeyDownActionTest.php | 2 -- tests/unit/WebDriverKeyUpActionTest.php | 2 -- tests/unit/WebDriverMouseMoveActionTest.php | 2 -- tests/unit/WebDriverMouseToOffsetActionTest.php | 2 -- tests/unit/WebDriverSendKeysActionTest.php | 2 -- 11 files changed, 22 deletions(-) diff --git a/tests/unit/WebDriverButtonReleaseActionTest.php b/tests/unit/WebDriverButtonReleaseActionTest.php index 3a4779855..88e65b9f1 100644 --- a/tests/unit/WebDriverButtonReleaseActionTest.php +++ b/tests/unit/WebDriverButtonReleaseActionTest.php @@ -13,8 +13,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; - use Facebook\WebDriver\Interactions\Internal\WebDriverButtonReleaseAction; class WebDriverButtonReleaseActionTest extends \PHPUnit_Framework_TestCase { diff --git a/tests/unit/WebDriverClickActionTest.php b/tests/unit/WebDriverClickActionTest.php index 07dd8e5c2..b69b0bb69 100644 --- a/tests/unit/WebDriverClickActionTest.php +++ b/tests/unit/WebDriverClickActionTest.php @@ -13,8 +13,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; - use Facebook\WebDriver\Interactions\Internal\WebDriverClickAction; class WebDriverClickActionTest extends \PHPUnit_Framework_TestCase { diff --git a/tests/unit/WebDriverClickAndHoldActionTest.php b/tests/unit/WebDriverClickAndHoldActionTest.php index 7bcefd0d5..191337cb3 100644 --- a/tests/unit/WebDriverClickAndHoldActionTest.php +++ b/tests/unit/WebDriverClickAndHoldActionTest.php @@ -13,8 +13,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; - use Facebook\WebDriver\Interactions\Internal\WebDriverClickAndHoldAction; class WebDriverClickAndHoldActionTest extends \PHPUnit_Framework_TestCase { diff --git a/tests/unit/WebDriverContextClickActionTest.php b/tests/unit/WebDriverContextClickActionTest.php index b85a1d7db..1a23c6a19 100644 --- a/tests/unit/WebDriverContextClickActionTest.php +++ b/tests/unit/WebDriverContextClickActionTest.php @@ -13,8 +13,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; - use Facebook\WebDriver\Interactions\Internal\WebDriverContextClickAction; class WebDriverContextClickActionTest extends \PHPUnit_Framework_TestCase { diff --git a/tests/unit/WebDriverCoordinatesTest.php b/tests/unit/WebDriverCoordinatesTest.php index 6002c58bd..5371cc795 100644 --- a/tests/unit/WebDriverCoordinatesTest.php +++ b/tests/unit/WebDriverCoordinatesTest.php @@ -13,8 +13,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; - use Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates; class WebDriverCoordinatesTest extends \PHPUnit_Framework_TestCase { diff --git a/tests/unit/WebDriverDoubleClickActionTest.php b/tests/unit/WebDriverDoubleClickActionTest.php index 958c2e3cf..5904363fd 100644 --- a/tests/unit/WebDriverDoubleClickActionTest.php +++ b/tests/unit/WebDriverDoubleClickActionTest.php @@ -13,8 +13,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; - use Facebook\WebDriver\Interactions\Internal\WebDriverDoubleClickAction; class WebDriverDoubleClickActionTest extends \PHPUnit_Framework_TestCase { diff --git a/tests/unit/WebDriverKeyDownActionTest.php b/tests/unit/WebDriverKeyDownActionTest.php index 2f0ddf593..ad1178432 100644 --- a/tests/unit/WebDriverKeyDownActionTest.php +++ b/tests/unit/WebDriverKeyDownActionTest.php @@ -13,8 +13,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; - use Facebook\WebDriver\Interactions\Internal\WebDriverKeyDownAction; class WebDriverKeyDownActionTest extends \PHPUnit_Framework_TestCase { diff --git a/tests/unit/WebDriverKeyUpActionTest.php b/tests/unit/WebDriverKeyUpActionTest.php index 51c3a9548..24e61638e 100644 --- a/tests/unit/WebDriverKeyUpActionTest.php +++ b/tests/unit/WebDriverKeyUpActionTest.php @@ -13,8 +13,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; - use Facebook\WebDriver\Interactions\Internal\WebDriverKeyUpAction; class WebDriverKeyUpActionTest extends \PHPUnit_Framework_TestCase { diff --git a/tests/unit/WebDriverMouseMoveActionTest.php b/tests/unit/WebDriverMouseMoveActionTest.php index 1b8f89f78..09f368e4b 100644 --- a/tests/unit/WebDriverMouseMoveActionTest.php +++ b/tests/unit/WebDriverMouseMoveActionTest.php @@ -13,8 +13,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; - use Facebook\WebDriver\Interactions\Internal\WebDriverMouseMoveAction; class WebDriverMouseMoveActionTest extends \PHPUnit_Framework_TestCase { diff --git a/tests/unit/WebDriverMouseToOffsetActionTest.php b/tests/unit/WebDriverMouseToOffsetActionTest.php index cca46496d..03f0b5e4c 100644 --- a/tests/unit/WebDriverMouseToOffsetActionTest.php +++ b/tests/unit/WebDriverMouseToOffsetActionTest.php @@ -13,8 +13,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; - use Facebook\WebDriver\Interactions\Internal\WebDriverMoveToOffsetAction; class WebDriverMouseToOffsetActionTest extends \PHPUnit_Framework_TestCase { diff --git a/tests/unit/WebDriverSendKeysActionTest.php b/tests/unit/WebDriverSendKeysActionTest.php index e5782b9c3..ca6ea0df9 100644 --- a/tests/unit/WebDriverSendKeysActionTest.php +++ b/tests/unit/WebDriverSendKeysActionTest.php @@ -13,8 +13,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -namespace Facebook\WebDriver; - use Facebook\WebDriver\Interactions\Internal\WebDriverSendKeysAction; class WebDriverSendKeysActionTest extends \PHPUnit_Framework_TestCase { From 7eb613422bbbf3ac644ed2ad08ad814961766feb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aar=C3=B3n=20Nieves=20Fern=C3=A1ndez?= Date: Wed, 2 Sep 2015 11:17:29 +0200 Subject: [PATCH 173/784] Copy paste typo error --- example.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example.php b/example.php index 556a100a0..ea3ff4180 100644 --- a/example.php +++ b/example.php @@ -34,7 +34,7 @@ // print the title of the current page echo "The title is " . $driver->getTitle() . "'\n"; -// print the title of the current page +// print the URI of the current page echo "The current URI is " . $driver->getCurrentURL() . "'\n"; // Search 'php' in the search box From e38915816fb267bc1060e8c61851079bcae339be Mon Sep 17 00:00:00 2001 From: Daniel Beardsley Date: Wed, 23 Sep 2015 15:38:28 -0700 Subject: [PATCH 174/784] RemoteWebElement: allow overriding construction Previously, if a developer wanted to extend the RemoteWebElement() class, you couldn't effectively do it. The name of the class was hard-coded in a private factory method of RemoteWebDriver that couldn't be overriden. Now, a custom class that extends RemoteWebDriver can construct a class derived from RemoteWebElement, allowing extra functionality to be added to Elements themselves. The same logic applies to the EventFiringWebElement. --- lib/Remote/RemoteWebDriver.php | 2 +- lib/Remote/RemoteWebElement.php | 5 ++--- lib/Support/Events/EventFiringWebDriver.php | 2 +- lib/Support/Events/EventFiringWebElement.php | 4 ++-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index 9d8a6a76a..ad253e701 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -430,7 +430,7 @@ public function action() { * @param string $id The id of the element to be created. * @return RemoteWebElement */ - private function newElement($id) { + protected function newElement($id) { return new RemoteWebElement($this->getExecuteMethod(), $id); } diff --git a/lib/Remote/RemoteWebElement.php b/lib/Remote/RemoteWebElement.php index 53fc1e908..235e3872c 100644 --- a/lib/Remote/RemoteWebElement.php +++ b/lib/Remote/RemoteWebElement.php @@ -416,8 +416,7 @@ public function equals(WebDriverElement $other) { * * @return RemoteWebElement */ - private function newElement($id) { - $class = get_class($this); - return new $class($this->executor, $id); + protected function newElement($id) { + return new static($this->executor, $id); } } diff --git a/lib/Support/Events/EventFiringWebDriver.php b/lib/Support/Events/EventFiringWebDriver.php index d21c224c8..ab279cb1d 100644 --- a/lib/Support/Events/EventFiringWebDriver.php +++ b/lib/Support/Events/EventFiringWebDriver.php @@ -85,7 +85,7 @@ public function getWebDriver() { * @param WebDriverElement $element * @return EventFiringWebElement */ - private function newElement(WebDriverElement $element) { + protected function newElement(WebDriverElement $element) { return new EventFiringWebElement($element, $this->getDispatcher()); } diff --git a/lib/Support/Events/EventFiringWebElement.php b/lib/Support/Events/EventFiringWebElement.php index 3084ec1b5..3025bd8ba 100644 --- a/lib/Support/Events/EventFiringWebElement.php +++ b/lib/Support/Events/EventFiringWebElement.php @@ -78,8 +78,8 @@ public function getElement() { * @param WebDriverElement $element * @return EventFiringWebElement */ - private function newElement(WebDriverElement $element) { - return new EventFiringWebElement($element, $this->getDispatcher()); + protected function newElement(WebDriverElement $element) { + return new static($element, $this->getDispatcher()); } /** From 9c70763340e104731ac5d5d05eddceebfd340645 Mon Sep 17 00:00:00 2001 From: "achange@grovo" Date: Thu, 15 Oct 2015 14:19:21 -0400 Subject: [PATCH 175/784] clarifying README.md for getting code --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8c0719969..7beb7564c 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,13 @@ Any complaint, question, idea? You can post it on the user group https://www.fac ## GETTING THE CODE -### Github +There are two ways of getting the code: + +### Via Github git clone git@github.com:facebook/php-webdriver.git -### Packagist -Add the dependency. https://packagist.org/packages/facebook/webdriver +### Via Packagist +Add the dependency to composer.json (see https://packagist.org/packages/facebook/webdriver) ```json { @@ -27,6 +29,8 @@ Add the dependency. https://packagist.org/packages/facebook/webdriver } ``` +## INSTALLATION + Download the composer.phar curl -sS https://getcomposer.org/installer | php From 6bb9fdfd077ea8f2f624e73cf138af0aca196112 Mon Sep 17 00:00:00 2001 From: Gregor Kralik Date: Thu, 22 Oct 2015 14:17:52 +0200 Subject: [PATCH 176/784] FirefoxProfile: clean up temporary files during profile setup, some temporary files/folders are created. these temporary files/folders can grow quite large, so clean them up after the profile has been constructed to prevent disk space issues. --- lib/Firefox/FirefoxProfile.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index d15d9556e..caefb1e4d 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -98,6 +98,11 @@ public function encode() { $zip->close(); $profile = base64_encode(file_get_contents($temp_zip)); + + // clean up + rmdir($temp_dir); + unlink($temp_zip); + return $profile; } @@ -122,6 +127,10 @@ private function installExtension($extension, $profile_dir) { mkdir($ext_dir, 0777, true); $this->extractTo($extension, $ext_dir); + + // clean up + rmdir($temp_dir); + return $ext_dir; } From da5cbd33c20e9e90eb97f89a0d0a8cdcabf747d2 Mon Sep 17 00:00:00 2001 From: Gregor Kralik Date: Thu, 22 Oct 2015 17:26:44 +0200 Subject: [PATCH 177/784] recursively delete temporary directories rmdir() will only succeed if the target directory is empty. use a helper function to recursively delete the target directory contents before using rmdir() on it. --- lib/Firefox/FirefoxProfile.php | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index caefb1e4d..df76eaa6a 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -100,9 +100,9 @@ public function encode() { $profile = base64_encode(file_get_contents($temp_zip)); // clean up - rmdir($temp_dir); + $this->deleteDirectory($temp_dir); unlink($temp_zip); - + return $profile; } @@ -129,8 +129,8 @@ private function installExtension($extension, $profile_dir) { $this->extractTo($extension, $ext_dir); // clean up - rmdir($temp_dir); - + $this->deleteDirectory($temp_dir); + return $ext_dir; } @@ -152,6 +152,23 @@ private function createTempDirectory($prefix = '') { return $temp_dir; } + /** + * @param string $directory The path to the directory. + */ + private function deleteDirectory($directory) { + $dir = new RecursiveDirectoryIterator($directory, FilesystemIterator::SKIP_DOTS); + $files = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST); + + foreach($paths as $path) { + if ($path->isDir() && !$path->isLink()) { + rmdir($path->getPathname()); + } else { + unlink($path->getPathname()) + } + } + + rmdir($directory; + } /** * @param string $xpi The path to the .xpi extension. * @param string $target_dir The path to the unzip directory. From 75f80c3b8cb2f44cce5190cc3f50e5766ca9ad11 Mon Sep 17 00:00:00 2001 From: Gregor Kralik Date: Thu, 22 Oct 2015 17:30:56 +0200 Subject: [PATCH 178/784] CS fix --- lib/Firefox/FirefoxProfile.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index df76eaa6a..f5a82d0cb 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -169,6 +169,7 @@ private function deleteDirectory($directory) { rmdir($directory; } + /** * @param string $xpi The path to the .xpi extension. * @param string $target_dir The path to the unzip directory. From cb04dc709d082e2d576fd7ab4a3368aa2b3e21eb Mon Sep 17 00:00:00 2001 From: Gregor Kralik Date: Tue, 27 Oct 2015 09:06:09 +0100 Subject: [PATCH 179/784] fix some syntax errors --- lib/Firefox/FirefoxProfile.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index f5a82d0cb..004b8db0f 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -157,17 +157,17 @@ private function createTempDirectory($prefix = '') { */ private function deleteDirectory($directory) { $dir = new RecursiveDirectoryIterator($directory, FilesystemIterator::SKIP_DOTS); - $files = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST); + $paths = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST); - foreach($paths as $path) { + foreach ($paths as $path) { if ($path->isDir() && !$path->isLink()) { rmdir($path->getPathname()); } else { - unlink($path->getPathname()) + unlink($path->getPathname()); } } - rmdir($directory; + rmdir($directory); } /** From 01820c60a43ce14758f4369814323d1d666fa967 Mon Sep 17 00:00:00 2001 From: Phelipe Alves de Souza Date: Sat, 31 Oct 2015 20:23:50 -0200 Subject: [PATCH 180/784] Method call uses 2 parameters, but method signature uses 1 parameters --- lib/Remote/Service/DriverCommandExecutor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Remote/Service/DriverCommandExecutor.php b/lib/Remote/Service/DriverCommandExecutor.php index f4857e933..10ab2b90f 100644 --- a/lib/Remote/Service/DriverCommandExecutor.php +++ b/lib/Remote/Service/DriverCommandExecutor.php @@ -50,7 +50,7 @@ public function execute(WebDriverCommand $command, $curl_opts = array()) { } try { - $value = parent::execute($command, $curl_opts); + $value = parent::execute($command); if ($command->getName() === DriverCommand::QUIT) { $this->service->stop(); } From 3f4aa23e3965497dcb0c3663e10d83b5e2e8149c Mon Sep 17 00:00:00 2001 From: Phelipe Alves de Souza Date: Sat, 31 Oct 2015 20:36:50 -0200 Subject: [PATCH 181/784] PHPDoc comment doesn't contain all necessary @throws tag(s) --- lib/Firefox/FirefoxProfile.php | 1 + lib/Remote/DesiredCapabilities.php | 1 + lib/WebDriverSelect.php | 13 +++++++++++++ 3 files changed, 15 insertions(+) diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index d15d9556e..1d869ff5a 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -45,6 +45,7 @@ public function addExtension($extension) { * @param string $key * @param string|bool|int $value * @return FirefoxProfile + * @throws WebDriverException */ public function setPreference($key, $value) { if (is_string($value)) { diff --git a/lib/Remote/DesiredCapabilities.php b/lib/Remote/DesiredCapabilities.php index 08ff2b978..915d544ec 100644 --- a/lib/Remote/DesiredCapabilities.php +++ b/lib/Remote/DesiredCapabilities.php @@ -115,6 +115,7 @@ public function isJavascriptEnabled() { * This is a htmlUnit-only option. * * @param bool $enabled + * @throws Exception * @return DesiredCapabilities * @see https://code.google.com/p/selenium/wiki/DesiredCapabilities#Read-write_capabilities */ diff --git a/lib/WebDriverSelect.php b/lib/WebDriverSelect.php index cc09a1ac6..20082dd0b 100644 --- a/lib/WebDriverSelect.php +++ b/lib/WebDriverSelect.php @@ -68,6 +68,8 @@ public function getAllSelectedOptions() { } /** + * @throws NoSuchElementException + * * @return WebDriverElement The first selected option in this select tag (or * the currently selected option in a normal select) */ @@ -84,6 +86,8 @@ public function getFirstSelectedOption() { /** * Deselect all options in multiple select tag. * + * @throws UnsupportedOperationException + * * @return void */ public function deselectAll() { @@ -104,6 +108,9 @@ public function deselectAll() { * Select the option at the given index. * * @param int $index The index of the option. (0-based) + * + * @throws NoSuchElementException + * * @return void */ public function selectByIndex($index) { @@ -133,6 +140,9 @@ public function selectByIndex($index) { * ; * * @param string $value The value to match against. + * + * @throws NoSuchElementException + * * @return void */ public function selectByValue($value) { @@ -164,6 +174,9 @@ public function selectByValue($value) { * ; * * @param string $text The visible text to match against. + * + * @throws NoSuchElementException + * * @return void */ public function selectByVisibleText($text) { From 1d828236f0431542cecee1132ded87aca92f291f Mon Sep 17 00:00:00 2001 From: Phelipe Alves de Souza Date: Sat, 31 Oct 2015 20:54:21 -0200 Subject: [PATCH 182/784] Removed unused imports --- lib/Remote/ExecuteMethod.php | 2 -- lib/Remote/LocalFileDetector.php | 2 -- 2 files changed, 4 deletions(-) diff --git a/lib/Remote/ExecuteMethod.php b/lib/Remote/ExecuteMethod.php index aa13af5ea..ff13c58fe 100644 --- a/lib/Remote/ExecuteMethod.php +++ b/lib/Remote/ExecuteMethod.php @@ -15,8 +15,6 @@ namespace Facebook\WebDriver\Remote; -use Facebook\WebDriver\Remote\WebDriverResponse; - interface ExecuteMethod { /** diff --git a/lib/Remote/LocalFileDetector.php b/lib/Remote/LocalFileDetector.php index c6d44f78c..1308ed6a1 100644 --- a/lib/Remote/LocalFileDetector.php +++ b/lib/Remote/LocalFileDetector.php @@ -15,8 +15,6 @@ namespace Facebook\WebDriver\Remote; -use Facebook\WebDriver\Remote\FileDetector; - class LocalFileDetector implements FileDetector { /** * @param string $file From a2130bae8a89836bb8a4f975316919d0dc8a9521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20V=C3=B6lk?= Date: Tue, 3 Nov 2015 15:32:24 +0100 Subject: [PATCH 183/784] fix issue #259 --- lib/Firefox/FirefoxProfile.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index ff41f6a30..a7d926652 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -16,6 +16,7 @@ namespace Facebook\WebDriver\Firefox; use Facebook\WebDriver\Exception\WebDriverException; +use FilesystemIterator; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; use ZipArchive; @@ -170,7 +171,7 @@ private function deleteDirectory($directory) { rmdir($directory); } - + /** * @param string $xpi The path to the .xpi extension. * @param string $target_dir The path to the unzip directory. From 1bd54495e3a971aef8e3b371f43db183f6022f66 Mon Sep 17 00:00:00 2001 From: John Nicholls Date: Wed, 4 Nov 2015 14:47:08 +0000 Subject: [PATCH 184/784] add missing single quotes --- example.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example.php b/example.php index ea3ff4180..690a3b1c3 100644 --- a/example.php +++ b/example.php @@ -32,10 +32,10 @@ $link->click(); // print the title of the current page -echo "The title is " . $driver->getTitle() . "'\n"; +echo "The title is '" . $driver->getTitle() . "'\n"; // print the URI of the current page -echo "The current URI is " . $driver->getCurrentURL() . "'\n"; +echo "The current URI is '" . $driver->getCurrentURL() . "'\n"; // Search 'php' in the search box $input = $driver->findElement( From 1a8d108040abbb419b12737cf6be2400ab344a00 Mon Sep 17 00:00:00 2001 From: Diogo Guerra Date: Thu, 3 Dec 2015 10:51:29 +0100 Subject: [PATCH 185/784] Update composer.json --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 8d4095415..a420f3fdc 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { - "name": "facebook/webdriver", - "description": "A PHP client for WebDriver", + "name": "dguerra/facebook-webdriver", + "description": "A fork of Facebook PHP client for WebDriver", "keywords": ["webdriver", "selenium", "php", "facebook"], "homepage": "https://github.com/facebook/php-webdriver", "type": "library", From 912a5e528c2e545a44d9030f5fcb8bebf1446006 Mon Sep 17 00:00:00 2001 From: DGuerra Date: Thu, 3 Dec 2015 11:23:30 +0100 Subject: [PATCH 186/784] Added possibility to set RDF file --- lib/Firefox/FirefoxProfile.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index a7d926652..4ba192bb4 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -33,6 +33,11 @@ class FirefoxProfile { */ private $extensions = array(); + /** + * @var string + */ + private $rdfFile; + /** * @param string $extension The path to the xpi extension. * @return FirefoxProfile @@ -42,6 +47,19 @@ public function addExtension($extension) { return $this; } + /** + * @param string $rdfFile The path to the rdf file + * @return FirefoxProfile + */ + public function setRdfFile($rdfFile) { + if(!is_file($rdfFile)) { + return; + } + + $this->rdfFile = $rdfFile; + return $this; + } + /** * @param string $key * @param string|bool|int $value @@ -69,6 +87,10 @@ public function setPreference($key, $value) { public function encode() { $temp_dir = $this->createTempDirectory('WebDriverFirefoxProfile'); + if(isset($this->rdfFile)) { + copy($this->rdfFile, $temp_dir . DIRECTORY_SEPARATOR . "mimeTypes.rdf"); + } + foreach ($this->extensions as $extension) { $this->installExtension($extension, $temp_dir); } From 8865a365d3e9fe9ccd9b9395c56e38f257191116 Mon Sep 17 00:00:00 2001 From: DGuerra Date: Thu, 3 Dec 2015 11:32:09 +0100 Subject: [PATCH 187/784] Added possibility to add datas for extensions --- lib/Firefox/FirefoxProfile.php | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index 4ba192bb4..b1d0d5b23 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -33,6 +33,11 @@ class FirefoxProfile { */ private $extensions = array(); + /** + * @var array + */ + private $extensionsDatas = array(); + /** * @var string */ @@ -47,6 +52,19 @@ public function addExtension($extension) { return $this; } + /** + * @param string $extensionDatas The path to the folder containing the datas to add to the extension + * @return FirefoxProfile + */ + public function addExtensionDatas($extensionDatas) { + if(!is_dir($extensionDatas)) { + return; + } + + $this->extensionsDatas[dirname($extensionDatas)] = $extensionDatas; + return $this; + } + /** * @param string $rdfFile The path to the rdf file * @return FirefoxProfile @@ -95,6 +113,17 @@ public function encode() { $this->installExtension($extension, $temp_dir); } + foreach ($this->extensionsDatas as $dirname => $extensionDatas) { + mkdir($temp_dir . DIRECTORY_SEPARATOR . $dirname); + $files = scandir($extensionDatas); + foreach ($files as $file) { + if(is_file($file) + && $file != "." + && $file != "..") { + copy($extensionDatas . DIRECTORY_SEPARATOR . $file, $temp_dir . DIRECTORY_SEPARATOR . $dirname . DIRECTORY_SEPARATOR . $file); + } + } + $content = ""; foreach ($this->preferences as $key => $value) { $content .= sprintf("user_pref(\"%s\", %s);\n", $key, $value); From 26440448164ca03e4d7664316112785ec52c88ea Mon Sep 17 00:00:00 2001 From: DGuerra Date: Thu, 3 Dec 2015 11:35:22 +0100 Subject: [PATCH 188/784] Renamed added vars to follow convention used by the others ones --- lib/Firefox/FirefoxProfile.php | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index b1d0d5b23..6b356ecd9 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -36,12 +36,12 @@ class FirefoxProfile { /** * @var array */ - private $extensionsDatas = array(); + private $extensions_datas = array(); /** * @var string */ - private $rdfFile; + private $rdf_file; /** * @param string $extension The path to the xpi extension. @@ -53,28 +53,28 @@ public function addExtension($extension) { } /** - * @param string $extensionDatas The path to the folder containing the datas to add to the extension + * @param string $extension_datas The path to the folder containing the datas to add to the extension * @return FirefoxProfile */ - public function addExtensionDatas($extensionDatas) { - if(!is_dir($extensionDatas)) { + public function addExtensionDatas($extension_datas) { + if(!is_dir($extension_datas)) { return; } - $this->extensionsDatas[dirname($extensionDatas)] = $extensionDatas; + $this->extensions_datas[dirname($extension_datas)] = $extension_datas; return $this; } /** - * @param string $rdfFile The path to the rdf file + * @param string $rdf_file The path to the rdf file * @return FirefoxProfile */ - public function setRdfFile($rdfFile) { - if(!is_file($rdfFile)) { + public function setRdfFile($rdf_file) { + if(!is_file($rdf_file)) { return; } - $this->rdfFile = $rdfFile; + $this->rdf_file = $rdf_file; return $this; } @@ -105,22 +105,22 @@ public function setPreference($key, $value) { public function encode() { $temp_dir = $this->createTempDirectory('WebDriverFirefoxProfile'); - if(isset($this->rdfFile)) { - copy($this->rdfFile, $temp_dir . DIRECTORY_SEPARATOR . "mimeTypes.rdf"); + if(isset($this->rdf_file)) { + copy($this->rdf_file, $temp_dir . DIRECTORY_SEPARATOR . "mimeTypes.rdf"); } foreach ($this->extensions as $extension) { $this->installExtension($extension, $temp_dir); } - foreach ($this->extensionsDatas as $dirname => $extensionDatas) { + foreach ($this->extensions_datas as $dirname => $extension_datas) { mkdir($temp_dir . DIRECTORY_SEPARATOR . $dirname); - $files = scandir($extensionDatas); + $files = scandir($extension_datas); foreach ($files as $file) { if(is_file($file) && $file != "." && $file != "..") { - copy($extensionDatas . DIRECTORY_SEPARATOR . $file, $temp_dir . DIRECTORY_SEPARATOR . $dirname . DIRECTORY_SEPARATOR . $file); + copy($extension_datas . DIRECTORY_SEPARATOR . $file, $temp_dir . DIRECTORY_SEPARATOR . $dirname . DIRECTORY_SEPARATOR . $file); } } From 2d2588d6bb7873b250047766492c7ab77410ccec Mon Sep 17 00:00:00 2001 From: DGuerra Date: Thu, 3 Dec 2015 11:37:20 +0100 Subject: [PATCH 189/784] Added prefix to extension temporary directory --- lib/Firefox/FirefoxProfile.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index 6b356ecd9..f23ddadde 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -165,7 +165,7 @@ public function encode() { * @return string The path to the directory of this extension. */ private function installExtension($extension, $profile_dir) { - $temp_dir = $this->createTempDirectory(); + $temp_dir = $this->createTempDirectory('WebDriverFirefoxProfileExtension'); $this->extractTo($extension, $temp_dir); From 77289453ac3f33586e1f1aadb9a83f98e7c58aa5 Mon Sep 17 00:00:00 2001 From: DGuerra Date: Thu, 3 Dec 2015 11:54:27 +0100 Subject: [PATCH 190/784] Corrected forgotten bracket --- lib/Firefox/FirefoxProfile.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index f23ddadde..fe21c2e99 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -121,6 +121,7 @@ public function encode() { && $file != "." && $file != "..") { copy($extension_datas . DIRECTORY_SEPARATOR . $file, $temp_dir . DIRECTORY_SEPARATOR . $dirname . DIRECTORY_SEPARATOR . $file); + } } } From d23382b50acf85d3bf7f76b9c5b4956660aa91ae Mon Sep 17 00:00:00 2001 From: DGuerra Date: Thu, 3 Dec 2015 14:19:22 +0100 Subject: [PATCH 191/784] Using correct function to get extension datas directory name --- lib/Firefox/FirefoxProfile.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index fe21c2e99..62c809f84 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -61,7 +61,7 @@ public function addExtensionDatas($extension_datas) { return; } - $this->extensions_datas[dirname($extension_datas)] = $extension_datas; + $this->extensions_datas[basename($extension_datas)] = $extension_datas; return $this; } From 7b1af60eb964450f10c3d9f42d810749786b4398 Mon Sep 17 00:00:00 2001 From: DGuerra Date: Fri, 4 Dec 2015 00:05:39 +0100 Subject: [PATCH 192/784] Extension datas directories added recursively --- composer.json | 4 ++-- lib/Firefox/FirefoxProfile.php | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/composer.json b/composer.json index a420f3fdc..8d4095415 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { - "name": "dguerra/facebook-webdriver", - "description": "A fork of Facebook PHP client for WebDriver", + "name": "facebook/webdriver", + "description": "A PHP client for WebDriver", "keywords": ["webdriver", "selenium", "php", "facebook"], "homepage": "https://github.com/facebook/php-webdriver", "type": "library", diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index 62c809f84..3d7739f5c 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -57,7 +57,7 @@ public function addExtension($extension) { * @return FirefoxProfile */ public function addExtensionDatas($extension_datas) { - if(!is_dir($extension_datas)) { + if (!is_dir($extension_datas)) { return; } @@ -70,7 +70,7 @@ public function addExtensionDatas($extension_datas) { * @return FirefoxProfile */ public function setRdfFile($rdf_file) { - if(!is_file($rdf_file)) { + if (!is_file($rdf_file)) { return; } @@ -105,7 +105,7 @@ public function setPreference($key, $value) { public function encode() { $temp_dir = $this->createTempDirectory('WebDriverFirefoxProfile'); - if(isset($this->rdf_file)) { + if (isset($this->rdf_file)) { copy($this->rdf_file, $temp_dir . DIRECTORY_SEPARATOR . "mimeTypes.rdf"); } @@ -115,13 +115,13 @@ public function encode() { foreach ($this->extensions_datas as $dirname => $extension_datas) { mkdir($temp_dir . DIRECTORY_SEPARATOR . $dirname); - $files = scandir($extension_datas); - foreach ($files as $file) { - if(is_file($file) - && $file != "." - && $file != "..") { - copy($extension_datas . DIRECTORY_SEPARATOR . $file, $temp_dir . DIRECTORY_SEPARATOR . $dirname . DIRECTORY_SEPARATOR . $file); - } + $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($extension_datas, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST); + foreach ($iterator as $item) { + if ($item->isDir()) { + mkdir($temp_dir . DIRECTORY_SEPARATOR . $dirname . DIRECTORY_SEPARATOR . $iterator->getSubPathName()); + } else { + copy($item, $temp_dir . DIRECTORY_SEPARATOR . $dirname . DIRECTORY_SEPARATOR . $iterator->getSubPathName()); + } } } From 3f9606a43831d1ccc0befb1570eeefb2b30049a1 Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Tue, 8 Dec 2015 08:35:18 -0800 Subject: [PATCH 193/784] Check isset for timeout in seconds --- lib/WebDriverWait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/WebDriverWait.php b/lib/WebDriverWait.php index 4b43b3755..5cddd29c3 100644 --- a/lib/WebDriverWait.php +++ b/lib/WebDriverWait.php @@ -35,7 +35,7 @@ public function __construct( $timeout_in_second = null, $interval_in_millisecond = null) { $this->driver = $driver; - $this->timeout = $timeout_in_second ?: 30; + $this->timeout = isset($timeout_in_second) ? $timeout_in_second : 30; $this->interval = $interval_in_millisecond ?: 250; } From ee78deaa5aa8cdc8c767f79bef834b17d0f70088 Mon Sep 17 00:00:00 2001 From: Tobias Kappe Date: Thu, 24 Dec 2015 14:47:58 +0100 Subject: [PATCH 194/784] Use sys_get_temp_dir rather than the empty string when calling tempnam. The latter fails when using the empty string if an open_basedir restriction is in effect. --- lib/Firefox/FirefoxProfile.php | 4 ++-- lib/Remote/RemoteWebElement.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index 3d7739f5c..423bad924 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -132,7 +132,7 @@ public function encode() { file_put_contents($temp_dir.'/user.js', $content); $zip = new ZipArchive(); - $temp_zip = tempnam('', 'WebDriverFirefoxProfileZip'); + $temp_zip = tempnam(sys_get_temp_dir(), 'WebDriverFirefoxProfileZip'); $zip->open($temp_zip, ZipArchive::CREATE); $dir = new RecursiveDirectoryIterator($temp_dir); @@ -195,7 +195,7 @@ private function installExtension($extension, $profile_dir) { * @throws WebDriverException */ private function createTempDirectory($prefix = '') { - $temp_dir = tempnam('', $prefix); + $temp_dir = tempnam(sys_get_temp_dir(), $prefix); if (file_exists($temp_dir)) { unlink($temp_dir); mkdir($temp_dir); diff --git a/lib/Remote/RemoteWebElement.php b/lib/Remote/RemoteWebElement.php index 235e3872c..e9e1ca31e 100644 --- a/lib/Remote/RemoteWebElement.php +++ b/lib/Remote/RemoteWebElement.php @@ -332,7 +332,7 @@ private function upload($local_file) { } // Create a temporary file in the system temp directory. - $temp_zip = tempnam('', 'WebDriverZip'); + $temp_zip = tempnam(sys_get_temp_dir(), 'WebDriverZip'); $zip = new ZipArchive(); if ($zip->open($temp_zip, ZipArchive::CREATE) !== true) { return false; From 64485b2f068f6198261793fe62582cc2d1a0cd7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 30 Dec 2015 14:01:01 +0100 Subject: [PATCH 195/784] Fix strict standards error --- lib/Chrome/ChromeDriver.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/lib/Chrome/ChromeDriver.php b/lib/Chrome/ChromeDriver.php index 67427205d..0cabccd91 100644 --- a/lib/Chrome/ChromeDriver.php +++ b/lib/Chrome/ChromeDriver.php @@ -56,18 +56,15 @@ public function startSession($desired_capabilities) { /** * Always throws an exception. Use ChromeDriver::start() instead. * - * @param string $url The url of the remote server - * @param DesiredCapabilities $desired_capabilities The desired capabilities - * @param int|null $timeout_in_ms - * @param int|null $request_timeout_in_ms - * * @throws WebDriverException */ public static function create( $url = 'http://localhost:4444/wd/hub', $desired_capabilities = null, - $timeout_in_ms = null, - $request_timeout_in_ms = null + $connection_timeout_in_ms = null, + $request_timeout_in_ms = null, + $http_proxy = null, + $http_proxy_port = null ) { throw new WebDriverException('Please use ChromeDriver::start() instead.'); } From 4967a61f12858ebfab64e77c4c44826fc256b351 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 30 Dec 2015 18:48:44 +0100 Subject: [PATCH 196/784] Move tests to appropriate folders, use namespaces, improve phpdoc --- composer.json | 5 +++-- .../WebDriverButtonReleaseActionTest.php | 12 +++++++----- .../Internal}/WebDriverClickActionTest.php | 12 +++++++----- .../Internal}/WebDriverClickAndHoldActionTest.php | 12 +++++++----- .../Internal}/WebDriverContextClickActionTest.php | 12 +++++++----- .../Internal}/WebDriverCoordinatesTest.php | 2 +- .../Internal}/WebDriverDoubleClickActionTest.php | 12 +++++++----- .../Internal}/WebDriverKeyDownActionTest.php | 14 +++++++++----- .../Internal}/WebDriverKeyUpActionTest.php | 14 +++++++++----- .../Internal}/WebDriverMouseMoveActionTest.php | 12 +++++++----- .../WebDriverMouseToOffsetActionTest.php | 8 ++++++-- .../Internal}/WebDriverSendKeysActionTest.php | 15 ++++++++++----- 12 files changed, 80 insertions(+), 50 deletions(-) rename tests/unit/{ => Interactions/Internal}/WebDriverButtonReleaseActionTest.php (82%) rename tests/unit/{ => Interactions/Internal}/WebDriverClickActionTest.php (82%) rename tests/unit/{ => Interactions/Internal}/WebDriverClickAndHoldActionTest.php (82%) rename tests/unit/{ => Interactions/Internal}/WebDriverContextClickActionTest.php (83%) rename tests/unit/{ => Interactions/Internal}/WebDriverCoordinatesTest.php (95%) rename tests/unit/{ => Interactions/Internal}/WebDriverDoubleClickActionTest.php (83%) rename tests/unit/{ => Interactions/Internal}/WebDriverKeyDownActionTest.php (80%) rename tests/unit/{ => Interactions/Internal}/WebDriverKeyUpActionTest.php (80%) rename tests/unit/{ => Interactions/Internal}/WebDriverMouseMoveActionTest.php (83%) rename tests/unit/{ => Interactions/Internal}/WebDriverMouseToOffsetActionTest.php (85%) rename tests/unit/{ => Interactions/Internal}/WebDriverSendKeysActionTest.php (80%) diff --git a/composer.json b/composer.json index 8d4095415..be4ba7dd5 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,8 @@ }, "autoload-dev": { "psr-4": { - "Facebook\\WebDriver\\": "tests/functional" - } + "Facebook\\WebDriver\\": "tests/unit" + }, + "classmap": ["tests/functional/"] } } diff --git a/tests/unit/WebDriverButtonReleaseActionTest.php b/tests/unit/Interactions/Internal/WebDriverButtonReleaseActionTest.php similarity index 82% rename from tests/unit/WebDriverButtonReleaseActionTest.php rename to tests/unit/Interactions/Internal/WebDriverButtonReleaseActionTest.php index 88e65b9f1..982e8d268 100644 --- a/tests/unit/WebDriverButtonReleaseActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverButtonReleaseActionTest.php @@ -13,15 +13,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -use Facebook\WebDriver\Interactions\Internal\WebDriverButtonReleaseAction; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverMouse; class WebDriverButtonReleaseActionTest extends \PHPUnit_Framework_TestCase { - /** - * @type WebDriverButtonReleaseAction - */ + /** @var WebDriverButtonReleaseAction */ private $webDriverButtonReleaseAction; - + /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ private $webDriverMouse; + /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ private $locationProvider; public function setUp() { diff --git a/tests/unit/WebDriverClickActionTest.php b/tests/unit/Interactions/Internal/WebDriverClickActionTest.php similarity index 82% rename from tests/unit/WebDriverClickActionTest.php rename to tests/unit/Interactions/Internal/WebDriverClickActionTest.php index b69b0bb69..8fab683fe 100644 --- a/tests/unit/WebDriverClickActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverClickActionTest.php @@ -13,15 +13,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -use Facebook\WebDriver\Interactions\Internal\WebDriverClickAction; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverMouse; class WebDriverClickActionTest extends \PHPUnit_Framework_TestCase { - /** - * @type WebDriverClickAction - */ + /** @var WebDriverClickAction */ private $webDriverClickAction; - + /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ private $webDriverMouse; + /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ private $locationProvider; public function setUp() { diff --git a/tests/unit/WebDriverClickAndHoldActionTest.php b/tests/unit/Interactions/Internal/WebDriverClickAndHoldActionTest.php similarity index 82% rename from tests/unit/WebDriverClickAndHoldActionTest.php rename to tests/unit/Interactions/Internal/WebDriverClickAndHoldActionTest.php index 191337cb3..b10ac2cea 100644 --- a/tests/unit/WebDriverClickAndHoldActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverClickAndHoldActionTest.php @@ -13,15 +13,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -use Facebook\WebDriver\Interactions\Internal\WebDriverClickAndHoldAction; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverMouse; class WebDriverClickAndHoldActionTest extends \PHPUnit_Framework_TestCase { - /** - * @type WebDriverClickAndHoldAction - */ + /** @var WebDriverClickAndHoldAction */ private $webDriverClickAndHoldAction; - + /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ private $webDriverMouse; + /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ private $locationProvider; public function setUp() { diff --git a/tests/unit/WebDriverContextClickActionTest.php b/tests/unit/Interactions/Internal/WebDriverContextClickActionTest.php similarity index 83% rename from tests/unit/WebDriverContextClickActionTest.php rename to tests/unit/Interactions/Internal/WebDriverContextClickActionTest.php index 1a23c6a19..a57cb127a 100644 --- a/tests/unit/WebDriverContextClickActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverContextClickActionTest.php @@ -13,15 +13,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -use Facebook\WebDriver\Interactions\Internal\WebDriverContextClickAction; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverMouse; class WebDriverContextClickActionTest extends \PHPUnit_Framework_TestCase { - /** - * @type WebDriverContextClickAction - */ + /** @var WebDriverContextClickAction */ private $webDriverContextClickAction; - + /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ private $webDriverMouse; + /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ private $locationProvider; public function setUp() { diff --git a/tests/unit/WebDriverCoordinatesTest.php b/tests/unit/Interactions/Internal/WebDriverCoordinatesTest.php similarity index 95% rename from tests/unit/WebDriverCoordinatesTest.php rename to tests/unit/Interactions/Internal/WebDriverCoordinatesTest.php index 5371cc795..d38c7220a 100644 --- a/tests/unit/WebDriverCoordinatesTest.php +++ b/tests/unit/Interactions/Internal/WebDriverCoordinatesTest.php @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates; +namespace Facebook\WebDriver\Interactions\Internal; class WebDriverCoordinatesTest extends \PHPUnit_Framework_TestCase { public function testConstruct() { diff --git a/tests/unit/WebDriverDoubleClickActionTest.php b/tests/unit/Interactions/Internal/WebDriverDoubleClickActionTest.php similarity index 83% rename from tests/unit/WebDriverDoubleClickActionTest.php rename to tests/unit/Interactions/Internal/WebDriverDoubleClickActionTest.php index 5904363fd..7f09f64dc 100644 --- a/tests/unit/WebDriverDoubleClickActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverDoubleClickActionTest.php @@ -13,15 +13,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -use Facebook\WebDriver\Interactions\Internal\WebDriverDoubleClickAction; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverMouse; class WebDriverDoubleClickActionTest extends \PHPUnit_Framework_TestCase { - /** - * @type WebDriverDoubleClickAction - */ + /** @var WebDriverDoubleClickAction */ private $webDriverDoubleClickAction; - + /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ private $webDriverMouse; + /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ private $locationProvider; public function setUp() { diff --git a/tests/unit/WebDriverKeyDownActionTest.php b/tests/unit/Interactions/Internal/WebDriverKeyDownActionTest.php similarity index 80% rename from tests/unit/WebDriverKeyDownActionTest.php rename to tests/unit/Interactions/Internal/WebDriverKeyDownActionTest.php index ad1178432..5bba82f4f 100644 --- a/tests/unit/WebDriverKeyDownActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverKeyDownActionTest.php @@ -13,16 +13,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -use Facebook\WebDriver\Interactions\Internal\WebDriverKeyDownAction; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverKeyboard; +use Facebook\WebDriver\WebDriverMouse; class WebDriverKeyDownActionTest extends \PHPUnit_Framework_TestCase { - /** - * @type WebDriverKeyDownAction - */ + /** @var WebDriverKeyDownAction */ private $webDriverKeyDownAction; - + /** @var WebDriverKeyboard|\PHPUnit_Framework_MockObject_MockObject */ private $webDriverKeyboard; + /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ private $webDriverMouse; + /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ private $locationProvider; public function setUp() { diff --git a/tests/unit/WebDriverKeyUpActionTest.php b/tests/unit/Interactions/Internal/WebDriverKeyUpActionTest.php similarity index 80% rename from tests/unit/WebDriverKeyUpActionTest.php rename to tests/unit/Interactions/Internal/WebDriverKeyUpActionTest.php index 24e61638e..cd2b7b00c 100644 --- a/tests/unit/WebDriverKeyUpActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverKeyUpActionTest.php @@ -13,16 +13,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -use Facebook\WebDriver\Interactions\Internal\WebDriverKeyUpAction; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverKeyboard; +use Facebook\WebDriver\WebDriverMouse; class WebDriverKeyUpActionTest extends \PHPUnit_Framework_TestCase { - /** - * @type WebDriverKeyUpAction - */ + /** @var WebDriverKeyUpAction */ private $webDriverKeyUpAction; - + /** @var WebDriverKeyboard|\PHPUnit_Framework_MockObject_MockObject */ private $webDriverKeyboard; + /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ private $webDriverMouse; + /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ private $locationProvider; public function setUp() { diff --git a/tests/unit/WebDriverMouseMoveActionTest.php b/tests/unit/Interactions/Internal/WebDriverMouseMoveActionTest.php similarity index 83% rename from tests/unit/WebDriverMouseMoveActionTest.php rename to tests/unit/Interactions/Internal/WebDriverMouseMoveActionTest.php index 09f368e4b..6376adfa0 100644 --- a/tests/unit/WebDriverMouseMoveActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverMouseMoveActionTest.php @@ -13,15 +13,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -use Facebook\WebDriver\Interactions\Internal\WebDriverMouseMoveAction; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverMouse; class WebDriverMouseMoveActionTest extends \PHPUnit_Framework_TestCase { - /** - * @type WebDriverMouseMoveAction - */ + /** @var WebDriverMouseMoveAction */ private $webDriverMouseMoveAction; - + /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ private $webDriverMouse; + /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ private $locationProvider; public function setUp() { diff --git a/tests/unit/WebDriverMouseToOffsetActionTest.php b/tests/unit/Interactions/Internal/WebDriverMouseToOffsetActionTest.php similarity index 85% rename from tests/unit/WebDriverMouseToOffsetActionTest.php rename to tests/unit/Interactions/Internal/WebDriverMouseToOffsetActionTest.php index 03f0b5e4c..2ea16d552 100644 --- a/tests/unit/WebDriverMouseToOffsetActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverMouseToOffsetActionTest.php @@ -13,15 +13,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -use Facebook\WebDriver\Interactions\Internal\WebDriverMoveToOffsetAction; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverMouse; class WebDriverMouseToOffsetActionTest extends \PHPUnit_Framework_TestCase { /** * @type WebDriverMoveToOffsetAction */ private $webDriverMoveToOffsetAction; - + /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ private $webDriverMouse; + /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ private $locationProvider; public function setUp() { diff --git a/tests/unit/WebDriverSendKeysActionTest.php b/tests/unit/Interactions/Internal/WebDriverSendKeysActionTest.php similarity index 80% rename from tests/unit/WebDriverSendKeysActionTest.php rename to tests/unit/Interactions/Internal/WebDriverSendKeysActionTest.php index ca6ea0df9..f7c2917d0 100644 --- a/tests/unit/WebDriverSendKeysActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverSendKeysActionTest.php @@ -13,17 +13,22 @@ // See the License for the specific language governing permissions and // limitations under the License. -use Facebook\WebDriver\Interactions\Internal\WebDriverSendKeysAction; +namespace Facebook\WebDriver\Interactions\Internal; + +use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverKeyboard; +use Facebook\WebDriver\WebDriverMouse; class WebDriverSendKeysActionTest extends \PHPUnit_Framework_TestCase { - /** - * @type WebDriverSendKeysAction - */ + /** @var WebDriverSendKeysAction */ private $webDriverSendKeysAction; - + /** @var WebDriverKeyboard|\PHPUnit_Framework_MockObject_MockObject */ private $webDriverKeyboard; + /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ private $webDriverMouse; + /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ private $locationProvider; + /** @var array */ private $keys; public function setUp() { From 07ab9b5c336038266b0164cc628dbf37d032bc4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 30 Dec 2015 18:56:48 +0100 Subject: [PATCH 197/784] Minor codestyle fixes --- lib/Chrome/ChromeOptions.php | 6 ++--- lib/Firefox/FirefoxDriver.php | 5 +++- lib/Firefox/FirefoxProfile.php | 4 ++-- lib/Remote/DriverCommand.php | 10 ++++---- lib/Remote/RemoteWebDriver.php | 2 +- lib/Remote/Service/DriverCommandExecutor.php | 3 +-- lib/Remote/WebDriverBrowserType.php | 5 +++- lib/Remote/WebDriverCapabilityType.php | 8 ++++--- lib/Remote/WebDriverCommand.php | 18 ++++++++++++++- lib/WebDriverPlatform.php | 5 +++- phpunit.xml.dist | 24 +++++++++++--------- 11 files changed, 58 insertions(+), 32 deletions(-) diff --git a/lib/Chrome/ChromeOptions.php b/lib/Chrome/ChromeOptions.php index 5cc125f56..da387c55a 100644 --- a/lib/Chrome/ChromeOptions.php +++ b/lib/Chrome/ChromeOptions.php @@ -85,8 +85,7 @@ public function addExtensions(array $paths) { } /** - * @param array $encoded_extensions An array of base64 encoded of the - * extensions. + * @param array $encoded_extensions An array of base64 encoded of the extensions. * @return ChromeOptions */ public function addEncodedExtensions(array $encoded_extensions) { @@ -109,8 +108,7 @@ public function setExperimentalOption($name, $value) { } /** - * @return DesiredCapabilities The DesiredCapabilities for Chrome with this - * options. + * @return DesiredCapabilities The DesiredCapabilities for Chrome with this options. */ public function toCapabilities() { $capabilities = DesiredCapabilities::chrome(); diff --git a/lib/Firefox/FirefoxDriver.php b/lib/Firefox/FirefoxDriver.php index 8afbe0c2d..083af226b 100644 --- a/lib/Firefox/FirefoxDriver.php +++ b/lib/Firefox/FirefoxDriver.php @@ -16,6 +16,9 @@ namespace Facebook\WebDriver\Firefox; class FirefoxDriver { - const PROFILE = 'firefox_profile'; + + private function __construct() + { + } } diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index 3d7739f5c..163d06049 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -55,7 +55,7 @@ public function addExtension($extension) { /** * @param string $extension_datas The path to the folder containing the datas to add to the extension * @return FirefoxProfile - */ + */ public function addExtensionDatas($extension_datas) { if (!is_dir($extension_datas)) { return; @@ -73,7 +73,7 @@ public function setRdfFile($rdf_file) { if (!is_file($rdf_file)) { return; } - + $this->rdf_file = $rdf_file; return $this; } diff --git a/lib/Remote/DriverCommand.php b/lib/Remote/DriverCommand.php index 61ad9d515..18e9fb37b 100644 --- a/lib/Remote/DriverCommand.php +++ b/lib/Remote/DriverCommand.php @@ -19,7 +19,6 @@ * This list of command defined in the WebDriver json wire protocol. */ class DriverCommand { - const GET_ALL_SESSIONS = "getAllSessions"; const GET_CAPABILITIES = "getCapabilities"; const NEW_SESSION = "newSession"; @@ -126,16 +125,14 @@ class DriverCommand { const SET_SCREEN_ORIENTATION = "setScreenOrientation"; const GET_SCREEN_ORIENTATION = "getScreenOrientation"; - // These belong to the Advanced user interactions - an element is - // optional for these commands. + // These belong to the Advanced user interactions - an element is optional for these commands. const CLICK = "mouseClick"; const DOUBLE_CLICK = "mouseDoubleClick"; const MOUSE_DOWN = "mouseButtonDown"; const MOUSE_UP = "mouseButtonUp"; const MOVE_TO = "mouseMoveTo"; - // Those allow interactions with the Input Methods installed on - // the system. + // Those allow interactions with the Input Methods installed on the system. const IME_GET_AVAILABLE_ENGINES = "imeGetAvailableEngines"; const IME_GET_ACTIVE_ENGINE = "imeGetActiveEngine"; const IME_IS_ACTIVATED = "imeIsActivated"; @@ -168,4 +165,7 @@ class DriverCommand { const GET_NETWORK_CONNECTION = "getNetworkConnection"; const SET_NETWORK_CONNECTION = "setNetworkConnection"; + private function __construct() + { + } } diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index ad253e701..1fda245b2 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -74,7 +74,7 @@ public static function create( ) { $url = preg_replace('#/+$#', '', $url); - // Passing DesiredCapabilities as $desired_capabilities is encourged but + // Passing DesiredCapabilities as $desired_capabilities is encouraged but // array is also accepted for legacy reason. if ($desired_capabilities instanceof DesiredCapabilities) { $desired_capabilities = $desired_capabilities->toArray(); diff --git a/lib/Remote/Service/DriverCommandExecutor.php b/lib/Remote/Service/DriverCommandExecutor.php index 10ab2b90f..2ac3414f1 100644 --- a/lib/Remote/Service/DriverCommandExecutor.php +++ b/lib/Remote/Service/DriverCommandExecutor.php @@ -38,13 +38,12 @@ public function __construct(DriverService $service) { /** * @param WebDriverCommand $command - * @param array $curl_opts * * @return mixed * @throws WebDriverException * @throws \Exception */ - public function execute(WebDriverCommand $command, $curl_opts = array()) { + public function execute(WebDriverCommand $command) { if ($command->getName() === DriverCommand::NEW_SESSION) { $this->service->start(); } diff --git a/lib/Remote/WebDriverBrowserType.php b/lib/Remote/WebDriverBrowserType.php index 5ab1df391..a9de79143 100644 --- a/lib/Remote/WebDriverBrowserType.php +++ b/lib/Remote/WebDriverBrowserType.php @@ -19,7 +19,6 @@ * All the browsers supported by selenium */ class WebDriverBrowserType { - const FIREFOX = "firefox"; const FIREFOX_2 = "firefox2"; const FIREFOX_3 = "firefox3"; @@ -42,4 +41,8 @@ class WebDriverBrowserType { const IPHONE = "iphone"; const IPAD = "iPad"; const PHANTOMJS = "phantomjs"; + + private function __construct() + { + } } diff --git a/lib/Remote/WebDriverCapabilityType.php b/lib/Remote/WebDriverCapabilityType.php index 552db09be..459952364 100644 --- a/lib/Remote/WebDriverCapabilityType.php +++ b/lib/Remote/WebDriverCapabilityType.php @@ -16,11 +16,9 @@ namespace Facebook\WebDriver\Remote; /** - * WebDriverCapabilityType contains all constants defined in the WebDriver - * Wire Protocol. + * WebDriverCapabilityType contains all constants defined in the WebDriver Wire Protocol. */ class WebDriverCapabilityType { - const BROWSER_NAME = 'browserName'; const VERSION = 'version'; const PLATFORM = 'platform'; @@ -37,4 +35,8 @@ class WebDriverCapabilityType { const ACCEPT_SSL_CERTS = 'acceptSslCerts'; const NATIVE_EVENTS = 'nativeEvents'; const PROXY = 'proxy'; + + private function __construct() + { + } } diff --git a/lib/Remote/WebDriverCommand.php b/lib/Remote/WebDriverCommand.php index 303af3cfb..cb90d2b64 100644 --- a/lib/Remote/WebDriverCommand.php +++ b/lib/Remote/WebDriverCommand.php @@ -16,25 +16,41 @@ namespace Facebook\WebDriver\Remote; class WebDriverCommand { - + /** @var string */ private $sessionID; + /** @var string */ private $name; + /** @var array */ private $parameters; + /** + * @param string $session_id + * @param string $name Constant from DriverCommand + * @param array $parameters Array of + */ public function __construct($session_id, $name, $parameters) { $this->sessionID = $session_id; $this->name = $name; $this->parameters = $parameters; } + /** + * @return string + */ public function getName() { return $this->name; } + /** + * @return string + */ public function getSessionID() { return $this->sessionID; } + /** + * @return array + */ public function getParameters() { return $this->parameters; } diff --git a/lib/WebDriverPlatform.php b/lib/WebDriverPlatform.php index 4954bf56e..9dc42fabd 100644 --- a/lib/WebDriverPlatform.php +++ b/lib/WebDriverPlatform.php @@ -19,7 +19,6 @@ * The platforms supported by WebDriver. */ class WebDriverPlatform { - const ANDROID = 'ANDROID'; const ANY = 'ANY'; const LINUX = 'LINUX'; @@ -28,4 +27,8 @@ class WebDriverPlatform { const VISTA = 'VISTA'; const WINDOWS = 'WINDOWS'; const XP = 'XP'; + + private function __construct() + { + } } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 4dfdec0a7..83eb0ecef 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -2,18 +2,20 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.6/phpunit.xsd" + backupGlobals="false" + backupStaticAttributes="false" + colors="true" + convertErrorsToExceptions="true" + convertNoticesToExceptions="true" + convertWarningsToExceptions="true" + processIsolation="false" + stopOnFailure="false" + bootstrap="tests/bootstrap.php" + > - + tests/unit From ef5d08965a1b641e53d38dafe34617462e31a839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 30 Dec 2015 19:22:40 +0100 Subject: [PATCH 198/784] Define constants with common Firefox profile preferences --- lib/Firefox/FirefoxPreferences.php | 33 ++++++++++++++++++++++++++++++ lib/Firefox/FirefoxProfile.php | 13 ++++++++++++ lib/Remote/DesiredCapabilities.php | 3 ++- 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 lib/Firefox/FirefoxPreferences.php diff --git a/lib/Firefox/FirefoxPreferences.php b/lib/Firefox/FirefoxPreferences.php new file mode 100644 index 000000000..6b7ca91dd --- /dev/null +++ b/lib/Firefox/FirefoxPreferences.php @@ -0,0 +1,33 @@ +preferences)) { + return $this->preferences[$key]; + } + + return null; + } + /** * @return string */ diff --git a/lib/Remote/DesiredCapabilities.php b/lib/Remote/DesiredCapabilities.php index 915d544ec..ef732ec53 100644 --- a/lib/Remote/DesiredCapabilities.php +++ b/lib/Remote/DesiredCapabilities.php @@ -18,6 +18,7 @@ use Exception; use Facebook\WebDriver\Chrome\ChromeOptions; use Facebook\WebDriver\Firefox\FirefoxDriver; +use Facebook\WebDriver\Firefox\FirefoxPreferences; use Facebook\WebDriver\Firefox\FirefoxProfile; use Facebook\WebDriver\WebDriverCapabilities; use Facebook\WebDriver\WebDriverPlatform; @@ -203,7 +204,7 @@ public static function firefox() { // disable the "Reader View" help tooltip, which can hide elements in the window.document $profile = new FirefoxProfile(); - $profile->setPreference('reader.parse-on-load.enabled', false); + $profile->setPreference(FirefoxPreferences::READER_PARSE_ON_LOAD_ENABLED, false); $caps->setCapability(FirefoxDriver::PROFILE, $profile); return $caps; From a0485d418a6841eaaec80b718676e8a8ed618a04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 30 Dec 2015 19:23:23 +0100 Subject: [PATCH 199/784] Unit tests for WebDriverCommand and DesiredCapabilities --- tests/unit/Remote/DesiredCapabilitiesTest.php | 133 ++++++++++++++++++ tests/unit/Remote/WebDriverCommandTest.php | 28 ++++ 2 files changed, 161 insertions(+) create mode 100644 tests/unit/Remote/DesiredCapabilitiesTest.php create mode 100644 tests/unit/Remote/WebDriverCommandTest.php diff --git a/tests/unit/Remote/DesiredCapabilitiesTest.php b/tests/unit/Remote/DesiredCapabilitiesTest.php new file mode 100644 index 000000000..7f187f706 --- /dev/null +++ b/tests/unit/Remote/DesiredCapabilitiesTest.php @@ -0,0 +1,133 @@ + 'fooVal', WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY) + ); + + $this->assertSame('fooVal', $capabilities->getCapability('fooKey')); + $this->assertSame('ANY', $capabilities->getPlatform()); + + $this->assertSame( + array('fooKey' => 'fooVal', WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY), + $capabilities->toArray() + ); + } + + public function testShouldInstantiateEmptyInstance() + { + $capabilities = new DesiredCapabilities(); + + $this->assertNull($capabilities->getCapability('foo')); + $this->assertSame(array(), $capabilities->toArray()); + } + + public function testShouldProvideAccessToCapabilitiesUsingSettersAndGetters() + { + $capabilities = new DesiredCapabilities(); + // generic capability setter + $capabilities->setCapability('custom', 1337); + // specific setters + $capabilities->setBrowserName(WebDriverBrowserType::CHROME); + $capabilities->setPlatform(WebDriverPlatform::LINUX); + $capabilities->setVersion(333); + + $this->assertSame(1337, $capabilities->getCapability('custom')); + $this->assertSame(WebDriverBrowserType::CHROME, $capabilities->getBrowserName()); + $this->assertSame(WebDriverPlatform::LINUX, $capabilities->getPlatform()); + $this->assertSame(333, $capabilities->getVersion()); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage isJavascriptEnable() is a htmlunit-only option + */ + public function testShouldNotAllowToDisableJavascriptForNonHtmlUnitBrowser() + { + $capabilities = new DesiredCapabilities(); + $capabilities->setBrowserName(WebDriverBrowserType::FIREFOX); + $capabilities->setJavascriptEnabled(false); + } + + public function testShouldAllowToDisableJavascriptForHtmlUnitBrowser() + { + $capabilities = new DesiredCapabilities(); + $capabilities->setBrowserName(WebDriverBrowserType::HTMLUNIT); + $capabilities->setJavascriptEnabled(false); + + $this->assertFalse($capabilities->isJavascriptEnabled()); + } + + /** + * @dataProvider browserCapabilitiesProvider + * @param string $setupMethod + * @param string $expectedBrowser + * @param string $expectedPlatform + */ + public function testShouldProvideShortcutSetupForCapabilitiesOfEachBrowser( + $setupMethod, + $expectedBrowser, + $expectedPlatform + ) + { + /** @var DesiredCapabilities $capabilities */ + $capabilities = call_user_func(array('Facebook\WebDriver\Remote\DesiredCapabilities', $setupMethod)); + + $this->assertSame($expectedBrowser, $capabilities->getBrowserName()); + $this->assertSame($expectedPlatform, $capabilities->getPlatform()); + } + + /** + * @return array + */ + public function browserCapabilitiesProvider() + { + return array( + array('android', WebDriverBrowserType::ANDROID, WebDriverPlatform::ANDROID), + array('chrome', WebDriverBrowserType::CHROME, WebDriverPlatform::ANY), + array('firefox', WebDriverBrowserType::FIREFOX, WebDriverPlatform::ANY), + array('htmlUnit', WebDriverBrowserType::HTMLUNIT, WebDriverPlatform::ANY), + array('htmlUnitWithJS', WebDriverBrowserType::HTMLUNIT, WebDriverPlatform::ANY), + array('internetExplorer', WebDriverBrowserType::IE, WebDriverPlatform::WINDOWS), + array('iphone', WebDriverBrowserType::IPHONE, WebDriverPlatform::MAC), + array('ipad', WebDriverBrowserType::IPAD, WebDriverPlatform::MAC), + array('opera', WebDriverBrowserType::OPERA, WebDriverPlatform::ANY), + array('safari', WebDriverBrowserType::SAFARI, WebDriverPlatform::ANY), + array('phantomjs', WebDriverBrowserType::PHANTOMJS, WebDriverPlatform::ANY), + ); + } + + public function testShouldSetupFirefoxProfileAndDisableReaderViewForFirefoxBrowser() + { + $capabilities = DesiredCapabilities::firefox(); + + /** @var FirefoxProfile $firefoxProfile */ + $firefoxProfile = $capabilities->getCapability(FirefoxDriver::PROFILE); + $this->assertInstanceOf('Facebook\WebDriver\Firefox\FirefoxProfile', $firefoxProfile); + + $this->assertSame('false', $firefoxProfile->getPreference(FirefoxPreferences::READER_PARSE_ON_LOAD_ENABLED)); + } +} diff --git a/tests/unit/Remote/WebDriverCommandTest.php b/tests/unit/Remote/WebDriverCommandTest.php new file mode 100644 index 000000000..b4b9fc052 --- /dev/null +++ b/tests/unit/Remote/WebDriverCommandTest.php @@ -0,0 +1,28 @@ + 'bar')); + + $this->assertSame('session-id-123', $command->getSessionID()); + $this->assertSame('bar-baz-name', $command->getName()); + $this->assertSame(array('foo' => 'bar'), $command->getParameters()); + } +} From a7fd742c06ffc594cac8ccbec539f1196dcfabc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 1 Jan 2016 17:06:12 +0100 Subject: [PATCH 200/784] Added CHANGELOG.md (fixes #275) --- CHANGELOG.md | 14 ++++++++++++++ README.md | 19 +++++++++++-------- 2 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..2229754c1 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog +This project versioning adheres to [Semantic Versioning](http://semver.org/). + +## Unreleased +- Added CHANGELOG.md + +## 1.1.1 - 2015-12-31 +- Fixed strict standards error in `ChromeDriver` +- Added unit tests for `WebDriverCommand` and `DesiredCapabilities` +- Fixed retrieving temporary path name in `FirefoxDriver` when `open_basedir` restriction is in effect + +## 1.1.0 - 2015-12-08 +- FirefoxProfile improved - added possibility to set RDF file and to add datas for extensions +- Fixed setting 0 second timeout of `WebDriverWait` diff --git a/README.md b/README.md index 7beb7564c..5f2b0a958 100644 --- a/README.md +++ b/README.md @@ -77,15 +77,10 @@ Install the library. RemoteWebDriver::create($host, $desired_capabilities); ``` -* See https://code.google.com/p/selenium/wiki/DesiredCapabilities for more details. +* See https://code.google.com/p/selenium/wiki/DesiredCapabilities for more details. -## RUN UNIT TESTS - -To run unit tests simply run: - - ./vendor/bin/phpunit -c ./tests - -Note: For the functional test suite, a running selenium server is required. +## Changelog +For latest changes see [CHANGELOG.md](CHANGELOG.md) file. ## MORE INFORMATION @@ -118,3 +113,11 @@ We love to have your help to make php-webdriver better. Feel free to When you are going to contribute, please keep in mind that this webdriver client aims to be as close as possible to other languages Java/Ruby/Python/C#. FYI, here is the overview of [the official Java API](http://selenium.googlecode.com/svn/trunk/docs/api/java/index.html?overview-summary.html) + +### Run unit tests + +To run unit tests simply run: + + ./vendor/bin/phpunit -c ./tests + +Note: For the functional test suite, a running selenium server is required. From f89848df63108c8938e2c1cc45addd0c6d56e718 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 1 Jan 2016 17:21:26 +0100 Subject: [PATCH 201/784] Cleanup README a bit --- README.md | 66 ++++++++++++++++++++++--------------------------------- 1 file changed, 26 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 5f2b0a958..cf25e6021 100644 --- a/README.md +++ b/README.md @@ -1,75 +1,61 @@ -php-webdriver -- WebDriver bindings for PHP +php-webdriver – WebDriver bindings for PHP =========================================== -## DESCRIPTION +## Description +Php-webdriver library is PHP language binding for Selenium WebDriver, which allows you to control web browsers from PHP. -This WebDriver client aims to be as close as possible to bindings in other languages. The concepts are very similar to the Java, .NET, Python and Ruby bindings for WebDriver. +This WebDriver client aims to be as close as possible to bindings in other languages. +The concepts are very similar to the Java, .NET, Python and Ruby bindings for WebDriver. -Looking for documentation about php-webdriver? See http://facebook.github.io/php-webdriver/ +This is new version of PHP client, rewritten from scratch starting 2013. +Using the old version? Check out Adam Goucher's fork of it at https://github.com/Element-34/php-webdriver -The PHP client was rewritten from scratch. Using the old version? Check out Adam Goucher's fork of it at https://github.com/Element-34/php-webdriver +Looking for API documentation of php-webdriver? See http://facebook.github.io/php-webdriver/ Any complaint, question, idea? You can post it on the user group https://www.facebook.com/groups/phpwebdriver/. -## GETTING THE CODE +## Installation -There are two ways of getting the code: +Installation is possible using [Composer](https://getcomposer.org/). -### Via Github - git clone git@github.com:facebook/php-webdriver.git - -### Via Packagist -Add the dependency to composer.json (see https://packagist.org/packages/facebook/webdriver) - -```json -{ - "require": { - "facebook/webdriver": "~1.0" - } -} -``` - -## INSTALLATION - -Download the composer.phar +If you don't already use Composer, you can download the `composer.phar` binary: curl -sS https://getcomposer.org/installer | php -Install the library. - - php composer.phar install +Then install the library: + php composer.phar require facebook/webdriver -## GETTING STARTED +## Getting started -* All you need as the server for this client is the selenium-server-standalone-#.jar file provided here: http://selenium-release.storage.googleapis.com/index.html +All you need as the server for this client is the `selenium-server-standalone-#.jar` file provided here: http://selenium-release.storage.googleapis.com/index.html -* Download and run that file, replacing # with the current server version. +* Download and run that file, replacing # with the current server version. ``` java -jar selenium-server-standalone-#.jar ``` -* Then when you create a session, be sure to pass the url to where your server is running. +Then when you create a session, be sure to pass the url to where your server is running. ```php // This would be the url of the host running the server-standalone.jar $host = 'http://localhost:4444/wd/hub'; // this is the default ``` -* Launch Firefox +* Launch Firefox: ```php $driver = RemoteWebDriver::create($host, DesiredCapabilities::firefox()); ``` -* Launch Chrome +* Launch Chrome: ```php $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome()); ``` -* You can also customize the desired capabilities. +You can also customize the desired capabilities: ```php $desired_capabilities = DesiredCapabilities::firefox(); @@ -82,13 +68,13 @@ Install the library. ## Changelog For latest changes see [CHANGELOG.md](CHANGELOG.md) file. -## MORE INFORMATION +## More information Check out the Selenium docs and wiki at http://docs.seleniumhq.org/docs/ and https://code.google.com/p/selenium/wiki Learn how to integrate it with PHPUnit [Blogpost](http://codeception.com/11-12-2013/working-with-phpunit-and-selenium-webdriver.html) | [Demo Project](https://github.com/DavertMik/php-webdriver-demo) -## SUPPORT +## Support We have a great community willing to try and help you! @@ -104,12 +90,12 @@ https://www.facebook.com/groups/phpwebdriver/ If you're reading this you've already found our Github repository. If you have a question, feel free to submit it as an issue and our staff will do their best to help you as soon as possible. -## CONTRIBUTING +## Contributing -We love to have your help to make php-webdriver better. Feel free to +We love to have your help to make php-webdriver better. Feel free to -* open an [issue](https://github.com/facebook/php-webdriver/issues) if you run into any problem. -* fork the project and submit [pull request](https://github.com/facebook/php-webdriver/pulls). Before the pull requests can be accepted, a [Contributors Licensing Agreement](http://developers.facebook.com/opensource/cla) must be signed. +* open an [issue](https://github.com/facebook/php-webdriver/issues) if you run into any problem. +* fork the project and submit [pull request](https://github.com/facebook/php-webdriver/pulls). Before the pull requests can be accepted, a [Contributors Licensing Agreement](http://developers.facebook.com/opensource/cla) must be signed. When you are going to contribute, please keep in mind that this webdriver client aims to be as close as possible to other languages Java/Ruby/Python/C#. FYI, here is the overview of [the official Java API](http://selenium.googlecode.com/svn/trunk/docs/api/java/index.html?overview-summary.html) From 5f55880ea3eb0d3820c0731c9e6a33f801e9f707 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 1 Jan 2016 17:22:06 +0100 Subject: [PATCH 202/784] Fix not working example in README (setJavascriptEnabled works only for htmlUnit browser, not Firefox --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cf25e6021..42883b931 100644 --- a/README.md +++ b/README.md @@ -59,8 +59,8 @@ You can also customize the desired capabilities: ```php $desired_capabilities = DesiredCapabilities::firefox(); - $desired_capabilities->setJavascriptEnabled(false); - RemoteWebDriver::create($host, $desired_capabilities); + $desired_capabilities->setCapability('acceptSslCerts', false); + $driver = RemoteWebDriver::create($host, $desired_capabilities); ``` * See https://code.google.com/p/selenium/wiki/DesiredCapabilities for more details. From 49127be66fde8657080e1d48c26051f06a3b1cbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Mon, 4 Jan 2016 18:17:28 +0100 Subject: [PATCH 203/784] Added information and rules for contributors --- CHANGELOG.md | 1 + CONTRIBUTING.md | 36 ++++++++++++++++++++++++++++++++++++ README.md | 17 ++--------------- 3 files changed, 39 insertions(+), 15 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 2229754c1..ff5496df5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased - Added CHANGELOG.md +- Added CONTRIBUTING.md with information and rules for contributors ## 1.1.1 - 2015-12-31 - Fixed strict standards error in `ChromeDriver` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..1da3f3d35 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,36 @@ +# Contributing to php-webdriver + +We love to have your help to make php-webdriver better! + +Feel free to open an [issue](https://github.com/facebook/php-webdriver/issues) if you run into any problem, or +send a pull request (see bellow) with your contribution. + +## Workflow when contributing a patch + +1. Fork the project on GitHub +2. Implement your code changes into separate branch +3. Make sure all PHPUnit tests passes (see below). We also have Travis CI build which will automatically run tests on your pull request). +4. When implementing notable change, fix or a new feature, add record to Unreleased section of [CHANGELOG.md](CHANGELOG.md) +5. Submit your [pull request](https://github.com/facebook/php-webdriver/pulls) against community branch + +Note before any pull request can be accepted, a [Contributors Licensing Agreement](http://developers.facebook.com/opensource/cla) must be signed. + +When you are going to contribute, please keep in mind that this webdriver client aims to be as close as possible to other languages Java/Ruby/Python/C#. +FYI, here is the overview of [the official Java API](http://selenium.googlecode.com/svn/trunk/docs/api/java/index.html?overview-summary.html) + +### Run unit tests + +There are two test-suites: one with unit tests only, second with functional tests, which require running selenium server. + +To execute all tests simply run: + + ./vendor/bin/phpunit + +If you want to execute just the unit tests, run: + + ./vendor/bin/phpunit --testsuite Unit-Testsuite + +For the functional tests you must first download and start the selenium server, then run the `Functional-Testsuite` test suite: + + java -jar selenium-server-standalone-2.48.2.jar -log selenium.log & + ./vendor/bin/phpunit --testsuite Functional-Testsuite diff --git a/README.md b/README.md index 42883b931..a69a01f54 100644 --- a/README.md +++ b/README.md @@ -92,18 +92,5 @@ If you're reading this you've already found our Github repository. If you have a ## Contributing -We love to have your help to make php-webdriver better. Feel free to - -* open an [issue](https://github.com/facebook/php-webdriver/issues) if you run into any problem. -* fork the project and submit [pull request](https://github.com/facebook/php-webdriver/pulls). Before the pull requests can be accepted, a [Contributors Licensing Agreement](http://developers.facebook.com/opensource/cla) must be signed. - -When you are going to contribute, please keep in mind that this webdriver client aims to be as close as possible to other languages Java/Ruby/Python/C#. -FYI, here is the overview of [the official Java API](http://selenium.googlecode.com/svn/trunk/docs/api/java/index.html?overview-summary.html) - -### Run unit tests - -To run unit tests simply run: - - ./vendor/bin/phpunit -c ./tests - -Note: For the functional test suite, a running selenium server is required. +We love to have your help to make php-webdriver better. See [CONTRIBUTING.md](CONTRIBUTING.md) for more information +about contributing and developing php-webdriver. From bc48fe4584e9816e6a8f4f7a2b7ecfda091850d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 5 Jan 2016 08:36:56 +0100 Subject: [PATCH 204/784] Rename test suites to make them easier to write --- CONTRIBUTING.md | 6 +++--- phpunit.xml.dist | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1da3f3d35..b426d475d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,9 +28,9 @@ To execute all tests simply run: If you want to execute just the unit tests, run: - ./vendor/bin/phpunit --testsuite Unit-Testsuite + ./vendor/bin/phpunit --testsuite unit -For the functional tests you must first download and start the selenium server, then run the `Functional-Testsuite` test suite: +For the functional tests you must first download and start the selenium server, then run the `functional` test suite: java -jar selenium-server-standalone-2.48.2.jar -log selenium.log & - ./vendor/bin/phpunit --testsuite Functional-Testsuite + ./vendor/bin/phpunit --testsuite functional diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 83eb0ecef..06dee9c0f 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -15,12 +15,12 @@ bootstrap="tests/bootstrap.php" > - - + + tests/unit - - tests/functional/ + + tests/functional From ebed69f8404ca5ca1ad4468b6bae9cb93e31a231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 6 Jan 2016 22:09:11 +0100 Subject: [PATCH 205/784] Fix code markdown in README --- README.md | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index a69a01f54..9f8d34d3d 100644 --- a/README.md +++ b/README.md @@ -30,18 +30,16 @@ Then install the library: All you need as the server for this client is the `selenium-server-standalone-#.jar` file provided here: http://selenium-release.storage.googleapis.com/index.html -* Download and run that file, replacing # with the current server version. +Download and run that file, replacing # with the current server version. - ``` java -jar selenium-server-standalone-#.jar - ``` Then when you create a session, be sure to pass the url to where your server is running. - ```php - // This would be the url of the host running the server-standalone.jar - $host = 'http://localhost:4444/wd/hub'; // this is the default - ``` +```php +// This would be the url of the host running the server-standalone.jar +$host = 'http://localhost:4444/wd/hub'; // this is the default +``` * Launch Firefox: @@ -57,11 +55,11 @@ Then when you create a session, be sure to pass the url to where your server is You can also customize the desired capabilities: - ```php - $desired_capabilities = DesiredCapabilities::firefox(); - $desired_capabilities->setCapability('acceptSslCerts', false); - $driver = RemoteWebDriver::create($host, $desired_capabilities); - ``` +```php +$desired_capabilities = DesiredCapabilities::firefox(); +$desired_capabilities->setCapability('acceptSslCerts', false); +$driver = RemoteWebDriver::create($host, $desired_capabilities); +``` * See https://code.google.com/p/selenium/wiki/DesiredCapabilities for more details. From 017bf3bc88d3ae2cf5a8e98c8004bec1f2835927 Mon Sep 17 00:00:00 2001 From: Lars Moelleken Date: Mon, 1 Feb 2016 13:17:53 +0100 Subject: [PATCH 206/784] [+]: fixed function-call from "$checker->waitUntilUnAvailable()" -> "$checker->waitUntilUnavailable()" [~]: "\t" -> spaces [~]: "dirname(__FILE__)" -> "__DIR__" [*]: "" -> --- lib/Firefox/FirefoxProfile.php | 21 ++++++++++++--------- lib/Remote/Service/DriverService.php | 2 +- tests/functional/WebDriverTestCase.php | 6 +++--- tests/functional/html/upload.html | 2 +- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index bf23e5e7a..651e0b2eb 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -131,10 +131,10 @@ public function encode() { $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($extension_datas, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST); foreach ($iterator as $item) { if ($item->isDir()) { - mkdir($temp_dir . DIRECTORY_SEPARATOR . $dirname . DIRECTORY_SEPARATOR . $iterator->getSubPathName()); - } else { - copy($item, $temp_dir . DIRECTORY_SEPARATOR . $dirname . DIRECTORY_SEPARATOR . $iterator->getSubPathName()); - } + mkdir($temp_dir . DIRECTORY_SEPARATOR . $dirname . DIRECTORY_SEPARATOR . $iterator->getSubPathName()); + } else { + copy($item, $temp_dir . DIRECTORY_SEPARATOR . $dirname . DIRECTORY_SEPARATOR . $iterator->getSubPathName()); + } } } @@ -150,15 +150,18 @@ public function encode() { $dir = new RecursiveDirectoryIterator($temp_dir); $files = new RecursiveIteratorIterator($dir); + + $dir_prefix = preg_replace( + '#\\\\#', + '\\\\\\\\', + $temp_dir.DIRECTORY_SEPARATOR + ); + foreach ($files as $name => $object) { if (is_dir($name)) { continue; } - $dir_prefix = preg_replace( - '#\\\\#', - '\\\\\\\\', - $temp_dir.DIRECTORY_SEPARATOR - ); + $path = preg_replace("#^{$dir_prefix}#", "", $name); $zip->addFile($name, $path); } diff --git a/lib/Remote/Service/DriverService.php b/lib/Remote/Service/DriverService.php index 09ad7c815..8a18e5d5d 100644 --- a/lib/Remote/Service/DriverService.php +++ b/lib/Remote/Service/DriverService.php @@ -109,7 +109,7 @@ public function stop() { $this->process = null; $checker = new URLChecker(); - $checker->waitUntilUnAvailable(3 * 1000, $this->url.'/shutdown'); + $checker->waitUntilUnavailable(3 * 1000, $this->url.'/shutdown'); return $this; } diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index 73b3c2b58..9be2153d3 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -40,8 +40,8 @@ protected function setUp() { protected function tearDown() { if ($this->driver) { - $this->driver->quit(); - } + $this->driver->quit(); + } } /** @@ -51,6 +51,6 @@ protected function tearDown() { * @return string */ protected function getTestPath($path) { - return 'file:///'.dirname(__FILE__).'/html/'.$path; + return 'file:///'.__DIR__.'/html/'.$path; } } diff --git a/tests/functional/html/upload.html b/tests/functional/html/upload.html index d542ad04f..ed03702d3 100644 --- a/tests/functional/html/upload.html +++ b/tests/functional/html/upload.html @@ -4,7 +4,7 @@
- +
From 61274d2fa4b38162e7b25391321484fa8164da30 Mon Sep 17 00:00:00 2001 From: Lars Moelleken Date: Mon, 1 Feb 2016 13:18:53 +0100 Subject: [PATCH 207/784] [+]: ".gitattributes" <- prevent installing special files via composer --- .gitattributes | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..c3b6383af --- /dev/null +++ b/.gitattributes @@ -0,0 +1,8 @@ +* text=auto + +/tests export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/.travis.yml export-ignore +/example.php export-ignore +/phpunit.xml.dist export-ignore From 0f3048f2499285538a8be240afa9d722aa6fe1d4 Mon Sep 17 00:00:00 2001 From: javier gomez Date: Thu, 25 Feb 2016 10:39:39 +0100 Subject: [PATCH 208/784] Enhance moveToElement method description --- lib/Interactions/WebDriverActions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Interactions/WebDriverActions.php b/lib/Interactions/WebDriverActions.php index 4d8a623d8..3e11b3c0a 100644 --- a/lib/Interactions/WebDriverActions.php +++ b/lib/Interactions/WebDriverActions.php @@ -168,8 +168,8 @@ public function moveByOffset($x_offset, $y_offset) { } /** - * Move to the middle of the given WebDriverElement. If offset are provided, - * move the an offset from the top-left cornerof that element. + * Move to the middle of the given WebDriverElement. + * Extra shift, calculated from the top-left corner of the element, can be set by passing $x_offset and $y_offset parameters. * * @param WebDriverElement $element * @param int $x_offset From 09ec61c59a8fd86bd02b9efa28748ccc2ba6444a Mon Sep 17 00:00:00 2001 From: phpdave Date: Tue, 15 Mar 2016 09:12:55 -0400 Subject: [PATCH 209/784] Updated Readme to fix DesiredCapabilities link Fixing this issue https://github.com/facebook/php-webdriver/issues/283 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f8d34d3d..146d45ad6 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ $desired_capabilities->setCapability('acceptSslCerts', false); $driver = RemoteWebDriver::create($host, $desired_capabilities); ``` -* See https://code.google.com/p/selenium/wiki/DesiredCapabilities for more details. +* See https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities for more details. ## Changelog For latest changes see [CHANGELOG.md](CHANGELOG.md) file. From 46661a59a094469227c5b10c6e8716f71079ec03 Mon Sep 17 00:00:00 2001 From: Jan Kohlhof Date: Fri, 11 Mar 2016 22:55:45 +0100 Subject: [PATCH 210/784] Added ext-curl as dependency As suggested correctly in #279 --- CHANGELOG.md | 1 + composer.json | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff5496df5..103ffee19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +- Added ext-curl to composer.json - Added CHANGELOG.md - Added CONTRIBUTING.md with information and rules for contributors diff --git a/composer.json b/composer.json index be4ba7dd5..682e72479 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,8 @@ "source": "https://github.com/facebook/php-webdriver" }, "require": { - "php": ">=5.3.19" + "php": ">=5.3.19", + "ext-curl": "*" }, "require-dev": { "phpunit/phpunit": "4.6.*" From a7834be0fed2770ca9b760b443c10267352a917e Mon Sep 17 00:00:00 2001 From: Scott Davey Date: Mon, 9 May 2016 17:30:24 +1000 Subject: [PATCH 211/784] Fixed PHP Fatal crash in RemoteWebDriver:507 --- lib/Remote/RemoteWebDriver.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index 1fda245b2..8fb7003c1 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -504,7 +504,11 @@ public function execute($command_name, $params = array()) { $params ); - $response = $this->executor->execute($command); - return $response->getValue(); + if ($this->executor) { + $response = $this->executor->execute($command); + return $response->getValue(); + } else { + return null; + } } } From 0eb0a0ad8c7177a5071d17853c982ba2507d25f3 Mon Sep 17 00:00:00 2001 From: Andre Fortin Date: Fri, 3 Jun 2016 19:38:44 -0400 Subject: [PATCH 212/784] Throw exception if extension doesn't exist. Update to make extractTo() throw an exception if the Firefox extension .xpi file doesn't exist, which should be the desired behavior. Currently extractTo() only throws an error if the .xpi file exists AND is unable to open. ZipArchive throws some Warning messages when you use extractTo() and close() on an initialized ZipArchive object which is the case if the file doesn't exist. --- lib/Firefox/FirefoxProfile.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index 651e0b2eb..9617f4e77 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -249,11 +249,15 @@ private function deleteDirectory($directory) { */ private function extractTo($xpi, $target_dir) { $zip = new ZipArchive(); - if ($zip->open($xpi)) { - $zip->extractTo($target_dir); - $zip->close(); + if (file_exists($xpi)) { + if ($zip->open($xpi)) { + $zip->extractTo($target_dir); + $zip->close(); + } else { + throw new \Exception("Failed to open the firefox extension. '$xpi'"); + } } else { - throw new \Exception("Failed to open the firefox extension. '$xpi'"); + throw new \Exception("Firefox extension doesn't exist. '$xpi'"); } return $this; } From 14a6ff7d8b7f8303c79ac5154a9da9041817c089 Mon Sep 17 00:00:00 2001 From: Andre Fortin Date: Sat, 4 Jun 2016 02:11:38 -0400 Subject: [PATCH 213/784] Fixed Hardcoded 'em' namespace in installExtension() prevents some extensions from loading:507 --- lib/Firefox/FirefoxProfile.php | 42 ++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index 9617f4e77..03830dc63 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -183,21 +183,33 @@ public function encode() { */ private function installExtension($extension, $profile_dir) { $temp_dir = $this->createTempDirectory('WebDriverFirefoxProfileExtension'); - - $this->extractTo($extension, $temp_dir); - - $install_rdf_path = $temp_dir.'/install.rdf'; - // This is a hacky way to parse the id since there is no offical - // RDF parser library. - $matches = array(); - $xml = file_get_contents($install_rdf_path); - preg_match('#([^<]+)#', $xml, $matches); - $ext_dir = $profile_dir.'/extensions/'.$matches[1]; - - mkdir($ext_dir, 0777, true); - - $this->extractTo($extension, $ext_dir); - + $this->extractTo($extension, $temp_dir); + + // This is a hacky way to parse the id since there is no offical RDF parser library. + // Find the correct namespace for the id element. + $install_rdf_path = $temp_dir.'/install.rdf'; + $xml = simplexml_load_file($install_rdf_path); + $ns = $xml->getDocNamespaces(); + $prefix = ''; + if (!empty($ns)) { + foreach($ns as $key => $value) { + if (strpos($value, '//www.mozilla.org/2004/em-rdf') > 0) { + if ($key != '') { + $prefix = $key . ':'; // Separate the namespace from the name. + } + break; + } + } + } + // Get the extension id from the install manifest. + $matches = array(); + preg_match('#<'.$prefix.'id>([^<]+)#', $xml->asXML(), $matches); + if (isset($matches[1])) { + $ext_dir = $profile_dir.'/extensions/'.$matches[1]; + mkdir($ext_dir, 0777, true); + $this->extractTo($extension, $ext_dir); + } + // clean up $this->deleteDirectory($temp_dir); From 4dc9974e643a9330d6c614bcf2c4454c200f922a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 19 Jul 2016 02:09:35 +0200 Subject: [PATCH 214/784] Update changelog according to latest release --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 103ffee19..02933ab90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +- Fixed FirefoxProfile to support installation of extensions with custom namespace prefix in their manifest file + +## 1.1.2 - 2016-06-04 - Added ext-curl to composer.json - Added CHANGELOG.md - Added CONTRIBUTING.md with information and rules for contributors From 29a41cb8e7f590ffdc613dab9a28ebafd5af5c83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 30 Jul 2016 14:55:20 +0200 Subject: [PATCH 215/784] Allow PHPUnit 5.x for unit tests --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 682e72479..43c61fa88 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "ext-curl": "*" }, "require-dev": { - "phpunit/phpunit": "4.6.*" + "phpunit/phpunit": "4.6.* || ~5.0" }, "suggest": { "phpdocumentor/phpdocumentor": "2.*" From 1f158a0091db69ee82d1e1be604fbee15d230537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 30 Jul 2016 14:55:34 +0200 Subject: [PATCH 216/784] Replace deprecated ->getMock() call --- .../Internal/WebDriverButtonReleaseActionTest.php | 4 ++-- .../unit/Interactions/Internal/WebDriverClickActionTest.php | 4 ++-- .../Internal/WebDriverClickAndHoldActionTest.php | 4 ++-- .../Internal/WebDriverContextClickActionTest.php | 4 ++-- .../Internal/WebDriverDoubleClickActionTest.php | 4 ++-- .../Interactions/Internal/WebDriverKeyDownActionTest.php | 6 +++--- .../unit/Interactions/Internal/WebDriverKeyUpActionTest.php | 6 +++--- .../Interactions/Internal/WebDriverMouseMoveActionTest.php | 4 ++-- .../Internal/WebDriverMouseToOffsetActionTest.php | 4 ++-- .../Interactions/Internal/WebDriverSendKeysActionTest.php | 6 +++--- 10 files changed, 23 insertions(+), 23 deletions(-) diff --git a/tests/unit/Interactions/Internal/WebDriverButtonReleaseActionTest.php b/tests/unit/Interactions/Internal/WebDriverButtonReleaseActionTest.php index 982e8d268..58373d9b9 100644 --- a/tests/unit/Interactions/Internal/WebDriverButtonReleaseActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverButtonReleaseActionTest.php @@ -27,8 +27,8 @@ class WebDriverButtonReleaseActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); + $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); + $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); $this->webDriverButtonReleaseAction = new WebDriverButtonReleaseAction( $this->webDriverMouse, $this->locationProvider diff --git a/tests/unit/Interactions/Internal/WebDriverClickActionTest.php b/tests/unit/Interactions/Internal/WebDriverClickActionTest.php index 8fab683fe..c58d507d1 100644 --- a/tests/unit/Interactions/Internal/WebDriverClickActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverClickActionTest.php @@ -27,8 +27,8 @@ class WebDriverClickActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); + $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); + $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); $this->webDriverClickAction = new WebDriverClickAction( $this->webDriverMouse, $this->locationProvider diff --git a/tests/unit/Interactions/Internal/WebDriverClickAndHoldActionTest.php b/tests/unit/Interactions/Internal/WebDriverClickAndHoldActionTest.php index b10ac2cea..ae046c58e 100644 --- a/tests/unit/Interactions/Internal/WebDriverClickAndHoldActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverClickAndHoldActionTest.php @@ -27,8 +27,8 @@ class WebDriverClickAndHoldActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); + $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); + $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); $this->webDriverClickAndHoldAction = new WebDriverClickAndHoldAction( $this->webDriverMouse, $this->locationProvider diff --git a/tests/unit/Interactions/Internal/WebDriverContextClickActionTest.php b/tests/unit/Interactions/Internal/WebDriverContextClickActionTest.php index a57cb127a..d9b9ef2b8 100644 --- a/tests/unit/Interactions/Internal/WebDriverContextClickActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverContextClickActionTest.php @@ -27,8 +27,8 @@ class WebDriverContextClickActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); + $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); + $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); $this->webDriverContextClickAction = new WebDriverContextClickAction( $this->webDriverMouse, $this->locationProvider diff --git a/tests/unit/Interactions/Internal/WebDriverDoubleClickActionTest.php b/tests/unit/Interactions/Internal/WebDriverDoubleClickActionTest.php index 7f09f64dc..f1c6d3a02 100644 --- a/tests/unit/Interactions/Internal/WebDriverDoubleClickActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverDoubleClickActionTest.php @@ -27,8 +27,8 @@ class WebDriverDoubleClickActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); + $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); + $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); $this->webDriverDoubleClickAction = new WebDriverDoubleClickAction( $this->webDriverMouse, $this->locationProvider diff --git a/tests/unit/Interactions/Internal/WebDriverKeyDownActionTest.php b/tests/unit/Interactions/Internal/WebDriverKeyDownActionTest.php index 5bba82f4f..10a6201e0 100644 --- a/tests/unit/Interactions/Internal/WebDriverKeyDownActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverKeyDownActionTest.php @@ -30,9 +30,9 @@ class WebDriverKeyDownActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverKeyboard = $this->getMock('Facebook\WebDriver\WebDriverKeyboard'); - $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); + $this->webDriverKeyboard = $this->getMockBuilder('Facebook\WebDriver\WebDriverKeyboard')->getMock(); + $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); + $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); $this->webDriverKeyDownAction = new WebDriverKeyDownAction( $this->webDriverKeyboard, diff --git a/tests/unit/Interactions/Internal/WebDriverKeyUpActionTest.php b/tests/unit/Interactions/Internal/WebDriverKeyUpActionTest.php index cd2b7b00c..75fb1bde9 100644 --- a/tests/unit/Interactions/Internal/WebDriverKeyUpActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverKeyUpActionTest.php @@ -30,9 +30,9 @@ class WebDriverKeyUpActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverKeyboard = $this->getMock('Facebook\WebDriver\WebDriverKeyboard'); - $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); + $this->webDriverKeyboard = $this->getMockBuilder('Facebook\WebDriver\WebDriverKeyboard')->getMock(); + $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); + $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); $this->webDriverKeyUpAction = new WebDriverKeyUpAction( $this->webDriverKeyboard, diff --git a/tests/unit/Interactions/Internal/WebDriverMouseMoveActionTest.php b/tests/unit/Interactions/Internal/WebDriverMouseMoveActionTest.php index 6376adfa0..10edb2588 100644 --- a/tests/unit/Interactions/Internal/WebDriverMouseMoveActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverMouseMoveActionTest.php @@ -27,8 +27,8 @@ class WebDriverMouseMoveActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); + $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); + $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); $this->webDriverMouseMoveAction = new WebDriverMouseMoveAction( $this->webDriverMouse, diff --git a/tests/unit/Interactions/Internal/WebDriverMouseToOffsetActionTest.php b/tests/unit/Interactions/Internal/WebDriverMouseToOffsetActionTest.php index 2ea16d552..aeec43a5a 100644 --- a/tests/unit/Interactions/Internal/WebDriverMouseToOffsetActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverMouseToOffsetActionTest.php @@ -29,8 +29,8 @@ class WebDriverMouseToOffsetActionTest extends \PHPUnit_Framework_TestCase { private $locationProvider; public function setUp() { - $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); + $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); + $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); $this->webDriverMoveToOffsetAction = new WebDriverMoveToOffsetAction( $this->webDriverMouse, diff --git a/tests/unit/Interactions/Internal/WebDriverSendKeysActionTest.php b/tests/unit/Interactions/Internal/WebDriverSendKeysActionTest.php index f7c2917d0..bf1a5b8a7 100644 --- a/tests/unit/Interactions/Internal/WebDriverSendKeysActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverSendKeysActionTest.php @@ -32,9 +32,9 @@ class WebDriverSendKeysActionTest extends \PHPUnit_Framework_TestCase { private $keys; public function setUp() { - $this->webDriverKeyboard = $this->getMock('Facebook\WebDriver\WebDriverKeyboard'); - $this->webDriverMouse = $this->getMock('Facebook\WebDriver\WebDriverMouse'); - $this->locationProvider = $this->getMock('Facebook\WebDriver\Internal\WebDriverLocatable'); + $this->webDriverKeyboard = $this->getMockBuilder('Facebook\WebDriver\WebDriverKeyboard')->getMock(); + $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); + $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); $this->keys = array('t', 'e', 's', 't'); $this->webDriverSendKeysAction = new WebDriverSendKeysAction( From c051b545cbd566f87d05ce99a5bcfad2e5e0ae28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 30 Jul 2016 16:16:16 +0200 Subject: [PATCH 217/784] PSR-2 codestyle --- CHANGELOG.md | 1 + lib/Chrome/ChromeDriver.php | 116 +- lib/Chrome/ChromeDriverService.php | 23 +- lib/Chrome/ChromeOptions.php | 275 ++--- .../ElementNotSelectableException.php | 7 +- lib/Exception/ElementNotVisibleException.php | 6 +- lib/Exception/ExpectedException.php | 7 +- .../IMEEngineActivationFailedException.php | 7 +- lib/Exception/IMENotAvailableException.php | 7 +- lib/Exception/IndexOutOfBoundsException.php | 6 +- .../InvalidCookieDomainException.php | 6 +- lib/Exception/InvalidCoordinatesException.php | 7 +- .../InvalidElementStateException.php | 6 +- lib/Exception/InvalidSelectorException.php | 7 +- .../MoveTargetOutOfBoundsException.php | 7 +- lib/Exception/NoAlertOpenException.php | 6 +- lib/Exception/NoCollectionException.php | 6 +- lib/Exception/NoScriptResultException.php | 6 +- lib/Exception/NoStringException.php | 6 +- lib/Exception/NoStringLengthException.php | 6 +- lib/Exception/NoStringWrapperException.php | 6 +- lib/Exception/NoSuchCollectionException.php | 6 +- lib/Exception/NoSuchDocumentException.php | 7 +- lib/Exception/NoSuchDriverException.php | 6 +- lib/Exception/NoSuchElementException.php | 6 +- lib/Exception/NoSuchFrameException.php | 6 +- lib/Exception/NoSuchWindowException.php | 6 +- lib/Exception/NullPointerException.php | 7 +- lib/Exception/ScriptTimeoutException.php | 7 +- lib/Exception/SessionNotCreatedException.php | 7 +- .../StaleElementReferenceException.php | 6 +- lib/Exception/TimeOutException.php | 6 +- lib/Exception/UnableToSetCookieException.php | 6 +- .../UnexpectedAlertOpenException.php | 6 +- .../UnexpectedJavascriptException.php | 6 +- lib/Exception/UnexpectedTagNameException.php | 36 +- lib/Exception/UnknownCommandException.php | 6 +- lib/Exception/UnknownServerException.php | 6 +- .../UnrecognizedExceptionException.php | 7 +- .../UnsupportedOperationException.php | 7 +- lib/Exception/WebDriverCurlException.php | 7 +- lib/Exception/WebDriverException.php | 285 ++--- lib/Exception/XPathLookupException.php | 6 +- lib/Firefox/FirefoxDriver.php | 11 +- lib/Firefox/FirefoxPreferences.php | 21 +- lib/Firefox/FirefoxProfile.php | 479 +++++---- .../Internal/WebDriverButtonReleaseAction.php | 13 +- .../Internal/WebDriverClickAction.php | 13 +- .../Internal/WebDriverClickAndHoldAction.php | 13 +- .../Internal/WebDriverContextClickAction.php | 13 +- .../Internal/WebDriverCoordinates.php | 89 +- .../Internal/WebDriverDoubleClickAction.php | 13 +- .../Internal/WebDriverKeyDownAction.php | 15 +- .../Internal/WebDriverKeyUpAction.php | 15 +- .../Internal/WebDriverKeysRelatedAction.php | 51 +- .../Internal/WebDriverMouseAction.php | 63 +- .../Internal/WebDriverMouseMoveAction.php | 13 +- .../Internal/WebDriverMoveToOffsetAction.php | 44 +- .../Internal/WebDriverSendKeysAction.php | 48 +- .../Internal/WebDriverSingleKeyAction.php | 27 +- .../Touch/WebDriverDoubleTapAction.php | 13 +- .../Touch/WebDriverDownAction.php | 38 +- .../Touch/WebDriverFlickAction.php | 34 +- .../Touch/WebDriverFlickFromElementAction.php | 64 +- .../Touch/WebDriverLongPressAction.php | 13 +- .../Touch/WebDriverMoveAction.php | 38 +- .../Touch/WebDriverScrollAction.php | 38 +- .../WebDriverScrollFromElementAction.php | 54 +- lib/Interactions/Touch/WebDriverTapAction.php | 13 +- .../Touch/WebDriverTouchAction.php | 65 +- .../Touch/WebDriverTouchScreen.php | 185 ++-- lib/Interactions/WebDriverActions.php | 473 +++++---- lib/Interactions/WebDriverCompositeAction.php | 58 +- lib/Interactions/WebDriverTouchActions.php | 304 +++--- lib/Internal/WebDriverLocatable.php | 14 +- lib/JavaScriptExecutor.php | 53 +- lib/Net/URLChecker.php | 102 +- lib/Remote/DesiredCapabilities.php | 557 +++++----- lib/Remote/DriverCommand.php | 275 +++-- lib/Remote/ExecuteMethod.php | 16 +- lib/Remote/FileDetector.php | 22 +- lib/Remote/HttpCommandExecutor.php | 564 +++++----- lib/Remote/LocalFileDetector.php | 15 +- lib/Remote/RemoteExecuteMethod.php | 39 +- lib/Remote/RemoteKeyboard.php | 105 +- lib/Remote/RemoteMouse.php | 218 ++-- lib/Remote/RemoteTargetLocator.php | 147 +-- lib/Remote/RemoteTouchScreen.php | 350 +++--- lib/Remote/RemoteWebDriver.php | 994 +++++++++--------- lib/Remote/RemoteWebElement.php | 806 +++++++------- lib/Remote/Service/DriverCommandExecutor.php | 68 +- lib/Remote/Service/DriverService.php | 230 ++-- lib/Remote/UselessFileDetector.php | 18 +- lib/Remote/WebDriverBrowserType.php | 52 +- lib/Remote/WebDriverCapabilityType.php | 41 +- lib/Remote/WebDriverCommand.php | 75 +- lib/Remote/WebDriverResponse.php | 130 +-- lib/Support/Events/EventFiringWebDriver.php | 646 ++++++------ .../Events/EventFiringWebDriverNavigation.php | 267 ++--- lib/Support/Events/EventFiringWebElement.php | 662 ++++++------ lib/WebDriver.php | 229 ++-- lib/WebDriverAction.php | 11 +- lib/WebDriverAlert.php | 95 +- lib/WebDriverBy.php | 199 ++-- lib/WebDriverCapabilities.php | 66 +- lib/WebDriverCommandExecutor.php | 16 +- lib/WebDriverDimension.php | 72 +- lib/WebDriverDispatcher.php | 117 ++- lib/WebDriverElement.php | 230 ++-- lib/WebDriverEventListener.php | 191 ++-- lib/WebDriverExpectedCondition.php | 801 +++++++------- lib/WebDriverHasInputDevices.php | 20 +- lib/WebDriverKeyboard.php | 50 +- lib/WebDriverKeys.php | 176 ++-- lib/WebDriverMouse.php | 74 +- lib/WebDriverNavigation.php | 95 +- lib/WebDriverOptions.php | 300 +++--- lib/WebDriverPlatform.php | 25 +- lib/WebDriverPoint.php | 121 ++- lib/WebDriverSearchContext.php | 42 +- lib/WebDriverSelect.php | 486 ++++----- lib/WebDriverTargetLocator.php | 78 +- lib/WebDriverTimeouts.php | 101 +- lib/WebDriverUpAction.php | 38 +- lib/WebDriverWait.php | 91 +- lib/WebDriverWindow.php | 248 ++--- tests/functional/BaseTest.php | 156 +-- tests/functional/FileUploadTest.php | 45 +- tests/functional/WebDriverTestCase.php | 57 +- .../WebDriverButtonReleaseActionTest.php | 47 +- .../Internal/WebDriverClickActionTest.php | 47 +- .../WebDriverClickAndHoldActionTest.php | 47 +- .../WebDriverContextClickActionTest.php | 47 +- .../Internal/WebDriverCoordinatesTest.php | 40 +- .../WebDriverDoubleClickActionTest.php | 47 +- .../Internal/WebDriverKeyDownActionTest.php | 57 +- .../Internal/WebDriverKeyUpActionTest.php | 59 +- .../Internal/WebDriverMouseMoveActionTest.php | 47 +- .../WebDriverMouseToOffsetActionTest.php | 55 +- .../Internal/WebDriverSendKeysActionTest.php | 65 +- tests/unit/Remote/DesiredCapabilitiesTest.php | 215 ++-- tests/unit/Remote/WebDriverCommandTest.php | 14 +- 142 files changed, 7637 insertions(+), 7149 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 02933ab90..f379bdaa7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased - Fixed FirefoxProfile to support installation of extensions with custom namespace prefix in their manifest file +- Comply codestyle with [PSR-2](http://www.php-fig.org/psr/psr-2/) ## 1.1.2 - 2016-06-04 - Added ext-curl to composer.json diff --git a/lib/Chrome/ChromeDriver.php b/lib/Chrome/ChromeDriver.php index 0cabccd91..75131c215 100644 --- a/lib/Chrome/ChromeDriver.php +++ b/lib/Chrome/ChromeDriver.php @@ -15,72 +15,72 @@ namespace Facebook\WebDriver\Chrome; +use Facebook\WebDriver\Exception\WebDriverException; use Facebook\WebDriver\Remote\DesiredCapabilities; use Facebook\WebDriver\Remote\DriverCommand; -use Facebook\WebDriver\Remote\Service\DriverCommandExecutor; -use Facebook\WebDriver\Exception\WebDriverException; use Facebook\WebDriver\Remote\RemoteWebDriver; +use Facebook\WebDriver\Remote\Service\DriverCommandExecutor; use Facebook\WebDriver\Remote\WebDriverCommand; -class ChromeDriver extends RemoteWebDriver { +class ChromeDriver extends RemoteWebDriver +{ + public static function start(DesiredCapabilities $desired_capabilities = null, ChromeDriverService $service = null) + { + if ($desired_capabilities === null) { + $desired_capabilities = DesiredCapabilities::chrome(); + } + if ($service === null) { + $service = ChromeDriverService::createDefaultService(); + } + $executor = new DriverCommandExecutor($service); + $driver = new static(); + $driver->setCommandExecutor($executor) + ->startSession($desired_capabilities); - public static function start( - DesiredCapabilities $desired_capabilities = null, - ChromeDriverService $service = null - ) { - if ($desired_capabilities === null) { - $desired_capabilities = DesiredCapabilities::chrome(); + return $driver; } - if ($service === null) { - $service = ChromeDriverService::createDefaultService(); - } - $executor = new DriverCommandExecutor($service); - $driver = new static(); - $driver->setCommandExecutor($executor) - ->startSession($desired_capabilities); - return $driver; - } - public function startSession($desired_capabilities) { - $command = new WebDriverCommand( - null, - DriverCommand::NEW_SESSION, - array( - 'desiredCapabilities' => $desired_capabilities->toArray(), - ) - ); - $response = $this->executor->execute($command); - $this->setSessionID($response->getSessionID()); - } + public function startSession($desired_capabilities) + { + $command = new WebDriverCommand( + null, + DriverCommand::NEW_SESSION, + array( + 'desiredCapabilities' => $desired_capabilities->toArray(), + ) + ); + $response = $this->executor->execute($command); + $this->setSessionID($response->getSessionID()); + } - /** - * Always throws an exception. Use ChromeDriver::start() instead. - * - * @throws WebDriverException - */ - public static function create( - $url = 'http://localhost:4444/wd/hub', - $desired_capabilities = null, - $connection_timeout_in_ms = null, - $request_timeout_in_ms = null, - $http_proxy = null, - $http_proxy_port = null - ) { - throw new WebDriverException('Please use ChromeDriver::start() instead.'); - } + /** + * Always throws an exception. Use ChromeDriver::start() instead. + * + * @throws WebDriverException + */ + public static function create( + $url = 'http://localhost:4444/wd/hub', + $desired_capabilities = null, + $connection_timeout_in_ms = null, + $request_timeout_in_ms = null, + $http_proxy = null, + $http_proxy_port = null + ) { + throw new WebDriverException('Please use ChromeDriver::start() instead.'); + } - /** - * Always throws an exception. Use ChromeDriver::start() instead. - * - * @param string $session_id The existing session id - * @param string $url The url of the remote server - * - * @throws WebDriverException - */ - public static function createBySessionID( - $session_id, - $url = 'http://localhost:4444/wd/hub' - ) { - throw new WebDriverException('Please use ChromeDriver::start() instead.'); - } + /** + * Always throws an exception. Use ChromeDriver::start() instead. + * + * @param string $session_id The existing session id + * @param string $url The url of the remote server + * + * @throws WebDriverException + */ + public static function createBySessionID( + $session_id, + $url = 'http://localhost:4444/wd/hub' + ) { + throw new WebDriverException('Please use ChromeDriver::start() instead.'); + } } diff --git a/lib/Chrome/ChromeDriverService.php b/lib/Chrome/ChromeDriverService.php index d60f376a6..a48207a46 100644 --- a/lib/Chrome/ChromeDriverService.php +++ b/lib/Chrome/ChromeDriverService.php @@ -17,17 +17,18 @@ use Facebook\WebDriver\Remote\Service\DriverService; -class ChromeDriverService extends DriverService { +class ChromeDriverService extends DriverService +{ + // The environment variable storing the path to the chrome driver executable. + const CHROME_DRIVER_EXE_PROPERTY = 'webdriver.chrome.driver'; - // The environment variable storing the path to the chrome driver executable. - const CHROME_DRIVER_EXE_PROPERTY = "webdriver.chrome.driver"; - - public static function createDefaultService() { - $exe = getenv(self::CHROME_DRIVER_EXE_PROPERTY); - $port = 9515; // TODO: Get another port if the default port is used. - $args = array("--port=$port"); - $service = new ChromeDriverService($exe, $port, $args); - return $service; - } + public static function createDefaultService() + { + $exe = getenv(self::CHROME_DRIVER_EXE_PROPERTY); + $port = 9515; // TODO: Get another port if the default port is used. + $args = array("--port=$port"); + $service = new self($exe, $port, $args); + return $service; + } } diff --git a/lib/Chrome/ChromeOptions.php b/lib/Chrome/ChromeOptions.php index da387c55a..3af14b9c3 100644 --- a/lib/Chrome/ChromeOptions.php +++ b/lib/Chrome/ChromeOptions.php @@ -22,141 +22,154 @@ * * @see https://sites.google.com/a/chromium.org/chromedriver/capabilities */ -class ChromeOptions { - - /** - * The key of chrome options in desired capabilities. - */ - const CAPABILITY = "chromeOptions"; - - /** - * @var array - */ - private $arguments = array(); - - /** - * @var string - */ - private $binary = ''; - - /** - * @var array - */ - private $extensions = array(); - - /** - * @var array - */ - private $experimentalOptions = array(); - - /** - * Sets the path of the Chrome executable. The path should be either absolute - * or relative to the location running ChromeDriver server. - * - * @param string $path - * @return ChromeOptions - */ - public function setBinary($path) { - $this->binary = $path; - return $this; - } - - /** - * @param array $arguments - * @return ChromeOptions - */ - public function addArguments(array $arguments) { - $this->arguments = array_merge($this->arguments, $arguments); - return $this; - } - - /** - * Add a Chrome extension to install on browser startup. Each path should be - * a packed Chrome extension. - * - * @param array $paths - * @return ChromeOptions - */ - public function addExtensions(array $paths) { - foreach ($paths as $path) { - $this->addExtension($path); +class ChromeOptions +{ + /** + * The key of chrome options in desired capabilities. + */ + const CAPABILITY = 'chromeOptions'; + /** + * @var array + */ + private $arguments = array(); + /** + * @var string + */ + private $binary = ''; + /** + * @var array + */ + private $extensions = array(); + /** + * @var array + */ + private $experimentalOptions = array(); + + /** + * Sets the path of the Chrome executable. The path should be either absolute + * or relative to the location running ChromeDriver server. + * + * @param string $path + * @return ChromeOptions + */ + public function setBinary($path) + { + $this->binary = $path; + + return $this; } - return $this; - } - - /** - * @param array $encoded_extensions An array of base64 encoded of the extensions. - * @return ChromeOptions - */ - public function addEncodedExtensions(array $encoded_extensions) { - foreach ($encoded_extensions as $encoded_extension) { - $this->addEncodedExtension($encoded_extension); + + /** + * @param array $arguments + * @return ChromeOptions + */ + public function addArguments(array $arguments) + { + $this->arguments = array_merge($this->arguments, $arguments); + + return $this; + } + + /** + * Add a Chrome extension to install on browser startup. Each path should be + * a packed Chrome extension. + * + * @param array $paths + * @return ChromeOptions + */ + public function addExtensions(array $paths) + { + foreach ($paths as $path) { + $this->addExtension($path); + } + + return $this; + } + + /** + * @param array $encoded_extensions An array of base64 encoded of the extensions. + * @return ChromeOptions + */ + public function addEncodedExtensions(array $encoded_extensions) + { + foreach ($encoded_extensions as $encoded_extension) { + $this->addEncodedExtension($encoded_extension); + } + + return $this; + } + + /** + * Sets an experimental option which has not exposed officially. + * + * @param string $name + * @param mixed $value + * @return ChromeOptions + */ + public function setExperimentalOption($name, $value) + { + $this->experimentalOptions[$name] = $value; + + return $this; + } + + /** + * @return DesiredCapabilities The DesiredCapabilities for Chrome with this options. + */ + public function toCapabilities() + { + $capabilities = DesiredCapabilities::chrome(); + $capabilities->setCapability(self::CAPABILITY, $this); + + return $capabilities; } - return $this; - } - - /** - * Sets an experimental option which has not exposed officially. - * - * @param string $name - * @param mixed $value - * @return ChromeOptions - */ - public function setExperimentalOption($name, $value) { - $this->experimentalOptions[$name] = $value; - return $this; - } - - /** - * @return DesiredCapabilities The DesiredCapabilities for Chrome with this options. - */ - public function toCapabilities() { - $capabilities = DesiredCapabilities::chrome(); - $capabilities->setCapability(self::CAPABILITY, $this); - return $capabilities; - } - - /** - * @return array - */ - public function toArray() { - $options = $this->experimentalOptions; - - // The selenium server expects a 'dictionary' instead of a 'list' when - // reading the chrome option. However, an empty array in PHP will be - // converted to a 'list' instead of a 'dictionary'. To fix it, we always - // set the 'binary' to avoid returning an empty array. - $options['binary'] = $this->binary; - - if ($this->arguments) { - $options['args'] = $this->arguments; + + /** + * @return array + */ + public function toArray() + { + $options = $this->experimentalOptions; + + // The selenium server expects a 'dictionary' instead of a 'list' when + // reading the chrome option. However, an empty array in PHP will be + // converted to a 'list' instead of a 'dictionary'. To fix it, we always + // set the 'binary' to avoid returning an empty array. + $options['binary'] = $this->binary; + + if ($this->arguments) { + $options['args'] = $this->arguments; + } + + if ($this->extensions) { + $options['extensions'] = $this->extensions; + } + + return $options; } - if ($this->extensions) { - $options['extensions'] = $this->extensions; + /** + * Add a Chrome extension to install on browser startup. Each path should be a + * packed Chrome extension. + * + * @param string $path + * @return ChromeOptions + */ + private function addExtension($path) + { + $this->addEncodedExtension(base64_encode(file_get_contents($path))); + + return $this; } - return $options; - } - - /** - * Add a Chrome extension to install on browser startup. Each path should be a - * packed Chrome extension. - * - * @param string $path - * @return ChromeOptions - */ - private function addExtension($path) { - $this->addEncodedExtension(base64_encode(file_get_contents($path))); - return $this; - } - - /** - * @param string $encoded_extension Base64 encoded of the extension. - * @return ChromeOptions - */ - private function addEncodedExtension($encoded_extension) { - $this->extensions[] = $encoded_extension; - return $this; - } + /** + * @param string $encoded_extension Base64 encoded of the extension. + * @return ChromeOptions + */ + private function addEncodedExtension($encoded_extension) + { + $this->extensions[] = $encoded_extension; + + return $this; + } } diff --git a/lib/Exception/ElementNotSelectableException.php b/lib/Exception/ElementNotSelectableException.php index 9acfb88f2..77c6accb0 100644 --- a/lib/Exception/ElementNotSelectableException.php +++ b/lib/Exception/ElementNotSelectableException.php @@ -15,7 +15,6 @@ namespace Facebook\WebDriver\Exception; - -class ElementNotSelectableException extends WebDriverException { - -} \ No newline at end of file +class ElementNotSelectableException extends WebDriverException +{ +} diff --git a/lib/Exception/ElementNotVisibleException.php b/lib/Exception/ElementNotVisibleException.php index c452d2daa..2de5fd10c 100644 --- a/lib/Exception/ElementNotVisibleException.php +++ b/lib/Exception/ElementNotVisibleException.php @@ -15,6 +15,6 @@ namespace Facebook\WebDriver\Exception; -class ElementNotVisibleException extends WebDriverException { - -} \ No newline at end of file +class ElementNotVisibleException extends WebDriverException +{ +} diff --git a/lib/Exception/ExpectedException.php b/lib/Exception/ExpectedException.php index cd8f15cc5..9c43f47e3 100644 --- a/lib/Exception/ExpectedException.php +++ b/lib/Exception/ExpectedException.php @@ -15,7 +15,6 @@ namespace Facebook\WebDriver\Exception; - -class ExpectedException extends WebDriverException { - -} \ No newline at end of file +class ExpectedException extends WebDriverException +{ +} diff --git a/lib/Exception/IMEEngineActivationFailedException.php b/lib/Exception/IMEEngineActivationFailedException.php index cd13d0181..6e372c313 100644 --- a/lib/Exception/IMEEngineActivationFailedException.php +++ b/lib/Exception/IMEEngineActivationFailedException.php @@ -15,7 +15,6 @@ namespace Facebook\WebDriver\Exception; - -class IMEEngineActivationFailedException extends WebDriverException { - -} \ No newline at end of file +class IMEEngineActivationFailedException extends WebDriverException +{ +} diff --git a/lib/Exception/IMENotAvailableException.php b/lib/Exception/IMENotAvailableException.php index 94497c0d5..aeb78dc48 100644 --- a/lib/Exception/IMENotAvailableException.php +++ b/lib/Exception/IMENotAvailableException.php @@ -15,7 +15,6 @@ namespace Facebook\WebDriver\Exception; - -class IMENotAvailableException extends WebDriverException { - -} \ No newline at end of file +class IMENotAvailableException extends WebDriverException +{ +} diff --git a/lib/Exception/IndexOutOfBoundsException.php b/lib/Exception/IndexOutOfBoundsException.php index 322f67b14..ad52d21e9 100644 --- a/lib/Exception/IndexOutOfBoundsException.php +++ b/lib/Exception/IndexOutOfBoundsException.php @@ -2,6 +2,6 @@ namespace Facebook\WebDriver\Exception; -class IndexOutOfBoundsException extends WebDriverException { - -} \ No newline at end of file +class IndexOutOfBoundsException extends WebDriverException +{ +} diff --git a/lib/Exception/InvalidCookieDomainException.php b/lib/Exception/InvalidCookieDomainException.php index 5dbaae9eb..bae6c06db 100644 --- a/lib/Exception/InvalidCookieDomainException.php +++ b/lib/Exception/InvalidCookieDomainException.php @@ -15,6 +15,6 @@ namespace Facebook\WebDriver\Exception; -class InvalidCookieDomainException extends WebDriverException { - -} \ No newline at end of file +class InvalidCookieDomainException extends WebDriverException +{ +} diff --git a/lib/Exception/InvalidCoordinatesException.php b/lib/Exception/InvalidCoordinatesException.php index 571a107b2..53e9e9ef9 100644 --- a/lib/Exception/InvalidCoordinatesException.php +++ b/lib/Exception/InvalidCoordinatesException.php @@ -15,7 +15,6 @@ namespace Facebook\WebDriver\Exception; - -class InvalidCoordinatesException extends WebDriverException { - -} \ No newline at end of file +class InvalidCoordinatesException extends WebDriverException +{ +} diff --git a/lib/Exception/InvalidElementStateException.php b/lib/Exception/InvalidElementStateException.php index 5c49c4c88..94ec58f1a 100644 --- a/lib/Exception/InvalidElementStateException.php +++ b/lib/Exception/InvalidElementStateException.php @@ -15,6 +15,6 @@ namespace Facebook\WebDriver\Exception; -class InvalidElementStateException extends WebDriverException { - -} \ No newline at end of file +class InvalidElementStateException extends WebDriverException +{ +} diff --git a/lib/Exception/InvalidSelectorException.php b/lib/Exception/InvalidSelectorException.php index 2c106970c..530fba2f4 100644 --- a/lib/Exception/InvalidSelectorException.php +++ b/lib/Exception/InvalidSelectorException.php @@ -15,7 +15,6 @@ namespace Facebook\WebDriver\Exception; - -class InvalidSelectorException extends WebDriverException { - -} \ No newline at end of file +class InvalidSelectorException extends WebDriverException +{ +} diff --git a/lib/Exception/MoveTargetOutOfBoundsException.php b/lib/Exception/MoveTargetOutOfBoundsException.php index 39e97adbd..7a96b5805 100644 --- a/lib/Exception/MoveTargetOutOfBoundsException.php +++ b/lib/Exception/MoveTargetOutOfBoundsException.php @@ -15,7 +15,6 @@ namespace Facebook\WebDriver\Exception; - -class MoveTargetOutOfBoundsException extends WebDriverException { - -} \ No newline at end of file +class MoveTargetOutOfBoundsException extends WebDriverException +{ +} diff --git a/lib/Exception/NoAlertOpenException.php b/lib/Exception/NoAlertOpenException.php index cdc846e08..ebc19964e 100644 --- a/lib/Exception/NoAlertOpenException.php +++ b/lib/Exception/NoAlertOpenException.php @@ -15,6 +15,6 @@ namespace Facebook\WebDriver\Exception; -class NoAlertOpenException extends WebDriverException { - -} \ No newline at end of file +class NoAlertOpenException extends WebDriverException +{ +} diff --git a/lib/Exception/NoCollectionException.php b/lib/Exception/NoCollectionException.php index 2bfe9069a..ec6335cdb 100644 --- a/lib/Exception/NoCollectionException.php +++ b/lib/Exception/NoCollectionException.php @@ -2,6 +2,6 @@ namespace Facebook\WebDriver\Exception; -class NoCollectionException extends WebDriverException { - -} \ No newline at end of file +class NoCollectionException extends WebDriverException +{ +} diff --git a/lib/Exception/NoScriptResultException.php b/lib/Exception/NoScriptResultException.php index 80d23f7de..f86ca2215 100644 --- a/lib/Exception/NoScriptResultException.php +++ b/lib/Exception/NoScriptResultException.php @@ -15,6 +15,6 @@ namespace Facebook\WebDriver\Exception; -class NoScriptResultException extends WebDriverException { - -} \ No newline at end of file +class NoScriptResultException extends WebDriverException +{ +} diff --git a/lib/Exception/NoStringException.php b/lib/Exception/NoStringException.php index 13c107b7d..790898607 100644 --- a/lib/Exception/NoStringException.php +++ b/lib/Exception/NoStringException.php @@ -2,6 +2,6 @@ namespace Facebook\WebDriver\Exception; -class NoStringException extends WebDriverException { - -} \ No newline at end of file +class NoStringException extends WebDriverException +{ +} diff --git a/lib/Exception/NoStringLengthException.php b/lib/Exception/NoStringLengthException.php index 8f50bb4ca..7047d72d3 100644 --- a/lib/Exception/NoStringLengthException.php +++ b/lib/Exception/NoStringLengthException.php @@ -15,6 +15,6 @@ namespace Facebook\WebDriver\Exception; -class NoStringLengthException extends WebDriverException { - -} \ No newline at end of file +class NoStringLengthException extends WebDriverException +{ +} diff --git a/lib/Exception/NoStringWrapperException.php b/lib/Exception/NoStringWrapperException.php index 2e17124e2..d5f75efd0 100644 --- a/lib/Exception/NoStringWrapperException.php +++ b/lib/Exception/NoStringWrapperException.php @@ -15,6 +15,6 @@ namespace Facebook\WebDriver\Exception; -class NoStringWrapperException extends WebDriverException { - -} \ No newline at end of file +class NoStringWrapperException extends WebDriverException +{ +} diff --git a/lib/Exception/NoSuchCollectionException.php b/lib/Exception/NoSuchCollectionException.php index d9e6c47ab..9899cf2fe 100644 --- a/lib/Exception/NoSuchCollectionException.php +++ b/lib/Exception/NoSuchCollectionException.php @@ -15,6 +15,6 @@ namespace Facebook\WebDriver\Exception; -class NoSuchCollectionException extends WebDriverException { - -} \ No newline at end of file +class NoSuchCollectionException extends WebDriverException +{ +} diff --git a/lib/Exception/NoSuchDocumentException.php b/lib/Exception/NoSuchDocumentException.php index b542fdfd6..f3bba91fd 100644 --- a/lib/Exception/NoSuchDocumentException.php +++ b/lib/Exception/NoSuchDocumentException.php @@ -15,7 +15,6 @@ namespace Facebook\WebDriver\Exception; - -class NoSuchDocumentException extends WebDriverException { - -} \ No newline at end of file +class NoSuchDocumentException extends WebDriverException +{ +} diff --git a/lib/Exception/NoSuchDriverException.php b/lib/Exception/NoSuchDriverException.php index c34735b9d..c227d676a 100644 --- a/lib/Exception/NoSuchDriverException.php +++ b/lib/Exception/NoSuchDriverException.php @@ -15,6 +15,6 @@ namespace Facebook\WebDriver\Exception; -class NoSuchDriverException extends WebDriverException { - -} \ No newline at end of file +class NoSuchDriverException extends WebDriverException +{ +} diff --git a/lib/Exception/NoSuchElementException.php b/lib/Exception/NoSuchElementException.php index da39f7cab..f8d730580 100644 --- a/lib/Exception/NoSuchElementException.php +++ b/lib/Exception/NoSuchElementException.php @@ -15,6 +15,6 @@ namespace Facebook\WebDriver\Exception; -class NoSuchElementException extends WebDriverException { - -} \ No newline at end of file +class NoSuchElementException extends WebDriverException +{ +} diff --git a/lib/Exception/NoSuchFrameException.php b/lib/Exception/NoSuchFrameException.php index 474f4dc6e..7168c84a8 100644 --- a/lib/Exception/NoSuchFrameException.php +++ b/lib/Exception/NoSuchFrameException.php @@ -15,6 +15,6 @@ namespace Facebook\WebDriver\Exception; -class NoSuchFrameException extends WebDriverException { - -} \ No newline at end of file +class NoSuchFrameException extends WebDriverException +{ +} diff --git a/lib/Exception/NoSuchWindowException.php b/lib/Exception/NoSuchWindowException.php index bbeee4f0d..142d32e64 100644 --- a/lib/Exception/NoSuchWindowException.php +++ b/lib/Exception/NoSuchWindowException.php @@ -15,6 +15,6 @@ namespace Facebook\WebDriver\Exception; -class NoSuchWindowException extends WebDriverException { - -} \ No newline at end of file +class NoSuchWindowException extends WebDriverException +{ +} diff --git a/lib/Exception/NullPointerException.php b/lib/Exception/NullPointerException.php index 00f2fb5bb..cbc373a87 100644 --- a/lib/Exception/NullPointerException.php +++ b/lib/Exception/NullPointerException.php @@ -15,7 +15,6 @@ namespace Facebook\WebDriver\Exception; - -class NullPointerException extends WebDriverException { - -} \ No newline at end of file +class NullPointerException extends WebDriverException +{ +} diff --git a/lib/Exception/ScriptTimeoutException.php b/lib/Exception/ScriptTimeoutException.php index 4095728a2..ed4203656 100644 --- a/lib/Exception/ScriptTimeoutException.php +++ b/lib/Exception/ScriptTimeoutException.php @@ -15,7 +15,6 @@ namespace Facebook\WebDriver\Exception; - -class ScriptTimeoutException extends WebDriverException { - -} \ No newline at end of file +class ScriptTimeoutException extends WebDriverException +{ +} diff --git a/lib/Exception/SessionNotCreatedException.php b/lib/Exception/SessionNotCreatedException.php index 9b67edf94..f374141f1 100644 --- a/lib/Exception/SessionNotCreatedException.php +++ b/lib/Exception/SessionNotCreatedException.php @@ -15,7 +15,6 @@ namespace Facebook\WebDriver\Exception; - -class SessionNotCreatedException extends WebDriverException { - -} \ No newline at end of file +class SessionNotCreatedException extends WebDriverException +{ +} diff --git a/lib/Exception/StaleElementReferenceException.php b/lib/Exception/StaleElementReferenceException.php index 7e265725c..2fbf99973 100644 --- a/lib/Exception/StaleElementReferenceException.php +++ b/lib/Exception/StaleElementReferenceException.php @@ -15,6 +15,6 @@ namespace Facebook\WebDriver\Exception; -class StaleElementReferenceException extends WebDriverException { - -} \ No newline at end of file +class StaleElementReferenceException extends WebDriverException +{ +} diff --git a/lib/Exception/TimeOutException.php b/lib/Exception/TimeOutException.php index 6301f4144..f7443e3d5 100644 --- a/lib/Exception/TimeOutException.php +++ b/lib/Exception/TimeOutException.php @@ -15,6 +15,6 @@ namespace Facebook\WebDriver\Exception; -class TimeOutException extends WebDriverException { - -} \ No newline at end of file +class TimeOutException extends WebDriverException +{ +} diff --git a/lib/Exception/UnableToSetCookieException.php b/lib/Exception/UnableToSetCookieException.php index 7ece63e50..0a1edae94 100644 --- a/lib/Exception/UnableToSetCookieException.php +++ b/lib/Exception/UnableToSetCookieException.php @@ -15,6 +15,6 @@ namespace Facebook\WebDriver\Exception; -class UnableToSetCookieException extends WebDriverException { - -} \ No newline at end of file +class UnableToSetCookieException extends WebDriverException +{ +} diff --git a/lib/Exception/UnexpectedAlertOpenException.php b/lib/Exception/UnexpectedAlertOpenException.php index e97eddeae..422255a77 100644 --- a/lib/Exception/UnexpectedAlertOpenException.php +++ b/lib/Exception/UnexpectedAlertOpenException.php @@ -15,6 +15,6 @@ namespace Facebook\WebDriver\Exception; -class UnexpectedAlertOpenException extends WebDriverException { - -} \ No newline at end of file +class UnexpectedAlertOpenException extends WebDriverException +{ +} diff --git a/lib/Exception/UnexpectedJavascriptException.php b/lib/Exception/UnexpectedJavascriptException.php index c8da7e505..5cf8a8f92 100644 --- a/lib/Exception/UnexpectedJavascriptException.php +++ b/lib/Exception/UnexpectedJavascriptException.php @@ -15,6 +15,6 @@ namespace Facebook\WebDriver\Exception; -class UnexpectedJavascriptException extends WebDriverException { - -} \ No newline at end of file +class UnexpectedJavascriptException extends WebDriverException +{ +} diff --git a/lib/Exception/UnexpectedTagNameException.php b/lib/Exception/UnexpectedTagNameException.php index 514abd374..0703c7d4e 100644 --- a/lib/Exception/UnexpectedTagNameException.php +++ b/lib/Exception/UnexpectedTagNameException.php @@ -15,20 +15,22 @@ namespace Facebook\WebDriver\Exception; -class UnexpectedTagNameException extends WebDriverException { - - /** - * @param string $expected_tag_name - * @param string $actual_tag_name - */ - public function __construct( - $expected_tag_name, - $actual_tag_name) { - parent::__construct( - sprintf( - "Element should have been \"%s\" but was \"%s\"", - $expected_tag_name, $actual_tag_name - ) - ); - } -} \ No newline at end of file +class UnexpectedTagNameException extends WebDriverException +{ + /** + * @param string $expected_tag_name + * @param string $actual_tag_name + */ + public function __construct( + $expected_tag_name, + $actual_tag_name + ) { + parent::__construct( + sprintf( + 'Element should have been "%s" but was "%s"', + $expected_tag_name, + $actual_tag_name + ) + ); + } +} diff --git a/lib/Exception/UnknownCommandException.php b/lib/Exception/UnknownCommandException.php index 2d20b0096..723d6dbef 100644 --- a/lib/Exception/UnknownCommandException.php +++ b/lib/Exception/UnknownCommandException.php @@ -15,6 +15,6 @@ namespace Facebook\WebDriver\Exception; -class UnknownCommandException extends WebDriverException { - -} \ No newline at end of file +class UnknownCommandException extends WebDriverException +{ +} diff --git a/lib/Exception/UnknownServerException.php b/lib/Exception/UnknownServerException.php index 13c3780c4..c24b415ef 100644 --- a/lib/Exception/UnknownServerException.php +++ b/lib/Exception/UnknownServerException.php @@ -15,6 +15,6 @@ namespace Facebook\WebDriver\Exception; -class UnknownServerException extends WebDriverException { - -} \ No newline at end of file +class UnknownServerException extends WebDriverException +{ +} diff --git a/lib/Exception/UnrecognizedExceptionException.php b/lib/Exception/UnrecognizedExceptionException.php index 9d0046dc0..fa1038605 100644 --- a/lib/Exception/UnrecognizedExceptionException.php +++ b/lib/Exception/UnrecognizedExceptionException.php @@ -15,7 +15,6 @@ namespace Facebook\WebDriver\Exception; - -class UnrecognizedExceptionException extends WebDriverException { - -} \ No newline at end of file +class UnrecognizedExceptionException extends WebDriverException +{ +} diff --git a/lib/Exception/UnsupportedOperationException.php b/lib/Exception/UnsupportedOperationException.php index 781c2276a..64f8d1930 100644 --- a/lib/Exception/UnsupportedOperationException.php +++ b/lib/Exception/UnsupportedOperationException.php @@ -15,7 +15,6 @@ namespace Facebook\WebDriver\Exception; - -class UnsupportedOperationException extends WebDriverException { - -} \ No newline at end of file +class UnsupportedOperationException extends WebDriverException +{ +} diff --git a/lib/Exception/WebDriverCurlException.php b/lib/Exception/WebDriverCurlException.php index 9719565d2..f559826c0 100644 --- a/lib/Exception/WebDriverCurlException.php +++ b/lib/Exception/WebDriverCurlException.php @@ -15,7 +15,6 @@ namespace Facebook\WebDriver\Exception; - -class WebDriverCurlException extends WebDriverException { - -} \ No newline at end of file +class WebDriverCurlException extends WebDriverException +{ +} diff --git a/lib/Exception/WebDriverException.php b/lib/Exception/WebDriverException.php index a23f42103..d05519b51 100644 --- a/lib/Exception/WebDriverException.php +++ b/lib/Exception/WebDriverException.php @@ -17,149 +17,152 @@ use Exception; -class WebDriverException extends Exception { +class WebDriverException extends Exception +{ + private $results; - private $results; - - /** - * @param string $message - * @param mixed $results - */ - public function __construct($message, $results = null) { - parent::__construct($message); - $this->results = $results; - } + /** + * @param string $message + * @param mixed $results + */ + public function __construct($message, $results = null) + { + parent::__construct($message); + $this->results = $results; + } - /** - * @return mixed - */ - public function getResults() { - return $this->results; - } + /** + * @return mixed + */ + public function getResults() + { + return $this->results; + } - /** - * Throw WebDriverExceptions. - * For $status_code >= 0, they are errors defined in the json wired protocol. - * For $status_code < 0, they are errors defined in php-webdriver. - * - * @param int $status_code - * @param string $message - * @param mixed $results - * - * @throws ElementNotSelectableException - * @throws ElementNotVisibleException - * @throws ExpectedException - * @throws IMEEngineActivationFailedException - * @throws IMENotAvailableException - * @throws IndexOutOfBoundsException - * @throws InvalidCookieDomainException - * @throws InvalidCoordinatesException - * @throws InvalidElementStateException - * @throws InvalidSelectorException - * @throws MoveTargetOutOfBoundsException - * @throws NoAlertOpenException - * @throws NoCollectionException - * @throws NoScriptResultException - * @throws NoStringException - * @throws NoStringLengthException - * @throws NoStringWrapperException - * @throws NoSuchCollectionException - * @throws NoSuchDocumentException - * @throws NoSuchDriverException - * @throws NoSuchElementException - * @throws NoSuchFrameException - * @throws NoSuchWindowException - * @throws NullPointerException - * @throws ScriptTimeoutException - * @throws SessionNotCreatedException - * @throws StaleElementReferenceException - * @throws TimeOutException - * @throws UnableToSetCookieException - * @throws UnexpectedAlertOpenException - * @throws UnexpectedJavascriptException - * @throws UnknownCommandException - * @throws UnknownServerException - * @throws UnrecognizedExceptionException - * @throws WebDriverCurlException - * @throws XPathLookupException - */ - public static function throwException($status_code, $message, $results) { - switch ($status_code) { - case -1: - throw new WebDriverCurlException($message); - case 0: - // Success - break; - case 1: - throw new IndexOutOfBoundsException($message, $results); - case 2: - throw new NoCollectionException($message, $results); - case 3: - throw new NoStringException($message, $results); - case 4: - throw new NoStringLengthException($message, $results); - case 5: - throw new NoStringWrapperException($message, $results); - case 6: - throw new NoSuchDriverException($message, $results); - case 7: - throw new NoSuchElementException($message, $results); - case 8: - throw new NoSuchFrameException($message, $results); - case 9: - throw new UnknownCommandException($message, $results); - case 10: - throw new StaleElementReferenceException($message, $results); - case 11: - throw new ElementNotVisibleException($message, $results); - case 12: - throw new InvalidElementStateException($message, $results); - case 13: - throw new UnknownServerException($message, $results); - case 14: - throw new ExpectedException($message, $results); - case 15: - throw new ElementNotSelectableException($message, $results); - case 16: - throw new NoSuchDocumentException($message, $results); - case 17: - throw new UnexpectedJavascriptException($message, $results); - case 18: - throw new NoScriptResultException($message, $results); - case 19: - throw new XPathLookupException($message, $results); - case 20: - throw new NoSuchCollectionException($message, $results); - case 21: - throw new TimeOutException($message, $results); - case 22: - throw new NullPointerException($message, $results); - case 23: - throw new NoSuchWindowException($message, $results); - case 24: - throw new InvalidCookieDomainException($message, $results); - case 25: - throw new UnableToSetCookieException($message, $results); - case 26: - throw new UnexpectedAlertOpenException($message, $results); - case 27: - throw new NoAlertOpenException($message, $results); - case 28: - throw new ScriptTimeoutException($message, $results); - case 29: - throw new InvalidCoordinatesException($message, $results); - case 30: - throw new IMENotAvailableException($message, $results); - case 31: - throw new IMEEngineActivationFailedException($message, $results); - case 32: - throw new InvalidSelectorException($message, $results); - case 33: - throw new SessionNotCreatedException($message, $results); - case 34: - throw new MoveTargetOutOfBoundsException($message, $results); - default: - throw new UnrecognizedExceptionException($message, $results); + /** + * Throw WebDriverExceptions. + * For $status_code >= 0, they are errors defined in the json wired protocol. + * For $status_code < 0, they are errors defined in php-webdriver. + * + * @param int $status_code + * @param string $message + * @param mixed $results + * + * @throws ElementNotSelectableException + * @throws ElementNotVisibleException + * @throws ExpectedException + * @throws IMEEngineActivationFailedException + * @throws IMENotAvailableException + * @throws IndexOutOfBoundsException + * @throws InvalidCookieDomainException + * @throws InvalidCoordinatesException + * @throws InvalidElementStateException + * @throws InvalidSelectorException + * @throws MoveTargetOutOfBoundsException + * @throws NoAlertOpenException + * @throws NoCollectionException + * @throws NoScriptResultException + * @throws NoStringException + * @throws NoStringLengthException + * @throws NoStringWrapperException + * @throws NoSuchCollectionException + * @throws NoSuchDocumentException + * @throws NoSuchDriverException + * @throws NoSuchElementException + * @throws NoSuchFrameException + * @throws NoSuchWindowException + * @throws NullPointerException + * @throws ScriptTimeoutException + * @throws SessionNotCreatedException + * @throws StaleElementReferenceException + * @throws TimeOutException + * @throws UnableToSetCookieException + * @throws UnexpectedAlertOpenException + * @throws UnexpectedJavascriptException + * @throws UnknownCommandException + * @throws UnknownServerException + * @throws UnrecognizedExceptionException + * @throws WebDriverCurlException + * @throws XPathLookupException + */ + public static function throwException($status_code, $message, $results) + { + switch ($status_code) { + case -1: + throw new WebDriverCurlException($message); + case 0: + // Success + break; + case 1: + throw new IndexOutOfBoundsException($message, $results); + case 2: + throw new NoCollectionException($message, $results); + case 3: + throw new NoStringException($message, $results); + case 4: + throw new NoStringLengthException($message, $results); + case 5: + throw new NoStringWrapperException($message, $results); + case 6: + throw new NoSuchDriverException($message, $results); + case 7: + throw new NoSuchElementException($message, $results); + case 8: + throw new NoSuchFrameException($message, $results); + case 9: + throw new UnknownCommandException($message, $results); + case 10: + throw new StaleElementReferenceException($message, $results); + case 11: + throw new ElementNotVisibleException($message, $results); + case 12: + throw new InvalidElementStateException($message, $results); + case 13: + throw new UnknownServerException($message, $results); + case 14: + throw new ExpectedException($message, $results); + case 15: + throw new ElementNotSelectableException($message, $results); + case 16: + throw new NoSuchDocumentException($message, $results); + case 17: + throw new UnexpectedJavascriptException($message, $results); + case 18: + throw new NoScriptResultException($message, $results); + case 19: + throw new XPathLookupException($message, $results); + case 20: + throw new NoSuchCollectionException($message, $results); + case 21: + throw new TimeOutException($message, $results); + case 22: + throw new NullPointerException($message, $results); + case 23: + throw new NoSuchWindowException($message, $results); + case 24: + throw new InvalidCookieDomainException($message, $results); + case 25: + throw new UnableToSetCookieException($message, $results); + case 26: + throw new UnexpectedAlertOpenException($message, $results); + case 27: + throw new NoAlertOpenException($message, $results); + case 28: + throw new ScriptTimeoutException($message, $results); + case 29: + throw new InvalidCoordinatesException($message, $results); + case 30: + throw new IMENotAvailableException($message, $results); + case 31: + throw new IMEEngineActivationFailedException($message, $results); + case 32: + throw new InvalidSelectorException($message, $results); + case 33: + throw new SessionNotCreatedException($message, $results); + case 34: + throw new MoveTargetOutOfBoundsException($message, $results); + default: + throw new UnrecognizedExceptionException($message, $results); + } } - } } diff --git a/lib/Exception/XPathLookupException.php b/lib/Exception/XPathLookupException.php index de9e2e707..c7f589dcc 100644 --- a/lib/Exception/XPathLookupException.php +++ b/lib/Exception/XPathLookupException.php @@ -15,6 +15,6 @@ namespace Facebook\WebDriver\Exception; -class XPathLookupException extends WebDriverException { - -} \ No newline at end of file +class XPathLookupException extends WebDriverException +{ +} diff --git a/lib/Firefox/FirefoxDriver.php b/lib/Firefox/FirefoxDriver.php index 083af226b..9e0751238 100644 --- a/lib/Firefox/FirefoxDriver.php +++ b/lib/Firefox/FirefoxDriver.php @@ -15,10 +15,11 @@ namespace Facebook\WebDriver\Firefox; -class FirefoxDriver { - const PROFILE = 'firefox_profile'; +class FirefoxDriver +{ + const PROFILE = 'firefox_profile'; - private function __construct() - { - } + private function __construct() + { + } } diff --git a/lib/Firefox/FirefoxPreferences.php b/lib/Firefox/FirefoxPreferences.php index 6b7ca91dd..b869a2667 100644 --- a/lib/Firefox/FirefoxPreferences.php +++ b/lib/Firefox/FirefoxPreferences.php @@ -19,15 +19,16 @@ * Constants of common Firefox profile preferences (about:config values). * @see http://kb.mozillazine.org/Firefox_:_FAQs_:_About:config_Entries */ -class FirefoxPreferences { - /** @var string Port WebDriver uses to communicate with Firefox instance */ - const WEBDRIVER_FIREFOX_PORT = 'webdriver_firefox_port'; - /** @var string Should the reader view (FF 38+) be enabled? */ - const READER_PARSE_ON_LOAD_ENABLED = 'reader.parse-on-load.enabled'; - /** @var string Browser homepage */ - const BROWSER_STARTUP_HOMEPAGE = 'browser.startup.homepage'; +class FirefoxPreferences +{ + /** @var string Port WebDriver uses to communicate with Firefox instance */ + const WEBDRIVER_FIREFOX_PORT = 'webdriver_firefox_port'; + /** @var string Should the reader view (FF 38+) be enabled? */ + const READER_PARSE_ON_LOAD_ENABLED = 'reader.parse-on-load.enabled'; + /** @var string Browser homepage */ + const BROWSER_STARTUP_HOMEPAGE = 'browser.startup.homepage'; - private function __construct() - { - } + private function __construct() + { + } } diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index 03830dc63..925ac157f 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -21,256 +21,279 @@ use RecursiveIteratorIterator; use ZipArchive; -class FirefoxProfile { - - /** - * @var array - */ - private $preferences = array(); - - /** - * @var array - */ - private $extensions = array(); - - /** - * @var array - */ - private $extensions_datas = array(); - - /** - * @var string - */ - private $rdf_file; - - /** - * @param string $extension The path to the xpi extension. - * @return FirefoxProfile - */ - public function addExtension($extension) { - $this->extensions[] = $extension; - return $this; - } - - /** - * @param string $extension_datas The path to the folder containing the datas to add to the extension - * @return FirefoxProfile - */ - public function addExtensionDatas($extension_datas) { - if (!is_dir($extension_datas)) { - return; +class FirefoxProfile +{ + /** + * @var array + */ + private $preferences = array(); + /** + * @var array + */ + private $extensions = array(); + /** + * @var array + */ + private $extensions_datas = array(); + /** + * @var string + */ + private $rdf_file; + + /** + * @param string $extension The path to the xpi extension. + * @return FirefoxProfile + */ + public function addExtension($extension) + { + $this->extensions[] = $extension; + + return $this; } - $this->extensions_datas[basename($extension_datas)] = $extension_datas; - return $this; - } - - /** - * @param string $rdf_file The path to the rdf file - * @return FirefoxProfile - */ - public function setRdfFile($rdf_file) { - if (!is_file($rdf_file)) { - return; - } + /** + * @param string $extension_datas The path to the folder containing the datas to add to the extension + * @return FirefoxProfile + */ + public function addExtensionDatas($extension_datas) + { + if (!is_dir($extension_datas)) { + return null; + } - $this->rdf_file = $rdf_file; - return $this; - } - - /** - * @param string $key - * @param string|bool|int $value - * @return FirefoxProfile - * @throws WebDriverException - */ - public function setPreference($key, $value) { - if (is_string($value)) { - $value = sprintf('"%s"', $value); - } else if (is_int($value)) { - $value = sprintf('%d', $value); - } else if (is_bool($value)) { - $value = $value ? 'true' : 'false'; - } else { - throw new WebDriverException( - 'The value of the preference should be either a string, int or bool.'); - } - $this->preferences[$key] = $value; - return $this; - } - - /** - * @param $key - * @return mixed - */ - public function getPreference($key) - { - if (array_key_exists($key, $this->preferences)) { - return $this->preferences[$key]; - } + $this->extensions_datas[basename($extension_datas)] = $extension_datas; - return null; - } + return $this; + } - /** - * @return string - */ - public function encode() { - $temp_dir = $this->createTempDirectory('WebDriverFirefoxProfile'); + /** + * @param string $rdf_file The path to the rdf file + * @return FirefoxProfile + */ + public function setRdfFile($rdf_file) + { + if (!is_file($rdf_file)) { + return null; + } - if (isset($this->rdf_file)) { - copy($this->rdf_file, $temp_dir . DIRECTORY_SEPARATOR . "mimeTypes.rdf"); - } + $this->rdf_file = $rdf_file; - foreach ($this->extensions as $extension) { - $this->installExtension($extension, $temp_dir); + return $this; } - foreach ($this->extensions_datas as $dirname => $extension_datas) { - mkdir($temp_dir . DIRECTORY_SEPARATOR . $dirname); - $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($extension_datas, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST); - foreach ($iterator as $item) { - if ($item->isDir()) { - mkdir($temp_dir . DIRECTORY_SEPARATOR . $dirname . DIRECTORY_SEPARATOR . $iterator->getSubPathName()); + /** + * @param string $key + * @param string|bool|int $value + * @throws WebDriverException + * @return FirefoxProfile + */ + public function setPreference($key, $value) + { + if (is_string($value)) { + $value = sprintf('"%s"', $value); } else { - copy($item, $temp_dir . DIRECTORY_SEPARATOR . $dirname . DIRECTORY_SEPARATOR . $iterator->getSubPathName()); + if (is_int($value)) { + $value = sprintf('%d', $value); + } else { + if (is_bool($value)) { + $value = $value ? 'true' : 'false'; + } else { + throw new WebDriverException( + 'The value of the preference should be either a string, int or bool.' + ); + } + } } - } + $this->preferences[$key] = $value; + + return $this; } - $content = ""; - foreach ($this->preferences as $key => $value) { - $content .= sprintf("user_pref(\"%s\", %s);\n", $key, $value); + /** + * @param $key + * @return mixed + */ + public function getPreference($key) + { + if (array_key_exists($key, $this->preferences)) { + return $this->preferences[$key]; + } + + return null; } - file_put_contents($temp_dir.'/user.js', $content); - $zip = new ZipArchive(); - $temp_zip = tempnam(sys_get_temp_dir(), 'WebDriverFirefoxProfileZip'); - $zip->open($temp_zip, ZipArchive::CREATE); + /** + * @return string + */ + public function encode() + { + $temp_dir = $this->createTempDirectory('WebDriverFirefoxProfile'); + + if (isset($this->rdf_file)) { + copy($this->rdf_file, $temp_dir . DIRECTORY_SEPARATOR . 'mimeTypes.rdf'); + } + + foreach ($this->extensions as $extension) { + $this->installExtension($extension, $temp_dir); + } + + foreach ($this->extensions_datas as $dirname => $extension_datas) { + mkdir($temp_dir . DIRECTORY_SEPARATOR . $dirname); + $iterator = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($extension_datas, RecursiveDirectoryIterator::SKIP_DOTS), + RecursiveIteratorIterator::SELF_FIRST + ); + foreach ($iterator as $item) { + $target_dir = $temp_dir . DIRECTORY_SEPARATOR . $dirname . DIRECTORY_SEPARATOR + . $iterator->getSubPathName(); + + if ($item->isDir()) { + mkdir($target_dir); + } else { + copy($item, $target_dir); + } + } + } + + $content = ''; + foreach ($this->preferences as $key => $value) { + $content .= sprintf("user_pref(\"%s\", %s);\n", $key, $value); + } + file_put_contents($temp_dir . '/user.js', $content); + + $zip = new ZipArchive(); + $temp_zip = tempnam(sys_get_temp_dir(), 'WebDriverFirefoxProfileZip'); + $zip->open($temp_zip, ZipArchive::CREATE); + + $dir = new RecursiveDirectoryIterator($temp_dir); + $files = new RecursiveIteratorIterator($dir); - $dir = new RecursiveDirectoryIterator($temp_dir); - $files = new RecursiveIteratorIterator($dir); + $dir_prefix = preg_replace( + '#\\\\#', + '\\\\\\\\', + $temp_dir . DIRECTORY_SEPARATOR + ); - $dir_prefix = preg_replace( - '#\\\\#', - '\\\\\\\\', - $temp_dir.DIRECTORY_SEPARATOR - ); + foreach ($files as $name => $object) { + if (is_dir($name)) { + continue; + } - foreach ($files as $name => $object) { - if (is_dir($name)) { - continue; - } + $path = preg_replace("#^{$dir_prefix}#", '', $name); + $zip->addFile($name, $path); + } + $zip->close(); + + $profile = base64_encode(file_get_contents($temp_zip)); + + // clean up + $this->deleteDirectory($temp_dir); + unlink($temp_zip); + + return $profile; + } + + /** + * @param string $extension The path to the extension. + * @param string $profile_dir The path to the profile directory. + * @return string The path to the directory of this extension. + */ + private function installExtension($extension, $profile_dir) + { + $temp_dir = $this->createTempDirectory('WebDriverFirefoxProfileExtension'); + $this->extractTo($extension, $temp_dir); + + // This is a hacky way to parse the id since there is no offical RDF parser library. + // Find the correct namespace for the id element. + $install_rdf_path = $temp_dir . '/install.rdf'; + $xml = simplexml_load_file($install_rdf_path); + $ns = $xml->getDocNamespaces(); + $prefix = ''; + if (!empty($ns)) { + foreach ($ns as $key => $value) { + if (strpos($value, '//www.mozilla.org/2004/em-rdf') > 0) { + if ($key != '') { + $prefix = $key . ':'; // Separate the namespace from the name. + } + break; + } + } + } + // Get the extension id from the install manifest. + $matches = array(); + preg_match('#<' . $prefix . 'id>([^<]+)#', $xml->asXML(), $matches); + if (isset($matches[1])) { + $ext_dir = $profile_dir . '/extensions/' . $matches[1]; + mkdir($ext_dir, 0777, true); + $this->extractTo($extension, $ext_dir); + } + + // clean up + $this->deleteDirectory($temp_dir); - $path = preg_replace("#^{$dir_prefix}#", "", $name); - $zip->addFile($name, $path); + return $ext_dir; } - $zip->close(); - - $profile = base64_encode(file_get_contents($temp_zip)); - - // clean up - $this->deleteDirectory($temp_dir); - unlink($temp_zip); - - return $profile; - } - - /** - * @param string $extension The path to the extension. - * @param string $profile_dir The path to the profile directory. - * @return string The path to the directory of this extension. - */ - private function installExtension($extension, $profile_dir) { - $temp_dir = $this->createTempDirectory('WebDriverFirefoxProfileExtension'); - $this->extractTo($extension, $temp_dir); - - // This is a hacky way to parse the id since there is no offical RDF parser library. - // Find the correct namespace for the id element. - $install_rdf_path = $temp_dir.'/install.rdf'; - $xml = simplexml_load_file($install_rdf_path); - $ns = $xml->getDocNamespaces(); - $prefix = ''; - if (!empty($ns)) { - foreach($ns as $key => $value) { - if (strpos($value, '//www.mozilla.org/2004/em-rdf') > 0) { - if ($key != '') { - $prefix = $key . ':'; // Separate the namespace from the name. - } - break; - } - } - } - // Get the extension id from the install manifest. - $matches = array(); - preg_match('#<'.$prefix.'id>([^<]+)#', $xml->asXML(), $matches); - if (isset($matches[1])) { - $ext_dir = $profile_dir.'/extensions/'.$matches[1]; - mkdir($ext_dir, 0777, true); - $this->extractTo($extension, $ext_dir); - } - - // clean up - $this->deleteDirectory($temp_dir); - - return $ext_dir; - } - - /** - * @param string $prefix Prefix of the temp directory. - * - * @return string The path to the temp directory created. - * @throws WebDriverException - */ - private function createTempDirectory($prefix = '') { - $temp_dir = tempnam(sys_get_temp_dir(), $prefix); - if (file_exists($temp_dir)) { - unlink($temp_dir); - mkdir($temp_dir); - if (!is_dir($temp_dir)) { - throw new WebDriverException('Cannot create firefox profile.'); - } + + /** + * @param string $prefix Prefix of the temp directory. + * + * @throws WebDriverException + * @return string The path to the temp directory created. + */ + private function createTempDirectory($prefix = '') + { + $temp_dir = tempnam(sys_get_temp_dir(), $prefix); + if (file_exists($temp_dir)) { + unlink($temp_dir); + mkdir($temp_dir); + if (!is_dir($temp_dir)) { + throw new WebDriverException('Cannot create firefox profile.'); + } + } + + return $temp_dir; } - return $temp_dir; - } - - /** - * @param string $directory The path to the directory. - */ - private function deleteDirectory($directory) { - $dir = new RecursiveDirectoryIterator($directory, FilesystemIterator::SKIP_DOTS); - $paths = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST); - - foreach ($paths as $path) { - if ($path->isDir() && !$path->isLink()) { - rmdir($path->getPathname()); - } else { - unlink($path->getPathname()); - } + + /** + * @param string $directory The path to the directory. + */ + private function deleteDirectory($directory) + { + $dir = new RecursiveDirectoryIterator($directory, FilesystemIterator::SKIP_DOTS); + $paths = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST); + + foreach ($paths as $path) { + if ($path->isDir() && !$path->isLink()) { + rmdir($path->getPathname()); + } else { + unlink($path->getPathname()); + } + } + + rmdir($directory); } - rmdir($directory); - } - - /** - * @param string $xpi The path to the .xpi extension. - * @param string $target_dir The path to the unzip directory. - * - * @return FirefoxProfile - * @throws \Exception - */ - private function extractTo($xpi, $target_dir) { - $zip = new ZipArchive(); - if (file_exists($xpi)) { - if ($zip->open($xpi)) { - $zip->extractTo($target_dir); - $zip->close(); - } else { - throw new \Exception("Failed to open the firefox extension. '$xpi'"); - } - } else { - throw new \Exception("Firefox extension doesn't exist. '$xpi'"); + /** + * @param string $xpi The path to the .xpi extension. + * @param string $target_dir The path to the unzip directory. + * + * @throws \Exception + * @return FirefoxProfile + */ + private function extractTo($xpi, $target_dir) + { + $zip = new ZipArchive(); + if (file_exists($xpi)) { + if ($zip->open($xpi)) { + $zip->extractTo($target_dir); + $zip->close(); + } else { + throw new \Exception("Failed to open the firefox extension. '$xpi'"); + } + } else { + throw new \Exception("Firefox extension doesn't exist. '$xpi'"); + } + + return $this; } - return $this; - } } diff --git a/lib/Interactions/Internal/WebDriverButtonReleaseAction.php b/lib/Interactions/Internal/WebDriverButtonReleaseAction.php index a63570ae6..5df3cb6db 100644 --- a/lib/Interactions/Internal/WebDriverButtonReleaseAction.php +++ b/lib/Interactions/Internal/WebDriverButtonReleaseAction.php @@ -20,11 +20,10 @@ /** * Move to the location and then release the mouse key. */ -class WebDriverButtonReleaseAction - extends WebDriverMouseAction - implements WebDriverAction { - - public function perform() { - $this->mouse->mouseUp($this->getActionLocation()); - } +class WebDriverButtonReleaseAction extends WebDriverMouseAction implements WebDriverAction +{ + public function perform() + { + $this->mouse->mouseUp($this->getActionLocation()); + } } diff --git a/lib/Interactions/Internal/WebDriverClickAction.php b/lib/Interactions/Internal/WebDriverClickAction.php index f110d34bd..cf5bb9e68 100644 --- a/lib/Interactions/Internal/WebDriverClickAction.php +++ b/lib/Interactions/Internal/WebDriverClickAction.php @@ -17,11 +17,10 @@ use Facebook\WebDriver\WebDriverAction; -class WebDriverClickAction - extends WebDriverMouseAction - implements WebDriverAction { - - public function perform() { - $this->mouse->click($this->getActionLocation()); - } +class WebDriverClickAction extends WebDriverMouseAction implements WebDriverAction +{ + public function perform() + { + $this->mouse->click($this->getActionLocation()); + } } diff --git a/lib/Interactions/Internal/WebDriverClickAndHoldAction.php b/lib/Interactions/Internal/WebDriverClickAndHoldAction.php index 264d1503f..8f1907d84 100644 --- a/lib/Interactions/Internal/WebDriverClickAndHoldAction.php +++ b/lib/Interactions/Internal/WebDriverClickAndHoldAction.php @@ -20,11 +20,10 @@ /** * Move the the location, click and hold. */ -class WebDriverClickAndHoldAction - extends WebDriverMouseAction - implements WebDriverAction { - - public function perform() { - $this->mouse->mouseDown($this->getActionLocation()); - } +class WebDriverClickAndHoldAction extends WebDriverMouseAction implements WebDriverAction +{ + public function perform() + { + $this->mouse->mouseDown($this->getActionLocation()); + } } diff --git a/lib/Interactions/Internal/WebDriverContextClickAction.php b/lib/Interactions/Internal/WebDriverContextClickAction.php index d431173e9..175c60e3e 100644 --- a/lib/Interactions/Internal/WebDriverContextClickAction.php +++ b/lib/Interactions/Internal/WebDriverContextClickAction.php @@ -20,11 +20,10 @@ /** * You can call it 'Right Click' if you like. */ -class WebDriverContextClickAction - extends WebDriverMouseAction - implements WebDriverAction { - - public function perform() { - $this->mouse->contextClick($this->getActionLocation()); - } +class WebDriverContextClickAction extends WebDriverMouseAction implements WebDriverAction +{ + public function perform() + { + $this->mouse->contextClick($this->getActionLocation()); + } } diff --git a/lib/Interactions/Internal/WebDriverCoordinates.php b/lib/Interactions/Internal/WebDriverCoordinates.php index 89aae19bb..ca7069cb5 100644 --- a/lib/Interactions/Internal/WebDriverCoordinates.php +++ b/lib/Interactions/Internal/WebDriverCoordinates.php @@ -22,54 +22,53 @@ /** * Interface representing basic mouse operations. */ -class WebDriverCoordinates { +class WebDriverCoordinates +{ + private $onScreen; + private $inViewPort; + private $onPage; + private $auxiliary; - private - $onScreen, - $inViewPort, - $onPage, - $auxiliary; + public function __construct($on_screen, Closure $in_view_port, Closure $on_page, $auxiliary) + { + $this->onScreen = $on_screen; + $this->inViewPort = $in_view_port; + $this->onPage = $on_page; + $this->auxiliary = $auxiliary; + } - public function __construct( - $on_screen, - Closure $in_view_port, - Closure $on_page, - $auxiliary) { + /** + * @throws UnsupportedOperationException + * @return WebDriverPoint + */ + public function onScreen() + { + throw new UnsupportedOperationException( + 'onScreen is planned but not yet supported by Selenium' + ); + } - $this->onScreen = $on_screen; - $this->inViewPort = $in_view_port; - $this->onPage = $on_page; - $this->auxiliary = $auxiliary; - } + /** + * @return WebDriverPoint + */ + public function inViewPort() + { + return call_user_func($this->inViewPort); + } - /** - * @return WebDriverPoint - * @throws UnsupportedOperationException - */ - public function onScreen() { - throw new UnsupportedOperationException( - 'onScreen is planned but not yet supported by Selenium' - ); - } + /** + * @return WebDriverPoint + */ + public function onPage() + { + return call_user_func($this->onPage); + } - /** - * @return WebDriverPoint - */ - public function inViewPort() { - return call_user_func($this->inViewPort); - } - - /** - * @return WebDriverPoint - */ - public function onPage() { - return call_user_func($this->onPage); - } - - /** - * @return Object The attached object. - */ - public function getAuxiliary() { - return $this->auxiliary; - } + /** + * @return object The attached object. + */ + public function getAuxiliary() + { + return $this->auxiliary; + } } diff --git a/lib/Interactions/Internal/WebDriverDoubleClickAction.php b/lib/Interactions/Internal/WebDriverDoubleClickAction.php index 218a05b5e..46c197bbb 100644 --- a/lib/Interactions/Internal/WebDriverDoubleClickAction.php +++ b/lib/Interactions/Internal/WebDriverDoubleClickAction.php @@ -17,11 +17,10 @@ use Facebook\WebDriver\WebDriverAction; -class WebDriverDoubleClickAction - extends WebDriverMouseAction - implements WebDriverAction { - - public function perform() { - $this->mouse->doubleClick($this->getActionLocation()); - } +class WebDriverDoubleClickAction extends WebDriverMouseAction implements WebDriverAction +{ + public function perform() + { + $this->mouse->doubleClick($this->getActionLocation()); + } } diff --git a/lib/Interactions/Internal/WebDriverKeyDownAction.php b/lib/Interactions/Internal/WebDriverKeyDownAction.php index 29350e484..bb3820ed3 100644 --- a/lib/Interactions/Internal/WebDriverKeyDownAction.php +++ b/lib/Interactions/Internal/WebDriverKeyDownAction.php @@ -17,12 +17,11 @@ use Facebook\WebDriver\WebDriverAction; -class WebDriverKeyDownAction - extends WebDriverSingleKeyAction - implements WebDriverAction { - - public function perform() { - $this->focusOnElement(); - $this->keyboard->pressKey($this->key); - } +class WebDriverKeyDownAction extends WebDriverSingleKeyAction implements WebDriverAction +{ + public function perform() + { + $this->focusOnElement(); + $this->keyboard->pressKey($this->key); + } } diff --git a/lib/Interactions/Internal/WebDriverKeyUpAction.php b/lib/Interactions/Internal/WebDriverKeyUpAction.php index 9b89747eb..b675025e6 100644 --- a/lib/Interactions/Internal/WebDriverKeyUpAction.php +++ b/lib/Interactions/Internal/WebDriverKeyUpAction.php @@ -17,12 +17,11 @@ use Facebook\WebDriver\WebDriverAction; -class WebDriverKeyUpAction - extends WebDriverSingleKeyAction - implements WebDriverAction { - - public function perform() { - $this->focusOnElement(); - $this->keyboard->releaseKey($this->key); - } +class WebDriverKeyUpAction extends WebDriverSingleKeyAction implements WebDriverAction +{ + public function perform() + { + $this->focusOnElement(); + $this->keyboard->releaseKey($this->key); + } } diff --git a/lib/Interactions/Internal/WebDriverKeysRelatedAction.php b/lib/Interactions/Internal/WebDriverKeysRelatedAction.php index 77892cc25..b2f062750 100644 --- a/lib/Interactions/Internal/WebDriverKeysRelatedAction.php +++ b/lib/Interactions/Internal/WebDriverKeysRelatedAction.php @@ -16,38 +16,37 @@ namespace Facebook\WebDriver\Interactions\Internal; use Facebook\WebDriver\Internal\WebDriverLocatable; -use Facebook\WebDriver\WebDriverMouse; use Facebook\WebDriver\WebDriverKeyboard; +use Facebook\WebDriver\WebDriverMouse; /** * Base class for all keyboard-related actions. */ -abstract class WebDriverKeysRelatedAction { +abstract class WebDriverKeysRelatedAction +{ + protected $keyboard; + protected $mouse; + protected $locationProvider; - protected $keyboard; - protected $mouse; - protected $locationProvider; - - /** - * @param WebDriverKeyboard $keyboard - * @param WebDriverMouse $mouse - * @param WebDriverLocatable $location_provider - */ - public function __construct( - WebDriverKeyboard $keyboard, - WebDriverMouse $mouse, - WebDriverLocatable $location_provider = null) { - $this->keyboard = $keyboard; - $this->mouse = $mouse; - $this->locationProvider = $location_provider; - } + /** + * @param WebDriverKeyboard $keyboard + * @param WebDriverMouse $mouse + * @param WebDriverLocatable $location_provider + */ + public function __construct( + WebDriverKeyboard $keyboard, + WebDriverMouse $mouse, + WebDriverLocatable $location_provider = null + ) { + $this->keyboard = $keyboard; + $this->mouse = $mouse; + $this->locationProvider = $location_provider; + } - /** - * @return void - */ - protected function focusOnElement() { - if ($this->locationProvider) { - $this->mouse->click($this->locationProvider->getCoordinates()); + protected function focusOnElement() + { + if ($this->locationProvider) { + $this->mouse->click($this->locationProvider->getCoordinates()); + } } - } } diff --git a/lib/Interactions/Internal/WebDriverMouseAction.php b/lib/Interactions/Internal/WebDriverMouseAction.php index f6a115f43..8a13d86a7 100644 --- a/lib/Interactions/Internal/WebDriverMouseAction.php +++ b/lib/Interactions/Internal/WebDriverMouseAction.php @@ -15,46 +15,43 @@ namespace Facebook\WebDriver\Interactions\Internal; -use Facebook\WebDriver\WebDriverMouse; use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverMouse; /** * Base class for all mouse-related actions. */ -class WebDriverMouseAction { - - /** - * @var WebDriverMouse - */ - protected $mouse; - - /** - * @var WebDriverLocatable - */ - protected $locationProvider; +class WebDriverMouseAction +{ + /** + * @var WebDriverMouse + */ + protected $mouse; + /** + * @var WebDriverLocatable + */ + protected $locationProvider; + + public function __construct(WebDriverMouse $mouse, WebDriverLocatable $location_provider = null) + { + $this->mouse = $mouse; + $this->locationProvider = $location_provider; + } - public function __construct( - WebDriverMouse $mouse, - WebDriverLocatable $location_provider = null) { - $this->mouse = $mouse; - $this->locationProvider = $location_provider; - } + /** + * @return null|WebDriverCoordinates + */ + protected function getActionLocation() + { + if ($this->locationProvider !== null) { + return $this->locationProvider->getCoordinates(); + } - /** - * @return null|WebDriverCoordinates - */ - protected function getActionLocation() { - if ($this->locationProvider !== null) { - return $this->locationProvider->getCoordinates(); + return null; } - return null; - } - - /** - * @return void - */ - protected function moveToLocation() { - $this->mouse->mouseMove($this->locationProvider); - } + protected function moveToLocation() + { + $this->mouse->mouseMove($this->locationProvider); + } } diff --git a/lib/Interactions/Internal/WebDriverMouseMoveAction.php b/lib/Interactions/Internal/WebDriverMouseMoveAction.php index d229904fc..87c6d7cbb 100644 --- a/lib/Interactions/Internal/WebDriverMouseMoveAction.php +++ b/lib/Interactions/Internal/WebDriverMouseMoveAction.php @@ -17,11 +17,10 @@ use Facebook\WebDriver\WebDriverAction; -class WebDriverMouseMoveAction - extends WebDriverMouseAction - implements WebDriverAction { - - public function perform() { - $this->mouse->mouseMove($this->getActionLocation()); - } +class WebDriverMouseMoveAction extends WebDriverMouseAction implements WebDriverAction +{ + public function perform() + { + $this->mouse->mouseMove($this->getActionLocation()); + } } diff --git a/lib/Interactions/Internal/WebDriverMoveToOffsetAction.php b/lib/Interactions/Internal/WebDriverMoveToOffsetAction.php index f1e0270f8..7fffa0189 100644 --- a/lib/Interactions/Internal/WebDriverMoveToOffsetAction.php +++ b/lib/Interactions/Internal/WebDriverMoveToOffsetAction.php @@ -15,30 +15,32 @@ namespace Facebook\WebDriver\Interactions\Internal; -use Facebook\WebDriver\WebDriverAction; use Facebook\WebDriver\Internal\WebDriverLocatable; +use Facebook\WebDriver\WebDriverAction; use Facebook\WebDriver\WebDriverMouse; -class WebDriverMoveToOffsetAction - extends WebDriverMouseAction - implements WebDriverAction { - - private $xOffset, $yOffset; +class WebDriverMoveToOffsetAction extends WebDriverMouseAction implements WebDriverAction +{ + private $xOffset; + private $yOffset; - public function __construct(WebDriverMouse $mouse, - WebDriverLocatable $location_provider = null, - $x_offset = null, - $y_offset = null) { - parent::__construct($mouse, $location_provider); - $this->xOffset = $x_offset; - $this->yOffset = $y_offset; - } + public function __construct( + WebDriverMouse $mouse, + WebDriverLocatable $location_provider = null, + $x_offset = null, + $y_offset = null + ) { + parent::__construct($mouse, $location_provider); + $this->xOffset = $x_offset; + $this->yOffset = $y_offset; + } - public function perform() { - $this->mouse->mouseMove( - $this->getActionLocation(), - $this->xOffset, - $this->yOffset - ); - } + public function perform() + { + $this->mouse->mouseMove( + $this->getActionLocation(), + $this->xOffset, + $this->yOffset + ); + } } diff --git a/lib/Interactions/Internal/WebDriverSendKeysAction.php b/lib/Interactions/Internal/WebDriverSendKeysAction.php index 2c9512dd3..14836be38 100644 --- a/lib/Interactions/Internal/WebDriverSendKeysAction.php +++ b/lib/Interactions/Internal/WebDriverSendKeysAction.php @@ -15,34 +15,34 @@ namespace Facebook\WebDriver\Interactions\Internal; +use Facebook\WebDriver\Internal\WebDriverLocatable; use Facebook\WebDriver\WebDriverAction; use Facebook\WebDriver\WebDriverKeyboard; -use Facebook\WebDriver\Internal\WebDriverLocatable; use Facebook\WebDriver\WebDriverMouse; -class WebDriverSendKeysAction - extends WebDriverKeysRelatedAction - implements WebDriverAction { - - private $keys; +class WebDriverSendKeysAction extends WebDriverKeysRelatedAction implements WebDriverAction +{ + private $keys; - /** - * @param WebDriverKeyboard $keyboard - * @param WebDriverMouse $mouse - * @param WebDriverLocatable $location_provider - * @param string $keys - */ - public function __construct( - WebDriverKeyboard $keyboard, - WebDriverMouse $mouse, - WebDriverLocatable $location_provider = null, - $keys = null) { - parent::__construct($keyboard, $mouse, $location_provider); - $this->keys = $keys; - } + /** + * @param WebDriverKeyboard $keyboard + * @param WebDriverMouse $mouse + * @param WebDriverLocatable $location_provider + * @param string $keys + */ + public function __construct( + WebDriverKeyboard $keyboard, + WebDriverMouse $mouse, + WebDriverLocatable $location_provider = null, + $keys = null + ) { + parent::__construct($keyboard, $mouse, $location_provider); + $this->keys = $keys; + } - public function perform() { - $this->focusOnElement(); - $this->keyboard->sendKeys($this->keys); - } + public function perform() + { + $this->focusOnElement(); + $this->keyboard->sendKeys($this->keys); + } } diff --git a/lib/Interactions/Internal/WebDriverSingleKeyAction.php b/lib/Interactions/Internal/WebDriverSingleKeyAction.php index 86cd74936..174304d15 100644 --- a/lib/Interactions/Internal/WebDriverSingleKeyAction.php +++ b/lib/Interactions/Internal/WebDriverSingleKeyAction.php @@ -15,23 +15,22 @@ namespace Facebook\WebDriver\Interactions\Internal; +use Facebook\WebDriver\Internal\WebDriverLocatable; use Facebook\WebDriver\WebDriverAction; use Facebook\WebDriver\WebDriverKeyboard; -use Facebook\WebDriver\Internal\WebDriverLocatable; use Facebook\WebDriver\WebDriverMouse; -abstract class WebDriverSingleKeyAction - extends WebDriverKeysRelatedAction - implements WebDriverAction { - - protected $key; +abstract class WebDriverSingleKeyAction extends WebDriverKeysRelatedAction implements WebDriverAction +{ + protected $key; - public function __construct( - WebDriverKeyboard $keyboard, - WebDriverMouse $mouse, - WebDriverLocatable $location_provider = null, - $key = null) { - parent::__construct($keyboard, $mouse, $location_provider); - $this->key = $key; - } + public function __construct( + WebDriverKeyboard $keyboard, + WebDriverMouse $mouse, + WebDriverLocatable $location_provider = null, + $key = null + ) { + parent::__construct($keyboard, $mouse, $location_provider); + $this->key = $key; + } } diff --git a/lib/Interactions/Touch/WebDriverDoubleTapAction.php b/lib/Interactions/Touch/WebDriverDoubleTapAction.php index 92ccfa222..47664fe23 100644 --- a/lib/Interactions/Touch/WebDriverDoubleTapAction.php +++ b/lib/Interactions/Touch/WebDriverDoubleTapAction.php @@ -17,11 +17,10 @@ use Facebook\WebDriver\WebDriverAction; -class WebDriverDoubleTapAction - extends WebDriverTouchAction - implements WebDriverAction { - - public function perform() { - $this->touchScreen->doubleTap($this->locationProvider); - } +class WebDriverDoubleTapAction extends WebDriverTouchAction implements WebDriverAction +{ + public function perform() + { + $this->touchScreen->doubleTap($this->locationProvider); + } } diff --git a/lib/Interactions/Touch/WebDriverDownAction.php b/lib/Interactions/Touch/WebDriverDownAction.php index eb946008f..46224aea2 100644 --- a/lib/Interactions/Touch/WebDriverDownAction.php +++ b/lib/Interactions/Touch/WebDriverDownAction.php @@ -17,25 +17,25 @@ use Facebook\WebDriver\WebDriverAction; -class WebDriverDownAction - extends WebDriverTouchAction - implements WebDriverAction { +class WebDriverDownAction extends WebDriverTouchAction implements WebDriverAction +{ + private $x; + private $y; - private $x; - private $y; + /** + * @param WebDriverTouchScreen $touch_screen + * @param int $x + * @param int $y + */ + public function __construct(WebDriverTouchScreen $touch_screen, $x, $y) + { + $this->x = $x; + $this->y = $y; + parent::__construct($touch_screen); + } - /** - * @param WebDriverTouchScreen $touch_screen - * @param int $x - * @param int $y - */ - public function __construct(WebDriverTouchScreen $touch_screen, $x, $y) { - $this->x = $x; - $this->y = $y; - parent::__construct($touch_screen); - } - - public function perform() { - $this->touchScreen->down($this->x, $this->y); - } + public function perform() + { + $this->touchScreen->down($this->x, $this->y); + } } diff --git a/lib/Interactions/Touch/WebDriverFlickAction.php b/lib/Interactions/Touch/WebDriverFlickAction.php index 575c3eb4d..48e65dc95 100644 --- a/lib/Interactions/Touch/WebDriverFlickAction.php +++ b/lib/Interactions/Touch/WebDriverFlickAction.php @@ -17,22 +17,22 @@ use Facebook\WebDriver\WebDriverAction; -class WebDriverFlickAction - extends WebDriverTouchAction - implements WebDriverAction { +class WebDriverFlickAction extends WebDriverTouchAction implements WebDriverAction +{ + /** + * @param WebDriverTouchScreen $touch_screen + * @param int $x + * @param int $y + */ + public function __construct(WebDriverTouchScreen $touch_screen, $x, $y) + { + $this->x = $x; + $this->y = $y; + parent::__construct($touch_screen); + } - /** - * @param WebDriverTouchScreen $touch_screen - * @param int $x - * @param int $y - */ - public function __construct(WebDriverTouchScreen $touch_screen, $x, $y) { - $this->x = $x; - $this->y = $y; - parent::__construct($touch_screen); - } - - public function perform() { - $this->touchScreen->flick($this->x, $this->y); - } + public function perform() + { + $this->touchScreen->flick($this->x, $this->y); + } } diff --git a/lib/Interactions/Touch/WebDriverFlickFromElementAction.php b/lib/Interactions/Touch/WebDriverFlickFromElementAction.php index afd13ab8c..d91e84898 100644 --- a/lib/Interactions/Touch/WebDriverFlickFromElementAction.php +++ b/lib/Interactions/Touch/WebDriverFlickFromElementAction.php @@ -18,37 +18,39 @@ use Facebook\WebDriver\WebDriverAction; use Facebook\WebDriver\WebDriverElement; -class WebDriverFlickFromElementAction - extends WebDriverTouchAction - implements WebDriverAction { +class WebDriverFlickFromElementAction extends WebDriverTouchAction implements WebDriverAction +{ + private $x; + private $y; + private $speed; - private $x; - private $y; - private $speed; + /** + * @param WebDriverTouchScreen $touch_screen + * @param WebDriverElement $element + * @param int $x + * @param int $y + * @param int $speed + */ + public function __construct( + WebDriverTouchScreen $touch_screen, + WebDriverElement $element, + $x, + $y, + $speed + ) { + $this->x = $x; + $this->y = $y; + $this->speed = $speed; + parent::__construct($touch_screen, $element); + } - /** - * @param WebDriverTouchScreen $touch_screen - * @param WebDriverElement $element - * @param int $x - * @param int $y - * @param int $speed - */ - public function __construct( - WebDriverTouchScreen $touch_screen, - WebDriverElement $element, $x, $y, $speed - ) { - $this->x = $x; - $this->y = $y; - $this->speed = $speed; - parent::__construct($touch_screen, $element); - } - - public function perform() { - $this->touchScreen->flickFromElement( - $this->locationProvider, - $this->x, - $this->y, - $this->speed - ); - } + public function perform() + { + $this->touchScreen->flickFromElement( + $this->locationProvider, + $this->x, + $this->y, + $this->speed + ); + } } diff --git a/lib/Interactions/Touch/WebDriverLongPressAction.php b/lib/Interactions/Touch/WebDriverLongPressAction.php index c46770d86..bf6e8bf49 100644 --- a/lib/Interactions/Touch/WebDriverLongPressAction.php +++ b/lib/Interactions/Touch/WebDriverLongPressAction.php @@ -17,11 +17,10 @@ use Facebook\WebDriver\WebDriverAction; -class WebDriverLongPressAction - extends WebDriverTouchAction - implements WebDriverAction { - - public function perform() { - $this->touchScreen->longPress($this->locationProvider); - } +class WebDriverLongPressAction extends WebDriverTouchAction implements WebDriverAction +{ + public function perform() + { + $this->touchScreen->longPress($this->locationProvider); + } } diff --git a/lib/Interactions/Touch/WebDriverMoveAction.php b/lib/Interactions/Touch/WebDriverMoveAction.php index 330783271..bb2a4bab1 100644 --- a/lib/Interactions/Touch/WebDriverMoveAction.php +++ b/lib/Interactions/Touch/WebDriverMoveAction.php @@ -17,25 +17,25 @@ use Facebook\WebDriver\WebDriverAction; -class WebDriverMoveAction - extends WebDriverTouchAction - implements WebDriverAction { +class WebDriverMoveAction extends WebDriverTouchAction implements WebDriverAction +{ + private $x; + private $y; - private $x; - private $y; + /** + * @param WebDriverTouchScreen $touch_screen + * @param int $x + * @param int $y + */ + public function __construct(WebDriverTouchScreen $touch_screen, $x, $y) + { + $this->x = $x; + $this->y = $y; + parent::__construct($touch_screen); + } - /** - * @param WebDriverTouchScreen $touch_screen - * @param int $x - * @param int $y - */ - public function __construct(WebDriverTouchScreen $touch_screen, $x, $y) { - $this->x = $x; - $this->y = $y; - parent::__construct($touch_screen); - } - - public function perform() { - $this->touchScreen->move($this->x, $this->y); - } + public function perform() + { + $this->touchScreen->move($this->x, $this->y); + } } diff --git a/lib/Interactions/Touch/WebDriverScrollAction.php b/lib/Interactions/Touch/WebDriverScrollAction.php index 8dc1f14b7..0bb70a8e5 100644 --- a/lib/Interactions/Touch/WebDriverScrollAction.php +++ b/lib/Interactions/Touch/WebDriverScrollAction.php @@ -17,25 +17,25 @@ use Facebook\WebDriver\WebDriverAction; -class WebDriverScrollAction - extends WebDriverTouchAction - implements WebDriverAction { +class WebDriverScrollAction extends WebDriverTouchAction implements WebDriverAction +{ + private $x; + private $y; - private $x; - private $y; + /** + * @param WebDriverTouchScreen $touch_screen + * @param int $x + * @param int $y + */ + public function __construct(WebDriverTouchScreen $touch_screen, $x, $y) + { + $this->x = $x; + $this->y = $y; + parent::__construct($touch_screen); + } - /** - * @param WebDriverTouchScreen $touch_screen - * @param int $x - * @param int $y - */ - public function __construct(WebDriverTouchScreen $touch_screen, $x, $y) { - $this->x = $x; - $this->y = $y; - parent::__construct($touch_screen); - } - - public function perform() { - $this->touchScreen->scroll($this->x, $this->y); - } + public function perform() + { + $this->touchScreen->scroll($this->x, $this->y); + } } diff --git a/lib/Interactions/Touch/WebDriverScrollFromElementAction.php b/lib/Interactions/Touch/WebDriverScrollFromElementAction.php index df31f13b0..073244480 100644 --- a/lib/Interactions/Touch/WebDriverScrollFromElementAction.php +++ b/lib/Interactions/Touch/WebDriverScrollFromElementAction.php @@ -18,32 +18,34 @@ use Facebook\WebDriver\WebDriverAction; use Facebook\WebDriver\WebDriverElement; -class WebDriverScrollFromElementAction - extends WebDriverTouchAction - implements WebDriverAction { +class WebDriverScrollFromElementAction extends WebDriverTouchAction implements WebDriverAction +{ + private $x; + private $y; - private $x; - private $y; + /** + * @param WebDriverTouchScreen $touch_screen + * @param WebDriverElement $element + * @param int $x + * @param int $y + */ + public function __construct( + WebDriverTouchScreen $touch_screen, + WebDriverElement $element, + $x, + $y + ) { + $this->x = $x; + $this->y = $y; + parent::__construct($touch_screen, $element); + } - /** - * @param WebDriverTouchScreen $touch_screen - * @param WebDriverElement $element - * @param int $x - * @param int $y - */ - public function __construct( - WebDriverTouchScreen $touch_screen, WebDriverElement $element, $x, $y - ) { - $this->x = $x; - $this->y = $y; - parent::__construct($touch_screen, $element); - } - - public function perform() { - $this->touchScreen->scrollFromElement( - $this->locationProvider, - $this->x, - $this->y - ); - } + public function perform() + { + $this->touchScreen->scrollFromElement( + $this->locationProvider, + $this->x, + $this->y + ); + } } diff --git a/lib/Interactions/Touch/WebDriverTapAction.php b/lib/Interactions/Touch/WebDriverTapAction.php index 835acc848..31ccf5678 100644 --- a/lib/Interactions/Touch/WebDriverTapAction.php +++ b/lib/Interactions/Touch/WebDriverTapAction.php @@ -17,11 +17,10 @@ use Facebook\WebDriver\WebDriverAction; -class WebDriverTapAction - extends WebDriverTouchAction - implements WebDriverAction { - - public function perform() { - $this->touchScreen->tap($this->locationProvider); - } +class WebDriverTapAction extends WebDriverTouchAction implements WebDriverAction +{ + public function perform() + { + $this->touchScreen->tap($this->locationProvider); + } } diff --git a/lib/Interactions/Touch/WebDriverTouchAction.php b/lib/Interactions/Touch/WebDriverTouchAction.php index e267f1ab3..dd09e6499 100644 --- a/lib/Interactions/Touch/WebDriverTouchAction.php +++ b/lib/Interactions/Touch/WebDriverTouchAction.php @@ -15,42 +15,41 @@ namespace Facebook\WebDriver\Interactions\Touch; -use Facebook\WebDriver\Internal\WebDriverLocatable; use Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates; +use Facebook\WebDriver\Internal\WebDriverLocatable; /** * Base class for all touch-related actions. */ -abstract class WebDriverTouchAction { - - /** - * @var WebDriverTouchScreen - */ - protected $touchScreen; - - /** - * @var WebDriverLocatable - */ - protected $locationProvider; - - /** - * @param WebDriverTouchScreen $touch_screen - * @param WebDriverLocatable $location_provider - */ - public function __construct( - WebDriverTouchScreen $touch_screen, - WebDriverLocatable $location_provider = null - ) { - $this->touchScreen = $touch_screen; - $this->locationProvider = $location_provider; - } - - /** - * @return null|WebDriverCoordinates - */ - protected function getActionLocation() { - return $this->locationProvider !== null - ? $this->locationProvider->getCoordinates() : null; - } - +abstract class WebDriverTouchAction +{ + /** + * @var WebDriverTouchScreen + */ + protected $touchScreen; + /** + * @var WebDriverLocatable + */ + protected $locationProvider; + + /** + * @param WebDriverTouchScreen $touch_screen + * @param WebDriverLocatable $location_provider + */ + public function __construct( + WebDriverTouchScreen $touch_screen, + WebDriverLocatable $location_provider = null + ) { + $this->touchScreen = $touch_screen; + $this->locationProvider = $location_provider; + } + + /** + * @return null|WebDriverCoordinates + */ + protected function getActionLocation() + { + return $this->locationProvider !== null + ? $this->locationProvider->getCoordinates() : null; + } } diff --git a/lib/Interactions/Touch/WebDriverTouchScreen.php b/lib/Interactions/Touch/WebDriverTouchScreen.php index cb753cd0d..4bb6f1100 100644 --- a/lib/Interactions/Touch/WebDriverTouchScreen.php +++ b/lib/Interactions/Touch/WebDriverTouchScreen.php @@ -20,103 +20,108 @@ /** * Interface representing touch screen operations. */ -interface WebDriverTouchScreen { +interface WebDriverTouchScreen +{ + /** + * Single tap on the touch enabled device. + * + * @param WebDriverElement $element + * @return $this + */ + public function tap(WebDriverElement $element); - /** - * Single tap on the touch enabled device. - * - * @param WebDriverElement $element - * @return $this - */ - public function tap(WebDriverElement $element); + /** + * Double tap on the touch screen using finger motion events. + * + * @param WebDriverElement $element + * @return $this + */ + public function doubleTap(WebDriverElement $element); - /** - * Double tap on the touch screen using finger motion events. - * - * @param WebDriverElement $element - * @return $this - */ - public function doubleTap(WebDriverElement $element); + /** + * Finger down on the screen. + * + * @param int $x + * @param int $y + * @return $this + */ + public function down($x, $y); - /** - * Finger down on the screen. - * - * @param int $x - * @param int $y - * @return $this - */ - public function down($x, $y); + /** + * Flick on the touch screen using finger motion events. Use this flick + * command if you don't care where the flick starts on the screen. + * + * @param int $xspeed + * @param int $yspeed + * @return $this + */ + public function flick($xspeed, $yspeed); - /** - * Flick on the touch screen using finger motion events. Use this flick - * command if you don't care where the flick starts on the screen. - * - * @param int $xspeed - * @param int $yspeed - * @return $this - */ - public function flick($xspeed, $yspeed); + /** + * Flick on the touch screen using finger motion events. + * This flickcommand starts at a particular screen location. + * + * @param WebDriverElement $element + * @param int $xoffset + * @param int $yoffset + * @param int $speed + * @return $this + */ + public function flickFromElement( + WebDriverElement $element, + $xoffset, + $yoffset, + $speed + ); - /** - * Flick on the touch screen using finger motion events. - * This flickcommand starts at a particular screen location. - * - * @param WebDriverElement $element - * @param int $xoffset - * @param int $yoffset - * @param int $speed - * @return $this - */ - public function flickFromElement( - WebDriverElement $element, $xoffset, $yoffset, $speed); + /** + * Long press on the touch screen using finger motion events. + * + * @param WebDriverElement $element + * @return $this + */ + public function longPress(WebDriverElement $element); - /** - * Long press on the touch screen using finger motion events. - * - * @param WebDriverElement $element - * @return $this - */ - public function longPress(WebDriverElement $element); + /** + * Finger move on the screen. + * + * @param int $x + * @param int $y + * @return $this + */ + public function move($x, $y); - /** - * Finger move on the screen. - * - * @param int $x - * @param int $y - * @return $this - */ - public function move($x, $y); + /** + * Scroll on the touch screen using finger based motion events. Use this + * command if you don't care where the scroll starts on the screen. + * + * @param int $xoffset + * @param int $yoffset + * @return $this + */ + public function scroll($xoffset, $yoffset); + /** + * Scroll on the touch screen using finger based motion events. Use this + * command to start scrolling at a particular screen location. + * + * @param WebDriverElement $element + * @param int $xoffset + * @param int $yoffset + * @return $this + */ + public function scrollFromElement( + WebDriverElement $element, + $xoffset, + $yoffset + ); - /** - * Scroll on the touch screen using finger based motion events. Use this - * command if you don't care where the scroll starts on the screen. - * - * @param int $xoffset - * @param int $yoffset - * @return $this - */ - public function scroll($xoffset, $yoffset); - - /** - * Scroll on the touch screen using finger based motion events. Use this - * command to start scrolling at a particular screen location. - * - * @param WebDriverElement $element - * @param int $xoffset - * @param int $yoffset - * @return $this - */ - public function scrollFromElement( - WebDriverElement $element, $xoffset, $yoffset); - - /** - * Finger up on the screen. - * - * @param int $x - * @param int $y - * @return $this - */ - public function up($x, $y); - + /** + * Finger up on the screen. + * + * @param int $x + * @param int $y + * @return $this + */ + public function up($x, $y); } diff --git a/lib/Interactions/WebDriverActions.php b/lib/Interactions/WebDriverActions.php index 3e11b3c0a..860cf8d5a 100644 --- a/lib/Interactions/WebDriverActions.php +++ b/lib/Interactions/WebDriverActions.php @@ -15,237 +15,264 @@ namespace Facebook\WebDriver\Interactions; -use Facebook\WebDriver\Interactions\Internal\WebDriverClickAndHoldAction; -use Facebook\WebDriver\Interactions\Internal\WebDriverMoveToOffsetAction; use Facebook\WebDriver\Interactions\Internal\WebDriverButtonReleaseAction; -use Facebook\WebDriver\Interactions\Internal\WebDriverDoubleClickAction; -use Facebook\WebDriver\Interactions\Internal\WebDriverSendKeysAction; use Facebook\WebDriver\Interactions\Internal\WebDriverClickAction; -use Facebook\WebDriver\Interactions\Internal\WebDriverKeyDownAction; +use Facebook\WebDriver\Interactions\Internal\WebDriverClickAndHoldAction; use Facebook\WebDriver\Interactions\Internal\WebDriverContextClickAction; +use Facebook\WebDriver\Interactions\Internal\WebDriverDoubleClickAction; +use Facebook\WebDriver\Interactions\Internal\WebDriverKeyDownAction; use Facebook\WebDriver\Interactions\Internal\WebDriverKeyUpAction; use Facebook\WebDriver\Interactions\Internal\WebDriverMouseMoveAction; -use Facebook\WebDriver\WebDriverElement; +use Facebook\WebDriver\Interactions\Internal\WebDriverMoveToOffsetAction; +use Facebook\WebDriver\Interactions\Internal\WebDriverSendKeysAction; use Facebook\WebDriver\WebDriver; +use Facebook\WebDriver\WebDriverElement; /** * WebDriver action builder. It implements the builder pattern. */ -class WebDriverActions { - - protected $driver; - protected $keyboard; - protected $mouse; - protected $action; - - public function __construct(WebDriver $driver) { - $this->driver = $driver; - $this->keyboard = $driver->getKeyboard(); - $this->mouse = $driver->getMouse(); - $this->action = new WebDriverCompositeAction(); - } - - /** - * A convenience method for performing the actions without calling build(). - * @return void - */ - public function perform() { - $this->action->perform(); - } - - /** - * Mouse click. - * If $element is provided, move to the middle of the element first. - * - * @param WebDriverElement $element - * @return WebDriverActions - */ - public function click(WebDriverElement $element = null) { - $this->action->addAction( - new WebDriverClickAction($this->mouse, $element) - ); - return $this; - } - - /** - * Mouse click and hold. - * If $element is provided, move to the middle of the element first. - * - * @param WebDriverElement $element - * @return WebDriverActions - */ - public function clickAndHold(WebDriverElement $element = null) { - $this->action->addAction( - new WebDriverClickAndHoldAction($this->mouse, $element) - ); - return $this; - } - - /** - * Context-click (right click). - * If $element is provided, move to the middle of the element first. - * - * @param WebDriverElement $element - * @return WebDriverActions - */ - public function contextClick(WebDriverElement $element = null) { - $this->action->addAction( - new WebDriverContextClickAction($this->mouse, $element) - ); - return $this; - } - - /** - * Double click. - * If $element is provided, move to the middle of the element first. - * - * @param WebDriverElement $element - * @return WebDriverActions - */ - public function doubleClick(WebDriverElement $element = null) { - $this->action->addAction( - new WebDriverDoubleClickAction($this->mouse, $element) - ); - return $this; - } - - /** - * Drag and drop from $source to $target. - * - * @param WebDriverElement $source - * @param WebDriverElement $target - * @return WebDriverActions - */ - public function dragAndDrop(WebDriverElement $source, - WebDriverElement $target) { - $this->action->addAction( - new WebDriverClickAndHoldAction($this->mouse, $source) - ); - $this->action->addAction( - new WebDriverMouseMoveAction($this->mouse, $target) - ); - $this->action->addAction( - new WebDriverButtonReleaseAction($this->mouse, $target) - ); - return $this; - } - - /** - * Drag $source and drop by offset ($x_offset, $y_offset). - * - * @param WebDriverElement $source - * @param int $x_offset - * @param int $y_offset - * @return WebDriverActions - */ - public function dragAndDropBy(WebDriverElement $source, - $x_offset, - $y_offset) { - $this->action->addAction( - new WebDriverClickAndHoldAction($this->mouse, $source) - ); - $this->action->addAction( - new WebDriverMoveToOffsetAction($this->mouse, null, $x_offset, $y_offset) - ); - $this->action->addAction( - new WebDriverButtonReleaseAction($this->mouse, null) - ); - return $this; - } - - /** - * Mouse move by offset. - * - * @param int $x_offset - * @param int $y_offset - * @return WebDriverActions - */ - public function moveByOffset($x_offset, $y_offset) { - $this->action->addAction( - new WebDriverMoveToOffsetAction($this->mouse, null, $x_offset, $y_offset) - ); - return $this; - } - - /** - * Move to the middle of the given WebDriverElement. - * Extra shift, calculated from the top-left corner of the element, can be set by passing $x_offset and $y_offset parameters. - * - * @param WebDriverElement $element - * @param int $x_offset - * @param int $y_offset - * @return WebDriverActions - */ - public function moveToElement(WebDriverElement $element, - $x_offset = null, - $y_offset = null) { - $this->action->addAction(new WebDriverMoveToOffsetAction( - $this->mouse, $element, $x_offset, $y_offset - )); - return $this; - } - - /** - * Release the mouse button. - * If $element is provided, move to the middle of the element first. - * - * @param WebDriverElement $element - * @return WebDriverActions - */ - public function release(WebDriverElement $element = null) { - $this->action->addAction( - new WebDriverButtonReleaseAction($this->mouse, $element) - ); - return $this; - } - - /** - * Press a key on keyboard. - * If $element is provided, focus on that element first. - * - * @see WebDriverKeys for special keys like CONTROL, ALT, etc. - * @param WebDriverElement $element - * @param string $key - * @return WebDriverActions - */ - public function keyDown(WebDriverElement $element = null, $key = null) { - $this->action->addAction( - new WebDriverKeyDownAction($this->keyboard, $this->mouse, $element, $key) - ); - return $this; - } - - /** - * Release a key on keyboard. - * If $element is provided, focus on that element first. - * - * @see WebDriverKeys for special keys like CONTROL, ALT, etc. - * @param WebDriverElement $element - * @param string $key - * @return WebDriverActions - */ - public function keyUp(WebDriverElement $element = null, $key = null) { - $this->action->addAction( - new WebDriverKeyUpAction($this->keyboard, $this->mouse, $element, $key) - ); - return $this; - } - - /** - * Send keys by keyboard. - * If $element is provided, focus on that element first. - * - * @see WebDriverKeys for special keys like CONTROL, ALT, etc. - * @param WebDriverElement $element - * @param string $keys - * @return WebDriverActions - */ - public function sendKeys(WebDriverElement $element = null, $keys = null) { - $this->action->addAction( - new WebDriverSendKeysAction( - $this->keyboard, $this->mouse, $element, $keys - ) - ); - return $this; - } +class WebDriverActions +{ + protected $driver; + protected $keyboard; + protected $mouse; + protected $action; + + public function __construct(WebDriver $driver) + { + $this->driver = $driver; + $this->keyboard = $driver->getKeyboard(); + $this->mouse = $driver->getMouse(); + $this->action = new WebDriverCompositeAction(); + } + + /** + * A convenience method for performing the actions without calling build(). + */ + public function perform() + { + $this->action->perform(); + } + + /** + * Mouse click. + * If $element is provided, move to the middle of the element first. + * + * @param WebDriverElement $element + * @return WebDriverActions + */ + public function click(WebDriverElement $element = null) + { + $this->action->addAction( + new WebDriverClickAction($this->mouse, $element) + ); + + return $this; + } + + /** + * Mouse click and hold. + * If $element is provided, move to the middle of the element first. + * + * @param WebDriverElement $element + * @return WebDriverActions + */ + public function clickAndHold(WebDriverElement $element = null) + { + $this->action->addAction( + new WebDriverClickAndHoldAction($this->mouse, $element) + ); + + return $this; + } + + /** + * Context-click (right click). + * If $element is provided, move to the middle of the element first. + * + * @param WebDriverElement $element + * @return WebDriverActions + */ + public function contextClick(WebDriverElement $element = null) + { + $this->action->addAction( + new WebDriverContextClickAction($this->mouse, $element) + ); + + return $this; + } + + /** + * Double click. + * If $element is provided, move to the middle of the element first. + * + * @param WebDriverElement $element + * @return WebDriverActions + */ + public function doubleClick(WebDriverElement $element = null) + { + $this->action->addAction( + new WebDriverDoubleClickAction($this->mouse, $element) + ); + + return $this; + } + + /** + * Drag and drop from $source to $target. + * + * @param WebDriverElement $source + * @param WebDriverElement $target + * @return WebDriverActions + */ + public function dragAndDrop(WebDriverElement $source, WebDriverElement $target) + { + $this->action->addAction( + new WebDriverClickAndHoldAction($this->mouse, $source) + ); + $this->action->addAction( + new WebDriverMouseMoveAction($this->mouse, $target) + ); + $this->action->addAction( + new WebDriverButtonReleaseAction($this->mouse, $target) + ); + + return $this; + } + + /** + * Drag $source and drop by offset ($x_offset, $y_offset). + * + * @param WebDriverElement $source + * @param int $x_offset + * @param int $y_offset + * @return WebDriverActions + */ + public function dragAndDropBy(WebDriverElement $source, $x_offset, $y_offset) + { + $this->action->addAction( + new WebDriverClickAndHoldAction($this->mouse, $source) + ); + $this->action->addAction( + new WebDriverMoveToOffsetAction($this->mouse, null, $x_offset, $y_offset) + ); + $this->action->addAction( + new WebDriverButtonReleaseAction($this->mouse, null) + ); + + return $this; + } + + /** + * Mouse move by offset. + * + * @param int $x_offset + * @param int $y_offset + * @return WebDriverActions + */ + public function moveByOffset($x_offset, $y_offset) + { + $this->action->addAction( + new WebDriverMoveToOffsetAction($this->mouse, null, $x_offset, $y_offset) + ); + + return $this; + } + + /** + * Move to the middle of the given WebDriverElement. + * Extra shift, calculated from the top-left corner of the element, can be set by passing $x_offset and $y_offset + * parameters. + * + * @param WebDriverElement $element + * @param int $x_offset + * @param int $y_offset + * @return WebDriverActions + */ + public function moveToElement(WebDriverElement $element, $x_offset = null, $y_offset = null) + { + $this->action->addAction(new WebDriverMoveToOffsetAction( + $this->mouse, + $element, + $x_offset, + $y_offset + )); + + return $this; + } + + /** + * Release the mouse button. + * If $element is provided, move to the middle of the element first. + * + * @param WebDriverElement $element + * @return WebDriverActions + */ + public function release(WebDriverElement $element = null) + { + $this->action->addAction( + new WebDriverButtonReleaseAction($this->mouse, $element) + ); + + return $this; + } + + /** + * Press a key on keyboard. + * If $element is provided, focus on that element first. + * + * @see WebDriverKeys for special keys like CONTROL, ALT, etc. + * @param WebDriverElement $element + * @param string $key + * @return WebDriverActions + */ + public function keyDown(WebDriverElement $element = null, $key = null) + { + $this->action->addAction( + new WebDriverKeyDownAction($this->keyboard, $this->mouse, $element, $key) + ); + + return $this; + } + + /** + * Release a key on keyboard. + * If $element is provided, focus on that element first. + * + * @see WebDriverKeys for special keys like CONTROL, ALT, etc. + * @param WebDriverElement $element + * @param string $key + * @return WebDriverActions + */ + public function keyUp(WebDriverElement $element = null, $key = null) + { + $this->action->addAction( + new WebDriverKeyUpAction($this->keyboard, $this->mouse, $element, $key) + ); + + return $this; + } + + /** + * Send keys by keyboard. + * If $element is provided, focus on that element first. + * + * @see WebDriverKeys for special keys like CONTROL, ALT, etc. + * @param WebDriverElement $element + * @param string $keys + * @return WebDriverActions + */ + public function sendKeys(WebDriverElement $element = null, $keys = null) + { + $this->action->addAction( + new WebDriverSendKeysAction( + $this->keyboard, + $this->mouse, + $element, + $keys + ) + ); + + return $this; + } } diff --git a/lib/Interactions/WebDriverCompositeAction.php b/lib/Interactions/WebDriverCompositeAction.php index 63d9863d7..f17cc4588 100644 --- a/lib/Interactions/WebDriverCompositeAction.php +++ b/lib/Interactions/WebDriverCompositeAction.php @@ -20,36 +20,40 @@ /** * An action for aggregating actions and triggering all of them afterwards. */ -class WebDriverCompositeAction implements WebDriverAction { +class WebDriverCompositeAction implements WebDriverAction +{ + private $actions = array(); - private $actions = array(); + /** + * Add an WebDriverAction to the sequence. + * + * @param WebDriverAction $action + * @return WebDriverCompositeAction The current instance. + */ + public function addAction(WebDriverAction $action) + { + $this->actions[] = $action; - /** - * Add an WebDriverAction to the sequence. - * - * @param WebDriverAction $action - * @return WebDriverCompositeAction The current instance. - */ - public function addAction(WebDriverAction $action) { - $this->actions[] = $action; - return $this; - } + return $this; + } - /** - * Get the number of actions in the sequence. - * - * @return int The number of actions. - */ - public function getNumberOfActions() { - return count($this->actions); - } + /** + * Get the number of actions in the sequence. + * + * @return int The number of actions. + */ + public function getNumberOfActions() + { + return count($this->actions); + } - /** - * Perform the seqeunce of actions. - */ - public function perform() { - foreach ($this->actions as $action) { - $action->perform(); + /** + * Perform the seqeunce of actions. + */ + public function perform() + { + foreach ($this->actions as $action) { + $action->perform(); + } } - } } diff --git a/lib/Interactions/WebDriverTouchActions.php b/lib/Interactions/WebDriverTouchActions.php index ec77242fc..d8cf05f4b 100644 --- a/lib/Interactions/WebDriverTouchActions.php +++ b/lib/Interactions/WebDriverTouchActions.php @@ -15,155 +15,179 @@ namespace Facebook\WebDriver\Interactions; -use Facebook\WebDriver\Interactions\Touch\WebDriverTouchScreen; use Facebook\WebDriver\Interactions\Touch\WebDriverDoubleTapAction; +use Facebook\WebDriver\Interactions\Touch\WebDriverDownAction; use Facebook\WebDriver\Interactions\Touch\WebDriverFlickAction; use Facebook\WebDriver\Interactions\Touch\WebDriverFlickFromElementAction; use Facebook\WebDriver\Interactions\Touch\WebDriverLongPressAction; -use Facebook\WebDriver\Interactions\Touch\WebDriverTapAction; -use Facebook\WebDriver\Interactions\Touch\WebDriverScrollFromElementAction; -use Facebook\WebDriver\Interactions\Touch\WebDriverDownAction; use Facebook\WebDriver\Interactions\Touch\WebDriverMoveAction; use Facebook\WebDriver\Interactions\Touch\WebDriverScrollAction; -use Facebook\WebDriver\WebDriverUpAction; -use Facebook\WebDriver\WebDriverElement; +use Facebook\WebDriver\Interactions\Touch\WebDriverScrollFromElementAction; +use Facebook\WebDriver\Interactions\Touch\WebDriverTapAction; +use Facebook\WebDriver\Interactions\Touch\WebDriverTouchScreen; use Facebook\WebDriver\WebDriver; +use Facebook\WebDriver\WebDriverElement; +use Facebook\WebDriver\WebDriverUpAction; /** * WebDriver action builder for touch events */ -class WebDriverTouchActions extends WebDriverActions { - - /** - * @var WebDriverTouchScreen - */ - protected $touchScreen; - - public function __construct(WebDriver $driver) { - parent::__construct($driver); - $this->touchScreen = $driver->getTouch(); - } - - /** - * @param WebDriverElement $element - * @return WebDriverTouchActions - */ - public function tap(WebDriverElement $element) { - $this->action->addAction( - new WebDriverTapAction($this->touchScreen, $element) - ); - return $this; - } - - /** - * @param int $x - * @param int $y - * @return WebDriverTouchActions - */ - public function down($x, $y) { - $this->action->addAction( - new WebDriverDownAction($this->touchScreen, $x, $y) - ); - return $this; - } - - /** - * @param int $x - * @param int $y - * @return WebDriverTouchActions - */ - public function up($x, $y) { - $this->action->addAction( - new WebDriverUpAction($this->touchScreen, $x, $y) - ); - return $this; - } - - /** - * @param int $x - * @param int $y - * @return WebDriverTouchActions - */ - public function move($x, $y) { - $this->action->addAction( - new WebDriverMoveAction($this->touchScreen, $x, $y) - ); - return $this; - } - - /** - * @param int $x - * @param int $y - * @return WebDriverTouchActions - */ - public function scroll($x, $y) { - $this->action->addAction( - new WebDriverScrollAction($this->touchScreen, $x, $y) - ); - return $this; - } - - /** - * @param WebDriverElement $element - * @param int $x - * @param int $y - * @return WebDriverTouchActions - */ - public function scrollFromElement(WebDriverElement $element, $x, $y) { - $this->action->addAction( - new WebDriverScrollFromElementAction($this->touchScreen, $element, $x, $y) - ); - return $this; - } - - /** - * @param WebDriverElement $element - * @return WebDriverTouchActions - */ - public function doubleTap(WebDriverElement $element) { - $this->action->addAction( - new WebDriverDoubleTapAction($this->touchScreen, $element) - ); - return $this; - } - - /** - * @param WebDriverElement $element - * @return WebDriverTouchActions - */ - public function longPress(WebDriverElement $element) { - $this->action->addAction( - new WebDriverLongPressAction($this->touchScreen, $element) - ); - return $this; - } - - /** - * @param int $x - * @param int $y - * @return WebDriverTouchActions - */ - public function flick($x, $y) { - $this->action->addAction( - new WebDriverFlickAction($this->touchScreen, $x, $y) - ); - return $this; - } - - /** - * @param WebDriverElement $element - * @param int $x - * @param int $y - * @param int $speed - * @return WebDriverTouchActions - */ - public function flickFromElement(WebDriverElement $element, $x, $y, $speed) { - $this->action->addAction( - new WebDriverFlickFromElementAction( - $this->touchScreen, $element, $x, $y, $speed - ) - ); - return $this; - } - +class WebDriverTouchActions extends WebDriverActions +{ + /** + * @var WebDriverTouchScreen + */ + protected $touchScreen; + + public function __construct(WebDriver $driver) + { + parent::__construct($driver); + $this->touchScreen = $driver->getTouch(); + } + + /** + * @param WebDriverElement $element + * @return WebDriverTouchActions + */ + public function tap(WebDriverElement $element) + { + $this->action->addAction( + new WebDriverTapAction($this->touchScreen, $element) + ); + + return $this; + } + + /** + * @param int $x + * @param int $y + * @return WebDriverTouchActions + */ + public function down($x, $y) + { + $this->action->addAction( + new WebDriverDownAction($this->touchScreen, $x, $y) + ); + + return $this; + } + + /** + * @param int $x + * @param int $y + * @return WebDriverTouchActions + */ + public function up($x, $y) + { + $this->action->addAction( + new WebDriverUpAction($this->touchScreen, $x, $y) + ); + + return $this; + } + + /** + * @param int $x + * @param int $y + * @return WebDriverTouchActions + */ + public function move($x, $y) + { + $this->action->addAction( + new WebDriverMoveAction($this->touchScreen, $x, $y) + ); + + return $this; + } + + /** + * @param int $x + * @param int $y + * @return WebDriverTouchActions + */ + public function scroll($x, $y) + { + $this->action->addAction( + new WebDriverScrollAction($this->touchScreen, $x, $y) + ); + + return $this; + } + + /** + * @param WebDriverElement $element + * @param int $x + * @param int $y + * @return WebDriverTouchActions + */ + public function scrollFromElement(WebDriverElement $element, $x, $y) + { + $this->action->addAction( + new WebDriverScrollFromElementAction($this->touchScreen, $element, $x, $y) + ); + + return $this; + } + + /** + * @param WebDriverElement $element + * @return WebDriverTouchActions + */ + public function doubleTap(WebDriverElement $element) + { + $this->action->addAction( + new WebDriverDoubleTapAction($this->touchScreen, $element) + ); + + return $this; + } + + /** + * @param WebDriverElement $element + * @return WebDriverTouchActions + */ + public function longPress(WebDriverElement $element) + { + $this->action->addAction( + new WebDriverLongPressAction($this->touchScreen, $element) + ); + + return $this; + } + + /** + * @param int $x + * @param int $y + * @return WebDriverTouchActions + */ + public function flick($x, $y) + { + $this->action->addAction( + new WebDriverFlickAction($this->touchScreen, $x, $y) + ); + + return $this; + } + + /** + * @param WebDriverElement $element + * @param int $x + * @param int $y + * @param int $speed + * @return WebDriverTouchActions + */ + public function flickFromElement(WebDriverElement $element, $x, $y, $speed) + { + $this->action->addAction( + new WebDriverFlickFromElementAction( + $this->touchScreen, + $element, + $x, + $y, + $speed + ) + ); + + return $this; + } } diff --git a/lib/Internal/WebDriverLocatable.php b/lib/Internal/WebDriverLocatable.php index 1523c35c0..e40c36b57 100644 --- a/lib/Internal/WebDriverLocatable.php +++ b/lib/Internal/WebDriverLocatable.php @@ -18,12 +18,12 @@ use Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates; /** - * interface representing basic mouse operations. + * Interface representing basic mouse operations. */ -interface WebDriverLocatable { - - /** - * @return WebDriverCoordinates - */ - public function getCoordinates(); +interface WebDriverLocatable +{ + /** + * @return WebDriverCoordinates + */ + public function getCoordinates(); } diff --git a/lib/JavaScriptExecutor.php b/lib/JavaScriptExecutor.php index 3e0db1302..61aa21b0e 100644 --- a/lib/JavaScriptExecutor.php +++ b/lib/JavaScriptExecutor.php @@ -18,32 +18,31 @@ /** * WebDriver interface implemented by drivers that support JavaScript. */ -interface JavaScriptExecutor { - - /** - * Inject a snippet of JavaScript into the page for execution in the context - * of the currently selected frame. The executed script is assumed to be - * synchronous and the result of evaluating the script will be returned. - * - * @param string $script The script to inject. - * @param array $arguments The arguments of the script. - * @return mixed The return value of the script. - */ - public function executeScript($script, array $arguments = array()); - - /** - * Inject a snippet of JavaScript into the page for asynchronous execution in - * the context of the currently selected frame. - * - * The driver will pass a callback as the last argument to the snippet, and - * block until the callback is invoked. - * - * @see WebDriverExecuteAsyncScriptTestCase - * - * @param string $script The script to inject. - * @param array $arguments The arguments of the script. - * @return mixed The value passed by the script to the callback. - */ - public function executeAsyncScript($script, array $arguments = array()); +interface JavaScriptExecutor +{ + /** + * Inject a snippet of JavaScript into the page for execution in the context + * of the currently selected frame. The executed script is assumed to be + * synchronous and the result of evaluating the script will be returned. + * + * @param string $script The script to inject. + * @param array $arguments The arguments of the script. + * @return mixed The return value of the script. + */ + public function executeScript($script, array $arguments = array()); + /** + * Inject a snippet of JavaScript into the page for asynchronous execution in + * the context of the currently selected frame. + * + * The driver will pass a callback as the last argument to the snippet, and + * block until the callback is invoked. + * + * @see WebDriverExecuteAsyncScriptTestCase + * + * @param string $script The script to inject. + * @param array $arguments The arguments of the script. + * @return mixed The value passed by the script to the callback. + */ + public function executeAsyncScript($script, array $arguments = array()); } diff --git a/lib/Net/URLChecker.php b/lib/Net/URLChecker.php index b41d68c25..3a5d76316 100644 --- a/lib/Net/URLChecker.php +++ b/lib/Net/URLChecker.php @@ -18,64 +18,68 @@ use Exception; use Facebook\WebDriver\Exception\TimeOutException; -class URLChecker { +class URLChecker +{ + const POLL_INTERVAL_MS = 500; + const CONNECT_TIMEOUT_MS = 500; - const POLL_INTERVAL_MS = 500; - const CONNECT_TIMEOUT_MS = 500; + public function waitUntilAvailable($timeout_in_ms, $url) + { + $end = microtime(true) + $timeout_in_ms / 1000; - public function waitUntilAvailable($timeout_in_ms, $url) { - $end = microtime(true) + $timeout_in_ms / 1000; + while ($end > microtime(true)) { + if ($this->getHTTPResponseCode($timeout_in_ms, $url) === 200) { + return $this; + } + usleep(self::POLL_INTERVAL_MS); + } - while ($end > microtime(true)) { - if ($this->getHTTPResponseCode($timeout_in_ms, $url) === 200) { - return $this; - } - usleep(self::POLL_INTERVAL_MS); + throw new TimeOutException(sprintf( + 'Timed out waiting for %s to become available after %d ms.', + $url, + $timeout_in_ms + )); } - throw new TimeOutException(sprintf( - "Timed out waiting for %s to become available after %d ms.", - $url, - $timeout_in_ms - )); - } + public function waitUntilUnavailable($timeout_in_ms, $url) + { + $end = microtime(true) + $timeout_in_ms / 1000; - public function waitUntilUnavailable($timeout_in_ms, $url) { - $end = microtime(true) + $timeout_in_ms / 1000; + while ($end > microtime(true)) { + if ($this->getHTTPResponseCode($timeout_in_ms, $url) !== 200) { + return $this; + } + usleep(self::POLL_INTERVAL_MS); + } - while ($end > microtime(true)) { - if ($this->getHTTPResponseCode($timeout_in_ms, $url) !== 200) { - return $this; - } - usleep(self::POLL_INTERVAL_MS); + throw new TimeOutException(sprintf( + 'Timed out waiting for %s to become unavailable after %d ms.', + $url, + $timeout_in_ms + )); } - throw new TimeOutException(sprintf( - "Timed out waiting for %s to become unavailable after %d ms.", - $url, - $timeout_in_ms - )); - } + private function getHTTPResponseCode($timeout_in_ms, $url) + { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, self::CONNECT_TIMEOUT_MS); + // There is a PHP bug in some versions which didn't define the constant. + curl_setopt( + $ch, + 156, // CURLOPT_CONNECTTIMEOUT_MS + self::CONNECT_TIMEOUT_MS + ); + $code = null; + try { + curl_exec($ch); + $info = curl_getinfo($ch); + $code = $info['http_code']; + } catch (Exception $e) { + } + curl_close($ch); - private function getHTTPResponseCode($timeout_in_ms, $url) { - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, self::CONNECT_TIMEOUT_MS); - // There is a PHP bug in some versions which didn't define the constant. - curl_setopt( - $ch, - 156, // CURLOPT_CONNECTTIMEOUT_MS - self::CONNECT_TIMEOUT_MS - ); - $code = null; - try { - curl_exec($ch); - $info = curl_getinfo($ch); - $code = $info['http_code']; - } catch (Exception $e) { + return $code; } - curl_close($ch); - return $code; - } } diff --git a/lib/Remote/DesiredCapabilities.php b/lib/Remote/DesiredCapabilities.php index ef732ec53..8e30aae14 100644 --- a/lib/Remote/DesiredCapabilities.php +++ b/lib/Remote/DesiredCapabilities.php @@ -23,271 +23,306 @@ use Facebook\WebDriver\WebDriverCapabilities; use Facebook\WebDriver\WebDriverPlatform; -class DesiredCapabilities implements WebDriverCapabilities { - - private $capabilities; - - public function __construct(array $capabilities = array()) { - $this->capabilities = $capabilities; - } - - /** - * @return string The name of the browser. - */ - public function getBrowserName() { - return $this->get(WebDriverCapabilityType::BROWSER_NAME, ''); - } - - /** - * @param string $browser_name - * @return DesiredCapabilities - */ - public function setBrowserName($browser_name) { - $this->set(WebDriverCapabilityType::BROWSER_NAME, $browser_name); - return $this; - } - - /** - * @return string The version of the browser. - */ - public function getVersion() { - return $this->get(WebDriverCapabilityType::VERSION, ''); - } - - /** - * @param string $version - * @return DesiredCapabilities - */ - public function setVersion($version) { - $this->set(WebDriverCapabilityType::VERSION, $version); - return $this; - } - - /** - * @param string $name - * @return mixed The value of a capability. - */ - public function getCapability($name) { - return $this->get($name); - } - - /** - * @param string $name - * @param mixed $value - * @return DesiredCapabilities - */ - public function setCapability($name, $value) { - $this->set($name, $value); - return $this; - } - - /** - * @return string The name of the platform. - */ - public function getPlatform() { - return $this->get(WebDriverCapabilityType::PLATFORM, ''); - } - - /** - * @param string $platform - * @return DesiredCapabilities - */ - public function setPlatform($platform) { - $this->set(WebDriverCapabilityType::PLATFORM, $platform); - return $this; - } - - /** - * @param string $capability_name - * @return bool Whether the value is not null and not false. - */ - public function is($capability_name) { - return (bool) $this->get($capability_name); - } - - /** - * @return bool Whether javascript is enabled. - */ - public function isJavascriptEnabled() { - return $this->get(WebDriverCapabilityType::JAVASCRIPT_ENABLED, false); - } - - /** - * This is a htmlUnit-only option. - * - * @param bool $enabled - * @throws Exception - * @return DesiredCapabilities - * @see https://code.google.com/p/selenium/wiki/DesiredCapabilities#Read-write_capabilities - */ - public function setJavascriptEnabled($enabled) { - $browser = $this->getBrowserName(); - if ($browser && $browser !== WebDriverBrowserType::HTMLUNIT) { - throw new Exception( - 'isJavascriptEnable() is a htmlunit-only option. '. - 'See https://code.google.com/p/selenium/wiki/DesiredCapabilities#Read-write_capabilities.' - ); +class DesiredCapabilities implements WebDriverCapabilities +{ + private $capabilities; + + public function __construct(array $capabilities = array()) + { + $this->capabilities = $capabilities; + } + + /** + * @return string The name of the browser. + */ + public function getBrowserName() + { + return $this->get(WebDriverCapabilityType::BROWSER_NAME, ''); + } + + /** + * @param string $browser_name + * @return DesiredCapabilities + */ + public function setBrowserName($browser_name) + { + $this->set(WebDriverCapabilityType::BROWSER_NAME, $browser_name); + + return $this; + } + + /** + * @return string The version of the browser. + */ + public function getVersion() + { + return $this->get(WebDriverCapabilityType::VERSION, ''); + } + + /** + * @param string $version + * @return DesiredCapabilities + */ + public function setVersion($version) + { + $this->set(WebDriverCapabilityType::VERSION, $version); + + return $this; + } + + /** + * @param string $name + * @return mixed The value of a capability. + */ + public function getCapability($name) + { + return $this->get($name); } - $this->set(WebDriverCapabilityType::JAVASCRIPT_ENABLED, $enabled); - return $this; - } - - /** - * @return array - */ - public function toArray() { - if (isset($this->capabilities[ChromeOptions::CAPABILITY]) && - $this->capabilities[ChromeOptions::CAPABILITY] instanceof ChromeOptions) { - $this->capabilities[ChromeOptions::CAPABILITY] = - $this->capabilities[ChromeOptions::CAPABILITY]->toArray(); + /** + * @param string $name + * @param mixed $value + * @return DesiredCapabilities + */ + public function setCapability($name, $value) + { + $this->set($name, $value); + + return $this; + } + + /** + * @return string The name of the platform. + */ + public function getPlatform() + { + return $this->get(WebDriverCapabilityType::PLATFORM, ''); } - if (isset($this->capabilities[FirefoxDriver::PROFILE]) && - $this->capabilities[FirefoxDriver::PROFILE] instanceof FirefoxProfile) { - $this->capabilities[FirefoxDriver::PROFILE] = - $this->capabilities[FirefoxDriver::PROFILE]->encode(); + /** + * @param string $platform + * @return DesiredCapabilities + */ + public function setPlatform($platform) + { + $this->set(WebDriverCapabilityType::PLATFORM, $platform); + + return $this; } - return $this->capabilities; - } - - /** - * @param string $key - * @param mixed $value - * @return DesiredCapabilities - */ - private function set($key, $value) { - $this->capabilities[$key] = $value; - return $this; - } - - /** - * @param string $key - * @param mixed $default - * @return mixed - */ - private function get($key, $default = null) { - return isset($this->capabilities[$key]) - ? $this->capabilities[$key] - : $default; - } - - /** - * @return DesiredCapabilities - */ - public static function android() { - return new DesiredCapabilities(array( - WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::ANDROID, - WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANDROID, - )); - } - - /** - * @return DesiredCapabilities - */ - public static function chrome() { - return new DesiredCapabilities(array( - WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::CHROME, - WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, - )); - } - - /** - * @return DesiredCapabilities - */ - public static function firefox() { - $caps = new DesiredCapabilities(array( - WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::FIREFOX, - WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, - )); - - // disable the "Reader View" help tooltip, which can hide elements in the window.document - $profile = new FirefoxProfile(); - $profile->setPreference(FirefoxPreferences::READER_PARSE_ON_LOAD_ENABLED, false); - $caps->setCapability(FirefoxDriver::PROFILE, $profile); - - return $caps; - } - - /** - * @return DesiredCapabilities - */ - public static function htmlUnit() { - return new DesiredCapabilities(array( - WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::HTMLUNIT, - WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, - )); - } - - /** - * @return DesiredCapabilities - */ - public static function htmlUnitWithJS() { - $caps = new DesiredCapabilities(array( - WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::HTMLUNIT, - WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, - )); - return $caps->setJavascriptEnabled(true); - } - - /** - * @return DesiredCapabilities - */ - public static function internetExplorer() { - return new DesiredCapabilities(array( - WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::IE, - WebDriverCapabilityType::PLATFORM => WebDriverPlatform::WINDOWS, - )); - } - - /** - * @return DesiredCapabilities - */ - public static function iphone() { - return new DesiredCapabilities(array( - WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::IPHONE, - WebDriverCapabilityType::PLATFORM => WebDriverPlatform::MAC, - )); - } - - /** - * @return DesiredCapabilities - */ - public static function ipad() { - return new DesiredCapabilities(array( - WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::IPAD, - WebDriverCapabilityType::PLATFORM => WebDriverPlatform::MAC, - )); - } - - /** - * @return DesiredCapabilities - */ - public static function opera() { - return new DesiredCapabilities(array( - WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::OPERA, - WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, - )); - } - - /** - * @return DesiredCapabilities - */ - public static function safari() { - return new DesiredCapabilities(array( - WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::SAFARI, - WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, - )); - } - - /** - * @return DesiredCapabilities - */ - public static function phantomjs() { - return new DesiredCapabilities(array( - WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::PHANTOMJS, - WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, - )); - } + /** + * @param string $capability_name + * @return bool Whether the value is not null and not false. + */ + public function is($capability_name) + { + return (bool) $this->get($capability_name); + } + + /** + * @return bool Whether javascript is enabled. + */ + public function isJavascriptEnabled() + { + return $this->get(WebDriverCapabilityType::JAVASCRIPT_ENABLED, false); + } + + /** + * This is a htmlUnit-only option. + * + * @param bool $enabled + * @throws Exception + * @return DesiredCapabilities + * @see https://code.google.com/p/selenium/wiki/DesiredCapabilities#Read-write_capabilities + */ + public function setJavascriptEnabled($enabled) + { + $browser = $this->getBrowserName(); + if ($browser && $browser !== WebDriverBrowserType::HTMLUNIT) { + throw new Exception( + 'isJavascriptEnable() is a htmlunit-only option. ' . + 'See https://code.google.com/p/selenium/wiki/DesiredCapabilities#Read-write_capabilities.' + ); + } + + $this->set(WebDriverCapabilityType::JAVASCRIPT_ENABLED, $enabled); + + return $this; + } + + /** + * @return array + */ + public function toArray() + { + if (isset($this->capabilities[ChromeOptions::CAPABILITY]) && + $this->capabilities[ChromeOptions::CAPABILITY] instanceof ChromeOptions + ) { + $this->capabilities[ChromeOptions::CAPABILITY] = + $this->capabilities[ChromeOptions::CAPABILITY]->toArray(); + } + + if (isset($this->capabilities[FirefoxDriver::PROFILE]) && + $this->capabilities[FirefoxDriver::PROFILE] instanceof FirefoxProfile + ) { + $this->capabilities[FirefoxDriver::PROFILE] = + $this->capabilities[FirefoxDriver::PROFILE]->encode(); + } + + return $this->capabilities; + } + + /** + * @param string $key + * @param mixed $value + * @return DesiredCapabilities + */ + private function set($key, $value) + { + $this->capabilities[$key] = $value; + + return $this; + } + + /** + * @param string $key + * @param mixed $default + * @return mixed + */ + private function get($key, $default = null) + { + return isset($this->capabilities[$key]) + ? $this->capabilities[$key] + : $default; + } + + /** + * @return DesiredCapabilities + */ + public static function android() + { + return new self(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::ANDROID, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANDROID, + )); + } + + /** + * @return DesiredCapabilities + */ + public static function chrome() + { + return new self(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::CHROME, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, + )); + } + + /** + * @return DesiredCapabilities + */ + public static function firefox() + { + $caps = new self(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::FIREFOX, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, + )); + + // disable the "Reader View" help tooltip, which can hide elements in the window.document + $profile = new FirefoxProfile(); + $profile->setPreference(FirefoxPreferences::READER_PARSE_ON_LOAD_ENABLED, false); + $caps->setCapability(FirefoxDriver::PROFILE, $profile); + + return $caps; + } + + /** + * @return DesiredCapabilities + */ + public static function htmlUnit() + { + return new self(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::HTMLUNIT, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, + )); + } + + /** + * @return DesiredCapabilities + */ + public static function htmlUnitWithJS() + { + $caps = new self(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::HTMLUNIT, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, + )); + + return $caps->setJavascriptEnabled(true); + } + + /** + * @return DesiredCapabilities + */ + public static function internetExplorer() + { + return new self(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::IE, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::WINDOWS, + )); + } + + /** + * @return DesiredCapabilities + */ + public static function iphone() + { + return new self(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::IPHONE, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::MAC, + )); + } + + /** + * @return DesiredCapabilities + */ + public static function ipad() + { + return new self(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::IPAD, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::MAC, + )); + } + + /** + * @return DesiredCapabilities + */ + public static function opera() + { + return new self(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::OPERA, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, + )); + } + + /** + * @return DesiredCapabilities + */ + public static function safari() + { + return new self(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::SAFARI, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, + )); + } + + /** + * @return DesiredCapabilities + */ + public static function phantomjs() + { + return new self(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::PHANTOMJS, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, + )); + } } diff --git a/lib/Remote/DriverCommand.php b/lib/Remote/DriverCommand.php index 18e9fb37b..e2ce958b5 100644 --- a/lib/Remote/DriverCommand.php +++ b/lib/Remote/DriverCommand.php @@ -18,154 +18,129 @@ /** * This list of command defined in the WebDriver json wire protocol. */ -class DriverCommand { - const GET_ALL_SESSIONS = "getAllSessions"; - const GET_CAPABILITIES = "getCapabilities"; - const NEW_SESSION = "newSession"; - - const STATUS = "status"; - - const CLOSE = "close"; - const QUIT = "quit"; - - const GET = "get"; - const GO_BACK = "goBack"; - const GO_FORWARD = "goForward"; - const REFRESH = "refresh"; - - const ADD_COOKIE = "addCookie"; - const GET_ALL_COOKIES = "getCookies"; - const DELETE_COOKIE = "deleteCookie"; - const DELETE_ALL_COOKIES = "deleteAllCookies"; - - const FIND_ELEMENT = "findElement"; - const FIND_ELEMENTS = "findElements"; - const FIND_CHILD_ELEMENT = "findChildElement"; - const FIND_CHILD_ELEMENTS = "findChildElements"; - - const CLEAR_ELEMENT = "clearElement"; - const CLICK_ELEMENT = "clickElement"; - const SEND_KEYS_TO_ELEMENT = "sendKeysToElement"; - const SEND_KEYS_TO_ACTIVE_ELEMENT = "sendKeysToActiveElement"; - const SUBMIT_ELEMENT = "submitElement"; - const UPLOAD_FILE = "uploadFile"; - - const GET_CURRENT_WINDOW_HANDLE = "getCurrentWindowHandle"; - const GET_WINDOW_HANDLES = "getWindowHandles"; - - const GET_CURRENT_CONTEXT_HANDLE = "getCurrentContextHandle"; - const GET_CONTEXT_HANDLES = "getContextHandles"; - - // Switching between to window/frame/iframe - const SWITCH_TO_WINDOW = "switchToWindow"; - const SWITCH_TO_CONTEXT = "switchToContext"; - const SWITCH_TO_FRAME = "switchToFrame"; - const SWITCH_TO_PARENT_FRAME = "switchToParentFrame"; - const GET_ACTIVE_ELEMENT = "getActiveElement"; - - // Information of the page - const GET_CURRENT_URL = "getCurrentUrl"; - const GET_PAGE_SOURCE = "getPageSource"; - const GET_TITLE = "getTitle"; - - // Javascript API - const EXECUTE_SCRIPT = "executeScript"; - const EXECUTE_ASYNC_SCRIPT = "executeAsyncScript"; - - // API getting information from an element. - const GET_ELEMENT_TEXT = "getElementText"; - const GET_ELEMENT_TAG_NAME = "getElementTagName"; - const IS_ELEMENT_SELECTED = "isElementSelected"; - const IS_ELEMENT_ENABLED = "isElementEnabled"; - const IS_ELEMENT_DISPLAYED = "isElementDisplayed"; - const GET_ELEMENT_LOCATION = "getElementLocation"; - const GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW = - "getElementLocationOnceScrolledIntoView"; - const GET_ELEMENT_SIZE = "getElementSize"; - const GET_ELEMENT_ATTRIBUTE = "getElementAttribute"; - const GET_ELEMENT_VALUE_OF_CSS_PROPERTY = "getElementValueOfCssProperty"; - const ELEMENT_EQUALS = "elementEquals"; - - const SCREENSHOT = "screenshot"; - - // Alert API - const ACCEPT_ALERT = "acceptAlert"; - const DISMISS_ALERT = "dismissAlert"; - const GET_ALERT_TEXT = "getAlertText"; - const SET_ALERT_VALUE = "setAlertValue"; - - // Timeout API - const SET_TIMEOUT = "setTimeout"; - const IMPLICITLY_WAIT = "implicitlyWait"; - const SET_SCRIPT_TIMEOUT = "setScriptTimeout"; - - const EXECUTE_SQL = "executeSQL"; - const GET_LOCATION = "getLocation"; - const SET_LOCATION = "setLocation"; - const GET_APP_CACHE = "getAppCache"; - const GET_APP_CACHE_STATUS = "getStatus"; - const CLEAR_APP_CACHE = "clearAppCache"; - const IS_BROWSER_ONLINE = "isBrowserOnline"; - const SET_BROWSER_ONLINE = "setBrowserOnline"; - - const GET_LOCAL_STORAGE_ITEM = "getLocalStorageItem"; - const GET_LOCAL_STORAGE_KEYS = "getLocalStorageKeys"; - const SET_LOCAL_STORAGE_ITEM = "setLocalStorageItem"; - const REMOVE_LOCAL_STORAGE_ITEM = "removeLocalStorageItem"; - const CLEAR_LOCAL_STORAGE = "clearLocalStorage"; - const GET_LOCAL_STORAGE_SIZE = "getLocalStorageSize"; - - const GET_SESSION_STORAGE_ITEM = "getSessionStorageItem"; - const GET_SESSION_STORAGE_KEYS = "getSessionStorageKey"; - const SET_SESSION_STORAGE_ITEM = "setSessionStorageItem"; - const REMOVE_SESSION_STORAGE_ITEM = "removeSessionStorageItem"; - const CLEAR_SESSION_STORAGE = "clearSessionStorage"; - const GET_SESSION_STORAGE_SIZE = "getSessionStorageSize"; - - const SET_SCREEN_ORIENTATION = "setScreenOrientation"; - const GET_SCREEN_ORIENTATION = "getScreenOrientation"; - - // These belong to the Advanced user interactions - an element is optional for these commands. - const CLICK = "mouseClick"; - const DOUBLE_CLICK = "mouseDoubleClick"; - const MOUSE_DOWN = "mouseButtonDown"; - const MOUSE_UP = "mouseButtonUp"; - const MOVE_TO = "mouseMoveTo"; - - // Those allow interactions with the Input Methods installed on the system. - const IME_GET_AVAILABLE_ENGINES = "imeGetAvailableEngines"; - const IME_GET_ACTIVE_ENGINE = "imeGetActiveEngine"; - const IME_IS_ACTIVATED = "imeIsActivated"; - const IME_DEACTIVATE = "imeDeactivate"; - const IME_ACTIVATE_ENGINE = "imeActivateEngine"; - - // These belong to the Advanced Touch API - const TOUCH_SINGLE_TAP = "touchSingleTap"; - const TOUCH_DOWN = "touchDown"; - const TOUCH_UP = "touchUp"; - const TOUCH_MOVE = "touchMove"; - const TOUCH_SCROLL = "touchScroll"; - const TOUCH_DOUBLE_TAP = "touchDoubleTap"; - const TOUCH_LONG_PRESS = "touchLongPress"; - const TOUCH_FLICK = "touchFlick"; - - // Window API (beta) - const SET_WINDOW_SIZE = "setWindowSize"; - const SET_WINDOW_POSITION = "setWindowPosition"; - const GET_WINDOW_SIZE = "getWindowSize"; - const GET_WINDOW_POSITION = "getWindowPosition"; - const MAXIMIZE_WINDOW = "maximizeWindow"; - - // Logging API - const GET_AVAILABLE_LOG_TYPES = "getAvailableLogTypes"; - const GET_LOG = "getLog"; - const GET_SESSION_LOGS = "getSessionLogs"; - - // Mobile API - const GET_NETWORK_CONNECTION = "getNetworkConnection"; - const SET_NETWORK_CONNECTION = "setNetworkConnection"; - - private function __construct() - { - } +class DriverCommand +{ + const GET_ALL_SESSIONS = 'getAllSessions'; + const GET_CAPABILITIES = 'getCapabilities'; + const NEW_SESSION = 'newSession'; + const STATUS = 'status'; + const CLOSE = 'close'; + const QUIT = 'quit'; + const GET = 'get'; + const GO_BACK = 'goBack'; + const GO_FORWARD = 'goForward'; + const REFRESH = 'refresh'; + const ADD_COOKIE = 'addCookie'; + const GET_ALL_COOKIES = 'getCookies'; + const DELETE_COOKIE = 'deleteCookie'; + const DELETE_ALL_COOKIES = 'deleteAllCookies'; + const FIND_ELEMENT = 'findElement'; + const FIND_ELEMENTS = 'findElements'; + const FIND_CHILD_ELEMENT = 'findChildElement'; + const FIND_CHILD_ELEMENTS = 'findChildElements'; + const CLEAR_ELEMENT = 'clearElement'; + const CLICK_ELEMENT = 'clickElement'; + const SEND_KEYS_TO_ELEMENT = 'sendKeysToElement'; + const SEND_KEYS_TO_ACTIVE_ELEMENT = 'sendKeysToActiveElement'; + const SUBMIT_ELEMENT = 'submitElement'; + const UPLOAD_FILE = 'uploadFile'; + const GET_CURRENT_WINDOW_HANDLE = 'getCurrentWindowHandle'; + const GET_WINDOW_HANDLES = 'getWindowHandles'; + const GET_CURRENT_CONTEXT_HANDLE = 'getCurrentContextHandle'; + const GET_CONTEXT_HANDLES = 'getContextHandles'; + // Switching between to window/frame/iframe + const SWITCH_TO_WINDOW = 'switchToWindow'; + const SWITCH_TO_CONTEXT = 'switchToContext'; + const SWITCH_TO_FRAME = 'switchToFrame'; + const SWITCH_TO_PARENT_FRAME = 'switchToParentFrame'; + const GET_ACTIVE_ELEMENT = 'getActiveElement'; + // Information of the page + const GET_CURRENT_URL = 'getCurrentUrl'; + const GET_PAGE_SOURCE = 'getPageSource'; + const GET_TITLE = 'getTitle'; + // Javascript API + const EXECUTE_SCRIPT = 'executeScript'; + const EXECUTE_ASYNC_SCRIPT = 'executeAsyncScript'; + // API getting information from an element. + const GET_ELEMENT_TEXT = 'getElementText'; + const GET_ELEMENT_TAG_NAME = 'getElementTagName'; + const IS_ELEMENT_SELECTED = 'isElementSelected'; + const IS_ELEMENT_ENABLED = 'isElementEnabled'; + const IS_ELEMENT_DISPLAYED = 'isElementDisplayed'; + const GET_ELEMENT_LOCATION = 'getElementLocation'; + const GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW = 'getElementLocationOnceScrolledIntoView'; + const GET_ELEMENT_SIZE = 'getElementSize'; + const GET_ELEMENT_ATTRIBUTE = 'getElementAttribute'; + const GET_ELEMENT_VALUE_OF_CSS_PROPERTY = 'getElementValueOfCssProperty'; + const ELEMENT_EQUALS = 'elementEquals'; + const SCREENSHOT = 'screenshot'; + // Alert API + const ACCEPT_ALERT = 'acceptAlert'; + const DISMISS_ALERT = 'dismissAlert'; + const GET_ALERT_TEXT = 'getAlertText'; + const SET_ALERT_VALUE = 'setAlertValue'; + // Timeout API + const SET_TIMEOUT = 'setTimeout'; + const IMPLICITLY_WAIT = 'implicitlyWait'; + const SET_SCRIPT_TIMEOUT = 'setScriptTimeout'; + const EXECUTE_SQL = 'executeSQL'; + const GET_LOCATION = 'getLocation'; + const SET_LOCATION = 'setLocation'; + const GET_APP_CACHE = 'getAppCache'; + const GET_APP_CACHE_STATUS = 'getStatus'; + const CLEAR_APP_CACHE = 'clearAppCache'; + const IS_BROWSER_ONLINE = 'isBrowserOnline'; + const SET_BROWSER_ONLINE = 'setBrowserOnline'; + const GET_LOCAL_STORAGE_ITEM = 'getLocalStorageItem'; + const GET_LOCAL_STORAGE_KEYS = 'getLocalStorageKeys'; + const SET_LOCAL_STORAGE_ITEM = 'setLocalStorageItem'; + const REMOVE_LOCAL_STORAGE_ITEM = 'removeLocalStorageItem'; + const CLEAR_LOCAL_STORAGE = 'clearLocalStorage'; + const GET_LOCAL_STORAGE_SIZE = 'getLocalStorageSize'; + const GET_SESSION_STORAGE_ITEM = 'getSessionStorageItem'; + const GET_SESSION_STORAGE_KEYS = 'getSessionStorageKey'; + const SET_SESSION_STORAGE_ITEM = 'setSessionStorageItem'; + const REMOVE_SESSION_STORAGE_ITEM = 'removeSessionStorageItem'; + const CLEAR_SESSION_STORAGE = 'clearSessionStorage'; + const GET_SESSION_STORAGE_SIZE = 'getSessionStorageSize'; + const SET_SCREEN_ORIENTATION = 'setScreenOrientation'; + const GET_SCREEN_ORIENTATION = 'getScreenOrientation'; + // These belong to the Advanced user interactions - an element is optional for these commands. + const CLICK = 'mouseClick'; + const DOUBLE_CLICK = 'mouseDoubleClick'; + const MOUSE_DOWN = 'mouseButtonDown'; + const MOUSE_UP = 'mouseButtonUp'; + const MOVE_TO = 'mouseMoveTo'; + // Those allow interactions with the Input Methods installed on the system. + const IME_GET_AVAILABLE_ENGINES = 'imeGetAvailableEngines'; + const IME_GET_ACTIVE_ENGINE = 'imeGetActiveEngine'; + const IME_IS_ACTIVATED = 'imeIsActivated'; + const IME_DEACTIVATE = 'imeDeactivate'; + const IME_ACTIVATE_ENGINE = 'imeActivateEngine'; + // These belong to the Advanced Touch API + const TOUCH_SINGLE_TAP = 'touchSingleTap'; + const TOUCH_DOWN = 'touchDown'; + const TOUCH_UP = 'touchUp'; + const TOUCH_MOVE = 'touchMove'; + const TOUCH_SCROLL = 'touchScroll'; + const TOUCH_DOUBLE_TAP = 'touchDoubleTap'; + const TOUCH_LONG_PRESS = 'touchLongPress'; + const TOUCH_FLICK = 'touchFlick'; + // Window API (beta) + const SET_WINDOW_SIZE = 'setWindowSize'; + const SET_WINDOW_POSITION = 'setWindowPosition'; + const GET_WINDOW_SIZE = 'getWindowSize'; + const GET_WINDOW_POSITION = 'getWindowPosition'; + const MAXIMIZE_WINDOW = 'maximizeWindow'; + // Logging API + const GET_AVAILABLE_LOG_TYPES = 'getAvailableLogTypes'; + const GET_LOG = 'getLog'; + const GET_SESSION_LOGS = 'getSessionLogs'; + // Mobile API + const GET_NETWORK_CONNECTION = 'getNetworkConnection'; + const SET_NETWORK_CONNECTION = 'setNetworkConnection'; + + private function __construct() + { + } } diff --git a/lib/Remote/ExecuteMethod.php b/lib/Remote/ExecuteMethod.php index ff13c58fe..38ad319e7 100644 --- a/lib/Remote/ExecuteMethod.php +++ b/lib/Remote/ExecuteMethod.php @@ -15,12 +15,12 @@ namespace Facebook\WebDriver\Remote; -interface ExecuteMethod { - - /** - * @param string $command_name - * @param array $parameters - * @return WebDriverResponse - */ - public function execute($command_name, array $parameters = array()); +interface ExecuteMethod +{ + /** + * @param string $command_name + * @param array $parameters + * @return WebDriverResponse + */ + public function execute($command_name, array $parameters = array()); } diff --git a/lib/Remote/FileDetector.php b/lib/Remote/FileDetector.php index a6e52f48d..483df049c 100644 --- a/lib/Remote/FileDetector.php +++ b/lib/Remote/FileDetector.php @@ -15,15 +15,15 @@ namespace Facebook\WebDriver\Remote; -interface FileDetector { - - /** - * Try to detect whether the given $file is a file or not. Return the path - * of the file. Otherwise, return null. - * - * @param string $file - * - * @return null|string The path of the file. - */ - public function getLocalFile($file); +interface FileDetector +{ + /** + * Try to detect whether the given $file is a file or not. Return the path + * of the file. Otherwise, return null. + * + * @param string $file + * + * @return null|string The path of the file. + */ + public function getLocalFile($file); } diff --git a/lib/Remote/HttpCommandExecutor.php b/lib/Remote/HttpCommandExecutor.php index ebd47357e..37670610d 100644 --- a/lib/Remote/HttpCommandExecutor.php +++ b/lib/Remote/HttpCommandExecutor.php @@ -15,287 +15,355 @@ namespace Facebook\WebDriver\Remote; +use BadMethodCallException; use Facebook\WebDriver\Exception\WebDriverException; use Facebook\WebDriver\WebDriverCommandExecutor; use InvalidArgumentException; -use BadMethodCallException; /** * Command executor talking to the standalone server via HTTP. */ -class HttpCommandExecutor implements WebDriverCommandExecutor { +class HttpCommandExecutor implements WebDriverCommandExecutor +{ + /** + * @see + * http://code.google.com/p/selenium/wiki/JsonWireProtocol#Command_Reference + */ + protected static $commands = array( + DriverCommand::ACCEPT_ALERT => array('method' => 'POST', 'url' => '/session/:sessionId/accept_alert'), + DriverCommand::ADD_COOKIE => array('method' => 'POST', 'url' => '/session/:sessionId/cookie'), + DriverCommand::CLEAR_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/clear'), + DriverCommand::CLICK_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/click'), + DriverCommand::CLOSE => array('method' => 'DELETE', 'url' => '/session/:sessionId/window'), + DriverCommand::DELETE_ALL_COOKIES => array('method' => 'DELETE', 'url' => '/session/:sessionId/cookie'), + DriverCommand::DELETE_COOKIE => array('method' => 'DELETE', 'url' => '/session/:sessionId/cookie/:name'), + DriverCommand::DISMISS_ALERT => array('method' => 'POST', 'url' => '/session/:sessionId/dismiss_alert'), + DriverCommand::ELEMENT_EQUALS => array( + 'method' => 'GET', + 'url' => '/session/:sessionId/element/:id/equals/:other', + ), + DriverCommand::FIND_CHILD_ELEMENT => array( + 'method' => 'POST', + 'url' => '/session/:sessionId/element/:id/element', + ), + DriverCommand::FIND_CHILD_ELEMENTS => array( + 'method' => 'POST', + 'url' => '/session/:sessionId/element/:id/elements', + ), + DriverCommand::EXECUTE_SCRIPT => array('method' => 'POST', 'url' => '/session/:sessionId/execute'), + DriverCommand::EXECUTE_ASYNC_SCRIPT => array('method' => 'POST', 'url' => '/session/:sessionId/execute_async'), + DriverCommand::FIND_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element'), + DriverCommand::FIND_ELEMENTS => array('method' => 'POST', 'url' => '/session/:sessionId/elements'), + DriverCommand::SWITCH_TO_FRAME => array('method' => 'POST', 'url' => '/session/:sessionId/frame'), + DriverCommand::SWITCH_TO_WINDOW => array('method' => 'POST', 'url' => '/session/:sessionId/window'), + DriverCommand::GET => array('method' => 'POST', 'url' => '/session/:sessionId/url'), + DriverCommand::GET_ACTIVE_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/active'), + DriverCommand::GET_ALERT_TEXT => array('method' => 'GET', 'url' => '/session/:sessionId/alert_text'), + DriverCommand::GET_ALL_COOKIES => array('method' => 'GET', 'url' => '/session/:sessionId/cookie'), + DriverCommand::GET_ALL_SESSIONS => array('method' => 'GET', 'url' => '/sessions'), + DriverCommand::GET_AVAILABLE_LOG_TYPES => array('method' => 'GET', 'url' => '/session/:sessionId/log/types'), + DriverCommand::GET_CURRENT_URL => array('method' => 'GET', 'url' => '/session/:sessionId/url'), + DriverCommand::GET_CURRENT_WINDOW_HANDLE => array( + 'method' => 'GET', + 'url' => '/session/:sessionId/window_handle', + ), + DriverCommand::GET_ELEMENT_ATTRIBUTE => array( + 'method' => 'GET', + 'url' => '/session/:sessionId/element/:id/attribute/:name', + ), + DriverCommand::GET_ELEMENT_VALUE_OF_CSS_PROPERTY => array( + 'method' => 'GET', + 'url' => '/session/:sessionId/element/:id/css/:propertyName', + ), + DriverCommand::GET_ELEMENT_LOCATION => array( + 'method' => 'GET', + 'url' => '/session/:sessionId/element/:id/location', + ), + DriverCommand::GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW => array( + 'method' => 'GET', + 'url' => '/session/:sessionId/element/:id/location_in_view', + ), + DriverCommand::GET_ELEMENT_SIZE => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/size'), + DriverCommand::GET_ELEMENT_TAG_NAME => array( + 'method' => 'GET', + 'url' => '/session/:sessionId/element/:id/name', + ), + DriverCommand::GET_ELEMENT_TEXT => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/text'), + DriverCommand::GET_LOG => array('method' => 'POST', 'url' => '/session/:sessionId/log'), + DriverCommand::GET_PAGE_SOURCE => array('method' => 'GET', 'url' => '/session/:sessionId/source'), + DriverCommand::GET_SCREEN_ORIENTATION => array('method' => 'GET', 'url' => '/session/:sessionId/orientation'), + DriverCommand::GET_CAPABILITIES => array('method' => 'GET', 'url' => '/session/:sessionId'), + DriverCommand::GET_TITLE => array('method' => 'GET', 'url' => '/session/:sessionId/title'), + DriverCommand::GET_WINDOW_HANDLES => array('method' => 'GET', 'url' => '/session/:sessionId/window_handles'), + DriverCommand::GET_WINDOW_POSITION => array( + 'method' => 'GET', + 'url' => '/session/:sessionId/window/:windowHandle/position', + ), + DriverCommand::GET_WINDOW_SIZE => array( + 'method' => 'GET', + 'url' => '/session/:sessionId/window/:windowHandle/size', + ), + DriverCommand::GO_BACK => array('method' => 'POST', 'url' => '/session/:sessionId/back'), + DriverCommand::GO_FORWARD => array('method' => 'POST', 'url' => '/session/:sessionId/forward'), + DriverCommand::IS_ELEMENT_DISPLAYED => array( + 'method' => 'GET', + 'url' => '/session/:sessionId/element/:id/displayed', + ), + DriverCommand::IS_ELEMENT_ENABLED => array( + 'method' => 'GET', + 'url' => '/session/:sessionId/element/:id/enabled', + ), + DriverCommand::IS_ELEMENT_SELECTED => array( + 'method' => 'GET', + 'url' => '/session/:sessionId/element/:id/selected', + ), + DriverCommand::MAXIMIZE_WINDOW => array( + 'method' => 'POST', + 'url' => '/session/:sessionId/window/:windowHandle/maximize', + ), + DriverCommand::MOUSE_DOWN => array('method' => 'POST', 'url' => '/session/:sessionId/buttondown'), + DriverCommand::MOUSE_UP => array('method' => 'POST', 'url' => '/session/:sessionId/buttonup'), + DriverCommand::CLICK => array('method' => 'POST', 'url' => '/session/:sessionId/click'), + DriverCommand::DOUBLE_CLICK => array('method' => 'POST', 'url' => '/session/:sessionId/doubleclick'), + DriverCommand::MOVE_TO => array('method' => 'POST', 'url' => '/session/:sessionId/moveto'), + DriverCommand::NEW_SESSION => array('method' => 'POST', 'url' => '/session'), + DriverCommand::QUIT => array('method' => 'DELETE', 'url' => '/session/:sessionId'), + DriverCommand::REFRESH => array('method' => 'POST', 'url' => '/session/:sessionId/refresh'), + DriverCommand::UPLOAD_FILE => array('method' => 'POST', 'url' => '/session/:sessionId/file'), // undocumented + DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/keys'), + DriverCommand::SET_ALERT_VALUE => array('method' => 'POST', 'url' => '/session/:sessionId/alert_text'), + DriverCommand::SEND_KEYS_TO_ELEMENT => array( + 'method' => 'POST', + 'url' => '/session/:sessionId/element/:id/value', + ), + DriverCommand::IMPLICITLY_WAIT => array( + 'method' => 'POST', + 'url' => '/session/:sessionId/timeouts/implicit_wait', + ), + DriverCommand::SET_SCREEN_ORIENTATION => array('method' => 'POST', 'url' => '/session/:sessionId/orientation'), + DriverCommand::SET_TIMEOUT => array('method' => 'POST', 'url' => '/session/:sessionId/timeouts'), + DriverCommand::SET_SCRIPT_TIMEOUT => array( + 'method' => 'POST', + 'url' => '/session/:sessionId/timeouts/async_script', + ), + DriverCommand::SET_WINDOW_POSITION => array( + 'method' => 'POST', + 'url' => '/session/:sessionId/window/:windowHandle/position', + ), + DriverCommand::SET_WINDOW_SIZE => array( + 'method' => 'POST', + 'url' => '/session/:sessionId/window/:windowHandle/size', + ), + DriverCommand::SUBMIT_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/submit'), + DriverCommand::SCREENSHOT => array('method' => 'GET', 'url' => '/session/:sessionId/screenshot'), + DriverCommand::TOUCH_SINGLE_TAP => array('method' => 'POST', 'url' => '/session/:sessionId/touch/click'), + DriverCommand::TOUCH_DOWN => array('method' => 'POST', 'url' => '/session/:sessionId/touch/down'), + DriverCommand::TOUCH_DOUBLE_TAP => array('method' => 'POST', 'url' => '/session/:sessionId/touch/doubleclick'), + DriverCommand::TOUCH_FLICK => array('method' => 'POST', 'url' => '/session/:sessionId/touch/flick'), + DriverCommand::TOUCH_LONG_PRESS => array('method' => 'POST', 'url' => '/session/:sessionId/touch/longclick'), + DriverCommand::TOUCH_MOVE => array('method' => 'POST', 'url' => '/session/:sessionId/touch/move'), + DriverCommand::TOUCH_SCROLL => array('method' => 'POST', 'url' => '/session/:sessionId/touch/scroll'), + DriverCommand::TOUCH_UP => array('method' => 'POST', 'url' => '/session/:sessionId/touch/up'), + ); + /** + * @var string + */ + protected $url; + /** + * @var resource + */ + protected $curl; - /** - * @see - * http://code.google.com/p/selenium/wiki/JsonWireProtocol#Command_Reference - */ - protected static $commands = array( - DriverCommand::ACCEPT_ALERT => array('method' => 'POST', 'url' => '/session/:sessionId/accept_alert'), - DriverCommand::ADD_COOKIE => array('method' => 'POST', 'url' => '/session/:sessionId/cookie'), - DriverCommand::CLEAR_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/clear'), - DriverCommand::CLICK_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/click'), - DriverCommand::CLOSE => array('method' => 'DELETE', 'url' => '/session/:sessionId/window'), - DriverCommand::DELETE_ALL_COOKIES => array('method' => 'DELETE', 'url' => '/session/:sessionId/cookie'), - DriverCommand::DELETE_COOKIE => array('method' => 'DELETE', 'url' => '/session/:sessionId/cookie/:name'), - DriverCommand::DISMISS_ALERT => array('method' => 'POST', 'url' => '/session/:sessionId/dismiss_alert'), - DriverCommand::ELEMENT_EQUALS => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/equals/:other'), - DriverCommand::FIND_CHILD_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/element'), - DriverCommand::FIND_CHILD_ELEMENTS => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/elements'), - DriverCommand::EXECUTE_SCRIPT => array('method' => 'POST', 'url' => '/session/:sessionId/execute'), - DriverCommand::EXECUTE_ASYNC_SCRIPT => array('method' => 'POST', 'url' => '/session/:sessionId/execute_async'), - DriverCommand::FIND_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element'), - DriverCommand::FIND_ELEMENTS => array('method' => 'POST', 'url' => '/session/:sessionId/elements'), - DriverCommand::SWITCH_TO_FRAME => array('method' => 'POST', 'url' => '/session/:sessionId/frame'), - DriverCommand::SWITCH_TO_WINDOW => array('method' => 'POST', 'url' => '/session/:sessionId/window'), - DriverCommand::GET => array('method' => 'POST', 'url' => '/session/:sessionId/url'), - DriverCommand::GET_ACTIVE_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/active'), - DriverCommand::GET_ALERT_TEXT => array('method' => 'GET', 'url' => '/session/:sessionId/alert_text'), - DriverCommand::GET_ALL_COOKIES => array('method' => 'GET', 'url' => '/session/:sessionId/cookie'), - DriverCommand::GET_ALL_SESSIONS => array('method' => 'GET', 'url' => '/sessions'), - DriverCommand::GET_AVAILABLE_LOG_TYPES => array('method' => 'GET', 'url' => '/session/:sessionId/log/types'), - DriverCommand::GET_CURRENT_URL => array('method' => 'GET', 'url' => '/session/:sessionId/url'), - DriverCommand::GET_CURRENT_WINDOW_HANDLE => array('method' => 'GET', 'url' => '/session/:sessionId/window_handle'), - DriverCommand::GET_ELEMENT_ATTRIBUTE => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/attribute/:name'), - DriverCommand::GET_ELEMENT_VALUE_OF_CSS_PROPERTY => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/css/:propertyName'), - DriverCommand::GET_ELEMENT_LOCATION => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/location'), - DriverCommand::GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/location_in_view'), - DriverCommand::GET_ELEMENT_SIZE => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/size'), - DriverCommand::GET_ELEMENT_TAG_NAME => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/name'), - DriverCommand::GET_ELEMENT_TEXT => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/text'), - DriverCommand::GET_LOG => array('method' => 'POST', 'url' => '/session/:sessionId/log'), - DriverCommand::GET_PAGE_SOURCE => array('method' => 'GET', 'url' => '/session/:sessionId/source'), - DriverCommand::GET_SCREEN_ORIENTATION => array('method' => 'GET', 'url' => '/session/:sessionId/orientation'), - DriverCommand::GET_CAPABILITIES => array('method' => 'GET', 'url' => '/session/:sessionId'), - DriverCommand::GET_TITLE => array('method' => 'GET', 'url' => '/session/:sessionId/title'), - DriverCommand::GET_WINDOW_HANDLES => array('method' => 'GET', 'url' => '/session/:sessionId/window_handles'), - DriverCommand::GET_WINDOW_POSITION => array('method' => 'GET', 'url' => '/session/:sessionId/window/:windowHandle/position'), - DriverCommand::GET_WINDOW_SIZE => array('method' => 'GET', 'url' => '/session/:sessionId/window/:windowHandle/size'), - DriverCommand::GO_BACK => array('method' => 'POST', 'url' => '/session/:sessionId/back'), - DriverCommand::GO_FORWARD => array('method' => 'POST', 'url' => '/session/:sessionId/forward'), - DriverCommand::IS_ELEMENT_DISPLAYED=> array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/displayed'), - DriverCommand::IS_ELEMENT_ENABLED=> array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/enabled'), - DriverCommand::IS_ELEMENT_SELECTED=> array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/selected'), - DriverCommand::MAXIMIZE_WINDOW => array('method' => 'POST', 'url' => '/session/:sessionId/window/:windowHandle/maximize'), - DriverCommand::MOUSE_DOWN => array('method' => 'POST', 'url' => '/session/:sessionId/buttondown'), - DriverCommand::MOUSE_UP => array('method' => 'POST', 'url' => '/session/:sessionId/buttonup'), - DriverCommand::CLICK => array('method' => 'POST', 'url' => '/session/:sessionId/click'), - DriverCommand::DOUBLE_CLICK => array('method' => 'POST', 'url' => '/session/:sessionId/doubleclick'), - DriverCommand::MOVE_TO => array('method' => 'POST', 'url' => '/session/:sessionId/moveto'), - DriverCommand::NEW_SESSION => array('method' => 'POST', 'url' => '/session'), - DriverCommand::QUIT => array('method' => 'DELETE', 'url' => '/session/:sessionId'), - DriverCommand::REFRESH => array('method' => 'POST', 'url' => '/session/:sessionId/refresh'), - DriverCommand::UPLOAD_FILE => array('method' => 'POST', 'url' => '/session/:sessionId/file'), // undocumented - DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/keys'), - DriverCommand::SET_ALERT_VALUE => array('method' => 'POST', 'url' => '/session/:sessionId/alert_text'), - DriverCommand::SEND_KEYS_TO_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/value'), - DriverCommand::IMPLICITLY_WAIT => array('method' => 'POST', 'url' => '/session/:sessionId/timeouts/implicit_wait'), - DriverCommand::SET_SCREEN_ORIENTATION => array('method' => 'POST', 'url' => '/session/:sessionId/orientation'), - DriverCommand::SET_TIMEOUT => array('method' => 'POST', 'url' => '/session/:sessionId/timeouts'), - DriverCommand::SET_SCRIPT_TIMEOUT => array('method' => 'POST', 'url' => '/session/:sessionId/timeouts/async_script'), - DriverCommand::SET_WINDOW_POSITION => array('method' => 'POST', 'url' => '/session/:sessionId/window/:windowHandle/position'), - DriverCommand::SET_WINDOW_SIZE => array('method' => 'POST', 'url' => '/session/:sessionId/window/:windowHandle/size'), - DriverCommand::SUBMIT_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/submit'), - DriverCommand::SCREENSHOT => array('method' => 'GET', 'url' => '/session/:sessionId/screenshot'), - DriverCommand::TOUCH_SINGLE_TAP => array('method' => 'POST', 'url' => '/session/:sessionId/touch/click'), - DriverCommand::TOUCH_DOWN => array('method' => 'POST', 'url' => '/session/:sessionId/touch/down'), - DriverCommand::TOUCH_DOUBLE_TAP => array('method' => 'POST', 'url' => '/session/:sessionId/touch/doubleclick'), - DriverCommand::TOUCH_FLICK => array('method' => 'POST', 'url' => '/session/:sessionId/touch/flick'), - DriverCommand::TOUCH_LONG_PRESS => array('method' => 'POST', 'url' => '/session/:sessionId/touch/longclick'), - DriverCommand::TOUCH_MOVE => array('method' => 'POST', 'url' => '/session/:sessionId/touch/move'), - DriverCommand::TOUCH_SCROLL => array('method' => 'POST', 'url' => '/session/:sessionId/touch/scroll'), - DriverCommand::TOUCH_UP => array('method' => 'POST', 'url' => '/session/:sessionId/touch/up'), - ); + /** + * @param string $url + * @param string|null $http_proxy + * @param int|null $http_proxy_port + */ + public function __construct($url, $http_proxy = null, $http_proxy_port = null) + { + $this->url = $url; + $this->curl = curl_init(); - /** - * @var string - */ - protected $url; - /** - * @var resource - */ - protected $curl; + if (!empty($http_proxy)) { + curl_setopt($this->curl, CURLOPT_PROXY, $http_proxy); + if (!empty($http_proxy_port)) { + curl_setopt($this->curl, CURLOPT_PROXYPORT, $http_proxy_port); + } + } - /** - * @param string $url - * @param string|null $http_proxy - * @param int|null $http_proxy_port - */ - public function __construct($url, $http_proxy = null, $http_proxy_port = null) { - $this->url = $url; - $this->curl = curl_init(); + // Get credentials from $url (if any) + $matches = null; + if (preg_match("/^(https?:\/\/)(.*):(.*)@(.*?)/U", $url, $matches)) { + $this->url = $matches[1] . $matches[4]; + $auth_creds = $matches[2] . ':' . $matches[3]; + curl_setopt($this->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_setopt($this->curl, CURLOPT_USERPWD, $auth_creds); + } - if (!empty($http_proxy)) { - curl_setopt($this->curl, CURLOPT_PROXY, $http_proxy); - if (!empty($http_proxy_port)) { - curl_setopt($this->curl, CURLOPT_PROXYPORT, $http_proxy_port); - } + curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); + curl_setopt( + $this->curl, + CURLOPT_HTTPHEADER, + array( + 'Content-Type: application/json;charset=UTF-8', + 'Accept: application/json', + ) + ); + $this->setRequestTimeout(30000); + $this->setConnectionTimeout(30000); } - // Get credentials from $url (if any) - $matches = null; - if (preg_match("/^(https?:\/\/)(.*):(.*)@(.*?)/U", $url, $matches)) { - $this->url = $matches[1].$matches[4]; - $auth_creds = $matches[2].":".$matches[3]; - curl_setopt($this->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); - curl_setopt($this->curl, CURLOPT_USERPWD, $auth_creds); + /** + * Set timeout for the connect phase + * + * @param int $timeout_in_ms Timeout in milliseconds + * @return HttpCommandExecutor + */ + public function setConnectionTimeout($timeout_in_ms) + { + // There is a PHP bug in some versions which didn't define the constant. + curl_setopt( + $this->curl, + /* CURLOPT_CONNECTTIMEOUT_MS */ + 156, + $timeout_in_ms + ); + + return $this; } - curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); - curl_setopt( - $this->curl, - CURLOPT_HTTPHEADER, - array( - 'Content-Type: application/json;charset=UTF-8', - 'Accept: application/json', - ) - ); - $this->setRequestTimeout(30000); - $this->setConnectionTimeout(30000); - } + /** + * Set the maximum time of a request + * + * @param int $timeout_in_ms Timeout in milliseconds + * @return HttpCommandExecutor + */ + public function setRequestTimeout($timeout_in_ms) + { + // There is a PHP bug in some versions (at least for PHP 5.3.3) which + // didn't define the constant. + curl_setopt( + $this->curl, + /* CURLOPT_TIMEOUT_MS */ + 155, + $timeout_in_ms + ); - /** - * Set timeout for the connect phase - * - * @param int $timeout_in_ms Timeout in milliseconds - * @return HttpCommandExecutor - */ - public function setConnectionTimeout($timeout_in_ms) { - // There is a PHP bug in some versions which didn't define the constant. - curl_setopt( - $this->curl, - /* CURLOPT_CONNECTTIMEOUT_MS */ 156, - $timeout_in_ms - ); - return $this; - } + return $this; + } - /** - * Set the maximum time of a request - * - * @param int $timeout_in_ms Timeout in milliseconds - * @return HttpCommandExecutor - */ - public function setRequestTimeout($timeout_in_ms) { - // There is a PHP bug in some versions (at least for PHP 5.3.3) which - // didn't define the constant. - curl_setopt( - $this->curl, - /* CURLOPT_TIMEOUT_MS */ 155, - $timeout_in_ms - ); - return $this; - } + /** + * @param WebDriverCommand $command + * + * @throws WebDriverException + * @return mixed + */ + public function execute(WebDriverCommand $command) + { + if (!isset(self::$commands[$command->getName()])) { + throw new InvalidArgumentException($command->getName() . ' is not a valid command.'); + } - /** - * @param WebDriverCommand $command - * - * @return mixed - * - * @throws WebDriverException - */ - public function execute(WebDriverCommand $command) { - if (!isset(self::$commands[$command->getName()])) { - throw new InvalidArgumentException( - $command->getName()." is not a valid command." - ); - } - $raw = self::$commands[$command->getName()]; - $http_method = $raw['method']; - $url = $raw['url']; - $url = str_replace(':sessionId', $command->getSessionID(), $url); - $params = $command->getParameters(); - foreach ($params as $name => $value) { - if ($name[0] === ':') { - $url = str_replace($name, $value, $url); - if ($http_method != 'POST') { - unset($params[$name]); + $raw = self::$commands[$command->getName()]; + $http_method = $raw['method']; + $url = $raw['url']; + $url = str_replace(':sessionId', $command->getSessionID(), $url); + $params = $command->getParameters(); + foreach ($params as $name => $value) { + if ($name[0] === ':') { + $url = str_replace($name, $value, $url); + if ($http_method != 'POST') { + unset($params[$name]); + } + } } - } - } - if ($params && is_array($params) && $http_method !== 'POST') { - throw new BadMethodCallException(sprintf( - 'The http method called for %s is %s but it has to be POST' . - ' if you want to pass the JSON params %s', - $url, - $http_method, - json_encode($params) - )); - } + if ($params && is_array($params) && $http_method !== 'POST') { + throw new BadMethodCallException(sprintf( + 'The http method called for %s is %s but it has to be POST' . + ' if you want to pass the JSON params %s', + $url, + $http_method, + json_encode($params) + )); + } - curl_setopt($this->curl, CURLOPT_URL, $this->url . $url); + curl_setopt($this->curl, CURLOPT_URL, $this->url . $url); - // https://github.com/facebook/php-webdriver/issues/173 - if ($command->getName() === DriverCommand::NEW_SESSION) { - curl_setopt($this->curl, CURLOPT_POST, 1); - } else { - curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $http_method); - } + // https://github.com/facebook/php-webdriver/issues/173 + if ($command->getName() === DriverCommand::NEW_SESSION) { + curl_setopt($this->curl, CURLOPT_POST, 1); + } else { + curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $http_method); + } - $encoded_params = null; + $encoded_params = null; - if ($http_method === 'POST' && $params && is_array($params)) { - $encoded_params = json_encode($params); - } + if ($http_method === 'POST' && $params && is_array($params)) { + $encoded_params = json_encode($params); + } - curl_setopt($this->curl, CURLOPT_POSTFIELDS, $encoded_params); + curl_setopt($this->curl, CURLOPT_POSTFIELDS, $encoded_params); - $raw_results = trim(curl_exec($this->curl)); + $raw_results = trim(curl_exec($this->curl)); - if ($error = curl_error($this->curl)) { - $msg = sprintf( - 'Curl error thrown for http %s to %s', - $http_method, - $url); - if ($params && is_array($params)) { - $msg .= sprintf(' with params: %s', json_encode($params)); - } - WebDriverException::throwException(-1, $msg . "\n\n" . $error, array()); - } + if ($error = curl_error($this->curl)) { + $msg = sprintf( + 'Curl error thrown for http %s to %s', + $http_method, + $url + ); + if ($params && is_array($params)) { + $msg .= sprintf(' with params: %s', json_encode($params)); + } + WebDriverException::throwException(-1, $msg . "\n\n" . $error, array()); + } - $results = json_decode($raw_results, true); + $results = json_decode($raw_results, true); - if ($results === null && json_last_error() !== JSON_ERROR_NONE) { - throw new WebDriverException( - sprintf( - "JSON decoding of remote response failed.\n". - "Error code: %d\n". - "The response: '%s'\n", - json_last_error(), - $raw_results - ) - ); - } + if ($results === null && json_last_error() !== JSON_ERROR_NONE) { + throw new WebDriverException( + sprintf( + "JSON decoding of remote response failed.\n" . + "Error code: %d\n" . + "The response: '%s'\n", + json_last_error(), + $raw_results + ) + ); + } - $value = null; - if (is_array($results) && array_key_exists('value', $results)) { - $value = $results['value']; - } + $value = null; + if (is_array($results) && array_key_exists('value', $results)) { + $value = $results['value']; + } - $message = null; - if (is_array($value) && array_key_exists('message', $value)) { - $message = $value['message']; - } + $message = null; + if (is_array($value) && array_key_exists('message', $value)) { + $message = $value['message']; + } - $sessionId = null; - if (is_array($results) && array_key_exists('sessionId', $results)) { - $sessionId = $results['sessionId']; - } + $sessionId = null; + if (is_array($results) && array_key_exists('sessionId', $results)) { + $sessionId = $results['sessionId']; + } + + $status = isset($results['status']) ? $results['status'] : 0; + WebDriverException::throwException($status, $message, $results); - $status = isset($results['status']) ? $results['status'] : 0; - WebDriverException::throwException($status, $message, $results); + $response = new WebDriverResponse($sessionId); - $response = new WebDriverResponse($sessionId); - return $response - ->setStatus($status) - ->setValue($value); - } + return $response + ->setStatus($status) + ->setValue($value); + } - /** - * @return string - */ - public function getAddressOfRemoteServer() { - return $this->url; - } + /** + * @return string + */ + public function getAddressOfRemoteServer() + { + return $this->url; + } } diff --git a/lib/Remote/LocalFileDetector.php b/lib/Remote/LocalFileDetector.php index 1308ed6a1..07f996cf0 100644 --- a/lib/Remote/LocalFileDetector.php +++ b/lib/Remote/LocalFileDetector.php @@ -15,16 +15,19 @@ namespace Facebook\WebDriver\Remote; -class LocalFileDetector implements FileDetector { +class LocalFileDetector implements FileDetector +{ /** * @param string $file * * @return null|string */ - public function getLocalFile($file) { - if (is_file($file)) { - return $file; + public function getLocalFile($file) + { + if (is_file($file)) { + return $file; + } + + return null; } - return null; - } } diff --git a/lib/Remote/RemoteExecuteMethod.php b/lib/Remote/RemoteExecuteMethod.php index e0ded1032..5a995215e 100644 --- a/lib/Remote/RemoteExecuteMethod.php +++ b/lib/Remote/RemoteExecuteMethod.php @@ -15,26 +15,25 @@ namespace Facebook\WebDriver\Remote; -class RemoteExecuteMethod implements ExecuteMethod { +class RemoteExecuteMethod implements ExecuteMethod +{ + private $driver; - private $driver; + /** + * @param RemoteWebDriver $driver + */ + public function __construct(RemoteWebDriver $driver) + { + $this->driver = $driver; + } - /** - * @param RemoteWebDriver $driver - */ - public function __construct(RemoteWebDriver $driver) { - $this->driver = $driver; - } - - /** - * @param string $command_name - * @param array $parameters - * @return mixed - */ - public function execute( - $command_name, - array $parameters = array() - ) { - return $this->driver->execute($command_name, $parameters); - } + /** + * @param string $command_name + * @param array $parameters + * @return mixed + */ + public function execute($command_name, array $parameters = array()) + { + return $this->driver->execute($command_name, $parameters); + } } diff --git a/lib/Remote/RemoteKeyboard.php b/lib/Remote/RemoteKeyboard.php index 2b297d1d9..7b2e114a2 100644 --- a/lib/Remote/RemoteKeyboard.php +++ b/lib/Remote/RemoteKeyboard.php @@ -15,63 +15,70 @@ namespace Facebook\WebDriver\Remote; -use Facebook\WebDriver\WebDriverKeys; use Facebook\WebDriver\WebDriverKeyboard; +use Facebook\WebDriver\WebDriverKeys; /** * Execute keyboard commands for RemoteWebDriver. */ -class RemoteKeyboard implements WebDriverKeyboard { +class RemoteKeyboard implements WebDriverKeyboard +{ + /** + * @var RemoteExecuteMethod + */ + private $executor; + + /** + * @param RemoteExecuteMethod $executor + */ + public function __construct(RemoteExecuteMethod $executor) + { + $this->executor = $executor; + } + + /** + * Send keys to active element + * @param string|array $keys + * @return $this + */ + public function sendKeys($keys) + { + $this->executor->execute(DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT, array( + 'value' => WebDriverKeys::encode($keys), + )); - /** - * @var RemoteExecuteMethod - */ - private $executor; + return $this; + } - /** - * @param RemoteExecuteMethod $executor - */ - public function __construct(RemoteExecuteMethod $executor) { - $this->executor = $executor; - } + /** + * Press a modifier key + * + * @see WebDriverKeys + * @param string $key + * @return $this + */ + public function pressKey($key) + { + $this->executor->execute(DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT, array( + 'value' => array((string) $key), + )); - /** - * Send keys to active element - * @param string|array $keys - * @return $this - */ - public function sendKeys($keys) { - $this->executor->execute(DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT, array( - 'value' => WebDriverKeys::encode($keys), - )); - return $this; - } + return $this; + } - /** - * Press a modifier key - * - * @see WebDriverKeys - * @param string $key - * @return $this - */ - public function pressKey($key) { - $this->executor->execute(DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT, array( - 'value' => array((string)$key), - )); - return $this; - } + /** + * Release a modifier key + * + * @see WebDriverKeys + * @param string $key + * @return $this + */ + public function releaseKey($key) + { + $this->executor->execute(DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT, array( + 'value' => array((string) $key), + )); - /** - * Release a modifier key - * - * @see WebDriverKeys - * @param string $key - * @return $this - */ - public function releaseKey($key) { - $this->executor->execute(DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT, array( - 'value' => array((string)$key), - )); - return $this; - } + return $this; + } } diff --git a/lib/Remote/RemoteMouse.php b/lib/Remote/RemoteMouse.php index c2e0d2263..00a4ef7b6 100644 --- a/lib/Remote/RemoteMouse.php +++ b/lib/Remote/RemoteMouse.php @@ -21,110 +21,124 @@ /** * Execute mouse commands for RemoteWebDriver. */ -class RemoteMouse implements WebDriverMouse { - - /** - * @var RemoteExecuteMethod - */ - private $executor; - - /** - * @param RemoteExecuteMethod $executor - */ - public function __construct(RemoteExecuteMethod $executor) { - $this->executor = $executor; - } - - /** - * @param null|WebDriverCoordinates $where - * - * @return RemoteMouse - */ - public function click(WebDriverCoordinates $where = null) { - $this->moveIfNeeded($where); - $this->executor->execute(DriverCommand::CLICK, array( - 'button' => 0, - )); - return $this; - } - - /** - * @param WebDriverCoordinates $where - * - * @return RemoteMouse - */ - public function contextClick(WebDriverCoordinates $where = null) { - $this->moveIfNeeded($where); - $this->executor->execute(DriverCommand::CLICK, array( - 'button' => 2, - )); - return $this; - } - - /** - * @param WebDriverCoordinates $where - * - * @return RemoteMouse - */ - public function doubleClick(WebDriverCoordinates $where = null) { - $this->moveIfNeeded($where); - $this->executor->execute(DriverCommand::DOUBLE_CLICK); - return $this; - } - - /** - * @param WebDriverCoordinates $where - * - * @return RemoteMouse - */ - public function mouseDown(WebDriverCoordinates $where = null) { - $this->moveIfNeeded($where); - $this->executor->execute(DriverCommand::MOUSE_DOWN); - return $this; - } - - /** - * @param WebDriverCoordinates $where - * @param int|null $x_offset - * @param int|null $y_offset - * - * @return RemoteMouse - */ - public function mouseMove(WebDriverCoordinates $where = null, - $x_offset = null, - $y_offset = null) { - $params = array(); - if ($where !== null) { - $params['element'] = $where->getAuxiliary(); +class RemoteMouse implements WebDriverMouse +{ + /** + * @var RemoteExecuteMethod + */ + private $executor; + + /** + * @param RemoteExecuteMethod $executor + */ + public function __construct(RemoteExecuteMethod $executor) + { + $this->executor = $executor; + } + + /** + * @param null|WebDriverCoordinates $where + * + * @return RemoteMouse + */ + public function click(WebDriverCoordinates $where = null) + { + $this->moveIfNeeded($where); + $this->executor->execute(DriverCommand::CLICK, array( + 'button' => 0, + )); + + return $this; + } + + /** + * @param WebDriverCoordinates $where + * + * @return RemoteMouse + */ + public function contextClick(WebDriverCoordinates $where = null) + { + $this->moveIfNeeded($where); + $this->executor->execute(DriverCommand::CLICK, array( + 'button' => 2, + )); + + return $this; + } + + /** + * @param WebDriverCoordinates $where + * + * @return RemoteMouse + */ + public function doubleClick(WebDriverCoordinates $where = null) + { + $this->moveIfNeeded($where); + $this->executor->execute(DriverCommand::DOUBLE_CLICK); + + return $this; } - if ($x_offset !== null) { - $params['xoffset'] = $x_offset; + + /** + * @param WebDriverCoordinates $where + * + * @return RemoteMouse + */ + public function mouseDown(WebDriverCoordinates $where = null) + { + $this->moveIfNeeded($where); + $this->executor->execute(DriverCommand::MOUSE_DOWN); + + return $this; } - if ($y_offset !== null) { - $params['yoffset'] = $y_offset; + + /** + * @param WebDriverCoordinates $where + * @param int|null $x_offset + * @param int|null $y_offset + * + * @return RemoteMouse + */ + public function mouseMove( + WebDriverCoordinates $where = null, + $x_offset = null, + $y_offset = null + ) { + $params = array(); + if ($where !== null) { + $params['element'] = $where->getAuxiliary(); + } + if ($x_offset !== null) { + $params['xoffset'] = $x_offset; + } + if ($y_offset !== null) { + $params['yoffset'] = $y_offset; + } + $this->executor->execute(DriverCommand::MOVE_TO, $params); + + return $this; } - $this->executor->execute(DriverCommand::MOVE_TO, $params); - return $this; - } - - /** - * @param WebDriverCoordinates $where - * - * @return RemoteMouse - */ - public function mouseUp(WebDriverCoordinates $where = null) { - $this->moveIfNeeded($where); - $this->executor->execute(DriverCommand::MOUSE_UP); - return $this; - } - - /** - * @param WebDriverCoordinates $where - * @return void - */ - protected function moveIfNeeded(WebDriverCoordinates $where = null) { - if ($where) { - $this->mouseMove($where); + + /** + * @param WebDriverCoordinates $where + * + * @return RemoteMouse + */ + public function mouseUp(WebDriverCoordinates $where = null) + { + $this->moveIfNeeded($where); + $this->executor->execute(DriverCommand::MOUSE_UP); + + return $this; + } + + /** + * @param WebDriverCoordinates $where + */ + protected function moveIfNeeded(WebDriverCoordinates $where = null) + { + if ($where) { + $this->mouseMove($where); + } } - } } diff --git a/lib/Remote/RemoteTargetLocator.php b/lib/Remote/RemoteTargetLocator.php index e2f5a0aea..67d2ad7cd 100644 --- a/lib/Remote/RemoteTargetLocator.php +++ b/lib/Remote/RemoteTargetLocator.php @@ -15,90 +15,97 @@ namespace Facebook\WebDriver\Remote; -use Facebook\WebDriver\WebDriverTargetLocator; -use Facebook\WebDriver\WebDriverElement; -use Facebook\WebDriver\WebDriverAlert; use Facebook\WebDriver\WebDriver; +use Facebook\WebDriver\WebDriverAlert; +use Facebook\WebDriver\WebDriverElement; +use Facebook\WebDriver\WebDriverTargetLocator; /** * Used to locate a given frame or window for RemoteWebDriver. */ -class RemoteTargetLocator implements WebDriverTargetLocator { +class RemoteTargetLocator implements WebDriverTargetLocator +{ + protected $executor; + protected $driver; - protected $executor; - protected $driver; + public function __construct($executor, $driver) + { + $this->executor = $executor; + $this->driver = $driver; + } - public function __construct($executor, $driver) { - $this->executor = $executor; - $this->driver = $driver; - } + /** + * Switch to the main document if the page contains iframes. Otherwise, switch + * to the first frame on the page. + * + * @return WebDriver The driver focused on the top window or the first frame. + */ + public function defaultContent() + { + $params = array('id' => null); + $this->executor->execute(DriverCommand::SWITCH_TO_FRAME, $params); - /** - * Switch to the main document if the page contains iframes. Otherwise, switch - * to the first frame on the page. - * - * @return WebDriver The driver focused on the top window or the first frame. - */ - public function defaultContent() { - $params = array('id' => null); - $this->executor->execute(DriverCommand::SWITCH_TO_FRAME, $params); + return $this->driver; + } - return $this->driver; - } + /** + * Switch to the iframe by its id or name. + * + * @param WebDriverElement|string $frame The WebDriverElement, + * the id or the name of the frame. + * @return WebDriver The driver focused on the given frame. + */ + public function frame($frame) + { + if ($frame instanceof WebDriverElement) { + $id = array('ELEMENT' => $frame->getID()); + } else { + $id = (string) $frame; + } - /** - * Switch to the iframe by its id or name. - * - * @param WebDriverElement|string $frame The WebDriverElement, - the id or the name of the frame. - * @return WebDriver The driver focused on the given frame. - */ - public function frame($frame) { - if ($frame instanceof WebDriverElement) { - $id = array('ELEMENT' => $frame->getID()); - } else { - $id = (string)$frame; - } + $params = array('id' => $id); + $this->executor->execute(DriverCommand::SWITCH_TO_FRAME, $params); - $params = array('id' => $id); - $this->executor->execute(DriverCommand::SWITCH_TO_FRAME, $params); + return $this->driver; + } - return $this->driver; - } + /** + * Switch the focus to another window by its handle. + * + * @param string $handle The handle of the window to be focused on. + * @return WebDriver Tge driver focused on the given window. + * @see WebDriver::getWindowHandles + */ + public function window($handle) + { + $params = array('name' => (string) $handle); + $this->executor->execute(DriverCommand::SWITCH_TO_WINDOW, $params); - /** - * Switch the focus to another window by its handle. - * - * @param string $handle The handle of the window to be focused on. - * @return WebDriver Tge driver focused on the given window. - * @see WebDriver::getWindowHandles - */ - public function window($handle) { - $params = array('name' => (string)$handle); - $this->executor->execute(DriverCommand::SWITCH_TO_WINDOW, $params); + return $this->driver; + } - return $this->driver; - } + /** + * Switch to the currently active modal dialog for this particular driver + * instance. + * + * @return WebDriverAlert + */ + public function alert() + { + return new WebDriverAlert($this->executor); + } - /** - * Switch to the currently active modal dialog for this particular driver - * instance. - * - * @return WebDriverAlert - */ - public function alert() { - return new WebDriverAlert($this->executor); - } + /** + * Switches to the element that currently has focus within the document + * currently "switched to", or the body element if this cannot be detected. + * + * @return RemoteWebElement + */ + public function activeElement() + { + $response = $this->driver->execute(DriverCommand::GET_ACTIVE_ELEMENT); + $method = new RemoteExecuteMethod($this->driver); - /** - * Switches to the element that currently has focus within the document - * currently "switched to", or the body element if this cannot be detected. - * - * @return RemoteWebElement - */ - public function activeElement() { - $response = $this->driver->execute(DriverCommand::GET_ACTIVE_ELEMENT); - $method = new RemoteExecuteMethod($this->driver); - return new RemoteWebElement($method, $response['ELEMENT']); - } + return new RemoteWebElement($method, $response['ELEMENT']); + } } diff --git a/lib/Remote/RemoteTouchScreen.php b/lib/Remote/RemoteTouchScreen.php index 7929d5db3..a052a6063 100644 --- a/lib/Remote/RemoteTouchScreen.php +++ b/lib/Remote/RemoteTouchScreen.php @@ -21,177 +21,181 @@ /** * Execute touch commands for RemoteWebDriver. */ -class RemoteTouchScreen implements WebDriverTouchScreen { - - /** - * @var RemoteExecuteMethod - */ - private $executor; - - /** - * @param RemoteExecuteMethod $executor - */ - public function __construct(RemoteExecuteMethod $executor) { - $this->executor = $executor; - } - - /** - * @param WebDriverElement $element - * - * @return RemoteTouchScreen The instance. - */ - public function tap(WebDriverElement $element) { - $this->executor->execute( - DriverCommand::TOUCH_SINGLE_TAP, - array('element' => $element->getID()) - ); - - return $this; - } - - /** - * @param WebDriverElement $element - * - * @return RemoteTouchScreen The instance. - */ - public function doubleTap(WebDriverElement $element) { - $this->executor->execute( - DriverCommand::TOUCH_DOUBLE_TAP, - array('element' => $element->getID()) - ); - - return $this; - } - - /** - * @param int $x - * @param int $y - * - * @return RemoteTouchScreen The instance. - */ - public function down($x, $y) { - $this->executor->execute(DriverCommand::TOUCH_DOWN, array( - 'x' => $x, - 'y' => $y, - )); - - return $this; - } - - - /** - * @param int $xspeed - * @param int $yspeed - * - * @return RemoteTouchScreen The instance. - */ - public function flick($xspeed, $yspeed) { - $this->executor->execute(DriverCommand::TOUCH_FLICK, array( - 'xspeed' => $xspeed, - 'yspeed' => $yspeed, - )); - - return $this; - } - - /** - * @param WebDriverElement $element - * @param int $xoffset - * @param int $yoffset - * @param int $speed - * - * @return RemoteTouchScreen The instance. - */ - public function flickFromElement( - WebDriverElement $element, $xoffset, $yoffset, $speed - ) { - $this->executor->execute(DriverCommand::TOUCH_FLICK, array( - 'xoffset' => $xoffset, - 'yoffset' => $yoffset, - 'element' => $element->getID(), - 'speed' => $speed, - )); - - return $this; - } - - /** - * @param WebDriverElement $element - * - * @return RemoteTouchScreen The instance. - */ - public function longPress(WebDriverElement $element) { - $this->executor->execute( - DriverCommand::TOUCH_LONG_PRESS, - array('element' => $element->getID()) - ); - - return $this; - } - - /** - * @param int $x - * @param int $y - * - * @return RemoteTouchScreen The instance. - */ - public function move($x, $y) { - $this->executor->execute(DriverCommand::TOUCH_MOVE, array( - 'x' => $x, - 'y' => $y, - )); - - return $this; - } - - /** - * @param int $xoffset - * @param int $yoffset - * - * @return RemoteTouchScreen The instance. - */ - public function scroll($xoffset, $yoffset) { - $this->executor->execute(DriverCommand::TOUCH_SCROLL, array( - 'xoffset' => $xoffset, - 'yoffset' => $yoffset, - )); - - return $this; - } - - /** - * @param WebDriverElement $element - * @param int $xoffset - * @param int $yoffset - * - * @return RemoteTouchScreen The instance. - */ - public function scrollFromElement( - WebDriverElement $element, $xoffset, $yoffset - ) { - $this->executor->execute(DriverCommand::TOUCH_SCROLL, array( - 'element' => $element->getID(), - 'xoffset' => $xoffset, - 'yoffset' => $yoffset, - )); - - return $this; - } - - - /** - * @param int $x - * @param int $y - * - * @return RemoteTouchScreen The instance. - */ - public function up($x, $y) { - $this->executor->execute(DriverCommand::TOUCH_UP, array( - 'x' => $x, - 'y' => $y, - )); - - return $this; - } - +class RemoteTouchScreen implements WebDriverTouchScreen +{ + /** + * @var RemoteExecuteMethod + */ + private $executor; + + /** + * @param RemoteExecuteMethod $executor + */ + public function __construct(RemoteExecuteMethod $executor) + { + $this->executor = $executor; + } + + /** + * @param WebDriverElement $element + * + * @return RemoteTouchScreen The instance. + */ + public function tap(WebDriverElement $element) + { + $this->executor->execute( + DriverCommand::TOUCH_SINGLE_TAP, + array('element' => $element->getID()) + ); + + return $this; + } + + /** + * @param WebDriverElement $element + * + * @return RemoteTouchScreen The instance. + */ + public function doubleTap(WebDriverElement $element) + { + $this->executor->execute( + DriverCommand::TOUCH_DOUBLE_TAP, + array('element' => $element->getID()) + ); + + return $this; + } + + /** + * @param int $x + * @param int $y + * + * @return RemoteTouchScreen The instance. + */ + public function down($x, $y) + { + $this->executor->execute(DriverCommand::TOUCH_DOWN, array( + 'x' => $x, + 'y' => $y, + )); + + return $this; + } + + /** + * @param int $xspeed + * @param int $yspeed + * + * @return RemoteTouchScreen The instance. + */ + public function flick($xspeed, $yspeed) + { + $this->executor->execute(DriverCommand::TOUCH_FLICK, array( + 'xspeed' => $xspeed, + 'yspeed' => $yspeed, + )); + + return $this; + } + + /** + * @param WebDriverElement $element + * @param int $xoffset + * @param int $yoffset + * @param int $speed + * + * @return RemoteTouchScreen The instance. + */ + public function flickFromElement(WebDriverElement $element, $xoffset, $yoffset, $speed) + { + $this->executor->execute(DriverCommand::TOUCH_FLICK, array( + 'xoffset' => $xoffset, + 'yoffset' => $yoffset, + 'element' => $element->getID(), + 'speed' => $speed, + )); + + return $this; + } + + /** + * @param WebDriverElement $element + * + * @return RemoteTouchScreen The instance. + */ + public function longPress(WebDriverElement $element) + { + $this->executor->execute( + DriverCommand::TOUCH_LONG_PRESS, + array('element' => $element->getID()) + ); + + return $this; + } + + /** + * @param int $x + * @param int $y + * + * @return RemoteTouchScreen The instance. + */ + public function move($x, $y) + { + $this->executor->execute(DriverCommand::TOUCH_MOVE, array( + 'x' => $x, + 'y' => $y, + )); + + return $this; + } + + /** + * @param int $xoffset + * @param int $yoffset + * + * @return RemoteTouchScreen The instance. + */ + public function scroll($xoffset, $yoffset) + { + $this->executor->execute(DriverCommand::TOUCH_SCROLL, array( + 'xoffset' => $xoffset, + 'yoffset' => $yoffset, + )); + + return $this; + } + + /** + * @param WebDriverElement $element + * @param int $xoffset + * @param int $yoffset + * + * @return RemoteTouchScreen The instance. + */ + public function scrollFromElement(WebDriverElement $element, $xoffset, $yoffset) + { + $this->executor->execute(DriverCommand::TOUCH_SCROLL, array( + 'element' => $element->getID(), + 'xoffset' => $xoffset, + 'yoffset' => $yoffset, + )); + + return $this; + } + + /** + * @param int $x + * @param int $y + * + * @return RemoteTouchScreen The instance. + */ + public function up($x, $y) + { + $this->executor->execute(DriverCommand::TOUCH_UP, array( + 'x' => $x, + 'y' => $y, + )); + + return $this; + } } diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index 8fb7003c1..4f885bc43 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -25,155 +25,162 @@ use Facebook\WebDriver\WebDriverOptions; use Facebook\WebDriver\WebDriverWait; -class RemoteWebDriver implements WebDriver, JavaScriptExecutor { - /** - * @var HttpCommandExecutor - */ - protected $executor; - /** - * @var string - */ - protected $sessionID; - /** - * @var RemoteMouse - */ - protected $mouse; - /** - * @var RemoteKeyboard - */ - protected $keyboard; - /** - * @var RemoteTouchScreen - */ - protected $touch; - /** - * @var RemoteExecuteMethod - */ - protected $executeMethod; - - protected function __construct() {} - - /** - * Construct the RemoteWebDriver by a desired capabilities. - * - * @param string $url The url of the remote server - * @param DesiredCapabilities|array $desired_capabilities The desired capabilities - * @param int|null $connection_timeout_in_ms - * @param int|null $request_timeout_in_ms - * @param string|null $http_proxy The proxy to tunnel requests through - * @param int|null $http_proxy_port - * @return RemoteWebDriver - */ - public static function create( - $url = 'http://localhost:4444/wd/hub', - $desired_capabilities = null, - $connection_timeout_in_ms = null, - $request_timeout_in_ms = null, - $http_proxy = null, - $http_proxy_port = null - ) { - $url = preg_replace('#/+$#', '', $url); - - // Passing DesiredCapabilities as $desired_capabilities is encouraged but - // array is also accepted for legacy reason. - if ($desired_capabilities instanceof DesiredCapabilities) { - $desired_capabilities = $desired_capabilities->toArray(); - } - - $executor = new HttpCommandExecutor($url, $http_proxy, $http_proxy_port); - if ($connection_timeout_in_ms !== null) { - $executor->setConnectionTimeout($connection_timeout_in_ms); - } - if ($request_timeout_in_ms !== null) { - $executor->setRequestTimeout($request_timeout_in_ms); - } - - $command = new WebDriverCommand( - null, - DriverCommand::NEW_SESSION, - array('desiredCapabilities' => $desired_capabilities) - ); - - $response = $executor->execute($command); - - $driver = new static(); - $driver->setSessionID($response->getSessionID()) - ->setCommandExecutor($executor); - return $driver; - } - - /** - * [Experimental] Construct the RemoteWebDriver by an existing session. - * - * This constructor can boost the performance a lot by reusing the same - * browser for the whole test suite. You do not have to pass the desired - * capabilities because the session was created before. - * - * @param string $url The url of the remote server - * @param string $session_id The existing session id - * @return RemoteWebDriver - */ - public static function createBySessionID( - $session_id, - $url = 'http://localhost:4444/wd/hub' - ) { - $driver = new static(); - $driver->setSessionID($session_id) - ->setCommandExecutor(new HttpCommandExecutor($url)); - return $driver; - } - - /** - * Close the current window. - * - * @return RemoteWebDriver The current instance. - */ - public function close() { - $this->execute(DriverCommand::CLOSE, array()); - - return $this; - } - - /** - * Find the first WebDriverElement using the given mechanism. - * - * @param WebDriverBy $by - * @return RemoteWebElement NoSuchElementException is thrown in - * HttpCommandExecutor if no element is found. - * @see WebDriverBy - */ - public function findElement(WebDriverBy $by) { - $params = array('using' => $by->getMechanism(), 'value' => $by->getValue()); - $raw_element = $this->execute( - DriverCommand::FIND_ELEMENT, - $params - ); - - return $this->newElement($raw_element['ELEMENT']); - } - - /** - * Find all WebDriverElements within the current page using the given - * mechanism. - * - * @param WebDriverBy $by - * @return RemoteWebElement[] A list of all WebDriverElements, or an empty - * array if nothing matches - * @see WebDriverBy - */ - public function findElements(WebDriverBy $by) { - $params = array('using' => $by->getMechanism(), 'value' => $by->getValue()); - $raw_elements = $this->execute( - DriverCommand::FIND_ELEMENTS, - $params - ); - - $elements = array(); - foreach ($raw_elements as $raw_element) { - $elements[] = $this->newElement($raw_element['ELEMENT']); - } - return $elements; - } +class RemoteWebDriver implements WebDriver, JavaScriptExecutor +{ + /** + * @var HttpCommandExecutor + */ + protected $executor; + /** + * @var string + */ + protected $sessionID; + /** + * @var RemoteMouse + */ + protected $mouse; + /** + * @var RemoteKeyboard + */ + protected $keyboard; + /** + * @var RemoteTouchScreen + */ + protected $touch; + /** + * @var RemoteExecuteMethod + */ + protected $executeMethod; + + protected function __construct() + { + } + + /** + * Construct the RemoteWebDriver by a desired capabilities. + * + * @param string $url The url of the remote server + * @param DesiredCapabilities|array $desired_capabilities The desired capabilities + * @param int|null $connection_timeout_in_ms + * @param int|null $request_timeout_in_ms + * @param string|null $http_proxy The proxy to tunnel requests through + * @param int|null $http_proxy_port + * @return RemoteWebDriver + */ + public static function create( + $url = 'http://localhost:4444/wd/hub', + $desired_capabilities = null, + $connection_timeout_in_ms = null, + $request_timeout_in_ms = null, + $http_proxy = null, + $http_proxy_port = null + ) { + $url = preg_replace('#/+$#', '', $url); + + // Passing DesiredCapabilities as $desired_capabilities is encouraged but + // array is also accepted for legacy reason. + if ($desired_capabilities instanceof DesiredCapabilities) { + $desired_capabilities = $desired_capabilities->toArray(); + } + + $executor = new HttpCommandExecutor($url, $http_proxy, $http_proxy_port); + if ($connection_timeout_in_ms !== null) { + $executor->setConnectionTimeout($connection_timeout_in_ms); + } + if ($request_timeout_in_ms !== null) { + $executor->setRequestTimeout($request_timeout_in_ms); + } + + $command = new WebDriverCommand( + null, + DriverCommand::NEW_SESSION, + array('desiredCapabilities' => $desired_capabilities) + ); + + $response = $executor->execute($command); + + $driver = new static(); + $driver->setSessionID($response->getSessionID()) + ->setCommandExecutor($executor); + + return $driver; + } + + /** + * [Experimental] Construct the RemoteWebDriver by an existing session. + * + * This constructor can boost the performance a lot by reusing the same + * browser for the whole test suite. You do not have to pass the desired + * capabilities because the session was created before. + * + * @param string $url The url of the remote server + * @param string $session_id The existing session id + * @return RemoteWebDriver + */ + public static function createBySessionID($session_id, $url = 'http://localhost:4444/wd/hub') + { + $driver = new static(); + $driver->setSessionID($session_id) + ->setCommandExecutor(new HttpCommandExecutor($url)); + + return $driver; + } + + /** + * Close the current window. + * + * @return RemoteWebDriver The current instance. + */ + public function close() + { + $this->execute(DriverCommand::CLOSE, array()); + + return $this; + } + + /** + * Find the first WebDriverElement using the given mechanism. + * + * @param WebDriverBy $by + * @return RemoteWebElement NoSuchElementException is thrown in + * HttpCommandExecutor if no element is found. + * @see WebDriverBy + */ + public function findElement(WebDriverBy $by) + { + $params = array('using' => $by->getMechanism(), 'value' => $by->getValue()); + $raw_element = $this->execute( + DriverCommand::FIND_ELEMENT, + $params + ); + + return $this->newElement($raw_element['ELEMENT']); + } + + /** + * Find all WebDriverElements within the current page using the given + * mechanism. + * + * @param WebDriverBy $by + * @return RemoteWebElement[] A list of all WebDriverElements, or an empty + * array if nothing matches + * @see WebDriverBy + */ + public function findElements(WebDriverBy $by) + { + $params = array('using' => $by->getMechanism(), 'value' => $by->getValue()); + $raw_elements = $this->execute( + DriverCommand::FIND_ELEMENTS, + $params + ); + + $elements = array(); + foreach ($raw_elements as $raw_element) { + $elements[] = $this->newElement($raw_element['ELEMENT']); + } + + return $elements; + } /** * Load a new web page in the current browser window. @@ -182,333 +189,366 @@ public function findElements(WebDriverBy $by) { * * @return RemoteWebDriver The current instance. */ - public function get($url) { - $params = array('url' => (string)$url); - $this->execute(DriverCommand::GET, $params); - - return $this; - } - - /** - * Get a string representing the current URL that the browser is looking at. - * - * @return string The current URL. - */ - public function getCurrentURL() { - return $this->execute(DriverCommand::GET_CURRENT_URL); - } - - /** - * Get the source of the last loaded page. - * - * @return string The current page source. - */ - public function getPageSource() { - return $this->execute(DriverCommand::GET_PAGE_SOURCE); - } - - /** - * Get the title of the current page. - * - * @return string The title of the current page. - */ - public function getTitle() { - return $this->execute(DriverCommand::GET_TITLE); - } - - /** - * Return an opaque handle to this window that uniquely identifies it within - * this driver instance. - * - * @return string The current window handle. - */ - public function getWindowHandle() { - return $this->execute( - DriverCommand::GET_CURRENT_WINDOW_HANDLE, - array() - ); - } - - /** - * Get all window handles available to the current session. - * - * @return array An array of string containing all available window handles. - */ - public function getWindowHandles() { - return $this->execute(DriverCommand::GET_WINDOW_HANDLES, array()); - } - - /** - * Quits this driver, closing every associated window. - * - * @return void - */ - public function quit() { - $this->execute(DriverCommand::QUIT); - $this->executor = null; - } - - /** - * Prepare arguments for JavaScript injection - * - * @param array $arguments - * @return array - */ - private function prepareScriptArguments(array $arguments) { - $args = array(); - foreach ($arguments as $key => $value) { - if ($value instanceof WebDriverElement) { - $args[$key] = array('ELEMENT'=>$value->getID()); - } else { - if (is_array($value)) { - $value = $this->prepareScriptArguments($value); + public function get($url) + { + $params = array('url' => (string) $url); + $this->execute(DriverCommand::GET, $params); + + return $this; + } + + /** + * Get a string representing the current URL that the browser is looking at. + * + * @return string The current URL. + */ + public function getCurrentURL() + { + return $this->execute(DriverCommand::GET_CURRENT_URL); + } + + /** + * Get the source of the last loaded page. + * + * @return string The current page source. + */ + public function getPageSource() + { + return $this->execute(DriverCommand::GET_PAGE_SOURCE); + } + + /** + * Get the title of the current page. + * + * @return string The title of the current page. + */ + public function getTitle() + { + return $this->execute(DriverCommand::GET_TITLE); + } + + /** + * Return an opaque handle to this window that uniquely identifies it within + * this driver instance. + * + * @return string The current window handle. + */ + public function getWindowHandle() + { + return $this->execute( + DriverCommand::GET_CURRENT_WINDOW_HANDLE, + array() + ); + } + + /** + * Get all window handles available to the current session. + * + * @return array An array of string containing all available window handles. + */ + public function getWindowHandles() + { + return $this->execute(DriverCommand::GET_WINDOW_HANDLES, array()); + } + + /** + * Quits this driver, closing every associated window. + */ + public function quit() + { + $this->execute(DriverCommand::QUIT); + $this->executor = null; + } + + /** + * Prepare arguments for JavaScript injection + * + * @param array $arguments + * @return array + */ + private function prepareScriptArguments(array $arguments) + { + $args = array(); + foreach ($arguments as $key => $value) { + if ($value instanceof WebDriverElement) { + $args[$key] = array('ELEMENT' => $value->getID()); + } else { + if (is_array($value)) { + $value = $this->prepareScriptArguments($value); + } + $args[$key] = $value; + } } - $args[$key] = $value; - } - } - return $args; - } - - /** - * Inject a snippet of JavaScript into the page for execution in the context - * of the currently selected frame. The executed script is assumed to be - * synchronous and the result of evaluating the script will be returned. - * - * @param string $script The script to inject. - * @param array $arguments The arguments of the script. - * @return mixed The return value of the script. - */ - public function executeScript($script, array $arguments = array()) { - $params = array( - 'script' => $script, - 'args' => $this->prepareScriptArguments($arguments), - ); - return $this->execute(DriverCommand::EXECUTE_SCRIPT, $params); - } - - /** - * Inject a snippet of JavaScript into the page for asynchronous execution in - * the context of the currently selected frame. - * - * The driver will pass a callback as the last argument to the snippet, and - * block until the callback is invoked. - * - * @see WebDriverExecuteAsyncScriptTestCase - * - * @param string $script The script to inject. - * @param array $arguments The arguments of the script. - * @return mixed The value passed by the script to the callback. - */ - public function executeAsyncScript($script, array $arguments = array()) { - $params = array( - 'script' => $script, - 'args' => $this->prepareScriptArguments($arguments), - ); - return $this->execute( - DriverCommand::EXECUTE_ASYNC_SCRIPT, - $params - ); - } - - /** - * Take a screenshot of the current page. - * - * @param string $save_as The path of the screenshot to be saved. - * @return string The screenshot in PNG format. - */ - public function takeScreenshot($save_as = null) { - $screenshot = base64_decode( - $this->execute(DriverCommand::SCREENSHOT) - ); - if ($save_as) { - file_put_contents($save_as, $screenshot); - } - return $screenshot; - } - - /** - * Construct a new WebDriverWait by the current WebDriver instance. - * Sample usage: - * - * $driver->wait(20, 1000)->until( - * WebDriverExpectedCondition::titleIs('WebDriver Page') - * ); - * - * @param int $timeout_in_second - * @param int $interval_in_millisecond - * - * @return WebDriverWait - */ - public function wait( - $timeout_in_second = 30, - $interval_in_millisecond = 250) { - return new WebDriverWait( - $this, $timeout_in_second, $interval_in_millisecond - ); - } - - /** - * An abstraction for managing stuff you would do in a browser menu. For - * example, adding and deleting cookies. - * - * @return WebDriverOptions - */ - public function manage() { - return new WebDriverOptions($this->getExecuteMethod()); - } - - /** - * An abstraction allowing the driver to access the browser's history and to - * navigate to a given URL. - * - * @return WebDriverNavigation - * @see WebDriverNavigation - */ - public function navigate() { - return new WebDriverNavigation($this->getExecuteMethod()); - } - - /** - * Switch to a different window or frame. - * - * @return RemoteTargetLocator - * @see RemoteTargetLocator - */ - public function switchTo() { - return new RemoteTargetLocator($this->getExecuteMethod(), $this); - } - - /** - * @return RemoteMouse - */ - public function getMouse() { - if (!$this->mouse) { - $this->mouse = new RemoteMouse($this->getExecuteMethod()); - } - return $this->mouse; - } - - /** - * @return RemoteKeyboard - */ - public function getKeyboard() { - if (!$this->keyboard) { - $this->keyboard = new RemoteKeyboard($this->getExecuteMethod()); - } - return $this->keyboard; - } - - /** - * @return RemoteTouchScreen - */ - public function getTouch() { - if (!$this->touch) { - $this->touch = new RemoteTouchScreen($this->getExecuteMethod()); - } - return $this->touch; - } - - protected function getExecuteMethod() { - if (!$this->executeMethod) { - $this->executeMethod = new RemoteExecuteMethod($this); - } - return $this->executeMethod; - } - - /** - * Construct a new action builder. - * - * @return WebDriverActions - */ - public function action() { - return new WebDriverActions($this); - } - - /** - * Return the WebDriverElement with the given id. - * - * @param string $id The id of the element to be created. - * @return RemoteWebElement - */ - protected function newElement($id) { - return new RemoteWebElement($this->getExecuteMethod(), $id); - } - - /** - * Set the command executor of this RemoteWebdriver - * - * @param WebDriverCommandExecutor $executor - * @return RemoteWebDriver - */ - public function setCommandExecutor(WebDriverCommandExecutor $executor) { - $this->executor = $executor; - return $this; - } - - /** - * Set the command executor of this RemoteWebdriver - * - * @return HttpCommandExecutor - */ - public function getCommandExecutor() { - return $this->executor; - } - - /** - * Set the session id of the RemoteWebDriver. - * - * @param string $session_id - * @return RemoteWebDriver - */ - public function setSessionID($session_id) { - $this->sessionID = $session_id; - return $this; - } - - /** - * Get current selenium sessionID - * - * @return string sessionID - */ - public function getSessionID() { - return $this->sessionID; - } - - /** - * Get all selenium sessions. - * - * @param string $url The url of the remote server - * @param int $timeout_in_ms - * @return array - */ - public static function getAllSessions( - $url = 'http://localhost:4444/wd/hub', - $timeout_in_ms = 30000 - ) { - $executor = new HttpCommandExecutor($url); - $executor->setConnectionTimeout($timeout_in_ms); - - $command = new WebDriverCommand( - null, - DriverCommand::GET_ALL_SESSIONS, - array() - ); - - return $executor->execute($command)->getValue(); - } - - public function execute($command_name, $params = array()) { - $command = new WebDriverCommand( - $this->sessionID, - $command_name, - $params - ); - - if ($this->executor) { - $response = $this->executor->execute($command); - return $response->getValue(); - } else { - return null; - } - } + + return $args; + } + + /** + * Inject a snippet of JavaScript into the page for execution in the context + * of the currently selected frame. The executed script is assumed to be + * synchronous and the result of evaluating the script will be returned. + * + * @param string $script The script to inject. + * @param array $arguments The arguments of the script. + * @return mixed The return value of the script. + */ + public function executeScript($script, array $arguments = array()) + { + $params = array( + 'script' => $script, + 'args' => $this->prepareScriptArguments($arguments), + ); + + return $this->execute(DriverCommand::EXECUTE_SCRIPT, $params); + } + + /** + * Inject a snippet of JavaScript into the page for asynchronous execution in + * the context of the currently selected frame. + * + * The driver will pass a callback as the last argument to the snippet, and + * block until the callback is invoked. + * + * @see WebDriverExecuteAsyncScriptTestCase + * + * @param string $script The script to inject. + * @param array $arguments The arguments of the script. + * @return mixed The value passed by the script to the callback. + */ + public function executeAsyncScript($script, array $arguments = array()) + { + $params = array( + 'script' => $script, + 'args' => $this->prepareScriptArguments($arguments), + ); + + return $this->execute( + DriverCommand::EXECUTE_ASYNC_SCRIPT, + $params + ); + } + + /** + * Take a screenshot of the current page. + * + * @param string $save_as The path of the screenshot to be saved. + * @return string The screenshot in PNG format. + */ + public function takeScreenshot($save_as = null) + { + $screenshot = base64_decode( + $this->execute(DriverCommand::SCREENSHOT) + ); + if ($save_as) { + file_put_contents($save_as, $screenshot); + } + + return $screenshot; + } + + /** + * Construct a new WebDriverWait by the current WebDriver instance. + * Sample usage: + * + * $driver->wait(20, 1000)->until( + * WebDriverExpectedCondition::titleIs('WebDriver Page') + * ); + * + * @param int $timeout_in_second + * @param int $interval_in_millisecond + * + * @return WebDriverWait + */ + public function wait($timeout_in_second = 30, $interval_in_millisecond = 250) + { + return new WebDriverWait( + $this, + $timeout_in_second, + $interval_in_millisecond + ); + } + + /** + * An abstraction for managing stuff you would do in a browser menu. For + * example, adding and deleting cookies. + * + * @return WebDriverOptions + */ + public function manage() + { + return new WebDriverOptions($this->getExecuteMethod()); + } + + /** + * An abstraction allowing the driver to access the browser's history and to + * navigate to a given URL. + * + * @return WebDriverNavigation + * @see WebDriverNavigation + */ + public function navigate() + { + return new WebDriverNavigation($this->getExecuteMethod()); + } + + /** + * Switch to a different window or frame. + * + * @return RemoteTargetLocator + * @see RemoteTargetLocator + */ + public function switchTo() + { + return new RemoteTargetLocator($this->getExecuteMethod(), $this); + } + + /** + * @return RemoteMouse + */ + public function getMouse() + { + if (!$this->mouse) { + $this->mouse = new RemoteMouse($this->getExecuteMethod()); + } + + return $this->mouse; + } + + /** + * @return RemoteKeyboard + */ + public function getKeyboard() + { + if (!$this->keyboard) { + $this->keyboard = new RemoteKeyboard($this->getExecuteMethod()); + } + + return $this->keyboard; + } + + /** + * @return RemoteTouchScreen + */ + public function getTouch() + { + if (!$this->touch) { + $this->touch = new RemoteTouchScreen($this->getExecuteMethod()); + } + + return $this->touch; + } + + protected function getExecuteMethod() + { + if (!$this->executeMethod) { + $this->executeMethod = new RemoteExecuteMethod($this); + } + + return $this->executeMethod; + } + + /** + * Construct a new action builder. + * + * @return WebDriverActions + */ + public function action() + { + return new WebDriverActions($this); + } + + /** + * Return the WebDriverElement with the given id. + * + * @param string $id The id of the element to be created. + * @return RemoteWebElement + */ + protected function newElement($id) + { + return new RemoteWebElement($this->getExecuteMethod(), $id); + } + + /** + * Set the command executor of this RemoteWebdriver + * + * @param WebDriverCommandExecutor $executor + * @return RemoteWebDriver + */ + public function setCommandExecutor(WebDriverCommandExecutor $executor) + { + $this->executor = $executor; + + return $this; + } + + /** + * Set the command executor of this RemoteWebdriver + * + * @return HttpCommandExecutor + */ + public function getCommandExecutor() + { + return $this->executor; + } + + /** + * Set the session id of the RemoteWebDriver. + * + * @param string $session_id + * @return RemoteWebDriver + */ + public function setSessionID($session_id) + { + $this->sessionID = $session_id; + + return $this; + } + + /** + * Get current selenium sessionID + * + * @return string sessionID + */ + public function getSessionID() + { + return $this->sessionID; + } + + /** + * Get all selenium sessions. + * + * @param string $url The url of the remote server + * @param int $timeout_in_ms + * @return array + */ + public static function getAllSessions($url = 'http://localhost:4444/wd/hub', $timeout_in_ms = 30000) + { + $executor = new HttpCommandExecutor($url); + $executor->setConnectionTimeout($timeout_in_ms); + + $command = new WebDriverCommand( + null, + DriverCommand::GET_ALL_SESSIONS, + array() + ); + + return $executor->execute($command)->getValue(); + } + + public function execute($command_name, $params = array()) + { + $command = new WebDriverCommand( + $this->sessionID, + $command_name, + $params + ); + + if ($this->executor) { + $response = $this->executor->execute($command); + + return $response->getValue(); + } else { + return null; + } + } } diff --git a/lib/Remote/RemoteWebElement.php b/lib/Remote/RemoteWebElement.php index e9e1ca31e..217356592 100644 --- a/lib/Remote/RemoteWebElement.php +++ b/lib/Remote/RemoteWebElement.php @@ -28,395 +28,429 @@ /** * Represents an HTML element. */ -class RemoteWebElement implements WebDriverElement, WebDriverLocatable { - - /** - * @var RemoteExecuteMethod - */ - protected $executor; - /** - * @var string - */ - protected $id; - /** - * @var UselessFileDetector - */ - protected $fileDetector; - - /** - * @param RemoteExecuteMethod $executor - * @param string $id - */ - public function __construct(RemoteExecuteMethod $executor, $id) { - $this->executor = $executor; - $this->id = $id; - $this->fileDetector = new UselessFileDetector(); - } - - /** - * If this element is a TEXTAREA or text INPUT element, this will clear the - * value. - * - * @return RemoteWebElement The current instance. - */ - public function clear() { - $this->executor->execute( - DriverCommand::CLEAR_ELEMENT, - array(':id' => $this->id) - ); - return $this; - } - - /** - * Click this element. - * - * @return RemoteWebElement The current instance. - */ - public function click() { - $this->executor->execute( - DriverCommand::CLICK_ELEMENT, - array(':id' => $this->id) - ); - return $this; - } - - /** - * Find the first WebDriverElement within this element using the given - * mechanism. - * - * @param WebDriverBy $by - * @return RemoteWebElement NoSuchElementException is thrown in - * HttpCommandExecutor if no element is found. - * @see WebDriverBy - */ - public function findElement(WebDriverBy $by) { - $params = array( - 'using' => $by->getMechanism(), - 'value' => $by->getValue(), - ':id' => $this->id, - ); - $raw_element = $this->executor->execute( - DriverCommand::FIND_CHILD_ELEMENT, - $params - ); - - return $this->newElement($raw_element['ELEMENT']); - } - - /** - * Find all WebDriverElements within this element using the given mechanism. - * - * @param WebDriverBy $by - * @return RemoteWebElement[] A list of all WebDriverElements, or an empty - * array if nothing matches - * @see WebDriverBy - */ - public function findElements(WebDriverBy $by) { - $params = array( - 'using' => $by->getMechanism(), - 'value' => $by->getValue(), - ':id' => $this->id, - ); - $raw_elements = $this->executor->execute( - DriverCommand::FIND_CHILD_ELEMENTS, - $params - ); - - $elements = array(); - foreach ($raw_elements as $raw_element) { - $elements[] = $this->newElement($raw_element['ELEMENT']); +class RemoteWebElement implements WebDriverElement, WebDriverLocatable +{ + /** + * @var RemoteExecuteMethod + */ + protected $executor; + /** + * @var string + */ + protected $id; + /** + * @var UselessFileDetector + */ + protected $fileDetector; + + /** + * @param RemoteExecuteMethod $executor + * @param string $id + */ + public function __construct(RemoteExecuteMethod $executor, $id) + { + $this->executor = $executor; + $this->id = $id; + $this->fileDetector = new UselessFileDetector(); } - return $elements; - } - - /** - * Get the value of a the given attribute of the element. - * - * @param string $attribute_name The name of the attribute. - * @return string|null The value of the attribute. - */ - public function getAttribute($attribute_name) { - $params = array( - ':name' => $attribute_name, - ':id' => $this->id, - ); - return $this->executor->execute( - DriverCommand::GET_ELEMENT_ATTRIBUTE, - $params - ); - } - - /** - * Get the value of a given CSS property. - * - * @param string $css_property_name The name of the CSS property. - * @return string The value of the CSS property. - */ - public function getCSSValue($css_property_name) { - $params = array( - ':propertyName' => $css_property_name, - ':id' => $this->id, - ); - return $this->executor->execute( - DriverCommand::GET_ELEMENT_VALUE_OF_CSS_PROPERTY, - $params - ); - } - - /** - * Get the location of element relative to the top-left corner of the page. - * - * @return WebDriverPoint The location of the element. - */ - public function getLocation() { - $location = $this->executor->execute( - DriverCommand::GET_ELEMENT_LOCATION, - array(':id' => $this->id) - ); - return new WebDriverPoint($location['x'], $location['y']); - } - - /** - * Try scrolling the element into the view port and return the location of - * element relative to the top-left corner of the page afterwards. - * - * @return WebDriverPoint The location of the element. - */ - public function getLocationOnScreenOnceScrolledIntoView() { - $location = $this->executor->execute( - DriverCommand::GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW, - array(':id' => $this->id) - ); - return new WebDriverPoint($location['x'], $location['y']); - } - - /** - * @return WebDriverCoordinates - */ - public function getCoordinates() { - $element = $this; - - $on_screen = null; // planned but not yet implemented - $in_view_port = function () use ($element) { - return $element->getLocationOnScreenOnceScrolledIntoView(); - }; - $on_page = function () use ($element) { - return $element->getLocation(); - }; - $auxiliary = $this->getID(); - - return new WebDriverCoordinates( - $on_screen, - $in_view_port, - $on_page, - $auxiliary - ); - } - - /** - * Get the size of element. - * - * @return WebDriverDimension The dimension of the element. - */ - public function getSize() { - $size = $this->executor->execute( - DriverCommand::GET_ELEMENT_SIZE, - array(':id' => $this->id) - ); - return new WebDriverDimension($size['width'], $size['height']); - } - - /** - * Get the tag name of this element. - * - * @return string The tag name. - */ - public function getTagName() { - // Force tag name to be lowercase as expected by protocol for Opera driver - // until this issue is not resolved : - // https://github.com/operasoftware/operadriver/issues/102 - // Remove it when fixed to be consistent with the protocol. - return strtolower($this->executor->execute( - DriverCommand::GET_ELEMENT_TAG_NAME, - array(':id' => $this->id) - )); - } - - /** - * Get the visible (i.e. not hidden by CSS) innerText of this element, - * including sub-elements, without any leading or trailing whitespace. - * - * @return string The visible innerText of this element. - */ - public function getText() { - return $this->executor->execute( - DriverCommand::GET_ELEMENT_TEXT, - array(':id' => $this->id) - ); - } - - /** - * Is this element displayed or not? This method avoids the problem of having - * to parse an element's "style" attribute. - * - * @return bool - */ - public function isDisplayed() { - return $this->executor->execute( - DriverCommand::IS_ELEMENT_DISPLAYED, - array(':id' => $this->id) - ); - } - - /** - * Is the element currently enabled or not? This will generally return true - * for everything but disabled input elements. - * - * @return bool - */ - public function isEnabled() { - return $this->executor->execute( - DriverCommand::IS_ELEMENT_ENABLED, - array(':id' => $this->id) - ); - } - - /** - * Determine whether or not this element is selected or not. - * - * @return bool - */ - public function isSelected() { - return $this->executor->execute( - DriverCommand::IS_ELEMENT_SELECTED, - array(':id' => $this->id) - ); - } - - /** - * Simulate typing into an element, which may set its value. - * - * @param mixed $value The data to be typed. - * @return RemoteWebElement The current instance. - */ - public function sendKeys($value) { - $local_file = $this->fileDetector->getLocalFile($value); - if ($local_file === null) { - $params = array( - 'value' => WebDriverKeys::encode($value), - ':id' => $this->id, - ); - $this->executor->execute(DriverCommand::SEND_KEYS_TO_ELEMENT, $params); - } else { - $remote_path = $this->upload($local_file); - $params = array( - 'value' => WebDriverKeys::encode($remote_path), - ':id' => $this->id, - ); - $this->executor->execute(DriverCommand::SEND_KEYS_TO_ELEMENT, $params); + + /** + * If this element is a TEXTAREA or text INPUT element, this will clear the + * value. + * + * @return RemoteWebElement The current instance. + */ + public function clear() + { + $this->executor->execute( + DriverCommand::CLEAR_ELEMENT, + array(':id' => $this->id) + ); + + return $this; + } + + /** + * Click this element. + * + * @return RemoteWebElement The current instance. + */ + public function click() + { + $this->executor->execute( + DriverCommand::CLICK_ELEMENT, + array(':id' => $this->id) + ); + + return $this; + } + + /** + * Find the first WebDriverElement within this element using the given + * mechanism. + * + * @param WebDriverBy $by + * @return RemoteWebElement NoSuchElementException is thrown in + * HttpCommandExecutor if no element is found. + * @see WebDriverBy + */ + public function findElement(WebDriverBy $by) + { + $params = array( + 'using' => $by->getMechanism(), + 'value' => $by->getValue(), + ':id' => $this->id, + ); + $raw_element = $this->executor->execute( + DriverCommand::FIND_CHILD_ELEMENT, + $params + ); + + return $this->newElement($raw_element['ELEMENT']); + } + + /** + * Find all WebDriverElements within this element using the given mechanism. + * + * @param WebDriverBy $by + * @return RemoteWebElement[] A list of all WebDriverElements, or an empty + * array if nothing matches + * @see WebDriverBy + */ + public function findElements(WebDriverBy $by) + { + $params = array( + 'using' => $by->getMechanism(), + 'value' => $by->getValue(), + ':id' => $this->id, + ); + $raw_elements = $this->executor->execute( + DriverCommand::FIND_CHILD_ELEMENTS, + $params + ); + + $elements = array(); + foreach ($raw_elements as $raw_element) { + $elements[] = $this->newElement($raw_element['ELEMENT']); + } + + return $elements; + } + + /** + * Get the value of a the given attribute of the element. + * + * @param string $attribute_name The name of the attribute. + * @return string|null The value of the attribute. + */ + public function getAttribute($attribute_name) + { + $params = array( + ':name' => $attribute_name, + ':id' => $this->id, + ); + + return $this->executor->execute( + DriverCommand::GET_ELEMENT_ATTRIBUTE, + $params + ); + } + + /** + * Get the value of a given CSS property. + * + * @param string $css_property_name The name of the CSS property. + * @return string The value of the CSS property. + */ + public function getCSSValue($css_property_name) + { + $params = array( + ':propertyName' => $css_property_name, + ':id' => $this->id, + ); + + return $this->executor->execute( + DriverCommand::GET_ELEMENT_VALUE_OF_CSS_PROPERTY, + $params + ); + } + + /** + * Get the location of element relative to the top-left corner of the page. + * + * @return WebDriverPoint The location of the element. + */ + public function getLocation() + { + $location = $this->executor->execute( + DriverCommand::GET_ELEMENT_LOCATION, + array(':id' => $this->id) + ); + + return new WebDriverPoint($location['x'], $location['y']); + } + + /** + * Try scrolling the element into the view port and return the location of + * element relative to the top-left corner of the page afterwards. + * + * @return WebDriverPoint The location of the element. + */ + public function getLocationOnScreenOnceScrolledIntoView() + { + $location = $this->executor->execute( + DriverCommand::GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW, + array(':id' => $this->id) + ); + + return new WebDriverPoint($location['x'], $location['y']); + } + + /** + * @return WebDriverCoordinates + */ + public function getCoordinates() + { + $element = $this; + + $on_screen = null; // planned but not yet implemented + $in_view_port = function () use ($element) { + return $element->getLocationOnScreenOnceScrolledIntoView(); + }; + $on_page = function () use ($element) { + return $element->getLocation(); + }; + $auxiliary = $this->getID(); + + return new WebDriverCoordinates( + $on_screen, + $in_view_port, + $on_page, + $auxiliary + ); + } + + /** + * Get the size of element. + * + * @return WebDriverDimension The dimension of the element. + */ + public function getSize() + { + $size = $this->executor->execute( + DriverCommand::GET_ELEMENT_SIZE, + array(':id' => $this->id) + ); + + return new WebDriverDimension($size['width'], $size['height']); + } + + /** + * Get the tag name of this element. + * + * @return string The tag name. + */ + public function getTagName() + { + // Force tag name to be lowercase as expected by protocol for Opera driver + // until this issue is not resolved : + // https://github.com/operasoftware/operadriver/issues/102 + // Remove it when fixed to be consistent with the protocol. + return strtolower($this->executor->execute( + DriverCommand::GET_ELEMENT_TAG_NAME, + array(':id' => $this->id) + )); + } + + /** + * Get the visible (i.e. not hidden by CSS) innerText of this element, + * including sub-elements, without any leading or trailing whitespace. + * + * @return string The visible innerText of this element. + */ + public function getText() + { + return $this->executor->execute( + DriverCommand::GET_ELEMENT_TEXT, + array(':id' => $this->id) + ); + } + + /** + * Is this element displayed or not? This method avoids the problem of having + * to parse an element's "style" attribute. + * + * @return bool + */ + public function isDisplayed() + { + return $this->executor->execute( + DriverCommand::IS_ELEMENT_DISPLAYED, + array(':id' => $this->id) + ); + } + + /** + * Is the element currently enabled or not? This will generally return true + * for everything but disabled input elements. + * + * @return bool + */ + public function isEnabled() + { + return $this->executor->execute( + DriverCommand::IS_ELEMENT_ENABLED, + array(':id' => $this->id) + ); + } + + /** + * Determine whether or not this element is selected or not. + * + * @return bool + */ + public function isSelected() + { + return $this->executor->execute( + DriverCommand::IS_ELEMENT_SELECTED, + array(':id' => $this->id) + ); + } + + /** + * Simulate typing into an element, which may set its value. + * + * @param mixed $value The data to be typed. + * @return RemoteWebElement The current instance. + */ + public function sendKeys($value) + { + $local_file = $this->fileDetector->getLocalFile($value); + if ($local_file === null) { + $params = array( + 'value' => WebDriverKeys::encode($value), + ':id' => $this->id, + ); + $this->executor->execute(DriverCommand::SEND_KEYS_TO_ELEMENT, $params); + } else { + $remote_path = $this->upload($local_file); + $params = array( + 'value' => WebDriverKeys::encode($remote_path), + ':id' => $this->id, + ); + $this->executor->execute(DriverCommand::SEND_KEYS_TO_ELEMENT, $params); + } + + return $this; + } + + /** + * Upload a local file to the server + * + * @param string $local_file + * + * @throws WebDriverException + * @return string The remote path of the file. + */ + private function upload($local_file) + { + if (!is_file($local_file)) { + throw new WebDriverException('You may only upload files: ' . $local_file); + } + + // Create a temporary file in the system temp directory. + $temp_zip = tempnam(sys_get_temp_dir(), 'WebDriverZip'); + $zip = new ZipArchive(); + if ($zip->open($temp_zip, ZipArchive::CREATE) !== true) { + return false; + } + $info = pathinfo($local_file); + $file_name = $info['basename']; + $zip->addFile($local_file, $file_name); + $zip->close(); + $params = array( + 'file' => base64_encode(file_get_contents($temp_zip)), + ); + $remote_path = $this->executor->execute( + DriverCommand::UPLOAD_FILE, + $params + ); + unlink($temp_zip); + + return $remote_path; + } + + /** + * Set the fileDetector in order to let the RemoteWebElement to know that + * you are going to upload a file. + * + * Basically, if you want WebDriver trying to send a file, set the fileDetector + * to be LocalFileDetector. Otherwise, keep it UselessFileDetector. + * + * eg. $element->setFileDetector(new LocalFileDetector); + * + * @param FileDetector $detector + * @return RemoteWebElement + * @see FileDetector + * @see LocalFileDetector + * @see UselessFileDetector + */ + public function setFileDetector(FileDetector $detector) + { + $this->fileDetector = $detector; + + return $this; } - return $this; - } - - /** - * Upload a local file to the server - * - * @param string $local_file - * - * @throws WebDriverException - * @return string The remote path of the file. - */ - private function upload($local_file) { - if (!is_file($local_file)) { - throw new WebDriverException("You may only upload files: " . $local_file); + + /** + * If this current element is a form, or an element within a form, then this + * will be submitted to the remote server. + * + * @return RemoteWebElement The current instance. + */ + public function submit() + { + $this->executor->execute( + DriverCommand::SUBMIT_ELEMENT, + array(':id' => $this->id) + ); + + return $this; + } + + /** + * Get the opaque ID of the element. + * + * @return string The opaque ID. + */ + public function getID() + { + return $this->id; + } + + /** + * Test if two element IDs refer to the same DOM element. + * + * @param WebDriverElement $other + * @return bool + */ + public function equals(WebDriverElement $other) + { + return $this->executor->execute(DriverCommand::ELEMENT_EQUALS, array( + ':id' => $this->id, + ':other' => $other->getID(), + )); } - // Create a temporary file in the system temp directory. - $temp_zip = tempnam(sys_get_temp_dir(), 'WebDriverZip'); - $zip = new ZipArchive(); - if ($zip->open($temp_zip, ZipArchive::CREATE) !== true) { - return false; + /** + * Return the WebDriverElement with $id + * + * @param string $id + * + * @return RemoteWebElement + */ + protected function newElement($id) + { + return new static($this->executor, $id); } - $info = pathinfo($local_file); - $file_name = $info['basename']; - $zip->addFile($local_file, $file_name); - $zip->close(); - $params = array( - 'file' => base64_encode(file_get_contents($temp_zip)), - ); - $remote_path = $this->executor->execute( - DriverCommand::UPLOAD_FILE, - $params - ); - unlink($temp_zip); - return $remote_path; - } - - /** - * Set the fileDetector in order to let the RemoteWebElement to know that - * you are going to upload a file. - * - * Basically, if you want WebDriver trying to send a file, set the fileDetector - * to be LocalFileDetector. Otherwise, keep it UselessFileDetector. - * - * eg. $element->setFileDetector(new LocalFileDetector); - * - * @param FileDetector $detector - * @return RemoteWebElement - * @see FileDetector - * @see LocalFileDetector - * @see UselessFileDetector - */ - public function setFileDetector(FileDetector $detector) { - $this->fileDetector = $detector; - return $this; - } - - /** - * If this current element is a form, or an element within a form, then this - * will be submitted to the remote server. - * - * @return RemoteWebElement The current instance. - */ - public function submit() { - $this->executor->execute( - DriverCommand::SUBMIT_ELEMENT, - array(':id' => $this->id) - ); - - return $this; - } - - /** - * Get the opaque ID of the element. - * - * @return string The opaque ID. - */ - public function getID() { - return $this->id; - } - - /** - * Test if two element IDs refer to the same DOM element. - * - * @param WebDriverElement $other - * @return bool - */ - public function equals(WebDriverElement $other) { - return $this->executor->execute(DriverCommand::ELEMENT_EQUALS, array( - ':id' => $this->id, - ':other' => $other->getID(), - )); - } - - /** - * Return the WebDriverElement with $id - * - * @param string $id - * - * @return RemoteWebElement - */ - protected function newElement($id) { - return new static($this->executor, $id); - } } diff --git a/lib/Remote/Service/DriverCommandExecutor.php b/lib/Remote/Service/DriverCommandExecutor.php index 2ac3414f1..59125833b 100644 --- a/lib/Remote/Service/DriverCommandExecutor.php +++ b/lib/Remote/Service/DriverCommandExecutor.php @@ -24,42 +24,44 @@ * A HttpCommandExecutor that talks to a local driver service instead of * a remote server. */ -class DriverCommandExecutor extends HttpCommandExecutor { +class DriverCommandExecutor extends HttpCommandExecutor +{ + /** + * @var DriverService + */ + private $service; - /** - * @var DriverService - */ - private $service; + public function __construct(DriverService $service) + { + parent::__construct($service->getURL()); + $this->service = $service; + } - public function __construct(DriverService $service) { - parent::__construct($service->getURL()); - $this->service = $service; - } + /** + * @param WebDriverCommand $command + * + * @throws WebDriverException + * @throws \Exception + * @return mixed + */ + public function execute(WebDriverCommand $command) + { + if ($command->getName() === DriverCommand::NEW_SESSION) { + $this->service->start(); + } - /** - * @param WebDriverCommand $command - * - * @return mixed - * @throws WebDriverException - * @throws \Exception - */ - public function execute(WebDriverCommand $command) { - if ($command->getName() === DriverCommand::NEW_SESSION) { - $this->service->start(); - } + try { + $value = parent::execute($command); + if ($command->getName() === DriverCommand::QUIT) { + $this->service->stop(); + } - try { - $value = parent::execute($command); - if ($command->getName() === DriverCommand::QUIT) { - $this->service->stop(); - } - return $value; - } catch (\Exception $e) { - if (!$this->service->isRunning()) { - throw new WebDriverException('The driver server has died.'); - } - throw $e; + return $value; + } catch (\Exception $e) { + if (!$this->service->isRunning()) { + throw new WebDriverException('The driver server has died.'); + } + throw $e; + } } - } - } diff --git a/lib/Remote/Service/DriverService.php b/lib/Remote/Service/DriverService.php index 8a18e5d5d..82a427a44 100644 --- a/lib/Remote/Service/DriverService.php +++ b/lib/Remote/Service/DriverService.php @@ -18,130 +18,132 @@ use Exception; use Facebook\WebDriver\Net\URLChecker; -class DriverService { - - /** - * @var string - */ - private $executable; - - /** - * @var string - */ - private $url; - - /** - * @var array - */ - private $args; - - /** - * @var array - */ - private $environment; - - /** - * @var resource - */ - private $process; - - /** - * @param string $executable - * @param int $port The given port the service should use. - * @param array $args - * @param array|null $environment Use the system environment if it is null - */ - public function __construct( - $executable, - $port, - $args = array(), - $environment = null - ) { - $this->executable = self::checkExecutable($executable); - $this->url = sprintf('http://localhost:%d', $port); - $this->args = $args; - $this->environment = $environment ?: $_ENV; - } - - /** - * @return string - */ - public function getURL() { - return $this->url; - } - - /** - * @return DriverService - */ - public function start() { - if ($this->process !== null) { - return $this; +class DriverService +{ + /** + * @var string + */ + private $executable; + + /** + * @var string + */ + private $url; + + /** + * @var array + */ + private $args; + + /** + * @var array + */ + private $environment; + + /** + * @var resource + */ + private $process; + + /** + * @param string $executable + * @param int $port The given port the service should use. + * @param array $args + * @param array|null $environment Use the system environment if it is null + */ + public function __construct($executable, $port, $args = array(), $environment = null) + { + $this->executable = self::checkExecutable($executable); + $this->url = sprintf('http://localhost:%d', $port); + $this->args = $args; + $this->environment = $environment ?: $_ENV; } - $pipes = array(); - $this->process = proc_open( - sprintf("%s %s", $this->executable, implode(' ', $this->args)), - $descriptorspec = array( - 0 => array('pipe', 'r'), // stdin - 1 => array('pipe', 'w'), // stdout - 2 => array('pipe', 'a'), // stderr - ), - $pipes, - null, - $this->environment - ); - - $checker = new URLChecker(); - $checker->waitUntilAvailable(20 * 1000, $this->url.'/status'); - - return $this; - } - - /** - * @return DriverService - */ - public function stop() { - if ($this->process === null) { - return $this; + /** + * @return string + */ + public function getURL() + { + return $this->url; } - proc_terminate($this->process); - $this->process = null; + /** + * @return DriverService + */ + public function start() + { + if ($this->process !== null) { + return $this; + } + + $pipes = array(); + $this->process = proc_open( + sprintf('%s %s', $this->executable, implode(' ', $this->args)), + $descriptorspec = array( + 0 => array('pipe', 'r'), // stdin + 1 => array('pipe', 'w'), // stdout + 2 => array('pipe', 'a'), // stderr + ), + $pipes, + null, + $this->environment + ); + + $checker = new URLChecker(); + $checker->waitUntilAvailable(20 * 1000, $this->url . '/status'); + + return $this; + } - $checker = new URLChecker(); - $checker->waitUntilUnavailable(3 * 1000, $this->url.'/shutdown'); + /** + * @return DriverService + */ + public function stop() + { + if ($this->process === null) { + return $this; + } - return $this; - } + proc_terminate($this->process); + $this->process = null; - /** - * @return bool - */ - public function isRunning() { - if ($this->process === null) { - return false; - } + $checker = new URLChecker(); + $checker->waitUntilUnavailable(3 * 1000, $this->url . '/shutdown'); - $status = proc_get_status($this->process); - return $status['running']; - } - - /** - * Check if the executable is executable. - * - * @param string $executable - * @return string - * @throws Exception - */ - protected static function checkExecutable($executable) { - if (!is_file($executable)) { - throw new Exception("'$executable' is not a file."); + return $this; } - if (!is_executable($executable)) { - throw new Exception("'$executable' is not executable."); + /** + * @return bool + */ + public function isRunning() + { + if ($this->process === null) { + return false; + } + + $status = proc_get_status($this->process); + + return $status['running']; } - return $executable; - } + /** + * Check if the executable is executable. + * + * @param string $executable + * @throws Exception + * @return string + */ + protected static function checkExecutable($executable) + { + if (!is_file($executable)) { + throw new Exception("'$executable' is not a file."); + } + + if (!is_executable($executable)) { + throw new Exception("'$executable' is not executable."); + } + + return $executable; + } } diff --git a/lib/Remote/UselessFileDetector.php b/lib/Remote/UselessFileDetector.php index 9a8090038..f1e71f0c5 100644 --- a/lib/Remote/UselessFileDetector.php +++ b/lib/Remote/UselessFileDetector.php @@ -15,13 +15,13 @@ namespace Facebook\WebDriver\Remote; -class UselessFileDetector implements FileDetector { - /** - * @param string $file - * - * @return null - */ - public function getLocalFile($file) { - return null; - } +class UselessFileDetector implements FileDetector +{ + /** + * @param string $file + */ + public function getLocalFile($file) + { + return null; + } } diff --git a/lib/Remote/WebDriverBrowserType.php b/lib/Remote/WebDriverBrowserType.php index a9de79143..977662a4a 100644 --- a/lib/Remote/WebDriverBrowserType.php +++ b/lib/Remote/WebDriverBrowserType.php @@ -18,31 +18,31 @@ /** * All the browsers supported by selenium */ -class WebDriverBrowserType { - const FIREFOX = "firefox"; - const FIREFOX_2 = "firefox2"; - const FIREFOX_3 = "firefox3"; - const FIREFOX_PROXY = "firefoxproxy"; - const FIREFOX_CHROME = "firefoxchrome"; - const GOOGLECHROME = "googlechrome"; - const SAFARI = "safari"; - const OPERA = "opera"; - const IEXPLORE= "iexplore"; - const IEXPLORE_PROXY= "iexploreproxy"; - const SAFARI_PROXY = "safariproxy"; - const CHROME = "chrome"; - const KONQUEROR = "konqueror"; - const MOCK = "mock"; - const IE_HTA="iehta"; +class WebDriverBrowserType +{ + const FIREFOX = 'firefox'; + const FIREFOX_2 = 'firefox2'; + const FIREFOX_3 = 'firefox3'; + const FIREFOX_PROXY = 'firefoxproxy'; + const FIREFOX_CHROME = 'firefoxchrome'; + const GOOGLECHROME = 'googlechrome'; + const SAFARI = 'safari'; + const OPERA = 'opera'; + const IEXPLORE = 'iexplore'; + const IEXPLORE_PROXY = 'iexploreproxy'; + const SAFARI_PROXY = 'safariproxy'; + const CHROME = 'chrome'; + const KONQUEROR = 'konqueror'; + const MOCK = 'mock'; + const IE_HTA = 'iehta'; + const ANDROID = 'android'; + const HTMLUNIT = 'htmlunit'; + const IE = 'internet explorer'; + const IPHONE = 'iphone'; + const IPAD = 'iPad'; + const PHANTOMJS = 'phantomjs'; - const ANDROID = "android"; - const HTMLUNIT = "htmlunit"; - const IE = "internet explorer"; - const IPHONE = "iphone"; - const IPAD = "iPad"; - const PHANTOMJS = "phantomjs"; - - private function __construct() - { - } + private function __construct() + { + } } diff --git a/lib/Remote/WebDriverCapabilityType.php b/lib/Remote/WebDriverCapabilityType.php index 459952364..131b16561 100644 --- a/lib/Remote/WebDriverCapabilityType.php +++ b/lib/Remote/WebDriverCapabilityType.php @@ -18,25 +18,26 @@ /** * WebDriverCapabilityType contains all constants defined in the WebDriver Wire Protocol. */ -class WebDriverCapabilityType { - const BROWSER_NAME = 'browserName'; - const VERSION = 'version'; - const PLATFORM = 'platform'; - const JAVASCRIPT_ENABLED = 'javascriptEnabled'; - const TAKES_SCREENSHOT = 'takesScreenshot'; - const HANDLES_ALERTS = 'handlesAlerts'; - const DATABASE_ENABLED = 'databaseEnabled'; - const LOCATION_CONTEXT_ENABLED = 'locationContextEnabled'; - const APPLICATION_CACHE_ENABLED = 'applicationCacheEnabled'; - const BROWSER_CONNECTION_ENABLED = 'browserConnectionEnabled'; - const CSS_SELECTORS_ENABLED = 'cssSelectorsEnabled'; - const WEB_STORAGE_ENABLED = 'webStorageEnabled'; - const ROTATABLE = 'rotatable'; - const ACCEPT_SSL_CERTS = 'acceptSslCerts'; - const NATIVE_EVENTS = 'nativeEvents'; - const PROXY = 'proxy'; +class WebDriverCapabilityType +{ + const BROWSER_NAME = 'browserName'; + const VERSION = 'version'; + const PLATFORM = 'platform'; + const JAVASCRIPT_ENABLED = 'javascriptEnabled'; + const TAKES_SCREENSHOT = 'takesScreenshot'; + const HANDLES_ALERTS = 'handlesAlerts'; + const DATABASE_ENABLED = 'databaseEnabled'; + const LOCATION_CONTEXT_ENABLED = 'locationContextEnabled'; + const APPLICATION_CACHE_ENABLED = 'applicationCacheEnabled'; + const BROWSER_CONNECTION_ENABLED = 'browserConnectionEnabled'; + const CSS_SELECTORS_ENABLED = 'cssSelectorsEnabled'; + const WEB_STORAGE_ENABLED = 'webStorageEnabled'; + const ROTATABLE = 'rotatable'; + const ACCEPT_SSL_CERTS = 'acceptSslCerts'; + const NATIVE_EVENTS = 'nativeEvents'; + const PROXY = 'proxy'; - private function __construct() - { - } + private function __construct() + { + } } diff --git a/lib/Remote/WebDriverCommand.php b/lib/Remote/WebDriverCommand.php index cb90d2b64..b801b0645 100644 --- a/lib/Remote/WebDriverCommand.php +++ b/lib/Remote/WebDriverCommand.php @@ -15,43 +15,48 @@ namespace Facebook\WebDriver\Remote; -class WebDriverCommand { - /** @var string */ - private $sessionID; - /** @var string */ - private $name; - /** @var array */ - private $parameters; +class WebDriverCommand +{ + /** @var string */ + private $sessionID; + /** @var string */ + private $name; + /** @var array */ + private $parameters; - /** - * @param string $session_id - * @param string $name Constant from DriverCommand - * @param array $parameters Array of - */ - public function __construct($session_id, $name, $parameters) { - $this->sessionID = $session_id; - $this->name = $name; - $this->parameters = $parameters; - } + /** + * @param string $session_id + * @param string $name Constant from DriverCommand + * @param array $parameters Array of + */ + public function __construct($session_id, $name, $parameters) + { + $this->sessionID = $session_id; + $this->name = $name; + $this->parameters = $parameters; + } - /** - * @return string - */ - public function getName() { - return $this->name; - } + /** + * @return string + */ + public function getName() + { + return $this->name; + } - /** - * @return string - */ - public function getSessionID() { - return $this->sessionID; - } + /** + * @return string + */ + public function getSessionID() + { + return $this->sessionID; + } - /** - * @return array - */ - public function getParameters() { - return $this->parameters; - } + /** + * @return array + */ + public function getParameters() + { + return $this->parameters; + } } diff --git a/lib/Remote/WebDriverResponse.php b/lib/Remote/WebDriverResponse.php index d3fcdadcb..92ac6f66d 100644 --- a/lib/Remote/WebDriverResponse.php +++ b/lib/Remote/WebDriverResponse.php @@ -15,75 +15,83 @@ namespace Facebook\WebDriver\Remote; -class WebDriverResponse { +class WebDriverResponse +{ + /** + * @var int + */ + private $status; + /** + * @var mixed + */ + private $value; + /** + * @var string + */ + private $sessionID; - /** - * @var int - */ - private $status; + /** + * @param null|string $session_id + */ + public function __construct($session_id = null) + { + $this->sessionID = $session_id; + } - /** - * @var mixed - */ - private $value; + /** + * @return null|int + */ + public function getStatus() + { + return $this->status; + } - /** - * @var string - */ - private $sessionID; + /** + * @param int $status + * @return WebDriverResponse + */ + public function setStatus($status) + { + $this->status = $status; - /** - * @param null|string $session_id - */ - public function __construct($session_id = null) { - $this->sessionID = $session_id; - } + return $this; + } - /** - * @return null|int - */ - public function getStatus() { - return $this->status; - } + /** + * @return mixed + */ + public function getValue() + { + return $this->value; + } - /** - * @param int $status - * @return WebDriverResponse - */ - public function setStatus($status) { - $this->status = $status; - return $this; - } + /** + * @param mixed $value + * @return WebDriverResponse + */ + public function setValue($value) + { + $this->value = $value; - /** - * @return mixed - */ - public function getValue() { - return $this->value; - } + return $this; + } - /** - * @param mixed $value - * @return WebDriverResponse - */ - public function setValue($value) { - $this->value = $value; - return $this; - } + /** + * @return null|string + */ + public function getSessionID() + { + return $this->sessionID; + } - /** - * @return null|string - */ - public function getSessionID() { - return $this->sessionID; - } + /** + * @param mixed $session_id + * @return WebDriverResponse + */ + public function setSessionID($session_id) + { + $this->sessionID = $session_id; - /** - * @param mixed $session_id - * @return WebDriverResponse - */ - public function setSessionID($session_id) { - $this->sessionID = $session_id; - return $this; - } + return $this; + } } diff --git a/lib/Support/Events/EventFiringWebDriver.php b/lib/Support/Events/EventFiringWebDriver.php index ab279cb1d..7ea2242b0 100644 --- a/lib/Support/Events/EventFiringWebDriver.php +++ b/lib/Support/Events/EventFiringWebDriver.php @@ -27,339 +27,367 @@ use Facebook\WebDriver\WebDriverTargetLocator; use Facebook\WebDriver\WebDriverWait; -class EventFiringWebDriver implements WebDriver, JavaScriptExecutor { - - /** - * @var WebDriver - */ - protected $driver; - - /** - * @var WebDriverDispatcher - */ - protected $dispatcher; - - /** - * @param WebDriver $driver - * @param WebDriverDispatcher $dispatcher - */ - public function __construct(WebDriver $driver, - WebDriverDispatcher $dispatcher = null) { - $this->dispatcher = $dispatcher ?: new WebDriverDispatcher(); - if (!$this->dispatcher->getDefaultDriver()) { - $this->dispatcher->setDefaultDriver($this); +class EventFiringWebDriver implements WebDriver, JavaScriptExecutor +{ + /** + * @var WebDriver + */ + protected $driver; + + /** + * @var WebDriverDispatcher + */ + protected $dispatcher; + + /** + * @param WebDriver $driver + * @param WebDriverDispatcher $dispatcher + */ + public function __construct(WebDriver $driver, WebDriverDispatcher $dispatcher = null) + { + $this->dispatcher = $dispatcher ?: new WebDriverDispatcher(); + if (!$this->dispatcher->getDefaultDriver()) { + $this->dispatcher->setDefaultDriver($this); + } + $this->driver = $driver; + + return $this; } - $this->driver = $driver; - return $this; - } - - /** - * @return WebDriverDispatcher - */ - public function getDispatcher() { - return $this->dispatcher; - } - - /** - * @param mixed $method - * @return void - */ - protected function dispatch($method) { - if (!$this->dispatcher) { - return; + + /** + * @return WebDriverDispatcher + */ + public function getDispatcher() + { + return $this->dispatcher; } - $arguments = func_get_args(); - unset($arguments[0]); - $this->dispatcher->dispatch($method, $arguments); - } - - /** - * @return WebDriver - */ - public function getWebDriver() { - return $this->driver; - } - - /** - * @param WebDriverElement $element - * @return EventFiringWebElement - */ - protected function newElement(WebDriverElement $element) { - return new EventFiringWebElement($element, $this->getDispatcher()); - } - - /** - * @param mixed $url - * @return $this - * @throws WebDriverException - */ - public function get($url) { - $this->dispatch('beforeNavigateTo', $url, $this); - try { - $this->driver->get($url); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + /** + * @param mixed $method + */ + protected function dispatch($method) + { + if (!$this->dispatcher) { + return; + } + + $arguments = func_get_args(); + unset($arguments[0]); + $this->dispatcher->dispatch($method, $arguments); } - $this->dispatch('afterNavigateTo', $url, $this); - return $this; - } - - /** - * @param WebDriverBy $by - * @return array - * @throws WebDriverException - */ - public function findElements(WebDriverBy $by) { - $this->dispatch('beforeFindBy', $by, null, $this); - try { - $elements = array(); - foreach ($this->driver->findElements($by) as $element) { - $elements[] = $this->newElement($element); - } - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @return WebDriver + */ + public function getWebDriver() + { + return $this->driver; } - $this->dispatch('afterFindBy', $by, null, $this); - return $elements; - - } - - /** - * @param WebDriverBy $by - * @return EventFiringWebElement - * @throws WebDriverException - */ - public function findElement(WebDriverBy $by) { - $this->dispatch('beforeFindBy', $by, null, $this); - try { - $element = $this->newElement($this->driver->findElement($by)); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @param WebDriverElement $element + * @return EventFiringWebElement + */ + protected function newElement(WebDriverElement $element) + { + return new EventFiringWebElement($element, $this->getDispatcher()); } - $this->dispatch('afterFindBy', $by, null, $this); - return $element; - } - - /** - * @param $script - * @param array $arguments - * @return mixed - * @throws WebDriverException - */ - public function executeScript($script, array $arguments = array()) { - if (!$this->driver instanceof JavaScriptExecutor) { - throw new UnsupportedOperationException( - 'driver does not implement JavaScriptExecutor' - ); + + /** + * @param mixed $url + * @throws WebDriverException + * @return $this + */ + public function get($url) + { + $this->dispatch('beforeNavigateTo', $url, $this); + try { + $this->driver->get($url); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch('afterNavigateTo', $url, $this); + + return $this; } - $this->dispatch('beforeScript', $script, $this); - try { - $result = $this->driver->executeScript($script, $arguments); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + /** + * @param WebDriverBy $by + * @throws WebDriverException + * @return array + */ + public function findElements(WebDriverBy $by) + { + $this->dispatch('beforeFindBy', $by, null, $this); + try { + $elements = array(); + foreach ($this->driver->findElements($by) as $element) { + $elements[] = $this->newElement($element); + } + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch('afterFindBy', $by, null, $this); + + return $elements; } - $this->dispatch('afterScript', $script, $this); - return $result; - } - - /** - * @param $script - * @param array $arguments - * @return mixed - * @throws WebDriverException - */ - public function executeAsyncScript($script, array $arguments = array()) { - if (!$this->driver instanceof JavaScriptExecutor) { - throw new UnsupportedOperationException( - 'driver does not implement JavaScriptExecutor' - ); + + /** + * @param WebDriverBy $by + * @throws WebDriverException + * @return EventFiringWebElement + */ + public function findElement(WebDriverBy $by) + { + $this->dispatch('beforeFindBy', $by, null, $this); + try { + $element = $this->newElement($this->driver->findElement($by)); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch('afterFindBy', $by, null, $this); + + return $element; } - $this->dispatch('beforeScript', $script, $this); - try { - $result = $this->driver->executeAsyncScript($script, $arguments); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + /** + * @param $script + * @param array $arguments + * @throws WebDriverException + * @return mixed + */ + public function executeScript($script, array $arguments = array()) + { + if (!$this->driver instanceof JavaScriptExecutor) { + throw new UnsupportedOperationException( + 'driver does not implement JavaScriptExecutor' + ); + } + + $this->dispatch('beforeScript', $script, $this); + try { + $result = $this->driver->executeScript($script, $arguments); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch('afterScript', $script, $this); + + return $result; } - $this->dispatch('afterScript', $script, $this); - return $result; - } - - /** - * @return $this - * @throws WebDriverException - */ - public function close() { - try { - $this->driver->close(); - return $this; - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @param $script + * @param array $arguments + * @throws WebDriverException + * @return mixed + */ + public function executeAsyncScript($script, array $arguments = array()) + { + if (!$this->driver instanceof JavaScriptExecutor) { + throw new UnsupportedOperationException( + 'driver does not implement JavaScriptExecutor' + ); + } + + $this->dispatch('beforeScript', $script, $this); + try { + $result = $this->driver->executeAsyncScript($script, $arguments); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch('afterScript', $script, $this); + + return $result; } - } - - /** - * @return string - * @throws WebDriverException - */ - public function getCurrentURL() { - try { - return $this->driver->getCurrentURL(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + * @return $this + */ + public function close() + { + try { + $this->driver->close(); + + return $this; + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - /** - * @return string - * @throws WebDriverException - */ - public function getPageSource() { - try { - return $this->driver->getPageSource(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + * @return string + */ + public function getCurrentURL() + { + try { + return $this->driver->getCurrentURL(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - /** - * @return string - * @throws WebDriverException - */ - public function getTitle() { - try { - return $this->driver->getTitle(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + * @return string + */ + public function getPageSource() + { + try { + return $this->driver->getPageSource(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - /** - * @return string - * @throws WebDriverException - */ - public function getWindowHandle() { - try { - return $this->driver->getWindowHandle(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + * @return string + */ + public function getTitle() + { + try { + return $this->driver->getTitle(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - /** - * @return array - * @throws WebDriverException - */ - public function getWindowHandles() { - try { - return $this->driver->getWindowHandles(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + * @return string + */ + public function getWindowHandle() + { + try { + return $this->driver->getWindowHandle(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - /** - * @throws WebDriverException - */ - public function quit() { - try { - $this->driver->quit(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + * @return array + */ + public function getWindowHandles() + { + try { + return $this->driver->getWindowHandles(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - /** - * @param null|string $save_as - * @return string - * @throws WebDriverException - */ - public function takeScreenshot($save_as = null) { - try { - return $this->driver->takeScreenshot($save_as); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + */ + public function quit() + { + try { + $this->driver->quit(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - /** - * @param int $timeout_in_second - * @param int $interval_in_millisecond - * @return WebDriverWait - * @throws WebDriverException - */ - public function wait($timeout_in_second = 30, - $interval_in_millisecond = 250) { - try { - return $this->driver->wait($timeout_in_second, $interval_in_millisecond); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @param null|string $save_as + * @throws WebDriverException + * @return string + */ + public function takeScreenshot($save_as = null) + { + try { + return $this->driver->takeScreenshot($save_as); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - /** - * @return WebDriverOptions - * @throws WebDriverException - */ - public function manage() { - try { - return $this->driver->manage(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @param int $timeout_in_second + * @param int $interval_in_millisecond + * @throws WebDriverException + * @return WebDriverWait + */ + public function wait($timeout_in_second = 30, $interval_in_millisecond = 250) + { + try { + return $this->driver->wait($timeout_in_second, $interval_in_millisecond); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - /** - * @return EventFiringWebDriverNavigation - * @throws WebDriverException - */ - public function navigate() { - try { - return new EventFiringWebDriverNavigation( - $this->driver->navigate(), - $this->getDispatcher() - ); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + * @return WebDriverOptions + */ + public function manage() + { + try { + return $this->driver->manage(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - /** - * @return WebDriverTargetLocator - * @throws WebDriverException - */ - public function switchTo() { - try { - return $this->driver->switchTo(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + * @return EventFiringWebDriverNavigation + */ + public function navigate() + { + try { + return new EventFiringWebDriverNavigation( + $this->driver->navigate(), + $this->getDispatcher() + ); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - /** - * @return WebDriverTouchScreen - * @throws WebDriverException - */ - public function getTouch() { - try { - return $this->driver->getTouch(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + * @return WebDriverTargetLocator + */ + public function switchTo() + { + try { + return $this->driver->switchTo(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - private function dispatchOnException($exception) { - $this->dispatch('onException', $exception, $this); - throw $exception; - } - - public function execute($name, $params) { - try { - return $this->driver->execute($name, $params); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + * @return WebDriverTouchScreen + */ + public function getTouch() + { + try { + return $this->driver->getTouch(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + private function dispatchOnException($exception) + { + $this->dispatch('onException', $exception, $this); + throw $exception; + } + + public function execute($name, $params) + { + try { + return $this->driver->execute($name, $params); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } } diff --git a/lib/Support/Events/EventFiringWebDriverNavigation.php b/lib/Support/Events/EventFiringWebDriverNavigation.php index 56341e2c2..a588d5e17 100644 --- a/lib/Support/Events/EventFiringWebDriverNavigation.php +++ b/lib/Support/Events/EventFiringWebDriverNavigation.php @@ -19,138 +19,149 @@ use Facebook\WebDriver\WebDriverDispatcher; use Facebook\WebDriver\WebDriverNavigation; -class EventFiringWebDriverNavigation { - - /** - * @var WebDriverNavigation - */ - protected $navigator; - - /** - * @var WebDriverDispatcher - */ - protected $dispatcher; - - /** - * @param WebDriverNavigation $navigator - * @param WebDriverDispatcher $dispatcher - */ - public function __construct(WebDriverNavigation $navigator, - WebDriverDispatcher $dispatcher) { - $this->navigator = $navigator; - $this->dispatcher = $dispatcher; - return $this; - } - - /** - * @return WebDriverDispatcher - */ - public function getDispatcher() { - return $this->dispatcher; - } - - /** - * @param mixed $method - * @return void - */ - protected function dispatch($method) { - if (!$this->dispatcher) { - return; +class EventFiringWebDriverNavigation +{ + /** + * @var WebDriverNavigation + */ + protected $navigator; + /** + * @var WebDriverDispatcher + */ + protected $dispatcher; + + /** + * @param WebDriverNavigation $navigator + * @param WebDriverDispatcher $dispatcher + */ + public function __construct(WebDriverNavigation $navigator, WebDriverDispatcher $dispatcher) + { + $this->navigator = $navigator; + $this->dispatcher = $dispatcher; + + return $this; + } + + /** + * @return WebDriverDispatcher + */ + public function getDispatcher() + { + return $this->dispatcher; + } + + /** + * @param mixed $method + */ + protected function dispatch($method) + { + if (!$this->dispatcher) { + return; + } + + $arguments = func_get_args(); + unset($arguments[0]); + $this->dispatcher->dispatch($method, $arguments); + } + + /** + * @return WebDriverNavigation + */ + public function getNavigator() + { + return $this->navigator; } - $arguments = func_get_args(); - unset($arguments[0]); - $this->dispatcher->dispatch($method, $arguments); - } - - /** - * @return WebDriverNavigation - */ - public function getNavigator() { - return $this->navigator; - } - - /** - * @return $this - * @throws WebDriverException - */ - public function back() { - $this->dispatch( - 'beforeNavigateBack', - $this->getDispatcher()->getDefaultDriver() - ); - try { - $this->navigator->back(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + /** + * @throws WebDriverException + * @return $this + */ + public function back() + { + $this->dispatch( + 'beforeNavigateBack', + $this->getDispatcher()->getDefaultDriver() + ); + try { + $this->navigator->back(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch( + 'afterNavigateBack', + $this->getDispatcher()->getDefaultDriver() + ); + + return $this; } - $this->dispatch( - 'afterNavigateBack', - $this->getDispatcher()->getDefaultDriver() - ); - return $this; - } - - /** - * @return $this - * @throws WebDriverException - */ - public function forward() { - $this->dispatch( - 'beforeNavigateForward', - $this->getDispatcher()->getDefaultDriver() - ); - try { - $this->navigator->forward(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + * @return $this + */ + public function forward() + { + $this->dispatch( + 'beforeNavigateForward', + $this->getDispatcher()->getDefaultDriver() + ); + try { + $this->navigator->forward(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch( + 'afterNavigateForward', + $this->getDispatcher()->getDefaultDriver() + ); + + return $this; } - $this->dispatch( - 'afterNavigateForward', - $this->getDispatcher()->getDefaultDriver() - ); - return $this; - } - - /** - * @return $this - * @throws WebDriverException - */ - public function refresh() { - try { - $this->navigator->refresh(); - return $this; - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + * @return $this + */ + public function refresh() + { + try { + $this->navigator->refresh(); + + return $this; + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - /** - * @param mixed $url - * @return $this - * @throws WebDriverException - */ - public function to($url) { - $this->dispatch( - 'beforeNavigateTo', - $url, - $this->getDispatcher()->getDefaultDriver() - ); - try { - $this->navigator->to($url); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @param mixed $url + * @throws WebDriverException + * @return $this + */ + public function to($url) + { + $this->dispatch( + 'beforeNavigateTo', + $url, + $this->getDispatcher()->getDefaultDriver() + ); + try { + $this->navigator->to($url); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch( + 'afterNavigateTo', + $url, + $this->getDispatcher()->getDefaultDriver() + ); + + return $this; + } + + private function dispatchOnException($exception) + { + $this->dispatch('onException', $exception); + throw $exception; } - $this->dispatch( - 'afterNavigateTo', - $url, - $this->getDispatcher()->getDefaultDriver() - ); - return $this; - } - - private function dispatchOnException($exception) { - $this->dispatch('onException', $exception); - throw $exception; - } } diff --git a/lib/Support/Events/EventFiringWebElement.php b/lib/Support/Events/EventFiringWebElement.php index 3025bd8ba..8f6f20d81 100644 --- a/lib/Support/Events/EventFiringWebElement.php +++ b/lib/Support/Events/EventFiringWebElement.php @@ -24,346 +24,370 @@ use Facebook\WebDriver\WebDriverElement; use Facebook\WebDriver\WebDriverPoint; -class EventFiringWebElement implements WebDriverElement, WebDriverLocatable { - - /** - * @var WebDriverElement - */ - protected $element; - - /** - * @var WebDriverDispatcher - */ - protected $dispatcher; - - /** - * @param WebDriverElement $element - * @param WebDriverDispatcher $dispatcher - */ - public function __construct(WebDriverElement $element, - WebDriverDispatcher $dispatcher) { - $this->element = $element; - $this->dispatcher = $dispatcher; - return $this; - } - - /** - * @return WebDriverDispatcher - */ - public function getDispatcher() { - return $this->dispatcher; - } - - /** - * @param mixed $method - * @return void - */ - protected function dispatch($method) { - if (!$this->dispatcher) { - return; +class EventFiringWebElement implements WebDriverElement, WebDriverLocatable +{ + /** + * @var WebDriverElement + */ + protected $element; + /** + * @var WebDriverDispatcher + */ + protected $dispatcher; + + /** + * @param WebDriverElement $element + * @param WebDriverDispatcher $dispatcher + */ + public function __construct(WebDriverElement $element, WebDriverDispatcher $dispatcher) + { + $this->element = $element; + $this->dispatcher = $dispatcher; + + return $this; } - $arguments = func_get_args(); - unset($arguments[0]); - $this->dispatcher->dispatch($method, $arguments); - } - - /** - * @return WebDriverElement - */ - public function getElement() { - return $this->element; - } - - /** - * @param WebDriverElement $element - * @return EventFiringWebElement - */ - protected function newElement(WebDriverElement $element) { - return new static($element, $this->getDispatcher()); - } - - /** - * @param mixed $value - * @return $this - * @throws WebDriverException - */ - public function sendKeys($value) { - - $this->dispatch('beforeChangeValueOf', $this); - try { - $this->element->sendKeys($value); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @return WebDriverDispatcher + */ + public function getDispatcher() + { + return $this->dispatcher; } - $this->dispatch('afterChangeValueOf', $this); - return $this; - - } - - /** - * @return $this - * @throws WebDriverException - */ - public function click() { - $this->dispatch('beforeClickOn', $this); - try { - $this->element->click(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @param mixed $method + */ + protected function dispatch($method) + { + if (!$this->dispatcher) { + return; + } + $arguments = func_get_args(); + unset($arguments[0]); + $this->dispatcher->dispatch($method, $arguments); } - $this->dispatch('afterClickOn', $this); - return $this; - } - - /** - * @param WebDriverBy $by - * @return EventFiringWebElement - * @throws WebDriverException - */ - public function findElement(WebDriverBy $by) { - $this->dispatch( - 'beforeFindBy', - $by, - $this, - $this->dispatcher->getDefaultDriver()); - try { - $element = $this->newElement($this->element->findElement($by)); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @return WebDriverElement + */ + public function getElement() + { + return $this->element; } - $this->dispatch( - 'afterFindBy', - $by, - $this, - $this->dispatcher->getDefaultDriver() - ); - return $element; - } - - /** - * @param WebDriverBy $by - * @return array - * @throws WebDriverException - */ - public function findElements(WebDriverBy $by) { - $this->dispatch( - 'beforeFindBy', - $by, - $this, - $this->dispatcher->getDefaultDriver() - ); - try { - $elements = array(); - foreach ($this->element->findElements($by) as $element) { - $elements[] = $this->newElement($element); - } - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @param WebDriverElement $element + * @return EventFiringWebElement + */ + protected function newElement(WebDriverElement $element) + { + return new static($element, $this->getDispatcher()); } - $this->dispatch( - 'afterFindBy', - $by, - $this, - $this->dispatcher->getDefaultDriver() - ); - return $elements; - } - - /** - * @return $this - * @throws WebDriverException - */ - public function clear() { - try { - $this->element->clear(); - return $this; - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @param mixed $value + * @throws WebDriverException + * @return $this + */ + public function sendKeys($value) + { + $this->dispatch('beforeChangeValueOf', $this); + try { + $this->element->sendKeys($value); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch('afterChangeValueOf', $this); + + return $this; } - } - - /** - * @param string $attribute_name - * @return string - * @throws WebDriverException - */ - public function getAttribute($attribute_name) { - try { - return $this->element->getAttribute($attribute_name); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + * @return $this + */ + public function click() + { + $this->dispatch('beforeClickOn', $this); + try { + $this->element->click(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch('afterClickOn', $this); + + return $this; } - } - - /** - * @param string $css_property_name - * @return string - * @throws WebDriverException - */ - public function getCSSValue($css_property_name) { - try { - return $this->element->getCSSValue($css_property_name); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @param WebDriverBy $by + * @throws WebDriverException + * @return EventFiringWebElement + */ + public function findElement(WebDriverBy $by) + { + $this->dispatch( + 'beforeFindBy', + $by, + $this, + $this->dispatcher->getDefaultDriver() + ); + try { + $element = $this->newElement($this->element->findElement($by)); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch( + 'afterFindBy', + $by, + $this, + $this->dispatcher->getDefaultDriver() + ); + + return $element; } - } - - /** - * @return WebDriverPoint - * @throws WebDriverException - */ - public function getLocation() { - try { - return $this->element->getLocation(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @param WebDriverBy $by + * @throws WebDriverException + * @return array + */ + public function findElements(WebDriverBy $by) + { + $this->dispatch( + 'beforeFindBy', + $by, + $this, + $this->dispatcher->getDefaultDriver() + ); + try { + $elements = array(); + foreach ($this->element->findElements($by) as $element) { + $elements[] = $this->newElement($element); + } + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + $this->dispatch( + 'afterFindBy', + $by, + $this, + $this->dispatcher->getDefaultDriver() + ); + + return $elements; + } + + /** + * @throws WebDriverException + * @return $this + */ + public function clear() + { + try { + $this->element->clear(); + + return $this; + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - /** - * @return WebDriverPoint - * @throws WebDriverException - */ - public function getLocationOnScreenOnceScrolledIntoView() { - try { - return $this->element->getLocationOnScreenOnceScrolledIntoView(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @param string $attribute_name + * @throws WebDriverException + * @return string + */ + public function getAttribute($attribute_name) + { + try { + return $this->element->getAttribute($attribute_name); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + + /** + * @param string $css_property_name + * @throws WebDriverException + * @return string + */ + public function getCSSValue($css_property_name) + { + try { + return $this->element->getCSSValue($css_property_name); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - /** - * @return WebDriverCoordinates - */ - public function getCoordinates() { - try { - return $this->element->getCoordinates(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + * @return WebDriverPoint + */ + public function getLocation() + { + try { + return $this->element->getLocation(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - - /** - * @return WebDriverDimension - * @throws WebDriverException - */ - public function getSize() { - try { - return $this->element->getSize(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + * @return WebDriverPoint + */ + public function getLocationOnScreenOnceScrolledIntoView() + { + try { + return $this->element->getLocationOnScreenOnceScrolledIntoView(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - /** - * @return string - * @throws WebDriverException - */ - public function getTagName() { - try { - return $this->element->getTagName(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @return WebDriverCoordinates + */ + public function getCoordinates() + { + try { + return $this->element->getCoordinates(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - /** - * @return string - * @throws WebDriverException - */ - public function getText() { - try { - return $this->element->getText(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + * @return WebDriverDimension + */ + public function getSize() + { + try { + return $this->element->getSize(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - /** - * @return bool - * @throws WebDriverException - */ - public function isDisplayed() { - try { - return $this->element->isDisplayed(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + * @return string + */ + public function getTagName() + { + try { + return $this->element->getTagName(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - /** - * @return bool - * @throws WebDriverException - */ - public function isEnabled() { - try { - return $this->element->isEnabled(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + * @return string + */ + public function getText() + { + try { + return $this->element->getText(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - /** - * @return bool - * @throws WebDriverException - */ - public function isSelected() { - try { - return $this->element->isSelected(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + * @return bool + */ + public function isDisplayed() + { + try { + return $this->element->isDisplayed(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - /** - * @return $this - * @throws WebDriverException - */ - public function submit() { - try { - $this->element->submit(); - return $this; - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + * @return bool + */ + public function isEnabled() + { + try { + return $this->element->isEnabled(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - /** - * @return string - * @throws WebDriverException - */ - public function getID() { - try { - return $this->element->getID(); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + * @return bool + */ + public function isSelected() + { + try { + return $this->element->isSelected(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - - - /** - * Test if two element IDs refer to the same DOM element. - * - * @param WebDriverElement $other - * @return bool - */ - public function equals(WebDriverElement $other) { - try { - return $this->element->equals($other); - } catch (WebDriverException $exception) { - $this->dispatchOnException($exception); + + /** + * @throws WebDriverException + * @return $this + */ + public function submit() + { + try { + $this->element->submit(); + + return $this; + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } } - } - private function dispatchOnException($exception) { - $this->dispatch( - 'onException', - $exception, - $this->dispatcher->getDefaultDriver() - ); - throw $exception; - } + /** + * @throws WebDriverException + * @return string + */ + public function getID() + { + try { + return $this->element->getID(); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + /** + * Test if two element IDs refer to the same DOM element. + * + * @param WebDriverElement $other + * @return bool + */ + public function equals(WebDriverElement $other) + { + try { + return $this->element->equals($other); + } catch (WebDriverException $exception) { + $this->dispatchOnException($exception); + } + } + private function dispatchOnException($exception) + { + $this->dispatch( + 'onException', + $exception, + $this->dispatcher->getDefaultDriver() + ); + throw $exception; + } } diff --git a/lib/WebDriver.php b/lib/WebDriver.php index b143583ca..85e8c1931 100755 --- a/lib/WebDriver.php +++ b/lib/WebDriver.php @@ -18,119 +18,118 @@ /** * The interface for WebDriver. */ -interface WebDriver extends WebDriverSearchContext { - - /** - * Close the current window. - * - * @return WebDriver The current instance. - */ - public function close(); - - /** - * Load a new web page in the current browser window. - * - * @param string $url - * @return WebDriver The current instance. - */ - public function get($url); - - /** - * Get a string representing the current URL that the browser is looking at. - * - * @return string The current URL. - */ - public function getCurrentURL(); - - /** - * Get the source of the last loaded page. - * - * @return string The current page source. - */ - public function getPageSource(); - - /** - * Get the title of the current page. - * - * @return string The title of the current page. - */ - public function getTitle(); - - /** - * Return an opaque handle to this window that uniquely identifies it within - * this driver instance. - * - * @return string The current window handle. - */ - public function getWindowHandle(); - - /** - * Get all window handles available to the current session. - * - * @return array An array of string containing all available window handles. - */ - public function getWindowHandles(); - - /** - * Quits this driver, closing every associated window. - * - * @return void - */ - public function quit(); - - /** - * Take a screenshot of the current page. - * - * @param string $save_as The path of the screenshot to be saved. - * @return string The screenshot in PNG format. - */ - public function takeScreenshot($save_as = null); - - /** - * Construct a new WebDriverWait by the current WebDriver instance. - * Sample usage: - * - * $driver->wait(20, 1000)->until( - * WebDriverExpectedCondition::titleIs('WebDriver Page') - * ); - * - * @param int $timeout_in_second - * @param int $interval_in_millisecond - * @return WebDriverWait - */ - public function wait( - $timeout_in_second = 30, - $interval_in_millisecond = 250); - - /** - * An abstraction for managing stuff you would do in a browser menu. For - * example, adding and deleting cookies. - * - * @return WebDriverOptions - */ - public function manage(); - - /** - * An abstraction allowing the driver to access the browser's history and to - * navigate to a given URL. - * - * @return WebDriverNavigation - * @see WebDriverNavigation - */ - public function navigate(); - - /** - * Switch to a different window or frame. - * - * @return WebDriverTargetLocator - * @see WebDriverTargetLocator - */ - public function switchTo(); - - /** - * @param string $name - * @param array $params - * @return mixed - */ - public function execute($name, $params); +interface WebDriver extends WebDriverSearchContext +{ + /** + * Close the current window. + * + * @return WebDriver The current instance. + */ + public function close(); + + /** + * Load a new web page in the current browser window. + * + * @param string $url + * @return WebDriver The current instance. + */ + public function get($url); + + /** + * Get a string representing the current URL that the browser is looking at. + * + * @return string The current URL. + */ + public function getCurrentURL(); + + /** + * Get the source of the last loaded page. + * + * @return string The current page source. + */ + public function getPageSource(); + + /** + * Get the title of the current page. + * + * @return string The title of the current page. + */ + public function getTitle(); + + /** + * Return an opaque handle to this window that uniquely identifies it within + * this driver instance. + * + * @return string The current window handle. + */ + public function getWindowHandle(); + + /** + * Get all window handles available to the current session. + * + * @return array An array of string containing all available window handles. + */ + public function getWindowHandles(); + + /** + * Quits this driver, closing every associated window. + */ + public function quit(); + + /** + * Take a screenshot of the current page. + * + * @param string $save_as The path of the screenshot to be saved. + * @return string The screenshot in PNG format. + */ + public function takeScreenshot($save_as = null); + + /** + * Construct a new WebDriverWait by the current WebDriver instance. + * Sample usage: + * + * $driver->wait(20, 1000)->until( + * WebDriverExpectedCondition::titleIs('WebDriver Page') + * ); + * + * @param int $timeout_in_second + * @param int $interval_in_millisecond + * @return WebDriverWait + */ + public function wait( + $timeout_in_second = 30, + $interval_in_millisecond = 250 + ); + + /** + * An abstraction for managing stuff you would do in a browser menu. For + * example, adding and deleting cookies. + * + * @return WebDriverOptions + */ + public function manage(); + + /** + * An abstraction allowing the driver to access the browser's history and to + * navigate to a given URL. + * + * @return WebDriverNavigation + * @see WebDriverNavigation + */ + public function navigate(); + + /** + * Switch to a different window or frame. + * + * @return WebDriverTargetLocator + * @see WebDriverTargetLocator + */ + public function switchTo(); + + /** + * @param string $name + * @param array $params + * @return mixed + */ + public function execute($name, $params); } diff --git a/lib/WebDriverAction.php b/lib/WebDriverAction.php index a5d2d32d8..e73b883ad 100644 --- a/lib/WebDriverAction.php +++ b/lib/WebDriverAction.php @@ -18,10 +18,9 @@ /** * Interface representing a single user-interaction action. */ -interface WebDriverAction { - - /** - * @return void - */ - public function perform(); +interface WebDriverAction +{ + /** + */ + public function perform(); } diff --git a/lib/WebDriverAlert.php b/lib/WebDriverAlert.php index 8bef6d846..4ba9f6168 100644 --- a/lib/WebDriverAlert.php +++ b/lib/WebDriverAlert.php @@ -20,55 +20,62 @@ /** * An abstraction allowing the driver to manipulate the javascript alerts */ -class WebDriverAlert { +class WebDriverAlert +{ + protected $executor; - protected $executor; + public function __construct($executor) + { + $this->executor = $executor; + } - public function __construct($executor) { - $this->executor = $executor; - } + /** + * Accept alert + * + * @return WebDriverAlert The instance. + */ + public function accept() + { + $this->executor->execute(DriverCommand::ACCEPT_ALERT); - /** - * Accept alert - * - * @return WebDriverAlert The instance. - */ - public function accept() { - $this->executor->execute(DriverCommand::ACCEPT_ALERT); - return $this; - } + return $this; + } - /** - * Dismiss alert - * - * @return WebDriverAlert The instance. - */ - public function dismiss() { - $this->executor->execute(DriverCommand::DISMISS_ALERT); - return $this; - } + /** + * Dismiss alert + * + * @return WebDriverAlert The instance. + */ + public function dismiss() + { + $this->executor->execute(DriverCommand::DISMISS_ALERT); - /** - * Get alert text - * - * @return string - */ - public function getText() { - return $this->executor->execute(DriverCommand::GET_ALERT_TEXT); - } + return $this; + } - /** - * Send keystrokes to javascript prompt() dialog - * - * @param string $value - * @return WebDriverAlert - */ - public function sendKeys($value) { - $this->executor->execute( - DriverCommand::SET_ALERT_VALUE, - array('text' => $value) - ); - return $this; - } + /** + * Get alert text + * + * @return string + */ + public function getText() + { + return $this->executor->execute(DriverCommand::GET_ALERT_TEXT); + } + /** + * Send keystrokes to javascript prompt() dialog + * + * @param string $value + * @return WebDriverAlert + */ + public function sendKeys($value) + { + $this->executor->execute( + DriverCommand::SET_ALERT_VALUE, + array('text' => $value) + ); + + return $this; + } } diff --git a/lib/WebDriverBy.php b/lib/WebDriverBy.php index c409768a8..92242ae56 100644 --- a/lib/WebDriverBy.php +++ b/lib/WebDriverBy.php @@ -22,109 +22,120 @@ * * @see WebDriver::findElement, WebDriverElement::findElement */ -class WebDriverBy { +class WebDriverBy +{ + private $mechanism; + private $value; - private $mechanism; - private $value; + protected function __construct($mechanism, $value) + { + $this->mechanism = $mechanism; + $this->value = $value; + } - protected function __construct($mechanism, $value) { - $this->mechanism = $mechanism; - $this->value = $value; - } + /** + * @return string + */ + public function getMechanism() + { + return $this->mechanism; + } - /** - * @return string - */ - public function getMechanism() { - return $this->mechanism; - } + /** + * @return string + */ + public function getValue() + { + return $this->value; + } - /** - * @return string - */ - public function getValue() { - return $this->value; - } + /** + * Locates elements whose class name contains the search value; compound class + * names are not permitted. + * + * @param string $class_name + * @return WebDriverBy + */ + public static function className($class_name) + { + return new self('class name', $class_name); + } - /** - * Locates elements whose class name contains the search value; compound class - * names are not permitted. - * - * @param string $class_name - * @return WebDriverBy - */ - public static function className($class_name) { - return new WebDriverBy('class name', $class_name); - } + /** + * Locates elements matching a CSS selector. + * + * @param string $css_selector + * @return WebDriverBy + */ + public static function cssSelector($css_selector) + { + return new self('css selector', $css_selector); + } - /** - * Locates elements matching a CSS selector. - * - * @param string $css_selector - * @return WebDriverBy - */ - public static function cssSelector($css_selector) { - return new WebDriverBy('css selector', $css_selector); - } + /** + * Locates elements whose ID attribute matches the search value. + * + * @param string $id + * @return WebDriverBy + */ + public static function id($id) + { + return new self('id', $id); + } - /** - * Locates elements whose ID attribute matches the search value. - * - * @param string $id - * @return WebDriverBy - */ - public static function id($id) { - return new WebDriverBy('id', $id); - } + /** + * Locates elements whose NAME attribute matches the search value. + * + * @param string $name + * @return WebDriverBy + */ + public static function name($name) + { + return new self('name', $name); + } - /** - * Locates elements whose NAME attribute matches the search value. - * - * @param string $name - * @return WebDriverBy - */ - public static function name($name) { - return new WebDriverBy('name', $name); - } + /** + * Locates anchor elements whose visible text matches the search value. + * + * @param string $link_text + * @return WebDriverBy + */ + public static function linkText($link_text) + { + return new self('link text', $link_text); + } - /** - * Locates anchor elements whose visible text matches the search value. - * - * @param string $link_text - * @return WebDriverBy - */ - public static function linkText($link_text) { - return new WebDriverBy('link text', $link_text); - } + /** + * Locates anchor elements whose visible text partially matches the search + * value. + * + * @param string $partial_link_text + * @return WebDriverBy + */ + public static function partialLinkText($partial_link_text) + { + return new self('partial link text', $partial_link_text); + } - /** - * Locates anchor elements whose visible text partially matches the search - * value. - * - * @param string $partial_link_text - * @return WebDriverBy - */ - public static function partialLinkText($partial_link_text) { - return new WebDriverBy('partial link text', $partial_link_text); - } + /** + * Locates elements whose tag name matches the search value. + * + * @param string $tag_name + * @return WebDriverBy + */ + public static function tagName($tag_name) + { + return new self('tag name', $tag_name); + } - /** - * Locates elements whose tag name matches the search value. - * - * @param string $tag_name - * @return WebDriverBy - */ - public static function tagName($tag_name) { - return new WebDriverBy('tag name', $tag_name); - } - - /** - * Locates elements matching an XPath expression. - * - * @param string $xpath - * @return WebDriverBy - */ - public static function xpath($xpath) { - return new WebDriverBy('xpath', $xpath); - } + /** + * Locates elements matching an XPath expression. + * + * @param string $xpath + * @return WebDriverBy + */ + public static function xpath($xpath) + { + return new self('xpath', $xpath); + } } diff --git a/lib/WebDriverCapabilities.php b/lib/WebDriverCapabilities.php index 721db82e6..6fce03c08 100644 --- a/lib/WebDriverCapabilities.php +++ b/lib/WebDriverCapabilities.php @@ -15,37 +15,37 @@ namespace Facebook\WebDriver; -interface WebDriverCapabilities { - - /** - * @return string The name of the browser. - */ - public function getBrowserName(); - - /** - * @param string $name - * @return mixed The value of a capability. - */ - public function getCapability($name); - - /** - * @return string The name of the platform. - */ - public function getPlatform(); - - /** - * @return string The version of the browser. - */ - public function getVersion(); - - /** - * @param string $capability_name - * @return bool Whether the value is not null and not false. - */ - public function is($capability_name); - - /** - * @return bool Whether javascript is enabled. - */ - public function isJavascriptEnabled(); +interface WebDriverCapabilities +{ + /** + * @return string The name of the browser. + */ + public function getBrowserName(); + + /** + * @param string $name + * @return mixed The value of a capability. + */ + public function getCapability($name); + + /** + * @return string The name of the platform. + */ + public function getPlatform(); + + /** + * @return string The version of the browser. + */ + public function getVersion(); + + /** + * @param string $capability_name + * @return bool Whether the value is not null and not false. + */ + public function is($capability_name); + + /** + * @return bool Whether javascript is enabled. + */ + public function isJavascriptEnabled(); } diff --git a/lib/WebDriverCommandExecutor.php b/lib/WebDriverCommandExecutor.php index d58998f70..00357c6e7 100644 --- a/lib/WebDriverCommandExecutor.php +++ b/lib/WebDriverCommandExecutor.php @@ -20,12 +20,12 @@ /** * Interface for all command executor. */ -interface WebDriverCommandExecutor { - - /** - * @param WebDriverCommand $command - * - * @return mixed - */ - public function execute(WebDriverCommand $command); +interface WebDriverCommandExecutor +{ + /** + * @param WebDriverCommand $command + * + * @return mixed + */ + public function execute(WebDriverCommand $command); } diff --git a/lib/WebDriverDimension.php b/lib/WebDriverDimension.php index c66278931..5b274e29a 100644 --- a/lib/WebDriverDimension.php +++ b/lib/WebDriverDimension.php @@ -18,42 +18,46 @@ /** * Represent a dimension. */ -class WebDriverDimension { +class WebDriverDimension +{ + private $height; + private $width; - private $height, $width; + public function __construct($width, $height) + { + $this->width = $width; + $this->height = $height; + } - public function __construct($width, $height) { - $this->width = $width; - $this->height = $height; - } + /** + * Get the height. + * + * @return int The height. + */ + public function getHeight() + { + return $this->height; + } - /** - * Get the height. - * - * @return int The height. - */ - public function getHeight() { - return $this->height; - } + /** + * Get the width. + * + * @return int The width. + */ + public function getWidth() + { + return $this->width; + } - /** - * Get the width. - * - * @return int The width. - */ - public function getWidth() { - return $this->width; - } - - /** - * Check whether the given dimension is the same as the instance. - * - * @param WebDriverDimension $dimension The dimension to be compared with. - * @return bool Whether the height and the width are the same as the - * instance. - */ - public function equals(WebDriverDimension $dimension) { - return $this->height === $dimension->getHeight() && - $this->width === $dimension->getWidth(); - } + /** + * Check whether the given dimension is the same as the instance. + * + * @param WebDriverDimension $dimension The dimension to be compared with. + * @return bool Whether the height and the width are the same as the + * instance. + */ + public function equals(WebDriverDimension $dimension) + { + return $this->height === $dimension->getHeight() && $this->width === $dimension->getWidth(); + } } diff --git a/lib/WebDriverDispatcher.php b/lib/WebDriverDispatcher.php index c8caea4d9..202a3ec93 100644 --- a/lib/WebDriverDispatcher.php +++ b/lib/WebDriverDispatcher.php @@ -17,68 +17,75 @@ use Facebook\WebDriver\Support\Events\EventFiringWebDriver; -class WebDriverDispatcher { +class WebDriverDispatcher +{ + /** + * @var array + */ + protected $listeners = array(); + /** + * @var EventFiringWebDriver + */ + protected $driver = null; - /** - * @var array - */ - protected $listeners = array(); + /** + * this is needed so that EventFiringWebElement can pass the driver to the + * exception handling + * + * @param EventFiringWebDriver $driver + * @return $this + */ + public function setDefaultDriver(EventFiringWebDriver $driver) + { + $this->driver = $driver; - /** - * @var EventFiringWebDriver - */ - protected $driver = null; - - /** - * this is needed so that EventFiringWebElement can pass the driver to the - * exception handling - * - * @param EventFiringWebDriver $driver - * @return $this - */ - public function setDefaultDriver(EventFiringWebDriver $driver) { - $this->driver = $driver; - return $this; - } + return $this; + } - /** - * @return null|EventFiringWebDriver - */ - public function getDefaultDriver() { - return $this->driver; - } + /** + * @return null|EventFiringWebDriver + */ + public function getDefaultDriver() + { + return $this->driver; + } - /** - * @param WebDriverEventListener $listener - * @return $this - */ - public function register(WebDriverEventListener $listener) { - $this->listeners[] = $listener; - return $this; - } + /** + * @param WebDriverEventListener $listener + * @return $this + */ + public function register(WebDriverEventListener $listener) + { + $this->listeners[] = $listener; - /** - * @param WebDriverEventListener $listener - * @return $this - */ - public function unregister(WebDriverEventListener $listener) { - $key = array_search($listener, $this->listeners, true); - if ($key !== false) { - unset($this->listeners[$key]); + return $this; } - return $this; - } - /** - * @param mixed $method - * @param mixed $arguments - * @return $this - */ - public function dispatch($method, $arguments) { - foreach ($this->listeners as $listener) { - call_user_func_array(array($listener, $method), $arguments); + /** + * @param WebDriverEventListener $listener + * @return $this + */ + public function unregister(WebDriverEventListener $listener) + { + $key = array_search($listener, $this->listeners, true); + if ($key !== false) { + unset($this->listeners[$key]); + } + + return $this; } - return $this; - } + /** + * @param mixed $method + * @param mixed $arguments + * @return $this + */ + public function dispatch($method, $arguments) + { + foreach ($this->listeners as $listener) { + call_user_func_array(array($listener, $method), $arguments); + } + + return $this; + } } diff --git a/lib/WebDriverElement.php b/lib/WebDriverElement.php index d49190604..6eb7df5c6 100644 --- a/lib/WebDriverElement.php +++ b/lib/WebDriverElement.php @@ -18,119 +18,119 @@ /** * Interface for an HTML element in the WebDriver framework. */ -interface WebDriverElement extends WebDriverSearchContext { - - /** - * If this element is a TEXTAREA or text INPUT element, this will clear the - * value. - * - * @return WebDriverElement The current instance. - */ - public function clear(); - - /** - * Click this element. - * - * @return WebDriverElement The current instance. - */ - public function click(); - - /** - * Get the value of a the given attribute of the element. - * - * @param string $attribute_name The name of the attribute. - * @return string The value of the attribute. - */ - public function getAttribute($attribute_name); - - /** - * Get the value of a given CSS property. - * - * @param string $css_property_name The name of the CSS property. - * @return string The value of the CSS property. - */ - public function getCSSValue($css_property_name); - - /** - * Get the location of element relative to the top-left corner of the page. - * - * @return WebDriverPoint The location of the element. - */ - public function getLocation(); - - /** - * Try scrolling the element into the view port and return the location of - * element relative to the top-left corner of the page afterwards. - * - * @return WebDriverPoint The location of the element. - */ - public function getLocationOnScreenOnceScrolledIntoView(); - - /** - * Get the size of element. - * - * @return WebDriverDimension The dimension of the element. - */ - public function getSize(); - - /** - * Get the tag name of this element. - * - * @return string The tag name. - */ - public function getTagName(); - - /** - * Get the visible (i.e. not hidden by CSS) innerText of this element, - * including sub-elements, without any leading or trailing whitespace. - * - * @return string The visible innerText of this element. - */ - public function getText(); - - /** - * Is this element displayed or not? This method avoids the problem of having - * to parse an element's "style" attribute. - * - * @return bool - */ - public function isDisplayed(); - - /** - * Is the element currently enabled or not? This will generally return true - * for everything but disabled input elements. - * - * @return bool - */ - public function isEnabled(); - - /** - * Determine whether or not this element is selected or not. - * - * @return bool - */ - public function isSelected(); - - /** - * Simulate typing into an element, which may set its value. - * - * @param mixed $value The data to be typed. - * @return WebDriverElement The current instance. - */ - public function sendKeys($value); - - /** - * If this current element is a form, or an element within a form, then this - * will be submitted to the remote server. - * - * @return WebDriverElement The current instance. - */ - public function submit(); - - /** - * Get the opaque ID of the element. - * - * @return string The opaque ID. - */ - public function getID(); +interface WebDriverElement extends WebDriverSearchContext +{ + /** + * If this element is a TEXTAREA or text INPUT element, this will clear the + * value. + * + * @return WebDriverElement The current instance. + */ + public function clear(); + + /** + * Click this element. + * + * @return WebDriverElement The current instance. + */ + public function click(); + + /** + * Get the value of a the given attribute of the element. + * + * @param string $attribute_name The name of the attribute. + * @return string The value of the attribute. + */ + public function getAttribute($attribute_name); + + /** + * Get the value of a given CSS property. + * + * @param string $css_property_name The name of the CSS property. + * @return string The value of the CSS property. + */ + public function getCSSValue($css_property_name); + + /** + * Get the location of element relative to the top-left corner of the page. + * + * @return WebDriverPoint The location of the element. + */ + public function getLocation(); + + /** + * Try scrolling the element into the view port and return the location of + * element relative to the top-left corner of the page afterwards. + * + * @return WebDriverPoint The location of the element. + */ + public function getLocationOnScreenOnceScrolledIntoView(); + + /** + * Get the size of element. + * + * @return WebDriverDimension The dimension of the element. + */ + public function getSize(); + + /** + * Get the tag name of this element. + * + * @return string The tag name. + */ + public function getTagName(); + + /** + * Get the visible (i.e. not hidden by CSS) innerText of this element, + * including sub-elements, without any leading or trailing whitespace. + * + * @return string The visible innerText of this element. + */ + public function getText(); + + /** + * Is this element displayed or not? This method avoids the problem of having + * to parse an element's "style" attribute. + * + * @return bool + */ + public function isDisplayed(); + + /** + * Is the element currently enabled or not? This will generally return true + * for everything but disabled input elements. + * + * @return bool + */ + public function isEnabled(); + + /** + * Determine whether or not this element is selected or not. + * + * @return bool + */ + public function isSelected(); + + /** + * Simulate typing into an element, which may set its value. + * + * @param mixed $value The data to be typed. + * @return WebDriverElement The current instance. + */ + public function sendKeys($value); + + /** + * If this current element is a form, or an element within a form, then this + * will be submitted to the remote server. + * + * @return WebDriverElement The current instance. + */ + public function submit(); + + /** + * Get the opaque ID of the element. + * + * @return string The opaque ID. + */ + public function getID(); } diff --git a/lib/WebDriverEventListener.php b/lib/WebDriverEventListener.php index afea9c0fd..074adebf6 100644 --- a/lib/WebDriverEventListener.php +++ b/lib/WebDriverEventListener.php @@ -19,110 +19,89 @@ use Facebook\WebDriver\Support\Events\EventFiringWebDriver; use Facebook\WebDriver\Support\Events\EventFiringWebElement; -interface WebDriverEventListener { - - /** - * @param string $url - * @param EventFiringWebDriver $driver - * @return void - */ - public function beforeNavigateTo($url, EventFiringWebDriver $driver); - - /** - * @param string $url - * @param EventFiringWebDriver $driver - * @return void - */ - public function afterNavigateTo($url, EventFiringWebDriver $driver); - - /** - * @param EventFiringWebDriver $driver - * @return void - */ - public function beforeNavigateBack(EventFiringWebDriver $driver); - - /** - * @param EventFiringWebDriver $driver - * @return void - */ - public function afterNavigateBack(EventFiringWebDriver $driver); - - /** - * @param EventFiringWebDriver $driver - * @return void - */ - public function beforeNavigateForward(EventFiringWebDriver $driver); - - /** - * @param EventFiringWebDriver $driver - * @return void - */ - public function afterNavigateForward(EventFiringWebDriver $driver); - - /** - * @param WebDriverBy $by - * @param EventFiringWebElement|null $element - * @param EventFiringWebDriver $driver - * @return void - */ - public function beforeFindBy(WebDriverBy $by, - $element, - EventFiringWebDriver $driver); - - /** - * @param WebDriverBy $by - * @param EventFiringWebElement|null $element - * @param EventFiringWebDriver $driver - * @return void - */ - public function afterFindBy(WebDriverBy $by, - $element, - EventFiringWebDriver $driver); - - /** - * @param string $script - * @param EventFiringWebDriver $driver - * @return void - */ - public function beforeScript($script, EventFiringWebDriver $driver); - - /** - * @param string $script - * @param EventFiringWebDriver $driver - * @return void - */ - public function afterScript($script, EventFiringWebDriver $driver); - - /** - * @param EventFiringWebElement $element - * @return void - */ - public function beforeClickOn(EventFiringWebElement $element); - - /** - * @param EventFiringWebElement $element - * @return void - */ - public function afterClickOn(EventFiringWebElement $element); - - /** - * @param EventFiringWebElement $element - * @return void - */ - public function beforeChangeValueOf(EventFiringWebElement $element); - - /** - * @param EventFiringWebElement $element - * @return void - */ - public function afterChangeValueOf(EventFiringWebElement $element); - - /** - * @param WebDriverException $exception - * @param EventFiringWebDriver $driver - * @return void - */ - public function onException(WebDriverException $exception, - EventFiringWebDriver $driver = null); - +interface WebDriverEventListener +{ + /** + * @param string $url + * @param EventFiringWebDriver $driver + */ + public function beforeNavigateTo($url, EventFiringWebDriver $driver); + + /** + * @param string $url + * @param EventFiringWebDriver $driver + */ + public function afterNavigateTo($url, EventFiringWebDriver $driver); + + /** + * @param EventFiringWebDriver $driver + */ + public function beforeNavigateBack(EventFiringWebDriver $driver); + + /** + * @param EventFiringWebDriver $driver + */ + public function afterNavigateBack(EventFiringWebDriver $driver); + + /** + * @param EventFiringWebDriver $driver + */ + public function beforeNavigateForward(EventFiringWebDriver $driver); + + /** + * @param EventFiringWebDriver $driver + */ + public function afterNavigateForward(EventFiringWebDriver $driver); + + /** + * @param WebDriverBy $by + * @param EventFiringWebElement|null $element + * @param EventFiringWebDriver $driver + */ + public function beforeFindBy(WebDriverBy $by, $element, EventFiringWebDriver $driver); + + /** + * @param WebDriverBy $by + * @param EventFiringWebElement|null $element + * @param EventFiringWebDriver $driver + */ + public function afterFindBy(WebDriverBy $by, $element, EventFiringWebDriver $driver); + + /** + * @param string $script + * @param EventFiringWebDriver $driver + */ + public function beforeScript($script, EventFiringWebDriver $driver); + + /** + * @param string $script + * @param EventFiringWebDriver $driver + */ + public function afterScript($script, EventFiringWebDriver $driver); + + /** + * @param EventFiringWebElement $element + */ + public function beforeClickOn(EventFiringWebElement $element); + + /** + * @param EventFiringWebElement $element + */ + public function afterClickOn(EventFiringWebElement $element); + + /** + * @param EventFiringWebElement $element + */ + public function beforeChangeValueOf(EventFiringWebElement $element); + + /** + * @param EventFiringWebElement $element + */ + public function afterChangeValueOf(EventFiringWebElement $element); + + /** + * @param WebDriverException $exception + * @param EventFiringWebDriver $driver + */ + public function onException(WebDriverException $exception, EventFiringWebDriver $driver = null); } diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index 3de9a9731..8c069bd41 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -15,402 +15,427 @@ namespace Facebook\WebDriver; -use Facebook\WebDriver\Exception\StaleElementReferenceException; -use Facebook\WebDriver\Exception\NoSuchFrameException; -use Facebook\WebDriver\Exception\NoSuchElementException; use Facebook\WebDriver\Exception\NoAlertOpenException; +use Facebook\WebDriver\Exception\NoSuchElementException; +use Facebook\WebDriver\Exception\NoSuchFrameException; +use Facebook\WebDriver\Exception\StaleElementReferenceException; /** * Canned ExpectedConditions which are generally useful within webdriver tests. * * @see WebDriverWait */ -class WebDriverExpectedCondition { - - /** - * A closure function to be executed by WebDriverWait. It should return - * a truthy value, mostly boolean or a WebDriverElement, on success. - */ - private $apply; - - /** - * @return (function():T) a closure function to be executed by WebDriverWait - */ - public function getApply() { - return $this->apply; - } - - protected function __construct($apply) { - $this->apply = $apply; - } - - /** - * An expectation for checking the title of a page. - * - * @param string $title The expected title, which must be an exact match. - * @return bool WebDriverExpectedCondition True when the title matches, - * false otherwise. - */ - public static function titleIs($title) { - return new WebDriverExpectedCondition( - function ($driver) use ($title) { - return $title === $driver->getTitle(); - } - ); - } - - /** - * An expectation for checking substring of a page Title. - * - * @param string $title The expected substring of Title. - * @return bool WebDriverExpectedCondition True when in title, - * false otherwise. - */ - public static function titleContains($title) { - return new WebDriverExpectedCondition( - function ($driver) use ($title) { - return strpos($driver->getTitle(), $title) !== false; - } - ); - } - - /** - * An expectation for checking that an element is present on the DOM of a - * page. This does not necessarily mean that the element is visible. - * - * @param WebDriverBy $by The locator used to find the element. - * @return WebDriverExpectedCondition The element which - * is located. - */ - public static function presenceOfElementLocated(WebDriverBy $by) { - return new WebDriverExpectedCondition( - function ($driver) use ($by) { - return $driver->findElement($by); - } - ); - } - - /** - * An expectation for checking that an element is present on the DOM of a page - * and visible. Visibility means that the element is not only displayed but - * also has a height and width that is greater than 0. - * - * @param WebDriverBy $by The locator used to find the element. - * @return WebDriverExpectedCondition The element which is - * located and visible. - */ - public static function visibilityOfElementLocated(WebDriverBy $by) { - return new WebDriverExpectedCondition( - function ($driver) use ($by) { - try { - $element = $driver->findElement($by); - return $element->isDisplayed() ? $element : null; - } catch (StaleElementReferenceException $e) { - return null; - } - } - ); - } - - /** - * An expectation for checking that an element, known to be present on the DOM - * of a page, is visible. Visibility means that the element is not only - * displayed but also has a height and width that is greater than 0. - * - * @param WebDriverElement $element The element to be checked. - * @return WebDriverExpectedCondition The same - * WebDriverElement once it is visible. - */ - public static function visibilityOf(WebDriverElement $element) { - return new WebDriverExpectedCondition( - function ($driver) use ($element) { - return $element->isDisplayed() ? $element : null; - } - ); - } - - /** - * An expectation for checking that there is at least one element present on a - * web page. - * - * @param WebDriverBy $by The locator used to find the element. - * @return WebDriverExpectedCondition An array of WebDriverElements - * once they are located. - */ - public static function presenceOfAllElementsLocatedBy(WebDriverBy $by) { - return new WebDriverExpectedCondition( - function ($driver) use ($by) { - $elements = $driver->findElements($by); - return count($elements) > 0 ? $elements : null; - } - ); - } - - /** - * An expectation for checking if the given text is present in the specified - * element. - * - * @param WebDriverBy $by The locator used to find the element. - * @param string $text The text to be presented in the element. - * @return bool WebDriverExpectedCondition Whether the text is presented. - */ - public static function textToBePresentInElement( - WebDriverBy $by, $text) { - return new WebDriverExpectedCondition( - function ($driver) use ($by, $text) { - try { - $element_text = $driver->findElement($by)->getText(); - return strpos($element_text, $text) !== false; - } catch (StaleElementReferenceException $e) { - return null; - } - } - ); - } - - /** - * An expectation for checking if the given text is present in the specified - * elements value attribute. - * - * @param WebDriverBy $by The locator used to find the element. - * @param string $text The text to be presented in the element value. - * @return bool WebDriverExpectedCondition Whether the text is presented. - */ - public static function textToBePresentInElementValue( - WebDriverBy $by, $text) { - return new WebDriverExpectedCondition( - function ($driver) use ($by, $text) { - try { - $element_text = $driver->findElement($by)->getAttribute('value'); - return strpos($element_text, $text) !== false; - } catch (StaleElementReferenceException $e) { - return null; - } - } - ); - } - - /** - * Expectation for checking if iFrame exists. - * If iFrame exists switches driver's focus to the iFrame - * - * @param string $frame_locator The locator used to find the iFrame - * expected to be either the id or name value of the i/frame - * @return WebDriverExpectedCondition object focused on new frame - * when frame is found bool false otherwise - */ - public static function frameToBeAvailableAndSwitchToIt($frame_locator) { - return new WebDriverExpectedCondition( - function ($driver) use ($frame_locator) { - try { - return $driver->switchTo()->frame($frame_locator); - } catch (NoSuchFrameException $e) { - return false; - } - } - ); - } - - /** - * An expectation for checking that an element is either invisible or not - * present on the DOM. - * - * @param WebDriverBy $by The locator used to find the element. - * @return bool WebDriverExpectedCondition Whether there is no element - * located. - */ - public static function invisibilityOfElementLocated(WebDriverBy $by) { - return new WebDriverExpectedCondition( - function ($driver) use ($by) { - try { - return !($driver->findElement($by)->isDisplayed()); - } catch (NoSuchElementException $e) { - return true; - } catch (StaleElementReferenceException $e) { - return true; - } - } - ); - } - - /** - * An expectation for checking that an element with text is either invisible - * or not present on the DOM. - * - * @param WebdriverBy $by The locator used to find the element. - * @param string $text The text of the element. - * @return bool WebDriverExpectedCondition Whether the text is found in the - * element located. - */ - public static function invisibilityOfElementWithText( - WebDriverBy $by, $text) { - return new WebDriverExpectedCondition( - function ($driver) use ($by, $text) { - try { - return !($driver->findElement($by)->getText() === $text); - } catch (NoSuchElementException $e) { - return true; - } catch (StaleElementReferenceException $e) { - return true; - } - } - ); - } - - /** - * An expectation for checking an element is visible and enabled such that you - * can click it. - * - * @param WebDriverBy $by The locator used to find the element - * @return WebDriverExpectedCondition The WebDriverElement - * once it is located, visible and clickable - */ - public static function elementToBeClickable(WebDriverBy $by) { - $visibility_of_element_located = - WebDriverExpectedCondition::visibilityOfElementLocated($by); - return new WebDriverExpectedCondition( - function ($driver) use ($visibility_of_element_located) { - $element = call_user_func( - $visibility_of_element_located->getApply(), - $driver +class WebDriverExpectedCondition +{ + /** + * A closure function to be executed by WebDriverWait. It should return + * a truthy value, mostly boolean or a WebDriverElement, on success. + */ + private $apply; + + /** + * @return (function():T) a closure function to be executed by WebDriverWait + */ + public function getApply() + { + return $this->apply; + } + + protected function __construct($apply) + { + $this->apply = $apply; + } + + /** + * An expectation for checking the title of a page. + * + * @param string $title The expected title, which must be an exact match. + * @return bool WebDriverExpectedCondition True when the title matches, + * false otherwise. + */ + public static function titleIs($title) + { + return new self( + function ($driver) use ($title) { + return $title === $driver->getTitle(); + } + ); + } + + /** + * An expectation for checking substring of a page Title. + * + * @param string $title The expected substring of Title. + * @return bool WebDriverExpectedCondition True when in title, + * false otherwise. + */ + public static function titleContains($title) + { + return new self( + function ($driver) use ($title) { + return strpos($driver->getTitle(), $title) !== false; + } + ); + } + + /** + * An expectation for checking that an element is present on the DOM of a + * page. This does not necessarily mean that the element is visible. + * + * @param WebDriverBy $by The locator used to find the element. + * @return WebDriverExpectedCondition The element which + * is located. + */ + public static function presenceOfElementLocated(WebDriverBy $by) + { + return new self( + function ($driver) use ($by) { + return $driver->findElement($by); + } + ); + } + + /** + * An expectation for checking that an element is present on the DOM of a page + * and visible. Visibility means that the element is not only displayed but + * also has a height and width that is greater than 0. + * + * @param WebDriverBy $by The locator used to find the element. + * @return WebDriverExpectedCondition The element which is + * located and visible. + */ + public static function visibilityOfElementLocated(WebDriverBy $by) + { + return new self( + function ($driver) use ($by) { + try { + $element = $driver->findElement($by); + + return $element->isDisplayed() ? $element : null; + } catch (StaleElementReferenceException $e) { + return null; + } + } + ); + } + + /** + * An expectation for checking that an element, known to be present on the DOM + * of a page, is visible. Visibility means that the element is not only + * displayed but also has a height and width that is greater than 0. + * + * @param WebDriverElement $element The element to be checked. + * @return WebDriverExpectedCondition The same + * WebDriverElement once it is visible. + */ + public static function visibilityOf(WebDriverElement $element) + { + return new self( + function ($driver) use ($element) { + return $element->isDisplayed() ? $element : null; + } + ); + } + + /** + * An expectation for checking that there is at least one element present on a + * web page. + * + * @param WebDriverBy $by The locator used to find the element. + * @return WebDriverExpectedCondition An array of WebDriverElements + * once they are located. + */ + public static function presenceOfAllElementsLocatedBy(WebDriverBy $by) + { + return new self( + function ($driver) use ($by) { + $elements = $driver->findElements($by); + + return count($elements) > 0 ? $elements : null; + } ); - try { - if ($element !== null && $element->isEnabled()) { - return $element; - } else { - return null; - } - } catch (StaleElementReferenceException $e) { - return null; - } - } - ); - } - - /** - * Wait until an element is no longer attached to the DOM. - * - * @param WebDriverElement $element The element to wait for. - * @return bool WebDriverExpectedCondition false if the element is still - * attached to the DOM, true otherwise. - */ - public static function stalenessOf(WebDriverElement $element) { - return new WebDriverExpectedCondition( - function ($driver) use ($element) { - try { - $element->isEnabled(); - return false; - } catch (StaleElementReferenceException $e) { - return true; - } - } - ); - } - - /** - * Wrapper for a condition, which allows for elements to update by redrawing. - * - * This works around the problem of conditions which have two parts: find an - * element and then check for some condition on it. For these conditions it is - * possible that an element is located and then subsequently it is redrawn on - * the client. When this happens a StaleElementReferenceException is thrown - * when the second part of the condition is checked. - * - * @param WebDriverExpectedCondition $condition The condition wrapped. - * @return WebDriverExpectedCondition The return value of the - * getApply() of the given condition. - */ - public static function refreshed(WebDriverExpectedCondition $condition) { - return new WebDriverExpectedCondition( - function ($driver) use ($condition) { - try { - return call_user_func($condition->getApply(), $driver); - } catch (StaleElementReferenceException $e) { - return null; - } - } - ); - } - - /** - * An expectation for checking if the given element is selected. - * - * @param mixed $element_or_by Either the element or the locator. - * @return bool WebDriverExpectedCondition whether the element is selected. - */ - public static function elementToBeSelected($element_or_by) { - return WebDriverExpectedCondition::elementSelectionStateToBe( - $element_or_by, - true - ); - } - - /** - * An expectation for checking if the given element is selected. - * - * @param mixed $element_or_by Either the element or the locator. - * @param bool $selected The required state. - * @return bool WebDriverExpectedCondition Whether the element is selected. - */ - public static function elementSelectionStateToBe( - $element_or_by, - $selected - ) { - if ($element_or_by instanceof WebDriverElement) { - return new WebDriverExpectedCondition( - function ($driver) use ($element_or_by, $selected) { - return $element_or_by->isSelected() === $selected; - } - ); - } else if ($element_or_by instanceof WebDriverBy) { - return new WebDriverExpectedCondition( - function ($driver) use ($element_or_by, $selected) { - try { - $element = $driver->findElement($element_or_by); - return $element->isSelected() === $selected; - } catch (StaleElementReferenceException $e) { - return null; - } - } - ); } - } - - /** - * An expectation for whether an alert() box is present. - * - * @return WebDriverExpectedCondition if alert() is present, - * null otherwise. - */ - public static function alertIsPresent() { - return new WebDriverExpectedCondition( - function ($driver) { - try { - // Unlike the Java code, we get a WebDriverAlert object regardless - // of whether there is an alert. Calling getText() will throw - // an exception if it is not really there. - $alert = $driver->switchTo()->alert(); - $alert->getText(); - return $alert; - } catch (NoAlertOpenException $e) { - return null; + + /** + * An expectation for checking if the given text is present in the specified + * element. + * + * @param WebDriverBy $by The locator used to find the element. + * @param string $text The text to be presented in the element. + * @return bool WebDriverExpectedCondition Whether the text is presented. + */ + public static function textToBePresentInElement(WebDriverBy $by, $text) + { + return new self( + function ($driver) use ($by, $text) { + try { + $element_text = $driver->findElement($by)->getText(); + + return strpos($element_text, $text) !== false; + } catch (StaleElementReferenceException $e) { + return null; + } + } + ); + } + + /** + * An expectation for checking if the given text is present in the specified + * elements value attribute. + * + * @param WebDriverBy $by The locator used to find the element. + * @param string $text The text to be presented in the element value. + * @return bool WebDriverExpectedCondition Whether the text is presented. + */ + public static function textToBePresentInElementValue(WebDriverBy $by, $text) + { + return new self( + function ($driver) use ($by, $text) { + try { + $element_text = $driver->findElement($by)->getAttribute('value'); + + return strpos($element_text, $text) !== false; + } catch (StaleElementReferenceException $e) { + return null; + } + } + ); + } + + /** + * Expectation for checking if iFrame exists. + * If iFrame exists switches driver's focus to the iFrame + * + * @param string $frame_locator The locator used to find the iFrame + * expected to be either the id or name value of the i/frame + * @return WebDriverExpectedCondition object focused on new frame + * when frame is found bool false otherwise + */ + public static function frameToBeAvailableAndSwitchToIt($frame_locator) + { + return new self( + function ($driver) use ($frame_locator) { + try { + return $driver->switchTo()->frame($frame_locator); + } catch (NoSuchFrameException $e) { + return false; + } + } + ); + } + + /** + * An expectation for checking that an element is either invisible or not + * present on the DOM. + * + * @param WebDriverBy $by The locator used to find the element. + * @return bool WebDriverExpectedCondition Whether there is no element + * located. + */ + public static function invisibilityOfElementLocated(WebDriverBy $by) + { + return new self( + function ($driver) use ($by) { + try { + return !($driver->findElement($by)->isDisplayed()); + } catch (NoSuchElementException $e) { + return true; + } catch (StaleElementReferenceException $e) { + return true; + } + } + ); + } + + /** + * An expectation for checking that an element with text is either invisible + * or not present on the DOM. + * + * @param WebdriverBy $by The locator used to find the element. + * @param string $text The text of the element. + * @return bool WebDriverExpectedCondition Whether the text is found in the + * element located. + */ + public static function invisibilityOfElementWithText(WebDriverBy $by, $text) + { + return new self( + function ($driver) use ($by, $text) { + try { + return !($driver->findElement($by)->getText() === $text); + } catch (NoSuchElementException $e) { + return true; + } catch (StaleElementReferenceException $e) { + return true; + } + } + ); + } + + /** + * An expectation for checking an element is visible and enabled such that you + * can click it. + * + * @param WebDriverBy $by The locator used to find the element + * @return WebDriverExpectedCondition The WebDriverElement + * once it is located, visible and clickable + */ + public static function elementToBeClickable(WebDriverBy $by) + { + $visibility_of_element_located = + self::visibilityOfElementLocated($by); + + return new self( + function ($driver) use ($visibility_of_element_located) { + $element = call_user_func( + $visibility_of_element_located->getApply(), + $driver + ); + try { + if ($element !== null && $element->isEnabled()) { + return $element; + } else { + return null; + } + } catch (StaleElementReferenceException $e) { + return null; + } + } + ); + } + + /** + * Wait until an element is no longer attached to the DOM. + * + * @param WebDriverElement $element The element to wait for. + * @return bool WebDriverExpectedCondition false if the element is still + * attached to the DOM, true otherwise. + */ + public static function stalenessOf(WebDriverElement $element) + { + return new self( + function ($driver) use ($element) { + try { + $element->isEnabled(); + + return false; + } catch (StaleElementReferenceException $e) { + return true; + } + } + ); + } + + /** + * Wrapper for a condition, which allows for elements to update by redrawing. + * + * This works around the problem of conditions which have two parts: find an + * element and then check for some condition on it. For these conditions it is + * possible that an element is located and then subsequently it is redrawn on + * the client. When this happens a StaleElementReferenceException is thrown + * when the second part of the condition is checked. + * + * @param WebDriverExpectedCondition $condition The condition wrapped. + * @return WebDriverExpectedCondition The return value of the + * getApply() of the given condition. + */ + public static function refreshed(WebDriverExpectedCondition $condition) + { + return new self( + function ($driver) use ($condition) { + try { + return call_user_func($condition->getApply(), $driver); + } catch (StaleElementReferenceException $e) { + return null; + } + } + ); + } + + /** + * An expectation for checking if the given element is selected. + * + * @param mixed $element_or_by Either the element or the locator. + * @return bool WebDriverExpectedCondition whether the element is selected. + */ + public static function elementToBeSelected($element_or_by) + { + return self::elementSelectionStateToBe( + $element_or_by, + true + ); + } + + /** + * An expectation for checking if the given element is selected. + * + * @param mixed $element_or_by Either the element or the locator. + * @param bool $selected The required state. + * @return bool WebDriverExpectedCondition Whether the element is selected. + */ + public static function elementSelectionStateToBe($element_or_by, $selected) + { + if ($element_or_by instanceof WebDriverElement) { + return new self( + function ($driver) use ($element_or_by, $selected) { + return $element_or_by->isSelected() === $selected; + } + ); + } else { + if ($element_or_by instanceof WebDriverBy) { + return new self( + function ($driver) use ($element_or_by, $selected) { + try { + $element = $driver->findElement($element_or_by); + + return $element->isSelected() === $selected; + } catch (StaleElementReferenceException $e) { + return null; + } + } + ); + } } - } - ); - } - - /** - * An expectation with the logical opposite condition of the given condition. - * - * @param WebDriverExpectedCondition $condition The condition to be negated. - * @return mixed The negation of the result of the given condition. - */ - public static function not(WebDriverExpectedCondition $condition) { - return new WebDriverExpectedCondition( - function ($driver) use ($condition) { - $result = call_user_func($condition->getApply(), $driver); - return !$result; - } - ); - } + } + + /** + * An expectation for whether an alert() box is present. + * + * @return WebDriverExpectedCondition if alert() is present, + * null otherwise. + */ + public static function alertIsPresent() + { + return new self( + function ($driver) { + try { + // Unlike the Java code, we get a WebDriverAlert object regardless + // of whether there is an alert. Calling getText() will throw + // an exception if it is not really there. + $alert = $driver->switchTo()->alert(); + $alert->getText(); + + return $alert; + } catch (NoAlertOpenException $e) { + return null; + } + } + ); + } + + /** + * An expectation with the logical opposite condition of the given condition. + * + * @param WebDriverExpectedCondition $condition The condition to be negated. + * @return mixed The negation of the result of the given condition. + */ + public static function not(WebDriverExpectedCondition $condition) + { + return new self( + function ($driver) use ($condition) { + $result = call_user_func($condition->getApply(), $driver); + + return !$result; + } + ); + } } diff --git a/lib/WebDriverHasInputDevices.php b/lib/WebDriverHasInputDevices.php index 76c82dddc..93e42a30a 100644 --- a/lib/WebDriverHasInputDevices.php +++ b/lib/WebDriverHasInputDevices.php @@ -18,15 +18,15 @@ /** * Interface implemented by each driver that allows access to the input devices. */ -interface WebDriverHasInputDevices { +interface WebDriverHasInputDevices +{ + /** + * @return WebDriverKeyBoard + */ + public function getKeyboard(); - /** - * @return WebDriverKeyBoard - */ - public function getKeyboard(); - - /** - * @return WebDriverMouse - */ - public function getMouse(); + /** + * @return WebDriverMouse + */ + public function getMouse(); } diff --git a/lib/WebDriverKeyboard.php b/lib/WebDriverKeyboard.php index 042e47108..f44582a12 100644 --- a/lib/WebDriverKeyboard.php +++ b/lib/WebDriverKeyboard.php @@ -15,31 +15,31 @@ namespace Facebook\WebDriver; -interface WebDriverKeyboard { +interface WebDriverKeyboard +{ + /** + * Send a sequence of keys. + * + * @param string $keys + * @return $this + */ + public function sendKeys($keys); - /** - * Send a sequence of keys. - * - * @param string $keys - * @return $this - */ - public function sendKeys($keys); + /** + * Press a key + * + * @see WebDriverKeys + * @param string $key + * @return $this + */ + public function pressKey($key); - /** - * Press a key - * - * @see WebDriverKeys - * @param string $key - * @return $this - */ - public function pressKey($key); - - /** - * Release a key - * - * @see WebDriverKeys - * @param string $key - * @return $this - */ - public function releaseKey($key); + /** + * Release a key + * + * @see WebDriverKeys + * @param string $key + * @return $this + */ + public function releaseKey($key); } diff --git a/lib/WebDriverKeys.php b/lib/WebDriverKeys.php index b946cec9f..ecab819b6 100644 --- a/lib/WebDriverKeys.php +++ b/lib/WebDriverKeys.php @@ -19,97 +19,97 @@ * Representations of pressable keys that aren't text. * These are stored in the Unicode PUA (Private Use Area) code points. */ -class WebDriverKeys { +class WebDriverKeys +{ + const NULL = "\xEE\x80\x80"; + const CANCEL = "\xEE\x80\x81"; + const HELP = "\xEE\x80\x82"; + const BACKSPACE = "\xEE\x80\x83"; + const TAB = "\xEE\x80\x84"; + const CLEAR = "\xEE\x80\x85"; + const RETURN_KEY = "\xEE\x80\x86"; // php does not allow RETURN + const ENTER = "\xEE\x80\x87"; + const SHIFT = "\xEE\x80\x88"; + const LEFT_SHIFT = "\xEE\x80\x88"; + const CONTROL = "\xEE\x80\x89"; + const LEFT_CONTROL = "\xEE\x80\x89"; + const ALT = "\xEE\x80\x8A"; + const LEFT_ALT = "\xEE\x80\x8A"; + const PAUSE = "\xEE\x80\x8B"; + const ESCAPE = "\xEE\x80\x8C"; + const SPACE = "\xEE\x80\x8D"; + const PAGE_UP = "\xEE\x80\x8E"; + const PAGE_DOWN = "\xEE\x80\x8F"; + const END = "\xEE\x80\x90"; + const HOME = "\xEE\x80\x91"; + const LEFT = "\xEE\x80\x92"; + const ARROW_LEFT = "\xEE\x80\x92"; + const UP = "\xEE\x80\x93"; + const ARROW_UP = "\xEE\x80\x93"; + const RIGHT = "\xEE\x80\x94"; + const ARROW_RIGHT = "\xEE\x80\x94"; + const DOWN = "\xEE\x80\x95"; + const ARROW_DOWN = "\xEE\x80\x95"; + const INSERT = "\xEE\x80\x96"; + const DELETE = "\xEE\x80\x97"; + const SEMICOLON = "\xEE\x80\x98"; + const EQUALS = "\xEE\x80\x99"; + const NUMPAD0 = "\xEE\x80\x9A"; + const NUMPAD1 = "\xEE\x80\x9B"; + const NUMPAD2 = "\xEE\x80\x9C"; + const NUMPAD3 = "\xEE\x80\x9D"; + const NUMPAD4 = "\xEE\x80\x9E"; + const NUMPAD5 = "\xEE\x80\x9F"; + const NUMPAD6 = "\xEE\x80\xA0"; + const NUMPAD7 = "\xEE\x80\xA1"; + const NUMPAD8 = "\xEE\x80\xA2"; + const NUMPAD9 = "\xEE\x80\xA3"; + const MULTIPLY = "\xEE\x80\xA4"; + const ADD = "\xEE\x80\xA5"; + const SEPARATOR = "\xEE\x80\xA6"; + const SUBTRACT = "\xEE\x80\xA7"; + const DECIMAL = "\xEE\x80\xA8"; + const DIVIDE = "\xEE\x80\xA9"; + const F1 = "\xEE\x80\xB1"; + const F2 = "\xEE\x80\xB2"; + const F3 = "\xEE\x80\xB3"; + const F4 = "\xEE\x80\xB4"; + const F5 = "\xEE\x80\xB5"; + const F6 = "\xEE\x80\xB6"; + const F7 = "\xEE\x80\xB7"; + const F8 = "\xEE\x80\xB8"; + const F9 = "\xEE\x80\xB9"; + const F10 = "\xEE\x80\xBA"; + const F11 = "\xEE\x80\xBB"; + const F12 = "\xEE\x80\xBC"; + const META = "\xEE\x80\xBD"; + const COMMAND = "\xEE\x80\xBD"; // ALIAS + const ZENKAKU_HANKAKU = "\xEE\x80\xC0"; - const NULL = "\xEE\x80\x80"; - const CANCEL = "\xEE\x80\x81"; - const HELP = "\xEE\x80\x82"; - const BACKSPACE = "\xEE\x80\x83"; - const TAB = "\xEE\x80\x84"; - const CLEAR = "\xEE\x80\x85"; - const RETURN_KEY = "\xEE\x80\x86"; // php does not allow RETURN - const ENTER = "\xEE\x80\x87"; - const SHIFT = "\xEE\x80\x88"; - const LEFT_SHIFT = "\xEE\x80\x88"; - const CONTROL = "\xEE\x80\x89"; - const LEFT_CONTROL = "\xEE\x80\x89"; - const ALT = "\xEE\x80\x8A"; - const LEFT_ALT = "\xEE\x80\x8A"; - const PAUSE = "\xEE\x80\x8B"; - const ESCAPE = "\xEE\x80\x8C"; - const SPACE = "\xEE\x80\x8D"; - const PAGE_UP = "\xEE\x80\x8E"; - const PAGE_DOWN = "\xEE\x80\x8F"; - const END = "\xEE\x80\x90"; - const HOME = "\xEE\x80\x91"; - const LEFT = "\xEE\x80\x92"; - const ARROW_LEFT = "\xEE\x80\x92"; - const UP = "\xEE\x80\x93"; - const ARROW_UP = "\xEE\x80\x93"; - const RIGHT = "\xEE\x80\x94"; - const ARROW_RIGHT = "\xEE\x80\x94"; - const DOWN = "\xEE\x80\x95"; - const ARROW_DOWN = "\xEE\x80\x95"; - const INSERT = "\xEE\x80\x96"; - const DELETE = "\xEE\x80\x97"; - const SEMICOLON = "\xEE\x80\x98"; - const EQUALS = "\xEE\x80\x99"; - const NUMPAD0 = "\xEE\x80\x9A"; - const NUMPAD1 = "\xEE\x80\x9B"; - const NUMPAD2 = "\xEE\x80\x9C"; - const NUMPAD3 = "\xEE\x80\x9D"; - const NUMPAD4 = "\xEE\x80\x9E"; - const NUMPAD5 = "\xEE\x80\x9F"; - const NUMPAD6 = "\xEE\x80\xA0"; - const NUMPAD7 = "\xEE\x80\xA1"; - const NUMPAD8 = "\xEE\x80\xA2"; - const NUMPAD9 = "\xEE\x80\xA3"; - const MULTIPLY = "\xEE\x80\xA4"; - const ADD = "\xEE\x80\xA5"; - const SEPARATOR = "\xEE\x80\xA6"; - const SUBTRACT = "\xEE\x80\xA7"; - const DECIMAL = "\xEE\x80\xA8"; - const DIVIDE = "\xEE\x80\xA9"; - const F1 = "\xEE\x80\xB1"; - const F2 = "\xEE\x80\xB2"; - const F3 = "\xEE\x80\xB3"; - const F4 = "\xEE\x80\xB4"; - const F5 = "\xEE\x80\xB5"; - const F6 = "\xEE\x80\xB6"; - const F7 = "\xEE\x80\xB7"; - const F8 = "\xEE\x80\xB8"; - const F9 = "\xEE\x80\xB9"; - const F10 = "\xEE\x80\xBA"; - const F11 = "\xEE\x80\xBB"; - const F12 = "\xEE\x80\xBC"; - const META = "\xEE\x80\xBD"; - const COMMAND = "\xEE\x80\xBD"; // ALIAS - const ZENKAKU_HANKAKU = "\xEE\x80\xC0"; + /** + * Encode input of `sendKeys()`. + * @param string|array $keys + * @return array + */ + public static function encode($keys) + { + if (is_numeric($keys)) { + $keys = '' . $keys; + } - /** - * Encode input of `sendKeys()`. - * @param string|array $keys - * @return array - */ - public static function encode($keys) { + if (is_string($keys)) { + $keys = array($keys); + } - if (is_numeric($keys)) { - $keys = '' . $keys; - } - - if (is_string($keys)) { - $keys = array($keys); - } + $encoded = array(); + foreach ($keys as $key) { + if (is_array($key)) { + // handle modified keys + $key = implode('', $key) . self::NULL; + } + $encoded[] = (string) $key; + } - $encoded = array(); - foreach ($keys as $key) { - if (is_array($key)) { - // handle modified keys - $key = implode('', $key).self::NULL; - } - $encoded[] = (string)$key; + return $encoded; } - - return $encoded; - } } diff --git a/lib/WebDriverMouse.php b/lib/WebDriverMouse.php index 847bc2cd0..9fe052119 100644 --- a/lib/WebDriverMouse.php +++ b/lib/WebDriverMouse.php @@ -20,45 +20,47 @@ /** * Interface representing basic mouse operations. */ -interface WebDriverMouse { +interface WebDriverMouse +{ + /** + * @param WebDriverCoordinates $where + * @return WebDriverMouse + */ + public function click(WebDriverCoordinates $where); - /** - * @param WebDriverCoordinates $where - * @return WebDriverMouse - */ - public function click(WebDriverCoordinates $where); + /** + * @param WebDriverCoordinates $where + * @return WebDriverMouse + */ + public function contextClick(WebDriverCoordinates $where); - /** - * @param WebDriverCoordinates $where - * @return WebDriverMouse - */ - public function contextClick(WebDriverCoordinates $where); + /** + * @param WebDriverCoordinates $where + * @return WebDriverMouse + */ + public function doubleClick(WebDriverCoordinates $where); - /** - * @param WebDriverCoordinates $where - * @return WebDriverMouse - */ - public function doubleClick(WebDriverCoordinates $where); + /** + * @param WebDriverCoordinates $where + * @return WebDriverMouse + */ + public function mouseDown(WebDriverCoordinates $where); - /** - * @param WebDriverCoordinates $where - * @return WebDriverMouse - */ - public function mouseDown(WebDriverCoordinates $where); + /** + * @param WebDriverCoordinates $where + * @param int $x_offset + * @param int $y_offset + * @return WebDriverMouse + */ + public function mouseMove( + WebDriverCoordinates $where, + $x_offset = null, + $y_offset = null + ); - /** - * @param WebDriverCoordinates $where - * @param int $x_offset - * @param int $y_offset - * @return WebDriverMouse - */ - public function mouseMove(WebDriverCoordinates $where, - $x_offset = null, - $y_offset = null); - - /** - * @param WebDriverCoordinates $where - * @return WebDriverMouse - */ - public function mouseUp(WebDriverCoordinates $where); + /** + * @param WebDriverCoordinates $where + * @return WebDriverMouse + */ + public function mouseUp(WebDriverCoordinates $where); } diff --git a/lib/WebDriverNavigation.php b/lib/WebDriverNavigation.php index 8dd382dea..5e06d6257 100644 --- a/lib/WebDriverNavigation.php +++ b/lib/WebDriverNavigation.php @@ -27,53 +27,62 @@ * FirefoxProfile preferences. * https://code.google.com/p/selenium/wiki/DesiredCapabilities#settings */ -class WebDriverNavigation { +class WebDriverNavigation +{ + protected $executor; - protected $executor; + public function __construct(ExecuteMethod $executor) + { + $this->executor = $executor; + } - public function __construct(ExecuteMethod $executor) { - $this->executor = $executor; - } + /** + * Move back a single entry in the browser's history, if possible. + * + * @return WebDriverNavigation The instance. + */ + public function back() + { + $this->executor->execute(DriverCommand::GO_BACK); - /** - * Move back a single entry in the browser's history, if possible. - * - * @return WebDriverNavigation The instance. - */ - public function back() { - $this->executor->execute(DriverCommand::GO_BACK); - return $this; - } + return $this; + } - /** - * Move forward a single entry in the browser's history, if possible. - * - * @return WebDriverNavigation The instance. - */ - public function forward() { - $this->executor->execute(DriverCommand::GO_FORWARD); - return $this; - } + /** + * Move forward a single entry in the browser's history, if possible. + * + * @return WebDriverNavigation The instance. + */ + public function forward() + { + $this->executor->execute(DriverCommand::GO_FORWARD); - /** - * Refresh the current page. - * - * @return WebDriverNavigation The instance. - */ - public function refresh() { - $this->executor->execute(DriverCommand::REFRESH); - return $this; - } + return $this; + } - /** - * Navigate to the given URL. - * - * @param string $url - * @return WebDriverNavigation The instance. - */ - public function to($url) { - $params = array('url' => (string)$url); - $this->executor->execute(DriverCommand::GET, $params); - return $this; - } + /** + * Refresh the current page. + * + * @return WebDriverNavigation The instance. + */ + public function refresh() + { + $this->executor->execute(DriverCommand::REFRESH); + + return $this; + } + + /** + * Navigate to the given URL. + * + * @param string $url + * @return WebDriverNavigation The instance. + */ + public function to($url) + { + $params = array('url' => (string) $url); + $this->executor->execute(DriverCommand::GET, $params); + + return $this; + } } diff --git a/lib/WebDriverOptions.php b/lib/WebDriverOptions.php index 9f48b05d1..8b80d3dba 100644 --- a/lib/WebDriverOptions.php +++ b/lib/WebDriverOptions.php @@ -22,152 +22,170 @@ /** * Managing stuff you would do in a browser. */ -class WebDriverOptions { - - protected $executor; - - public function __construct(ExecuteMethod $executor) { - $this->executor = $executor; - } - - /** - * Add a specific cookie. - * - * Here are the valid attributes of a cookie array. - * 'name' : string The name of the cookie; may not be null or an empty - * string. - * 'value' : string The cookie value; may not be null. - * 'path' : string The path the cookie is visible to. If left blank or set - * to null, will be set to "/". - * 'domain': string The domain the cookie is visible to. It should be null or - * the same as the domain of the current URL. - * 'secure': bool Whether this cookie requires a secure connection(https?). - * It should be null or equal to the security of the current - * URL. - * 'expiry': int The cookie's expiration date; may be null. - * - * @param array $cookie An array with key as the attributes mentioned above. - * @return WebDriverOptions The current instance. - */ - public function addCookie(array $cookie) { - $this->validate($cookie); - $this->executor->execute( - DriverCommand::ADD_COOKIE, - array('cookie' => $cookie) - ); - return $this; - } - - /** - * Delete all the cookies that are currently visible. - * - * @return WebDriverOptions The current instance. - */ - public function deleteAllCookies() { - $this->executor->execute(DriverCommand::DELETE_ALL_COOKIES); - return $this; - } - - /** - * Delete the cookie with the give name. - * - * @param string $name - * @return WebDriverOptions The current instance. - */ - public function deleteCookieNamed($name) { - $this->executor->execute( - DriverCommand::DELETE_COOKIE, - array(':name' => $name) - ); - return $this; - } - - /** - * Get the cookie with a given name. - * - * @param string $name - * @return array The cookie, or null if no cookie with the given name is - * presented. - */ - public function getCookieNamed($name) { - $cookies = $this->getCookies(); - foreach ($cookies as $cookie) { - if ($cookie['name'] === $name) { - return $cookie; - } +class WebDriverOptions +{ + protected $executor; + + public function __construct(ExecuteMethod $executor) + { + $this->executor = $executor; + } + + /** + * Add a specific cookie. + * + * Here are the valid attributes of a cookie array. + * 'name' : string The name of the cookie; may not be null or an empty + * string. + * 'value' : string The cookie value; may not be null. + * 'path' : string The path the cookie is visible to. If left blank or set + * to null, will be set to "/". + * 'domain': string The domain the cookie is visible to. It should be null or + * the same as the domain of the current URL. + * 'secure': bool Whether this cookie requires a secure connection(https?). + * It should be null or equal to the security of the current + * URL. + * 'expiry': int The cookie's expiration date; may be null. + * + * @param array $cookie An array with key as the attributes mentioned above. + * @return WebDriverOptions The current instance. + */ + public function addCookie(array $cookie) + { + $this->validate($cookie); + $this->executor->execute( + DriverCommand::ADD_COOKIE, + array('cookie' => $cookie) + ); + + return $this; + } + + /** + * Delete all the cookies that are currently visible. + * + * @return WebDriverOptions The current instance. + */ + public function deleteAllCookies() + { + $this->executor->execute(DriverCommand::DELETE_ALL_COOKIES); + + return $this; + } + + /** + * Delete the cookie with the give name. + * + * @param string $name + * @return WebDriverOptions The current instance. + */ + public function deleteCookieNamed($name) + { + $this->executor->execute( + DriverCommand::DELETE_COOKIE, + array(':name' => $name) + ); + + return $this; } - return null; - } - - /** - * Get all the cookies for the current domain. - * - * @return array The array of cookies presented. - */ - public function getCookies() { - return $this->executor->execute(DriverCommand::GET_ALL_COOKIES); - } - - private function validate(array $cookie) { - if (!isset($cookie['name']) || - $cookie['name'] === '' || - strpos($cookie['name'], ';') !== false) { - throw new InvalidArgumentException( - '"name" should be non-empty and does not contain a ";"'); + + /** + * Get the cookie with a given name. + * + * @param string $name + * @return array The cookie, or null if no cookie with the given name is + * presented. + */ + public function getCookieNamed($name) + { + $cookies = $this->getCookies(); + foreach ($cookies as $cookie) { + if ($cookie['name'] === $name) { + return $cookie; + } + } + + return null; + } + + /** + * Get all the cookies for the current domain. + * + * @return array The array of cookies presented. + */ + public function getCookies() + { + return $this->executor->execute(DriverCommand::GET_ALL_COOKIES); + } + + private function validate(array $cookie) + { + if (!isset($cookie['name']) || + $cookie['name'] === '' || + strpos($cookie['name'], ';') !== false + ) { + throw new InvalidArgumentException( + '"name" should be non-empty and does not contain a ";"' + ); + } + + if (!isset($cookie['value'])) { + throw new InvalidArgumentException( + '"value" is required when setting a cookie.' + ); + } + + if (isset($cookie['domain']) && strpos($cookie['domain'], ':') !== false) { + throw new InvalidArgumentException( + '"domain" should not contain a port:' . (string) $cookie['domain'] + ); + } + } + + /** + * Return the interface for managing driver timeouts. + * + * @return WebDriverTimeouts + */ + public function timeouts() + { + return new WebDriverTimeouts($this->executor); } - if (!isset($cookie['value'])) { - throw new InvalidArgumentException( - '"value" is required when setting a cookie.'); + /** + * An abstraction allowing the driver to manipulate the browser's window + * + * @return WebDriverWindow + * @see WebDriverWindow + */ + public function window() + { + return new WebDriverWindow($this->executor); } - if (isset($cookie['domain']) && strpos($cookie['domain'], ':') !== false) { - throw new InvalidArgumentException( - '"domain" should not contain a port:'.(string)$cookie['domain']); + /** + * Get the log for a given log type. Log buffer is reset after each request. + * + * @param string $log_type The log type. + * @return array The list of log entries. + * @see https://code.google.com/p/selenium/wiki/JsonWireProtocol#Log_Type + */ + public function getLog($log_type) + { + return $this->executor->execute( + DriverCommand::GET_LOG, + array('type' => $log_type) + ); } - } - - /** - * Return the interface for managing driver timeouts. - * - * @return WebDriverTimeouts - */ - public function timeouts() { - return new WebDriverTimeouts($this->executor); - } - - /** - * An abstraction allowing the driver to manipulate the browser's window - * - * @return WebDriverWindow - * @see WebDriverWindow - */ - public function window() { - return new WebDriverWindow($this->executor); - } - - /** - * Get the log for a given log type. Log buffer is reset after each request. - * - * @param string $log_type The log type. - * @return array The list of log entries. - * @see https://code.google.com/p/selenium/wiki/JsonWireProtocol#Log_Type - */ - public function getLog($log_type) { - return $this->executor->execute( - DriverCommand::GET_LOG, - array('type' => $log_type) - ); - } - - /** - * Get available log types. - * - * @return array The list of available log types. - * @see https://code.google.com/p/selenium/wiki/JsonWireProtocol#Log_Type - */ - public function getAvailableLogTypes() { - return $this->executor->execute(DriverCommand::GET_AVAILABLE_LOG_TYPES); - } + /** + * Get available log types. + * + * @return array The list of available log types. + * @see https://code.google.com/p/selenium/wiki/JsonWireProtocol#Log_Type + */ + public function getAvailableLogTypes() + { + return $this->executor->execute(DriverCommand::GET_AVAILABLE_LOG_TYPES); + } } diff --git a/lib/WebDriverPlatform.php b/lib/WebDriverPlatform.php index 9dc42fabd..bb1923556 100644 --- a/lib/WebDriverPlatform.php +++ b/lib/WebDriverPlatform.php @@ -18,17 +18,18 @@ /** * The platforms supported by WebDriver. */ -class WebDriverPlatform { - const ANDROID = 'ANDROID'; - const ANY = 'ANY'; - const LINUX = 'LINUX'; - const MAC = 'MAC'; - const UNIX = 'UNIX'; - const VISTA = 'VISTA'; - const WINDOWS = 'WINDOWS'; - const XP = 'XP'; +class WebDriverPlatform +{ + const ANDROID = 'ANDROID'; + const ANY = 'ANY'; + const LINUX = 'LINUX'; + const MAC = 'MAC'; + const UNIX = 'UNIX'; + const VISTA = 'VISTA'; + const WINDOWS = 'WINDOWS'; + const XP = 'XP'; - private function __construct() - { - } + private function __construct() + { + } } diff --git a/lib/WebDriverPoint.php b/lib/WebDriverPoint.php index 0653eb988..e12977b22 100644 --- a/lib/WebDriverPoint.php +++ b/lib/WebDriverPoint.php @@ -18,67 +18,76 @@ /** * Represent a point. */ -class WebDriverPoint { +class WebDriverPoint +{ + private $x; + private $y; - private $x, $y; + public function __construct($x, $y) + { + $this->x = $x; + $this->y = $y; + } - public function __construct($x, $y) { - $this->x = $x; - $this->y = $y; - } + /** + * Get the x-coordinate. + * + * @return int The x-coordinate of the point. + */ + public function getX() + { + return $this->x; + } - /** - * Get the x-coordinate. - * - * @return int The x-coordinate of the point. - */ - public function getX() { - return $this->x; - } + /** + * Get the y-coordinate. + * + * @return int The y-coordinate of the point. + */ + public function getY() + { + return $this->y; + } - /** - * Get the y-coordinate. - * - * @return int The y-coordinate of the point. - */ - public function getY() { - return $this->y; - } + /** + * Set the point to a new position. + * + * @param int $new_x + * @param int $new_y + * @return WebDriverPoint The same instance with updated coordinates. + */ + public function move($new_x, $new_y) + { + $this->x = $new_x; + $this->y = $new_y; - /** - * Set the point to a new position. - * - * @param int $new_x - * @param int $new_y - * @return WebDriverPoint The same instance with updated coordinates. - */ - public function move($new_x, $new_y) { - $this->x = $new_x; - $this->y = $new_y; - return $this; - } + return $this; + } - /** - * Move the current by offsets. - * - * @param int $x_offset - * @param int $y_offset - * @return WebDriverPoint The same instance with updated coordinates. - */ - public function moveBy($x_offset, $y_offset) { - $this->x += $x_offset; - $this->y += $y_offset; - return $this; - } + /** + * Move the current by offsets. + * + * @param int $x_offset + * @param int $y_offset + * @return WebDriverPoint The same instance with updated coordinates. + */ + public function moveBy($x_offset, $y_offset) + { + $this->x += $x_offset; + $this->y += $y_offset; - /** - * Check whether the given point is the same as the instance. - * - * @param WebDriverPoint $point The point to be compared with. - * @return bool Whether the x and y coordinates are the same as the instance. - */ - public function equals(WebDriverPoint $point) { - return $this->x === $point->getX() && - $this->y === $point->getY(); - } + return $this; + } + + /** + * Check whether the given point is the same as the instance. + * + * @param WebDriverPoint $point The point to be compared with. + * @return bool Whether the x and y coordinates are the same as the instance. + */ + public function equals(WebDriverPoint $point) + { + return $this->x === $point->getX() && + $this->y === $point->getY(); + } } diff --git a/lib/WebDriverSearchContext.php b/lib/WebDriverSearchContext.php index d9cff1038..4d784c682 100644 --- a/lib/WebDriverSearchContext.php +++ b/lib/WebDriverSearchContext.php @@ -19,26 +19,26 @@ * The interface for WebDriver and WebDriverElement which is able to search for * WebDriverElement inside. */ -interface WebDriverSearchContext { +interface WebDriverSearchContext +{ + /** + * Find the first WebDriverElement within this element using the given + * mechanism. + * + * @param WebDriverBy $locator + * @return WebDriverElement NoSuchElementException is thrown in + * HttpCommandExecutor if no element is found. + * @see WebDriverBy + */ + public function findElement(WebDriverBy $locator); - /** - * Find the first WebDriverElement within this element using the given - * mechanism. - * - * @param WebDriverBy $locator - * @return WebDriverElement NoSuchElementException is thrown in - * HttpCommandExecutor if no element is found. - * @see WebDriverBy - */ - public function findElement(WebDriverBy $locator); - - /** - * Find all WebDriverElements within this element using the given mechanism. - * - * @param WebDriverBy $locator - * @return WebDriverElement[] A list of all WebDriverElements, or an empty array if - * nothing matches - * @see WebDriverBy - */ - public function findElements(WebDriverBy $locator); + /** + * Find all WebDriverElements within this element using the given mechanism. + * + * @param WebDriverBy $locator + * @return WebDriverElement[] A list of all WebDriverElements, or an empty array if + * nothing matches + * @see WebDriverBy + */ + public function findElements(WebDriverBy $locator); } diff --git a/lib/WebDriverSelect.php b/lib/WebDriverSelect.php index 20082dd0b..158690b2f 100644 --- a/lib/WebDriverSelect.php +++ b/lib/WebDriverSelect.php @@ -15,289 +15,291 @@ namespace Facebook\WebDriver; -use Facebook\WebDriver\Exception\UnexpectedTagNameException; use Facebook\WebDriver\Exception\NoSuchElementException; +use Facebook\WebDriver\Exception\UnexpectedTagNameException; use Facebook\WebDriver\Exception\UnsupportedOperationException; /** * Models a SELECT tag, providing helper methods to select and deselect options. */ -class WebDriverSelect { +class WebDriverSelect +{ + private $element; + private $isMulti; - private $element; - private $isMulti; + public function __construct(WebDriverElement $element) + { + $tag_name = $element->getTagName(); - public function __construct(WebDriverElement $element) { - $tag_name = $element->getTagName(); - - if ($tag_name !== 'select') { - throw new UnexpectedTagNameException('select', $tag_name); + if ($tag_name !== 'select') { + throw new UnexpectedTagNameException('select', $tag_name); + } + $this->element = $element; + $value = $element->getAttribute('multiple'); + $this->isMulti = ($value === 'true'); } - $this->element = $element; - $value = $element->getAttribute('multiple'); - $this->isMulti = ($value === 'true'); - } - /** - * @return bool Whether this select element support selecting multiple - * options. This is done by checking the value of the 'multiple' - * attribute. - */ - public function isMultiple() { - return $this->isMulti; - } - - /** - * @return WebDriverElement[] All options belonging to this select tag. - */ - public function getOptions() { - return $this->element->findElements(WebDriverBy::tagName('option')); - } - - /** - * @return WebDriverElement[] All selected options belonging to this select tag. - */ - public function getAllSelectedOptions() { - $selected_options = array(); - foreach ($this->getOptions() as $option) { - if ($option->isSelected()) { - $selected_options[] = $option; - } + /** + * @return bool Whether this select element support selecting multiple + * options. This is done by checking the value of the 'multiple' + * attribute. + */ + public function isMultiple() + { + return $this->isMulti; } - return $selected_options; - } - /** - * @throws NoSuchElementException - * - * @return WebDriverElement The first selected option in this select tag (or - * the currently selected option in a normal select) - */ - public function getFirstSelectedOption() { - foreach ($this->getOptions() as $option) { - if ($option->isSelected()) { - return $option; - } + /** + * @return WebDriverElement[] All options belonging to this select tag. + */ + public function getOptions() + { + return $this->element->findElements(WebDriverBy::tagName('option')); } - throw new NoSuchElementException('No options are selected'); - } + /** + * @return WebDriverElement[] All selected options belonging to this select tag. + */ + public function getAllSelectedOptions() + { + $selected_options = array(); + foreach ($this->getOptions() as $option) { + if ($option->isSelected()) { + $selected_options[] = $option; + } + } - /** - * Deselect all options in multiple select tag. - * - * @throws UnsupportedOperationException - * - * @return void - */ - public function deselectAll() { - if (!$this->isMultiple()) { - throw new UnsupportedOperationException( - 'You may only deselect all options of a multi-select' - ); + return $selected_options; } - foreach ($this->getOptions() as $option) { - if ($option->isSelected()) { - $option->click(); - } + /** + * @throws NoSuchElementException + * + * @return WebDriverElement The first selected option in this select tag (or + * the currently selected option in a normal select) + */ + public function getFirstSelectedOption() + { + foreach ($this->getOptions() as $option) { + if ($option->isSelected()) { + return $option; + } + } + + throw new NoSuchElementException('No options are selected'); } - } - /** - * Select the option at the given index. - * - * @param int $index The index of the option. (0-based) - * - * @throws NoSuchElementException - * - * @return void - */ - public function selectByIndex($index) { - $matched = false; - foreach ($this->getOptions() as $option) { - if ($option->getAttribute('index') === (string)$index) { - if (!$option->isSelected()) { - $option->click(); - if (!$this->isMultiple()) { - return; - } + /** + * Deselect all options in multiple select tag. + * + * @throws UnsupportedOperationException + */ + public function deselectAll() + { + if (!$this->isMultiple()) { + throw new UnsupportedOperationException( + 'You may only deselect all options of a multi-select' + ); + } + + foreach ($this->getOptions() as $option) { + if ($option->isSelected()) { + $option->click(); + } } - $matched = true; - } } - if (!$matched) { - throw new NoSuchElementException( - sprintf('Cannot locate option with index: %d', $index) - ); + + /** + * Select the option at the given index. + * + * @param int $index The index of the option. (0-based) + * + * @throws NoSuchElementException + */ + public function selectByIndex($index) + { + $matched = false; + foreach ($this->getOptions() as $option) { + if ($option->getAttribute('index') === (string) $index) { + if (!$option->isSelected()) { + $option->click(); + if (!$this->isMultiple()) { + return; + } + } + $matched = true; + } + } + if (!$matched) { + throw new NoSuchElementException( + sprintf('Cannot locate option with index: %d', $index) + ); + } } - } - /** - * Select all options that have value attribute matching the argument. That - * is, when given "foo" this would select an option like: - * - * ; - * - * @param string $value The value to match against. - * - * @throws NoSuchElementException - * - * @return void - */ - public function selectByValue($value) { - $matched = false; - $xpath = './/option[@value = '.$this->escapeQuotes($value).']'; - $options = $this->element->findElements(WebDriverBy::xpath($xpath)); + /** + * Select all options that have value attribute matching the argument. That + * is, when given "foo" this would select an option like: + * + * ; + * + * @param string $value The value to match against. + * + * @throws NoSuchElementException + */ + public function selectByValue($value) + { + $matched = false; + $xpath = './/option[@value = ' . $this->escapeQuotes($value) . ']'; + $options = $this->element->findElements(WebDriverBy::xpath($xpath)); - foreach ($options as $option) { - if (!$option->isSelected()) { - $option->click(); - } - if (!$this->isMultiple()) { - return; - } - $matched = true; - } + foreach ($options as $option) { + if (!$option->isSelected()) { + $option->click(); + } + if (!$this->isMultiple()) { + return; + } + $matched = true; + } - if (!$matched) { - throw new NoSuchElementException( - sprintf('Cannot locate option with value: %s', $value) - ); + if (!$matched) { + throw new NoSuchElementException( + sprintf('Cannot locate option with value: %s', $value) + ); + } } - } - /** - * Select all options that display text matching the argument. That is, when - * given "Bar" this would select an option like: - * - * ; - * - * @param string $text The visible text to match against. - * - * @throws NoSuchElementException - * - * @return void - */ - public function selectByVisibleText($text) { - $matched = false; - $xpath = './/option[normalize-space(.) = '.$this->escapeQuotes($text).']'; - $options = $this->element->findElements(WebDriverBy::xpath($xpath)); + /** + * Select all options that display text matching the argument. That is, when + * given "Bar" this would select an option like: + * + * ; + * + * @param string $text The visible text to match against. + * + * @throws NoSuchElementException + */ + public function selectByVisibleText($text) + { + $matched = false; + $xpath = './/option[normalize-space(.) = ' . $this->escapeQuotes($text) . ']'; + $options = $this->element->findElements(WebDriverBy::xpath($xpath)); - foreach ($options as $option) { - if (!$option->isSelected()) { - $option->click(); - } - if (!$this->isMultiple()) { - return; - } - $matched = true; - } + foreach ($options as $option) { + if (!$option->isSelected()) { + $option->click(); + } + if (!$this->isMultiple()) { + return; + } + $matched = true; + } - // Since the mechanism of getting the text in xpath is not the same as - // webdriver, use the expensive getText() to check if nothing is matched. - if (!$matched) { - foreach ($this->getOptions() as $option) { - if ($option->getText() === $text) { - if (!$option->isSelected()) { - $option->click(); - } - if (!$this->isMultiple()) { - return; - } - $matched = true; + // Since the mechanism of getting the text in xpath is not the same as + // webdriver, use the expensive getText() to check if nothing is matched. + if (!$matched) { + foreach ($this->getOptions() as $option) { + if ($option->getText() === $text) { + if (!$option->isSelected()) { + $option->click(); + } + if (!$this->isMultiple()) { + return; + } + $matched = true; + } + } } - } - } - if (!$matched) { - throw new NoSuchElementException( - sprintf('Cannot locate option with text: %s', $text) - ); + if (!$matched) { + throw new NoSuchElementException( + sprintf('Cannot locate option with text: %s', $text) + ); + } } - } - /** - * Deselect the option at the given index. - * - * @param int $index The index of the option. (0-based) - * @return void - */ - public function deselectByIndex($index) { - foreach ($this->getOptions() as $option) { - if ($option->getAttribute('index') === (string)$index && - $option->isSelected()) { - $option->click(); - } + /** + * Deselect the option at the given index. + * + * @param int $index The index of the option. (0-based) + */ + public function deselectByIndex($index) + { + foreach ($this->getOptions() as $option) { + if ($option->getAttribute('index') === (string) $index && $option->isSelected()) { + $option->click(); + } + } } - } - /** - * Deselect all options that have value attribute matching the argument. That - * is, when given "foo" this would select an option like: - * - * ; - * - * @param string $value The value to match against. - * @return void - */ - public function deselectByValue($value) { - $xpath = './/option[@value = '.$this->escapeQuotes($value).']'; - $options = $this->element->findElements(WebDriverBy::xpath($xpath)); - foreach ($options as $option) { - if ($option->isSelected()) { - $option->click(); - } + /** + * Deselect all options that have value attribute matching the argument. That + * is, when given "foo" this would select an option like: + * + * ; + * + * @param string $value The value to match against. + */ + public function deselectByValue($value) + { + $xpath = './/option[@value = ' . $this->escapeQuotes($value) . ']'; + $options = $this->element->findElements(WebDriverBy::xpath($xpath)); + foreach ($options as $option) { + if ($option->isSelected()) { + $option->click(); + } + } } - } - /** - * Deselect all options that display text matching the argument. That is, when - * given "Bar" this would select an option like: - * - * ; - * - * @param string $text The visible text to match against. - * @return void - */ - public function deselectByVisibleText($text) { - $xpath = './/option[normalize-space(.) = '.$this->escapeQuotes($text).']'; - $options = $this->element->findElements(WebDriverBy::xpath($xpath)); - foreach ($options as $option) { - if ($option->isSelected()) { - $option->click(); - } + /** + * Deselect all options that display text matching the argument. That is, when + * given "Bar" this would select an option like: + * + * ; + * + * @param string $text The visible text to match against. + */ + public function deselectByVisibleText($text) + { + $xpath = './/option[normalize-space(.) = ' . $this->escapeQuotes($text) . ']'; + $options = $this->element->findElements(WebDriverBy::xpath($xpath)); + foreach ($options as $option) { + if ($option->isSelected()) { + $option->click(); + } + } } - } - /** - * Convert strings with both quotes and ticks into: - * foo'"bar -> concat("foo'", '"', "bar") - * - * @param string $to_escape The string to be converted. - * @return string The escaped string. - */ - protected function escapeQuotes($to_escape) { - if (strpos($to_escape, '"') !== false && strpos($to_escape, "'") !== false) { - $substrings = explode('"', $to_escape); + /** + * Convert strings with both quotes and ticks into: + * foo'"bar -> concat("foo'", '"', "bar") + * + * @param string $to_escape The string to be converted. + * @return string The escaped string. + */ + protected function escapeQuotes($to_escape) + { + if (strpos($to_escape, '"') !== false && strpos($to_escape, "'") !== false) { + $substrings = explode('"', $to_escape); - $escaped = "concat("; - $first = true; - foreach ($substrings as $string) { - if (!$first) { - $escaped .= ", '\"',"; - $first = false; - } - $escaped .= '"' . $string . '"'; - } - return $escaped; - } + $escaped = 'concat('; + $first = true; + foreach ($substrings as $string) { + if (!$first) { + $escaped .= ", '\"',"; + $first = false; + } + $escaped .= '"' . $string . '"'; + } - if (strpos($to_escape, '"') !== false) { - return sprintf("'%s'", $to_escape); - } + return $escaped; + } - return sprintf('"%s"', $to_escape); - } + if (strpos($to_escape, '"') !== false) { + return sprintf("'%s'", $to_escape); + } + return sprintf('"%s"', $to_escape); + } } diff --git a/lib/WebDriverTargetLocator.php b/lib/WebDriverTargetLocator.php index 86e0939b8..d9fdf5c18 100644 --- a/lib/WebDriverTargetLocator.php +++ b/lib/WebDriverTargetLocator.php @@ -18,47 +18,47 @@ /** * Used to locate a given frame or window. */ -interface WebDriverTargetLocator { +interface WebDriverTargetLocator +{ + /** + * Switch to the main document if the page contains iframes. Otherwise, switch + * to the first frame on the page. + * + * @return WebDriver The driver focused on the top window or the first frame. + */ + public function defaultContent(); - /** - * Switch to the main document if the page contains iframes. Otherwise, switch - * to the first frame on the page. - * - * @return WebDriver The driver focused on the top window or the first frame. - */ - public function defaultContent(); + /** + * Switch to the iframe by its id or name. + * + * @param WebDriverElement|string $frame The WebDriverElement, + * the id or the name of the frame. + * @return WebDriver The driver focused on the given frame. + */ + public function frame($frame); - /** - * Switch to the iframe by its id or name. - * - * @param WebDriverElement|string $frame The WebDriverElement, - * the id or the name of the frame. - * @return WebDriver The driver focused on the given frame. - */ - public function frame($frame); + /** + * Switch the focus to another window by its handle. + * + * @param string $handle The handle of the window to be focused on. + * @return WebDriver Tge driver focused on the given window. + * @see WebDriver::getWindowHandles + */ + public function window($handle); - /** - * Switch the focus to another window by its handle. - * - * @param string $handle The handle of the window to be focused on. - * @return WebDriver Tge driver focused on the given window. - * @see WebDriver::getWindowHandles - */ - public function window($handle); + /** + * Switch to the currently active modal dialog for this particular driver + * instance. + * + * @return WebDriverAlert + */ + public function alert(); - /** - * Switch to the currently active modal dialog for this particular driver - * instance. - * - * @return WebDriverAlert - */ - public function alert(); - - /** - * Switches to the element that currently has focus within the document - * currently "switched to", or the body element if this cannot be detected. - * - * @return WebDriverElement - */ - public function activeElement(); + /** + * Switches to the element that currently has focus within the document + * currently "switched to", or the body element if this cannot be detected. + * + * @return WebDriverElement + */ + public function activeElement(); } diff --git a/lib/WebDriverTimeouts.php b/lib/WebDriverTimeouts.php index 2af6882ec..50b62f24f 100644 --- a/lib/WebDriverTimeouts.php +++ b/lib/WebDriverTimeouts.php @@ -20,56 +20,63 @@ /** * Managing timeout behavior for WebDriver instances. */ -class WebDriverTimeouts { +class WebDriverTimeouts +{ + protected $executor; - protected $executor; + public function __construct($executor) + { + $this->executor = $executor; + } - public function __construct($executor) { - $this->executor = $executor; - } + /** + * Specify the amount of time the driver should wait when searching for an + * element if it is not immediately present. + * + * @param int $seconds Wait time in second. + * @return WebDriverTimeouts The current instance. + */ + public function implicitlyWait($seconds) + { + $this->executor->execute( + DriverCommand::IMPLICITLY_WAIT, + array('ms' => $seconds * 1000) + ); - /** - * Specify the amount of time the driver should wait when searching for an - * element if it is not immediately present. - * - * @param int $seconds Wait time in second. - * @return WebDriverTimeouts The current instance. - */ - public function implicitlyWait($seconds) { - $this->executor->execute( - DriverCommand::IMPLICITLY_WAIT, - array('ms' => $seconds * 1000) - ); - return $this; - } + return $this; + } - /** - * Set the amount of time to wait for an asynchronous script to finish - * execution before throwing an error. - * - * @param int $seconds Wait time in second. - * @return WebDriverTimeouts The current instance. - */ - public function setScriptTimeout($seconds) { - $this->executor->execute( - DriverCommand::SET_SCRIPT_TIMEOUT, - array('ms' => $seconds * 1000) - ); - return $this; - } + /** + * Set the amount of time to wait for an asynchronous script to finish + * execution before throwing an error. + * + * @param int $seconds Wait time in second. + * @return WebDriverTimeouts The current instance. + */ + public function setScriptTimeout($seconds) + { + $this->executor->execute( + DriverCommand::SET_SCRIPT_TIMEOUT, + array('ms' => $seconds * 1000) + ); - /** - * Set the amount of time to wait for a page load to complete before throwing - * an error. - * - * @param int $seconds Wait time in second. - * @return WebDriverTimeouts The current instance. - */ - public function pageLoadTimeout($seconds) { - $this->executor->execute(DriverCommand::SET_TIMEOUT, array( - 'type' => 'page load', - 'ms' => $seconds * 1000, - )); - return $this; - } + return $this; + } + + /** + * Set the amount of time to wait for a page load to complete before throwing + * an error. + * + * @param int $seconds Wait time in second. + * @return WebDriverTimeouts The current instance. + */ + public function pageLoadTimeout($seconds) + { + $this->executor->execute(DriverCommand::SET_TIMEOUT, array( + 'type' => 'page load', + 'ms' => $seconds * 1000, + )); + + return $this; + } } diff --git a/lib/WebDriverUpAction.php b/lib/WebDriverUpAction.php index 2394f41a1..e8a480c9e 100644 --- a/lib/WebDriverUpAction.php +++ b/lib/WebDriverUpAction.php @@ -18,25 +18,25 @@ use Facebook\WebDriver\Interactions\Touch\WebDriverTouchAction; use Facebook\WebDriver\Interactions\Touch\WebDriverTouchScreen; -class WebDriverUpAction - extends WebDriverTouchAction - implements WebDriverAction { +class WebDriverUpAction extends WebDriverTouchAction implements WebDriverAction +{ + private $x; + private $y; - private $x; - private $y; + /** + * @param WebDriverTouchScreen $touch_screen + * @param int $x + * @param int $y + */ + public function __construct(WebDriverTouchScreen $touch_screen, $x, $y) + { + $this->x = $x; + $this->y = $y; + parent::__construct($touch_screen); + } - /** - * @param WebDriverTouchScreen $touch_screen - * @param int $x - * @param int $y - */ - public function __construct(WebDriverTouchScreen $touch_screen, $x, $y) { - $this->x = $x; - $this->y = $y; - parent::__construct($touch_screen); - } - - public function perform() { - $this->touchScreen->up($this->x, $this->y); - } + public function perform() + { + $this->touchScreen->up($this->x, $this->y); + } } diff --git a/lib/WebDriverWait.php b/lib/WebDriverWait.php index 5cddd29c3..a2297779d 100644 --- a/lib/WebDriverWait.php +++ b/lib/WebDriverWait.php @@ -24,57 +24,56 @@ * * @see WebDriverExpectedCondition. */ -class WebDriverWait { +class WebDriverWait +{ + protected $driver; + protected $timeout; + protected $interval; - protected $driver; - protected $timeout; - protected $interval; - - public function __construct( - WebDriver $driver, - $timeout_in_second = null, - $interval_in_millisecond = null) { - $this->driver = $driver; - $this->timeout = isset($timeout_in_second) ? $timeout_in_second : 30; - $this->interval = $interval_in_millisecond ?: 250; - } - - /** - * Calls the function provided with the driver as an argument until the return - * value is not falsey. - * - * @param (closure|WebDriverExpectedCondition) - * @param string $message - * - * @return mixed The return value of $func_or_ec + public function __construct(WebDriver $driver, $timeout_in_second = null, $interval_in_millisecond = null) + { + $this->driver = $driver; + $this->timeout = isset($timeout_in_second) ? $timeout_in_second : 30; + $this->interval = $interval_in_millisecond ?: 250; + } - * @throws NoSuchElementException - * @throws TimeOutException - * @throws \Exception - */ - public function until($func_or_ec, $message = "") { - $end = microtime(true) + $this->timeout; - $last_exception = null; + /** + * Calls the function provided with the driver as an argument until the return + * value is not falsey. + * + * @param (closure|WebDriverExpectedCondition) + * @param string $message + * + * @throws NoSuchElementException + * @throws TimeOutException + * @throws \Exception + * @return mixed The return value of $func_or_ec + */ + public function until($func_or_ec, $message = '') + { + $end = microtime(true) + $this->timeout; + $last_exception = null; - while ($end > microtime(true)) { - try { - if ($func_or_ec instanceof WebDriverExpectedCondition) { - $ret_val = call_user_func($func_or_ec->getApply(), $this->driver); - } else { - $ret_val = call_user_func($func_or_ec, $this->driver); + while ($end > microtime(true)) { + try { + if ($func_or_ec instanceof WebDriverExpectedCondition) { + $ret_val = call_user_func($func_or_ec->getApply(), $this->driver); + } else { + $ret_val = call_user_func($func_or_ec, $this->driver); + } + if ($ret_val) { + return $ret_val; + } + } catch (NoSuchElementException $e) { + $last_exception = $e; + } + usleep($this->interval * 1000); } - if ($ret_val) { - return $ret_val; + + if ($last_exception) { + throw $last_exception; } - } catch (NoSuchElementException $e) { - $last_exception = $e; - } - usleep($this->interval * 1000); - } - if ($last_exception) { - throw $last_exception; + throw new TimeOutException($message); } - throw new TimeOutException($message); - } } diff --git a/lib/WebDriverWindow.php b/lib/WebDriverWindow.php index dcfa19534..b63a681b3 100644 --- a/lib/WebDriverWindow.php +++ b/lib/WebDriverWindow.php @@ -21,128 +21,138 @@ /** * An abstraction allowing the driver to manipulate the browser's window */ -class WebDriverWindow { - - protected $executor; - - public function __construct($executor) { - $this->executor = $executor; - } - - /** - * Get the position of the current window, relative to the upper left corner - * of the screen. - * - * @return array The current window position. - */ - public function getPosition() { - $position = $this->executor->execute( - DriverCommand::GET_WINDOW_POSITION, - array(':windowHandle' => 'current') - ); - return new WebDriverPoint( - $position['x'], - $position['y'] - ); - } - - /** - * Get the size of the current window. This will return the outer window - * dimension, not just the view port. - * - * @return array The current window size. - */ - public function getSize() { - $size = $this->executor->execute( - DriverCommand::GET_WINDOW_SIZE, - array(':windowHandle' => 'current') - ); - return new WebDriverDimension( - $size['width'], - $size['height'] - ); - } - - /** - * Maximizes the current window if it is not already maximized - * - * @return WebDriverWindow The instance. - */ - public function maximize() { - $this->executor->execute( - DriverCommand::MAXIMIZE_WINDOW, - array(':windowHandle' => 'current') - ); - return $this; - } - - /** - * Set the size of the current window. This will change the outer window - * dimension, not just the view port. - * - * @param WebDriverDimension $size - * @return WebDriverWindow The instance. - */ - public function setSize(WebDriverDimension $size) { - $params = array( - 'width' => $size->getWidth(), - 'height' => $size->getHeight(), - ':windowHandle' => 'current', - ); - $this->executor->execute(DriverCommand::SET_WINDOW_SIZE, $params); - return $this; - } - - /** - * Set the position of the current window. This is relative to the upper left - * corner of the screen. - * - * @param WebDriverPoint $position - * @return WebDriverWindow The instance. - */ - public function setPosition(WebDriverPoint $position) { - $params = array( - 'x' => $position->getX(), - 'y' => $position->getY(), - ':windowHandle' => 'current', - ); - $this->executor->execute(DriverCommand::SET_WINDOW_POSITION, $params); - return $this; - } - - /** - * Get the current browser orientation. - * - * @return string Either LANDSCAPE|PORTRAIT - */ - public function getScreenOrientation() { - return $this->executor->execute(DriverCommand::GET_SCREEN_ORIENTATION); - } - - - /** - * Set the browser orientation. The orientation should either - * LANDSCAPE|PORTRAIT - * - * @param string $orientation - * @return WebDriverWindow The instance. - * @throws IndexOutOfBoundsException - */ - public function setScreenOrientation($orientation) { - $orientation = strtoupper($orientation); - if (!in_array($orientation, array('PORTRAIT', 'LANDSCAPE'))) { - throw new IndexOutOfBoundsException( - "Orientation must be either PORTRAIT, or LANDSCAPE" - ); +class WebDriverWindow +{ + protected $executor; + + public function __construct($executor) + { + $this->executor = $executor; + } + + /** + * Get the position of the current window, relative to the upper left corner + * of the screen. + * + * @return array The current window position. + */ + public function getPosition() + { + $position = $this->executor->execute( + DriverCommand::GET_WINDOW_POSITION, + array(':windowHandle' => 'current') + ); + + return new WebDriverPoint( + $position['x'], + $position['y'] + ); } - $this->executor->execute( - DriverCommand::SET_SCREEN_ORIENTATION, - array('orientation' => $orientation) - ); + /** + * Get the size of the current window. This will return the outer window + * dimension, not just the view port. + * + * @return array The current window size. + */ + public function getSize() + { + $size = $this->executor->execute( + DriverCommand::GET_WINDOW_SIZE, + array(':windowHandle' => 'current') + ); + + return new WebDriverDimension( + $size['width'], + $size['height'] + ); + } - return $this; + /** + * Maximizes the current window if it is not already maximized + * + * @return WebDriverWindow The instance. + */ + public function maximize() + { + $this->executor->execute( + DriverCommand::MAXIMIZE_WINDOW, + array(':windowHandle' => 'current') + ); + + return $this; + } - } + /** + * Set the size of the current window. This will change the outer window + * dimension, not just the view port. + * + * @param WebDriverDimension $size + * @return WebDriverWindow The instance. + */ + public function setSize(WebDriverDimension $size) + { + $params = array( + 'width' => $size->getWidth(), + 'height' => $size->getHeight(), + ':windowHandle' => 'current', + ); + $this->executor->execute(DriverCommand::SET_WINDOW_SIZE, $params); + + return $this; + } + /** + * Set the position of the current window. This is relative to the upper left + * corner of the screen. + * + * @param WebDriverPoint $position + * @return WebDriverWindow The instance. + */ + public function setPosition(WebDriverPoint $position) + { + $params = array( + 'x' => $position->getX(), + 'y' => $position->getY(), + ':windowHandle' => 'current', + ); + $this->executor->execute(DriverCommand::SET_WINDOW_POSITION, $params); + + return $this; + } + + /** + * Get the current browser orientation. + * + * @return string Either LANDSCAPE|PORTRAIT + */ + public function getScreenOrientation() + { + return $this->executor->execute(DriverCommand::GET_SCREEN_ORIENTATION); + } + + /** + * Set the browser orientation. The orientation should either + * LANDSCAPE|PORTRAIT + * + * @param string $orientation + * @throws IndexOutOfBoundsException + * @return WebDriverWindow The instance. + */ + public function setScreenOrientation($orientation) + { + $orientation = strtoupper($orientation); + if (!in_array($orientation, array('PORTRAIT', 'LANDSCAPE'))) { + throw new IndexOutOfBoundsException( + 'Orientation must be either PORTRAIT, or LANDSCAPE' + ); + } + + $this->executor->execute( + DriverCommand::SET_SCREEN_ORIENTATION, + array('orientation' => $orientation) + ); + + return $this; + } } diff --git a/tests/functional/BaseTest.php b/tests/functional/BaseTest.php index 351db6ed2..c9c522651 100644 --- a/tests/functional/BaseTest.php +++ b/tests/functional/BaseTest.php @@ -15,85 +15,95 @@ namespace Facebook\WebDriver; -class BaseTest extends WebDriverTestCase { - - public function testGetTitle() { - $this->driver->get($this->getTestPath('index.html')); - self::assertEquals( - 'php-webdriver test page', - $this->driver->getTitle() - ); - } - - public function testGetText() { - $this->driver->get($this->getTestPath('index.html')); - self::assertEquals( - 'Welcome to the facebook/php-webdriver testing page.', - $this->driver->findElement(WebDriverBy::id('welcome'))->getText() - ); - } +class BaseTest extends WebDriverTestCase +{ + public function testGetTitle() + { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'php-webdriver test page', + $this->driver->getTitle() + ); + } - public function testGetById() { - $this->driver->get($this->getTestPath('index.html')); - self::assertEquals( - 'Test by ID', - $this->driver->findElement(WebDriverBy::id('id_test'))->getText() - ); - } + public function testGetText() + { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Welcome to the facebook/php-webdriver testing page.', + $this->driver->findElement(WebDriverBy::id('welcome'))->getText() + ); + } - public function testGetByClassName() { - $this->driver->get($this->getTestPath('index.html')); - self::assertEquals( - 'Test by Class', - $this->driver->findElement(WebDriverBy::className('test_class'))->getText() - ); - } + public function testGetById() + { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Test by ID', + $this->driver->findElement(WebDriverBy::id('id_test'))->getText() + ); + } - public function testGetByCssSelector() { - $this->driver->get($this->getTestPath('index.html')); - self::assertEquals( - 'Test by Class', - $this->driver->findElement(WebDriverBy::cssSelector('.test_class'))->getText() - ); - } + public function testGetByClassName() + { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Test by Class', + $this->driver->findElement(WebDriverBy::className('test_class'))->getText() + ); + } - public function testGetByLinkText() { - $this->driver->get($this->getTestPath('index.html')); - self::assertEquals( - 'Click here', - $this->driver->findElement(WebDriverBy::linkText('Click here'))->getText() - ); - } + public function testGetByCssSelector() + { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Test by Class', + $this->driver->findElement(WebDriverBy::cssSelector('.test_class'))->getText() + ); + } - public function testGetByName() { - $this->driver->get($this->getTestPath('index.html')); - self::assertEquals( - 'Test Value', - $this->driver->findElement(WebDriverBy::name('test_name'))->getAttribute('value') - ); - } + public function testGetByLinkText() + { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Click here', + $this->driver->findElement(WebDriverBy::linkText('Click here'))->getText() + ); + } - public function testGetByXpath() { - $this->driver->get($this->getTestPath('index.html')); - self::assertEquals( - 'Test Value', - $this->driver->findElement(WebDriverBy::xpath('//input[@name="test_name"]'))->getAttribute('value') - ); - } + public function testGetByName() + { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Test Value', + $this->driver->findElement(WebDriverBy::name('test_name'))->getAttribute('value') + ); + } - public function testGetByPartialLinkText() { - $this->driver->get($this->getTestPath('index.html')); - self::assertEquals( - 'Click here', - $this->driver->findElement(WebDriverBy::partialLinkText('Click'))->getText() - ); - } + public function testGetByXpath() + { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Test Value', + $this->driver->findElement(WebDriverBy::xpath('//input[@name="test_name"]'))->getAttribute('value') + ); + } - public function testGetByTagName() { - $this->driver->get($this->getTestPath('index.html')); - self::assertEquals( - 'Test Value', - $this->driver->findElement(WebDriverBy::tagName('input'))->getAttribute('value') - ); - } + public function testGetByPartialLinkText() + { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Click here', + $this->driver->findElement(WebDriverBy::partialLinkText('Click'))->getText() + ); + } + + public function testGetByTagName() + { + $this->driver->get($this->getTestPath('index.html')); + self::assertEquals( + 'Test Value', + $this->driver->findElement(WebDriverBy::tagName('input'))->getAttribute('value') + ); + } } diff --git a/tests/functional/FileUploadTest.php b/tests/functional/FileUploadTest.php index 0ab233a14..29b878d9f 100644 --- a/tests/functional/FileUploadTest.php +++ b/tests/functional/FileUploadTest.php @@ -19,28 +19,31 @@ /** * An example test case for php-webdriver. - * - * Try running it by + * + * Try running it by * '../vendor/phpunit/phpunit/phpunit.php ExampleTestCase.php' */ -class FileUploadTest extends WebDriverTestCase { - - public function testFileUploading() { - $this->driver->get($this->getTestPath('upload.html')); - $file_input = $this->driver->findElement(WebDriverBy::id('upload')); - $file_input->setFileDetector(new LocalFileDetector()) - ->sendKeys(__DIR__ . '/files/FileUploadTestCaseFile.txt'); - self::assertNotEquals($this->getFilePath(), $file_input->getAttribute('value')); - } +class FileUploadTest extends WebDriverTestCase +{ + public function testFileUploading() + { + $this->driver->get($this->getTestPath('upload.html')); + $file_input = $this->driver->findElement(WebDriverBy::id('upload')); + $file_input->setFileDetector(new LocalFileDetector()) + ->sendKeys(__DIR__ . '/files/FileUploadTestCaseFile.txt'); + self::assertNotEquals($this->getFilePath(), $file_input->getAttribute('value')); + } - public function testUselessFileDetectorSendKeys() { - $this->driver->get($this->getTestPath('upload.html')); - $file_input = $this->driver->findElement(WebDriverBy::id('upload')); - $file_input->sendKeys($this->getFilePath()); - self::assertEquals($this->getFilePath(), $file_input->getAttribute('value')); - } - - private function getFilePath() { - return __DIR__ . '/files/FileUploadTestCaseFile.txt'; - } + public function testUselessFileDetectorSendKeys() + { + $this->driver->get($this->getTestPath('upload.html')); + $file_input = $this->driver->findElement(WebDriverBy::id('upload')); + $file_input->sendKeys($this->getFilePath()); + self::assertEquals($this->getFilePath(), $file_input->getAttribute('value')); + } + + private function getFilePath() + { + return __DIR__ . '/files/FileUploadTestCaseFile.txt'; + } } diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index 9be2153d3..fca694854 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -22,35 +22,38 @@ /** * The base class for test cases. */ -class WebDriverTestCase extends \PHPUnit_Framework_TestCase { +class WebDriverTestCase extends \PHPUnit_Framework_TestCase +{ + /** @var RemoteWebDriver $driver */ + protected $driver; - /** @var RemoteWebDriver $driver */ - protected $driver; + protected function setUp() + { + $this->driver = RemoteWebDriver::create( + 'http://localhost:4444/wd/hub', + array( + WebDriverCapabilityType::BROWSER_NAME + //=> WebDriverBrowserType::FIREFOX, + => WebDriverBrowserType::HTMLUNIT, + ) + ); + } - protected function setUp() { - $this->driver = RemoteWebDriver::create( - 'http://localhost:4444/wd/hub', - array( - WebDriverCapabilityType::BROWSER_NAME - //=> WebDriverBrowserType::FIREFOX, - => WebDriverBrowserType::HTMLUNIT, - ) - ); - } - - protected function tearDown() { - if ($this->driver) { - $this->driver->quit(); + protected function tearDown() + { + if ($this->driver) { + $this->driver->quit(); + } } - } - /** - * Get the URL of the test html. - * - * @param $path - * @return string - */ - protected function getTestPath($path) { - return 'file:///'.__DIR__.'/html/'.$path; - } + /** + * Get the URL of the test html. + * + * @param $path + * @return string + */ + protected function getTestPath($path) + { + return 'file:///' . __DIR__ . '/html/' . $path; + } } diff --git a/tests/unit/Interactions/Internal/WebDriverButtonReleaseActionTest.php b/tests/unit/Interactions/Internal/WebDriverButtonReleaseActionTest.php index 58373d9b9..a192190f9 100644 --- a/tests/unit/Interactions/Internal/WebDriverButtonReleaseActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverButtonReleaseActionTest.php @@ -18,28 +18,31 @@ use Facebook\WebDriver\Internal\WebDriverLocatable; use Facebook\WebDriver\WebDriverMouse; -class WebDriverButtonReleaseActionTest extends \PHPUnit_Framework_TestCase { - /** @var WebDriverButtonReleaseAction */ - private $webDriverButtonReleaseAction; - /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ - private $webDriverMouse; - /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ - private $locationProvider; +class WebDriverButtonReleaseActionTest extends \PHPUnit_Framework_TestCase +{ + /** @var WebDriverButtonReleaseAction */ + private $webDriverButtonReleaseAction; + /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ + private $webDriverMouse; + /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ + private $locationProvider; - public function setUp() { - $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); - $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); - $this->webDriverButtonReleaseAction = new WebDriverButtonReleaseAction( - $this->webDriverMouse, - $this->locationProvider - ); - } + public function setUp() + { + $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); + $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); + $this->webDriverButtonReleaseAction = new WebDriverButtonReleaseAction( + $this->webDriverMouse, + $this->locationProvider + ); + } - public function testPerformSendsMouseUpCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') - ->disableOriginalConstructor()->getMock(); - $this->webDriverMouse->expects($this->once())->method('mouseUp')->with($coords); - $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); - $this->webDriverButtonReleaseAction->perform(); - } + public function testPerformSendsMouseUpCommand() + { + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('mouseUp')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverButtonReleaseAction->perform(); + } } diff --git a/tests/unit/Interactions/Internal/WebDriverClickActionTest.php b/tests/unit/Interactions/Internal/WebDriverClickActionTest.php index c58d507d1..62162c77e 100644 --- a/tests/unit/Interactions/Internal/WebDriverClickActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverClickActionTest.php @@ -18,28 +18,31 @@ use Facebook\WebDriver\Internal\WebDriverLocatable; use Facebook\WebDriver\WebDriverMouse; -class WebDriverClickActionTest extends \PHPUnit_Framework_TestCase { - /** @var WebDriverClickAction */ - private $webDriverClickAction; - /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ - private $webDriverMouse; - /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ - private $locationProvider; +class WebDriverClickActionTest extends \PHPUnit_Framework_TestCase +{ + /** @var WebDriverClickAction */ + private $webDriverClickAction; + /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ + private $webDriverMouse; + /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ + private $locationProvider; - public function setUp() { - $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); - $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); - $this->webDriverClickAction = new WebDriverClickAction( - $this->webDriverMouse, - $this->locationProvider - ); - } + public function setUp() + { + $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); + $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); + $this->webDriverClickAction = new WebDriverClickAction( + $this->webDriverMouse, + $this->locationProvider + ); + } - public function testPerformSendsClickCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') - ->disableOriginalConstructor()->getMock(); - $this->webDriverMouse->expects($this->once())->method('click')->with($coords); - $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); - $this->webDriverClickAction->perform(); - } + public function testPerformSendsClickCommand() + { + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('click')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverClickAction->perform(); + } } diff --git a/tests/unit/Interactions/Internal/WebDriverClickAndHoldActionTest.php b/tests/unit/Interactions/Internal/WebDriverClickAndHoldActionTest.php index ae046c58e..9dec8b9aa 100644 --- a/tests/unit/Interactions/Internal/WebDriverClickAndHoldActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverClickAndHoldActionTest.php @@ -18,28 +18,31 @@ use Facebook\WebDriver\Internal\WebDriverLocatable; use Facebook\WebDriver\WebDriverMouse; -class WebDriverClickAndHoldActionTest extends \PHPUnit_Framework_TestCase { - /** @var WebDriverClickAndHoldAction */ - private $webDriverClickAndHoldAction; - /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ - private $webDriverMouse; - /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ - private $locationProvider; +class WebDriverClickAndHoldActionTest extends \PHPUnit_Framework_TestCase +{ + /** @var WebDriverClickAndHoldAction */ + private $webDriverClickAndHoldAction; + /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ + private $webDriverMouse; + /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ + private $locationProvider; - public function setUp() { - $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); - $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); - $this->webDriverClickAndHoldAction = new WebDriverClickAndHoldAction( - $this->webDriverMouse, - $this->locationProvider - ); - } + public function setUp() + { + $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); + $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); + $this->webDriverClickAndHoldAction = new WebDriverClickAndHoldAction( + $this->webDriverMouse, + $this->locationProvider + ); + } - public function testPerformSendsMouseDownCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') - ->disableOriginalConstructor()->getMock(); - $this->webDriverMouse->expects($this->once())->method('mouseDown')->with($coords); - $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); - $this->webDriverClickAndHoldAction->perform(); - } + public function testPerformSendsMouseDownCommand() + { + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('mouseDown')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverClickAndHoldAction->perform(); + } } diff --git a/tests/unit/Interactions/Internal/WebDriverContextClickActionTest.php b/tests/unit/Interactions/Internal/WebDriverContextClickActionTest.php index d9b9ef2b8..2c5a92547 100644 --- a/tests/unit/Interactions/Internal/WebDriverContextClickActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverContextClickActionTest.php @@ -18,28 +18,31 @@ use Facebook\WebDriver\Internal\WebDriverLocatable; use Facebook\WebDriver\WebDriverMouse; -class WebDriverContextClickActionTest extends \PHPUnit_Framework_TestCase { - /** @var WebDriverContextClickAction */ - private $webDriverContextClickAction; - /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ - private $webDriverMouse; - /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ - private $locationProvider; +class WebDriverContextClickActionTest extends \PHPUnit_Framework_TestCase +{ + /** @var WebDriverContextClickAction */ + private $webDriverContextClickAction; + /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ + private $webDriverMouse; + /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ + private $locationProvider; - public function setUp() { - $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); - $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); - $this->webDriverContextClickAction = new WebDriverContextClickAction( - $this->webDriverMouse, - $this->locationProvider - ); - } + public function setUp() + { + $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); + $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); + $this->webDriverContextClickAction = new WebDriverContextClickAction( + $this->webDriverMouse, + $this->locationProvider + ); + } - public function testPerformSendsContextClickCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') - ->disableOriginalConstructor()->getMock(); - $this->webDriverMouse->expects($this->once())->method('contextClick')->with($coords); - $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); - $this->webDriverContextClickAction->perform(); - } + public function testPerformSendsContextClickCommand() + { + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('contextClick')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverContextClickAction->perform(); + } } diff --git a/tests/unit/Interactions/Internal/WebDriverCoordinatesTest.php b/tests/unit/Interactions/Internal/WebDriverCoordinatesTest.php index d38c7220a..d782edf8c 100644 --- a/tests/unit/Interactions/Internal/WebDriverCoordinatesTest.php +++ b/tests/unit/Interactions/Internal/WebDriverCoordinatesTest.php @@ -15,26 +15,32 @@ namespace Facebook\WebDriver\Interactions\Internal; -class WebDriverCoordinatesTest extends \PHPUnit_Framework_TestCase { - public function testConstruct() { - $in_view_port = function() { }; - $on_page = function() { }; +class WebDriverCoordinatesTest extends \PHPUnit_Framework_TestCase +{ + public function testConstruct() + { + $in_view_port = function () { + }; + $on_page = function () { + }; - $webDriverCoordinates = new WebDriverCoordinates(null, $in_view_port, $on_page, 'auxiliary'); + $webDriverCoordinates = new WebDriverCoordinates(null, $in_view_port, $on_page, 'auxiliary'); - self::assertAttributeEquals(null, 'onScreen', $webDriverCoordinates); - self::assertAttributeEquals($in_view_port, 'inViewPort', $webDriverCoordinates); - self::assertAttributeEquals($on_page, 'onPage', $webDriverCoordinates); - self::assertAttributeEquals('auxiliary', 'auxiliary', $webDriverCoordinates); - } + self::assertAttributeEquals(null, 'onScreen', $webDriverCoordinates); + self::assertAttributeEquals($in_view_port, 'inViewPort', $webDriverCoordinates); + self::assertAttributeEquals($on_page, 'onPage', $webDriverCoordinates); + self::assertAttributeEquals('auxiliary', 'auxiliary', $webDriverCoordinates); + } - public function testGetAuxiliary() - { - $in_view_port = function() { }; - $on_page = function() { }; + public function testGetAuxiliary() + { + $in_view_port = function () { + }; + $on_page = function () { + }; - $webDriverCoordinates = new WebDriverCoordinates(null, $in_view_port, $on_page, 'auxiliary'); + $webDriverCoordinates = new WebDriverCoordinates(null, $in_view_port, $on_page, 'auxiliary'); - self::assertEquals('auxiliary', $webDriverCoordinates->getAuxiliary()); - } + self::assertEquals('auxiliary', $webDriverCoordinates->getAuxiliary()); + } } diff --git a/tests/unit/Interactions/Internal/WebDriverDoubleClickActionTest.php b/tests/unit/Interactions/Internal/WebDriverDoubleClickActionTest.php index f1c6d3a02..b83115f77 100644 --- a/tests/unit/Interactions/Internal/WebDriverDoubleClickActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverDoubleClickActionTest.php @@ -18,28 +18,31 @@ use Facebook\WebDriver\Internal\WebDriverLocatable; use Facebook\WebDriver\WebDriverMouse; -class WebDriverDoubleClickActionTest extends \PHPUnit_Framework_TestCase { - /** @var WebDriverDoubleClickAction */ - private $webDriverDoubleClickAction; - /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ - private $webDriverMouse; - /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ - private $locationProvider; +class WebDriverDoubleClickActionTest extends \PHPUnit_Framework_TestCase +{ + /** @var WebDriverDoubleClickAction */ + private $webDriverDoubleClickAction; + /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ + private $webDriverMouse; + /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ + private $locationProvider; - public function setUp() { - $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); - $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); - $this->webDriverDoubleClickAction = new WebDriverDoubleClickAction( - $this->webDriverMouse, - $this->locationProvider - ); - } + public function setUp() + { + $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); + $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); + $this->webDriverDoubleClickAction = new WebDriverDoubleClickAction( + $this->webDriverMouse, + $this->locationProvider + ); + } - public function testPerformSendsDoubleClickCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') - ->disableOriginalConstructor()->getMock(); - $this->webDriverMouse->expects($this->once())->method('doubleClick')->with($coords); - $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); - $this->webDriverDoubleClickAction->perform(); - } + public function testPerformSendsDoubleClickCommand() + { + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('doubleClick')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverDoubleClickAction->perform(); + } } diff --git a/tests/unit/Interactions/Internal/WebDriverKeyDownActionTest.php b/tests/unit/Interactions/Internal/WebDriverKeyDownActionTest.php index 10a6201e0..e1cb8acbc 100644 --- a/tests/unit/Interactions/Internal/WebDriverKeyDownActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverKeyDownActionTest.php @@ -19,34 +19,37 @@ use Facebook\WebDriver\WebDriverKeyboard; use Facebook\WebDriver\WebDriverMouse; -class WebDriverKeyDownActionTest extends \PHPUnit_Framework_TestCase { - /** @var WebDriverKeyDownAction */ - private $webDriverKeyDownAction; - /** @var WebDriverKeyboard|\PHPUnit_Framework_MockObject_MockObject */ - private $webDriverKeyboard; - /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ - private $webDriverMouse; - /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ - private $locationProvider; +class WebDriverKeyDownActionTest extends \PHPUnit_Framework_TestCase +{ + /** @var WebDriverKeyDownAction */ + private $webDriverKeyDownAction; + /** @var WebDriverKeyboard|\PHPUnit_Framework_MockObject_MockObject */ + private $webDriverKeyboard; + /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ + private $webDriverMouse; + /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ + private $locationProvider; - public function setUp() { - $this->webDriverKeyboard = $this->getMockBuilder('Facebook\WebDriver\WebDriverKeyboard')->getMock(); - $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); - $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); + public function setUp() + { + $this->webDriverKeyboard = $this->getMockBuilder('Facebook\WebDriver\WebDriverKeyboard')->getMock(); + $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); + $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); - $this->webDriverKeyDownAction = new WebDriverKeyDownAction( - $this->webDriverKeyboard, - $this->webDriverMouse, - $this->locationProvider - ); - } + $this->webDriverKeyDownAction = new WebDriverKeyDownAction( + $this->webDriverKeyboard, + $this->webDriverMouse, + $this->locationProvider + ); + } - public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') - ->disableOriginalConstructor()->getMock(); - $this->webDriverMouse->expects($this->once())->method('click')->with($coords); - $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); - $this->webDriverKeyboard->expects($this->once())->method('pressKey'); - $this->webDriverKeyDownAction->perform(); - } + public function testPerformFocusesOnElementAndSendPressKeyCommand() + { + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('click')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverKeyboard->expects($this->once())->method('pressKey'); + $this->webDriverKeyDownAction->perform(); + } } diff --git a/tests/unit/Interactions/Internal/WebDriverKeyUpActionTest.php b/tests/unit/Interactions/Internal/WebDriverKeyUpActionTest.php index 75fb1bde9..c21ac24c1 100644 --- a/tests/unit/Interactions/Internal/WebDriverKeyUpActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverKeyUpActionTest.php @@ -19,35 +19,38 @@ use Facebook\WebDriver\WebDriverKeyboard; use Facebook\WebDriver\WebDriverMouse; -class WebDriverKeyUpActionTest extends \PHPUnit_Framework_TestCase { - /** @var WebDriverKeyUpAction */ - private $webDriverKeyUpAction; - /** @var WebDriverKeyboard|\PHPUnit_Framework_MockObject_MockObject */ - private $webDriverKeyboard; - /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ - private $webDriverMouse; - /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ - private $locationProvider; +class WebDriverKeyUpActionTest extends \PHPUnit_Framework_TestCase +{ + /** @var WebDriverKeyUpAction */ + private $webDriverKeyUpAction; + /** @var WebDriverKeyboard|\PHPUnit_Framework_MockObject_MockObject */ + private $webDriverKeyboard; + /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ + private $webDriverMouse; + /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ + private $locationProvider; - public function setUp() { - $this->webDriverKeyboard = $this->getMockBuilder('Facebook\WebDriver\WebDriverKeyboard')->getMock(); - $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); - $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); + public function setUp() + { + $this->webDriverKeyboard = $this->getMockBuilder('Facebook\WebDriver\WebDriverKeyboard')->getMock(); + $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); + $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); - $this->webDriverKeyUpAction = new WebDriverKeyUpAction( - $this->webDriverKeyboard, - $this->webDriverMouse, - $this->locationProvider, - 'a' - ); - } + $this->webDriverKeyUpAction = new WebDriverKeyUpAction( + $this->webDriverKeyboard, + $this->webDriverMouse, + $this->locationProvider, + 'a' + ); + } - public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') - ->disableOriginalConstructor()->getMock(); - $this->webDriverMouse->expects($this->once())->method('click')->with($coords); - $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); - $this->webDriverKeyboard->expects($this->once())->method('releaseKey')->with('a'); - $this->webDriverKeyUpAction->perform(); - } + public function testPerformFocusesOnElementAndSendPressKeyCommand() + { + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('click')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverKeyboard->expects($this->once())->method('releaseKey')->with('a'); + $this->webDriverKeyUpAction->perform(); + } } diff --git a/tests/unit/Interactions/Internal/WebDriverMouseMoveActionTest.php b/tests/unit/Interactions/Internal/WebDriverMouseMoveActionTest.php index 10edb2588..fe3ca9379 100644 --- a/tests/unit/Interactions/Internal/WebDriverMouseMoveActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverMouseMoveActionTest.php @@ -18,29 +18,32 @@ use Facebook\WebDriver\Internal\WebDriverLocatable; use Facebook\WebDriver\WebDriverMouse; -class WebDriverMouseMoveActionTest extends \PHPUnit_Framework_TestCase { - /** @var WebDriverMouseMoveAction */ - private $webDriverMouseMoveAction; - /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ - private $webDriverMouse; - /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ - private $locationProvider; +class WebDriverMouseMoveActionTest extends \PHPUnit_Framework_TestCase +{ + /** @var WebDriverMouseMoveAction */ + private $webDriverMouseMoveAction; + /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ + private $webDriverMouse; + /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ + private $locationProvider; - public function setUp() { - $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); - $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); + public function setUp() + { + $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); + $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); - $this->webDriverMouseMoveAction = new WebDriverMouseMoveAction( - $this->webDriverMouse, - $this->locationProvider - ); - } + $this->webDriverMouseMoveAction = new WebDriverMouseMoveAction( + $this->webDriverMouse, + $this->locationProvider + ); + } - public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') - ->disableOriginalConstructor()->getMock(); - $this->webDriverMouse->expects($this->once())->method('mouseMove')->with($coords); - $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); - $this->webDriverMouseMoveAction->perform(); - } + public function testPerformFocusesOnElementAndSendPressKeyCommand() + { + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('mouseMove')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverMouseMoveAction->perform(); + } } diff --git a/tests/unit/Interactions/Internal/WebDriverMouseToOffsetActionTest.php b/tests/unit/Interactions/Internal/WebDriverMouseToOffsetActionTest.php index aeec43a5a..37a2853ba 100644 --- a/tests/unit/Interactions/Internal/WebDriverMouseToOffsetActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverMouseToOffsetActionTest.php @@ -18,33 +18,36 @@ use Facebook\WebDriver\Internal\WebDriverLocatable; use Facebook\WebDriver\WebDriverMouse; -class WebDriverMouseToOffsetActionTest extends \PHPUnit_Framework_TestCase { - /** - * @type WebDriverMoveToOffsetAction - */ - private $webDriverMoveToOffsetAction; - /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ - private $webDriverMouse; - /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ - private $locationProvider; +class WebDriverMouseToOffsetActionTest extends \PHPUnit_Framework_TestCase +{ + /** + * @type WebDriverMoveToOffsetAction + */ + private $webDriverMoveToOffsetAction; + /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ + private $webDriverMouse; + /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ + private $locationProvider; - public function setUp() { - $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); - $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); + public function setUp() + { + $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); + $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); - $this->webDriverMoveToOffsetAction = new WebDriverMoveToOffsetAction( - $this->webDriverMouse, - $this->locationProvider, - 150, - 200 - ); - } + $this->webDriverMoveToOffsetAction = new WebDriverMoveToOffsetAction( + $this->webDriverMouse, + $this->locationProvider, + 150, + 200 + ); + } - public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') - ->disableOriginalConstructor()->getMock(); - $this->webDriverMouse->expects($this->once())->method('mouseMove')->with($coords, 150, 200); - $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); - $this->webDriverMoveToOffsetAction->perform(); - } + public function testPerformFocusesOnElementAndSendPressKeyCommand() + { + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); + $this->webDriverMouse->expects($this->once())->method('mouseMove')->with($coords, 150, 200); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverMoveToOffsetAction->perform(); + } } diff --git a/tests/unit/Interactions/Internal/WebDriverSendKeysActionTest.php b/tests/unit/Interactions/Internal/WebDriverSendKeysActionTest.php index bf1a5b8a7..82a736dea 100644 --- a/tests/unit/Interactions/Internal/WebDriverSendKeysActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverSendKeysActionTest.php @@ -19,38 +19,41 @@ use Facebook\WebDriver\WebDriverKeyboard; use Facebook\WebDriver\WebDriverMouse; -class WebDriverSendKeysActionTest extends \PHPUnit_Framework_TestCase { - /** @var WebDriverSendKeysAction */ - private $webDriverSendKeysAction; - /** @var WebDriverKeyboard|\PHPUnit_Framework_MockObject_MockObject */ - private $webDriverKeyboard; - /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ - private $webDriverMouse; - /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ - private $locationProvider; - /** @var array */ - private $keys; +class WebDriverSendKeysActionTest extends \PHPUnit_Framework_TestCase +{ + /** @var WebDriverSendKeysAction */ + private $webDriverSendKeysAction; + /** @var WebDriverKeyboard|\PHPUnit_Framework_MockObject_MockObject */ + private $webDriverKeyboard; + /** @var WebDriverMouse|\PHPUnit_Framework_MockObject_MockObject */ + private $webDriverMouse; + /** @var WebDriverLocatable|\PHPUnit_Framework_MockObject_MockObject */ + private $locationProvider; + /** @var array */ + private $keys; - public function setUp() { - $this->webDriverKeyboard = $this->getMockBuilder('Facebook\WebDriver\WebDriverKeyboard')->getMock(); - $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); - $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); + public function setUp() + { + $this->webDriverKeyboard = $this->getMockBuilder('Facebook\WebDriver\WebDriverKeyboard')->getMock(); + $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); + $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); - $this->keys = array('t', 'e', 's', 't'); - $this->webDriverSendKeysAction = new WebDriverSendKeysAction( - $this->webDriverKeyboard, - $this->webDriverMouse, - $this->locationProvider, - $this->keys - ); - } + $this->keys = array('t', 'e', 's', 't'); + $this->webDriverSendKeysAction = new WebDriverSendKeysAction( + $this->webDriverKeyboard, + $this->webDriverMouse, + $this->locationProvider, + $this->keys + ); + } - public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') - ->disableOriginalConstructor()->getMock(); - $this->webDriverKeyboard->expects($this->once())->method('sendKeys')->with($this->keys); - $this->webDriverMouse->expects($this->once())->method('click')->with($coords); - $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); - $this->webDriverSendKeysAction->perform(); - } + public function testPerformFocusesOnElementAndSendPressKeyCommand() + { + $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + ->disableOriginalConstructor()->getMock(); + $this->webDriverKeyboard->expects($this->once())->method('sendKeys')->with($this->keys); + $this->webDriverMouse->expects($this->once())->method('click')->with($coords); + $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); + $this->webDriverSendKeysAction->perform(); + } } diff --git a/tests/unit/Remote/DesiredCapabilitiesTest.php b/tests/unit/Remote/DesiredCapabilitiesTest.php index 7f187f706..54f17a14d 100644 --- a/tests/unit/Remote/DesiredCapabilitiesTest.php +++ b/tests/unit/Remote/DesiredCapabilitiesTest.php @@ -22,112 +22,111 @@ class DesiredCapabilitiesTest extends \PHPUnit_Framework_TestCase { - public function testShouldInstantiateWithCapabilitiesGivenInConstructor() - { - $capabilities = new DesiredCapabilities( - array('fooKey' => 'fooVal', WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY) - ); - - $this->assertSame('fooVal', $capabilities->getCapability('fooKey')); - $this->assertSame('ANY', $capabilities->getPlatform()); - - $this->assertSame( - array('fooKey' => 'fooVal', WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY), - $capabilities->toArray() - ); - } - - public function testShouldInstantiateEmptyInstance() - { - $capabilities = new DesiredCapabilities(); - - $this->assertNull($capabilities->getCapability('foo')); - $this->assertSame(array(), $capabilities->toArray()); - } - - public function testShouldProvideAccessToCapabilitiesUsingSettersAndGetters() - { - $capabilities = new DesiredCapabilities(); - // generic capability setter - $capabilities->setCapability('custom', 1337); - // specific setters - $capabilities->setBrowserName(WebDriverBrowserType::CHROME); - $capabilities->setPlatform(WebDriverPlatform::LINUX); - $capabilities->setVersion(333); - - $this->assertSame(1337, $capabilities->getCapability('custom')); - $this->assertSame(WebDriverBrowserType::CHROME, $capabilities->getBrowserName()); - $this->assertSame(WebDriverPlatform::LINUX, $capabilities->getPlatform()); - $this->assertSame(333, $capabilities->getVersion()); - } - - /** - * @expectedException \Exception - * @expectedExceptionMessage isJavascriptEnable() is a htmlunit-only option - */ - public function testShouldNotAllowToDisableJavascriptForNonHtmlUnitBrowser() - { - $capabilities = new DesiredCapabilities(); - $capabilities->setBrowserName(WebDriverBrowserType::FIREFOX); - $capabilities->setJavascriptEnabled(false); - } - - public function testShouldAllowToDisableJavascriptForHtmlUnitBrowser() - { - $capabilities = new DesiredCapabilities(); - $capabilities->setBrowserName(WebDriverBrowserType::HTMLUNIT); - $capabilities->setJavascriptEnabled(false); - - $this->assertFalse($capabilities->isJavascriptEnabled()); - } - - /** - * @dataProvider browserCapabilitiesProvider - * @param string $setupMethod - * @param string $expectedBrowser - * @param string $expectedPlatform - */ - public function testShouldProvideShortcutSetupForCapabilitiesOfEachBrowser( - $setupMethod, - $expectedBrowser, - $expectedPlatform - ) - { - /** @var DesiredCapabilities $capabilities */ - $capabilities = call_user_func(array('Facebook\WebDriver\Remote\DesiredCapabilities', $setupMethod)); - - $this->assertSame($expectedBrowser, $capabilities->getBrowserName()); - $this->assertSame($expectedPlatform, $capabilities->getPlatform()); - } - - /** - * @return array - */ - public function browserCapabilitiesProvider() - { - return array( - array('android', WebDriverBrowserType::ANDROID, WebDriverPlatform::ANDROID), - array('chrome', WebDriverBrowserType::CHROME, WebDriverPlatform::ANY), - array('firefox', WebDriverBrowserType::FIREFOX, WebDriverPlatform::ANY), - array('htmlUnit', WebDriverBrowserType::HTMLUNIT, WebDriverPlatform::ANY), - array('htmlUnitWithJS', WebDriverBrowserType::HTMLUNIT, WebDriverPlatform::ANY), - array('internetExplorer', WebDriverBrowserType::IE, WebDriverPlatform::WINDOWS), - array('iphone', WebDriverBrowserType::IPHONE, WebDriverPlatform::MAC), - array('ipad', WebDriverBrowserType::IPAD, WebDriverPlatform::MAC), - array('opera', WebDriverBrowserType::OPERA, WebDriverPlatform::ANY), - array('safari', WebDriverBrowserType::SAFARI, WebDriverPlatform::ANY), - array('phantomjs', WebDriverBrowserType::PHANTOMJS, WebDriverPlatform::ANY), - ); - } - - public function testShouldSetupFirefoxProfileAndDisableReaderViewForFirefoxBrowser() - { - $capabilities = DesiredCapabilities::firefox(); - - /** @var FirefoxProfile $firefoxProfile */ - $firefoxProfile = $capabilities->getCapability(FirefoxDriver::PROFILE); - $this->assertInstanceOf('Facebook\WebDriver\Firefox\FirefoxProfile', $firefoxProfile); - - $this->assertSame('false', $firefoxProfile->getPreference(FirefoxPreferences::READER_PARSE_ON_LOAD_ENABLED)); - } + public function testShouldInstantiateWithCapabilitiesGivenInConstructor() + { + $capabilities = new DesiredCapabilities( + array('fooKey' => 'fooVal', WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY) + ); + + $this->assertSame('fooVal', $capabilities->getCapability('fooKey')); + $this->assertSame('ANY', $capabilities->getPlatform()); + + $this->assertSame( + array('fooKey' => 'fooVal', WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY), + $capabilities->toArray() + ); + } + + public function testShouldInstantiateEmptyInstance() + { + $capabilities = new DesiredCapabilities(); + + $this->assertNull($capabilities->getCapability('foo')); + $this->assertSame(array(), $capabilities->toArray()); + } + + public function testShouldProvideAccessToCapabilitiesUsingSettersAndGetters() + { + $capabilities = new DesiredCapabilities(); + // generic capability setter + $capabilities->setCapability('custom', 1337); + // specific setters + $capabilities->setBrowserName(WebDriverBrowserType::CHROME); + $capabilities->setPlatform(WebDriverPlatform::LINUX); + $capabilities->setVersion(333); + + $this->assertSame(1337, $capabilities->getCapability('custom')); + $this->assertSame(WebDriverBrowserType::CHROME, $capabilities->getBrowserName()); + $this->assertSame(WebDriverPlatform::LINUX, $capabilities->getPlatform()); + $this->assertSame(333, $capabilities->getVersion()); + } + + /** + * @expectedException \Exception + * @expectedExceptionMessage isJavascriptEnable() is a htmlunit-only option + */ + public function testShouldNotAllowToDisableJavascriptForNonHtmlUnitBrowser() + { + $capabilities = new DesiredCapabilities(); + $capabilities->setBrowserName(WebDriverBrowserType::FIREFOX); + $capabilities->setJavascriptEnabled(false); + } + + public function testShouldAllowToDisableJavascriptForHtmlUnitBrowser() + { + $capabilities = new DesiredCapabilities(); + $capabilities->setBrowserName(WebDriverBrowserType::HTMLUNIT); + $capabilities->setJavascriptEnabled(false); + + $this->assertFalse($capabilities->isJavascriptEnabled()); + } + + /** + * @dataProvider browserCapabilitiesProvider + * @param string $setupMethod + * @param string $expectedBrowser + * @param string $expectedPlatform + */ + public function testShouldProvideShortcutSetupForCapabilitiesOfEachBrowser( + $setupMethod, + $expectedBrowser, + $expectedPlatform + ) { + /** @var DesiredCapabilities $capabilities */ + $capabilities = call_user_func(array('Facebook\WebDriver\Remote\DesiredCapabilities', $setupMethod)); + + $this->assertSame($expectedBrowser, $capabilities->getBrowserName()); + $this->assertSame($expectedPlatform, $capabilities->getPlatform()); + } + + /** + * @return array + */ + public function browserCapabilitiesProvider() + { + return array( + array('android', WebDriverBrowserType::ANDROID, WebDriverPlatform::ANDROID), + array('chrome', WebDriverBrowserType::CHROME, WebDriverPlatform::ANY), + array('firefox', WebDriverBrowserType::FIREFOX, WebDriverPlatform::ANY), + array('htmlUnit', WebDriverBrowserType::HTMLUNIT, WebDriverPlatform::ANY), + array('htmlUnitWithJS', WebDriverBrowserType::HTMLUNIT, WebDriverPlatform::ANY), + array('internetExplorer', WebDriverBrowserType::IE, WebDriverPlatform::WINDOWS), + array('iphone', WebDriverBrowserType::IPHONE, WebDriverPlatform::MAC), + array('ipad', WebDriverBrowserType::IPAD, WebDriverPlatform::MAC), + array('opera', WebDriverBrowserType::OPERA, WebDriverPlatform::ANY), + array('safari', WebDriverBrowserType::SAFARI, WebDriverPlatform::ANY), + array('phantomjs', WebDriverBrowserType::PHANTOMJS, WebDriverPlatform::ANY), + ); + } + + public function testShouldSetupFirefoxProfileAndDisableReaderViewForFirefoxBrowser() + { + $capabilities = DesiredCapabilities::firefox(); + + /** @var FirefoxProfile $firefoxProfile */ + $firefoxProfile = $capabilities->getCapability(FirefoxDriver::PROFILE); + $this->assertInstanceOf('Facebook\WebDriver\Firefox\FirefoxProfile', $firefoxProfile); + + $this->assertSame('false', $firefoxProfile->getPreference(FirefoxPreferences::READER_PARSE_ON_LOAD_ENABLED)); + } } diff --git a/tests/unit/Remote/WebDriverCommandTest.php b/tests/unit/Remote/WebDriverCommandTest.php index b4b9fc052..c315b4b46 100644 --- a/tests/unit/Remote/WebDriverCommandTest.php +++ b/tests/unit/Remote/WebDriverCommandTest.php @@ -17,12 +17,12 @@ class WebDriverCommandTest extends \PHPUnit_Framework_TestCase { - public function testShouldSetOptionsUsingConstructot() - { - $command = new WebDriverCommand('session-id-123', 'bar-baz-name', array('foo' => 'bar')); + public function testShouldSetOptionsUsingConstructot() + { + $command = new WebDriverCommand('session-id-123', 'bar-baz-name', array('foo' => 'bar')); - $this->assertSame('session-id-123', $command->getSessionID()); - $this->assertSame('bar-baz-name', $command->getName()); - $this->assertSame(array('foo' => 'bar'), $command->getParameters()); - } + $this->assertSame('session-id-123', $command->getSessionID()); + $this->assertSame('bar-baz-name', $command->getName()); + $this->assertSame(array('foo' => 'bar'), $command->getParameters()); + } } From c8d18c6a6a214225aee6724c6a2f955cce163bb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 30 Jul 2016 16:19:22 +0200 Subject: [PATCH 218/784] Check codestyle on Travis --- .gitignore | 3 ++- .php_cs | 41 +++++++++++++++++++++++++++++++++++++++++ .travis.yml | 25 +++++++++++++++++-------- composer.json | 4 +++- 4 files changed, 63 insertions(+), 10 deletions(-) create mode 100644 .php_cs diff --git a/.gitignore b/.gitignore index 88ca8c5ff..2444076bd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,11 @@ composer.phar composer.lock vendor +.php_cs.cache # generic files to ignore *.lock *.DS_Store *~ *.swp -.idea \ No newline at end of file +.idea diff --git a/.php_cs b/.php_cs new file mode 100644 index 000000000..752fb9606 --- /dev/null +++ b/.php_cs @@ -0,0 +1,41 @@ +in(array(__DIR__ . '/lib', __DIR__ . '/tests')); + +return Symfony\CS\Config\Config::create() + ->fixers(array( + 'duplicate_semicolon', + 'extra_empty_lines', + 'multiline_array_trailing_comma', + 'namespace_no_leading_whitespace', + 'new_with_braces', + 'no_blank_lines_after_class_opening', + 'no_empty_lines_after_phpdocs', + 'object_operator', + 'operators_spaces', + 'trim_array_spaces', + 'phpdoc_indent', + 'phpdoc_no_access', + 'phpdoc_no_empty_return', + 'phpdoc_no_package', + 'phpdoc_scalar', + 'phpdoc_trim', + 'phpdoc_types', + 'phpdoc_order', + 'unused_use', + 'ordered_use', + 'remove_leading_slash_use', + 'remove_lines_between_uses', + 'function_typehint_space', + 'self_accessor', + 'single_array_no_trailing_comma', + 'single_blank_line_before_namespace', + 'single_quote', + 'spaces_cast', + 'whitespacy_lines', + 'newline_after_open_tag', + )) + ->level(Symfony\CS\FixerInterface::PSR2_LEVEL) + ->setUsingCache(true) + ->finder($finder); diff --git a/.travis.yml b/.travis.yml index 20d852e96..eb8e94685 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,12 @@ php: - 7 - hhvm +matrix: + include: + # Add PHP 7 build to check codestyle only in PHP 7 build + - php: 7 + env: CHECK_CODESTYLE=1 + env: global: - DISPLAY=:99.0 @@ -19,18 +25,21 @@ cache: - $HOME/.composer/cache before_install: - - composer self-update + - travis_retry composer self-update install: - - composer install --no-interaction --prefer-source + - travis_retry composer install --no-interaction --prefer-source before_script: - - sh -e /etc/init.d/xvfb start - - wget -q -t 3 http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar - - java -jar selenium-server-standalone-2.45.0.jar -log selenium.log & - - until $(echo | nc localhost 4444); do sleep 1; echo waiting for selenium-server...; done; - -script: ./vendor/bin/phpunit + - if [ -z "$CHECK_CODESTYLE" ]; then sh -e /etc/init.d/xvfb start; fi + - if [ -z "$CHECK_CODESTYLE" ]; then wget -q -t 3 http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar; fi + - if [ -z "$CHECK_CODESTYLE" ]; then java -jar selenium-server-standalone-2.45.0.jar -log selenium.log; fi & + - if [ -z "$CHECK_CODESTYLE" ]; then until $(echo | nc localhost 4444); do sleep 1; echo waiting for selenium-server...; done; fi + +script: + - if [ -n "$CHECK_CODESTYLE" ]; then ./vendor/bin/php-cs-fixer fix --diff --dry-run; fi + - if [ -n "$CHECK_CODESTYLE" ]; then ./vendor/bin/phpcs --standard=PSR2 ./lib/ ./tests/; fi + - if [ -z "$CHECK_CODESTYLE" ]; then ./vendor/bin/phpunit; fi after_script: - cat selenium.log diff --git a/composer.json b/composer.json index 43c61fa88..227542bf1 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,9 @@ "ext-curl": "*" }, "require-dev": { - "phpunit/phpunit": "4.6.* || ~5.0" + "phpunit/phpunit": "4.6.* || ~5.0", + "friendsofphp/php-cs-fixer": "^1.11", + "squizlabs/php_codesniffer": "^2.6" }, "suggest": { "phpdocumentor/phpdocumentor": "2.*" From 642b5e4d2348d3f79080a62be1d8ce44af8fbe6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 30 Jul 2016 16:41:07 +0200 Subject: [PATCH 219/784] Update contributor info with code-style requirements --- CONTRIBUTING.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b426d475d..2abd92165 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,7 +9,7 @@ send a pull request (see bellow) with your contribution. 1. Fork the project on GitHub 2. Implement your code changes into separate branch -3. Make sure all PHPUnit tests passes (see below). We also have Travis CI build which will automatically run tests on your pull request). +3. Make sure all PHPUnit tests passes and code-style matches PSR-2 (see below). We also have Travis CI build which will automatically run tests on your pull request. 4. When implementing notable change, fix or a new feature, add record to Unreleased section of [CHANGELOG.md](CHANGELOG.md) 5. Submit your [pull request](https://github.com/facebook/php-webdriver/pulls) against community branch @@ -34,3 +34,10 @@ For the functional tests you must first download and start the selenium server, java -jar selenium-server-standalone-2.48.2.jar -log selenium.log & ./vendor/bin/phpunit --testsuite functional + +### Check coding style + +Your code-style should comply with [PSR-2](http://www.php-fig.org/psr/psr-2/). To make sure your code matches this requirement run: + + ./vendor/bin/php-cs-fixer fix --diff --dry-run + ./vendor/bin/phpcs --standard=PSR2 ./lib/ ./tests/ From 8dd44ed56e4c61f308597486c47268a7574407de Mon Sep 17 00:00:00 2001 From: Michael Rijsdijk Date: Wed, 3 Aug 2016 14:06:12 +0200 Subject: [PATCH 220/784] Edit the link to the official Java API The link to the official Java API was broken --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b426d475d..a6125e2b3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,7 +16,7 @@ send a pull request (see bellow) with your contribution. Note before any pull request can be accepted, a [Contributors Licensing Agreement](http://developers.facebook.com/opensource/cla) must be signed. When you are going to contribute, please keep in mind that this webdriver client aims to be as close as possible to other languages Java/Ruby/Python/C#. -FYI, here is the overview of [the official Java API](http://selenium.googlecode.com/svn/trunk/docs/api/java/index.html?overview-summary.html) +FYI, here is the overview of [the official Java API](http://seleniumhq.github.io/selenium/docs/api/java/) ### Run unit tests From 8606656ea824e535d56de3582ddec532a552cb97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 2 Aug 2016 00:57:34 +0200 Subject: [PATCH 221/784] Add MicrosoftEdge to known browser types to enable basic Edge support (see #244) --- lib/Remote/DesiredCapabilities.php | 11 +++++++++++ lib/Remote/WebDriverBrowserType.php | 1 + tests/unit/Remote/DesiredCapabilitiesTest.php | 1 + 3 files changed, 13 insertions(+) diff --git a/lib/Remote/DesiredCapabilities.php b/lib/Remote/DesiredCapabilities.php index 8e30aae14..9366a0293 100644 --- a/lib/Remote/DesiredCapabilities.php +++ b/lib/Remote/DesiredCapabilities.php @@ -271,6 +271,17 @@ public static function internetExplorer() )); } + /** + * @return DesiredCapabilities + */ + public static function microsoftEdge() + { + return new self(array( + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::MICROSOFT_EDGE, + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::WINDOWS, + )); + } + /** * @return DesiredCapabilities */ diff --git a/lib/Remote/WebDriverBrowserType.php b/lib/Remote/WebDriverBrowserType.php index 977662a4a..4aa38125c 100644 --- a/lib/Remote/WebDriverBrowserType.php +++ b/lib/Remote/WebDriverBrowserType.php @@ -28,6 +28,7 @@ class WebDriverBrowserType const GOOGLECHROME = 'googlechrome'; const SAFARI = 'safari'; const OPERA = 'opera'; + const MICROSOFT_EDGE = 'MicrosoftEdge'; const IEXPLORE = 'iexplore'; const IEXPLORE_PROXY = 'iexploreproxy'; const SAFARI_PROXY = 'safariproxy'; diff --git a/tests/unit/Remote/DesiredCapabilitiesTest.php b/tests/unit/Remote/DesiredCapabilitiesTest.php index 54f17a14d..c68a747ed 100644 --- a/tests/unit/Remote/DesiredCapabilitiesTest.php +++ b/tests/unit/Remote/DesiredCapabilitiesTest.php @@ -110,6 +110,7 @@ public function browserCapabilitiesProvider() array('firefox', WebDriverBrowserType::FIREFOX, WebDriverPlatform::ANY), array('htmlUnit', WebDriverBrowserType::HTMLUNIT, WebDriverPlatform::ANY), array('htmlUnitWithJS', WebDriverBrowserType::HTMLUNIT, WebDriverPlatform::ANY), + array('MicrosoftEdge', WebDriverBrowserType::MICROSOFT_EDGE, WebDriverPlatform::WINDOWS), array('internetExplorer', WebDriverBrowserType::IE, WebDriverPlatform::WINDOWS), array('iphone', WebDriverBrowserType::IPHONE, WebDriverPlatform::MAC), array('ipad', WebDriverBrowserType::IPAD, WebDriverPlatform::MAC), From 5b3fdbe2fef3e3cba60d1d11904a487c67c0c22b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Thu, 18 Aug 2016 20:23:18 +0200 Subject: [PATCH 222/784] Remove deprecated browser types --- lib/Remote/WebDriverBrowserType.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/Remote/WebDriverBrowserType.php b/lib/Remote/WebDriverBrowserType.php index 4aa38125c..5dd61505e 100644 --- a/lib/Remote/WebDriverBrowserType.php +++ b/lib/Remote/WebDriverBrowserType.php @@ -21,17 +21,15 @@ class WebDriverBrowserType { const FIREFOX = 'firefox'; - const FIREFOX_2 = 'firefox2'; - const FIREFOX_3 = 'firefox3'; const FIREFOX_PROXY = 'firefoxproxy'; const FIREFOX_CHROME = 'firefoxchrome'; const GOOGLECHROME = 'googlechrome'; const SAFARI = 'safari'; + const SAFARI_PROXY = 'safariproxy'; const OPERA = 'opera'; const MICROSOFT_EDGE = 'MicrosoftEdge'; const IEXPLORE = 'iexplore'; const IEXPLORE_PROXY = 'iexploreproxy'; - const SAFARI_PROXY = 'safariproxy'; const CHROME = 'chrome'; const KONQUEROR = 'konqueror'; const MOCK = 'mock'; From 78582b90b721861bce6f90c2762d64a02c8fb51f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 26 Aug 2016 00:31:32 +0200 Subject: [PATCH 223/784] Update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f379bdaa7..b24bc9bcb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +- Added initial basic support of Microsoft Edge browser + +## 1.1.3 - 2016-08-10 - Fixed FirefoxProfile to support installation of extensions with custom namespace prefix in their manifest file - Comply codestyle with [PSR-2](http://www.php-fig.org/psr/psr-2/) From b9cd2ad25331566d5f9957e279ac31bb3ba56a2d Mon Sep 17 00:00:00 2001 From: Ivan Sebastian Date: Wed, 14 Sep 2016 09:04:02 +0700 Subject: [PATCH 224/784] Modify README to add link to sample code --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 146d45ad6..6cdae5742 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,8 @@ $driver = RemoteWebDriver::create($host, $desired_capabilities); * See https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities for more details. +* Above snippets are not intended to be a working example by simply copy pasting. See [example.php](example.php) for working example. + ## Changelog For latest changes see [CHANGELOG.md](CHANGELOG.md) file. From af4294ce7d703d39860a98d8a4c8545d62466580 Mon Sep 17 00:00:00 2001 From: Phelipe Alves de Souza Date: Fri, 16 Sep 2016 18:54:23 -0300 Subject: [PATCH 225/784] Declared not found fields --- lib/Interactions/Touch/WebDriverFlickAction.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/Interactions/Touch/WebDriverFlickAction.php b/lib/Interactions/Touch/WebDriverFlickAction.php index 48e65dc95..52f43fde6 100644 --- a/lib/Interactions/Touch/WebDriverFlickAction.php +++ b/lib/Interactions/Touch/WebDriverFlickAction.php @@ -19,6 +19,9 @@ class WebDriverFlickAction extends WebDriverTouchAction implements WebDriverAction { + private $x; + private $y; + /** * @param WebDriverTouchScreen $touch_screen * @param int $x From 3ab0f89954a5bae784f3c4dab2cc57624bba7ba8 Mon Sep 17 00:00:00 2001 From: Sepehr Lajevardi Date: Tue, 20 Sep 2016 00:49:47 +0430 Subject: [PATCH 226/784] Fix typo in test method name. --- tests/unit/Remote/WebDriverCommandTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/Remote/WebDriverCommandTest.php b/tests/unit/Remote/WebDriverCommandTest.php index c315b4b46..30a206119 100644 --- a/tests/unit/Remote/WebDriverCommandTest.php +++ b/tests/unit/Remote/WebDriverCommandTest.php @@ -17,7 +17,7 @@ class WebDriverCommandTest extends \PHPUnit_Framework_TestCase { - public function testShouldSetOptionsUsingConstructot() + public function testShouldSetOptionsUsingConstructor() { $command = new WebDriverCommand('session-id-123', 'bar-baz-name', array('foo' => 'bar')); From 25eeb6a1f2b99a85a8b79c6418e2453cd82a9f3e Mon Sep 17 00:00:00 2001 From: Sepehr Lajevardi Date: Wed, 5 Oct 2016 10:09:03 +0330 Subject: [PATCH 227/784] Utilize late static binding. --- lib/Chrome/ChromeDriverService.php | 2 +- lib/Remote/DesiredCapabilities.php | 24 ++++++++++---------- lib/WebDriverBy.php | 16 ++++++------- lib/WebDriverExpectedCondition.php | 36 +++++++++++++++--------------- 4 files changed, 39 insertions(+), 39 deletions(-) diff --git a/lib/Chrome/ChromeDriverService.php b/lib/Chrome/ChromeDriverService.php index a48207a46..4fb3b59e5 100644 --- a/lib/Chrome/ChromeDriverService.php +++ b/lib/Chrome/ChromeDriverService.php @@ -27,7 +27,7 @@ public static function createDefaultService() $exe = getenv(self::CHROME_DRIVER_EXE_PROPERTY); $port = 9515; // TODO: Get another port if the default port is used. $args = array("--port=$port"); - $service = new self($exe, $port, $args); + $service = new static($exe, $port, $args); return $service; } diff --git a/lib/Remote/DesiredCapabilities.php b/lib/Remote/DesiredCapabilities.php index 9366a0293..2a132b576 100644 --- a/lib/Remote/DesiredCapabilities.php +++ b/lib/Remote/DesiredCapabilities.php @@ -201,7 +201,7 @@ private function get($key, $default = null) */ public static function android() { - return new self(array( + return new static(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::ANDROID, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANDROID, )); @@ -212,7 +212,7 @@ public static function android() */ public static function chrome() { - return new self(array( + return new static(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::CHROME, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, )); @@ -223,7 +223,7 @@ public static function chrome() */ public static function firefox() { - $caps = new self(array( + $caps = new static(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::FIREFOX, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, )); @@ -241,7 +241,7 @@ public static function firefox() */ public static function htmlUnit() { - return new self(array( + return new static(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::HTMLUNIT, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, )); @@ -252,7 +252,7 @@ public static function htmlUnit() */ public static function htmlUnitWithJS() { - $caps = new self(array( + $caps = new static(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::HTMLUNIT, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, )); @@ -265,7 +265,7 @@ public static function htmlUnitWithJS() */ public static function internetExplorer() { - return new self(array( + return new static(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::IE, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::WINDOWS, )); @@ -276,7 +276,7 @@ public static function internetExplorer() */ public static function microsoftEdge() { - return new self(array( + return new static(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::MICROSOFT_EDGE, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::WINDOWS, )); @@ -287,7 +287,7 @@ public static function microsoftEdge() */ public static function iphone() { - return new self(array( + return new static(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::IPHONE, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::MAC, )); @@ -298,7 +298,7 @@ public static function iphone() */ public static function ipad() { - return new self(array( + return new static(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::IPAD, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::MAC, )); @@ -309,7 +309,7 @@ public static function ipad() */ public static function opera() { - return new self(array( + return new static(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::OPERA, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, )); @@ -320,7 +320,7 @@ public static function opera() */ public static function safari() { - return new self(array( + return new static(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::SAFARI, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, )); @@ -331,7 +331,7 @@ public static function safari() */ public static function phantomjs() { - return new self(array( + return new static(array( WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::PHANTOMJS, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, )); diff --git a/lib/WebDriverBy.php b/lib/WebDriverBy.php index 92242ae56..af51c26b2 100644 --- a/lib/WebDriverBy.php +++ b/lib/WebDriverBy.php @@ -58,7 +58,7 @@ public function getValue() */ public static function className($class_name) { - return new self('class name', $class_name); + return new static('class name', $class_name); } /** @@ -69,7 +69,7 @@ public static function className($class_name) */ public static function cssSelector($css_selector) { - return new self('css selector', $css_selector); + return new static('css selector', $css_selector); } /** @@ -80,7 +80,7 @@ public static function cssSelector($css_selector) */ public static function id($id) { - return new self('id', $id); + return new static('id', $id); } /** @@ -91,7 +91,7 @@ public static function id($id) */ public static function name($name) { - return new self('name', $name); + return new static('name', $name); } /** @@ -102,7 +102,7 @@ public static function name($name) */ public static function linkText($link_text) { - return new self('link text', $link_text); + return new static('link text', $link_text); } /** @@ -114,7 +114,7 @@ public static function linkText($link_text) */ public static function partialLinkText($partial_link_text) { - return new self('partial link text', $partial_link_text); + return new static('partial link text', $partial_link_text); } /** @@ -125,7 +125,7 @@ public static function partialLinkText($partial_link_text) */ public static function tagName($tag_name) { - return new self('tag name', $tag_name); + return new static('tag name', $tag_name); } /** @@ -136,6 +136,6 @@ public static function tagName($tag_name) */ public static function xpath($xpath) { - return new self('xpath', $xpath); + return new static('xpath', $xpath); } } diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index 8c069bd41..775d23cf5 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -55,7 +55,7 @@ protected function __construct($apply) */ public static function titleIs($title) { - return new self( + return new static( function ($driver) use ($title) { return $title === $driver->getTitle(); } @@ -71,7 +71,7 @@ function ($driver) use ($title) { */ public static function titleContains($title) { - return new self( + return new static( function ($driver) use ($title) { return strpos($driver->getTitle(), $title) !== false; } @@ -88,7 +88,7 @@ function ($driver) use ($title) { */ public static function presenceOfElementLocated(WebDriverBy $by) { - return new self( + return new static( function ($driver) use ($by) { return $driver->findElement($by); } @@ -106,7 +106,7 @@ function ($driver) use ($by) { */ public static function visibilityOfElementLocated(WebDriverBy $by) { - return new self( + return new static( function ($driver) use ($by) { try { $element = $driver->findElement($by); @@ -130,7 +130,7 @@ function ($driver) use ($by) { */ public static function visibilityOf(WebDriverElement $element) { - return new self( + return new static( function ($driver) use ($element) { return $element->isDisplayed() ? $element : null; } @@ -147,7 +147,7 @@ function ($driver) use ($element) { */ public static function presenceOfAllElementsLocatedBy(WebDriverBy $by) { - return new self( + return new static( function ($driver) use ($by) { $elements = $driver->findElements($by); @@ -166,7 +166,7 @@ function ($driver) use ($by) { */ public static function textToBePresentInElement(WebDriverBy $by, $text) { - return new self( + return new static( function ($driver) use ($by, $text) { try { $element_text = $driver->findElement($by)->getText(); @@ -189,7 +189,7 @@ function ($driver) use ($by, $text) { */ public static function textToBePresentInElementValue(WebDriverBy $by, $text) { - return new self( + return new static( function ($driver) use ($by, $text) { try { $element_text = $driver->findElement($by)->getAttribute('value'); @@ -213,7 +213,7 @@ function ($driver) use ($by, $text) { */ public static function frameToBeAvailableAndSwitchToIt($frame_locator) { - return new self( + return new static( function ($driver) use ($frame_locator) { try { return $driver->switchTo()->frame($frame_locator); @@ -234,7 +234,7 @@ function ($driver) use ($frame_locator) { */ public static function invisibilityOfElementLocated(WebDriverBy $by) { - return new self( + return new static( function ($driver) use ($by) { try { return !($driver->findElement($by)->isDisplayed()); @@ -258,7 +258,7 @@ function ($driver) use ($by) { */ public static function invisibilityOfElementWithText(WebDriverBy $by, $text) { - return new self( + return new static( function ($driver) use ($by, $text) { try { return !($driver->findElement($by)->getText() === $text); @@ -284,7 +284,7 @@ public static function elementToBeClickable(WebDriverBy $by) $visibility_of_element_located = self::visibilityOfElementLocated($by); - return new self( + return new static( function ($driver) use ($visibility_of_element_located) { $element = call_user_func( $visibility_of_element_located->getApply(), @@ -312,7 +312,7 @@ function ($driver) use ($visibility_of_element_located) { */ public static function stalenessOf(WebDriverElement $element) { - return new self( + return new static( function ($driver) use ($element) { try { $element->isEnabled(); @@ -340,7 +340,7 @@ function ($driver) use ($element) { */ public static function refreshed(WebDriverExpectedCondition $condition) { - return new self( + return new static( function ($driver) use ($condition) { try { return call_user_func($condition->getApply(), $driver); @@ -375,14 +375,14 @@ public static function elementToBeSelected($element_or_by) public static function elementSelectionStateToBe($element_or_by, $selected) { if ($element_or_by instanceof WebDriverElement) { - return new self( + return new static( function ($driver) use ($element_or_by, $selected) { return $element_or_by->isSelected() === $selected; } ); } else { if ($element_or_by instanceof WebDriverBy) { - return new self( + return new static( function ($driver) use ($element_or_by, $selected) { try { $element = $driver->findElement($element_or_by); @@ -405,7 +405,7 @@ function ($driver) use ($element_or_by, $selected) { */ public static function alertIsPresent() { - return new self( + return new static( function ($driver) { try { // Unlike the Java code, we get a WebDriverAlert object regardless @@ -430,7 +430,7 @@ function ($driver) { */ public static function not(WebDriverExpectedCondition $condition) { - return new self( + return new static( function ($driver) use ($condition) { $result = call_user_func($condition->getApply(), $driver); From a67e8ec9674a0951c268c3e1b542c6925de8c055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 11 Oct 2016 21:42:33 +0200 Subject: [PATCH 228/784] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b24bc9bcb..0b067bed7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased - Added initial basic support of Microsoft Edge browser +- Utilize late static binding to make eg. `WebDriverBy` and `DesiredCapabilities` classes easily extensible ## 1.1.3 - 2016-08-10 - Fixed FirefoxProfile to support installation of extensions with custom namespace prefix in their manifest file From 395cf63e6d85715951143240e35479e5fb8b800c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 20 Sep 2016 18:41:55 +0200 Subject: [PATCH 229/784] Require PHP 5.5+ (fixes #324) --- .travis.yml | 5 +---- CHANGELOG.md | 1 + composer.json | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index eb8e94685..facb0d4db 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,10 @@ language: php -sudo: false - php: - - 5.3 - - 5.4 - 5.5 - 5.6 - 7 + - 7.1 - hhvm matrix: diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b067bed7..a74435bef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased - Added initial basic support of Microsoft Edge browser - Utilize late static binding to make eg. `WebDriverBy` and `DesiredCapabilities` classes easily extensible +- PHP version at least 5.5 is required ## 1.1.3 - 2016-08-10 - Fixed FirefoxProfile to support installation of extensions with custom namespace prefix in their manifest file diff --git a/composer.json b/composer.json index 227542bf1..e8afaf77e 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ "source": "https://github.com/facebook/php-webdriver" }, "require": { - "php": ">=5.3.19", + "php": "^5.5 || ~7.0", "ext-curl": "*" }, "require-dev": { From 89d3c316cb9e71b4d20c94a37f1e65c8e5ed615a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 20 Sep 2016 18:52:08 +0200 Subject: [PATCH 230/784] Use PHP 5.5 features - class, short array syntax --- .php_cs | 32 ++- example.php | 18 +- lib/Chrome/ChromeDriver.php | 4 +- lib/Chrome/ChromeDriverService.php | 2 +- lib/Chrome/ChromeOptions.php | 6 +- lib/Firefox/FirefoxProfile.php | 8 +- lib/Interactions/WebDriverCompositeAction.php | 2 +- lib/JavaScriptExecutor.php | 4 +- lib/Remote/DesiredCapabilities.php | 50 ++--- lib/Remote/ExecuteMethod.php | 2 +- lib/Remote/HttpCommandExecutor.php | 209 ++++++++---------- lib/Remote/RemoteExecuteMethod.php | 2 +- lib/Remote/RemoteKeyboard.php | 16 +- lib/Remote/RemoteMouse.php | 10 +- lib/Remote/RemoteTargetLocator.php | 8 +- lib/Remote/RemoteTouchScreen.php | 34 +-- lib/Remote/RemoteWebDriver.php | 40 ++-- lib/Remote/RemoteWebElement.php | 56 ++--- lib/Remote/Service/DriverService.php | 14 +- lib/Support/Events/EventFiringWebDriver.php | 6 +- lib/Support/Events/EventFiringWebElement.php | 2 +- lib/WebDriverAction.php | 2 - lib/WebDriverAlert.php | 2 +- lib/WebDriverDispatcher.php | 4 +- lib/WebDriverExpectedCondition.php | 4 +- lib/WebDriverKeys.php | 4 +- lib/WebDriverNavigation.php | 2 +- lib/WebDriverOptions.php | 6 +- lib/WebDriverSelect.php | 2 +- lib/WebDriverTimeouts.php | 8 +- lib/WebDriverWindow.php | 18 +- tests/functional/WebDriverTestCase.php | 4 +- .../WebDriverButtonReleaseActionTest.php | 6 +- .../Internal/WebDriverClickActionTest.php | 6 +- .../WebDriverClickAndHoldActionTest.php | 6 +- .../WebDriverContextClickActionTest.php | 6 +- .../WebDriverDoubleClickActionTest.php | 6 +- .../Internal/WebDriverKeyDownActionTest.php | 8 +- .../Internal/WebDriverKeyUpActionTest.php | 8 +- .../Internal/WebDriverMouseMoveActionTest.php | 6 +- .../WebDriverMouseToOffsetActionTest.php | 6 +- .../Internal/WebDriverSendKeysActionTest.php | 10 +- tests/unit/Remote/DesiredCapabilitiesTest.php | 38 ++-- tests/unit/Remote/WebDriverCommandTest.php | 4 +- 44 files changed, 340 insertions(+), 351 deletions(-) diff --git a/.php_cs b/.php_cs index 752fb9606..0466edfbe 100644 --- a/.php_cs +++ b/.php_cs @@ -1,17 +1,24 @@ in(array(__DIR__ . '/lib', __DIR__ . '/tests')); + ->in([__DIR__ . '/lib', __DIR__ . '/tests']); return Symfony\CS\Config\Config::create() - ->fixers(array( + ->fixers([ + 'array_element_white_space_after_comma', 'duplicate_semicolon', 'extra_empty_lines', + 'function_typehint_space', + 'lowercase_cast', + 'method_argument_default_value', 'multiline_array_trailing_comma', 'namespace_no_leading_whitespace', + 'native_function_casing', 'new_with_braces', 'no_blank_lines_after_class_opening', 'no_empty_lines_after_phpdocs', + 'no_empty_phpdoc', + 'no_empty_statement', 'object_operator', 'operators_spaces', 'trim_array_spaces', @@ -20,6 +27,7 @@ return Symfony\CS\Config\Config::create() 'phpdoc_no_empty_return', 'phpdoc_no_package', 'phpdoc_scalar', + 'phpdoc_single_line_var_spacing', 'phpdoc_trim', 'phpdoc_types', 'phpdoc_order', @@ -27,15 +35,31 @@ return Symfony\CS\Config\Config::create() 'ordered_use', 'remove_leading_slash_use', 'remove_lines_between_uses', - 'function_typehint_space', + 'return', 'self_accessor', 'single_array_no_trailing_comma', 'single_blank_line_before_namespace', 'single_quote', + 'spaces_after_semicolon', + 'spaces_before_semicolon', 'spaces_cast', + 'standardize_not_equal', + 'ternary_spaces', + 'trim_array_spaces', + 'unary_operators_spaces', + 'unused_use', 'whitespacy_lines', + + // additional contrib checks + 'concat_with_spaces', 'newline_after_open_tag', - )) + 'no_useless_else', + 'no_useless_return', + 'php_unit_construct', + 'php_unit_dedicate_assert', + 'phpdoc_order', + 'short_array_syntax', + ]) ->level(Symfony\CS\FixerInterface::PSR2_LEVEL) ->setUsingCache(true) ->finder($finder); diff --git a/example.php b/example.php index 690a3b1c3..03b16728e 100644 --- a/example.php +++ b/example.php @@ -18,16 +18,16 @@ // adding cookie $driver->manage()->deleteAllCookies(); -$driver->manage()->addCookie(array( - 'name' => 'cookie_name', - 'value' => 'cookie_value', -)); +$driver->manage()->addCookie([ + 'name' => 'cookie_name', + 'value' => 'cookie_value', +]); $cookies = $driver->manage()->getCookies(); print_r($cookies); // click the link 'About' $link = $driver->findElement( - WebDriverBy::id('menu_about') + WebDriverBy::id('menu_about') ); $link->click(); @@ -39,15 +39,15 @@ // Search 'php' in the search box $input = $driver->findElement( - WebDriverBy::id('q') + WebDriverBy::id('q') ); $input->sendKeys('php')->submit(); // wait at most 10 seconds until at least one result is shown $driver->wait(10)->until( - WebDriverExpectedCondition::presenceOfAllElementsLocatedBy( - WebDriverBy::className('gsc-result') - ) + WebDriverExpectedCondition::presenceOfAllElementsLocatedBy( + WebDriverBy::className('gsc-result') + ) ); // close the Firefox diff --git a/lib/Chrome/ChromeDriver.php b/lib/Chrome/ChromeDriver.php index 75131c215..be807d7bc 100644 --- a/lib/Chrome/ChromeDriver.php +++ b/lib/Chrome/ChromeDriver.php @@ -45,9 +45,9 @@ public function startSession($desired_capabilities) $command = new WebDriverCommand( null, DriverCommand::NEW_SESSION, - array( + [ 'desiredCapabilities' => $desired_capabilities->toArray(), - ) + ] ); $response = $this->executor->execute($command); $this->setSessionID($response->getSessionID()); diff --git a/lib/Chrome/ChromeDriverService.php b/lib/Chrome/ChromeDriverService.php index 4fb3b59e5..90b3d24f7 100644 --- a/lib/Chrome/ChromeDriverService.php +++ b/lib/Chrome/ChromeDriverService.php @@ -26,7 +26,7 @@ public static function createDefaultService() { $exe = getenv(self::CHROME_DRIVER_EXE_PROPERTY); $port = 9515; // TODO: Get another port if the default port is used. - $args = array("--port=$port"); + $args = ["--port=$port"]; $service = new static($exe, $port, $args); return $service; diff --git a/lib/Chrome/ChromeOptions.php b/lib/Chrome/ChromeOptions.php index 3af14b9c3..901dc5388 100644 --- a/lib/Chrome/ChromeOptions.php +++ b/lib/Chrome/ChromeOptions.php @@ -31,7 +31,7 @@ class ChromeOptions /** * @var array */ - private $arguments = array(); + private $arguments = []; /** * @var string */ @@ -39,11 +39,11 @@ class ChromeOptions /** * @var array */ - private $extensions = array(); + private $extensions = []; /** * @var array */ - private $experimentalOptions = array(); + private $experimentalOptions = []; /** * Sets the path of the Chrome executable. The path should be either absolute diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index 925ac157f..6dd4d41b3 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -26,15 +26,15 @@ class FirefoxProfile /** * @var array */ - private $preferences = array(); + private $preferences = []; /** * @var array */ - private $extensions = array(); + private $extensions = []; /** * @var array */ - private $extensions_datas = array(); + private $extensions_datas = []; /** * @var string */ @@ -220,7 +220,7 @@ private function installExtension($extension, $profile_dir) } } // Get the extension id from the install manifest. - $matches = array(); + $matches = []; preg_match('#<' . $prefix . 'id>([^<]+)#', $xml->asXML(), $matches); if (isset($matches[1])) { $ext_dir = $profile_dir . '/extensions/' . $matches[1]; diff --git a/lib/Interactions/WebDriverCompositeAction.php b/lib/Interactions/WebDriverCompositeAction.php index f17cc4588..742544f59 100644 --- a/lib/Interactions/WebDriverCompositeAction.php +++ b/lib/Interactions/WebDriverCompositeAction.php @@ -22,7 +22,7 @@ */ class WebDriverCompositeAction implements WebDriverAction { - private $actions = array(); + private $actions = []; /** * Add an WebDriverAction to the sequence. diff --git a/lib/JavaScriptExecutor.php b/lib/JavaScriptExecutor.php index 61aa21b0e..d4a587acf 100644 --- a/lib/JavaScriptExecutor.php +++ b/lib/JavaScriptExecutor.php @@ -29,7 +29,7 @@ interface JavaScriptExecutor * @param array $arguments The arguments of the script. * @return mixed The return value of the script. */ - public function executeScript($script, array $arguments = array()); + public function executeScript($script, array $arguments = []); /** * Inject a snippet of JavaScript into the page for asynchronous execution in @@ -44,5 +44,5 @@ public function executeScript($script, array $arguments = array()); * @param array $arguments The arguments of the script. * @return mixed The value passed by the script to the callback. */ - public function executeAsyncScript($script, array $arguments = array()); + public function executeAsyncScript($script, array $arguments = []); } diff --git a/lib/Remote/DesiredCapabilities.php b/lib/Remote/DesiredCapabilities.php index 2a132b576..a1cbfddf0 100644 --- a/lib/Remote/DesiredCapabilities.php +++ b/lib/Remote/DesiredCapabilities.php @@ -27,7 +27,7 @@ class DesiredCapabilities implements WebDriverCapabilities { private $capabilities; - public function __construct(array $capabilities = array()) + public function __construct(array $capabilities = []) { $this->capabilities = $capabilities; } @@ -201,10 +201,10 @@ private function get($key, $default = null) */ public static function android() { - return new static(array( + return new static([ WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::ANDROID, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANDROID, - )); + ]); } /** @@ -212,10 +212,10 @@ public static function android() */ public static function chrome() { - return new static(array( + return new static([ WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::CHROME, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, - )); + ]); } /** @@ -223,10 +223,10 @@ public static function chrome() */ public static function firefox() { - $caps = new static(array( + $caps = new static([ WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::FIREFOX, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, - )); + ]); // disable the "Reader View" help tooltip, which can hide elements in the window.document $profile = new FirefoxProfile(); @@ -241,10 +241,10 @@ public static function firefox() */ public static function htmlUnit() { - return new static(array( + return new static([ WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::HTMLUNIT, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, - )); + ]); } /** @@ -252,10 +252,10 @@ public static function htmlUnit() */ public static function htmlUnitWithJS() { - $caps = new static(array( + $caps = new static([ WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::HTMLUNIT, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, - )); + ]); return $caps->setJavascriptEnabled(true); } @@ -265,10 +265,10 @@ public static function htmlUnitWithJS() */ public static function internetExplorer() { - return new static(array( + return new static([ WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::IE, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::WINDOWS, - )); + ]); } /** @@ -276,10 +276,10 @@ public static function internetExplorer() */ public static function microsoftEdge() { - return new static(array( + return new static([ WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::MICROSOFT_EDGE, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::WINDOWS, - )); + ]); } /** @@ -287,10 +287,10 @@ public static function microsoftEdge() */ public static function iphone() { - return new static(array( + return new static([ WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::IPHONE, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::MAC, - )); + ]); } /** @@ -298,10 +298,10 @@ public static function iphone() */ public static function ipad() { - return new static(array( + return new static([ WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::IPAD, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::MAC, - )); + ]); } /** @@ -309,10 +309,10 @@ public static function ipad() */ public static function opera() { - return new static(array( + return new static([ WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::OPERA, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, - )); + ]); } /** @@ -320,10 +320,10 @@ public static function opera() */ public static function safari() { - return new static(array( + return new static([ WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::SAFARI, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, - )); + ]); } /** @@ -331,9 +331,9 @@ public static function safari() */ public static function phantomjs() { - return new static(array( + return new static([ WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::PHANTOMJS, WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, - )); + ]); } } diff --git a/lib/Remote/ExecuteMethod.php b/lib/Remote/ExecuteMethod.php index 38ad319e7..b12c25ed8 100644 --- a/lib/Remote/ExecuteMethod.php +++ b/lib/Remote/ExecuteMethod.php @@ -22,5 +22,5 @@ interface ExecuteMethod * @param array $parameters * @return WebDriverResponse */ - public function execute($command_name, array $parameters = array()); + public function execute($command_name, array $parameters = []); } diff --git a/lib/Remote/HttpCommandExecutor.php b/lib/Remote/HttpCommandExecutor.php index 37670610d..9cfcd1fa4 100644 --- a/lib/Remote/HttpCommandExecutor.php +++ b/lib/Remote/HttpCommandExecutor.php @@ -29,142 +29,109 @@ class HttpCommandExecutor implements WebDriverCommandExecutor * @see * http://code.google.com/p/selenium/wiki/JsonWireProtocol#Command_Reference */ - protected static $commands = array( - DriverCommand::ACCEPT_ALERT => array('method' => 'POST', 'url' => '/session/:sessionId/accept_alert'), - DriverCommand::ADD_COOKIE => array('method' => 'POST', 'url' => '/session/:sessionId/cookie'), - DriverCommand::CLEAR_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/clear'), - DriverCommand::CLICK_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/click'), - DriverCommand::CLOSE => array('method' => 'DELETE', 'url' => '/session/:sessionId/window'), - DriverCommand::DELETE_ALL_COOKIES => array('method' => 'DELETE', 'url' => '/session/:sessionId/cookie'), - DriverCommand::DELETE_COOKIE => array('method' => 'DELETE', 'url' => '/session/:sessionId/cookie/:name'), - DriverCommand::DISMISS_ALERT => array('method' => 'POST', 'url' => '/session/:sessionId/dismiss_alert'), - DriverCommand::ELEMENT_EQUALS => array( - 'method' => 'GET', - 'url' => '/session/:sessionId/element/:id/equals/:other', - ), - DriverCommand::FIND_CHILD_ELEMENT => array( - 'method' => 'POST', - 'url' => '/session/:sessionId/element/:id/element', - ), - DriverCommand::FIND_CHILD_ELEMENTS => array( - 'method' => 'POST', - 'url' => '/session/:sessionId/element/:id/elements', - ), - DriverCommand::EXECUTE_SCRIPT => array('method' => 'POST', 'url' => '/session/:sessionId/execute'), - DriverCommand::EXECUTE_ASYNC_SCRIPT => array('method' => 'POST', 'url' => '/session/:sessionId/execute_async'), - DriverCommand::FIND_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element'), - DriverCommand::FIND_ELEMENTS => array('method' => 'POST', 'url' => '/session/:sessionId/elements'), - DriverCommand::SWITCH_TO_FRAME => array('method' => 'POST', 'url' => '/session/:sessionId/frame'), - DriverCommand::SWITCH_TO_WINDOW => array('method' => 'POST', 'url' => '/session/:sessionId/window'), - DriverCommand::GET => array('method' => 'POST', 'url' => '/session/:sessionId/url'), - DriverCommand::GET_ACTIVE_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/active'), - DriverCommand::GET_ALERT_TEXT => array('method' => 'GET', 'url' => '/session/:sessionId/alert_text'), - DriverCommand::GET_ALL_COOKIES => array('method' => 'GET', 'url' => '/session/:sessionId/cookie'), - DriverCommand::GET_ALL_SESSIONS => array('method' => 'GET', 'url' => '/sessions'), - DriverCommand::GET_AVAILABLE_LOG_TYPES => array('method' => 'GET', 'url' => '/session/:sessionId/log/types'), - DriverCommand::GET_CURRENT_URL => array('method' => 'GET', 'url' => '/session/:sessionId/url'), - DriverCommand::GET_CURRENT_WINDOW_HANDLE => array( - 'method' => 'GET', - 'url' => '/session/:sessionId/window_handle', - ), - DriverCommand::GET_ELEMENT_ATTRIBUTE => array( + protected static $commands = [ + DriverCommand::ACCEPT_ALERT => ['method' => 'POST', 'url' => '/session/:sessionId/accept_alert'], + DriverCommand::ADD_COOKIE => ['method' => 'POST', 'url' => '/session/:sessionId/cookie'], + DriverCommand::CLEAR_ELEMENT => ['method' => 'POST', 'url' => '/session/:sessionId/element/:id/clear'], + DriverCommand::CLICK_ELEMENT => ['method' => 'POST', 'url' => '/session/:sessionId/element/:id/click'], + DriverCommand::CLOSE => ['method' => 'DELETE', 'url' => '/session/:sessionId/window'], + DriverCommand::DELETE_ALL_COOKIES => ['method' => 'DELETE', 'url' => '/session/:sessionId/cookie'], + DriverCommand::DELETE_COOKIE => ['method' => 'DELETE', 'url' => '/session/:sessionId/cookie/:name'], + DriverCommand::DISMISS_ALERT => ['method' => 'POST', 'url' => '/session/:sessionId/dismiss_alert'], + DriverCommand::ELEMENT_EQUALS => ['method' => 'GET', 'url' => '/session/:sessionId/element/:id/equals/:other'], + DriverCommand::FIND_CHILD_ELEMENT => ['method' => 'POST', 'url' => '/session/:sessionId/element/:id/element'], + DriverCommand::FIND_CHILD_ELEMENTS => ['method' => 'POST', 'url' => '/session/:sessionId/element/:id/elements'], + DriverCommand::EXECUTE_SCRIPT => ['method' => 'POST', 'url' => '/session/:sessionId/execute'], + DriverCommand::EXECUTE_ASYNC_SCRIPT => ['method' => 'POST', 'url' => '/session/:sessionId/execute_async'], + DriverCommand::FIND_ELEMENT => ['method' => 'POST', 'url' => '/session/:sessionId/element'], + DriverCommand::FIND_ELEMENTS => ['method' => 'POST', 'url' => '/session/:sessionId/elements'], + DriverCommand::SWITCH_TO_FRAME => ['method' => 'POST', 'url' => '/session/:sessionId/frame'], + DriverCommand::SWITCH_TO_WINDOW => ['method' => 'POST', 'url' => '/session/:sessionId/window'], + DriverCommand::GET => ['method' => 'POST', 'url' => '/session/:sessionId/url'], + DriverCommand::GET_ACTIVE_ELEMENT => ['method' => 'POST', 'url' => '/session/:sessionId/element/active'], + DriverCommand::GET_ALERT_TEXT => ['method' => 'GET', 'url' => '/session/:sessionId/alert_text'], + DriverCommand::GET_ALL_COOKIES => ['method' => 'GET', 'url' => '/session/:sessionId/cookie'], + DriverCommand::GET_ALL_SESSIONS => ['method' => 'GET', 'url' => '/sessions'], + DriverCommand::GET_AVAILABLE_LOG_TYPES => ['method' => 'GET', 'url' => '/session/:sessionId/log/types'], + DriverCommand::GET_CURRENT_URL => ['method' => 'GET', 'url' => '/session/:sessionId/url'], + DriverCommand::GET_CURRENT_WINDOW_HANDLE => ['method' => 'GET', 'url' => '/session/:sessionId/window_handle'], + DriverCommand::GET_ELEMENT_ATTRIBUTE => [ 'method' => 'GET', 'url' => '/session/:sessionId/element/:id/attribute/:name', - ), - DriverCommand::GET_ELEMENT_VALUE_OF_CSS_PROPERTY => array( + ], + DriverCommand::GET_ELEMENT_VALUE_OF_CSS_PROPERTY => [ 'method' => 'GET', 'url' => '/session/:sessionId/element/:id/css/:propertyName', - ), - DriverCommand::GET_ELEMENT_LOCATION => array( + ], + DriverCommand::GET_ELEMENT_LOCATION => [ 'method' => 'GET', 'url' => '/session/:sessionId/element/:id/location', - ), - DriverCommand::GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW => array( + ], + DriverCommand::GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW => [ 'method' => 'GET', 'url' => '/session/:sessionId/element/:id/location_in_view', - ), - DriverCommand::GET_ELEMENT_SIZE => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/size'), - DriverCommand::GET_ELEMENT_TAG_NAME => array( - 'method' => 'GET', - 'url' => '/session/:sessionId/element/:id/name', - ), - DriverCommand::GET_ELEMENT_TEXT => array('method' => 'GET', 'url' => '/session/:sessionId/element/:id/text'), - DriverCommand::GET_LOG => array('method' => 'POST', 'url' => '/session/:sessionId/log'), - DriverCommand::GET_PAGE_SOURCE => array('method' => 'GET', 'url' => '/session/:sessionId/source'), - DriverCommand::GET_SCREEN_ORIENTATION => array('method' => 'GET', 'url' => '/session/:sessionId/orientation'), - DriverCommand::GET_CAPABILITIES => array('method' => 'GET', 'url' => '/session/:sessionId'), - DriverCommand::GET_TITLE => array('method' => 'GET', 'url' => '/session/:sessionId/title'), - DriverCommand::GET_WINDOW_HANDLES => array('method' => 'GET', 'url' => '/session/:sessionId/window_handles'), - DriverCommand::GET_WINDOW_POSITION => array( + ], + DriverCommand::GET_ELEMENT_SIZE => ['method' => 'GET', 'url' => '/session/:sessionId/element/:id/size'], + DriverCommand::GET_ELEMENT_TAG_NAME => ['method' => 'GET', 'url' => '/session/:sessionId/element/:id/name'], + DriverCommand::GET_ELEMENT_TEXT => ['method' => 'GET', 'url' => '/session/:sessionId/element/:id/text'], + DriverCommand::GET_LOG => ['method' => 'POST', 'url' => '/session/:sessionId/log'], + DriverCommand::GET_PAGE_SOURCE => ['method' => 'GET', 'url' => '/session/:sessionId/source'], + DriverCommand::GET_SCREEN_ORIENTATION => ['method' => 'GET', 'url' => '/session/:sessionId/orientation'], + DriverCommand::GET_CAPABILITIES => ['method' => 'GET', 'url' => '/session/:sessionId'], + DriverCommand::GET_TITLE => ['method' => 'GET', 'url' => '/session/:sessionId/title'], + DriverCommand::GET_WINDOW_HANDLES => ['method' => 'GET', 'url' => '/session/:sessionId/window_handles'], + DriverCommand::GET_WINDOW_POSITION => [ 'method' => 'GET', 'url' => '/session/:sessionId/window/:windowHandle/position', - ), - DriverCommand::GET_WINDOW_SIZE => array( - 'method' => 'GET', - 'url' => '/session/:sessionId/window/:windowHandle/size', - ), - DriverCommand::GO_BACK => array('method' => 'POST', 'url' => '/session/:sessionId/back'), - DriverCommand::GO_FORWARD => array('method' => 'POST', 'url' => '/session/:sessionId/forward'), - DriverCommand::IS_ELEMENT_DISPLAYED => array( + ], + DriverCommand::GET_WINDOW_SIZE => ['method' => 'GET', 'url' => '/session/:sessionId/window/:windowHandle/size'], + DriverCommand::GO_BACK => ['method' => 'POST', 'url' => '/session/:sessionId/back'], + DriverCommand::GO_FORWARD => ['method' => 'POST', 'url' => '/session/:sessionId/forward'], + DriverCommand::IS_ELEMENT_DISPLAYED => [ 'method' => 'GET', 'url' => '/session/:sessionId/element/:id/displayed', - ), - DriverCommand::IS_ELEMENT_ENABLED => array( - 'method' => 'GET', - 'url' => '/session/:sessionId/element/:id/enabled', - ), - DriverCommand::IS_ELEMENT_SELECTED => array( - 'method' => 'GET', - 'url' => '/session/:sessionId/element/:id/selected', - ), - DriverCommand::MAXIMIZE_WINDOW => array( + ], + DriverCommand::IS_ELEMENT_ENABLED => ['method' => 'GET', 'url' => '/session/:sessionId/element/:id/enabled'], + DriverCommand::IS_ELEMENT_SELECTED => ['method' => 'GET', 'url' => '/session/:sessionId/element/:id/selected'], + DriverCommand::MAXIMIZE_WINDOW => [ 'method' => 'POST', 'url' => '/session/:sessionId/window/:windowHandle/maximize', - ), - DriverCommand::MOUSE_DOWN => array('method' => 'POST', 'url' => '/session/:sessionId/buttondown'), - DriverCommand::MOUSE_UP => array('method' => 'POST', 'url' => '/session/:sessionId/buttonup'), - DriverCommand::CLICK => array('method' => 'POST', 'url' => '/session/:sessionId/click'), - DriverCommand::DOUBLE_CLICK => array('method' => 'POST', 'url' => '/session/:sessionId/doubleclick'), - DriverCommand::MOVE_TO => array('method' => 'POST', 'url' => '/session/:sessionId/moveto'), - DriverCommand::NEW_SESSION => array('method' => 'POST', 'url' => '/session'), - DriverCommand::QUIT => array('method' => 'DELETE', 'url' => '/session/:sessionId'), - DriverCommand::REFRESH => array('method' => 'POST', 'url' => '/session/:sessionId/refresh'), - DriverCommand::UPLOAD_FILE => array('method' => 'POST', 'url' => '/session/:sessionId/file'), // undocumented - DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/keys'), - DriverCommand::SET_ALERT_VALUE => array('method' => 'POST', 'url' => '/session/:sessionId/alert_text'), - DriverCommand::SEND_KEYS_TO_ELEMENT => array( - 'method' => 'POST', - 'url' => '/session/:sessionId/element/:id/value', - ), - DriverCommand::IMPLICITLY_WAIT => array( - 'method' => 'POST', - 'url' => '/session/:sessionId/timeouts/implicit_wait', - ), - DriverCommand::SET_SCREEN_ORIENTATION => array('method' => 'POST', 'url' => '/session/:sessionId/orientation'), - DriverCommand::SET_TIMEOUT => array('method' => 'POST', 'url' => '/session/:sessionId/timeouts'), - DriverCommand::SET_SCRIPT_TIMEOUT => array( - 'method' => 'POST', - 'url' => '/session/:sessionId/timeouts/async_script', - ), - DriverCommand::SET_WINDOW_POSITION => array( + ], + DriverCommand::MOUSE_DOWN => ['method' => 'POST', 'url' => '/session/:sessionId/buttondown'], + DriverCommand::MOUSE_UP => ['method' => 'POST', 'url' => '/session/:sessionId/buttonup'], + DriverCommand::CLICK => ['method' => 'POST', 'url' => '/session/:sessionId/click'], + DriverCommand::DOUBLE_CLICK => ['method' => 'POST', 'url' => '/session/:sessionId/doubleclick'], + DriverCommand::MOVE_TO => ['method' => 'POST', 'url' => '/session/:sessionId/moveto'], + DriverCommand::NEW_SESSION => ['method' => 'POST', 'url' => '/session'], + DriverCommand::QUIT => ['method' => 'DELETE', 'url' => '/session/:sessionId'], + DriverCommand::REFRESH => ['method' => 'POST', 'url' => '/session/:sessionId/refresh'], + DriverCommand::UPLOAD_FILE => ['method' => 'POST', 'url' => '/session/:sessionId/file'], // undocumented + DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT => ['method' => 'POST', 'url' => '/session/:sessionId/keys'], + DriverCommand::SET_ALERT_VALUE => ['method' => 'POST', 'url' => '/session/:sessionId/alert_text'], + DriverCommand::SEND_KEYS_TO_ELEMENT => ['method' => 'POST', 'url' => '/session/:sessionId/element/:id/value'], + DriverCommand::IMPLICITLY_WAIT => ['method' => 'POST', 'url' => '/session/:sessionId/timeouts/implicit_wait'], + DriverCommand::SET_SCREEN_ORIENTATION => ['method' => 'POST', 'url' => '/session/:sessionId/orientation'], + DriverCommand::SET_TIMEOUT => ['method' => 'POST', 'url' => '/session/:sessionId/timeouts'], + DriverCommand::SET_SCRIPT_TIMEOUT => ['method' => 'POST', 'url' => '/session/:sessionId/timeouts/async_script'], + DriverCommand::SET_WINDOW_POSITION => [ 'method' => 'POST', 'url' => '/session/:sessionId/window/:windowHandle/position', - ), - DriverCommand::SET_WINDOW_SIZE => array( + ], + DriverCommand::SET_WINDOW_SIZE => [ 'method' => 'POST', 'url' => '/session/:sessionId/window/:windowHandle/size', - ), - DriverCommand::SUBMIT_ELEMENT => array('method' => 'POST', 'url' => '/session/:sessionId/element/:id/submit'), - DriverCommand::SCREENSHOT => array('method' => 'GET', 'url' => '/session/:sessionId/screenshot'), - DriverCommand::TOUCH_SINGLE_TAP => array('method' => 'POST', 'url' => '/session/:sessionId/touch/click'), - DriverCommand::TOUCH_DOWN => array('method' => 'POST', 'url' => '/session/:sessionId/touch/down'), - DriverCommand::TOUCH_DOUBLE_TAP => array('method' => 'POST', 'url' => '/session/:sessionId/touch/doubleclick'), - DriverCommand::TOUCH_FLICK => array('method' => 'POST', 'url' => '/session/:sessionId/touch/flick'), - DriverCommand::TOUCH_LONG_PRESS => array('method' => 'POST', 'url' => '/session/:sessionId/touch/longclick'), - DriverCommand::TOUCH_MOVE => array('method' => 'POST', 'url' => '/session/:sessionId/touch/move'), - DriverCommand::TOUCH_SCROLL => array('method' => 'POST', 'url' => '/session/:sessionId/touch/scroll'), - DriverCommand::TOUCH_UP => array('method' => 'POST', 'url' => '/session/:sessionId/touch/up'), - ); + ], + DriverCommand::SUBMIT_ELEMENT => ['method' => 'POST', 'url' => '/session/:sessionId/element/:id/submit'], + DriverCommand::SCREENSHOT => ['method' => 'GET', 'url' => '/session/:sessionId/screenshot'], + DriverCommand::TOUCH_SINGLE_TAP => ['method' => 'POST', 'url' => '/session/:sessionId/touch/click'], + DriverCommand::TOUCH_DOWN => ['method' => 'POST', 'url' => '/session/:sessionId/touch/down'], + DriverCommand::TOUCH_DOUBLE_TAP => ['method' => 'POST', 'url' => '/session/:sessionId/touch/doubleclick'], + DriverCommand::TOUCH_FLICK => ['method' => 'POST', 'url' => '/session/:sessionId/touch/flick'], + DriverCommand::TOUCH_LONG_PRESS => ['method' => 'POST', 'url' => '/session/:sessionId/touch/longclick'], + DriverCommand::TOUCH_MOVE => ['method' => 'POST', 'url' => '/session/:sessionId/touch/move'], + DriverCommand::TOUCH_SCROLL => ['method' => 'POST', 'url' => '/session/:sessionId/touch/scroll'], + DriverCommand::TOUCH_UP => ['method' => 'POST', 'url' => '/session/:sessionId/touch/up'], + ]; /** * @var string */ @@ -205,10 +172,10 @@ public function __construct($url, $http_proxy = null, $http_proxy_port = null) curl_setopt( $this->curl, CURLOPT_HTTPHEADER, - array( + [ 'Content-Type: application/json;charset=UTF-8', 'Accept: application/json', - ) + ] ); $this->setRequestTimeout(30000); $this->setConnectionTimeout(30000); @@ -317,7 +284,7 @@ public function execute(WebDriverCommand $command) if ($params && is_array($params)) { $msg .= sprintf(' with params: %s', json_encode($params)); } - WebDriverException::throwException(-1, $msg . "\n\n" . $error, array()); + WebDriverException::throwException(-1, $msg . "\n\n" . $error, []); } $results = json_decode($raw_results, true); diff --git a/lib/Remote/RemoteExecuteMethod.php b/lib/Remote/RemoteExecuteMethod.php index 5a995215e..ce66e5610 100644 --- a/lib/Remote/RemoteExecuteMethod.php +++ b/lib/Remote/RemoteExecuteMethod.php @@ -32,7 +32,7 @@ public function __construct(RemoteWebDriver $driver) * @param array $parameters * @return mixed */ - public function execute($command_name, array $parameters = array()) + public function execute($command_name, array $parameters = []) { return $this->driver->execute($command_name, $parameters); } diff --git a/lib/Remote/RemoteKeyboard.php b/lib/Remote/RemoteKeyboard.php index 7b2e114a2..b10b1ca72 100644 --- a/lib/Remote/RemoteKeyboard.php +++ b/lib/Remote/RemoteKeyboard.php @@ -43,9 +43,9 @@ public function __construct(RemoteExecuteMethod $executor) */ public function sendKeys($keys) { - $this->executor->execute(DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT, array( + $this->executor->execute(DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT, [ 'value' => WebDriverKeys::encode($keys), - )); + ]); return $this; } @@ -59,9 +59,9 @@ public function sendKeys($keys) */ public function pressKey($key) { - $this->executor->execute(DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT, array( - 'value' => array((string) $key), - )); + $this->executor->execute(DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT, [ + 'value' => [(string) $key], + ]); return $this; } @@ -75,9 +75,9 @@ public function pressKey($key) */ public function releaseKey($key) { - $this->executor->execute(DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT, array( - 'value' => array((string) $key), - )); + $this->executor->execute(DriverCommand::SEND_KEYS_TO_ACTIVE_ELEMENT, [ + 'value' => [(string) $key], + ]); return $this; } diff --git a/lib/Remote/RemoteMouse.php b/lib/Remote/RemoteMouse.php index 00a4ef7b6..48c578df7 100644 --- a/lib/Remote/RemoteMouse.php +++ b/lib/Remote/RemoteMouse.php @@ -44,9 +44,9 @@ public function __construct(RemoteExecuteMethod $executor) public function click(WebDriverCoordinates $where = null) { $this->moveIfNeeded($where); - $this->executor->execute(DriverCommand::CLICK, array( + $this->executor->execute(DriverCommand::CLICK, [ 'button' => 0, - )); + ]); return $this; } @@ -59,9 +59,9 @@ public function click(WebDriverCoordinates $where = null) public function contextClick(WebDriverCoordinates $where = null) { $this->moveIfNeeded($where); - $this->executor->execute(DriverCommand::CLICK, array( + $this->executor->execute(DriverCommand::CLICK, [ 'button' => 2, - )); + ]); return $this; } @@ -104,7 +104,7 @@ public function mouseMove( $x_offset = null, $y_offset = null ) { - $params = array(); + $params = []; if ($where !== null) { $params['element'] = $where->getAuxiliary(); } diff --git a/lib/Remote/RemoteTargetLocator.php b/lib/Remote/RemoteTargetLocator.php index 67d2ad7cd..8eb38814f 100644 --- a/lib/Remote/RemoteTargetLocator.php +++ b/lib/Remote/RemoteTargetLocator.php @@ -42,7 +42,7 @@ public function __construct($executor, $driver) */ public function defaultContent() { - $params = array('id' => null); + $params = ['id' => null]; $this->executor->execute(DriverCommand::SWITCH_TO_FRAME, $params); return $this->driver; @@ -58,12 +58,12 @@ public function defaultContent() public function frame($frame) { if ($frame instanceof WebDriverElement) { - $id = array('ELEMENT' => $frame->getID()); + $id = ['ELEMENT' => $frame->getID()]; } else { $id = (string) $frame; } - $params = array('id' => $id); + $params = ['id' => $id]; $this->executor->execute(DriverCommand::SWITCH_TO_FRAME, $params); return $this->driver; @@ -78,7 +78,7 @@ public function frame($frame) */ public function window($handle) { - $params = array('name' => (string) $handle); + $params = ['name' => (string) $handle]; $this->executor->execute(DriverCommand::SWITCH_TO_WINDOW, $params); return $this->driver; diff --git a/lib/Remote/RemoteTouchScreen.php b/lib/Remote/RemoteTouchScreen.php index a052a6063..8c3981474 100644 --- a/lib/Remote/RemoteTouchScreen.php +++ b/lib/Remote/RemoteTouchScreen.php @@ -45,7 +45,7 @@ public function tap(WebDriverElement $element) { $this->executor->execute( DriverCommand::TOUCH_SINGLE_TAP, - array('element' => $element->getID()) + ['element' => $element->getID()] ); return $this; @@ -60,7 +60,7 @@ public function doubleTap(WebDriverElement $element) { $this->executor->execute( DriverCommand::TOUCH_DOUBLE_TAP, - array('element' => $element->getID()) + ['element' => $element->getID()] ); return $this; @@ -74,10 +74,10 @@ public function doubleTap(WebDriverElement $element) */ public function down($x, $y) { - $this->executor->execute(DriverCommand::TOUCH_DOWN, array( + $this->executor->execute(DriverCommand::TOUCH_DOWN, [ 'x' => $x, 'y' => $y, - )); + ]); return $this; } @@ -90,10 +90,10 @@ public function down($x, $y) */ public function flick($xspeed, $yspeed) { - $this->executor->execute(DriverCommand::TOUCH_FLICK, array( + $this->executor->execute(DriverCommand::TOUCH_FLICK, [ 'xspeed' => $xspeed, 'yspeed' => $yspeed, - )); + ]); return $this; } @@ -108,12 +108,12 @@ public function flick($xspeed, $yspeed) */ public function flickFromElement(WebDriverElement $element, $xoffset, $yoffset, $speed) { - $this->executor->execute(DriverCommand::TOUCH_FLICK, array( + $this->executor->execute(DriverCommand::TOUCH_FLICK, [ 'xoffset' => $xoffset, 'yoffset' => $yoffset, 'element' => $element->getID(), 'speed' => $speed, - )); + ]); return $this; } @@ -127,7 +127,7 @@ public function longPress(WebDriverElement $element) { $this->executor->execute( DriverCommand::TOUCH_LONG_PRESS, - array('element' => $element->getID()) + ['element' => $element->getID()] ); return $this; @@ -141,10 +141,10 @@ public function longPress(WebDriverElement $element) */ public function move($x, $y) { - $this->executor->execute(DriverCommand::TOUCH_MOVE, array( + $this->executor->execute(DriverCommand::TOUCH_MOVE, [ 'x' => $x, 'y' => $y, - )); + ]); return $this; } @@ -157,10 +157,10 @@ public function move($x, $y) */ public function scroll($xoffset, $yoffset) { - $this->executor->execute(DriverCommand::TOUCH_SCROLL, array( + $this->executor->execute(DriverCommand::TOUCH_SCROLL, [ 'xoffset' => $xoffset, 'yoffset' => $yoffset, - )); + ]); return $this; } @@ -174,11 +174,11 @@ public function scroll($xoffset, $yoffset) */ public function scrollFromElement(WebDriverElement $element, $xoffset, $yoffset) { - $this->executor->execute(DriverCommand::TOUCH_SCROLL, array( + $this->executor->execute(DriverCommand::TOUCH_SCROLL, [ 'element' => $element->getID(), 'xoffset' => $xoffset, 'yoffset' => $yoffset, - )); + ]); return $this; } @@ -191,10 +191,10 @@ public function scrollFromElement(WebDriverElement $element, $xoffset, $yoffset) */ public function up($x, $y) { - $this->executor->execute(DriverCommand::TOUCH_UP, array( + $this->executor->execute(DriverCommand::TOUCH_UP, [ 'x' => $x, 'y' => $y, - )); + ]); return $this; } diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index 4f885bc43..f1706e75b 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -94,7 +94,7 @@ public static function create( $command = new WebDriverCommand( null, DriverCommand::NEW_SESSION, - array('desiredCapabilities' => $desired_capabilities) + ['desiredCapabilities' => $desired_capabilities] ); $response = $executor->execute($command); @@ -133,7 +133,7 @@ public static function createBySessionID($session_id, $url = 'http://localhost:4 */ public function close() { - $this->execute(DriverCommand::CLOSE, array()); + $this->execute(DriverCommand::CLOSE, []); return $this; } @@ -148,7 +148,7 @@ public function close() */ public function findElement(WebDriverBy $by) { - $params = array('using' => $by->getMechanism(), 'value' => $by->getValue()); + $params = ['using' => $by->getMechanism(), 'value' => $by->getValue()]; $raw_element = $this->execute( DriverCommand::FIND_ELEMENT, $params @@ -168,13 +168,13 @@ public function findElement(WebDriverBy $by) */ public function findElements(WebDriverBy $by) { - $params = array('using' => $by->getMechanism(), 'value' => $by->getValue()); + $params = ['using' => $by->getMechanism(), 'value' => $by->getValue()]; $raw_elements = $this->execute( DriverCommand::FIND_ELEMENTS, $params ); - $elements = array(); + $elements = []; foreach ($raw_elements as $raw_element) { $elements[] = $this->newElement($raw_element['ELEMENT']); } @@ -191,7 +191,7 @@ public function findElements(WebDriverBy $by) */ public function get($url) { - $params = array('url' => (string) $url); + $params = ['url' => (string) $url]; $this->execute(DriverCommand::GET, $params); return $this; @@ -237,7 +237,7 @@ public function getWindowHandle() { return $this->execute( DriverCommand::GET_CURRENT_WINDOW_HANDLE, - array() + [] ); } @@ -248,7 +248,7 @@ public function getWindowHandle() */ public function getWindowHandles() { - return $this->execute(DriverCommand::GET_WINDOW_HANDLES, array()); + return $this->execute(DriverCommand::GET_WINDOW_HANDLES, []); } /** @@ -268,10 +268,10 @@ public function quit() */ private function prepareScriptArguments(array $arguments) { - $args = array(); + $args = []; foreach ($arguments as $key => $value) { if ($value instanceof WebDriverElement) { - $args[$key] = array('ELEMENT' => $value->getID()); + $args[$key] = ['ELEMENT' => $value->getID()]; } else { if (is_array($value)) { $value = $this->prepareScriptArguments($value); @@ -292,12 +292,12 @@ private function prepareScriptArguments(array $arguments) * @param array $arguments The arguments of the script. * @return mixed The return value of the script. */ - public function executeScript($script, array $arguments = array()) + public function executeScript($script, array $arguments = []) { - $params = array( + $params = [ 'script' => $script, 'args' => $this->prepareScriptArguments($arguments), - ); + ]; return $this->execute(DriverCommand::EXECUTE_SCRIPT, $params); } @@ -315,12 +315,12 @@ public function executeScript($script, array $arguments = array()) * @param array $arguments The arguments of the script. * @return mixed The value passed by the script to the callback. */ - public function executeAsyncScript($script, array $arguments = array()) + public function executeAsyncScript($script, array $arguments = []) { - $params = array( + $params = [ 'script' => $script, 'args' => $this->prepareScriptArguments($arguments), - ); + ]; return $this->execute( DriverCommand::EXECUTE_ASYNC_SCRIPT, @@ -529,13 +529,13 @@ public static function getAllSessions($url = 'http://localhost:4444/wd/hub', $ti $command = new WebDriverCommand( null, DriverCommand::GET_ALL_SESSIONS, - array() + [] ); return $executor->execute($command)->getValue(); } - public function execute($command_name, $params = array()) + public function execute($command_name, $params = []) { $command = new WebDriverCommand( $this->sessionID, @@ -547,8 +547,8 @@ public function execute($command_name, $params = array()) $response = $this->executor->execute($command); return $response->getValue(); - } else { - return null; } + + return null; } } diff --git a/lib/Remote/RemoteWebElement.php b/lib/Remote/RemoteWebElement.php index 217356592..d05b1e67a 100644 --- a/lib/Remote/RemoteWebElement.php +++ b/lib/Remote/RemoteWebElement.php @@ -64,7 +64,7 @@ public function clear() { $this->executor->execute( DriverCommand::CLEAR_ELEMENT, - array(':id' => $this->id) + [':id' => $this->id] ); return $this; @@ -79,7 +79,7 @@ public function click() { $this->executor->execute( DriverCommand::CLICK_ELEMENT, - array(':id' => $this->id) + [':id' => $this->id] ); return $this; @@ -96,11 +96,11 @@ public function click() */ public function findElement(WebDriverBy $by) { - $params = array( + $params = [ 'using' => $by->getMechanism(), 'value' => $by->getValue(), ':id' => $this->id, - ); + ]; $raw_element = $this->executor->execute( DriverCommand::FIND_CHILD_ELEMENT, $params @@ -119,17 +119,17 @@ public function findElement(WebDriverBy $by) */ public function findElements(WebDriverBy $by) { - $params = array( + $params = [ 'using' => $by->getMechanism(), 'value' => $by->getValue(), ':id' => $this->id, - ); + ]; $raw_elements = $this->executor->execute( DriverCommand::FIND_CHILD_ELEMENTS, $params ); - $elements = array(); + $elements = []; foreach ($raw_elements as $raw_element) { $elements[] = $this->newElement($raw_element['ELEMENT']); } @@ -145,10 +145,10 @@ public function findElements(WebDriverBy $by) */ public function getAttribute($attribute_name) { - $params = array( + $params = [ ':name' => $attribute_name, ':id' => $this->id, - ); + ]; return $this->executor->execute( DriverCommand::GET_ELEMENT_ATTRIBUTE, @@ -164,10 +164,10 @@ public function getAttribute($attribute_name) */ public function getCSSValue($css_property_name) { - $params = array( + $params = [ ':propertyName' => $css_property_name, ':id' => $this->id, - ); + ]; return $this->executor->execute( DriverCommand::GET_ELEMENT_VALUE_OF_CSS_PROPERTY, @@ -184,7 +184,7 @@ public function getLocation() { $location = $this->executor->execute( DriverCommand::GET_ELEMENT_LOCATION, - array(':id' => $this->id) + [':id' => $this->id] ); return new WebDriverPoint($location['x'], $location['y']); @@ -200,7 +200,7 @@ public function getLocationOnScreenOnceScrolledIntoView() { $location = $this->executor->execute( DriverCommand::GET_ELEMENT_LOCATION_ONCE_SCROLLED_INTO_VIEW, - array(':id' => $this->id) + [':id' => $this->id] ); return new WebDriverPoint($location['x'], $location['y']); @@ -239,7 +239,7 @@ public function getSize() { $size = $this->executor->execute( DriverCommand::GET_ELEMENT_SIZE, - array(':id' => $this->id) + [':id' => $this->id] ); return new WebDriverDimension($size['width'], $size['height']); @@ -258,7 +258,7 @@ public function getTagName() // Remove it when fixed to be consistent with the protocol. return strtolower($this->executor->execute( DriverCommand::GET_ELEMENT_TAG_NAME, - array(':id' => $this->id) + [':id' => $this->id] )); } @@ -272,7 +272,7 @@ public function getText() { return $this->executor->execute( DriverCommand::GET_ELEMENT_TEXT, - array(':id' => $this->id) + [':id' => $this->id] ); } @@ -286,7 +286,7 @@ public function isDisplayed() { return $this->executor->execute( DriverCommand::IS_ELEMENT_DISPLAYED, - array(':id' => $this->id) + [':id' => $this->id] ); } @@ -300,7 +300,7 @@ public function isEnabled() { return $this->executor->execute( DriverCommand::IS_ELEMENT_ENABLED, - array(':id' => $this->id) + [':id' => $this->id] ); } @@ -313,7 +313,7 @@ public function isSelected() { return $this->executor->execute( DriverCommand::IS_ELEMENT_SELECTED, - array(':id' => $this->id) + [':id' => $this->id] ); } @@ -327,17 +327,17 @@ public function sendKeys($value) { $local_file = $this->fileDetector->getLocalFile($value); if ($local_file === null) { - $params = array( + $params = [ 'value' => WebDriverKeys::encode($value), ':id' => $this->id, - ); + ]; $this->executor->execute(DriverCommand::SEND_KEYS_TO_ELEMENT, $params); } else { $remote_path = $this->upload($local_file); - $params = array( + $params = [ 'value' => WebDriverKeys::encode($remote_path), ':id' => $this->id, - ); + ]; $this->executor->execute(DriverCommand::SEND_KEYS_TO_ELEMENT, $params); } @@ -368,9 +368,9 @@ private function upload($local_file) $file_name = $info['basename']; $zip->addFile($local_file, $file_name); $zip->close(); - $params = array( + $params = [ 'file' => base64_encode(file_get_contents($temp_zip)), - ); + ]; $remote_path = $this->executor->execute( DriverCommand::UPLOAD_FILE, $params @@ -412,7 +412,7 @@ public function submit() { $this->executor->execute( DriverCommand::SUBMIT_ELEMENT, - array(':id' => $this->id) + [':id' => $this->id] ); return $this; @@ -436,10 +436,10 @@ public function getID() */ public function equals(WebDriverElement $other) { - return $this->executor->execute(DriverCommand::ELEMENT_EQUALS, array( + return $this->executor->execute(DriverCommand::ELEMENT_EQUALS, [ ':id' => $this->id, ':other' => $other->getID(), - )); + ]); } /** diff --git a/lib/Remote/Service/DriverService.php b/lib/Remote/Service/DriverService.php index 82a427a44..c32ce7246 100644 --- a/lib/Remote/Service/DriverService.php +++ b/lib/Remote/Service/DriverService.php @@ -51,7 +51,7 @@ class DriverService * @param array $args * @param array|null $environment Use the system environment if it is null */ - public function __construct($executable, $port, $args = array(), $environment = null) + public function __construct($executable, $port, $args = [], $environment = null) { $this->executable = self::checkExecutable($executable); $this->url = sprintf('http://localhost:%d', $port); @@ -76,14 +76,14 @@ public function start() return $this; } - $pipes = array(); + $pipes = []; $this->process = proc_open( sprintf('%s %s', $this->executable, implode(' ', $this->args)), - $descriptorspec = array( - 0 => array('pipe', 'r'), // stdin - 1 => array('pipe', 'w'), // stdout - 2 => array('pipe', 'a'), // stderr - ), + $descriptorspec = [ + 0 => ['pipe', 'r'], // stdin + 1 => ['pipe', 'w'], // stdout + 2 => ['pipe', 'a'], // stderr + ], $pipes, null, $this->environment diff --git a/lib/Support/Events/EventFiringWebDriver.php b/lib/Support/Events/EventFiringWebDriver.php index 7ea2242b0..2052d014f 100644 --- a/lib/Support/Events/EventFiringWebDriver.php +++ b/lib/Support/Events/EventFiringWebDriver.php @@ -120,7 +120,7 @@ public function findElements(WebDriverBy $by) { $this->dispatch('beforeFindBy', $by, null, $this); try { - $elements = array(); + $elements = []; foreach ($this->driver->findElements($by) as $element) { $elements[] = $this->newElement($element); } @@ -156,7 +156,7 @@ public function findElement(WebDriverBy $by) * @throws WebDriverException * @return mixed */ - public function executeScript($script, array $arguments = array()) + public function executeScript($script, array $arguments = []) { if (!$this->driver instanceof JavaScriptExecutor) { throw new UnsupportedOperationException( @@ -181,7 +181,7 @@ public function executeScript($script, array $arguments = array()) * @throws WebDriverException * @return mixed */ - public function executeAsyncScript($script, array $arguments = array()) + public function executeAsyncScript($script, array $arguments = []) { if (!$this->driver instanceof JavaScriptExecutor) { throw new UnsupportedOperationException( diff --git a/lib/Support/Events/EventFiringWebElement.php b/lib/Support/Events/EventFiringWebElement.php index 8f6f20d81..4a0384f53 100644 --- a/lib/Support/Events/EventFiringWebElement.php +++ b/lib/Support/Events/EventFiringWebElement.php @@ -162,7 +162,7 @@ public function findElements(WebDriverBy $by) $this->dispatcher->getDefaultDriver() ); try { - $elements = array(); + $elements = []; foreach ($this->element->findElements($by) as $element) { $elements[] = $this->newElement($element); } diff --git a/lib/WebDriverAction.php b/lib/WebDriverAction.php index e73b883ad..aead0a708 100644 --- a/lib/WebDriverAction.php +++ b/lib/WebDriverAction.php @@ -20,7 +20,5 @@ */ interface WebDriverAction { - /** - */ public function perform(); } diff --git a/lib/WebDriverAlert.php b/lib/WebDriverAlert.php index 4ba9f6168..2ef69172c 100644 --- a/lib/WebDriverAlert.php +++ b/lib/WebDriverAlert.php @@ -73,7 +73,7 @@ public function sendKeys($value) { $this->executor->execute( DriverCommand::SET_ALERT_VALUE, - array('text' => $value) + ['text' => $value] ); return $this; diff --git a/lib/WebDriverDispatcher.php b/lib/WebDriverDispatcher.php index 202a3ec93..782c84690 100644 --- a/lib/WebDriverDispatcher.php +++ b/lib/WebDriverDispatcher.php @@ -22,7 +22,7 @@ class WebDriverDispatcher /** * @var array */ - protected $listeners = array(); + protected $listeners = []; /** * @var EventFiringWebDriver */ @@ -83,7 +83,7 @@ public function unregister(WebDriverEventListener $listener) public function dispatch($method, $arguments) { foreach ($this->listeners as $listener) { - call_user_func_array(array($listener, $method), $arguments); + call_user_func_array([$listener, $method], $arguments); } return $this; diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index 775d23cf5..54e2283b5 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -293,9 +293,9 @@ function ($driver) use ($visibility_of_element_located) { try { if ($element !== null && $element->isEnabled()) { return $element; - } else { - return null; } + + return null; } catch (StaleElementReferenceException $e) { return null; } diff --git a/lib/WebDriverKeys.php b/lib/WebDriverKeys.php index ecab819b6..57d37c1eb 100644 --- a/lib/WebDriverKeys.php +++ b/lib/WebDriverKeys.php @@ -98,10 +98,10 @@ public static function encode($keys) } if (is_string($keys)) { - $keys = array($keys); + $keys = [$keys]; } - $encoded = array(); + $encoded = []; foreach ($keys as $key) { if (is_array($key)) { // handle modified keys diff --git a/lib/WebDriverNavigation.php b/lib/WebDriverNavigation.php index 5e06d6257..6c7857d1d 100644 --- a/lib/WebDriverNavigation.php +++ b/lib/WebDriverNavigation.php @@ -80,7 +80,7 @@ public function refresh() */ public function to($url) { - $params = array('url' => (string) $url); + $params = ['url' => (string) $url]; $this->executor->execute(DriverCommand::GET, $params); return $this; diff --git a/lib/WebDriverOptions.php b/lib/WebDriverOptions.php index 8b80d3dba..d9c8bee44 100644 --- a/lib/WebDriverOptions.php +++ b/lib/WebDriverOptions.php @@ -55,7 +55,7 @@ public function addCookie(array $cookie) $this->validate($cookie); $this->executor->execute( DriverCommand::ADD_COOKIE, - array('cookie' => $cookie) + ['cookie' => $cookie] ); return $this; @@ -83,7 +83,7 @@ public function deleteCookieNamed($name) { $this->executor->execute( DriverCommand::DELETE_COOKIE, - array(':name' => $name) + [':name' => $name] ); return $this; @@ -174,7 +174,7 @@ public function getLog($log_type) { return $this->executor->execute( DriverCommand::GET_LOG, - array('type' => $log_type) + ['type' => $log_type] ); } diff --git a/lib/WebDriverSelect.php b/lib/WebDriverSelect.php index 158690b2f..4a9797a00 100644 --- a/lib/WebDriverSelect.php +++ b/lib/WebDriverSelect.php @@ -62,7 +62,7 @@ public function getOptions() */ public function getAllSelectedOptions() { - $selected_options = array(); + $selected_options = []; foreach ($this->getOptions() as $option) { if ($option->isSelected()) { $selected_options[] = $option; diff --git a/lib/WebDriverTimeouts.php b/lib/WebDriverTimeouts.php index 50b62f24f..3e5936a4b 100644 --- a/lib/WebDriverTimeouts.php +++ b/lib/WebDriverTimeouts.php @@ -40,7 +40,7 @@ public function implicitlyWait($seconds) { $this->executor->execute( DriverCommand::IMPLICITLY_WAIT, - array('ms' => $seconds * 1000) + ['ms' => $seconds * 1000] ); return $this; @@ -57,7 +57,7 @@ public function setScriptTimeout($seconds) { $this->executor->execute( DriverCommand::SET_SCRIPT_TIMEOUT, - array('ms' => $seconds * 1000) + ['ms' => $seconds * 1000] ); return $this; @@ -72,10 +72,10 @@ public function setScriptTimeout($seconds) */ public function pageLoadTimeout($seconds) { - $this->executor->execute(DriverCommand::SET_TIMEOUT, array( + $this->executor->execute(DriverCommand::SET_TIMEOUT, [ 'type' => 'page load', 'ms' => $seconds * 1000, - )); + ]); return $this; } diff --git a/lib/WebDriverWindow.php b/lib/WebDriverWindow.php index b63a681b3..828d4969c 100644 --- a/lib/WebDriverWindow.php +++ b/lib/WebDriverWindow.php @@ -40,7 +40,7 @@ public function getPosition() { $position = $this->executor->execute( DriverCommand::GET_WINDOW_POSITION, - array(':windowHandle' => 'current') + [':windowHandle' => 'current'] ); return new WebDriverPoint( @@ -59,7 +59,7 @@ public function getSize() { $size = $this->executor->execute( DriverCommand::GET_WINDOW_SIZE, - array(':windowHandle' => 'current') + [':windowHandle' => 'current'] ); return new WebDriverDimension( @@ -77,7 +77,7 @@ public function maximize() { $this->executor->execute( DriverCommand::MAXIMIZE_WINDOW, - array(':windowHandle' => 'current') + [':windowHandle' => 'current'] ); return $this; @@ -92,11 +92,11 @@ public function maximize() */ public function setSize(WebDriverDimension $size) { - $params = array( + $params = [ 'width' => $size->getWidth(), 'height' => $size->getHeight(), ':windowHandle' => 'current', - ); + ]; $this->executor->execute(DriverCommand::SET_WINDOW_SIZE, $params); return $this; @@ -111,11 +111,11 @@ public function setSize(WebDriverDimension $size) */ public function setPosition(WebDriverPoint $position) { - $params = array( + $params = [ 'x' => $position->getX(), 'y' => $position->getY(), ':windowHandle' => 'current', - ); + ]; $this->executor->execute(DriverCommand::SET_WINDOW_POSITION, $params); return $this; @@ -142,7 +142,7 @@ public function getScreenOrientation() public function setScreenOrientation($orientation) { $orientation = strtoupper($orientation); - if (!in_array($orientation, array('PORTRAIT', 'LANDSCAPE'))) { + if (!in_array($orientation, ['PORTRAIT', 'LANDSCAPE'])) { throw new IndexOutOfBoundsException( 'Orientation must be either PORTRAIT, or LANDSCAPE' ); @@ -150,7 +150,7 @@ public function setScreenOrientation($orientation) $this->executor->execute( DriverCommand::SET_SCREEN_ORIENTATION, - array('orientation' => $orientation) + ['orientation' => $orientation] ); return $this; diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index fca694854..6ebe98b61 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -31,11 +31,11 @@ protected function setUp() { $this->driver = RemoteWebDriver::create( 'http://localhost:4444/wd/hub', - array( + [ WebDriverCapabilityType::BROWSER_NAME //=> WebDriverBrowserType::FIREFOX, => WebDriverBrowserType::HTMLUNIT, - ) + ] ); } diff --git a/tests/unit/Interactions/Internal/WebDriverButtonReleaseActionTest.php b/tests/unit/Interactions/Internal/WebDriverButtonReleaseActionTest.php index a192190f9..f2bb1b647 100644 --- a/tests/unit/Interactions/Internal/WebDriverButtonReleaseActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverButtonReleaseActionTest.php @@ -29,8 +29,8 @@ class WebDriverButtonReleaseActionTest extends \PHPUnit_Framework_TestCase public function setUp() { - $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); - $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); + $this->webDriverMouse = $this->getMockBuilder(WebDriverMouse::class)->getMock(); + $this->locationProvider = $this->getMockBuilder(WebDriverLocatable::class)->getMock(); $this->webDriverButtonReleaseAction = new WebDriverButtonReleaseAction( $this->webDriverMouse, $this->locationProvider @@ -39,7 +39,7 @@ public function setUp() public function testPerformSendsMouseUpCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + $coords = $this->getMockBuilder(WebDriverCoordinates::class) ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseUp')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); diff --git a/tests/unit/Interactions/Internal/WebDriverClickActionTest.php b/tests/unit/Interactions/Internal/WebDriverClickActionTest.php index 62162c77e..fdb868141 100644 --- a/tests/unit/Interactions/Internal/WebDriverClickActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverClickActionTest.php @@ -29,8 +29,8 @@ class WebDriverClickActionTest extends \PHPUnit_Framework_TestCase public function setUp() { - $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); - $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); + $this->webDriverMouse = $this->getMockBuilder(WebDriverMouse::class)->getMock(); + $this->locationProvider = $this->getMockBuilder(WebDriverLocatable::class)->getMock(); $this->webDriverClickAction = new WebDriverClickAction( $this->webDriverMouse, $this->locationProvider @@ -39,7 +39,7 @@ public function setUp() public function testPerformSendsClickCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + $coords = $this->getMockBuilder(WebDriverCoordinates::class) ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); diff --git a/tests/unit/Interactions/Internal/WebDriverClickAndHoldActionTest.php b/tests/unit/Interactions/Internal/WebDriverClickAndHoldActionTest.php index 9dec8b9aa..eb3f4bc6f 100644 --- a/tests/unit/Interactions/Internal/WebDriverClickAndHoldActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverClickAndHoldActionTest.php @@ -29,8 +29,8 @@ class WebDriverClickAndHoldActionTest extends \PHPUnit_Framework_TestCase public function setUp() { - $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); - $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); + $this->webDriverMouse = $this->getMockBuilder(WebDriverMouse::class)->getMock(); + $this->locationProvider = $this->getMockBuilder(WebDriverLocatable::class)->getMock(); $this->webDriverClickAndHoldAction = new WebDriverClickAndHoldAction( $this->webDriverMouse, $this->locationProvider @@ -39,7 +39,7 @@ public function setUp() public function testPerformSendsMouseDownCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + $coords = $this->getMockBuilder(WebDriverCoordinates::class) ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseDown')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); diff --git a/tests/unit/Interactions/Internal/WebDriverContextClickActionTest.php b/tests/unit/Interactions/Internal/WebDriverContextClickActionTest.php index 2c5a92547..e9162f239 100644 --- a/tests/unit/Interactions/Internal/WebDriverContextClickActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverContextClickActionTest.php @@ -29,8 +29,8 @@ class WebDriverContextClickActionTest extends \PHPUnit_Framework_TestCase public function setUp() { - $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); - $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); + $this->webDriverMouse = $this->getMockBuilder(WebDriverMouse::class)->getMock(); + $this->locationProvider = $this->getMockBuilder(WebDriverLocatable::class)->getMock(); $this->webDriverContextClickAction = new WebDriverContextClickAction( $this->webDriverMouse, $this->locationProvider @@ -39,7 +39,7 @@ public function setUp() public function testPerformSendsContextClickCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + $coords = $this->getMockBuilder(WebDriverCoordinates::class) ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('contextClick')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); diff --git a/tests/unit/Interactions/Internal/WebDriverDoubleClickActionTest.php b/tests/unit/Interactions/Internal/WebDriverDoubleClickActionTest.php index b83115f77..acd74550f 100644 --- a/tests/unit/Interactions/Internal/WebDriverDoubleClickActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverDoubleClickActionTest.php @@ -29,8 +29,8 @@ class WebDriverDoubleClickActionTest extends \PHPUnit_Framework_TestCase public function setUp() { - $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); - $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); + $this->webDriverMouse = $this->getMockBuilder(WebDriverMouse::class)->getMock(); + $this->locationProvider = $this->getMockBuilder(WebDriverLocatable::class)->getMock(); $this->webDriverDoubleClickAction = new WebDriverDoubleClickAction( $this->webDriverMouse, $this->locationProvider @@ -39,7 +39,7 @@ public function setUp() public function testPerformSendsDoubleClickCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + $coords = $this->getMockBuilder(WebDriverCoordinates::class) ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('doubleClick')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); diff --git a/tests/unit/Interactions/Internal/WebDriverKeyDownActionTest.php b/tests/unit/Interactions/Internal/WebDriverKeyDownActionTest.php index e1cb8acbc..267b58b3e 100644 --- a/tests/unit/Interactions/Internal/WebDriverKeyDownActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverKeyDownActionTest.php @@ -32,9 +32,9 @@ class WebDriverKeyDownActionTest extends \PHPUnit_Framework_TestCase public function setUp() { - $this->webDriverKeyboard = $this->getMockBuilder('Facebook\WebDriver\WebDriverKeyboard')->getMock(); - $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); - $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); + $this->webDriverKeyboard = $this->getMockBuilder(WebDriverKeyboard::class)->getMock(); + $this->webDriverMouse = $this->getMockBuilder(WebDriverMouse::class)->getMock(); + $this->locationProvider = $this->getMockBuilder(WebDriverLocatable::class)->getMock(); $this->webDriverKeyDownAction = new WebDriverKeyDownAction( $this->webDriverKeyboard, @@ -45,7 +45,7 @@ public function setUp() public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + $coords = $this->getMockBuilder(WebDriverCoordinates::class) ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); diff --git a/tests/unit/Interactions/Internal/WebDriverKeyUpActionTest.php b/tests/unit/Interactions/Internal/WebDriverKeyUpActionTest.php index c21ac24c1..970a35b0f 100644 --- a/tests/unit/Interactions/Internal/WebDriverKeyUpActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverKeyUpActionTest.php @@ -32,9 +32,9 @@ class WebDriverKeyUpActionTest extends \PHPUnit_Framework_TestCase public function setUp() { - $this->webDriverKeyboard = $this->getMockBuilder('Facebook\WebDriver\WebDriverKeyboard')->getMock(); - $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); - $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); + $this->webDriverKeyboard = $this->getMockBuilder(WebDriverKeyboard::class)->getMock(); + $this->webDriverMouse = $this->getMockBuilder(WebDriverMouse::class)->getMock(); + $this->locationProvider = $this->getMockBuilder(WebDriverLocatable::class)->getMock(); $this->webDriverKeyUpAction = new WebDriverKeyUpAction( $this->webDriverKeyboard, @@ -46,7 +46,7 @@ public function setUp() public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + $coords = $this->getMockBuilder(WebDriverCoordinates::class) ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); diff --git a/tests/unit/Interactions/Internal/WebDriverMouseMoveActionTest.php b/tests/unit/Interactions/Internal/WebDriverMouseMoveActionTest.php index fe3ca9379..565530ad8 100644 --- a/tests/unit/Interactions/Internal/WebDriverMouseMoveActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverMouseMoveActionTest.php @@ -29,8 +29,8 @@ class WebDriverMouseMoveActionTest extends \PHPUnit_Framework_TestCase public function setUp() { - $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); - $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); + $this->webDriverMouse = $this->getMockBuilder(WebDriverMouse::class)->getMock(); + $this->locationProvider = $this->getMockBuilder(WebDriverLocatable::class)->getMock(); $this->webDriverMouseMoveAction = new WebDriverMouseMoveAction( $this->webDriverMouse, @@ -40,7 +40,7 @@ public function setUp() public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + $coords = $this->getMockBuilder(WebDriverCoordinates::class) ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseMove')->with($coords); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); diff --git a/tests/unit/Interactions/Internal/WebDriverMouseToOffsetActionTest.php b/tests/unit/Interactions/Internal/WebDriverMouseToOffsetActionTest.php index 37a2853ba..d2d5286a1 100644 --- a/tests/unit/Interactions/Internal/WebDriverMouseToOffsetActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverMouseToOffsetActionTest.php @@ -31,8 +31,8 @@ class WebDriverMouseToOffsetActionTest extends \PHPUnit_Framework_TestCase public function setUp() { - $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); - $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); + $this->webDriverMouse = $this->getMockBuilder(WebDriverMouse::class)->getMock(); + $this->locationProvider = $this->getMockBuilder(WebDriverLocatable::class)->getMock(); $this->webDriverMoveToOffsetAction = new WebDriverMoveToOffsetAction( $this->webDriverMouse, @@ -44,7 +44,7 @@ public function setUp() public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + $coords = $this->getMockBuilder(WebDriverCoordinates::class) ->disableOriginalConstructor()->getMock(); $this->webDriverMouse->expects($this->once())->method('mouseMove')->with($coords, 150, 200); $this->locationProvider->expects($this->once())->method('getCoordinates')->will($this->returnValue($coords)); diff --git a/tests/unit/Interactions/Internal/WebDriverSendKeysActionTest.php b/tests/unit/Interactions/Internal/WebDriverSendKeysActionTest.php index 82a736dea..9b06b3df7 100644 --- a/tests/unit/Interactions/Internal/WebDriverSendKeysActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverSendKeysActionTest.php @@ -34,11 +34,11 @@ class WebDriverSendKeysActionTest extends \PHPUnit_Framework_TestCase public function setUp() { - $this->webDriverKeyboard = $this->getMockBuilder('Facebook\WebDriver\WebDriverKeyboard')->getMock(); - $this->webDriverMouse = $this->getMockBuilder('Facebook\WebDriver\WebDriverMouse')->getMock(); - $this->locationProvider = $this->getMockBuilder('Facebook\WebDriver\Internal\WebDriverLocatable')->getMock(); + $this->webDriverKeyboard = $this->getMockBuilder(WebDriverKeyboard::class)->getMock(); + $this->webDriverMouse = $this->getMockBuilder(WebDriverMouse::class)->getMock(); + $this->locationProvider = $this->getMockBuilder(WebDriverLocatable::class)->getMock(); - $this->keys = array('t', 'e', 's', 't'); + $this->keys = ['t', 'e', 's', 't']; $this->webDriverSendKeysAction = new WebDriverSendKeysAction( $this->webDriverKeyboard, $this->webDriverMouse, @@ -49,7 +49,7 @@ public function setUp() public function testPerformFocusesOnElementAndSendPressKeyCommand() { - $coords = $this->getMockBuilder('Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates') + $coords = $this->getMockBuilder(WebDriverCoordinates::class) ->disableOriginalConstructor()->getMock(); $this->webDriverKeyboard->expects($this->once())->method('sendKeys')->with($this->keys); $this->webDriverMouse->expects($this->once())->method('click')->with($coords); diff --git a/tests/unit/Remote/DesiredCapabilitiesTest.php b/tests/unit/Remote/DesiredCapabilitiesTest.php index c68a747ed..dacdcd139 100644 --- a/tests/unit/Remote/DesiredCapabilitiesTest.php +++ b/tests/unit/Remote/DesiredCapabilitiesTest.php @@ -25,14 +25,14 @@ class DesiredCapabilitiesTest extends \PHPUnit_Framework_TestCase public function testShouldInstantiateWithCapabilitiesGivenInConstructor() { $capabilities = new DesiredCapabilities( - array('fooKey' => 'fooVal', WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY) + ['fooKey' => 'fooVal', WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY] ); $this->assertSame('fooVal', $capabilities->getCapability('fooKey')); $this->assertSame('ANY', $capabilities->getPlatform()); $this->assertSame( - array('fooKey' => 'fooVal', WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY), + ['fooKey' => 'fooVal', WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY], $capabilities->toArray() ); } @@ -42,7 +42,7 @@ public function testShouldInstantiateEmptyInstance() $capabilities = new DesiredCapabilities(); $this->assertNull($capabilities->getCapability('foo')); - $this->assertSame(array(), $capabilities->toArray()); + $this->assertSame([], $capabilities->toArray()); } public function testShouldProvideAccessToCapabilitiesUsingSettersAndGetters() @@ -93,7 +93,7 @@ public function testShouldProvideShortcutSetupForCapabilitiesOfEachBrowser( $expectedPlatform ) { /** @var DesiredCapabilities $capabilities */ - $capabilities = call_user_func(array('Facebook\WebDriver\Remote\DesiredCapabilities', $setupMethod)); + $capabilities = call_user_func([DesiredCapabilities::class, $setupMethod]); $this->assertSame($expectedBrowser, $capabilities->getBrowserName()); $this->assertSame($expectedPlatform, $capabilities->getPlatform()); @@ -104,20 +104,20 @@ public function testShouldProvideShortcutSetupForCapabilitiesOfEachBrowser( */ public function browserCapabilitiesProvider() { - return array( - array('android', WebDriverBrowserType::ANDROID, WebDriverPlatform::ANDROID), - array('chrome', WebDriverBrowserType::CHROME, WebDriverPlatform::ANY), - array('firefox', WebDriverBrowserType::FIREFOX, WebDriverPlatform::ANY), - array('htmlUnit', WebDriverBrowserType::HTMLUNIT, WebDriverPlatform::ANY), - array('htmlUnitWithJS', WebDriverBrowserType::HTMLUNIT, WebDriverPlatform::ANY), - array('MicrosoftEdge', WebDriverBrowserType::MICROSOFT_EDGE, WebDriverPlatform::WINDOWS), - array('internetExplorer', WebDriverBrowserType::IE, WebDriverPlatform::WINDOWS), - array('iphone', WebDriverBrowserType::IPHONE, WebDriverPlatform::MAC), - array('ipad', WebDriverBrowserType::IPAD, WebDriverPlatform::MAC), - array('opera', WebDriverBrowserType::OPERA, WebDriverPlatform::ANY), - array('safari', WebDriverBrowserType::SAFARI, WebDriverPlatform::ANY), - array('phantomjs', WebDriverBrowserType::PHANTOMJS, WebDriverPlatform::ANY), - ); + return [ + ['android', WebDriverBrowserType::ANDROID, WebDriverPlatform::ANDROID], + ['chrome', WebDriverBrowserType::CHROME, WebDriverPlatform::ANY], + ['firefox', WebDriverBrowserType::FIREFOX, WebDriverPlatform::ANY], + ['htmlUnit', WebDriverBrowserType::HTMLUNIT, WebDriverPlatform::ANY], + ['htmlUnitWithJS', WebDriverBrowserType::HTMLUNIT, WebDriverPlatform::ANY], + ['MicrosoftEdge', WebDriverBrowserType::MICROSOFT_EDGE, WebDriverPlatform::WINDOWS], + ['internetExplorer', WebDriverBrowserType::IE, WebDriverPlatform::WINDOWS], + ['iphone', WebDriverBrowserType::IPHONE, WebDriverPlatform::MAC], + ['ipad', WebDriverBrowserType::IPAD, WebDriverPlatform::MAC], + ['opera', WebDriverBrowserType::OPERA, WebDriverPlatform::ANY], + ['safari', WebDriverBrowserType::SAFARI, WebDriverPlatform::ANY], + ['phantomjs', WebDriverBrowserType::PHANTOMJS, WebDriverPlatform::ANY], + ]; } public function testShouldSetupFirefoxProfileAndDisableReaderViewForFirefoxBrowser() @@ -126,7 +126,7 @@ public function testShouldSetupFirefoxProfileAndDisableReaderViewForFirefoxBrows /** @var FirefoxProfile $firefoxProfile */ $firefoxProfile = $capabilities->getCapability(FirefoxDriver::PROFILE); - $this->assertInstanceOf('Facebook\WebDriver\Firefox\FirefoxProfile', $firefoxProfile); + $this->assertInstanceOf(FirefoxProfile::class, $firefoxProfile); $this->assertSame('false', $firefoxProfile->getPreference(FirefoxPreferences::READER_PARSE_ON_LOAD_ENABLED)); } diff --git a/tests/unit/Remote/WebDriverCommandTest.php b/tests/unit/Remote/WebDriverCommandTest.php index 30a206119..9993c6ce5 100644 --- a/tests/unit/Remote/WebDriverCommandTest.php +++ b/tests/unit/Remote/WebDriverCommandTest.php @@ -19,10 +19,10 @@ class WebDriverCommandTest extends \PHPUnit_Framework_TestCase { public function testShouldSetOptionsUsingConstructor() { - $command = new WebDriverCommand('session-id-123', 'bar-baz-name', array('foo' => 'bar')); + $command = new WebDriverCommand('session-id-123', 'bar-baz-name', ['foo' => 'bar']); $this->assertSame('session-id-123', $command->getSessionID()); $this->assertSame('bar-baz-name', $command->getName()); - $this->assertSame(array('foo' => 'bar'), $command->getParameters()); + $this->assertSame(['foo' => 'bar'], $command->getParameters()); } } From 901814b5569e23f4084c2ac210b6170e995d6d5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 12 Oct 2016 12:39:37 +0200 Subject: [PATCH 231/784] Extend addCookie docs --- lib/WebDriverOptions.php | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/lib/WebDriverOptions.php b/lib/WebDriverOptions.php index d9c8bee44..2b298f20f 100644 --- a/lib/WebDriverOptions.php +++ b/lib/WebDriverOptions.php @@ -35,18 +35,17 @@ public function __construct(ExecuteMethod $executor) * Add a specific cookie. * * Here are the valid attributes of a cookie array. - * 'name' : string The name of the cookie; may not be null or an empty - * string. - * 'value' : string The cookie value; may not be null. - * 'path' : string The path the cookie is visible to. If left blank or set - * to null, will be set to "/". - * 'domain': string The domain the cookie is visible to. It should be null or - * the same as the domain of the current URL. - * 'secure': bool Whether this cookie requires a secure connection(https?). - * It should be null or equal to the security of the current - * URL. - * 'expiry': int The cookie's expiration date; may be null. + * 'name' : string The name of the cookie; may not be null or an empty string. + * 'value' : string The cookie value; may not be null. + * 'path' : string OPTIONAL The path the cookie is visible to. Defaults to "/" if omitted. + * 'domain' : string OPTIONAL The domain the cookie is visible to. Defaults to the current browsing context's + * document's URL domain if omitted. + * 'secure' : bool OPTIONAL Whether this cookie requires a secure connection (https). Defaults to false if + * omitted. + * 'httpOnly': bool OPTIONAL Whether the cookie is an HTTP only cookie. Defaults to false if omitted. + * 'expiry' : int OPTIONAL The cookie's expiration date, specified in seconds since Unix Epoch. * + * @see https://w3c.github.io/webdriver/webdriver-spec.html#cookies * @param array $cookie An array with key as the attributes mentioned above. * @return WebDriverOptions The current instance. */ @@ -93,8 +92,7 @@ public function deleteCookieNamed($name) * Get the cookie with a given name. * * @param string $name - * @return array The cookie, or null if no cookie with the given name is - * presented. + * @return array The cookie, or null if no cookie with the given name is presented. */ public function getCookieNamed($name) { From b1d4b9fb05fb0437d5f8f68bea1ecb26fa8cdbda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 18 Sep 2016 23:19:01 +0200 Subject: [PATCH 232/784] Do not set URL placeholder params as part of POST body (fixes #323) --- composer.json | 3 +- lib/Remote/HttpCommandExecutor.php | 4 +- tests/unit/Remote/HttpCommandExecutorTest.php | 94 +++++++++++++++++++ 3 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 tests/unit/Remote/HttpCommandExecutorTest.php diff --git a/composer.json b/composer.json index e8afaf77e..a6b95a894 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,8 @@ "require-dev": { "phpunit/phpunit": "4.6.* || ~5.0", "friendsofphp/php-cs-fixer": "^1.11", - "squizlabs/php_codesniffer": "^2.6" + "squizlabs/php_codesniffer": "^2.6", + "php-mock/php-mock-phpunit": "^1.1" }, "suggest": { "phpdocumentor/phpdocumentor": "2.*" diff --git a/lib/Remote/HttpCommandExecutor.php b/lib/Remote/HttpCommandExecutor.php index 9cfcd1fa4..11b53536a 100644 --- a/lib/Remote/HttpCommandExecutor.php +++ b/lib/Remote/HttpCommandExecutor.php @@ -240,9 +240,7 @@ public function execute(WebDriverCommand $command) foreach ($params as $name => $value) { if ($name[0] === ':') { $url = str_replace($name, $value, $url); - if ($http_method != 'POST') { - unset($params[$name]); - } + unset($params[$name]); } } diff --git a/tests/unit/Remote/HttpCommandExecutorTest.php b/tests/unit/Remote/HttpCommandExecutorTest.php new file mode 100644 index 000000000..268b3e873 --- /dev/null +++ b/tests/unit/Remote/HttpCommandExecutorTest.php @@ -0,0 +1,94 @@ +executor = new HttpCommandExecutor('http://localhost:4444/'); + } + + /** + * @dataProvider commandProvider + * @param int $command + * @param array $params + * @param string $expectedUrl + * @param string $expectedPostData + */ + public function testShouldSendRequestToAssembledUrl($command, array $params, $expectedUrl, $expectedPostData) + { + $command = new WebDriverCommand('foo-123', $command, $params); + + $curlSetoptMock = $this->getFunctionMock(__NAMESPACE__, 'curl_setopt'); + $curlSetoptMock->expects($this->at(0)) + ->with($this->anything(), CURLOPT_URL, $expectedUrl); + + $curlSetoptMock->expects($this->at(2)) + ->with($this->anything(), CURLOPT_POSTFIELDS, $expectedPostData); + + $curlExecMock = $this->getFunctionMock(__NAMESPACE__, 'curl_exec'); + $curlExecMock->expects($this->once()) + ->willReturn('{}'); + + $this->executor->execute($command); + } + + /** + * @return array[] + */ + public function commandProvider() + { + return [ + 'POST command having :id placeholder in url' => [ + DriverCommand::SEND_KEYS_TO_ELEMENT, + ['value' => 'submitted-value', ':id' => '1337'], + 'http://localhost:4444/session/foo-123/element/1337/value', + '{"value":"submitted-value"}', + ], + 'POST command without :id placeholder in url' => [ + DriverCommand::TOUCH_UP, + ['x' => 3, 'y' => 6], + 'http://localhost:4444/session/foo-123/touch/up', + '{"x":3,"y":6}', + ], + 'Extra useless placeholder parameter should be removed' => [ + DriverCommand::TOUCH_UP, + ['x' => 3, 'y' => 6, ':useless' => 'foo'], + 'http://localhost:4444/session/foo-123/touch/up', + '{"x":3,"y":6}', + ], + 'DELETE command' => [ + DriverCommand::DELETE_COOKIE, + [':name' => 'cookie-name'], + 'http://localhost:4444/session/foo-123/cookie/cookie-name', + null, + ], + 'GET command without session in URL' => [ + DriverCommand::GET_ALL_SESSIONS, + [], + 'http://localhost:4444/sessions', + null, + ], + ]; + } +} From 41ae93d12e3a4f5b0d7ddb00e538829b75133d7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 14 Oct 2016 15:57:00 +0200 Subject: [PATCH 233/784] Add and fix typehints --- lib/Chrome/ChromeDriver.php | 3 +- .../Internal/WebDriverCoordinates.php | 23 +++++- .../Internal/WebDriverKeysRelatedAction.php | 9 +++ .../Internal/WebDriverMouseAction.php | 4 + .../Internal/WebDriverMoveToOffsetAction.php | 12 +++ .../Internal/WebDriverSendKeysAction.php | 7 +- .../Internal/WebDriverSingleKeyAction.php | 5 +- .../Touch/WebDriverDownAction.php | 6 ++ .../Touch/WebDriverFlickAction.php | 6 ++ .../Touch/WebDriverFlickFromElementAction.php | 9 +++ lib/Interactions/WebDriverActions.php | 3 + lib/Interactions/WebDriverCompositeAction.php | 3 + lib/Remote/DesiredCapabilities.php | 3 + lib/Remote/RemoteExecuteMethod.php | 3 + lib/Remote/RemoteTargetLocator.php | 8 +- lib/Remote/RemoteWebDriver.php | 21 +++-- lib/Remote/RemoteWebElement.php | 9 +-- lib/Remote/UselessFileDetector.php | 3 - lib/Support/Events/EventFiringWebDriver.php | 8 +- lib/Support/Events/EventFiringWebElement.php | 2 + lib/WebDriverAlert.php | 6 +- lib/WebDriverBy.php | 6 ++ lib/WebDriverDimension.php | 13 +++- lib/WebDriverElement.php | 3 +- lib/WebDriverExpectedCondition.php | 76 ++++++++----------- lib/WebDriverOptions.php | 3 + lib/WebDriverTimeouts.php | 6 +- lib/WebDriverWait.php | 17 +++-- lib/WebDriverWindow.php | 6 +- 29 files changed, 197 insertions(+), 86 deletions(-) diff --git a/lib/Chrome/ChromeDriver.php b/lib/Chrome/ChromeDriver.php index be807d7bc..b8aad6a07 100644 --- a/lib/Chrome/ChromeDriver.php +++ b/lib/Chrome/ChromeDriver.php @@ -40,7 +40,7 @@ public static function start(DesiredCapabilities $desired_capabilities = null, C return $driver; } - public function startSession($desired_capabilities) + public function startSession(DesiredCapabilities $desired_capabilities) { $command = new WebDriverCommand( null, @@ -76,6 +76,7 @@ public static function create( * @param string $url The url of the remote server * * @throws WebDriverException + * @return RemoteWebDriver|void */ public static function createBySessionID( $session_id, diff --git a/lib/Interactions/Internal/WebDriverCoordinates.php b/lib/Interactions/Internal/WebDriverCoordinates.php index ca7069cb5..911b7aece 100644 --- a/lib/Interactions/Internal/WebDriverCoordinates.php +++ b/lib/Interactions/Internal/WebDriverCoordinates.php @@ -15,7 +15,6 @@ namespace Facebook\WebDriver\Interactions\Internal; -use Closure; use Facebook\WebDriver\Exception\UnsupportedOperationException; use Facebook\WebDriver\WebDriverPoint; @@ -24,12 +23,30 @@ */ class WebDriverCoordinates { + /** + * @var null + */ private $onScreen; + /** + * @var callable + */ private $inViewPort; + /** + * @var callable + */ private $onPage; + /** + * @var string + */ private $auxiliary; - public function __construct($on_screen, Closure $in_view_port, Closure $on_page, $auxiliary) + /** + * @param null $on_screen + * @param callable $in_view_port + * @param callable $on_page + * @param string $auxiliary + */ + public function __construct($on_screen, callable $in_view_port, callable $on_page, $auxiliary) { $this->onScreen = $on_screen; $this->inViewPort = $in_view_port; @@ -65,7 +82,7 @@ public function onPage() } /** - * @return object The attached object. + * @return string The attached object id. */ public function getAuxiliary() { diff --git a/lib/Interactions/Internal/WebDriverKeysRelatedAction.php b/lib/Interactions/Internal/WebDriverKeysRelatedAction.php index b2f062750..899bb822e 100644 --- a/lib/Interactions/Internal/WebDriverKeysRelatedAction.php +++ b/lib/Interactions/Internal/WebDriverKeysRelatedAction.php @@ -24,8 +24,17 @@ */ abstract class WebDriverKeysRelatedAction { + /** + * @var WebDriverKeyboard + */ protected $keyboard; + /** + * @var WebDriverMouse + */ protected $mouse; + /** + * @var WebDriverLocatable|null + */ protected $locationProvider; /** diff --git a/lib/Interactions/Internal/WebDriverMouseAction.php b/lib/Interactions/Internal/WebDriverMouseAction.php index 8a13d86a7..2bec07386 100644 --- a/lib/Interactions/Internal/WebDriverMouseAction.php +++ b/lib/Interactions/Internal/WebDriverMouseAction.php @@ -32,6 +32,10 @@ class WebDriverMouseAction */ protected $locationProvider; + /** + * @param WebDriverMouse $mouse + * @param WebDriverLocatable|null $location_provider + */ public function __construct(WebDriverMouse $mouse, WebDriverLocatable $location_provider = null) { $this->mouse = $mouse; diff --git a/lib/Interactions/Internal/WebDriverMoveToOffsetAction.php b/lib/Interactions/Internal/WebDriverMoveToOffsetAction.php index 7fffa0189..29be343d2 100644 --- a/lib/Interactions/Internal/WebDriverMoveToOffsetAction.php +++ b/lib/Interactions/Internal/WebDriverMoveToOffsetAction.php @@ -21,9 +21,21 @@ class WebDriverMoveToOffsetAction extends WebDriverMouseAction implements WebDriverAction { + /** + * @var int|null + */ private $xOffset; + /** + * @var int|null + */ private $yOffset; + /** + * @param WebDriverMouse $mouse + * @param WebDriverLocatable|null $location_provider + * @param int|null $x_offset + * @param int|null $y_offset + */ public function __construct( WebDriverMouse $mouse, WebDriverLocatable $location_provider = null, diff --git a/lib/Interactions/Internal/WebDriverSendKeysAction.php b/lib/Interactions/Internal/WebDriverSendKeysAction.php index 14836be38..ef3ea0b71 100644 --- a/lib/Interactions/Internal/WebDriverSendKeysAction.php +++ b/lib/Interactions/Internal/WebDriverSendKeysAction.php @@ -22,7 +22,10 @@ class WebDriverSendKeysAction extends WebDriverKeysRelatedAction implements WebDriverAction { - private $keys; + /** + * @var string + */ + private $keys = ''; /** * @param WebDriverKeyboard $keyboard @@ -34,7 +37,7 @@ public function __construct( WebDriverKeyboard $keyboard, WebDriverMouse $mouse, WebDriverLocatable $location_provider = null, - $keys = null + $keys = '' ) { parent::__construct($keyboard, $mouse, $location_provider); $this->keys = $keys; diff --git a/lib/Interactions/Internal/WebDriverSingleKeyAction.php b/lib/Interactions/Internal/WebDriverSingleKeyAction.php index 174304d15..6311ee805 100644 --- a/lib/Interactions/Internal/WebDriverSingleKeyAction.php +++ b/lib/Interactions/Internal/WebDriverSingleKeyAction.php @@ -22,13 +22,14 @@ abstract class WebDriverSingleKeyAction extends WebDriverKeysRelatedAction implements WebDriverAction { - protected $key; + /** @var string */ + protected $key = ''; public function __construct( WebDriverKeyboard $keyboard, WebDriverMouse $mouse, WebDriverLocatable $location_provider = null, - $key = null + $key = '' ) { parent::__construct($keyboard, $mouse, $location_provider); $this->key = $key; diff --git a/lib/Interactions/Touch/WebDriverDownAction.php b/lib/Interactions/Touch/WebDriverDownAction.php index 46224aea2..5f392313c 100644 --- a/lib/Interactions/Touch/WebDriverDownAction.php +++ b/lib/Interactions/Touch/WebDriverDownAction.php @@ -19,7 +19,13 @@ class WebDriverDownAction extends WebDriverTouchAction implements WebDriverAction { + /** + * @var int + */ private $x; + /** + * @var int + */ private $y; /** diff --git a/lib/Interactions/Touch/WebDriverFlickAction.php b/lib/Interactions/Touch/WebDriverFlickAction.php index 52f43fde6..a32164d83 100644 --- a/lib/Interactions/Touch/WebDriverFlickAction.php +++ b/lib/Interactions/Touch/WebDriverFlickAction.php @@ -19,7 +19,13 @@ class WebDriverFlickAction extends WebDriverTouchAction implements WebDriverAction { + /** + * @var int + */ private $x; + /** + * @var int + */ private $y; /** diff --git a/lib/Interactions/Touch/WebDriverFlickFromElementAction.php b/lib/Interactions/Touch/WebDriverFlickFromElementAction.php index d91e84898..78445c256 100644 --- a/lib/Interactions/Touch/WebDriverFlickFromElementAction.php +++ b/lib/Interactions/Touch/WebDriverFlickFromElementAction.php @@ -20,8 +20,17 @@ class WebDriverFlickFromElementAction extends WebDriverTouchAction implements WebDriverAction { + /** + * @var int + */ private $x; + /** + * @var int + */ private $y; + /** + * @var int + */ private $speed; /** diff --git a/lib/Interactions/WebDriverActions.php b/lib/Interactions/WebDriverActions.php index 860cf8d5a..281b84dac 100644 --- a/lib/Interactions/WebDriverActions.php +++ b/lib/Interactions/WebDriverActions.php @@ -38,6 +38,9 @@ class WebDriverActions protected $mouse; protected $action; + /** + * @param WebDriver $driver + */ public function __construct(WebDriver $driver) { $this->driver = $driver; diff --git a/lib/Interactions/WebDriverCompositeAction.php b/lib/Interactions/WebDriverCompositeAction.php index 742544f59..75b879082 100644 --- a/lib/Interactions/WebDriverCompositeAction.php +++ b/lib/Interactions/WebDriverCompositeAction.php @@ -22,6 +22,9 @@ */ class WebDriverCompositeAction implements WebDriverAction { + /** + * @var array + */ private $actions = []; /** diff --git a/lib/Remote/DesiredCapabilities.php b/lib/Remote/DesiredCapabilities.php index a1cbfddf0..badd04313 100644 --- a/lib/Remote/DesiredCapabilities.php +++ b/lib/Remote/DesiredCapabilities.php @@ -25,6 +25,9 @@ class DesiredCapabilities implements WebDriverCapabilities { + /** + * @var array + */ private $capabilities; public function __construct(array $capabilities = []) diff --git a/lib/Remote/RemoteExecuteMethod.php b/lib/Remote/RemoteExecuteMethod.php index ce66e5610..4ab9e3890 100644 --- a/lib/Remote/RemoteExecuteMethod.php +++ b/lib/Remote/RemoteExecuteMethod.php @@ -17,6 +17,9 @@ class RemoteExecuteMethod implements ExecuteMethod { + /** + * @var RemoteWebDriver + */ private $driver; /** diff --git a/lib/Remote/RemoteTargetLocator.php b/lib/Remote/RemoteTargetLocator.php index 8eb38814f..9b4fe2526 100644 --- a/lib/Remote/RemoteTargetLocator.php +++ b/lib/Remote/RemoteTargetLocator.php @@ -25,7 +25,13 @@ */ class RemoteTargetLocator implements WebDriverTargetLocator { + /** + * @var ExecuteMethod + */ protected $executor; + /** + * @var WebDriver + */ protected $driver; public function __construct($executor, $driver) @@ -103,7 +109,7 @@ public function alert() */ public function activeElement() { - $response = $this->driver->execute(DriverCommand::GET_ACTIVE_ELEMENT); + $response = $this->driver->execute(DriverCommand::GET_ACTIVE_ELEMENT, []); $method = new RemoteExecuteMethod($this->driver); return new RemoteWebElement($method, $response['ELEMENT']); diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index f1706e75b..a904024f5 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -142,8 +142,7 @@ public function close() * Find the first WebDriverElement using the given mechanism. * * @param WebDriverBy $by - * @return RemoteWebElement NoSuchElementException is thrown in - * HttpCommandExecutor if no element is found. + * @return RemoteWebElement NoSuchElementException is thrown in HttpCommandExecutor if no element is found. * @see WebDriverBy */ public function findElement(WebDriverBy $by) @@ -158,12 +157,10 @@ public function findElement(WebDriverBy $by) } /** - * Find all WebDriverElements within the current page using the given - * mechanism. + * Find all WebDriverElements within the current page using the given mechanism. * * @param WebDriverBy $by - * @return RemoteWebElement[] A list of all WebDriverElements, or an empty - * array if nothing matches + * @return RemoteWebElement[] A list of all WebDriverElements, or an empty array if nothing matches * @see WebDriverBy */ public function findElements(WebDriverBy $by) @@ -228,8 +225,7 @@ public function getTitle() } /** - * Return an opaque handle to this window that uniquely identifies it within - * this driver instance. + * Return an opaque handle to this window that uniquely identifies it within this driver instance. * * @return string The current window handle. */ @@ -369,8 +365,7 @@ public function wait($timeout_in_second = 30, $interval_in_millisecond = 250) } /** - * An abstraction for managing stuff you would do in a browser menu. For - * example, adding and deleting cookies. + * An abstraction for managing stuff you would do in a browser menu. For example, adding and deleting cookies. * * @return WebDriverOptions */ @@ -380,8 +375,7 @@ public function manage() } /** - * An abstraction allowing the driver to access the browser's history and to - * navigate to a given URL. + * An abstraction allowing the driver to access the browser's history and to navigate to a given URL. * * @return WebDriverNavigation * @see WebDriverNavigation @@ -438,6 +432,9 @@ public function getTouch() return $this->touch; } + /** + * @return RemoteExecuteMethod + */ protected function getExecuteMethod() { if (!$this->executeMethod) { diff --git a/lib/Remote/RemoteWebElement.php b/lib/Remote/RemoteWebElement.php index d05b1e67a..dfc66d124 100644 --- a/lib/Remote/RemoteWebElement.php +++ b/lib/Remote/RemoteWebElement.php @@ -55,8 +55,7 @@ public function __construct(RemoteExecuteMethod $executor, $id) } /** - * If this element is a TEXTAREA or text INPUT element, this will clear the - * value. + * If this element is a TEXTAREA or text INPUT element, this will clear the value. * * @return RemoteWebElement The current instance. */ @@ -86,8 +85,7 @@ public function click() } /** - * Find the first WebDriverElement within this element using the given - * mechanism. + * Find the first WebDriverElement within this element using the given mechanism. * * @param WebDriverBy $by * @return RemoteWebElement NoSuchElementException is thrown in @@ -403,8 +401,7 @@ public function setFileDetector(FileDetector $detector) } /** - * If this current element is a form, or an element within a form, then this - * will be submitted to the remote server. + * If this current element is a form, or an element within a form, then this will be submitted to the remote server. * * @return RemoteWebElement The current instance. */ diff --git a/lib/Remote/UselessFileDetector.php b/lib/Remote/UselessFileDetector.php index f1e71f0c5..5ddd78e7d 100644 --- a/lib/Remote/UselessFileDetector.php +++ b/lib/Remote/UselessFileDetector.php @@ -17,9 +17,6 @@ class UselessFileDetector implements FileDetector { - /** - * @param string $file - */ public function getLocalFile($file) { return null; diff --git a/lib/Support/Events/EventFiringWebDriver.php b/lib/Support/Events/EventFiringWebDriver.php index 2052d014f..268b35ac7 100644 --- a/lib/Support/Events/EventFiringWebDriver.php +++ b/lib/Support/Events/EventFiringWebDriver.php @@ -119,14 +119,16 @@ public function get($url) public function findElements(WebDriverBy $by) { $this->dispatch('beforeFindBy', $by, null, $this); + $elements = []; + try { - $elements = []; foreach ($this->driver->findElements($by) as $element) { $elements[] = $this->newElement($element); } } catch (WebDriverException $exception) { $this->dispatchOnException($exception); } + $this->dispatch('afterFindBy', $by, null, $this); return $elements; @@ -140,11 +142,13 @@ public function findElements(WebDriverBy $by) public function findElement(WebDriverBy $by) { $this->dispatch('beforeFindBy', $by, null, $this); + try { $element = $this->newElement($this->driver->findElement($by)); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); } + $this->dispatch('afterFindBy', $by, null, $this); return $element; @@ -165,11 +169,13 @@ public function executeScript($script, array $arguments = []) } $this->dispatch('beforeScript', $script, $this); + try { $result = $this->driver->executeScript($script, $arguments); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); } + $this->dispatch('afterScript', $script, $this); return $result; diff --git a/lib/Support/Events/EventFiringWebElement.php b/lib/Support/Events/EventFiringWebElement.php index 4a0384f53..872c59c5e 100644 --- a/lib/Support/Events/EventFiringWebElement.php +++ b/lib/Support/Events/EventFiringWebElement.php @@ -133,11 +133,13 @@ public function findElement(WebDriverBy $by) $this, $this->dispatcher->getDefaultDriver() ); + try { $element = $this->newElement($this->element->findElement($by)); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); } + $this->dispatch( 'afterFindBy', $by, diff --git a/lib/WebDriverAlert.php b/lib/WebDriverAlert.php index 2ef69172c..b35132de6 100644 --- a/lib/WebDriverAlert.php +++ b/lib/WebDriverAlert.php @@ -16,15 +16,19 @@ namespace Facebook\WebDriver; use Facebook\WebDriver\Remote\DriverCommand; +use Facebook\WebDriver\Remote\ExecuteMethod; /** * An abstraction allowing the driver to manipulate the javascript alerts */ class WebDriverAlert { + /** + * @var ExecuteMethod + */ protected $executor; - public function __construct($executor) + public function __construct(ExecuteMethod $executor) { $this->executor = $executor; } diff --git a/lib/WebDriverBy.php b/lib/WebDriverBy.php index af51c26b2..f882683b3 100644 --- a/lib/WebDriverBy.php +++ b/lib/WebDriverBy.php @@ -24,7 +24,13 @@ */ class WebDriverBy { + /** + * @var string + */ private $mechanism; + /** + * @var string + */ private $value; protected function __construct($mechanism, $value) diff --git a/lib/WebDriverDimension.php b/lib/WebDriverDimension.php index 5b274e29a..111a77821 100644 --- a/lib/WebDriverDimension.php +++ b/lib/WebDriverDimension.php @@ -20,9 +20,19 @@ */ class WebDriverDimension { + /** + * @var int + */ private $height; + /** + * @var int + */ private $width; + /** + * @param int $width + * @param int $height + */ public function __construct($width, $height) { $this->width = $width; @@ -53,8 +63,7 @@ public function getWidth() * Check whether the given dimension is the same as the instance. * * @param WebDriverDimension $dimension The dimension to be compared with. - * @return bool Whether the height and the width are the same as the - * instance. + * @return bool Whether the height and the width are the same as the instance. */ public function equals(WebDriverDimension $dimension) { diff --git a/lib/WebDriverElement.php b/lib/WebDriverElement.php index 6eb7df5c6..2505368b3 100644 --- a/lib/WebDriverElement.php +++ b/lib/WebDriverElement.php @@ -21,8 +21,7 @@ interface WebDriverElement extends WebDriverSearchContext { /** - * If this element is a TEXTAREA or text INPUT element, this will clear the - * value. + * If this element is a TEXTAREA or text INPUT element, this will clear the value. * * @return WebDriverElement The current instance. */ diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index 54e2283b5..b7cd53204 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -28,20 +28,21 @@ class WebDriverExpectedCondition { /** - * A closure function to be executed by WebDriverWait. It should return + * A callable function to be executed by WebDriverWait. It should return * a truthy value, mostly boolean or a WebDriverElement, on success. + * @var callable */ private $apply; /** - * @return (function():T) a closure function to be executed by WebDriverWait + * @return callable A callable function to be executed by WebDriverWait */ public function getApply() { return $this->apply; } - protected function __construct($apply) + protected function __construct(callable $apply) { $this->apply = $apply; } @@ -50,13 +51,12 @@ protected function __construct($apply) * An expectation for checking the title of a page. * * @param string $title The expected title, which must be an exact match. - * @return bool WebDriverExpectedCondition True when the title matches, - * false otherwise. + * @return bool WebDriverExpectedCondition True when the title matches, false otherwise. */ public static function titleIs($title) { return new static( - function ($driver) use ($title) { + function (WebDriver $driver) use ($title) { return $title === $driver->getTitle(); } ); @@ -66,13 +66,12 @@ function ($driver) use ($title) { * An expectation for checking substring of a page Title. * * @param string $title The expected substring of Title. - * @return bool WebDriverExpectedCondition True when in title, - * false otherwise. + * @return bool WebDriverExpectedCondition True when in title, false otherwise. */ public static function titleContains($title) { return new static( - function ($driver) use ($title) { + function (WebDriver $driver) use ($title) { return strpos($driver->getTitle(), $title) !== false; } ); @@ -83,13 +82,12 @@ function ($driver) use ($title) { * page. This does not necessarily mean that the element is visible. * * @param WebDriverBy $by The locator used to find the element. - * @return WebDriverExpectedCondition The element which - * is located. + * @return WebDriverExpectedCondition The element which is located. */ public static function presenceOfElementLocated(WebDriverBy $by) { return new static( - function ($driver) use ($by) { + function (WebDriver $driver) use ($by) { return $driver->findElement($by); } ); @@ -101,13 +99,12 @@ function ($driver) use ($by) { * also has a height and width that is greater than 0. * * @param WebDriverBy $by The locator used to find the element. - * @return WebDriverExpectedCondition The element which is - * located and visible. + * @return WebDriverExpectedCondition The element which is located and visible. */ public static function visibilityOfElementLocated(WebDriverBy $by) { return new static( - function ($driver) use ($by) { + function (WebDriver $driver) use ($by) { try { $element = $driver->findElement($by); @@ -125,13 +122,12 @@ function ($driver) use ($by) { * displayed but also has a height and width that is greater than 0. * * @param WebDriverElement $element The element to be checked. - * @return WebDriverExpectedCondition The same - * WebDriverElement once it is visible. + * @return WebDriverExpectedCondition The same WebDriverElement once it is visible. */ public static function visibilityOf(WebDriverElement $element) { return new static( - function ($driver) use ($element) { + function () use ($element) { return $element->isDisplayed() ? $element : null; } ); @@ -142,13 +138,12 @@ function ($driver) use ($element) { * web page. * * @param WebDriverBy $by The locator used to find the element. - * @return WebDriverExpectedCondition An array of WebDriverElements - * once they are located. + * @return WebDriverExpectedCondition An array of WebDriverElements once they are located. */ public static function presenceOfAllElementsLocatedBy(WebDriverBy $by) { return new static( - function ($driver) use ($by) { + function (WebDriver $driver) use ($by) { $elements = $driver->findElements($by); return count($elements) > 0 ? $elements : null; @@ -167,7 +162,7 @@ function ($driver) use ($by) { public static function textToBePresentInElement(WebDriverBy $by, $text) { return new static( - function ($driver) use ($by, $text) { + function (WebDriver $driver) use ($by, $text) { try { $element_text = $driver->findElement($by)->getText(); @@ -190,7 +185,7 @@ function ($driver) use ($by, $text) { public static function textToBePresentInElementValue(WebDriverBy $by, $text) { return new static( - function ($driver) use ($by, $text) { + function (WebDriver $driver) use ($by, $text) { try { $element_text = $driver->findElement($by)->getAttribute('value'); @@ -214,7 +209,7 @@ function ($driver) use ($by, $text) { public static function frameToBeAvailableAndSwitchToIt($frame_locator) { return new static( - function ($driver) use ($frame_locator) { + function (WebDriver $driver) use ($frame_locator) { try { return $driver->switchTo()->frame($frame_locator); } catch (NoSuchFrameException $e) { @@ -229,13 +224,12 @@ function ($driver) use ($frame_locator) { * present on the DOM. * * @param WebDriverBy $by The locator used to find the element. - * @return bool WebDriverExpectedCondition Whether there is no element - * located. + * @return bool WebDriverExpectedCondition Whether there is no element located. */ public static function invisibilityOfElementLocated(WebDriverBy $by) { return new static( - function ($driver) use ($by) { + function (WebDriver $driver) use ($by) { try { return !($driver->findElement($by)->isDisplayed()); } catch (NoSuchElementException $e) { @@ -253,13 +247,12 @@ function ($driver) use ($by) { * * @param WebdriverBy $by The locator used to find the element. * @param string $text The text of the element. - * @return bool WebDriverExpectedCondition Whether the text is found in the - * element located. + * @return bool WebDriverExpectedCondition Whether the text is found in the element located. */ public static function invisibilityOfElementWithText(WebDriverBy $by, $text) { return new static( - function ($driver) use ($by, $text) { + function (WebDriver $driver) use ($by, $text) { try { return !($driver->findElement($by)->getText() === $text); } catch (NoSuchElementException $e) { @@ -285,7 +278,7 @@ public static function elementToBeClickable(WebDriverBy $by) self::visibilityOfElementLocated($by); return new static( - function ($driver) use ($visibility_of_element_located) { + function (WebDriver $driver) use ($visibility_of_element_located) { $element = call_user_func( $visibility_of_element_located->getApply(), $driver @@ -307,13 +300,12 @@ function ($driver) use ($visibility_of_element_located) { * Wait until an element is no longer attached to the DOM. * * @param WebDriverElement $element The element to wait for. - * @return bool WebDriverExpectedCondition false if the element is still - * attached to the DOM, true otherwise. + * @return bool WebDriverExpectedCondition false if the element is still attached to the DOM, true otherwise. */ public static function stalenessOf(WebDriverElement $element) { return new static( - function ($driver) use ($element) { + function () use ($element) { try { $element->isEnabled(); @@ -335,13 +327,12 @@ function ($driver) use ($element) { * when the second part of the condition is checked. * * @param WebDriverExpectedCondition $condition The condition wrapped. - * @return WebDriverExpectedCondition The return value of the - * getApply() of the given condition. + * @return WebDriverExpectedCondition The return value of the getApply() of the given condition. */ public static function refreshed(WebDriverExpectedCondition $condition) { return new static( - function ($driver) use ($condition) { + function (WebDriver $driver) use ($condition) { try { return call_user_func($condition->getApply(), $driver); } catch (StaleElementReferenceException $e) { @@ -376,14 +367,14 @@ public static function elementSelectionStateToBe($element_or_by, $selected) { if ($element_or_by instanceof WebDriverElement) { return new static( - function ($driver) use ($element_or_by, $selected) { + function () use ($element_or_by, $selected) { return $element_or_by->isSelected() === $selected; } ); } else { if ($element_or_by instanceof WebDriverBy) { return new static( - function ($driver) use ($element_or_by, $selected) { + function (WebDriver $driver) use ($element_or_by, $selected) { try { $element = $driver->findElement($element_or_by); @@ -400,13 +391,12 @@ function ($driver) use ($element_or_by, $selected) { /** * An expectation for whether an alert() box is present. * - * @return WebDriverExpectedCondition if alert() is present, - * null otherwise. + * @return WebDriverExpectedCondition if alert() is present, null otherwise. */ public static function alertIsPresent() { return new static( - function ($driver) { + function (WebDriver $driver) { try { // Unlike the Java code, we get a WebDriverAlert object regardless // of whether there is an alert. Calling getText() will throw @@ -431,7 +421,7 @@ function ($driver) { public static function not(WebDriverExpectedCondition $condition) { return new static( - function ($driver) use ($condition) { + function (WebDriver $driver) use ($condition) { $result = call_user_func($condition->getApply(), $driver); return !$result; diff --git a/lib/WebDriverOptions.php b/lib/WebDriverOptions.php index 2b298f20f..fef36f695 100644 --- a/lib/WebDriverOptions.php +++ b/lib/WebDriverOptions.php @@ -24,6 +24,9 @@ */ class WebDriverOptions { + /** + * @var ExecuteMethod + */ protected $executor; public function __construct(ExecuteMethod $executor) diff --git a/lib/WebDriverTimeouts.php b/lib/WebDriverTimeouts.php index 3e5936a4b..d62f2a124 100644 --- a/lib/WebDriverTimeouts.php +++ b/lib/WebDriverTimeouts.php @@ -16,15 +16,19 @@ namespace Facebook\WebDriver; use Facebook\WebDriver\Remote\DriverCommand; +use Facebook\WebDriver\Remote\ExecuteMethod; /** * Managing timeout behavior for WebDriver instances. */ class WebDriverTimeouts { + /** + * @var ExecuteMethod + */ protected $executor; - public function __construct($executor) + public function __construct(ExecuteMethod $executor) { $this->executor = $executor; } diff --git a/lib/WebDriverWait.php b/lib/WebDriverWait.php index a2297779d..37c44f94f 100644 --- a/lib/WebDriverWait.php +++ b/lib/WebDriverWait.php @@ -19,15 +19,23 @@ use Facebook\WebDriver\Exception\TimeOutException; /** - * A utility class, designed to help the user to wait until a condition turns - * true. + * A utility class, designed to help the user to wait until a condition turns true. * * @see WebDriverExpectedCondition. */ class WebDriverWait { + /** + * @var WebDriver + */ protected $driver; + /** + * @var int + */ protected $timeout; + /** + * @var int + */ protected $interval; public function __construct(WebDriver $driver, $timeout_in_second = null, $interval_in_millisecond = null) @@ -38,10 +46,9 @@ public function __construct(WebDriver $driver, $timeout_in_second = null, $inter } /** - * Calls the function provided with the driver as an argument until the return - * value is not falsey. + * Calls the function provided with the driver as an argument until the return value is not falsey. * - * @param (closure|WebDriverExpectedCondition) + * @param callable|WebDriverExpectedCondition $func_or_ec * @param string $message * * @throws NoSuchElementException diff --git a/lib/WebDriverWindow.php b/lib/WebDriverWindow.php index 828d4969c..68e49e015 100644 --- a/lib/WebDriverWindow.php +++ b/lib/WebDriverWindow.php @@ -17,15 +17,19 @@ use Facebook\WebDriver\Exception\IndexOutOfBoundsException; use Facebook\WebDriver\Remote\DriverCommand; +use Facebook\WebDriver\Remote\ExecuteMethod; /** * An abstraction allowing the driver to manipulate the browser's window */ class WebDriverWindow { + /** + * @var ExecuteMethod + */ protected $executor; - public function __construct($executor) + public function __construct(ExecuteMethod $executor) { $this->executor = $executor; } From e8a899389b012b6d2cb6681ee35c29952ec05264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 14 Oct 2016 16:18:47 +0200 Subject: [PATCH 234/784] Use Symfony Process component to start local webdriver processes --- composer.json | 1 + lib/Remote/Service/DriverService.php | 32 +++++++++++++--------------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/composer.json b/composer.json index e8afaf77e..b0fcd0901 100644 --- a/composer.json +++ b/composer.json @@ -12,6 +12,7 @@ }, "require": { "php": "^5.5 || ~7.0", + "symfony/process": "^2.8 || ^3.1", "ext-curl": "*" }, "require-dev": { diff --git a/lib/Remote/Service/DriverService.php b/lib/Remote/Service/DriverService.php index c32ce7246..634c45864 100644 --- a/lib/Remote/Service/DriverService.php +++ b/lib/Remote/Service/DriverService.php @@ -17,7 +17,12 @@ use Exception; use Facebook\WebDriver\Net\URLChecker; +use Symfony\Component\Process\Process; +use Symfony\Component\Process\ProcessBuilder; +/** + * Start local WebDriver service (when remote WebDriver server is not used). + */ class DriverService { /** @@ -41,7 +46,7 @@ class DriverService private $environment; /** - * @var resource + * @var Process */ private $process; @@ -76,18 +81,13 @@ public function start() return $this; } - $pipes = []; - $this->process = proc_open( - sprintf('%s %s', $this->executable, implode(' ', $this->args)), - $descriptorspec = [ - 0 => ['pipe', 'r'], // stdin - 1 => ['pipe', 'w'], // stdout - 2 => ['pipe', 'a'], // stderr - ], - $pipes, - null, - $this->environment - ); + $processBuilder = (new ProcessBuilder()) + ->setPrefix($this->executable) + ->setArguments($this->args) + ->addEnvironmentVariables($this->environment); + + $this->process = $processBuilder->getProcess(); + $this->process->start(); $checker = new URLChecker(); $checker->waitUntilAvailable(20 * 1000, $this->url . '/status'); @@ -104,7 +104,7 @@ public function stop() return $this; } - proc_terminate($this->process); + $this->process->stop(); $this->process = null; $checker = new URLChecker(); @@ -122,9 +122,7 @@ public function isRunning() return false; } - $status = proc_get_status($this->process); - - return $status['running']; + return $this->process->isRunning(); } /** From eafb4ca316b5aa5d7f085b45dcd7d7a4c34b4e97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 14 Oct 2016 17:15:38 +0200 Subject: [PATCH 235/784] Update changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a74435bef..4791dbe55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,10 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased -- Added initial basic support of Microsoft Edge browser +- Added initial support of remote Microsoft Edge browser (but starting local EdgeDriver is still not supported) - Utilize late static binding to make eg. `WebDriverBy` and `DesiredCapabilities` classes easily extensible - PHP version at least 5.5 is required +- Fixed incompatibility with Appium, caused by redundant params present in requests to Selenium server ## 1.1.3 - 2016-08-10 - Fixed FirefoxProfile to support installation of extensions with custom namespace prefix in their manifest file From af21de3ae5306a8ca0bcc02a19735dadc43e83f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 14 Oct 2016 17:16:51 +0200 Subject: [PATCH 236/784] Release 1.2.0 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4791dbe55..f89047b65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased + +## 1.2.0 - 2016-10-14 - Added initial support of remote Microsoft Edge browser (but starting local EdgeDriver is still not supported) - Utilize late static binding to make eg. `WebDriverBy` and `DesiredCapabilities` classes easily extensible - PHP version at least 5.5 is required From d9d94a74444e81c6d0b195c3535edee24ce6428c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 18 Oct 2016 23:00:06 +0200 Subject: [PATCH 237/784] Add badges to readme --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6cdae5742..a09dd9843 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ -php-webdriver – WebDriver bindings for PHP -=========================================== +# php-webdriver – Selenium WebDriver bindings for PHP + +[![Latest Stable Version](https://img.shields.io/packagist/v/facebook/webdriver.svg?style=flat-square)](https://packagist.org/packages/facebook/webdriver) +[![Total Downloads](https://img.shields.io/packagist/dt/facebook/webdriver.svg?style=flat-square)](https://packagist.org/packages/facebook/webdriver) +[![License](https://img.shields.io/packagist/l/facebook/webdriver.svg?style=flat-square)](https://packagist.org/packages/facebook/webdriver) ## Description Php-webdriver library is PHP language binding for Selenium WebDriver, which allows you to control web browsers from PHP. From 6be7aea8ba2ccd249d3537ceb4ab3b58fa09a894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 18 Oct 2016 23:04:08 +0200 Subject: [PATCH 238/784] Add link to StackOverflow where one can also look for help --- README.md | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index a09dd9843..8c3e2370a 100644 --- a/README.md +++ b/README.md @@ -81,17 +81,9 @@ Learn how to integrate it with PHPUnit [Blogpost](http://codeception.com/11-12-2 We have a great community willing to try and help you! -Currently we offer support in two manners: - -### Via our Facebook Group - -If you have questions or are an active contributor consider joining our facebook group and contributing to the communal discussion and support - -https://www.facebook.com/groups/phpwebdriver/ - -### Via Github - -If you're reading this you've already found our Github repository. If you have a question, feel free to submit it as an issue and our staff will do their best to help you as soon as possible. +- **Via our Facebook Group** - If you have questions or are an active contributor consider joining our [facebook group](https://www.facebook.com/groups/phpwebdriver/) and contributing to the communal discussion and support. +- **Via StackOverflow** - You can also [ask a question](https://stackoverflow.com/questions/ask?tags=php+selenium-webdriver) or find many already answered question on StackOverflow. +- **Via GitHub** - Another option if you have a question (or bug report) is to [submit it here](https://github.com/facebook/php-webdriver/issues/new) as an new issue. ## Contributing From 87a7eae1af88425289bbf33e059d9c253148b59e Mon Sep 17 00:00:00 2001 From: "borgogelli@iubar.it" Date: Mon, 31 Oct 2016 21:42:41 +0100 Subject: [PATCH 239/784] Fix unused code in the URLChecker class --- lib/Net/URLChecker.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Net/URLChecker.php b/lib/Net/URLChecker.php index 3a5d76316..97813202b 100644 --- a/lib/Net/URLChecker.php +++ b/lib/Net/URLChecker.php @@ -28,7 +28,7 @@ public function waitUntilAvailable($timeout_in_ms, $url) $end = microtime(true) + $timeout_in_ms / 1000; while ($end > microtime(true)) { - if ($this->getHTTPResponseCode($timeout_in_ms, $url) === 200) { + if ($this->getHTTPResponseCode($url) === 200) { return $this; } usleep(self::POLL_INTERVAL_MS); @@ -46,7 +46,7 @@ public function waitUntilUnavailable($timeout_in_ms, $url) $end = microtime(true) + $timeout_in_ms / 1000; while ($end > microtime(true)) { - if ($this->getHTTPResponseCode($timeout_in_ms, $url) !== 200) { + if ($this->getHTTPResponseCode($url) !== 200) { return $this; } usleep(self::POLL_INTERVAL_MS); @@ -59,7 +59,7 @@ public function waitUntilUnavailable($timeout_in_ms, $url) )); } - private function getHTTPResponseCode($timeout_in_ms, $url) + private function getHTTPResponseCode($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); From e9d0e39456d630e777596df33fb729456778989a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 2 Nov 2016 21:41:03 +0100 Subject: [PATCH 240/784] Clarify meaning of selenium server URL variable of RemoteWebDriver --- lib/Chrome/ChromeDriver.php | 6 +++--- lib/Remote/RemoteWebDriver.php | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/Chrome/ChromeDriver.php b/lib/Chrome/ChromeDriver.php index b8aad6a07..32ddf8f85 100644 --- a/lib/Chrome/ChromeDriver.php +++ b/lib/Chrome/ChromeDriver.php @@ -59,7 +59,7 @@ public function startSession(DesiredCapabilities $desired_capabilities) * @throws WebDriverException */ public static function create( - $url = 'http://localhost:4444/wd/hub', + $selenium_server_url = 'http://localhost:4444/wd/hub', $desired_capabilities = null, $connection_timeout_in_ms = null, $request_timeout_in_ms = null, @@ -73,14 +73,14 @@ public static function create( * Always throws an exception. Use ChromeDriver::start() instead. * * @param string $session_id The existing session id - * @param string $url The url of the remote server + * @param string $selenium_server_url The url of the remote Selenium WebDriver server * * @throws WebDriverException * @return RemoteWebDriver|void */ public static function createBySessionID( $session_id, - $url = 'http://localhost:4444/wd/hub' + $selenium_server_url = 'http://localhost:4444/wd/hub' ) { throw new WebDriverException('Please use ChromeDriver::start() instead.'); } diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index a904024f5..964740ead 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -59,7 +59,7 @@ protected function __construct() /** * Construct the RemoteWebDriver by a desired capabilities. * - * @param string $url The url of the remote server + * @param string $selenium_server_url The url of the remote Selenium WebDriver server * @param DesiredCapabilities|array $desired_capabilities The desired capabilities * @param int|null $connection_timeout_in_ms * @param int|null $request_timeout_in_ms @@ -68,14 +68,14 @@ protected function __construct() * @return RemoteWebDriver */ public static function create( - $url = 'http://localhost:4444/wd/hub', + $selenium_server_url = 'http://localhost:4444/wd/hub', $desired_capabilities = null, $connection_timeout_in_ms = null, $request_timeout_in_ms = null, $http_proxy = null, $http_proxy_port = null ) { - $url = preg_replace('#/+$#', '', $url); + $selenium_server_url = preg_replace('#/+$#', '', $selenium_server_url); // Passing DesiredCapabilities as $desired_capabilities is encouraged but // array is also accepted for legacy reason. @@ -83,7 +83,7 @@ public static function create( $desired_capabilities = $desired_capabilities->toArray(); } - $executor = new HttpCommandExecutor($url, $http_proxy, $http_proxy_port); + $executor = new HttpCommandExecutor($selenium_server_url, $http_proxy, $http_proxy_port); if ($connection_timeout_in_ms !== null) { $executor->setConnectionTimeout($connection_timeout_in_ms); } @@ -113,15 +113,15 @@ public static function create( * browser for the whole test suite. You do not have to pass the desired * capabilities because the session was created before. * - * @param string $url The url of the remote server + * @param string $selenium_server_url The url of the remote Selenium WebDriver server * @param string $session_id The existing session id * @return RemoteWebDriver */ - public static function createBySessionID($session_id, $url = 'http://localhost:4444/wd/hub') + public static function createBySessionID($session_id, $selenium_server_url = 'http://localhost:4444/wd/hub') { $driver = new static(); $driver->setSessionID($session_id) - ->setCommandExecutor(new HttpCommandExecutor($url)); + ->setCommandExecutor(new HttpCommandExecutor($selenium_server_url)); return $driver; } @@ -514,13 +514,13 @@ public function getSessionID() /** * Get all selenium sessions. * - * @param string $url The url of the remote server + * @param string $selenium_server_url The url of the remote Selenium WebDriver server * @param int $timeout_in_ms * @return array */ - public static function getAllSessions($url = 'http://localhost:4444/wd/hub', $timeout_in_ms = 30000) + public static function getAllSessions($selenium_server_url = 'http://localhost:4444/wd/hub', $timeout_in_ms = 30000) { - $executor = new HttpCommandExecutor($url); + $executor = new HttpCommandExecutor($selenium_server_url); $executor->setConnectionTimeout($timeout_in_ms); $command = new WebDriverCommand( From e135093fdfc9b59860b003364b8c0fda76d2c7f8 Mon Sep 17 00:00:00 2001 From: Jan Travnicek Date: Thu, 1 Dec 2016 14:53:43 +0100 Subject: [PATCH 241/784] chore: fixed phpdoc in WebDriverWindow class --- lib/WebDriverWindow.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/WebDriverWindow.php b/lib/WebDriverWindow.php index 68e49e015..d48a70773 100644 --- a/lib/WebDriverWindow.php +++ b/lib/WebDriverWindow.php @@ -38,7 +38,7 @@ public function __construct(ExecuteMethod $executor) * Get the position of the current window, relative to the upper left corner * of the screen. * - * @return array The current window position. + * @return WebDriverPoint The current window position. */ public function getPosition() { @@ -57,7 +57,7 @@ public function getPosition() * Get the size of the current window. This will return the outer window * dimension, not just the view port. * - * @return array The current window size. + * @return WebDriverDimension The current window size. */ public function getSize() { From f45b91dc17096bcf0d3a2f566cd8f18be3a4a5e4 Mon Sep 17 00:00:00 2001 From: danielemontesi Date: Fri, 28 Oct 2016 17:58:42 +0200 Subject: [PATCH 242/784] Fix: const overwritten --- lib/Net/URLChecker.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/Net/URLChecker.php b/lib/Net/URLChecker.php index 3a5d76316..dd197c46c 100644 --- a/lib/Net/URLChecker.php +++ b/lib/Net/URLChecker.php @@ -64,13 +64,13 @@ private function getHTTPResponseCode($timeout_in_ms, $url) $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + // The PHP doc indicates that CURLOPT_CONNECTTIMEOUT_MS constant is added in cURL 7.16.2 + // available since PHP 5.2.3. + if (!defined(CURLOPT_CONNECTTIMEOUT_MS)) { + define('CURLOPT_CONNECTTIMEOUT_MS', 156); // default value for CURLOPT_CONNECTTIMEOUT_MS + } curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, self::CONNECT_TIMEOUT_MS); - // There is a PHP bug in some versions which didn't define the constant. - curl_setopt( - $ch, - 156, // CURLOPT_CONNECTTIMEOUT_MS - self::CONNECT_TIMEOUT_MS - ); + $code = null; try { curl_exec($ch); From baaaec74d76e3ff0ff53f946e9a63364410cc0d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 31 Dec 2016 18:25:21 +0100 Subject: [PATCH 243/784] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f89047b65..fadf18bf8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +- `Symfony\Process` is used to start local WebDriver processes (when browsers are run directly, without Selenium server) to workaround some PHP bugs and improve poratbility +- Clarified meaning of selenium server URL variable in methods of `RemoteWebDriver` class ## 1.2.0 - 2016-10-14 - Added initial support of remote Microsoft Edge browser (but starting local EdgeDriver is still not supported) From 465f523eb5c5697d3863f623596366f898789426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 9 Dec 2016 11:56:19 +0100 Subject: [PATCH 244/784] Simplify build matrix --- .travis.yml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index facb0d4db..a2161a201 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,10 @@ matrix: # Add PHP 7 build to check codestyle only in PHP 7 build - php: 7 env: CHECK_CODESTYLE=1 + before_script: ~ + script: + - ./vendor/bin/php-cs-fixer fix --diff --dry-run + - ./vendor/bin/phpcs --standard=PSR2 ./lib/ ./tests/ env: global: @@ -28,15 +32,13 @@ install: - travis_retry composer install --no-interaction --prefer-source before_script: - - if [ -z "$CHECK_CODESTYLE" ]; then sh -e /etc/init.d/xvfb start; fi - - if [ -z "$CHECK_CODESTYLE" ]; then wget -q -t 3 http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar; fi - - if [ -z "$CHECK_CODESTYLE" ]; then java -jar selenium-server-standalone-2.45.0.jar -log selenium.log; fi & - - if [ -z "$CHECK_CODESTYLE" ]; then until $(echo | nc localhost 4444); do sleep 1; echo waiting for selenium-server...; done; fi + - sh -e /etc/init.d/xvfb start + - wget -q -t 3 http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar + - java -jar selenium-server-standalone-2.45.0.jar -log selenium.log & + - until $(echo | nc localhost 4444); do sleep 1; echo waiting for selenium-server...; done script: - - if [ -n "$CHECK_CODESTYLE" ]; then ./vendor/bin/php-cs-fixer fix --diff --dry-run; fi - - if [ -n "$CHECK_CODESTYLE" ]; then ./vendor/bin/phpcs --standard=PSR2 ./lib/ ./tests/; fi - - if [ -z "$CHECK_CODESTYLE" ]; then ./vendor/bin/phpunit; fi + - ./vendor/bin/phpunit after_script: - cat selenium.log From c123f84528b66d7e566e0147c5f41f52759339a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 18 Dec 2016 02:18:42 +0100 Subject: [PATCH 245/784] Do not prefer source when installing from composer to take advantage from the Travis cache --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a2161a201..68a261845 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,7 @@ before_install: - travis_retry composer self-update install: - - travis_retry composer install --no-interaction --prefer-source + - travis_retry composer install --no-interaction before_script: - sh -e /etc/init.d/xvfb start From 882d263a68179806e8fcd51806f2398f63d694e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 1 Jan 2017 20:43:52 +0100 Subject: [PATCH 246/784] Make browser to run the functional tests against configurable --- tests/functional/WebDriverTestCase.php | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index 6ebe98b61..080a30bca 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -15,9 +15,9 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Remote\DesiredCapabilities; use Facebook\WebDriver\Remote\RemoteWebDriver; use Facebook\WebDriver\Remote\WebDriverBrowserType; -use Facebook\WebDriver\Remote\WebDriverCapabilityType; /** * The base class for test cases. @@ -26,17 +26,23 @@ class WebDriverTestCase extends \PHPUnit_Framework_TestCase { /** @var RemoteWebDriver $driver */ protected $driver; + /** @var DesiredCapabilities */ + protected $desiredCapabilities; protected function setUp() { - $this->driver = RemoteWebDriver::create( - 'http://localhost:4444/wd/hub', - [ - WebDriverCapabilityType::BROWSER_NAME - //=> WebDriverBrowserType::FIREFOX, - => WebDriverBrowserType::HTMLUNIT, - ] - ); + $this->desiredCapabilities = new DesiredCapabilities(); + $serverUrl = 'http://localhost:4444/wd/hub'; + + if (getenv('BROWSER_NAME')) { + $browserName = getenv('BROWSER_NAME'); + } else { + $browserName = WebDriverBrowserType::HTMLUNIT; + } + + $this->desiredCapabilities->setBrowserName($browserName); + + $this->driver = RemoteWebDriver::create($serverUrl, $this->desiredCapabilities); } protected function tearDown() From d0f29eeee746ffe2b4f2c2da4686dccf77943ec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 1 Jan 2017 21:07:25 +0100 Subject: [PATCH 247/784] Use Selenium server 2.53.1 (with disabled marionette) for integration tests Selenium 3 will follow hopefully after 3.0.2 will be released. --- .travis.yml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 68a261845..609ba75cf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,7 @@ env: cache: directories: - $HOME/.composer/cache + - jar before_install: - travis_retry composer self-update @@ -33,8 +34,13 @@ install: before_script: - sh -e /etc/init.d/xvfb start - - wget -q -t 3 http://selenium-release.storage.googleapis.com/2.45/selenium-server-standalone-2.45.0.jar - - java -jar selenium-server-standalone-2.45.0.jar -log selenium.log & + # TODO: upgrade to Selenium 3.0.2 (with latest HtmlUnit) once released, as HtmlUnit in 3.0.1 is broken + - if [ ! -f jar/selenium-server-standalone-2.53.1.jar ]; then wget -q -t 3 -P jar https://selenium-release.storage.googleapis.com/2.53/selenium-server-standalone-2.53.1.jar; fi + - if [ ! -f jar/htmlunit-driver-standalone-2.20.jar ]; then wget -q -t 3 -P jar https://github.com/SeleniumHQ/htmlunit-driver/releases/download/2.20/htmlunit-driver-standalone-2.20.jar; fi + # Temporarily run HtmlUnit from standalone jar file (it was not part of Selenium server standalone in version 2.53) + - java -cp "jar/selenium-server-standalone-2.53.1.jar:jar/htmlunit-driver-standalone-2.20.jar" org.openqa.grid.selenium.GridLauncher -log selenium.log & + # TODO: use this after upgrade to Selenium 3.0.2 + #- /usr/lib/jvm/java-8-oracle/bin/java -Dwebdriver.firefox.marionette=false -jar jar/selenium-server-standalone-3.0.2.jar -log selenium.log & - until $(echo | nc localhost 4444); do sleep 1; echo waiting for selenium-server...; done script: @@ -42,3 +48,9 @@ script: after_script: - cat selenium.log + +addons: + apt: + packages: + - oracle-java8-installer + From e55a533a07397e2fbf65319bc8677eba213fc8ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 1 Jan 2017 20:44:36 +0100 Subject: [PATCH 248/784] Run tests on Travis also against Firefox --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 609ba75cf..21f11b4e5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,9 @@ php: matrix: include: + # Add build to run tests against Firefox (other runs are agains HtmlUnit by default) + - php: 7 + env: BROWSER_NAME="firefox" # Add PHP 7 build to check codestyle only in PHP 7 build - php: 7 env: CHECK_CODESTYLE=1 @@ -50,7 +53,7 @@ after_script: - cat selenium.log addons: + firefox: "latest-esr" apt: packages: - oracle-java8-installer - From 75ee70317c914ec55b69df1966baf31a9396507c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 1 Jan 2017 20:48:41 +0100 Subject: [PATCH 249/784] Ignore local phpunit.xml --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 2444076bd..e2cc31fbb 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ composer.phar composer.lock vendor .php_cs.cache +phpunit.xml # generic files to ignore *.lock From 49d39df13c960d1b1289c20a6bfc1ef978c4360e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 1 Jan 2017 20:44:49 +0100 Subject: [PATCH 250/784] Minor phpdoc fixes --- lib/Remote/RemoteWebDriver.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index 964740ead..d06dc2e36 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -479,7 +479,7 @@ public function setCommandExecutor(WebDriverCommandExecutor $executor) } /** - * Set the command executor of this RemoteWebdriver + * Get the command executor of this RemoteWebdriver * * @return HttpCommandExecutor */ @@ -512,7 +512,7 @@ public function getSessionID() } /** - * Get all selenium sessions. + * Returns a list of the currently active sessions. * * @param string $selenium_server_url The url of the remote Selenium WebDriver server * @param int $timeout_in_ms From bdf7e2ecc718503b49836851933d656fc7955f2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 1 Jan 2017 20:22:05 +0100 Subject: [PATCH 251/784] Functional tests for RemoteWebDriver --- tests/functional/FileUploadTest.php | 4 +- .../{BaseTest.php => FindElementTest.php} | 29 +-- tests/functional/RemoteWebDriverTest.php | 202 ++++++++++++++++++ tests/functional/html/index.html | 20 +- tests/functional/html/open_new_window.html | 8 + tests/functional/html/upload.html | 8 +- 6 files changed, 239 insertions(+), 32 deletions(-) rename tests/functional/{BaseTest.php => FindElementTest.php} (84%) create mode 100644 tests/functional/RemoteWebDriverTest.php create mode 100644 tests/functional/html/open_new_window.html diff --git a/tests/functional/FileUploadTest.php b/tests/functional/FileUploadTest.php index 29b878d9f..57ebff23c 100644 --- a/tests/functional/FileUploadTest.php +++ b/tests/functional/FileUploadTest.php @@ -31,7 +31,7 @@ public function testFileUploading() $file_input = $this->driver->findElement(WebDriverBy::id('upload')); $file_input->setFileDetector(new LocalFileDetector()) ->sendKeys(__DIR__ . '/files/FileUploadTestCaseFile.txt'); - self::assertNotEquals($this->getFilePath(), $file_input->getAttribute('value')); + $this->assertNotEquals($this->getFilePath(), $file_input->getAttribute('value')); } public function testUselessFileDetectorSendKeys() @@ -39,7 +39,7 @@ public function testUselessFileDetectorSendKeys() $this->driver->get($this->getTestPath('upload.html')); $file_input = $this->driver->findElement(WebDriverBy::id('upload')); $file_input->sendKeys($this->getFilePath()); - self::assertEquals($this->getFilePath(), $file_input->getAttribute('value')); + $this->assertEquals($this->getFilePath(), $file_input->getAttribute('value')); } private function getFilePath() diff --git a/tests/functional/BaseTest.php b/tests/functional/FindElementTest.php similarity index 84% rename from tests/functional/BaseTest.php rename to tests/functional/FindElementTest.php index c9c522651..f479fc9bc 100644 --- a/tests/functional/BaseTest.php +++ b/tests/functional/FindElementTest.php @@ -15,21 +15,12 @@ namespace Facebook\WebDriver; -class BaseTest extends WebDriverTestCase +class FindElementTest extends WebDriverTestCase { - public function testGetTitle() - { - $this->driver->get($this->getTestPath('index.html')); - self::assertEquals( - 'php-webdriver test page', - $this->driver->getTitle() - ); - } - public function testGetText() { $this->driver->get($this->getTestPath('index.html')); - self::assertEquals( + $this->assertEquals( 'Welcome to the facebook/php-webdriver testing page.', $this->driver->findElement(WebDriverBy::id('welcome'))->getText() ); @@ -38,7 +29,7 @@ public function testGetText() public function testGetById() { $this->driver->get($this->getTestPath('index.html')); - self::assertEquals( + $this->assertEquals( 'Test by ID', $this->driver->findElement(WebDriverBy::id('id_test'))->getText() ); @@ -47,7 +38,7 @@ public function testGetById() public function testGetByClassName() { $this->driver->get($this->getTestPath('index.html')); - self::assertEquals( + $this->assertEquals( 'Test by Class', $this->driver->findElement(WebDriverBy::className('test_class'))->getText() ); @@ -56,7 +47,7 @@ public function testGetByClassName() public function testGetByCssSelector() { $this->driver->get($this->getTestPath('index.html')); - self::assertEquals( + $this->assertEquals( 'Test by Class', $this->driver->findElement(WebDriverBy::cssSelector('.test_class'))->getText() ); @@ -65,7 +56,7 @@ public function testGetByCssSelector() public function testGetByLinkText() { $this->driver->get($this->getTestPath('index.html')); - self::assertEquals( + $this->assertEquals( 'Click here', $this->driver->findElement(WebDriverBy::linkText('Click here'))->getText() ); @@ -74,7 +65,7 @@ public function testGetByLinkText() public function testGetByName() { $this->driver->get($this->getTestPath('index.html')); - self::assertEquals( + $this->assertEquals( 'Test Value', $this->driver->findElement(WebDriverBy::name('test_name'))->getAttribute('value') ); @@ -83,7 +74,7 @@ public function testGetByName() public function testGetByXpath() { $this->driver->get($this->getTestPath('index.html')); - self::assertEquals( + $this->assertEquals( 'Test Value', $this->driver->findElement(WebDriverBy::xpath('//input[@name="test_name"]'))->getAttribute('value') ); @@ -92,7 +83,7 @@ public function testGetByXpath() public function testGetByPartialLinkText() { $this->driver->get($this->getTestPath('index.html')); - self::assertEquals( + $this->assertEquals( 'Click here', $this->driver->findElement(WebDriverBy::partialLinkText('Click'))->getText() ); @@ -101,7 +92,7 @@ public function testGetByPartialLinkText() public function testGetByTagName() { $this->driver->get($this->getTestPath('index.html')); - self::assertEquals( + $this->assertEquals( 'Test Value', $this->driver->findElement(WebDriverBy::tagName('input'))->getAttribute('value') ); diff --git a/tests/functional/RemoteWebDriverTest.php b/tests/functional/RemoteWebDriverTest.php new file mode 100644 index 000000000..0f9691c96 --- /dev/null +++ b/tests/functional/RemoteWebDriverTest.php @@ -0,0 +1,202 @@ +driver->get($this->getTestPath('index.html')); + + $this->assertEquals( + 'php-webdriver test page', + $this->driver->getTitle() + ); + } + + public function testShouldGetCurrentUrl() + { + $this->driver->get($this->getTestPath('index.html')); + + $this->assertContains( + '/index.html', + $this->driver->getCurrentURL() + ); + } + + public function testShouldGetPageSource() + { + $this->driver->get($this->getTestPath('index.html')); + + $source = $this->driver->getPageSource(); + $this->assertContains('

', $source); + $this->assertContains('Welcome to the facebook/php-webdriver testing page.', $source); + } + + public function testShouldGetSessionId() + { + $sessionId = $this->driver->getSessionID(); + + $this->assertInternalType('string', $sessionId); + $this->assertNotEmpty($sessionId); + } + + public function testShouldGetAllSessions() + { + $sessions = RemoteWebDriver::getAllSessions(); + + $this->assertInternalType('array', $sessions); + $this->assertCount(1, $sessions); + + $this->assertArrayHasKey('capabilities', $sessions[0]); + $this->assertArrayHasKey('id', $sessions[0]); + $this->assertArrayHasKey('class', $sessions[0]); + } + + public function testShouldQuitAndUnsetExecutor() + { + $this->assertCount(1, RemoteWebDriver::getAllSessions()); + $this->assertInstanceOf(HttpCommandExecutor::class, $this->driver->getCommandExecutor()); + + $this->driver->quit(); + + $this->assertCount(0, RemoteWebDriver::getAllSessions()); + $this->assertNull($this->driver->getCommandExecutor()); + } + + public function testShouldGetWindowHandles() + { + $this->driver->get($this->getTestPath('open_new_window.html')); + + $windowHandle = $this->driver->getWindowHandle(); + $windowHandles = $this->driver->getWindowHandles(); + + $this->assertInternalType('string', $windowHandle); + $this->assertNotEmpty($windowHandle); + $this->assertSame([$windowHandle], $windowHandles); + + // Open second window + $this->driver->findElement(WebDriverBy::cssSelector('a'))->click(); + + $this->assertCount(2, $this->driver->getWindowHandles()); + } + + public function testShouldCloseWindow() + { + $this->driver->get($this->getTestPath('open_new_window.html')); + $this->driver->findElement(WebDriverBy::cssSelector('a'))->click(); + + $this->assertCount(2, $this->driver->getWindowHandles()); + + $this->driver->close(); + + $this->assertCount(1, $this->driver->getWindowHandles()); + } + + public function testShouldExecuteScriptAndDoNotBlockExecution() + { + $this->driver->get($this->getTestPath('index.html')); + + $element = $this->driver->findElement(WebDriverBy::id('id_test')); + $this->assertSame('Test by ID', $element->getText()); + + $this->driver->executeScript(' + setTimeout( + function(){document.getElementById("id_test").innerHTML = "Text changed by script"}, + 250 + )'); + + // Make sure the script don't block the test execution + $this->assertSame('Test by ID', $element->getText()); + + // If we wait, the script should be executed + usleep(300000); // wait 300 ms + $this->assertSame('Text changed by script', $element->getText()); + } + + public function testShouldExecuteAsyncScriptAndWaitUntilItIsFinished() + { + $this->driver->manage()->timeouts()->setScriptTimeout(1); + + $this->driver->get($this->getTestPath('index.html')); + + $element = $this->driver->findElement(WebDriverBy::id('id_test')); + $this->assertSame('Test by ID', $element->getText()); + + $this->driver->executeAsyncScript( + 'var callback = arguments[arguments.length - 1]; + setTimeout( + function(){ + document.getElementById("id_test").innerHTML = "Text changed by script"; + callback(); + }, + 250 + );' + ); + + // The result must be immediately available, as the executeAsyncScript should block the execution until the + // callback is called. + $this->assertSame('Text changed by script', $element->getText()); + } + + public function testShouldTakeScreenshot() + { + if (!extension_loaded('gd')) { + $this->markTestSkipped('GD extension must be enabled'); + } + if ($this->desiredCapabilities->getBrowserName() == WebDriverBrowserType::HTMLUNIT) { + $this->markTestSkipped('Screenshots are not supported by HtmlUnit browser'); + } + + $this->driver->get($this->getTestPath('index.html')); + + $outputPng = $this->driver->takeScreenshot(); + + $image = imagecreatefromstring($outputPng); + $this->assertInternalType('resource', $image); + + $this->assertGreaterThan(0, imagesx($image)); + $this->assertGreaterThan(0, imagesy($image)); + } + + public function testShouldSaveScreenshotToFile() + { + if (!extension_loaded('gd')) { + $this->markTestSkipped('GD extension must be enabled'); + } + if ($this->desiredCapabilities->getBrowserName() == WebDriverBrowserType::HTMLUNIT) { + $this->markTestSkipped('Screenshots are not supported by HtmlUnit browser'); + } + + $screenshotPath = sys_get_temp_dir() . '/selenium-screenshot.png'; + + $this->driver->get($this->getTestPath('index.html')); + + $this->driver->takeScreenshot($screenshotPath); + + $image = imagecreatefrompng($screenshotPath); + $this->assertInternalType('resource', $image); + + $this->assertGreaterThan(0, imagesx($image)); + $this->assertGreaterThan(0, imagesy($image)); + + unlink($screenshotPath); + } +} diff --git a/tests/functional/html/index.html b/tests/functional/html/index.html index 6bafefdc9..419b41ee2 100644 --- a/tests/functional/html/index.html +++ b/tests/functional/html/index.html @@ -1,12 +1,18 @@ - php-webdriver test page + php-webdriver test page -

Welcome to the facebook/php-webdriver testing page.

-

Test by ID

-

Test by Class

- Click here - +

Welcome to the facebook/php-webdriver testing page.

+

Test by ID

+

Test by Class

+ Click here + + +
    +
  • First
  • +
  • Second
  • +
  • Third
  • +
- \ No newline at end of file + diff --git a/tests/functional/html/open_new_window.html b/tests/functional/html/open_new_window.html new file mode 100644 index 000000000..f2ff1cf00 --- /dev/null +++ b/tests/functional/html/open_new_window.html @@ -0,0 +1,8 @@ + + + php-webdriver test page + + + open new window + + diff --git a/tests/functional/html/upload.html b/tests/functional/html/upload.html index ed03702d3..2eef0c026 100644 --- a/tests/functional/html/upload.html +++ b/tests/functional/html/upload.html @@ -1,10 +1,10 @@ - Upload a file + Upload a file -
- -
+
+ +
From f55c684703826a30d19e9bd3dd6567c833cc8c5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 1 Jan 2017 21:40:41 +0100 Subject: [PATCH 252/784] Separate functional test that finds elemements --- tests/functional/FindElementTest.php | 100 ------------------ .../RemoteWebDriverFindElementTest.php | 63 +++++++++++ tests/functional/RemoteWebElementTest.php | 30 ++++++ tests/functional/WebDriverByTest.php | 64 +++++++++++ 4 files changed, 157 insertions(+), 100 deletions(-) delete mode 100644 tests/functional/FindElementTest.php create mode 100644 tests/functional/RemoteWebDriverFindElementTest.php create mode 100644 tests/functional/RemoteWebElementTest.php create mode 100644 tests/functional/WebDriverByTest.php diff --git a/tests/functional/FindElementTest.php b/tests/functional/FindElementTest.php deleted file mode 100644 index f479fc9bc..000000000 --- a/tests/functional/FindElementTest.php +++ /dev/null @@ -1,100 +0,0 @@ -driver->get($this->getTestPath('index.html')); - $this->assertEquals( - 'Welcome to the facebook/php-webdriver testing page.', - $this->driver->findElement(WebDriverBy::id('welcome'))->getText() - ); - } - - public function testGetById() - { - $this->driver->get($this->getTestPath('index.html')); - $this->assertEquals( - 'Test by ID', - $this->driver->findElement(WebDriverBy::id('id_test'))->getText() - ); - } - - public function testGetByClassName() - { - $this->driver->get($this->getTestPath('index.html')); - $this->assertEquals( - 'Test by Class', - $this->driver->findElement(WebDriverBy::className('test_class'))->getText() - ); - } - - public function testGetByCssSelector() - { - $this->driver->get($this->getTestPath('index.html')); - $this->assertEquals( - 'Test by Class', - $this->driver->findElement(WebDriverBy::cssSelector('.test_class'))->getText() - ); - } - - public function testGetByLinkText() - { - $this->driver->get($this->getTestPath('index.html')); - $this->assertEquals( - 'Click here', - $this->driver->findElement(WebDriverBy::linkText('Click here'))->getText() - ); - } - - public function testGetByName() - { - $this->driver->get($this->getTestPath('index.html')); - $this->assertEquals( - 'Test Value', - $this->driver->findElement(WebDriverBy::name('test_name'))->getAttribute('value') - ); - } - - public function testGetByXpath() - { - $this->driver->get($this->getTestPath('index.html')); - $this->assertEquals( - 'Test Value', - $this->driver->findElement(WebDriverBy::xpath('//input[@name="test_name"]'))->getAttribute('value') - ); - } - - public function testGetByPartialLinkText() - { - $this->driver->get($this->getTestPath('index.html')); - $this->assertEquals( - 'Click here', - $this->driver->findElement(WebDriverBy::partialLinkText('Click'))->getText() - ); - } - - public function testGetByTagName() - { - $this->driver->get($this->getTestPath('index.html')); - $this->assertEquals( - 'Test Value', - $this->driver->findElement(WebDriverBy::tagName('input'))->getAttribute('value') - ); - } -} diff --git a/tests/functional/RemoteWebDriverFindElementTest.php b/tests/functional/RemoteWebDriverFindElementTest.php new file mode 100644 index 000000000..64f7b8d9c --- /dev/null +++ b/tests/functional/RemoteWebDriverFindElementTest.php @@ -0,0 +1,63 @@ +driver->get($this->getTestPath('index.html')); + + $this->setExpectedException(NoSuchElementException::class, 'Unable to locate element'); + $this->driver->findElement(WebDriverBy::id('not_existing')); + } + + public function testShouldFindElementIfExistsOnAPage() + { + $this->driver->get($this->getTestPath('index.html')); + + $element = $this->driver->findElement(WebDriverBy::id('id_test')); + + $this->assertInstanceOf(RemoteWebElement::class, $element); + } + + public function testShouldReturnEmptyArrayIfElementsCannotBeFound() + { + $this->driver->get($this->getTestPath('index.html')); + + $elements = $this->driver->findElements(WebDriverBy::cssSelector('not_existing')); + + $this->assertInternalType('array', $elements); + $this->assertCount(0, $elements); + } + + public function testShouldFindMultipleElements() + { + $this->driver->get($this->getTestPath('index.html')); + + $elements = $this->driver->findElements(WebDriverBy::cssSelector('ul > li')); + + $this->assertInternalType('array', $elements); + $this->assertCount(3, $elements); + $this->assertContainsOnlyInstancesOf(RemoteWebElement::class, $elements); + } +} diff --git a/tests/functional/RemoteWebElementTest.php b/tests/functional/RemoteWebElementTest.php new file mode 100644 index 000000000..1869671d4 --- /dev/null +++ b/tests/functional/RemoteWebElementTest.php @@ -0,0 +1,30 @@ +driver->get($this->getTestPath('index.html')); + $element = $this->driver->findElement(WebDriverBy::id('welcome')); + + $this->assertEquals( + 'Welcome to the facebook/php-webdriver testing page.', + $element->getText() + ); + } +} diff --git a/tests/functional/WebDriverByTest.php b/tests/functional/WebDriverByTest.php new file mode 100644 index 000000000..4309836f6 --- /dev/null +++ b/tests/functional/WebDriverByTest.php @@ -0,0 +1,64 @@ +driver->get($this->getTestPath('index.html')); + + $element = $this->driver->findElement($locator); + + $this->assertInstanceOf(RemoteWebElement::class, $element); + + if ($expectedText !== null) { + $this->assertEquals($expectedText, $element->getText()); + } + + if ($expectedAttributeValue !== null) { + $this->assertEquals($expectedAttributeValue, $element->getAttribute('value')); + } + } + + public function textElementsProvider() + { + return [ + 'id' => [WebDriverBy::id('id_test'), 'Test by ID'], + 'className' => [WebDriverBy::className('test_class'), 'Test by Class'], + 'cssSelector' => [WebDriverBy::cssSelector('.test_class'), 'Test by Class'], + 'linkText' => [WebDriverBy::linkText('Click here'), 'Click here'], + 'partialLinkText' => [WebDriverBy::partialLinkText('Click'), 'Click here'], + 'xpath' => [WebDriverBy::xpath('//input[@name="test_name"]'), '', 'Test Value'], + 'name' => [WebDriverBy::name('test_name'), '', 'Test Value'], + 'tagName' => [WebDriverBy::tagName('input'), '', 'Test Value'], + ]; + } +} From 3da2cc1527a143b8e93c2138794d0cebe6bdc115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Mon, 2 Jan 2017 02:13:45 +0100 Subject: [PATCH 253/784] Rewrite file upload functional tests to execute real upload against webserver --- .travis.yml | 2 + tests/functional/FileUploadTest.php | 48 ++++++++++++------- .../FileUploadTestFile.txt} | 0 tests/functional/WebDriverTestCase.php | 24 ++++++++-- tests/functional/html/upload.html | 10 ---- tests/functional/{html => web}/index.html | 4 +- .../{html => web}/open_new_window.html | 4 +- tests/functional/web/upload.html | 18 +++++++ tests/functional/web/upload.php | 29 +++++++++++ 9 files changed, 106 insertions(+), 33 deletions(-) rename tests/functional/{files/FileUploadTestCaseFile.txt => Fixtures/FileUploadTestFile.txt} (100%) delete mode 100644 tests/functional/html/upload.html rename tests/functional/{html => web}/index.html (87%) rename tests/functional/{html => web}/open_new_window.html (68%) create mode 100644 tests/functional/web/upload.html create mode 100644 tests/functional/web/upload.php diff --git a/.travis.yml b/.travis.yml index 21f11b4e5..b250e2d63 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,12 +45,14 @@ before_script: # TODO: use this after upgrade to Selenium 3.0.2 #- /usr/lib/jvm/java-8-oracle/bin/java -Dwebdriver.firefox.marionette=false -jar jar/selenium-server-standalone-3.0.2.jar -log selenium.log & - until $(echo | nc localhost 4444); do sleep 1; echo waiting for selenium-server...; done + - php -S localhost:8000 -t tests/functional/web/ &>>php-server.log & script: - ./vendor/bin/phpunit after_script: - cat selenium.log + - cat php-server.log addons: firefox: "latest-esr" diff --git a/tests/functional/FileUploadTest.php b/tests/functional/FileUploadTest.php index 57ebff23c..e3b6be1d3 100644 --- a/tests/functional/FileUploadTest.php +++ b/tests/functional/FileUploadTest.php @@ -17,33 +17,47 @@ use Facebook\WebDriver\Remote\LocalFileDetector; -/** - * An example test case for php-webdriver. - * - * Try running it by - * '../vendor/phpunit/phpunit/phpunit.php ExampleTestCase.php' - */ class FileUploadTest extends WebDriverTestCase { - public function testFileUploading() + public function testShouldUploadAFile() { - $this->driver->get($this->getTestPath('upload.html')); - $file_input = $this->driver->findElement(WebDriverBy::id('upload')); - $file_input->setFileDetector(new LocalFileDetector()) - ->sendKeys(__DIR__ . '/files/FileUploadTestCaseFile.txt'); - $this->assertNotEquals($this->getFilePath(), $file_input->getAttribute('value')); + $this->driver->get($this->getTestPageUrl('upload.html')); + + $fileElement = $this->driver->findElement(WebDriverBy::name('upload')); + + $fileElement->setFileDetector(new LocalFileDetector()) + ->sendKeys($this->getTestFilePath()); + + $fileElement->submit(); + + $this->driver->wait()->until( + WebDriverExpectedCondition::titleIs('File upload endpoint') + ); + + $uploadedFilesList = $this->driver->findElements(WebDriverBy::cssSelector('ul.uploaded-files li')); + $this->assertCount(1, $uploadedFilesList); + + $uploadedFileName = $this->driver->findElement(WebDriverBy::cssSelector('ul.uploaded-files li span.file-name')) + ->getText(); + $uploadedFileSize = $this->driver->findElement(WebDriverBy::cssSelector('ul.uploaded-files li span.file-size')) + ->getText(); + + $this->assertSame('FileUploadTestFile.txt', $uploadedFileName); + $this->assertSame('10', $uploadedFileSize); } - public function testUselessFileDetectorSendKeys() + public function xtestUselessFileDetectorSendKeys() { $this->driver->get($this->getTestPath('upload.html')); + $file_input = $this->driver->findElement(WebDriverBy::id('upload')); - $file_input->sendKeys($this->getFilePath()); - $this->assertEquals($this->getFilePath(), $file_input->getAttribute('value')); + $file_input->sendKeys($this->getTestFilePath()); + + $this->assertEquals($this->getTestFilePath(), $file_input->getAttribute('value')); } - private function getFilePath() + private function getTestFilePath() { - return __DIR__ . '/files/FileUploadTestCaseFile.txt'; + return __DIR__ . '/Fixtures/FileUploadTestFile.txt'; } } diff --git a/tests/functional/files/FileUploadTestCaseFile.txt b/tests/functional/Fixtures/FileUploadTestFile.txt similarity index 100% rename from tests/functional/files/FileUploadTestCaseFile.txt rename to tests/functional/Fixtures/FileUploadTestFile.txt diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index 080a30bca..f44c70343 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -15,6 +15,7 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Exception\NoSuchWindowException; use Facebook\WebDriver\Remote\DesiredCapabilities; use Facebook\WebDriver\Remote\RemoteWebDriver; use Facebook\WebDriver\Remote\WebDriverBrowserType; @@ -47,19 +48,34 @@ protected function setUp() protected function tearDown() { - if ($this->driver) { - $this->driver->quit(); + if ($this->driver->getCommandExecutor()) { + try { + $this->driver->quit(); + } catch (NoSuchWindowException $e) { + // browser may have died or is already closed + } } } /** - * Get the URL of the test html. + * Get the URL of the test html on filesystem. * * @param $path * @return string */ protected function getTestPath($path) { - return 'file:///' . __DIR__ . '/html/' . $path; + return 'file:///' . __DIR__ . '/web/' . $path; + } + + /** + * Get the URL of given test HTML on running webserver. + * + * @param string $path + * @return string + */ + protected function getTestPageUrl($path) + { + return 'http://localhost:8000/' . $path; } } diff --git a/tests/functional/html/upload.html b/tests/functional/html/upload.html deleted file mode 100644 index 2eef0c026..000000000 --- a/tests/functional/html/upload.html +++ /dev/null @@ -1,10 +0,0 @@ - - - Upload a file - - -
- -
- - diff --git a/tests/functional/html/index.html b/tests/functional/web/index.html similarity index 87% rename from tests/functional/html/index.html rename to tests/functional/web/index.html index 419b41ee2..139a25865 100644 --- a/tests/functional/html/index.html +++ b/tests/functional/web/index.html @@ -1,5 +1,7 @@ - + + + php-webdriver test page diff --git a/tests/functional/html/open_new_window.html b/tests/functional/web/open_new_window.html similarity index 68% rename from tests/functional/html/open_new_window.html rename to tests/functional/web/open_new_window.html index f2ff1cf00..b56e93d69 100644 --- a/tests/functional/html/open_new_window.html +++ b/tests/functional/web/open_new_window.html @@ -1,5 +1,7 @@ - + + + php-webdriver test page diff --git a/tests/functional/web/upload.html b/tests/functional/web/upload.html new file mode 100644 index 000000000..d02c5ed4b --- /dev/null +++ b/tests/functional/web/upload.html @@ -0,0 +1,18 @@ + + + + + Upload a file + + +
+

+ + +

+

+ +

+
+ + diff --git a/tests/functional/web/upload.php b/tests/functional/web/upload.php new file mode 100644 index 000000000..91a61bbcf --- /dev/null +++ b/tests/functional/web/upload.php @@ -0,0 +1,29 @@ + + + + + File upload endpoint + + + +File upload not detected'; +} elseif (isset($_FILES['upload']) && $_FILES['upload']['error'] == 4) { + echo '

Form was submitted but no file was selected for upload

'; +} else { + echo sprintf('

Received %d uploaded file(s)

', count($_FILES)); + echo '
    '; + foreach ($_FILES as $file) { + echo sprintf( + '
  • File name: %s, size: %d
  • ', + $file['name'], + $file['size'] + ); + } + echo '
'; +} +?> + + + From 6d385d71b1e705451fd07e3880c19f3b3d4e85f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Mon, 2 Jan 2017 03:44:31 +0100 Subject: [PATCH 254/784] Do not run tests on HHVM, as it doesn't support builtin webserver --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b250e2d63..b9b2fe6d3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,6 @@ php: - 5.6 - 7 - 7.1 - - hhvm matrix: include: From f718bfaf94af67d082d8374bd3a214d2606ce25d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Mon, 2 Jan 2017 19:37:55 +0100 Subject: [PATCH 255/784] Add some clarifications about the library status in README --- README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8c3e2370a..bc3e9fbb0 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,15 @@ ## Description Php-webdriver library is PHP language binding for Selenium WebDriver, which allows you to control web browsers from PHP. -This WebDriver client aims to be as close as possible to bindings in other languages. -The concepts are very similar to the Java, .NET, Python and Ruby bindings for WebDriver. +This library is compatible with Selenium server version 2.x and 3.x. +It implements the [JsonWireProtocol](https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol), which is currently supported +by the Selenium server and will also implement the [W3C WebDriver](https://w3c.github.io/webdriver/webdriver-spec.html) specification in the future. -This is new version of PHP client, rewritten from scratch starting 2013. -Using the old version? Check out Adam Goucher's fork of it at https://github.com/Element-34/php-webdriver +The concepts of this library are very similar to the "official" Java, .NET, Python and Ruby bindings from the +[Selenium project](https://github.com/SeleniumHQ/selenium/). + +**This is new version of PHP client, rewritten from scratch starting 2013.** +Using the old version? Check out [Adam Goucher's fork](https://github.com/Element-34/php-webdriver) of it. Looking for API documentation of php-webdriver? See http://facebook.github.io/php-webdriver/ From 8755ace212f55a783a5d50fb93e5d7d330121075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 8 Jan 2017 00:22:00 +0100 Subject: [PATCH 256/784] Send code coverage reports to coveralls.io --- .coveralls.yml | 2 ++ .gitignore | 1 + .travis.yml | 13 ++++++++----- composer.json | 3 ++- logs/.gitkeep | 0 5 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 .coveralls.yml create mode 100644 logs/.gitkeep diff --git a/.coveralls.yml b/.coveralls.yml new file mode 100644 index 000000000..8115fc995 --- /dev/null +++ b/.coveralls.yml @@ -0,0 +1,2 @@ +coverage_clover: ./logs/coverage-clover.xml +json_path: ./logs/coveralls-upload.json diff --git a/.gitignore b/.gitignore index e2cc31fbb..42ef8b562 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ composer.lock vendor .php_cs.cache phpunit.xml +logs/ # generic files to ignore *.lock diff --git a/.travis.yml b/.travis.yml index b9b2fe6d3..d8674413c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,18 +40,21 @@ before_script: - if [ ! -f jar/selenium-server-standalone-2.53.1.jar ]; then wget -q -t 3 -P jar https://selenium-release.storage.googleapis.com/2.53/selenium-server-standalone-2.53.1.jar; fi - if [ ! -f jar/htmlunit-driver-standalone-2.20.jar ]; then wget -q -t 3 -P jar https://github.com/SeleniumHQ/htmlunit-driver/releases/download/2.20/htmlunit-driver-standalone-2.20.jar; fi # Temporarily run HtmlUnit from standalone jar file (it was not part of Selenium server standalone in version 2.53) - - java -cp "jar/selenium-server-standalone-2.53.1.jar:jar/htmlunit-driver-standalone-2.20.jar" org.openqa.grid.selenium.GridLauncher -log selenium.log & + - java -cp "jar/selenium-server-standalone-2.53.1.jar:jar/htmlunit-driver-standalone-2.20.jar" org.openqa.grid.selenium.GridLauncher -log ./logs/selenium.log & # TODO: use this after upgrade to Selenium 3.0.2 #- /usr/lib/jvm/java-8-oracle/bin/java -Dwebdriver.firefox.marionette=false -jar jar/selenium-server-standalone-3.0.2.jar -log selenium.log & - until $(echo | nc localhost 4444); do sleep 1; echo waiting for selenium-server...; done - - php -S localhost:8000 -t tests/functional/web/ &>>php-server.log & + - php -S localhost:8000 -t tests/functional/web/ &>>./logs/php-server.log & script: - - ./vendor/bin/phpunit + - ./vendor/bin/phpunit --coverage-clover ./logs/coverage-clover.xml after_script: - - cat selenium.log - - cat php-server.log + - cat ./logs/selenium.log + - cat ./logs/php-server.log + +after_success: + - travis_retry php vendor/bin/coveralls -v addons: firefox: "latest-esr" diff --git a/composer.json b/composer.json index a8eb267e0..55780368b 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,8 @@ "phpunit/phpunit": "4.6.* || ~5.0", "friendsofphp/php-cs-fixer": "^1.11", "squizlabs/php_codesniffer": "^2.6", - "php-mock/php-mock-phpunit": "^1.1" + "php-mock/php-mock-phpunit": "^1.1", + "satooshi/php-coveralls": "^1.0" }, "suggest": { "phpdocumentor/phpdocumentor": "2.*" diff --git a/logs/.gitkeep b/logs/.gitkeep new file mode 100644 index 000000000..e69de29bb From 5e031e7bfde975e9a1b8b124c5a8ddf5676ed396 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 8 Jan 2017 00:15:35 +0100 Subject: [PATCH 257/784] Add lowest-dependencies Travis build --- .travis.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index d8674413c..3710d83da 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,16 +3,19 @@ language: php php: - 5.5 - 5.6 - - 7 + - 7.0 - 7.1 matrix: include: # Add build to run tests against Firefox (other runs are agains HtmlUnit by default) - - php: 7 + - php: 7.0 env: BROWSER_NAME="firefox" + # Build with lowest possible dependencies + - php: 7.0 + env: dependencies="--prefer-lowest" # Add PHP 7 build to check codestyle only in PHP 7 build - - php: 7 + - php: 7.0 env: CHECK_CODESTYLE=1 before_script: ~ script: @@ -32,7 +35,7 @@ before_install: - travis_retry composer self-update install: - - travis_retry composer install --no-interaction + - travis_retry composer update --no-interaction $dependencies before_script: - sh -e /etc/init.d/xvfb start From a583ff49e62241b41cc285893fe7344134628938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 18 Dec 2016 00:03:41 +0100 Subject: [PATCH 258/784] Support required capabilities --- lib/Remote/RemoteWebDriver.php | 41 +++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index d06dc2e36..abc27ccb5 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -63,8 +63,9 @@ protected function __construct() * @param DesiredCapabilities|array $desired_capabilities The desired capabilities * @param int|null $connection_timeout_in_ms * @param int|null $request_timeout_in_ms - * @param string|null $http_proxy The proxy to tunnel requests through + * @param string|null $http_proxy The proxy to tunnel requests to the remote Selenium WebDriver through * @param int|null $http_proxy_port + * @param DesiredCapabilities $required_capabilities The required capabilities * @return RemoteWebDriver */ public static function create( @@ -73,15 +74,12 @@ public static function create( $connection_timeout_in_ms = null, $request_timeout_in_ms = null, $http_proxy = null, - $http_proxy_port = null + $http_proxy_port = null, + DesiredCapabilities $required_capabilities = null ) { $selenium_server_url = preg_replace('#/+$#', '', $selenium_server_url); - // Passing DesiredCapabilities as $desired_capabilities is encouraged but - // array is also accepted for legacy reason. - if ($desired_capabilities instanceof DesiredCapabilities) { - $desired_capabilities = $desired_capabilities->toArray(); - } + $desired_capabilities = self::castToDesiredCapabilitiesObject($desired_capabilities); $executor = new HttpCommandExecutor($selenium_server_url, $http_proxy, $http_proxy_port); if ($connection_timeout_in_ms !== null) { @@ -91,10 +89,17 @@ public static function create( $executor->setRequestTimeout($request_timeout_in_ms); } + if ($required_capabilities !== null) { + // TODO: Selenium (as of v3.0.1) does accept requiredCapabilities only as a property of desiredCapabilities. + // This will probably change in future with the W3C WebDriver spec, but is the only way how to pass these + // values now. + $desired_capabilities->setCapability('requiredCapabilities', $required_capabilities->toArray()); + } + $command = new WebDriverCommand( null, DriverCommand::NEW_SESSION, - ['desiredCapabilities' => $desired_capabilities] + ['desiredCapabilities' => $desired_capabilities->toArray()] ); $response = $executor->execute($command); @@ -106,6 +111,26 @@ public static function create( return $driver; } + /** + * Cast legacy types (array or null) to DesiredCapabilities object. To be removed in future when instance of + * DesiredCapabilities will be required. + * + * @param array|DesiredCapabilities|null $desired_capabilities + * @return DesiredCapabilities + */ + protected static function castToDesiredCapabilitiesObject($desired_capabilities = null) + { + if ($desired_capabilities === null) { + return new DesiredCapabilities(); + } + + if (is_array($desired_capabilities)) { + return new DesiredCapabilities($desired_capabilities); + } + + return $desired_capabilities; + } + /** * [Experimental] Construct the RemoteWebDriver by an existing session. * From 86a0b18b8f2abec691a59930b69b7d4c96c325ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 8 Jan 2017 00:52:44 +0100 Subject: [PATCH 259/784] Add issue template --- ISSUE_TEMPLATE.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 ISSUE_TEMPLATE.md diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..3eef8cde7 --- /dev/null +++ b/ISSUE_TEMPLATE.md @@ -0,0 +1,21 @@ +### What are you trying to achieve? (Expected behavior) + + +### What do you get instead? (Actual behavior) + + +### How could the issue be reproduced? (Steps to reproduce) + + +```php +// You can insert your PHP code here (or remove this block if it is not relevant for the issue). +``` + +### Details + + +* Php-webdriver version: +* PHP version: +* Selenium server version: +* Operating system: +* Browser used + version: From 1ba81ee6aa2e175a76f8d8d0ca512e888cd5cd1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 8 Jan 2017 01:22:37 +0100 Subject: [PATCH 260/784] Add functional test for WebDriver creation --- .../functional/RemoteWebDriverCreateTest.php | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 tests/functional/RemoteWebDriverCreateTest.php diff --git a/tests/functional/RemoteWebDriverCreateTest.php b/tests/functional/RemoteWebDriverCreateTest.php new file mode 100644 index 000000000..4f05a4319 --- /dev/null +++ b/tests/functional/RemoteWebDriverCreateTest.php @@ -0,0 +1,63 @@ +driver = RemoteWebDriver::create($this->serverUrl, $this->desiredCapabilities, 10000, 13370); + + $this->assertInstanceOf(RemoteWebDriver::class, $this->driver); + + $this->assertInstanceOf(HttpCommandExecutor::class, $this->driver->getCommandExecutor()); + $this->assertSame($this->serverUrl, $this->driver->getCommandExecutor()->getAddressOfRemoteServer()); + + $this->assertInternalType('string', $this->driver->getSessionID()); + $this->assertNotEmpty($this->driver->getSessionID()); + + $returnedCapabilities = $this->driver->getCapabilities(); + $this->assertInstanceOf(WebDriverCapabilities::class, $returnedCapabilities); + $this->assertSame($this->desiredCapabilities->getBrowserName(), $returnedCapabilities->getBrowserName()); + } + + public function testShouldCreateWebDriverWithRequiredCapabilities() + { + $requiredCapabilities = new DesiredCapabilities(); + + $this->driver = RemoteWebDriver::create( + $this->serverUrl, + $this->desiredCapabilities, + null, + null, + null, + null, + $requiredCapabilities + ); + + $this->assertInstanceOf(RemoteWebDriver::class, $this->driver); + } +} From 6c155c801ccc6fe3b1efb4ab51147da3e790d834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 8 Jan 2017 00:10:37 +0100 Subject: [PATCH 261/784] Define @covers for functional tests, to cover just what is actually tested --- CHANGELOG.md | 4 +- lib/Chrome/ChromeDriver.php | 7 +-- lib/Remote/HttpCommandExecutor.php | 2 +- lib/Remote/RemoteWebDriver.php | 59 ++++++++++++++----- lib/Remote/Service/DriverCommandExecutor.php | 3 +- lib/WebDriverCommandExecutor.php | 3 +- tests/functional/FileUploadTest.php | 4 ++ .../RemoteWebDriverFindElementTest.php | 3 + tests/functional/RemoteWebDriverTest.php | 3 + tests/functional/RemoteWebElementTest.php | 3 + tests/functional/WebDriverByTest.php | 1 + tests/functional/WebDriverTestCase.php | 12 +++- 12 files changed, 77 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fadf18bf8..137452511 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,9 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased - `Symfony\Process` is used to start local WebDriver processes (when browsers are run directly, without Selenium server) to workaround some PHP bugs and improve poratbility -- Clarified meaning of selenium server URL variable in methods of `RemoteWebDriver` class +- Clarified meaning of selenium server URL variable in methods of `RemoteWebDriver` class +- Deprecated `setSessionID()` and `setCommandExecutor()` methods of `RemoteWebDriver` class; these values should be immutable and thus passed only via constructor. +- Added `getCapabilities()` method of `RemoteWebDriver`, to retrieve actual capabilities acknowledged by the remote driver on startup. ## 1.2.0 - 2016-10-14 - Added initial support of remote Microsoft Edge browser (but starting local EdgeDriver is still not supported) diff --git a/lib/Chrome/ChromeDriver.php b/lib/Chrome/ChromeDriver.php index 32ddf8f85..7aac128e4 100644 --- a/lib/Chrome/ChromeDriver.php +++ b/lib/Chrome/ChromeDriver.php @@ -33,9 +33,8 @@ public static function start(DesiredCapabilities $desired_capabilities = null, C $service = ChromeDriverService::createDefaultService(); } $executor = new DriverCommandExecutor($service); - $driver = new static(); - $driver->setCommandExecutor($executor) - ->startSession($desired_capabilities); + $driver = new static($executor, null, $desired_capabilities); + $driver->startSession($desired_capabilities); return $driver; } @@ -50,7 +49,7 @@ public function startSession(DesiredCapabilities $desired_capabilities) ] ); $response = $this->executor->execute($command); - $this->setSessionID($response->getSessionID()); + $this->sessionID = $response->getSessionID(); } /** diff --git a/lib/Remote/HttpCommandExecutor.php b/lib/Remote/HttpCommandExecutor.php index 11b53536a..85045855e 100644 --- a/lib/Remote/HttpCommandExecutor.php +++ b/lib/Remote/HttpCommandExecutor.php @@ -224,7 +224,7 @@ public function setRequestTimeout($timeout_in_ms) * @param WebDriverCommand $command * * @throws WebDriverException - * @return mixed + * @return WebDriverResponse */ public function execute(WebDriverCommand $command) { diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index abc27ccb5..dd1be325a 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -19,6 +19,7 @@ use Facebook\WebDriver\JavaScriptExecutor; use Facebook\WebDriver\WebDriver; use Facebook\WebDriver\WebDriverBy; +use Facebook\WebDriver\WebDriverCapabilities; use Facebook\WebDriver\WebDriverCommandExecutor; use Facebook\WebDriver\WebDriverElement; use Facebook\WebDriver\WebDriverNavigation; @@ -31,6 +32,11 @@ class RemoteWebDriver implements WebDriver, JavaScriptExecutor * @var HttpCommandExecutor */ protected $executor; + /** + * @var WebDriverCapabilities + */ + protected $capabilities; + /** * @var string */ @@ -52,8 +58,17 @@ class RemoteWebDriver implements WebDriver, JavaScriptExecutor */ protected $executeMethod; - protected function __construct() - { + protected function __construct( + HttpCommandExecutor $commandExecutor, + $sessionId, + WebDriverCapabilities $capabilities = null + ) { + $this->executor = $commandExecutor; + $this->sessionID = $sessionId; + + if ($capabilities !== null) { + $this->capabilities = $capabilities; + } } /** @@ -61,10 +76,10 @@ protected function __construct() * * @param string $selenium_server_url The url of the remote Selenium WebDriver server * @param DesiredCapabilities|array $desired_capabilities The desired capabilities - * @param int|null $connection_timeout_in_ms - * @param int|null $request_timeout_in_ms + * @param int|null $connection_timeout_in_ms Set timeout for the connect phase to remote Selenium WebDriver server + * @param int|null $request_timeout_in_ms Set the maximum time of a request to remote Selenium WebDriver server * @param string|null $http_proxy The proxy to tunnel requests to the remote Selenium WebDriver through - * @param int|null $http_proxy_port + * @param int|null $http_proxy_port The proxy port to tunnel requests to the remote Selenium WebDriver through * @param DesiredCapabilities $required_capabilities The required capabilities * @return RemoteWebDriver */ @@ -103,10 +118,9 @@ public static function create( ); $response = $executor->execute($command); + $returnedCapabilities = new DesiredCapabilities($response->getValue()); - $driver = new static(); - $driver->setSessionID($response->getSessionID()) - ->setCommandExecutor($executor); + $driver = new static($executor, $response->getSessionID(), $returnedCapabilities); return $driver; } @@ -134,9 +148,8 @@ protected static function castToDesiredCapabilitiesObject($desired_capabilities /** * [Experimental] Construct the RemoteWebDriver by an existing session. * - * This constructor can boost the performance a lot by reusing the same - * browser for the whole test suite. You do not have to pass the desired - * capabilities because the session was created before. + * This constructor can boost the performance a lot by reusing the same browser for the whole test suite. + * You cannot the desired capabilities because the session was created before. * * @param string $selenium_server_url The url of the remote Selenium WebDriver server * @param string $session_id The existing session id @@ -144,11 +157,9 @@ protected static function castToDesiredCapabilitiesObject($desired_capabilities */ public static function createBySessionID($session_id, $selenium_server_url = 'http://localhost:4444/wd/hub') { - $driver = new static(); - $driver->setSessionID($session_id) - ->setCommandExecutor(new HttpCommandExecutor($selenium_server_url)); + $executor = new HttpCommandExecutor($selenium_server_url); - return $driver; + return new static($executor, $session_id); } /** @@ -493,6 +504,9 @@ protected function newElement($id) /** * Set the command executor of this RemoteWebdriver * + * @deprecated To be removed in the future. Executor should be passed in the constructor. + * @internal + * @codeCoverageIgnore * @param WebDriverCommandExecutor $executor * @return RemoteWebDriver */ @@ -516,6 +530,9 @@ public function getCommandExecutor() /** * Set the session id of the RemoteWebDriver. * + * @deprecated To be removed in the future. Session ID should be passed in the constructor. + * @internal + * @codeCoverageIgnore * @param string $session_id * @return RemoteWebDriver */ @@ -529,13 +546,23 @@ public function setSessionID($session_id) /** * Get current selenium sessionID * - * @return string sessionID + * @return string */ public function getSessionID() { return $this->sessionID; } + /** + * Get capabilities of the RemoteWebDriver. + * + * @return WebDriverCapabilities + */ + public function getCapabilities() + { + return $this->capabilities; + } + /** * Returns a list of the currently active sessions. * diff --git a/lib/Remote/Service/DriverCommandExecutor.php b/lib/Remote/Service/DriverCommandExecutor.php index 59125833b..28cc5e438 100644 --- a/lib/Remote/Service/DriverCommandExecutor.php +++ b/lib/Remote/Service/DriverCommandExecutor.php @@ -19,6 +19,7 @@ use Facebook\WebDriver\Remote\DriverCommand; use Facebook\WebDriver\Remote\HttpCommandExecutor; use Facebook\WebDriver\Remote\WebDriverCommand; +use Facebook\WebDriver\Remote\WebDriverResponse; /** * A HttpCommandExecutor that talks to a local driver service instead of @@ -42,7 +43,7 @@ public function __construct(DriverService $service) * * @throws WebDriverException * @throws \Exception - * @return mixed + * @return WebDriverResponse */ public function execute(WebDriverCommand $command) { diff --git a/lib/WebDriverCommandExecutor.php b/lib/WebDriverCommandExecutor.php index 00357c6e7..0a50ccdde 100644 --- a/lib/WebDriverCommandExecutor.php +++ b/lib/WebDriverCommandExecutor.php @@ -16,6 +16,7 @@ namespace Facebook\WebDriver; use Facebook\WebDriver\Remote\WebDriverCommand; +use Facebook\WebDriver\Remote\WebDriverResponse; /** * Interface for all command executor. @@ -25,7 +26,7 @@ interface WebDriverCommandExecutor /** * @param WebDriverCommand $command * - * @return mixed + * @return WebDriverResponse */ public function execute(WebDriverCommand $command); } diff --git a/tests/functional/FileUploadTest.php b/tests/functional/FileUploadTest.php index e3b6be1d3..e8878e642 100644 --- a/tests/functional/FileUploadTest.php +++ b/tests/functional/FileUploadTest.php @@ -17,6 +17,10 @@ use Facebook\WebDriver\Remote\LocalFileDetector; +/** + * @covers Facebook\WebDriver\Remote\LocalFileDetector + * @covers Facebook\WebDriver\Remote\RemoteWebElement + */ class FileUploadTest extends WebDriverTestCase { public function testShouldUploadAFile() diff --git a/tests/functional/RemoteWebDriverFindElementTest.php b/tests/functional/RemoteWebDriverFindElementTest.php index 64f7b8d9c..751b0310e 100644 --- a/tests/functional/RemoteWebDriverFindElementTest.php +++ b/tests/functional/RemoteWebDriverFindElementTest.php @@ -20,6 +20,9 @@ /** * Tests for findElement() and findElements() method of RemoteWebDriver. + * @covers Facebook\WebDriver\Remote\RemoteWebDriver + * @covers Facebook\WebDriver\Exception\WebDriverException + * @covers Facebook\WebDriver\Exception\NoSuchElementException */ class RemoteWebDriverFindElementTest extends WebDriverTestCase { diff --git a/tests/functional/RemoteWebDriverTest.php b/tests/functional/RemoteWebDriverTest.php index 0f9691c96..1ce4c9570 100644 --- a/tests/functional/RemoteWebDriverTest.php +++ b/tests/functional/RemoteWebDriverTest.php @@ -19,6 +19,9 @@ use Facebook\WebDriver\Remote\RemoteWebDriver; use Facebook\WebDriver\Remote\WebDriverBrowserType; +/** + * @covers Facebook\WebDriver\Remote\RemoteWebDriver + */ class RemoteWebDriverTest extends WebDriverTestCase { public function testShouldGetPageTitle() diff --git a/tests/functional/RemoteWebElementTest.php b/tests/functional/RemoteWebElementTest.php index 1869671d4..e176d4189 100644 --- a/tests/functional/RemoteWebElementTest.php +++ b/tests/functional/RemoteWebElementTest.php @@ -15,6 +15,9 @@ namespace Facebook\WebDriver; +/** + * @covers Facebook\WebDriver\Remote\RemoteWebElement + */ class RemoteWebElementTest extends WebDriverTestCase { public function testShouldGetText() diff --git a/tests/functional/WebDriverByTest.php b/tests/functional/WebDriverByTest.php index 4309836f6..da614f69b 100644 --- a/tests/functional/WebDriverByTest.php +++ b/tests/functional/WebDriverByTest.php @@ -19,6 +19,7 @@ /** * Tests for locator strategies provided by WebDriverBy. + * @covers Facebook\WebDriver\WebDriverBy */ class WebDriverByTest extends WebDriverTestCase { diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index f44c70343..8c2fd4b8d 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -25,6 +25,11 @@ */ class WebDriverTestCase extends \PHPUnit_Framework_TestCase { + /** @var bool Indicate whether WebDriver should be created on setUp */ + protected $createWebDriver = true; + /** @var string */ + protected $serverUrl = 'http://localhost:4444/wd/hub'; + /** @var RemoteWebDriver $driver */ protected $driver; /** @var DesiredCapabilities */ @@ -33,7 +38,6 @@ class WebDriverTestCase extends \PHPUnit_Framework_TestCase protected function setUp() { $this->desiredCapabilities = new DesiredCapabilities(); - $serverUrl = 'http://localhost:4444/wd/hub'; if (getenv('BROWSER_NAME')) { $browserName = getenv('BROWSER_NAME'); @@ -43,12 +47,14 @@ protected function setUp() $this->desiredCapabilities->setBrowserName($browserName); - $this->driver = RemoteWebDriver::create($serverUrl, $this->desiredCapabilities); + if ($this->createWebDriver) { + $this->driver = RemoteWebDriver::create($this->serverUrl, $this->desiredCapabilities); + } } protected function tearDown() { - if ($this->driver->getCommandExecutor()) { + if ($this->driver instanceof RemoteWebDriver && $this->driver->getCommandExecutor()) { try { $this->driver->quit(); } catch (NoSuchWindowException $e) { From 3e2413d87e0ec88bed56c99f485df84d3c6cad03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 8 Jan 2017 00:35:35 +0100 Subject: [PATCH 262/784] Update changelog --- CHANGELOG.md | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 137452511..c3d9f1f42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,31 +2,32 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased -- `Symfony\Process` is used to start local WebDriver processes (when browsers are run directly, without Selenium server) to workaround some PHP bugs and improve poratbility -- Clarified meaning of selenium server URL variable in methods of `RemoteWebDriver` class +- `Symfony\Process` is used to start local WebDriver processes (when browsers are run directly, without Selenium server) to workaround some PHP bugs and improve portability. +- Clarified meaning of selenium server URL variable in methods of `RemoteWebDriver` class. - Deprecated `setSessionID()` and `setCommandExecutor()` methods of `RemoteWebDriver` class; these values should be immutable and thus passed only via constructor. - Added `getCapabilities()` method of `RemoteWebDriver`, to retrieve actual capabilities acknowledged by the remote driver on startup. +- Added option to pass required capabilities when creating `RemoteWebDriver`. (So far only desired capabilities were supported.) ## 1.2.0 - 2016-10-14 -- Added initial support of remote Microsoft Edge browser (but starting local EdgeDriver is still not supported) -- Utilize late static binding to make eg. `WebDriverBy` and `DesiredCapabilities` classes easily extensible -- PHP version at least 5.5 is required -- Fixed incompatibility with Appium, caused by redundant params present in requests to Selenium server +- Added initial support of remote Microsoft Edge browser (but starting local EdgeDriver is still not supported). +- Utilize late static binding to make eg. `WebDriverBy` and `DesiredCapabilities` classes easily extensible. +- PHP version at least 5.5 is required. +- Fixed incompatibility with Appium, caused by redundant params present in requests to Selenium server. ## 1.1.3 - 2016-08-10 -- Fixed FirefoxProfile to support installation of extensions with custom namespace prefix in their manifest file -- Comply codestyle with [PSR-2](http://www.php-fig.org/psr/psr-2/) +- Fixed FirefoxProfile to support installation of extensions with custom namespace prefix in their manifest file. +- Comply codestyle with [PSR-2](http://www.php-fig.org/psr/psr-2/). ## 1.1.2 - 2016-06-04 -- Added ext-curl to composer.json -- Added CHANGELOG.md -- Added CONTRIBUTING.md with information and rules for contributors +- Added ext-curl to composer.json. +- Added CHANGELOG.md. +- Added CONTRIBUTING.md with information and rules for contributors. ## 1.1.1 - 2015-12-31 -- Fixed strict standards error in `ChromeDriver` -- Added unit tests for `WebDriverCommand` and `DesiredCapabilities` -- Fixed retrieving temporary path name in `FirefoxDriver` when `open_basedir` restriction is in effect +- Fixed strict standards error in `ChromeDriver`. +- Added unit tests for `WebDriverCommand` and `DesiredCapabilities`. +- Fixed retrieving temporary path name in `FirefoxDriver` when `open_basedir` restriction is in effect. ## 1.1.0 - 2015-12-08 -- FirefoxProfile improved - added possibility to set RDF file and to add datas for extensions -- Fixed setting 0 second timeout of `WebDriverWait` +- FirefoxProfile improved - added possibility to set RDF file and to add datas for extensions. +- Fixed setting 0 second timeout of `WebDriverWait`. From 718d404e0a949afea74cde12a65acdcdeb1d8b95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 8 Jan 2017 01:18:51 +0100 Subject: [PATCH 263/784] Refactor WebDriverByTest data provider to not the repeat same code --- tests/functional/WebDriverByTest.php | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/tests/functional/WebDriverByTest.php b/tests/functional/WebDriverByTest.php index da614f69b..753790248 100644 --- a/tests/functional/WebDriverByTest.php +++ b/tests/functional/WebDriverByTest.php @@ -25,18 +25,21 @@ class WebDriverByTest extends WebDriverTestCase { /** * @dataProvider textElementsProvider - * @param WebDriverBy $locator + * @param $webDriverByLocatorMethod + * @param $webDriverByLocatorValue * @param string $expectedText * @param string $expectedAttributeValue */ public function testShouldFindTextElementByLocator( - WebDriverBy $locator, + $webDriverByLocatorMethod, + $webDriverByLocatorValue, $expectedText = null, $expectedAttributeValue = null ) { $this->driver->get($this->getTestPath('index.html')); - $element = $this->driver->findElement($locator); + $by = call_user_func([WebDriverBy::class, $webDriverByLocatorMethod], $webDriverByLocatorValue); + $element = $this->driver->findElement($by); $this->assertInstanceOf(RemoteWebElement::class, $element); @@ -52,14 +55,14 @@ public function testShouldFindTextElementByLocator( public function textElementsProvider() { return [ - 'id' => [WebDriverBy::id('id_test'), 'Test by ID'], - 'className' => [WebDriverBy::className('test_class'), 'Test by Class'], - 'cssSelector' => [WebDriverBy::cssSelector('.test_class'), 'Test by Class'], - 'linkText' => [WebDriverBy::linkText('Click here'), 'Click here'], - 'partialLinkText' => [WebDriverBy::partialLinkText('Click'), 'Click here'], - 'xpath' => [WebDriverBy::xpath('//input[@name="test_name"]'), '', 'Test Value'], - 'name' => [WebDriverBy::name('test_name'), '', 'Test Value'], - 'tagName' => [WebDriverBy::tagName('input'), '', 'Test Value'], + 'id' => ['id', 'id_test', 'Test by ID'], + 'className' => ['className', 'test_class', 'Test by Class'], + 'cssSelector' => ['cssSelector', '.test_class', 'Test by Class'], + 'linkText' => ['linkText', 'Click here', 'Click here'], + 'partialLinkText' => ['partialLinkText', 'Click', 'Click here'], + 'xpath' => ['xpath', '//input[@name="test_name"]', '', 'Test Value'], + 'name' => ['name', 'test_name', '', 'Test Value'], + 'tagName' => ['tagName', 'input', '', 'Test Value'], ]; } } From 702f5e287b6386462e131e0f9ccbb7dea8d1e14f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 8 Jan 2017 02:50:32 +0100 Subject: [PATCH 264/784] Fix coveralls reporting --- .travis.yml | 2 ++ phpunit.xml.dist | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/.travis.yml b/.travis.yml index 3710d83da..7c0cd3e77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,6 +21,8 @@ matrix: script: - ./vendor/bin/php-cs-fixer fix --diff --dry-run - ./vendor/bin/phpcs --standard=PSR2 ./lib/ ./tests/ + after_script: ~ + after_success: ~ env: global: diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 06dee9c0f..894ba470a 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -23,4 +23,10 @@ tests/functional
+ + + + ./lib + + From 60bf22af015e083c1ab08d9beaad163ed5ea8229 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 16 Dec 2016 14:54:11 +0100 Subject: [PATCH 265/784] Add tests for part of expected conditions --- lib/WebDriverExpectedCondition.php | 80 +++---- tests/unit/WebDriverExpectedConditionTest.php | 210 ++++++++++++++++++ 2 files changed, 245 insertions(+), 45 deletions(-) create mode 100644 tests/unit/WebDriverExpectedConditionTest.php diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index b7cd53204..f82255845 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -78,8 +78,8 @@ function (WebDriver $driver) use ($title) { } /** - * An expectation for checking that an element is present on the DOM of a - * page. This does not necessarily mean that the element is visible. + * An expectation for checking that an element is present on the DOM of a page. + * This does not necessarily mean that the element is visible. * * @param WebDriverBy $by The locator used to find the element. * @return WebDriverExpectedCondition The element which is located. @@ -94,9 +94,25 @@ function (WebDriver $driver) use ($by) { } /** - * An expectation for checking that an element is present on the DOM of a page - * and visible. Visibility means that the element is not only displayed but - * also has a height and width that is greater than 0. + * An expectation for checking that there is at least one element present on a web page. + * + * @param WebDriverBy $by The locator used to find the element. + * @return WebDriverExpectedCondition An array of WebDriverElements once they are located. + */ + public static function presenceOfAllElementsLocatedBy(WebDriverBy $by) + { + return new static( + function (WebDriver $driver) use ($by) { + $elements = $driver->findElements($by); + + return count($elements) > 0 ? $elements : null; + } + ); + } + + /** + * An expectation for checking that an element is present on the DOM of a page and visible. + * Visibility means that the element is not only displayed but also has a height and width that is greater than 0. * * @param WebDriverBy $by The locator used to find the element. * @return WebDriverExpectedCondition The element which is located and visible. @@ -117,9 +133,8 @@ function (WebDriver $driver) use ($by) { } /** - * An expectation for checking that an element, known to be present on the DOM - * of a page, is visible. Visibility means that the element is not only - * displayed but also has a height and width that is greater than 0. + * An expectation for checking that an element, known to be present on the DOM of a page, is visible. + * Visibility means that the element is not only displayed but also has a height and width that is greater than 0. * * @param WebDriverElement $element The element to be checked. * @return WebDriverExpectedCondition The same WebDriverElement once it is visible. @@ -134,30 +149,11 @@ function () use ($element) { } /** - * An expectation for checking that there is at least one element present on a - * web page. - * - * @param WebDriverBy $by The locator used to find the element. - * @return WebDriverExpectedCondition An array of WebDriverElements once they are located. - */ - public static function presenceOfAllElementsLocatedBy(WebDriverBy $by) - { - return new static( - function (WebDriver $driver) use ($by) { - $elements = $driver->findElements($by); - - return count($elements) > 0 ? $elements : null; - } - ); - } - - /** - * An expectation for checking if the given text is present in the specified - * element. + * An expectation for checking if the given text is present in the specified element. * * @param WebDriverBy $by The locator used to find the element. * @param string $text The text to be presented in the element. - * @return bool WebDriverExpectedCondition Whether the text is presented. + * @return bool WebDriverExpectedCondition Whether the text is present. */ public static function textToBePresentInElement(WebDriverBy $by, $text) { @@ -175,8 +171,7 @@ function (WebDriver $driver) use ($by, $text) { } /** - * An expectation for checking if the given text is present in the specified - * elements value attribute. + * An expectation for checking if the given text is present in the specified elements value attribute. * * @param WebDriverBy $by The locator used to find the element. * @param string $text The text to be presented in the element value. @@ -198,8 +193,7 @@ function (WebDriver $driver) use ($by, $text) { } /** - * Expectation for checking if iFrame exists. - * If iFrame exists switches driver's focus to the iFrame + * Expectation for checking if iFrame exists. If iFrame exists switches driver's focus to the iFrame. * * @param string $frame_locator The locator used to find the iFrame * expected to be either the id or name value of the i/frame @@ -220,8 +214,7 @@ function (WebDriver $driver) use ($frame_locator) { } /** - * An expectation for checking that an element is either invisible or not - * present on the DOM. + * An expectation for checking that an element is either invisible or not present on the DOM. * * @param WebDriverBy $by The locator used to find the element. * @return bool WebDriverExpectedCondition Whether there is no element located. @@ -231,7 +224,7 @@ public static function invisibilityOfElementLocated(WebDriverBy $by) return new static( function (WebDriver $driver) use ($by) { try { - return !($driver->findElement($by)->isDisplayed()); + return !$driver->findElement($by)->isDisplayed(); } catch (NoSuchElementException $e) { return true; } catch (StaleElementReferenceException $e) { @@ -242,8 +235,7 @@ function (WebDriver $driver) use ($by) { } /** - * An expectation for checking that an element with text is either invisible - * or not present on the DOM. + * An expectation for checking that an element with text is either invisible or not present on the DOM. * * @param WebdriverBy $by The locator used to find the element. * @param string $text The text of the element. @@ -265,8 +257,7 @@ function (WebDriver $driver) use ($by, $text) { } /** - * An expectation for checking an element is visible and enabled such that you - * can click it. + * An expectation for checking an element is visible and enabled such that you can click it. * * @param WebDriverBy $by The locator used to find the element * @return WebDriverExpectedCondition The WebDriverElement @@ -320,11 +311,10 @@ function () use ($element) { /** * Wrapper for a condition, which allows for elements to update by redrawing. * - * This works around the problem of conditions which have two parts: find an - * element and then check for some condition on it. For these conditions it is - * possible that an element is located and then subsequently it is redrawn on - * the client. When this happens a StaleElementReferenceException is thrown - * when the second part of the condition is checked. + * This works around the problem of conditions which have two parts: find an element and then check for some + * condition on it. For these conditions it is possible that an element is located and then subsequently it is + * redrawn on the client. When this happens a StaleElementReferenceException is thrown when the second part of + * the condition is checked. * * @param WebDriverExpectedCondition $condition The condition wrapped. * @return WebDriverExpectedCondition The return value of the getApply() of the given condition. diff --git a/tests/unit/WebDriverExpectedConditionTest.php b/tests/unit/WebDriverExpectedConditionTest.php new file mode 100644 index 000000000..85997939e --- /dev/null +++ b/tests/unit/WebDriverExpectedConditionTest.php @@ -0,0 +1,210 @@ +driverMock = $this + ->getMockBuilder(RemoteWebDriver::class) + ->disableOriginalConstructor() + ->getMock(); + $this->wait = new WebDriverWait($this->driverMock, 1, 1); + } + + public function testShouldDetectTitleIsCondition() + { + $this->driverMock->expects($this->any()) + ->method('getTitle') + ->willReturnOnConsecutiveCalls('old', 'oldwithnew', 'new'); + + $condition = WebDriverExpectedCondition::titleIs('new'); + + $this->assertFalse(call_user_func($condition->getApply(), $this->driverMock)); + $this->assertFalse(call_user_func($condition->getApply(), $this->driverMock)); + $this->assertTrue(call_user_func($condition->getApply(), $this->driverMock)); + } + + public function testShouldDetectTitleContainsCondition() + { + $this->driverMock->expects($this->any()) + ->method('getTitle') + ->willReturnOnConsecutiveCalls('old', 'oldwithnew', 'new'); + + $condition = WebDriverExpectedCondition::titleContains('new'); + + $this->assertFalse(call_user_func($condition->getApply(), $this->driverMock)); + $this->assertTrue(call_user_func($condition->getApply(), $this->driverMock)); + $this->assertTrue(call_user_func($condition->getApply(), $this->driverMock)); + } + + public function testShouldDetectPresenceOfElementLocatedCondition() + { + $element = new RemoteWebElement(new RemoteExecuteMethod($this->driverMock), 'id'); + + $this->driverMock->expects($this->at(0)) + ->method('findElement') + ->with($this->isInstanceOf(WebDriverBy::class)) + ->willThrowException(new NoSuchElementException('')); + + $this->driverMock->expects($this->at(1)) + ->method('findElement') + ->with($this->isInstanceOf(WebDriverBy::class)) + ->willReturn($element); + + $condition = WebDriverExpectedCondition::presenceOfElementLocated(WebDriverBy::cssSelector('.foo')); + + $this->assertSame($element, $this->wait->until($condition)); + } + + public function testShouldDetectPresenceOfAllElementsLocatedByCondition() + { + $element = $this->createRemoteWebElementMock(); + + $this->driverMock->expects($this->at(0)) + ->method('findElements') + ->with($this->isInstanceOf(WebDriverBy::class)) + ->willReturn([]); + + $this->driverMock->expects($this->at(1)) + ->method('findElements') + ->with($this->isInstanceOf(WebDriverBy::class)) + ->willReturn([$element]); + + $condition = WebDriverExpectedCondition::presenceOfAllElementsLocatedBy(WebDriverBy::cssSelector('.foo')); + + $this->assertSame([$element], $this->wait->until($condition)); + } + + public function testShouldDetectVisibilityOfElementLocatedCondition() + { + // Set-up the consecutive calls to apply() as follows: + // Call #1: throws NoSuchElementException + // Call #2: return Element, but isDisplayed will throw StaleElementReferenceException + // Call #3: return Element, but isDisplayed will return false + // Call #4: return Element, isDisplayed will true and condition will match + + $element = $this->createRemoteWebElementMock(); + $element->expects($this->at(0)) + ->method('isDisplayed') + ->willThrowException(new StaleElementReferenceException('')); + + $element->expects($this->at(1)) + ->method('isDisplayed') + ->willReturn(false); + + $element->expects($this->at(2)) + ->method('isDisplayed') + ->willReturn(true); + + $this->driverMock->expects($this->at(0)) + ->method('findElement') + ->with($this->isInstanceOf(WebDriverBy::class)) + ->willThrowException(new NoSuchElementException('')); + + $this->driverMock->expects($this->at(1)) + ->method('findElement') + ->with($this->isInstanceOf(WebDriverBy::class)) + ->willReturn($element); + + $this->driverMock->expects($this->at(2)) + ->method('findElement') + ->with($this->isInstanceOf(WebDriverBy::class)) + ->willReturn($element); + + $this->driverMock->expects($this->at(3)) + ->method('findElement') + ->with($this->isInstanceOf(WebDriverBy::class)) + ->willReturn($element); + + $condition = WebDriverExpectedCondition::visibilityOfElementLocated(WebDriverBy::cssSelector('.foo')); + + $this->assertSame($element, $this->wait->until($condition)); + } + + public function testShouldDetectVisibilityOfCondition() + { + $element = $this->createRemoteWebElementMock(); + $element->expects($this->at(0)) + ->method('isDisplayed') + ->willReturn(false); + + $element->expects($this->at(1)) + ->method('isDisplayed') + ->willReturn(true); + + $condition = WebDriverExpectedCondition::visibilityOf($element); + + $this->assertSame($element, $this->wait->until($condition)); + } + + public function testShouldDetectTextToBePresentInElementCondition() + { + // Set-up the consecutive calls to apply() as follows: + // Call #1: throws NoSuchElementException + // Call #2: return Element, but getText returns an old text + // Call #3: return Element, but getText will throw StaleElementReferenceException + // Call #4: return Element, getText will return new text and condition will match + + $element = $this->createRemoteWebElementMock(); + $element->expects($this->at(0)) + ->method('getText') + ->willReturn('this is an old text'); + + $element->expects($this->at(1)) + ->method('getText') + ->willThrowException(new StaleElementReferenceException('')); + + $element->expects($this->at(2)) + ->method('getText') + ->willReturn('this is a new text'); + + $this->setupDriverToReturnElementAfterAnException($element, 4); + + $condition = WebDriverExpectedCondition::textToBePresentInElement(WebDriverBy::cssSelector('.foo'), 'new'); + + $this->assertTrue($this->wait->until($condition)); + } + + /** + * @todo Replace with createMock() once PHP 5.5 support is dropped + * @return \PHPUnit_Framework_MockObject_MockObject|RemoteWebElement + */ + private function createRemoteWebElementMock() + { + return $this->getMockBuilder(RemoteWebElement::class) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->getMock(); + } +} From 3d96ee5e36bc85e47afaf904da7cae3a64594aac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 16 Dec 2016 16:07:58 +0100 Subject: [PATCH 266/784] Add titleMatches condition to test against regexp --- lib/WebDriverExpectedCondition.php | 15 +++++++++++++++ tests/unit/WebDriverExpectedConditionTest.php | 13 +++++++++++++ 2 files changed, 28 insertions(+) diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index f82255845..45ef86f50 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -77,6 +77,21 @@ function (WebDriver $driver) use ($title) { ); } + /** + * An expectation for checking current page title matches the given regular expression. + * + * @param string $titleRegexp The regular expression to test against. + * @return bool WebDriverExpectedCondition True when in title, false otherwise. + */ + public static function titleMatches($titleRegexp) + { + return new static( + function (WebDriver $driver) use ($titleRegexp) { + return (bool) preg_match($titleRegexp, $driver->getTitle()); + } + ); + } + /** * An expectation for checking that an element is present on the DOM of a page. * This does not necessarily mean that the element is visible. diff --git a/tests/unit/WebDriverExpectedConditionTest.php b/tests/unit/WebDriverExpectedConditionTest.php index 85997939e..a8d078e7a 100644 --- a/tests/unit/WebDriverExpectedConditionTest.php +++ b/tests/unit/WebDriverExpectedConditionTest.php @@ -67,6 +67,19 @@ public function testShouldDetectTitleContainsCondition() $this->assertTrue(call_user_func($condition->getApply(), $this->driverMock)); } + public function testShouldDetectTitleMatchesCondition() + { + $this->driverMock->expects($this->any()) + ->method('getTitle') + ->willReturnOnConsecutiveCalls('non-matching', 'matching-not', 'matching-123'); + + $condition = WebDriverExpectedCondition::titleMatches('/matching-\d{3}/'); + + $this->assertFalse(call_user_func($condition->getApply(), $this->driverMock)); + $this->assertFalse(call_user_func($condition->getApply(), $this->driverMock)); + $this->assertTrue(call_user_func($condition->getApply(), $this->driverMock)); + } + public function testShouldDetectPresenceOfElementLocatedCondition() { $element = new RemoteWebElement(new RemoteExecuteMethod($this->driverMock), 'id'); From b4281e53344a58d7411aa3e161fdeaf3446dd4c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 17 Dec 2016 17:16:38 +0100 Subject: [PATCH 267/784] Add new elementTextIs and elementTextMatches conditions --- lib/WebDriverExpectedCondition.php | 42 ++++++++ tests/unit/WebDriverExpectedConditionTest.php | 102 ++++++++++++++---- 2 files changed, 125 insertions(+), 19 deletions(-) diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index 45ef86f50..f2e75d1a2 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -165,6 +165,7 @@ function () use ($element) { /** * An expectation for checking if the given text is present in the specified element. + * To check exact text match use elementTextIs() condition. * * @param WebDriverBy $by The locator used to find the element. * @param string $text The text to be presented in the element. @@ -185,6 +186,47 @@ function (WebDriver $driver) use ($by, $text) { ); } + /** + * An expectation for checking if the given text exactly equals the text in specified element. + * To check only partial substring of the text use textToBePresentInElement() condition. + * + * @param WebDriverBy $by The locator used to find the element. + * @param string $text The expected text of the element. + * @return bool WebDriverExpectedCondition True when element has text value equal to given one + */ + public static function elementTextIs(WebDriverBy $by, $text) + { + return new static( + function (WebDriver $driver) use ($by, $text) { + try { + return $driver->findElement($by)->getText() == $text; + } catch (StaleElementReferenceException $e) { + return null; + } + } + ); + } + + /** + * An expectation for checking if the given regular expression matches the text in specified element. + * + * @param WebDriverBy $by The locator used to find the element. + * @param string $regexp The regular expression to test against. + * @return bool WebDriverExpectedCondition True when element has text value equal to given one + */ + public static function elementTextMatches(WebDriverBy $by, $regexp) + { + return new static( + function (WebDriver $driver) use ($by, $regexp) { + try { + return (bool) preg_match($regexp, $driver->findElement($by)->getText()); + } catch (StaleElementReferenceException $e) { + return null; + } + } + ); + } + /** * An expectation for checking if the given text is present in the specified elements value attribute. * diff --git a/tests/unit/WebDriverExpectedConditionTest.php b/tests/unit/WebDriverExpectedConditionTest.php index a8d078e7a..fda958486 100644 --- a/tests/unit/WebDriverExpectedConditionTest.php +++ b/tests/unit/WebDriverExpectedConditionTest.php @@ -139,25 +139,7 @@ public function testShouldDetectVisibilityOfElementLocatedCondition() ->method('isDisplayed') ->willReturn(true); - $this->driverMock->expects($this->at(0)) - ->method('findElement') - ->with($this->isInstanceOf(WebDriverBy::class)) - ->willThrowException(new NoSuchElementException('')); - - $this->driverMock->expects($this->at(1)) - ->method('findElement') - ->with($this->isInstanceOf(WebDriverBy::class)) - ->willReturn($element); - - $this->driverMock->expects($this->at(2)) - ->method('findElement') - ->with($this->isInstanceOf(WebDriverBy::class)) - ->willReturn($element); - - $this->driverMock->expects($this->at(3)) - ->method('findElement') - ->with($this->isInstanceOf(WebDriverBy::class)) - ->willReturn($element); + $this->setupDriverToReturnElementAfterAnException($element, 4); $condition = WebDriverExpectedCondition::visibilityOfElementLocated(WebDriverBy::cssSelector('.foo')); @@ -208,6 +190,88 @@ public function testShouldDetectTextToBePresentInElementCondition() $this->assertTrue($this->wait->until($condition)); } + public function testShouldDetectElementTextIsCondition() + { + // Set-up the consecutive calls to apply() as follows: + // Call #1: throws NoSuchElementException + // Call #2: return Element, but getText will throw StaleElementReferenceException + // Call #3: return Element, getText will return not-matching text + // Call #4: return Element, getText will return new text and condition will match + + $element = $this->createRemoteWebElementMock(); + $element->expects($this->at(0)) + ->method('getText') + ->willThrowException(new StaleElementReferenceException('')); + + $element->expects($this->at(1)) + ->method('getText') + ->willReturn('this is a new text, but not exactly'); + + $element->expects($this->at(2)) + ->method('getText') + ->willReturn('this is a new text'); + + $this->setupDriverToReturnElementAfterAnException($element, 4); + + $condition = WebDriverExpectedCondition::elementTextIs( + WebDriverBy::cssSelector('.foo'), + 'this is a new text' + ); + + $this->assertTrue($this->wait->until($condition)); + } + + public function testShouldDetectElementTextMatchesCondition() + { + // Set-up the consecutive calls to apply() as follows: + // Call #1: throws NoSuchElementException + // Call #2: return Element, but getText will throw StaleElementReferenceException + // Call #3: return Element, getText will return not-matching text + // Call #4: return Element, getText will return matching text + + $element = $this->createRemoteWebElementMock(); + + $element->expects($this->at(0)) + ->method('getText') + ->willThrowException(new StaleElementReferenceException('')); + + $element->expects($this->at(1)) + ->method('getText') + ->willReturn('non-matching'); + + $element->expects($this->at(2)) + ->method('getText') + ->willReturn('matching-123'); + + $this->setupDriverToReturnElementAfterAnException($element, 4); + + $condition = WebDriverExpectedCondition::elementTextMatches( + WebDriverBy::cssSelector('.foo'), + '/matching-\d{3}/' + ); + + $this->assertTrue($this->wait->until($condition)); + } + + /** + * @param RemoteWebElement $element + * @param int $expectedNumberOfFindElementCalls + */ + private function setupDriverToReturnElementAfterAnException($element, $expectedNumberOfFindElementCalls) + { + $this->driverMock->expects($this->at(0)) + ->method('findElement') + ->with($this->isInstanceOf(WebDriverBy::class)) + ->willThrowException(new NoSuchElementException('')); + + for ($i = 1; $i < $expectedNumberOfFindElementCalls; $i++) { + $this->driverMock->expects($this->at($i)) + ->method('findElement') + ->with($this->isInstanceOf(WebDriverBy::class)) + ->willReturn($element); + } + } + /** * @todo Replace with createMock() once PHP 5.5 support is dropped * @return \PHPUnit_Framework_MockObject_MockObject|RemoteWebElement From 3b686905b8dd9c5b36b49dd4f4301f831fb1f4c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 17 Dec 2016 17:54:57 +0100 Subject: [PATCH 268/784] Deprecate textToBePresentInElement condition in favor of elementTextContains --- lib/WebDriverExpectedCondition.php | 17 ++++++++++++++++- tests/unit/WebDriverExpectedConditionTest.php | 4 ++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index f2e75d1a2..0ab230a6a 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -167,11 +167,26 @@ function () use ($element) { * An expectation for checking if the given text is present in the specified element. * To check exact text match use elementTextIs() condition. * + * @codeCoverageIgnore + * @deprecated Use WebDriverExpectedCondition::elementTextContains() instead * @param WebDriverBy $by The locator used to find the element. * @param string $text The text to be presented in the element. * @return bool WebDriverExpectedCondition Whether the text is present. */ public static function textToBePresentInElement(WebDriverBy $by, $text) + { + return self::elementTextContains($by, $text); + } + + /** + * An expectation for checking if the given text is present in the specified element. + * To check exact text match use elementTextIs() condition. + * + * @param WebDriverBy $by The locator used to find the element. + * @param string $text The text to be presented in the element. + * @return bool WebDriverExpectedCondition Whether the text is present. + */ + public static function elementTextContains(WebDriverBy $by, $text) { return new static( function (WebDriver $driver) use ($by, $text) { @@ -188,7 +203,7 @@ function (WebDriver $driver) use ($by, $text) { /** * An expectation for checking if the given text exactly equals the text in specified element. - * To check only partial substring of the text use textToBePresentInElement() condition. + * To check only partial substring of the text use elementTextContains() condition. * * @param WebDriverBy $by The locator used to find the element. * @param string $text The expected text of the element. diff --git a/tests/unit/WebDriverExpectedConditionTest.php b/tests/unit/WebDriverExpectedConditionTest.php index fda958486..a221b8012 100644 --- a/tests/unit/WebDriverExpectedConditionTest.php +++ b/tests/unit/WebDriverExpectedConditionTest.php @@ -162,7 +162,7 @@ public function testShouldDetectVisibilityOfCondition() $this->assertSame($element, $this->wait->until($condition)); } - public function testShouldDetectTextToBePresentInElementCondition() + public function testShouldDetectElementTextContainsCondition() { // Set-up the consecutive calls to apply() as follows: // Call #1: throws NoSuchElementException @@ -185,7 +185,7 @@ public function testShouldDetectTextToBePresentInElementCondition() $this->setupDriverToReturnElementAfterAnException($element, 4); - $condition = WebDriverExpectedCondition::textToBePresentInElement(WebDriverBy::cssSelector('.foo'), 'new'); + $condition = WebDriverExpectedCondition::elementTextContains(WebDriverBy::cssSelector('.foo'), 'new'); $this->assertTrue($this->wait->until($condition)); } From b6a59dd7f3cb5fc8bca1d2787f8a34c740f752dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 17 Dec 2016 17:18:25 +0100 Subject: [PATCH 269/784] Add new numberOfWindowsToBe condition to check number of opened window handles --- lib/WebDriverExpectedCondition.php | 15 +++++++++++++++ tests/unit/WebDriverExpectedConditionTest.php | 13 +++++++++++++ 2 files changed, 28 insertions(+) diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index 0ab230a6a..6be57f834 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -474,6 +474,21 @@ function (WebDriver $driver) { ); } + /** + * An expectation checking the number of opened windows. + * + * @param int $expectedNumberOfWindows + * @return WebDriverExpectedCondition + */ + public static function numberOfWindowsToBe($expectedNumberOfWindows) + { + return new static( + function (WebDriver $driver) use ($expectedNumberOfWindows) { + return count($driver->getWindowHandles()) == $expectedNumberOfWindows; + } + ); + } + /** * An expectation with the logical opposite condition of the given condition. * diff --git a/tests/unit/WebDriverExpectedConditionTest.php b/tests/unit/WebDriverExpectedConditionTest.php index a221b8012..fea46f58f 100644 --- a/tests/unit/WebDriverExpectedConditionTest.php +++ b/tests/unit/WebDriverExpectedConditionTest.php @@ -253,6 +253,19 @@ public function testShouldDetectElementTextMatchesCondition() $this->assertTrue($this->wait->until($condition)); } + public function testShouldDetectNumberOfWindowsToBeCondition() + { + $this->driverMock->expects($this->any()) + ->method('getWindowHandles') + ->willReturnOnConsecutiveCalls(['one'], ['one', 'two', 'three'], ['one', 'two']); + + $condition = WebDriverExpectedCondition::numberOfWindowsToBe(2); + + $this->assertFalse(call_user_func($condition->getApply(), $this->driverMock)); + $this->assertFalse(call_user_func($condition->getApply(), $this->driverMock)); + $this->assertTrue(call_user_func($condition->getApply(), $this->driverMock)); + } + /** * @param RemoteWebElement $element * @param int $expectedNumberOfFindElementCalls From 81ee780856500ff4df90f38cdf594f5bef9ab707 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 8 Jan 2017 01:53:02 +0100 Subject: [PATCH 270/784] Improve functional test stability on slower environments --- tests/functional/RemoteWebDriverTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/functional/RemoteWebDriverTest.php b/tests/functional/RemoteWebDriverTest.php index 1ce4c9570..27cc57e17 100644 --- a/tests/functional/RemoteWebDriverTest.php +++ b/tests/functional/RemoteWebDriverTest.php @@ -98,6 +98,10 @@ public function testShouldGetWindowHandles() // Open second window $this->driver->findElement(WebDriverBy::cssSelector('a'))->click(); + $this->driver->wait()->until( + WebDriverExpectedCondition::numberOfWindowsToBe(2) + ); + $this->assertCount(2, $this->driver->getWindowHandles()); } From 17437fa0e61ed9c67736732075e8f47baba3d3ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 8 Jan 2017 02:29:03 +0100 Subject: [PATCH 271/784] Properly specify covered parts of RemoteWebDriver --- tests/functional/RemoteWebDriverTest.php | 42 +++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/tests/functional/RemoteWebDriverTest.php b/tests/functional/RemoteWebDriverTest.php index 27cc57e17..918b3514b 100644 --- a/tests/functional/RemoteWebDriverTest.php +++ b/tests/functional/RemoteWebDriverTest.php @@ -20,10 +20,13 @@ use Facebook\WebDriver\Remote\WebDriverBrowserType; /** - * @covers Facebook\WebDriver\Remote\RemoteWebDriver + * @coversDefaultClass Facebook\WebDriver\Remote\RemoteWebDriver */ class RemoteWebDriverTest extends WebDriverTestCase { + /** + * @covers ::getTitle + */ public function testShouldGetPageTitle() { $this->driver->get($this->getTestPath('index.html')); @@ -34,6 +37,10 @@ public function testShouldGetPageTitle() ); } + /** + * @covers ::getCurrentURL + * @covers ::get + */ public function testShouldGetCurrentUrl() { $this->driver->get($this->getTestPath('index.html')); @@ -44,6 +51,9 @@ public function testShouldGetCurrentUrl() ); } + /** + * @covers ::getPageSource + */ public function testShouldGetPageSource() { $this->driver->get($this->getTestPath('index.html')); @@ -53,6 +63,9 @@ public function testShouldGetPageSource() $this->assertContains('Welcome to the facebook/php-webdriver testing page.', $source); } + /** + * @covers ::getSessionID + */ public function testShouldGetSessionId() { $sessionId = $this->driver->getSessionID(); @@ -61,6 +74,9 @@ public function testShouldGetSessionId() $this->assertNotEmpty($sessionId); } + /** + * @covers ::getAllSessions + */ public function testShouldGetAllSessions() { $sessions = RemoteWebDriver::getAllSessions(); @@ -73,6 +89,11 @@ public function testShouldGetAllSessions() $this->assertArrayHasKey('class', $sessions[0]); } + /** + * @covers ::getAllSessions + * @covers ::getCommandExecutor + * @covers ::quit + */ public function testShouldQuitAndUnsetExecutor() { $this->assertCount(1, RemoteWebDriver::getAllSessions()); @@ -84,6 +105,10 @@ public function testShouldQuitAndUnsetExecutor() $this->assertNull($this->driver->getCommandExecutor()); } + /** + * @covers ::getWindowHandle + * @covers ::getWindowHandles + */ public function testShouldGetWindowHandles() { $this->driver->get($this->getTestPath('open_new_window.html')); @@ -105,6 +130,9 @@ public function testShouldGetWindowHandles() $this->assertCount(2, $this->driver->getWindowHandles()); } + /** + * @covers ::getWindowHandles + */ public function testShouldCloseWindow() { $this->driver->get($this->getTestPath('open_new_window.html')); @@ -117,6 +145,9 @@ public function testShouldCloseWindow() $this->assertCount(1, $this->driver->getWindowHandles()); } + /** + * @covers ::executeScript + */ public function testShouldExecuteScriptAndDoNotBlockExecution() { $this->driver->get($this->getTestPath('index.html')); @@ -138,6 +169,9 @@ function(){document.getElementById("id_test").innerHTML = "Text changed by scrip $this->assertSame('Text changed by script', $element->getText()); } + /** + * @covers ::executeAsyncScript + */ public function testShouldExecuteAsyncScriptAndWaitUntilItIsFinished() { $this->driver->manage()->timeouts()->setScriptTimeout(1); @@ -163,6 +197,9 @@ function(){ $this->assertSame('Text changed by script', $element->getText()); } + /** + * @covers ::takeScreenshot + */ public function testShouldTakeScreenshot() { if (!extension_loaded('gd')) { @@ -183,6 +220,9 @@ public function testShouldTakeScreenshot() $this->assertGreaterThan(0, imagesy($image)); } + /** + * @covers ::takeScreenshot + */ public function testShouldSaveScreenshotToFile() { if (!extension_loaded('gd')) { From aa90f690c9b59a3a7f66551b201c2d916e00c802 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 8 Jan 2017 02:41:28 +0100 Subject: [PATCH 272/784] Update changelog --- CHANGELOG.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3d9f1f42..f4ed9fd1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,21 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +### Added +- Added `getCapabilities()` method of `RemoteWebDriver`, to retrieve actual capabilities acknowledged by the remote driver on startup. +- Added option to pass required capabilities when creating `RemoteWebDriver`. (So far only desired capabilities were supported.) +- Added new expected conditions: + - `titleMatches` - current page title matches regular expression + - `elementTextIs` - text in element exactly equals given text + - `elementTextMatches` - text in element matches regular expression + - `elementTextContains` (as an alias for `textToBePresentInElement`) - text in element contains given text + - `numberOfWindowsToBe` - number of opened windows equals given number + +### Changed - `Symfony\Process` is used to start local WebDriver processes (when browsers are run directly, without Selenium server) to workaround some PHP bugs and improve portability. - Clarified meaning of selenium server URL variable in methods of `RemoteWebDriver` class. - Deprecated `setSessionID()` and `setCommandExecutor()` methods of `RemoteWebDriver` class; these values should be immutable and thus passed only via constructor. -- Added `getCapabilities()` method of `RemoteWebDriver`, to retrieve actual capabilities acknowledged by the remote driver on startup. -- Added option to pass required capabilities when creating `RemoteWebDriver`. (So far only desired capabilities were supported.) +- Deprecated `WebDriverExpectedCondition::textToBePresentInElement()` in favor of `elementTextContains()` ## 1.2.0 - 2016-10-14 - Added initial support of remote Microsoft Edge browser (but starting local EdgeDriver is still not supported). From 8e1d0c517a844241b35ec9f15c3e7b4f78a37600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Mar=C3=ADn?= Date: Thu, 15 Dec 2016 11:11:09 +0100 Subject: [PATCH 273/784] Adding URL related conditions --- lib/WebDriverExpectedCondition.php | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index 6be57f834..e203c552e 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -92,6 +92,36 @@ function (WebDriver $driver) use ($titleRegexp) { ); } + /** + * An expectation for checking the URL of a page. + * + * @param string $url The expected URL, which must be an exact match. + * @return bool WebDriverExpectedCondition True when the URL matches, false otherwise. + */ + public static function urlIs($url) + { + return new static( + function (WebDriver $driver) use ($url) { + return $url === $driver->getCurrentURL(); + } + ); + } + + /** + * An expectation for checking substring of the URL of a page. + * + * @param string $url The expected substring of the URL + * @return bool WebDriverExpectedCondition True when in URL, false otherwise. + */ + public static function urlContains($url) + { + return new static( + function (WebDriver $driver) use ($url) { + return strpos($driver->getCurrentURL(), $url) !== false; + } + ); + } + /** * An expectation for checking that an element is present on the DOM of a page. * This does not necessarily mean that the element is visible. From 8f9c3316dc16d9e78cec7ac97484e7c2dd9ba95f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 8 Jan 2017 13:15:07 +0100 Subject: [PATCH 274/784] Add urlMatches condition to test against regexp --- CHANGELOG.md | 5 ++- lib/WebDriverExpectedCondition.php | 15 +++++++ tests/unit/WebDriverExpectedConditionTest.php | 39 +++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4ed9fd1f..f49ce0aeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,13 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). - Added `getCapabilities()` method of `RemoteWebDriver`, to retrieve actual capabilities acknowledged by the remote driver on startup. - Added option to pass required capabilities when creating `RemoteWebDriver`. (So far only desired capabilities were supported.) - Added new expected conditions: + - `urlIs` - current URL exactly equals given value + - `urlContains` - current URL contains given text + - `urlMatches` - current URL matches regular expression - `titleMatches` - current page title matches regular expression - `elementTextIs` - text in element exactly equals given text - - `elementTextMatches` - text in element matches regular expression - `elementTextContains` (as an alias for `textToBePresentInElement`) - text in element contains given text + - `elementTextMatches` - text in element matches regular expression - `numberOfWindowsToBe` - number of opened windows equals given number ### Changed diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index e203c552e..0c70026f2 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -122,6 +122,21 @@ function (WebDriver $driver) use ($url) { ); } + /** + * An expectation for checking current page URL matches the given regular expression. + * + * @param string $urlRegexp The regular expression to test against. + * @return bool WebDriverExpectedCondition True when in url, false otherwise. + */ + public static function urlMatches($urlRegexp) + { + return new static( + function (WebDriver $driver) use ($urlRegexp) { + return (bool) preg_match($urlRegexp, $driver->getCurrentURL()); + } + ); + } + /** * An expectation for checking that an element is present on the DOM of a page. * This does not necessarily mean that the element is visible. diff --git a/tests/unit/WebDriverExpectedConditionTest.php b/tests/unit/WebDriverExpectedConditionTest.php index fea46f58f..93d98b392 100644 --- a/tests/unit/WebDriverExpectedConditionTest.php +++ b/tests/unit/WebDriverExpectedConditionTest.php @@ -80,6 +80,45 @@ public function testShouldDetectTitleMatchesCondition() $this->assertTrue(call_user_func($condition->getApply(), $this->driverMock)); } + public function testShouldDetectUrlIsCondition() + { + $this->driverMock->expects($this->any()) + ->method('getCurrentURL') + ->willReturnOnConsecutiveCalls('https://old/', 'https://oldwithnew/', 'https://new/'); + + $condition = WebDriverExpectedCondition::urlIs('https://new/'); + + $this->assertFalse(call_user_func($condition->getApply(), $this->driverMock)); + $this->assertFalse(call_user_func($condition->getApply(), $this->driverMock)); + $this->assertTrue(call_user_func($condition->getApply(), $this->driverMock)); + } + + public function testShouldDetectUrlContainsCondition() + { + $this->driverMock->expects($this->any()) + ->method('getCurrentURL') + ->willReturnOnConsecutiveCalls('https://old/', 'https://oldwithnew/', 'https://new/'); + + $condition = WebDriverExpectedCondition::urlContains('new'); + + $this->assertFalse(call_user_func($condition->getApply(), $this->driverMock)); + $this->assertTrue(call_user_func($condition->getApply(), $this->driverMock)); + $this->assertTrue(call_user_func($condition->getApply(), $this->driverMock)); + } + + public function testShouldDetectUrlMatchesCondition() + { + $this->driverMock->expects($this->any()) + ->method('getCurrentURL') + ->willReturnOnConsecutiveCalls('https://non/matching/', 'https://matching/not/', 'https://matching/123/'); + + $condition = WebDriverExpectedCondition::urlMatches('/matching\/\d{3}\/$/'); + + $this->assertFalse(call_user_func($condition->getApply(), $this->driverMock)); + $this->assertFalse(call_user_func($condition->getApply(), $this->driverMock)); + $this->assertTrue(call_user_func($condition->getApply(), $this->driverMock)); + } + public function testShouldDetectPresenceOfElementLocatedCondition() { $element = new RemoteWebElement(new RemoteExecuteMethod($this->driverMock), 'id'); From f2dc151ceeb99dce48ff6db741c7edb0cce7fb9f Mon Sep 17 00:00:00 2001 From: Cristian Fedatov Date: Wed, 21 Dec 2016 15:13:24 +0200 Subject: [PATCH 275/784] Possibility to select option by partial text using selectByVisiblePartialText method. (fixes #375) --- CHANGELOG.md | 1 + lib/WebDriverSelect.php | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f49ce0aeb..fdd5a9019 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). - `elementTextContains` (as an alias for `textToBePresentInElement`) - text in element contains given text - `elementTextMatches` - text in element matches regular expression - `numberOfWindowsToBe` - number of opened windows equals given number +- Possibility to select option of `' => ['#select'], + ' + +
+ + +
+ + + +
+ + + +
+ +

+ +

+ + + + + From 790ac29e93eeee2dab40b92ffb0a852ff4195c09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 8 Jan 2017 19:41:58 +0100 Subject: [PATCH 278/784] Allow to deselect option of ` by its partial text (using `selectByVisiblePartialText()`) +- `XPathEscaper` helper class to quote XPaths containing both single and double quotes. ### Changed - `Symfony\Process` is used to start local WebDriver processes (when browsers are run directly, without Selenium server) to workaround some PHP bugs and improve portability. @@ -23,6 +24,9 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). - Deprecated `WebDriverExpectedCondition::textToBePresentInElement()` in favor of `elementTextContains()` - Throw an exception when attempting to deselect options of non-multiselect (it already didn't have any effect, but was silently ignored). +### Fixed +- XPath escaping in `select*()` and `deselect*()` methods of `WebDriverSelect`. + ## 1.2.0 - 2016-10-14 - Added initial support of remote Microsoft Edge browser (but starting local EdgeDriver is still not supported). - Utilize late static binding to make eg. `WebDriverBy` and `DesiredCapabilities` classes easily extensible. diff --git a/lib/Support/XPathEscaper.php b/lib/Support/XPathEscaper.php new file mode 100644 index 000000000..10271128c --- /dev/null +++ b/lib/Support/XPathEscaper.php @@ -0,0 +1,45 @@ + concat('foo', "'" ,'"bar') + * + * @param string $xpathToEscape The xpath to be converted. + * @return string The escaped string. + */ + public static function escapeQuotes($xpathToEscape) + { + // Single quotes not present => we can quote in them + if (strpos($xpathToEscape, "'") === false) { + return sprintf("'%s'", $xpathToEscape); + } + + // Double quotes not present => we can quote in them + if (strpos($xpathToEscape, '"') === false) { + return sprintf('"%s"', $xpathToEscape); + } + + // Both single and double quotes are present + return sprintf( + "concat('%s')", + str_replace("'", "', \"'\" ,'", $xpathToEscape) + ); + } +} diff --git a/lib/WebDriverSelect.php b/lib/WebDriverSelect.php index e45bcc22d..a55a0ff90 100644 --- a/lib/WebDriverSelect.php +++ b/lib/WebDriverSelect.php @@ -18,6 +18,7 @@ use Facebook\WebDriver\Exception\NoSuchElementException; use Facebook\WebDriver\Exception\UnexpectedTagNameException; use Facebook\WebDriver\Exception\UnsupportedOperationException; +use Facebook\WebDriver\Support\XPathEscaper; /** * Models a SELECT tag, providing helper methods to select and deselect options. @@ -128,7 +129,7 @@ public function selectByIndex($index) public function selectByValue($value) { $matched = false; - $xpath = './/option[@value = ' . $this->escapeQuotes($value) . ']'; + $xpath = './/option[@value = ' . XPathEscaper::escapeQuotes($value) . ']'; $options = $this->element->findElements(WebDriverBy::xpath($xpath)); foreach ($options as $option) { @@ -161,7 +162,7 @@ public function selectByValue($value) public function selectByVisibleText($text) { $matched = false; - $xpath = './/option[normalize-space(.) = ' . $this->escapeQuotes($text) . ']'; + $xpath = './/option[normalize-space(.) = ' . XPathEscaper::escapeQuotes($text) . ']'; $options = $this->element->findElements(WebDriverBy::xpath($xpath)); foreach ($options as $option) { @@ -210,7 +211,7 @@ public function selectByVisibleText($text) public function selectByVisiblePartialText($text) { $matched = false; - $xpath = './/option[contains(normalize-space(.), ' . $this->escapeQuotes($text) . ')]'; + $xpath = './/option[contains(normalize-space(.), ' . XPathEscaper::escapeQuotes($text) . ')]'; $options = $this->element->findElements(WebDriverBy::xpath($xpath)); foreach ($options as $option) { @@ -282,7 +283,7 @@ public function deselectByValue($value) throw new UnsupportedOperationException('You may only deselect options of a multi-select'); } - $xpath = './/option[@value = ' . $this->escapeQuotes($value) . ']'; + $xpath = './/option[@value = ' . XPathEscaper::escapeQuotes($value) . ']'; $options = $this->element->findElements(WebDriverBy::xpath($xpath)); foreach ($options as $option) { if ($option->isSelected()) { @@ -306,7 +307,7 @@ public function deselectByVisibleText($text) throw new UnsupportedOperationException('You may only deselect options of a multi-select'); } - $xpath = './/option[normalize-space(.) = ' . $this->escapeQuotes($text) . ']'; + $xpath = './/option[normalize-space(.) = ' . XPathEscaper::escapeQuotes($text) . ']'; $options = $this->element->findElements(WebDriverBy::xpath($xpath)); foreach ($options as $option) { if ($option->isSelected()) { @@ -330,7 +331,7 @@ public function deselectByVisiblePartialText($text) throw new UnsupportedOperationException('You may only deselect options of a multi-select'); } - $xpath = './/option[contains(normalize-space(.), ' . $this->escapeQuotes($text) . ')]'; + $xpath = './/option[contains(normalize-space(.), ' . XPathEscaper::escapeQuotes($text) . ')]'; $options = $this->element->findElements(WebDriverBy::xpath($xpath)); foreach ($options as $option) { if ($option->isSelected()) { @@ -338,36 +339,4 @@ public function deselectByVisiblePartialText($text) } } } - - /** - * Convert strings with both quotes and ticks into: - * foo'"bar -> concat("foo'", '"', "bar") - * - * @param string $to_escape The string to be converted. - * @return string The escaped string. - */ - protected function escapeQuotes($to_escape) - { - if (strpos($to_escape, '"') !== false && strpos($to_escape, "'") !== false) { - $substrings = explode('"', $to_escape); - - $escaped = 'concat('; - $first = true; - foreach ($substrings as $string) { - if (!$first) { - $escaped .= ", '\"',"; - $first = false; - } - $escaped .= '"' . $string . '"'; - } - - return $escaped; - } - - if (strpos($to_escape, '"') !== false) { - return sprintf("'%s'", $to_escape); - } - - return sprintf('"%s"', $to_escape); - } } diff --git a/tests/unit/Support/XPathEscaperTest.php b/tests/unit/Support/XPathEscaperTest.php new file mode 100644 index 000000000..21ac4aea0 --- /dev/null +++ b/tests/unit/Support/XPathEscaperTest.php @@ -0,0 +1,49 @@ +assertSame($expectedOutput, $output); + } + + /** + * @return array[] + */ + public function xpathProvider() + { + return [ + 'empty string encapsulate in single quotes' => ['', "''"], + 'string without quotes encapsulate in single quotes' => ['foo bar', "'foo bar'"], + 'string with single quotes encapsulate in double quotes' => ['foo\'bar\'', '"foo\'bar\'"'], + 'string with double quotes encapsulate in single quotes' => ['foo"bar"', '\'foo"bar"\''], + 'string with both types of quotes concatenate' => ['\'"', "concat('', \"'\" ,'\"')"], + 'string with multiple both types of quotes concatenate' => [ + 'a \'b\'"c"', + "concat('a ', \"'\" ,'b', \"'\" ,'\"c\"')", + ], + ]; + } +} From c9d58a84a28e01713c183c9c4d5a855154bc70e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 8 Jan 2017 21:00:25 +0100 Subject: [PATCH 281/784] No need to check for multiple values when selecting/deselecting by index, as the index is unique --- lib/WebDriverSelect.php | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/lib/WebDriverSelect.php b/lib/WebDriverSelect.php index a55a0ff90..b071291ae 100644 --- a/lib/WebDriverSelect.php +++ b/lib/WebDriverSelect.php @@ -97,23 +97,17 @@ public function getFirstSelectedOption() */ public function selectByIndex($index) { - $matched = false; foreach ($this->getOptions() as $option) { if ($option->getAttribute('index') === (string) $index) { if (!$option->isSelected()) { $option->click(); - if (!$this->isMultiple()) { - return; - } } - $matched = true; + + return; } } - if (!$matched) { - throw new NoSuchElementException( - sprintf('Cannot locate option with index: %d', $index) - ); - } + + throw new NoSuchElementException(sprintf('Cannot locate option with index: %d', $index)); } /** @@ -262,8 +256,12 @@ public function deselectByIndex($index) } foreach ($this->getOptions() as $option) { - if ($option->getAttribute('index') === (string) $index && $option->isSelected()) { - $option->click(); + if ($option->getAttribute('index') === (string) $index) { + if ($option->isSelected()) { + $option->click(); + } + + return; } } } From 6e91c998c4b1c4a4bfeac4385da7b65b188f156e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 8 Jan 2017 21:04:29 +0100 Subject: [PATCH 282/784] DRY when (de)selecting options --- lib/WebDriverSelect.php | 62 +++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/lib/WebDriverSelect.php b/lib/WebDriverSelect.php index b071291ae..e8e9587ed 100644 --- a/lib/WebDriverSelect.php +++ b/lib/WebDriverSelect.php @@ -99,9 +99,7 @@ public function selectByIndex($index) { foreach ($this->getOptions() as $option) { if ($option->getAttribute('index') === (string) $index) { - if (!$option->isSelected()) { - $option->click(); - } + $this->selectOption($option); return; } @@ -127,9 +125,7 @@ public function selectByValue($value) $options = $this->element->findElements(WebDriverBy::xpath($xpath)); foreach ($options as $option) { - if (!$option->isSelected()) { - $option->click(); - } + $this->selectOption($option); if (!$this->isMultiple()) { return; } @@ -160,9 +156,7 @@ public function selectByVisibleText($text) $options = $this->element->findElements(WebDriverBy::xpath($xpath)); foreach ($options as $option) { - if (!$option->isSelected()) { - $option->click(); - } + $this->selectOption($option); if (!$this->isMultiple()) { return; } @@ -174,9 +168,7 @@ public function selectByVisibleText($text) if (!$matched) { foreach ($this->getOptions() as $option) { if ($option->getText() === $text) { - if (!$option->isSelected()) { - $option->click(); - } + $this->selectOption($option); if (!$this->isMultiple()) { return; } @@ -209,9 +201,7 @@ public function selectByVisiblePartialText($text) $options = $this->element->findElements(WebDriverBy::xpath($xpath)); foreach ($options as $option) { - if (!$option->isSelected()) { - $option->click(); - } + $this->selectOption($option); if (!$this->isMultiple()) { return; } @@ -237,9 +227,7 @@ public function deselectAll() } foreach ($this->getOptions() as $option) { - if ($option->isSelected()) { - $option->click(); - } + $this->deselectOption($option); } } @@ -257,9 +245,7 @@ public function deselectByIndex($index) foreach ($this->getOptions() as $option) { if ($option->getAttribute('index') === (string) $index) { - if ($option->isSelected()) { - $option->click(); - } + $this->deselectOption($option); return; } @@ -284,9 +270,7 @@ public function deselectByValue($value) $xpath = './/option[@value = ' . XPathEscaper::escapeQuotes($value) . ']'; $options = $this->element->findElements(WebDriverBy::xpath($xpath)); foreach ($options as $option) { - if ($option->isSelected()) { - $option->click(); - } + $this->deselectOption($option); } } @@ -308,9 +292,7 @@ public function deselectByVisibleText($text) $xpath = './/option[normalize-space(.) = ' . XPathEscaper::escapeQuotes($text) . ']'; $options = $this->element->findElements(WebDriverBy::xpath($xpath)); foreach ($options as $option) { - if ($option->isSelected()) { - $option->click(); - } + $this->deselectOption($option); } } @@ -332,9 +314,29 @@ public function deselectByVisiblePartialText($text) $xpath = './/option[contains(normalize-space(.), ' . XPathEscaper::escapeQuotes($text) . ')]'; $options = $this->element->findElements(WebDriverBy::xpath($xpath)); foreach ($options as $option) { - if ($option->isSelected()) { - $option->click(); - } + $this->deselectOption($option); + } + } + + /** + * Mark option selected + * @param WebDriverElement $option + */ + protected function selectOption(WebDriverElement $option) + { + if (!$option->isSelected()) { + $option->click(); + } + } + + /** + * Mark option not selected + * @param WebDriverElement $option + */ + protected function deselectOption(WebDriverElement $option) + { + if ($option->isSelected()) { + $option->click(); } } } From fa04797db3e48cab6be9265f85c6efec1a3ade9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 8 Jan 2017 21:11:26 +0100 Subject: [PATCH 283/784] Extract WebDriverSelectInterface, to allow implementation of custom select-like components Eg. components not built around and actual select tag. --- CHANGELOG.md | 1 + lib/WebDriverSelect.php | 96 +---------------------- lib/WebDriverSelectInterface.php | 127 +++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 92 deletions(-) create mode 100644 lib/WebDriverSelectInterface.php diff --git a/CHANGELOG.md b/CHANGELOG.md index caf23c691..12c55520e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). - `numberOfWindowsToBe` - number of opened windows equals given number - Possibility to select option of ` tag, providing helper methods to select and deselect options. */ -class WebDriverSelect +class WebDriverSelect implements WebDriverSelectInterface { + /** @var WebDriverElement */ private $element; + /** @var bool */ private $isMulti; public function __construct(WebDriverElement $element) @@ -40,25 +42,16 @@ public function __construct(WebDriverElement $element) $this->isMulti = ($value === 'true'); } - /** - * @return bool Whether this select element support selecting multiple options. - */ public function isMultiple() { return $this->isMulti; } - /** - * @return WebDriverElement[] All options belonging to this select tag. - */ public function getOptions() { return $this->element->findElements(WebDriverBy::tagName('option')); } - /** - * @return WebDriverElement[] All selected options belonging to this select tag. - */ public function getAllSelectedOptions() { $selected_options = []; @@ -71,12 +64,6 @@ public function getAllSelectedOptions() return $selected_options; } - /** - * @throws NoSuchElementException - * - * @return WebDriverElement The first selected option in this select tag (or - * the currently selected option in a normal select) - */ public function getFirstSelectedOption() { foreach ($this->getOptions() as $option) { @@ -88,13 +75,6 @@ public function getFirstSelectedOption() throw new NoSuchElementException('No options are selected'); } - /** - * Select the option at the given index. - * - * @param int $index The index of the option. (0-based) - * - * @throws NoSuchElementException - */ public function selectByIndex($index) { foreach ($this->getOptions() as $option) { @@ -108,16 +88,6 @@ public function selectByIndex($index) throw new NoSuchElementException(sprintf('Cannot locate option with index: %d', $index)); } - /** - * Select all options that have value attribute matching the argument. That - * is, when given "foo" this would select an option like: - * - * ; - * - * @param string $value The value to match against. - * - * @throws NoSuchElementException - */ public function selectByValue($value) { $matched = false; @@ -139,16 +109,6 @@ public function selectByValue($value) } } - /** - * Select all options that display text matching the argument. That is, when - * given "Bar" this would select an option like: - * - * ; - * - * @param string $text The visible text to match against. - * - * @throws NoSuchElementException - */ public function selectByVisibleText($text) { $matched = false; @@ -184,16 +144,6 @@ public function selectByVisibleText($text) } } - /** - * Select all options that display text partially matching the argument. That is, when - * given "Bar" this would select an option like: - * - * ; - * - * @param string $text The visible text to match against. - * - * @throws NoSuchElementException - */ public function selectByVisiblePartialText($text) { $matched = false; @@ -215,11 +165,6 @@ public function selectByVisiblePartialText($text) } } - /** - * Deselect all options in multiple select tag. - * - * @throws UnsupportedOperationException If the SELECT does not support multiple selections - */ public function deselectAll() { if (!$this->isMultiple()) { @@ -231,12 +176,6 @@ public function deselectAll() } } - /** - * Deselect the option at the given index. - * - * @param int $index The index of the option. (0-based) - * @throws UnsupportedOperationException If the SELECT does not support multiple selections - */ public function deselectByIndex($index) { if (!$this->isMultiple()) { @@ -252,15 +191,6 @@ public function deselectByIndex($index) } } - /** - * Deselect all options that have value attribute matching the argument. That - * is, when given "foo" this would deselect an option like: - * - * ; - * - * @param string $value The value to match against. - * @throws UnsupportedOperationException If the SELECT does not support multiple selections - */ public function deselectByValue($value) { if (!$this->isMultiple()) { @@ -274,15 +204,6 @@ public function deselectByValue($value) } } - /** - * Deselect all options that display text matching the argument. That is, when - * given "Bar" this would deselect an option like: - * - * ; - * - * @param string $text The visible text to match against. - * @throws UnsupportedOperationException If the SELECT does not support multiple selections - */ public function deselectByVisibleText($text) { if (!$this->isMultiple()) { @@ -296,15 +217,6 @@ public function deselectByVisibleText($text) } } - /** - * Deselect all options that display text matching the argument. That is, when - * given "Bar" this would deselect an option like: - * - * ; - * - * @param string $text The visible text to match against. - * @throws UnsupportedOperationException If the SELECT does not support multiple selections - */ public function deselectByVisiblePartialText($text) { if (!$this->isMultiple()) { diff --git a/lib/WebDriverSelectInterface.php b/lib/WebDriverSelectInterface.php new file mode 100644 index 000000000..cec06a33f --- /dev/null +++ b/lib/WebDriverSelectInterface.php @@ -0,0 +1,127 @@ +Bar; + * + * @param string $value The value to match against. + * + * @throws NoSuchElementException + */ + public function selectByValue($value); + + /** + * Select all options that display text matching the argument. That is, when given "Bar" this would + * select an option like: + * + * ; + * + * @param string $text The visible text to match against. + * + * @throws NoSuchElementException + */ + public function selectByVisibleText($text); + + /** + * Select all options that display text partially matching the argument. That is, when given "Bar" this would + * select an option like: + * + * ; + * + * @param string $text The visible text to match against. + * + * @throws NoSuchElementException + */ + public function selectByVisiblePartialText($text); + + /** + * Deselect all options in multiple select tag. + * + * @throws UnsupportedOperationException If the SELECT does not support multiple selections + */ + public function deselectAll(); + + /** + * Deselect the option at the given index. + * + * @param int $index The index of the option. (0-based) + * @throws UnsupportedOperationException If the SELECT does not support multiple selections + */ + public function deselectByIndex($index); + + /** + * Deselect all options that have value attribute matching the argument. That is, when given "foo" this would + * deselect an option like: + * + * ; + * + * @param string $value The value to match against. + * @throws UnsupportedOperationException If the SELECT does not support multiple selections + */ + public function deselectByValue($value); + + /** + * Deselect all options that display text matching the argument. That is, when given "Bar" this would + * deselect an option like: + * + * ; + * + * @param string $text The visible text to match against. + * @throws UnsupportedOperationException If the SELECT does not support multiple selections + */ + public function deselectByVisibleText($text); + + /** + * Deselect all options that display text matching the argument. That is, when given "Bar" this would + * deselect an option like: + * + * ; + * + * @param string $text The visible text to match against. + * @throws UnsupportedOperationException If the SELECT does not support multiple selections + */ + public function deselectByVisiblePartialText($text); +} From 0979f5587a8e17d014c4e69d9415de32e3ff65a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 10 Jan 2017 14:57:43 +0100 Subject: [PATCH 284/784] Add some more tests for RemoteWebElement --- tests/functional/RemoteWebElementTest.php | 58 +++++++++++++++++++++-- tests/functional/web/index.html | 12 +++++ 2 files changed, 65 insertions(+), 5 deletions(-) diff --git a/tests/functional/RemoteWebElementTest.php b/tests/functional/RemoteWebElementTest.php index e176d4189..1a04cf1a8 100644 --- a/tests/functional/RemoteWebElementTest.php +++ b/tests/functional/RemoteWebElementTest.php @@ -23,11 +23,59 @@ class RemoteWebElementTest extends WebDriverTestCase public function testShouldGetText() { $this->driver->get($this->getTestPath('index.html')); - $element = $this->driver->findElement(WebDriverBy::id('welcome')); + $elementWithSimpleText = $this->driver->findElement(WebDriverBy::id('text-simple')); + $elementWithTextWithSpaces = $this->driver->findElement(WebDriverBy::id('text-with-spaces')); - $this->assertEquals( - 'Welcome to the facebook/php-webdriver testing page.', - $element->getText() - ); + $this->assertEquals('Foo bar text', $elementWithSimpleText->getText()); + $this->assertEquals('Multiple spaces are stripped', $elementWithTextWithSpaces->getText()); + } + + public function testShouldGetAttributeValue() + { + $this->driver->get($this->getTestPath('index.html')); + + $element = $this->driver->findElement(WebDriverBy::id('text-simple')); + + $this->assertSame('note', $element->getAttribute('role')); + $this->assertSame('height: 5em; border: 1px solid black;', $element->getAttribute('style')); + $this->assertSame('text-simple', $element->getAttribute('id')); + } + + public function testShouldGetLocation() + { + $this->driver->get($this->getTestPath('index.html')); + + $element = $this->driver->findElement(WebDriverBy::id('element-with-location')); + + $elementLocation = $element->getLocation(); + $this->assertInstanceOf(WebDriverPoint::class, $elementLocation); + $this->assertSame(33, $elementLocation->getX()); + $this->assertSame(500, $elementLocation->getY()); + } + + public function testShouldGetSize() + { + $this->driver->get($this->getTestPath('index.html')); + + $element = $this->driver->findElement(WebDriverBy::id('element-with-location')); + + $elementSize = $element->getSize(); + $this->assertInstanceOf(WebDriverDimension::class, $elementSize); + $this->assertSame(333, $elementSize->getWidth()); + $this->assertSame(66, $elementSize->getHeight()); + } + + public function testShouldGetCssValue() + { + $this->driver->get($this->getTestPath('index.html')); + + $elementWithBorder = $this->driver->findElement(WebDriverBy::id('text-simple')); + $elementWithoutBorder = $this->driver->findElement(WebDriverBy::id('text-with-spaces')); + + $this->assertSame('solid', $elementWithBorder->getCSSValue('border-left-style')); + $this->assertSame('none', $elementWithoutBorder->getCSSValue('border-left-style')); + + $this->assertSame('rgba(0, 0, 0, 1)', $elementWithBorder->getCSSValue('border-left-color')); + $this->assertSame('rgba(0, 0, 0, 1)', $elementWithoutBorder->getCSSValue('border-left-color')); } } diff --git a/tests/functional/web/index.html b/tests/functional/web/index.html index 139a25865..282706cce 100644 --- a/tests/functional/web/index.html +++ b/tests/functional/web/index.html @@ -16,5 +16,17 @@

Welcome to the facebook/php-webdriver testing page.

  • Second
  • Third
  • + +

    Foo bar text

    +

    + Multiple spaces are + stripped +

    + +
    + Foo +
    + + From efe3dc68124ba299d2b84263f91b6dd44d586327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 10 Jan 2017 14:06:06 +0100 Subject: [PATCH 285/784] Optimize getAllSelectedOptions method for single select, because it always contains exactly one selected option --- CHANGELOG.md | 1 + lib/WebDriverSelect.php | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12c55520e..112936c86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). - Deprecated `setSessionID()` and `setCommandExecutor()` methods of `RemoteWebDriver` class; these values should be immutable and thus passed only via constructor. - Deprecated `WebDriverExpectedCondition::textToBePresentInElement()` in favor of `elementTextContains()` - Throw an exception when attempting to deselect options of non-multiselect (it already didn't have any effect, but was silently ignored). +- Optimize performance of `(de)selectByIndex()` and `getAllSelectedOptions()` methods of `WebDriverSelect` when used with non-multiple select element. ### Fixed - XPath escaping in `select*()` and `deselect*()` methods of `WebDriverSelect`. diff --git a/lib/WebDriverSelect.php b/lib/WebDriverSelect.php index 7e7455ae5..dc6a84038 100644 --- a/lib/WebDriverSelect.php +++ b/lib/WebDriverSelect.php @@ -58,6 +58,10 @@ public function getAllSelectedOptions() foreach ($this->getOptions() as $option) { if ($option->isSelected()) { $selected_options[] = $option; + + if (!$this->isMultiple()) { + return $selected_options; + } } } From 3df0ef7e929e984f2747b0a2846bc91b5a9f1d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 11 Jan 2017 23:57:07 +0100 Subject: [PATCH 286/784] Various codestyle and typehint fixes --- lib/Chrome/ChromeDriver.php | 3 +- lib/Firefox/FirefoxProfile.php | 5 +- lib/Interactions/WebDriverActions.php | 5 +- lib/Remote/RemoteWebDriver.php | 10 ++-- lib/Remote/Service/DriverService.php | 2 +- lib/Support/Events/EventFiringWebDriver.php | 27 +++++++-- lib/Support/Events/EventFiringWebElement.php | 27 +++++++-- lib/WebDriver.php | 7 +++ lib/WebDriverExpectedCondition.php | 56 ++++++++++--------- .../unit/Exception/WebDriverExceptionTest.php | 2 +- 10 files changed, 99 insertions(+), 45 deletions(-) diff --git a/lib/Chrome/ChromeDriver.php b/lib/Chrome/ChromeDriver.php index 7aac128e4..249c4f1b5 100644 --- a/lib/Chrome/ChromeDriver.php +++ b/lib/Chrome/ChromeDriver.php @@ -63,7 +63,8 @@ public static function create( $connection_timeout_in_ms = null, $request_timeout_in_ms = null, $http_proxy = null, - $http_proxy_port = null + $http_proxy_port = null, + DesiredCapabilities $required_capabilities = null ) { throw new WebDriverException('Please use ChromeDriver::start() instead.'); } diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index 6dd4d41b3..00dcebd5c 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -226,9 +226,12 @@ private function installExtension($extension, $profile_dir) $ext_dir = $profile_dir . '/extensions/' . $matches[1]; mkdir($ext_dir, 0777, true); $this->extractTo($extension, $ext_dir); + } else { + $this->deleteDirectory($temp_dir); + + throw new WebDriverException('Cannot get the extension id from the install manifest.'); } - // clean up $this->deleteDirectory($temp_dir); return $ext_dir; diff --git a/lib/Interactions/WebDriverActions.php b/lib/Interactions/WebDriverActions.php index 281b84dac..e97796854 100644 --- a/lib/Interactions/WebDriverActions.php +++ b/lib/Interactions/WebDriverActions.php @@ -27,6 +27,7 @@ use Facebook\WebDriver\Interactions\Internal\WebDriverSendKeysAction; use Facebook\WebDriver\WebDriver; use Facebook\WebDriver\WebDriverElement; +use Facebook\WebDriver\WebDriverHasInputDevices; /** * WebDriver action builder. It implements the builder pattern. @@ -39,9 +40,9 @@ class WebDriverActions protected $action; /** - * @param WebDriver $driver + * @param WebDriverHasInputDevices $driver */ - public function __construct(WebDriver $driver) + public function __construct(WebDriverHasInputDevices $driver) { $this->driver = $driver; $this->keyboard = $driver->getKeyboard(); diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index dd1be325a..c2ecd8d37 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -20,16 +20,16 @@ use Facebook\WebDriver\WebDriver; use Facebook\WebDriver\WebDriverBy; use Facebook\WebDriver\WebDriverCapabilities; -use Facebook\WebDriver\WebDriverCommandExecutor; use Facebook\WebDriver\WebDriverElement; +use Facebook\WebDriver\WebDriverHasInputDevices; use Facebook\WebDriver\WebDriverNavigation; use Facebook\WebDriver\WebDriverOptions; use Facebook\WebDriver\WebDriverWait; -class RemoteWebDriver implements WebDriver, JavaScriptExecutor +class RemoteWebDriver implements WebDriver, JavaScriptExecutor, WebDriverHasInputDevices { /** - * @var HttpCommandExecutor + * @var HttpCommandExecutor|null */ protected $executor; /** @@ -507,10 +507,10 @@ protected function newElement($id) * @deprecated To be removed in the future. Executor should be passed in the constructor. * @internal * @codeCoverageIgnore - * @param WebDriverCommandExecutor $executor + * @param HttpCommandExecutor $executor * @return RemoteWebDriver */ - public function setCommandExecutor(WebDriverCommandExecutor $executor) + public function setCommandExecutor(HttpCommandExecutor $executor) { $this->executor = $executor; diff --git a/lib/Remote/Service/DriverService.php b/lib/Remote/Service/DriverService.php index 634c45864..c15ef94f9 100644 --- a/lib/Remote/Service/DriverService.php +++ b/lib/Remote/Service/DriverService.php @@ -46,7 +46,7 @@ class DriverService private $environment; /** - * @var Process + * @var Process|null */ private $process; diff --git a/lib/Support/Events/EventFiringWebDriver.php b/lib/Support/Events/EventFiringWebDriver.php index 268b35ac7..34514e9cd 100644 --- a/lib/Support/Events/EventFiringWebDriver.php +++ b/lib/Support/Events/EventFiringWebDriver.php @@ -50,8 +50,6 @@ public function __construct(WebDriver $driver, WebDriverDispatcher $dispatcher = $this->dispatcher->setDefaultDriver($this); } $this->driver = $driver; - - return $this; } /** @@ -105,6 +103,7 @@ public function get($url) $this->driver->get($url); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } $this->dispatch('afterNavigateTo', $url, $this); @@ -127,6 +126,7 @@ public function findElements(WebDriverBy $by) } } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } $this->dispatch('afterFindBy', $by, null, $this); @@ -147,6 +147,7 @@ public function findElement(WebDriverBy $by) $element = $this->newElement($this->driver->findElement($by)); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } $this->dispatch('afterFindBy', $by, null, $this); @@ -174,6 +175,7 @@ public function executeScript($script, array $arguments = []) $result = $this->driver->executeScript($script, $arguments); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } $this->dispatch('afterScript', $script, $this); @@ -200,6 +202,7 @@ public function executeAsyncScript($script, array $arguments = []) $result = $this->driver->executeAsyncScript($script, $arguments); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } $this->dispatch('afterScript', $script, $this); @@ -218,6 +221,7 @@ public function close() return $this; } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -231,6 +235,7 @@ public function getCurrentURL() return $this->driver->getCurrentURL(); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -244,6 +249,7 @@ public function getPageSource() return $this->driver->getPageSource(); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -257,6 +263,7 @@ public function getTitle() return $this->driver->getTitle(); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -270,6 +277,7 @@ public function getWindowHandle() return $this->driver->getWindowHandle(); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -283,6 +291,7 @@ public function getWindowHandles() return $this->driver->getWindowHandles(); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -295,6 +304,7 @@ public function quit() $this->driver->quit(); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -309,6 +319,7 @@ public function takeScreenshot($save_as = null) return $this->driver->takeScreenshot($save_as); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -324,6 +335,7 @@ public function wait($timeout_in_second = 30, $interval_in_millisecond = 250) return $this->driver->wait($timeout_in_second, $interval_in_millisecond); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -337,6 +349,7 @@ public function manage() return $this->driver->manage(); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -353,6 +366,7 @@ public function navigate() ); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -366,6 +380,7 @@ public function switchTo() return $this->driver->switchTo(); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -379,13 +394,16 @@ public function getTouch() return $this->driver->getTouch(); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } - private function dispatchOnException($exception) + /** + * @param WebDriverException $exception + */ + private function dispatchOnException(WebDriverException $exception) { $this->dispatch('onException', $exception, $this); - throw $exception; } public function execute($name, $params) @@ -394,6 +412,7 @@ public function execute($name, $params) return $this->driver->execute($name, $params); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } } diff --git a/lib/Support/Events/EventFiringWebElement.php b/lib/Support/Events/EventFiringWebElement.php index 872c59c5e..b9591b0ef 100644 --- a/lib/Support/Events/EventFiringWebElement.php +++ b/lib/Support/Events/EventFiringWebElement.php @@ -43,8 +43,6 @@ public function __construct(WebDriverElement $element, WebDriverDispatcher $disp { $this->element = $element; $this->dispatcher = $dispatcher; - - return $this; } /** @@ -97,6 +95,7 @@ public function sendKeys($value) $this->element->sendKeys($value); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } $this->dispatch('afterChangeValueOf', $this); @@ -114,6 +113,7 @@ public function click() $this->element->click(); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } $this->dispatch('afterClickOn', $this); @@ -138,6 +138,7 @@ public function findElement(WebDriverBy $by) $element = $this->newElement($this->element->findElement($by)); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } $this->dispatch( @@ -170,6 +171,7 @@ public function findElements(WebDriverBy $by) } } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } $this->dispatch( 'afterFindBy', @@ -193,6 +195,7 @@ public function clear() return $this; } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -207,6 +210,7 @@ public function getAttribute($attribute_name) return $this->element->getAttribute($attribute_name); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -221,6 +225,7 @@ public function getCSSValue($css_property_name) return $this->element->getCSSValue($css_property_name); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -234,6 +239,7 @@ public function getLocation() return $this->element->getLocation(); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -247,6 +253,7 @@ public function getLocationOnScreenOnceScrolledIntoView() return $this->element->getLocationOnScreenOnceScrolledIntoView(); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -259,6 +266,7 @@ public function getCoordinates() return $this->element->getCoordinates(); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -272,6 +280,7 @@ public function getSize() return $this->element->getSize(); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -285,6 +294,7 @@ public function getTagName() return $this->element->getTagName(); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -298,6 +308,7 @@ public function getText() return $this->element->getText(); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -311,6 +322,7 @@ public function isDisplayed() return $this->element->isDisplayed(); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -324,6 +336,7 @@ public function isEnabled() return $this->element->isEnabled(); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -337,6 +350,7 @@ public function isSelected() return $this->element->isSelected(); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -352,6 +366,7 @@ public function submit() return $this; } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -365,6 +380,7 @@ public function getID() return $this->element->getID(); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -380,16 +396,19 @@ public function equals(WebDriverElement $other) return $this->element->equals($other); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } - private function dispatchOnException($exception) + /** + * @param WebDriverException $exception + */ + private function dispatchOnException(WebDriverException $exception) { $this->dispatch( 'onException', $exception, $this->dispatcher->getDefaultDriver() ); - throw $exception; } } diff --git a/lib/WebDriver.php b/lib/WebDriver.php index 85e8c1931..48aeefa6b 100755 --- a/lib/WebDriver.php +++ b/lib/WebDriver.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Interactions\Touch\WebDriverTouchScreen; + /** * The interface for WebDriver. */ @@ -126,6 +128,11 @@ public function navigate(); */ public function switchTo(); + /** + * @return WebDriverTouchScreen + */ + public function getTouch(); + /** * @param string $name * @param array $params diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index 0c70026f2..930a13733 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -51,7 +51,7 @@ protected function __construct(callable $apply) * An expectation for checking the title of a page. * * @param string $title The expected title, which must be an exact match. - * @return bool WebDriverExpectedCondition True when the title matches, false otherwise. + * @return WebDriverExpectedCondition Condition returns whether current page title equals given string. */ public static function titleIs($title) { @@ -66,7 +66,7 @@ function (WebDriver $driver) use ($title) { * An expectation for checking substring of a page Title. * * @param string $title The expected substring of Title. - * @return bool WebDriverExpectedCondition True when in title, false otherwise. + * @return WebDriverExpectedCondition Condition returns whether current page title contains given string. */ public static function titleContains($title) { @@ -81,7 +81,8 @@ function (WebDriver $driver) use ($title) { * An expectation for checking current page title matches the given regular expression. * * @param string $titleRegexp The regular expression to test against. - * @return bool WebDriverExpectedCondition True when in title, false otherwise. + * @return WebDriverExpectedCondition Condition returns whether current page title matches the regular + * expression. */ public static function titleMatches($titleRegexp) { @@ -96,7 +97,7 @@ function (WebDriver $driver) use ($titleRegexp) { * An expectation for checking the URL of a page. * * @param string $url The expected URL, which must be an exact match. - * @return bool WebDriverExpectedCondition True when the URL matches, false otherwise. + * @return WebDriverExpectedCondition Condition returns whether current URL equals given one. */ public static function urlIs($url) { @@ -111,7 +112,7 @@ function (WebDriver $driver) use ($url) { * An expectation for checking substring of the URL of a page. * * @param string $url The expected substring of the URL - * @return bool WebDriverExpectedCondition True when in URL, false otherwise. + * @return WebDriverExpectedCondition Condition returns whether current URL contains given string. */ public static function urlContains($url) { @@ -126,7 +127,7 @@ function (WebDriver $driver) use ($url) { * An expectation for checking current page URL matches the given regular expression. * * @param string $urlRegexp The regular expression to test against. - * @return bool WebDriverExpectedCondition True when in url, false otherwise. + * @return WebDriverExpectedCondition Condition returns whether current URL matches the regular expression. */ public static function urlMatches($urlRegexp) { @@ -142,7 +143,7 @@ function (WebDriver $driver) use ($urlRegexp) { * This does not necessarily mean that the element is visible. * * @param WebDriverBy $by The locator used to find the element. - * @return WebDriverExpectedCondition The element which is located. + * @return WebDriverExpectedCondition Condition returns the element which is located. */ public static function presenceOfElementLocated(WebDriverBy $by) { @@ -157,7 +158,7 @@ function (WebDriver $driver) use ($by) { * An expectation for checking that there is at least one element present on a web page. * * @param WebDriverBy $by The locator used to find the element. - * @return WebDriverExpectedCondition An array of WebDriverElements once they are located. + * @return WebDriverExpectedCondition Condition returns an array of WebDriverElements once they are located. */ public static function presenceOfAllElementsLocatedBy(WebDriverBy $by) { @@ -175,7 +176,7 @@ function (WebDriver $driver) use ($by) { * Visibility means that the element is not only displayed but also has a height and width that is greater than 0. * * @param WebDriverBy $by The locator used to find the element. - * @return WebDriverExpectedCondition The element which is located and visible. + * @return WebDriverExpectedCondition Condition returns the element which is located and visible. */ public static function visibilityOfElementLocated(WebDriverBy $by) { @@ -197,7 +198,8 @@ function (WebDriver $driver) use ($by) { * Visibility means that the element is not only displayed but also has a height and width that is greater than 0. * * @param WebDriverElement $element The element to be checked. - * @return WebDriverExpectedCondition The same WebDriverElement once it is visible. + * @return WebDriverExpectedCondition Condition returns the same WebDriverElement once it is + * visible. */ public static function visibilityOf(WebDriverElement $element) { @@ -216,7 +218,7 @@ function () use ($element) { * @deprecated Use WebDriverExpectedCondition::elementTextContains() instead * @param WebDriverBy $by The locator used to find the element. * @param string $text The text to be presented in the element. - * @return bool WebDriverExpectedCondition Whether the text is present. + * @return WebDriverExpectedCondition Condition returns whether the text is present in the element. */ public static function textToBePresentInElement(WebDriverBy $by, $text) { @@ -229,7 +231,7 @@ public static function textToBePresentInElement(WebDriverBy $by, $text) * * @param WebDriverBy $by The locator used to find the element. * @param string $text The text to be presented in the element. - * @return bool WebDriverExpectedCondition Whether the text is present. + * @return WebDriverExpectedCondition Condition returns whether the partial text is present in the element. */ public static function elementTextContains(WebDriverBy $by, $text) { @@ -252,7 +254,7 @@ function (WebDriver $driver) use ($by, $text) { * * @param WebDriverBy $by The locator used to find the element. * @param string $text The expected text of the element. - * @return bool WebDriverExpectedCondition True when element has text value equal to given one + * @return WebDriverExpectedCondition Condition returns whether the element has text value equal to given one. */ public static function elementTextIs(WebDriverBy $by, $text) { @@ -272,7 +274,7 @@ function (WebDriver $driver) use ($by, $text) { * * @param WebDriverBy $by The locator used to find the element. * @param string $regexp The regular expression to test against. - * @return bool WebDriverExpectedCondition True when element has text value equal to given one + * @return WebDriverExpectedCondition Condition returns whether the element has text value equal to given one. */ public static function elementTextMatches(WebDriverBy $by, $regexp) { @@ -292,7 +294,7 @@ function (WebDriver $driver) use ($by, $regexp) { * * @param WebDriverBy $by The locator used to find the element. * @param string $text The text to be presented in the element value. - * @return bool WebDriverExpectedCondition Whether the text is presented. + * @return WebDriverExpectedCondition Condition returns whether the text is present in value attribute. */ public static function textToBePresentInElementValue(WebDriverBy $by, $text) { @@ -314,8 +316,8 @@ function (WebDriver $driver) use ($by, $text) { * * @param string $frame_locator The locator used to find the iFrame * expected to be either the id or name value of the i/frame - * @return WebDriverExpectedCondition object focused on new frame - * when frame is found bool false otherwise + * @return WebDriverExpectedCondition Condition returns object focused on new frame when frame is + * found, false otherwise. */ public static function frameToBeAvailableAndSwitchToIt($frame_locator) { @@ -334,7 +336,7 @@ function (WebDriver $driver) use ($frame_locator) { * An expectation for checking that an element is either invisible or not present on the DOM. * * @param WebDriverBy $by The locator used to find the element. - * @return bool WebDriverExpectedCondition Whether there is no element located. + * @return WebDriverExpectedCondition Condition returns whether no visible element located. */ public static function invisibilityOfElementLocated(WebDriverBy $by) { @@ -356,7 +358,7 @@ function (WebDriver $driver) use ($by) { * * @param WebdriverBy $by The locator used to find the element. * @param string $text The text of the element. - * @return bool WebDriverExpectedCondition Whether the text is found in the element located. + * @return WebDriverExpectedCondition Condition returns whether the text is found in the element located. */ public static function invisibilityOfElementWithText(WebDriverBy $by, $text) { @@ -377,8 +379,8 @@ function (WebDriver $driver) use ($by, $text) { * An expectation for checking an element is visible and enabled such that you can click it. * * @param WebDriverBy $by The locator used to find the element - * @return WebDriverExpectedCondition The WebDriverElement - * once it is located, visible and clickable + * @return WebDriverExpectedCondition Condition return the WebDriverElement once it is located, + * visible and clickable. */ public static function elementToBeClickable(WebDriverBy $by) { @@ -408,7 +410,7 @@ function (WebDriver $driver) use ($visibility_of_element_located) { * Wait until an element is no longer attached to the DOM. * * @param WebDriverElement $element The element to wait for. - * @return bool WebDriverExpectedCondition false if the element is still attached to the DOM, true otherwise. + * @return WebDriverExpectedCondition Condition returns whether the element is still attached to the DOM. */ public static function stalenessOf(WebDriverElement $element) { @@ -434,7 +436,8 @@ function () use ($element) { * the condition is checked. * * @param WebDriverExpectedCondition $condition The condition wrapped. - * @return WebDriverExpectedCondition The return value of the getApply() of the given condition. + * @return WebDriverExpectedCondition Condition returns the return value of the getApply() of the given + * condition. */ public static function refreshed(WebDriverExpectedCondition $condition) { @@ -453,7 +456,7 @@ function (WebDriver $driver) use ($condition) { * An expectation for checking if the given element is selected. * * @param mixed $element_or_by Either the element or the locator. - * @return bool WebDriverExpectedCondition whether the element is selected. + * @return WebDriverExpectedCondition Condition returns whether the element is selected. */ public static function elementToBeSelected($element_or_by) { @@ -468,7 +471,7 @@ public static function elementToBeSelected($element_or_by) * * @param mixed $element_or_by Either the element or the locator. * @param bool $selected The required state. - * @return bool WebDriverExpectedCondition Whether the element is selected. + * @return WebDriverExpectedCondition Condition returns whether the element is selected. */ public static function elementSelectionStateToBe($element_or_by, $selected) { @@ -498,7 +501,8 @@ function (WebDriver $driver) use ($element_or_by, $selected) { /** * An expectation for whether an alert() box is present. * - * @return WebDriverExpectedCondition if alert() is present, null otherwise. + * @return WebDriverExpectedCondition Condition returns WebDriverAlert if alert() is present, + * null otherwise. */ public static function alertIsPresent() { diff --git a/tests/unit/Exception/WebDriverExceptionTest.php b/tests/unit/Exception/WebDriverExceptionTest.php index fb25eced2..1dfd94fac 100644 --- a/tests/unit/Exception/WebDriverExceptionTest.php +++ b/tests/unit/Exception/WebDriverExceptionTest.php @@ -35,7 +35,7 @@ public function testShouldThrowProperExceptionBasedOnSeleniumStatusCode($statusC { try { WebDriverException::throwException($statusCode, 'exception message', ['results']); - } catch (\Exception $e) { + } catch (WebDriverException $e) { $this->assertInstanceOf($expectedExceptionType, $e); $this->assertSame('exception message', $e->getMessage()); From 4066768b1a1e6e29a5f2b3eabd22349543dd97a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 13 Jan 2017 15:47:37 +0100 Subject: [PATCH 287/784] We should not change WebDriver interface (it would be an BC break) --- lib/WebDriver.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/WebDriver.php b/lib/WebDriver.php index 48aeefa6b..1c5b59418 100755 --- a/lib/WebDriver.php +++ b/lib/WebDriver.php @@ -130,8 +130,9 @@ public function switchTo(); /** * @return WebDriverTouchScreen + * @todo Add in next major release (BC) */ - public function getTouch(); + //public function getTouch(); /** * @param string $name From cd4f352735552cb36bfcdb5f314846b8c34a32ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 13 Jan 2017 16:08:59 +0100 Subject: [PATCH 288/784] Also do not change RemoteWebDriver interface (it would be an BC break as well) --- lib/Remote/RemoteWebDriver.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index c2ecd8d37..6942c117a 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -20,6 +20,7 @@ use Facebook\WebDriver\WebDriver; use Facebook\WebDriver\WebDriverBy; use Facebook\WebDriver\WebDriverCapabilities; +use Facebook\WebDriver\WebDriverCommandExecutor; use Facebook\WebDriver\WebDriverElement; use Facebook\WebDriver\WebDriverHasInputDevices; use Facebook\WebDriver\WebDriverNavigation; @@ -507,10 +508,10 @@ protected function newElement($id) * @deprecated To be removed in the future. Executor should be passed in the constructor. * @internal * @codeCoverageIgnore - * @param HttpCommandExecutor $executor + * @param WebDriverCommandExecutor $executor Despite the typehint, it have be an instance of HttpCommandExecutor. * @return RemoteWebDriver */ - public function setCommandExecutor(HttpCommandExecutor $executor) + public function setCommandExecutor(WebDriverCommandExecutor $executor) { $this->executor = $executor; From 77300c4ab2025d4316635f592ec849ca7323bd8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 13 Jan 2017 16:48:08 +0100 Subject: [PATCH 289/784] Release version 1.3.0 --- CHANGELOG.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 112936c86..04ce2d4dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased + +## 1.3.0 - 2017-01-13 ### Added - Added `getCapabilities()` method of `RemoteWebDriver`, to retrieve actual capabilities acknowledged by the remote driver on startup. - Added option to pass required capabilities when creating `RemoteWebDriver`. (So far only desired capabilities were supported.) @@ -14,7 +16,7 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). - `elementTextContains` (as an alias for `textToBePresentInElement`) - text in element contains given text - `elementTextMatches` - text in element matches regular expression - `numberOfWindowsToBe` - number of opened windows equals given number -- Possibility to select option of `` by its partial text (using `selectByVisiblePartialText()`). - `XPathEscaper` helper class to quote XPaths containing both single and double quotes. - `WebDriverSelectInterface`, to allow implementation of custom select-like components, eg. those not built around and actual select tag. @@ -22,7 +24,7 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). - `Symfony\Process` is used to start local WebDriver processes (when browsers are run directly, without Selenium server) to workaround some PHP bugs and improve portability. - Clarified meaning of selenium server URL variable in methods of `RemoteWebDriver` class. - Deprecated `setSessionID()` and `setCommandExecutor()` methods of `RemoteWebDriver` class; these values should be immutable and thus passed only via constructor. -- Deprecated `WebDriverExpectedCondition::textToBePresentInElement()` in favor of `elementTextContains()` +- Deprecated `WebDriverExpectedCondition::textToBePresentInElement()` in favor of `elementTextContains()`. - Throw an exception when attempting to deselect options of non-multiselect (it already didn't have any effect, but was silently ignored). - Optimize performance of `(de)selectByIndex()` and `getAllSelectedOptions()` methods of `WebDriverSelect` when used with non-multiple select element. From 62223d89bcdd4f755a62b2fbc193122e880c41fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 15 Jan 2017 00:50:02 +0100 Subject: [PATCH 290/784] Minor codestyle fixes --- lib/Remote/HttpCommandExecutor.php | 2 +- lib/Remote/RemoteTargetLocator.php | 2 +- lib/Support/Events/EventFiringWebDriver.php | 16 ++++++++-------- .../Events/EventFiringWebDriverNavigation.php | 12 ++++++++---- lib/WebDriverDispatcher.php | 2 +- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/lib/Remote/HttpCommandExecutor.php b/lib/Remote/HttpCommandExecutor.php index defb51669..2f6c1778f 100644 --- a/lib/Remote/HttpCommandExecutor.php +++ b/lib/Remote/HttpCommandExecutor.php @@ -154,7 +154,7 @@ public function __construct($url, $http_proxy = null, $http_proxy_port = null) if (!empty($http_proxy)) { curl_setopt($this->curl, CURLOPT_PROXY, $http_proxy); - if (!empty($http_proxy_port)) { + if ($http_proxy_port !== null) { curl_setopt($this->curl, CURLOPT_PROXYPORT, $http_proxy_port); } } diff --git a/lib/Remote/RemoteTargetLocator.php b/lib/Remote/RemoteTargetLocator.php index 9b4fe2526..5c218075d 100644 --- a/lib/Remote/RemoteTargetLocator.php +++ b/lib/Remote/RemoteTargetLocator.php @@ -79,7 +79,7 @@ public function frame($frame) * Switch the focus to another window by its handle. * * @param string $handle The handle of the window to be focused on. - * @return WebDriver Tge driver focused on the given window. + * @return WebDriver The driver focused on the given window. * @see WebDriver::getWindowHandles */ public function window($handle) diff --git a/lib/Support/Events/EventFiringWebDriver.php b/lib/Support/Events/EventFiringWebDriver.php index 34514e9cd..0dd805bcb 100644 --- a/lib/Support/Events/EventFiringWebDriver.php +++ b/lib/Support/Events/EventFiringWebDriver.php @@ -398,14 +398,6 @@ public function getTouch() } } - /** - * @param WebDriverException $exception - */ - private function dispatchOnException(WebDriverException $exception) - { - $this->dispatch('onException', $exception, $this); - } - public function execute($name, $params) { try { @@ -415,4 +407,12 @@ public function execute($name, $params) throw $exception; } } + + /** + * @param WebDriverException $exception + */ + private function dispatchOnException(WebDriverException $exception) + { + $this->dispatch('onException', $exception, $this); + } } diff --git a/lib/Support/Events/EventFiringWebDriverNavigation.php b/lib/Support/Events/EventFiringWebDriverNavigation.php index a588d5e17..34bc196ae 100644 --- a/lib/Support/Events/EventFiringWebDriverNavigation.php +++ b/lib/Support/Events/EventFiringWebDriverNavigation.php @@ -38,8 +38,6 @@ public function __construct(WebDriverNavigation $navigator, WebDriverDispatcher { $this->navigator = $navigator; $this->dispatcher = $dispatcher; - - return $this; } /** @@ -130,6 +128,7 @@ public function refresh() return $this; } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } } @@ -145,11 +144,14 @@ public function to($url) $url, $this->getDispatcher()->getDefaultDriver() ); + try { $this->navigator->to($url); } catch (WebDriverException $exception) { $this->dispatchOnException($exception); + throw $exception; } + $this->dispatch( 'afterNavigateTo', $url, @@ -159,9 +161,11 @@ public function to($url) return $this; } - private function dispatchOnException($exception) + /** + * @param WebDriverException $exception + */ + private function dispatchOnException(WebDriverException $exception) { $this->dispatch('onException', $exception); - throw $exception; } } diff --git a/lib/WebDriverDispatcher.php b/lib/WebDriverDispatcher.php index 782c84690..65e0f688d 100644 --- a/lib/WebDriverDispatcher.php +++ b/lib/WebDriverDispatcher.php @@ -26,7 +26,7 @@ class WebDriverDispatcher /** * @var EventFiringWebDriver */ - protected $driver = null; + protected $driver; /** * this is needed so that EventFiringWebElement can pass the driver to the From 43e17c76e23bf927836ff03ea72a46dd4fc321cc Mon Sep 17 00:00:00 2001 From: trotskyist Date: Wed, 3 Jun 2015 13:58:07 -0400 Subject: [PATCH 291/784] Fix an apparent typo in the doc comment to window() method --- lib/WebDriverTargetLocator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/WebDriverTargetLocator.php b/lib/WebDriverTargetLocator.php index d9fdf5c18..e6e5dabc5 100644 --- a/lib/WebDriverTargetLocator.php +++ b/lib/WebDriverTargetLocator.php @@ -41,7 +41,7 @@ public function frame($frame); * Switch the focus to another window by its handle. * * @param string $handle The handle of the window to be focused on. - * @return WebDriver Tge driver focused on the given window. + * @return WebDriver The driver focused on the given window. * @see WebDriver::getWindowHandles */ public function window($handle); From 232684ee8ad676618733c918a0d668e02d6bd339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 15 Jan 2017 13:14:39 +0100 Subject: [PATCH 292/784] Upgrade php-cs-fixer to version 2.0 --- .php_cs | 65 ------------------------------------------------ .php_cs.dist | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++ composer.json | 4 +-- 3 files changed, 71 insertions(+), 67 deletions(-) delete mode 100644 .php_cs create mode 100644 .php_cs.dist diff --git a/.php_cs b/.php_cs deleted file mode 100644 index 0466edfbe..000000000 --- a/.php_cs +++ /dev/null @@ -1,65 +0,0 @@ -in([__DIR__ . '/lib', __DIR__ . '/tests']); - -return Symfony\CS\Config\Config::create() - ->fixers([ - 'array_element_white_space_after_comma', - 'duplicate_semicolon', - 'extra_empty_lines', - 'function_typehint_space', - 'lowercase_cast', - 'method_argument_default_value', - 'multiline_array_trailing_comma', - 'namespace_no_leading_whitespace', - 'native_function_casing', - 'new_with_braces', - 'no_blank_lines_after_class_opening', - 'no_empty_lines_after_phpdocs', - 'no_empty_phpdoc', - 'no_empty_statement', - 'object_operator', - 'operators_spaces', - 'trim_array_spaces', - 'phpdoc_indent', - 'phpdoc_no_access', - 'phpdoc_no_empty_return', - 'phpdoc_no_package', - 'phpdoc_scalar', - 'phpdoc_single_line_var_spacing', - 'phpdoc_trim', - 'phpdoc_types', - 'phpdoc_order', - 'unused_use', - 'ordered_use', - 'remove_leading_slash_use', - 'remove_lines_between_uses', - 'return', - 'self_accessor', - 'single_array_no_trailing_comma', - 'single_blank_line_before_namespace', - 'single_quote', - 'spaces_after_semicolon', - 'spaces_before_semicolon', - 'spaces_cast', - 'standardize_not_equal', - 'ternary_spaces', - 'trim_array_spaces', - 'unary_operators_spaces', - 'unused_use', - 'whitespacy_lines', - - // additional contrib checks - 'concat_with_spaces', - 'newline_after_open_tag', - 'no_useless_else', - 'no_useless_return', - 'php_unit_construct', - 'php_unit_dedicate_assert', - 'phpdoc_order', - 'short_array_syntax', - ]) - ->level(Symfony\CS\FixerInterface::PSR2_LEVEL) - ->setUsingCache(true) - ->finder($finder); diff --git a/.php_cs.dist b/.php_cs.dist new file mode 100644 index 000000000..deb2dc803 --- /dev/null +++ b/.php_cs.dist @@ -0,0 +1,69 @@ +in([__DIR__ . '/lib', __DIR__ . '/tests']); + +return PhpCsFixer\Config::create() + ->setRules([ + '@PSR2' => true, + 'array_syntax' => ['syntax' => 'short'], + 'binary_operator_spaces' => true, + 'blank_line_before_return' => true, + 'cast_spaces' => true, + 'concat_space' => ['spacing' => 'one'], + 'function_typehint_space' => true, + 'linebreak_after_opening_tag' => true, + 'lowercase_cast' => true, + 'native_function_casing' => true, + 'new_with_braces' => true, + 'no_blank_lines_after_class_opening' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_empty_phpdoc' => true, + 'no_empty_statement' => true, + 'no_extra_consecutive_blank_lines' => [ + 'use', + 'break', + 'continue', + 'extra', + 'return', + 'throw', + 'useTrait', + 'curly_brace_block', + 'parenthesis_brace_block', + 'square_brace_block', + ], + 'no_leading_import_slash' => true, + 'no_leading_namespace_whitespace' => true, + 'no_singleline_whitespace_before_semicolons' => true, + 'no_trailing_comma_in_singleline_array' => true, + 'no_unreachable_default_argument_value' => true, + 'no_unused_imports' => true, + 'no_useless_else' => true, + 'no_useless_return' => true, + 'no_whitespace_in_blank_line' => true, + 'object_operator_without_whitespace' => true, + 'ordered_imports' => true, + 'php_unit_construct' => true, + 'php_unit_dedicate_assert' => true, + 'phpdoc_indent' => true, + 'phpdoc_no_access' => true, + 'phpdoc_no_empty_return' => true, + 'phpdoc_no_package' => true, + 'phpdoc_order' => true, + 'phpdoc_scalar' => true, + 'phpdoc_single_line_var_spacing' => true, + 'phpdoc_trim' => true, + 'phpdoc_types' => true, + 'self_accessor' => true, + 'single_blank_line_before_namespace' => true, + 'single_quote' => true, + 'space_after_semicolon' => true, + 'standardize_not_equals' => true, + 'ternary_operator_spaces' => true, + 'trailing_comma_in_multiline_array' => true, + 'trim_array_spaces' => true, + 'unary_operator_spaces' => true, + 'whitespace_after_comma_in_array' => true, + ]) + ->setRiskyAllowed(true) + ->setFinder($finder); diff --git a/composer.json b/composer.json index 55780368b..557b0c908 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "facebook/webdriver", - "description": "A PHP client for WebDriver", + "description": "A PHP client for Selenium WebDriver", "keywords": ["webdriver", "selenium", "php", "facebook"], "homepage": "https://github.com/facebook/php-webdriver", "type": "library", @@ -17,7 +17,7 @@ }, "require-dev": { "phpunit/phpunit": "4.6.* || ~5.0", - "friendsofphp/php-cs-fixer": "^1.11", + "friendsofphp/php-cs-fixer": "^2.0", "squizlabs/php_codesniffer": "^2.6", "php-mock/php-mock-phpunit": "^1.1", "satooshi/php-coveralls": "^1.0" From 3e64225dad97b72551e48eb85a63b526acd51b2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 15 Jan 2017 13:34:38 +0100 Subject: [PATCH 293/784] Add new php-cs-fixer checks; use multibyte string functions --- .php_cs.dist | 7 +++++++ lib/Chrome/ChromeDriver.php | 8 ++++++++ lib/Firefox/FirefoxProfile.php | 2 +- lib/Remote/RemoteWebElement.php | 2 +- lib/Support/XPathEscaper.php | 4 ++-- lib/WebDriver.php | 8 ++++---- lib/WebDriverExpectedCondition.php | 8 ++++---- lib/WebDriverOptions.php | 4 ++-- lib/WebDriverWindow.php | 2 +- 9 files changed, 30 insertions(+), 15 deletions(-) diff --git a/.php_cs.dist b/.php_cs.dist index deb2dc803..0d4568a4b 100644 --- a/.php_cs.dist +++ b/.php_cs.dist @@ -14,10 +14,14 @@ return PhpCsFixer\Config::create() 'function_typehint_space' => true, 'linebreak_after_opening_tag' => true, 'lowercase_cast' => true, + 'mb_str_functions' => true, + 'method_separation' => true, 'native_function_casing' => true, 'new_with_braces' => true, + 'no_alias_functions' => true, 'no_blank_lines_after_class_opening' => true, 'no_blank_lines_after_phpdoc' => true, + 'no_empty_comment' => true, 'no_empty_phpdoc' => true, 'no_empty_statement' => true, 'no_extra_consecutive_blank_lines' => [ @@ -45,6 +49,7 @@ return PhpCsFixer\Config::create() 'ordered_imports' => true, 'php_unit_construct' => true, 'php_unit_dedicate_assert' => true, + 'phpdoc_add_missing_param_annotation' => true, 'phpdoc_indent' => true, 'phpdoc_no_access' => true, 'phpdoc_no_empty_return' => true, @@ -54,7 +59,9 @@ return PhpCsFixer\Config::create() 'phpdoc_single_line_var_spacing' => true, 'phpdoc_trim' => true, 'phpdoc_types' => true, + 'psr4' => true, 'self_accessor' => true, + 'short_scalar_cast' => true, 'single_blank_line_before_namespace' => true, 'single_quote' => true, 'space_after_semicolon' => true, diff --git a/lib/Chrome/ChromeDriver.php b/lib/Chrome/ChromeDriver.php index 249c4f1b5..8ba76583c 100644 --- a/lib/Chrome/ChromeDriver.php +++ b/lib/Chrome/ChromeDriver.php @@ -55,7 +55,15 @@ public function startSession(DesiredCapabilities $desired_capabilities) /** * Always throws an exception. Use ChromeDriver::start() instead. * + * @param string $selenium_server_url + * @param DesiredCapabilities|array $desired_capabilities + * @param int|null $connection_timeout_in_ms + * @param int|null $request_timeout_in_ms + * @param string|null $http_proxy + * @param int|null $http_proxy_port + * @param DesiredCapabilities $required_capabilities * @throws WebDriverException + * @return RemoteWebDriver */ public static function create( $selenium_server_url = 'http://localhost:4444/wd/hub', diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index 00dcebd5c..8086198ca 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -211,7 +211,7 @@ private function installExtension($extension, $profile_dir) $prefix = ''; if (!empty($ns)) { foreach ($ns as $key => $value) { - if (strpos($value, '//www.mozilla.org/2004/em-rdf') > 0) { + if (mb_strpos($value, '//www.mozilla.org/2004/em-rdf') > 0) { if ($key != '') { $prefix = $key . ':'; // Separate the namespace from the name. } diff --git a/lib/Remote/RemoteWebElement.php b/lib/Remote/RemoteWebElement.php index dfc66d124..a7fbf6834 100644 --- a/lib/Remote/RemoteWebElement.php +++ b/lib/Remote/RemoteWebElement.php @@ -254,7 +254,7 @@ public function getTagName() // until this issue is not resolved : // https://github.com/operasoftware/operadriver/issues/102 // Remove it when fixed to be consistent with the protocol. - return strtolower($this->executor->execute( + return mb_strtolower($this->executor->execute( DriverCommand::GET_ELEMENT_TAG_NAME, [':id' => $this->id] )); diff --git a/lib/Support/XPathEscaper.php b/lib/Support/XPathEscaper.php index 10271128c..dc5907f01 100644 --- a/lib/Support/XPathEscaper.php +++ b/lib/Support/XPathEscaper.php @@ -27,12 +27,12 @@ class XPathEscaper public static function escapeQuotes($xpathToEscape) { // Single quotes not present => we can quote in them - if (strpos($xpathToEscape, "'") === false) { + if (mb_strpos($xpathToEscape, "'") === false) { return sprintf("'%s'", $xpathToEscape); } // Double quotes not present => we can quote in them - if (strpos($xpathToEscape, '"') === false) { + if (mb_strpos($xpathToEscape, '"') === false) { return sprintf('"%s"', $xpathToEscape); } diff --git a/lib/WebDriver.php b/lib/WebDriver.php index 1c5b59418..ea413f883 100755 --- a/lib/WebDriver.php +++ b/lib/WebDriver.php @@ -128,10 +128,10 @@ public function navigate(); */ public function switchTo(); - /** - * @return WebDriverTouchScreen - * @todo Add in next major release (BC) - */ + ///** + // * @return WebDriverTouchScreen + // * @todo Add in next major release (BC) + // */ //public function getTouch(); /** diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index 930a13733..baee93e85 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -72,7 +72,7 @@ public static function titleContains($title) { return new static( function (WebDriver $driver) use ($title) { - return strpos($driver->getTitle(), $title) !== false; + return mb_strpos($driver->getTitle(), $title) !== false; } ); } @@ -118,7 +118,7 @@ public static function urlContains($url) { return new static( function (WebDriver $driver) use ($url) { - return strpos($driver->getCurrentURL(), $url) !== false; + return mb_strpos($driver->getCurrentURL(), $url) !== false; } ); } @@ -240,7 +240,7 @@ function (WebDriver $driver) use ($by, $text) { try { $element_text = $driver->findElement($by)->getText(); - return strpos($element_text, $text) !== false; + return mb_strpos($element_text, $text) !== false; } catch (StaleElementReferenceException $e) { return null; } @@ -303,7 +303,7 @@ function (WebDriver $driver) use ($by, $text) { try { $element_text = $driver->findElement($by)->getAttribute('value'); - return strpos($element_text, $text) !== false; + return mb_strpos($element_text, $text) !== false; } catch (StaleElementReferenceException $e) { return null; } diff --git a/lib/WebDriverOptions.php b/lib/WebDriverOptions.php index fef36f695..bdf4db2ae 100644 --- a/lib/WebDriverOptions.php +++ b/lib/WebDriverOptions.php @@ -123,7 +123,7 @@ private function validate(array $cookie) { if (!isset($cookie['name']) || $cookie['name'] === '' || - strpos($cookie['name'], ';') !== false + mb_strpos($cookie['name'], ';') !== false ) { throw new InvalidArgumentException( '"name" should be non-empty and does not contain a ";"' @@ -136,7 +136,7 @@ private function validate(array $cookie) ); } - if (isset($cookie['domain']) && strpos($cookie['domain'], ':') !== false) { + if (isset($cookie['domain']) && mb_strpos($cookie['domain'], ':') !== false) { throw new InvalidArgumentException( '"domain" should not contain a port:' . (string) $cookie['domain'] ); diff --git a/lib/WebDriverWindow.php b/lib/WebDriverWindow.php index d48a70773..6b9090a99 100644 --- a/lib/WebDriverWindow.php +++ b/lib/WebDriverWindow.php @@ -145,7 +145,7 @@ public function getScreenOrientation() */ public function setScreenOrientation($orientation) { - $orientation = strtoupper($orientation); + $orientation = mb_strtoupper($orientation); if (!in_array($orientation, ['PORTRAIT', 'LANDSCAPE'])) { throw new IndexOutOfBoundsException( 'Orientation must be either PORTRAIT, or LANDSCAPE' From 04aab9f79dc5ac34d1c727fff46fc491350b4c7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 15 Jan 2017 13:42:38 +0100 Subject: [PATCH 294/784] Rearrange class methods order to match the standard one (public > protected > private) --- .php_cs.dist | 1 + lib/Remote/DesiredCapabilities.php | 48 +++---- lib/Remote/RemoteWebDriver.php | 132 +++++++++--------- lib/Remote/RemoteWebElement.php | 72 +++++----- lib/Support/Events/EventFiringWebDriver.php | 48 +++---- .../Events/EventFiringWebDriverNavigation.php | 30 ++-- lib/Support/Events/EventFiringWebElement.php | 46 +++--- lib/WebDriverExpectedCondition.php | 10 +- lib/WebDriverOptions.php | 45 +++--- 9 files changed, 214 insertions(+), 218 deletions(-) diff --git a/.php_cs.dist b/.php_cs.dist index 0d4568a4b..c40510179 100644 --- a/.php_cs.dist +++ b/.php_cs.dist @@ -46,6 +46,7 @@ return PhpCsFixer\Config::create() 'no_useless_return' => true, 'no_whitespace_in_blank_line' => true, 'object_operator_without_whitespace' => true, + 'ordered_class_elements' => true, 'ordered_imports' => true, 'php_unit_construct' => true, 'php_unit_dedicate_assert' => true, diff --git a/lib/Remote/DesiredCapabilities.php b/lib/Remote/DesiredCapabilities.php index badd04313..12060ab7b 100644 --- a/lib/Remote/DesiredCapabilities.php +++ b/lib/Remote/DesiredCapabilities.php @@ -175,30 +175,6 @@ public function toArray() return $this->capabilities; } - /** - * @param string $key - * @param mixed $value - * @return DesiredCapabilities - */ - private function set($key, $value) - { - $this->capabilities[$key] = $value; - - return $this; - } - - /** - * @param string $key - * @param mixed $default - * @return mixed - */ - private function get($key, $default = null) - { - return isset($this->capabilities[$key]) - ? $this->capabilities[$key] - : $default; - } - /** * @return DesiredCapabilities */ @@ -339,4 +315,28 @@ public static function phantomjs() WebDriverCapabilityType::PLATFORM => WebDriverPlatform::ANY, ]); } + + /** + * @param string $key + * @param mixed $value + * @return DesiredCapabilities + */ + private function set($key, $value) + { + $this->capabilities[$key] = $value; + + return $this; + } + + /** + * @param string $key + * @param mixed $default + * @return mixed + */ + private function get($key, $default = null) + { + return isset($this->capabilities[$key]) + ? $this->capabilities[$key] + : $default; + } } diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index 6942c117a..a06beb132 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -126,26 +126,6 @@ public static function create( return $driver; } - /** - * Cast legacy types (array or null) to DesiredCapabilities object. To be removed in future when instance of - * DesiredCapabilities will be required. - * - * @param array|DesiredCapabilities|null $desired_capabilities - * @return DesiredCapabilities - */ - protected static function castToDesiredCapabilitiesObject($desired_capabilities = null) - { - if ($desired_capabilities === null) { - return new DesiredCapabilities(); - } - - if (is_array($desired_capabilities)) { - return new DesiredCapabilities($desired_capabilities); - } - - return $desired_capabilities; - } - /** * [Experimental] Construct the RemoteWebDriver by an existing session. * @@ -293,29 +273,6 @@ public function quit() $this->executor = null; } - /** - * Prepare arguments for JavaScript injection - * - * @param array $arguments - * @return array - */ - private function prepareScriptArguments(array $arguments) - { - $args = []; - foreach ($arguments as $key => $value) { - if ($value instanceof WebDriverElement) { - $args[$key] = ['ELEMENT' => $value->getID()]; - } else { - if (is_array($value)) { - $value = $this->prepareScriptArguments($value); - } - $args[$key] = $value; - } - } - - return $args; - } - /** * Inject a snippet of JavaScript into the page for execution in the context * of the currently selected frame. The executed script is assumed to be @@ -469,18 +426,6 @@ public function getTouch() return $this->touch; } - /** - * @return RemoteExecuteMethod - */ - protected function getExecuteMethod() - { - if (!$this->executeMethod) { - $this->executeMethod = new RemoteExecuteMethod($this); - } - - return $this->executeMethod; - } - /** * Construct a new action builder. * @@ -491,17 +436,6 @@ public function action() return new WebDriverActions($this); } - /** - * Return the WebDriverElement with the given id. - * - * @param string $id The id of the element to be created. - * @return RemoteWebElement - */ - protected function newElement($id) - { - return new RemoteWebElement($this->getExecuteMethod(), $id); - } - /** * Set the command executor of this RemoteWebdriver * @@ -601,4 +535,70 @@ public function execute($command_name, $params = []) return null; } + + /** + * Prepare arguments for JavaScript injection + * + * @param array $arguments + * @return array + */ + protected function prepareScriptArguments(array $arguments) + { + $args = []; + foreach ($arguments as $key => $value) { + if ($value instanceof WebDriverElement) { + $args[$key] = ['ELEMENT' => $value->getID()]; + } else { + if (is_array($value)) { + $value = $this->prepareScriptArguments($value); + } + $args[$key] = $value; + } + } + + return $args; + } + + /** + * @return RemoteExecuteMethod + */ + protected function getExecuteMethod() + { + if (!$this->executeMethod) { + $this->executeMethod = new RemoteExecuteMethod($this); + } + + return $this->executeMethod; + } + + /** + * Return the WebDriverElement with the given id. + * + * @param string $id The id of the element to be created. + * @return RemoteWebElement + */ + protected function newElement($id) + { + return new RemoteWebElement($this->getExecuteMethod(), $id); + } + + /** + * Cast legacy types (array or null) to DesiredCapabilities object. To be removed in future when instance of + * DesiredCapabilities will be required. + * + * @param array|DesiredCapabilities|null $desired_capabilities + * @return DesiredCapabilities + */ + protected static function castToDesiredCapabilitiesObject($desired_capabilities = null) + { + if ($desired_capabilities === null) { + return new DesiredCapabilities(); + } + + if (is_array($desired_capabilities)) { + return new DesiredCapabilities($desired_capabilities); + } + + return $desired_capabilities; + } } diff --git a/lib/Remote/RemoteWebElement.php b/lib/Remote/RemoteWebElement.php index a7fbf6834..c10bfbf32 100644 --- a/lib/Remote/RemoteWebElement.php +++ b/lib/Remote/RemoteWebElement.php @@ -342,42 +342,6 @@ public function sendKeys($value) return $this; } - /** - * Upload a local file to the server - * - * @param string $local_file - * - * @throws WebDriverException - * @return string The remote path of the file. - */ - private function upload($local_file) - { - if (!is_file($local_file)) { - throw new WebDriverException('You may only upload files: ' . $local_file); - } - - // Create a temporary file in the system temp directory. - $temp_zip = tempnam(sys_get_temp_dir(), 'WebDriverZip'); - $zip = new ZipArchive(); - if ($zip->open($temp_zip, ZipArchive::CREATE) !== true) { - return false; - } - $info = pathinfo($local_file); - $file_name = $info['basename']; - $zip->addFile($local_file, $file_name); - $zip->close(); - $params = [ - 'file' => base64_encode(file_get_contents($temp_zip)), - ]; - $remote_path = $this->executor->execute( - DriverCommand::UPLOAD_FILE, - $params - ); - unlink($temp_zip); - - return $remote_path; - } - /** * Set the fileDetector in order to let the RemoteWebElement to know that * you are going to upload a file. @@ -450,4 +414,40 @@ protected function newElement($id) { return new static($this->executor, $id); } + + /** + * Upload a local file to the server + * + * @param string $local_file + * + * @throws WebDriverException + * @return string The remote path of the file. + */ + protected function upload($local_file) + { + if (!is_file($local_file)) { + throw new WebDriverException('You may only upload files: ' . $local_file); + } + + // Create a temporary file in the system temp directory. + $temp_zip = tempnam(sys_get_temp_dir(), 'WebDriverZip'); + $zip = new ZipArchive(); + if ($zip->open($temp_zip, ZipArchive::CREATE) !== true) { + return false; + } + $info = pathinfo($local_file); + $file_name = $info['basename']; + $zip->addFile($local_file, $file_name); + $zip->close(); + $params = [ + 'file' => base64_encode(file_get_contents($temp_zip)), + ]; + $remote_path = $this->executor->execute( + DriverCommand::UPLOAD_FILE, + $params + ); + unlink($temp_zip); + + return $remote_path; + } } diff --git a/lib/Support/Events/EventFiringWebDriver.php b/lib/Support/Events/EventFiringWebDriver.php index 0dd805bcb..ffac00e5c 100644 --- a/lib/Support/Events/EventFiringWebDriver.php +++ b/lib/Support/Events/EventFiringWebDriver.php @@ -60,20 +60,6 @@ public function getDispatcher() return $this->dispatcher; } - /** - * @param mixed $method - */ - protected function dispatch($method) - { - if (!$this->dispatcher) { - return; - } - - $arguments = func_get_args(); - unset($arguments[0]); - $this->dispatcher->dispatch($method, $arguments); - } - /** * @return WebDriver */ @@ -82,15 +68,6 @@ public function getWebDriver() return $this->driver; } - /** - * @param WebDriverElement $element - * @return EventFiringWebElement - */ - protected function newElement(WebDriverElement $element) - { - return new EventFiringWebElement($element, $this->getDispatcher()); - } - /** * @param mixed $url * @throws WebDriverException @@ -408,10 +385,33 @@ public function execute($name, $params) } } + /** + * @param WebDriverElement $element + * @return EventFiringWebElement + */ + protected function newElement(WebDriverElement $element) + { + return new EventFiringWebElement($element, $this->getDispatcher()); + } + + /** + * @param mixed $method + */ + protected function dispatch($method) + { + if (!$this->dispatcher) { + return; + } + + $arguments = func_get_args(); + unset($arguments[0]); + $this->dispatcher->dispatch($method, $arguments); + } + /** * @param WebDriverException $exception */ - private function dispatchOnException(WebDriverException $exception) + protected function dispatchOnException(WebDriverException $exception) { $this->dispatch('onException', $exception, $this); } diff --git a/lib/Support/Events/EventFiringWebDriverNavigation.php b/lib/Support/Events/EventFiringWebDriverNavigation.php index 34bc196ae..5aeaf510b 100644 --- a/lib/Support/Events/EventFiringWebDriverNavigation.php +++ b/lib/Support/Events/EventFiringWebDriverNavigation.php @@ -48,20 +48,6 @@ public function getDispatcher() return $this->dispatcher; } - /** - * @param mixed $method - */ - protected function dispatch($method) - { - if (!$this->dispatcher) { - return; - } - - $arguments = func_get_args(); - unset($arguments[0]); - $this->dispatcher->dispatch($method, $arguments); - } - /** * @return WebDriverNavigation */ @@ -161,10 +147,24 @@ public function to($url) return $this; } + /** + * @param mixed $method + */ + protected function dispatch($method) + { + if (!$this->dispatcher) { + return; + } + + $arguments = func_get_args(); + unset($arguments[0]); + $this->dispatcher->dispatch($method, $arguments); + } + /** * @param WebDriverException $exception */ - private function dispatchOnException(WebDriverException $exception) + protected function dispatchOnException(WebDriverException $exception) { $this->dispatch('onException', $exception); } diff --git a/lib/Support/Events/EventFiringWebElement.php b/lib/Support/Events/EventFiringWebElement.php index b9591b0ef..f932b20a3 100644 --- a/lib/Support/Events/EventFiringWebElement.php +++ b/lib/Support/Events/EventFiringWebElement.php @@ -53,19 +53,6 @@ public function getDispatcher() return $this->dispatcher; } - /** - * @param mixed $method - */ - protected function dispatch($method) - { - if (!$this->dispatcher) { - return; - } - $arguments = func_get_args(); - unset($arguments[0]); - $this->dispatcher->dispatch($method, $arguments); - } - /** * @return WebDriverElement */ @@ -74,15 +61,6 @@ public function getElement() return $this->element; } - /** - * @param WebDriverElement $element - * @return EventFiringWebElement - */ - protected function newElement(WebDriverElement $element) - { - return new static($element, $this->getDispatcher()); - } - /** * @param mixed $value * @throws WebDriverException @@ -403,7 +381,7 @@ public function equals(WebDriverElement $other) /** * @param WebDriverException $exception */ - private function dispatchOnException(WebDriverException $exception) + protected function dispatchOnException(WebDriverException $exception) { $this->dispatch( 'onException', @@ -411,4 +389,26 @@ private function dispatchOnException(WebDriverException $exception) $this->dispatcher->getDefaultDriver() ); } + + /** + * @param mixed $method + */ + protected function dispatch($method) + { + if (!$this->dispatcher) { + return; + } + $arguments = func_get_args(); + unset($arguments[0]); + $this->dispatcher->dispatch($method, $arguments); + } + + /** + * @param WebDriverElement $element + * @return EventFiringWebElement + */ + protected function newElement(WebDriverElement $element) + { + return new static($element, $this->getDispatcher()); + } } diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index baee93e85..58ba939e9 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -34,6 +34,11 @@ class WebDriverExpectedCondition */ private $apply; + protected function __construct(callable $apply) + { + $this->apply = $apply; + } + /** * @return callable A callable function to be executed by WebDriverWait */ @@ -42,11 +47,6 @@ public function getApply() return $this->apply; } - protected function __construct(callable $apply) - { - $this->apply = $apply; - } - /** * An expectation for checking the title of a page. * diff --git a/lib/WebDriverOptions.php b/lib/WebDriverOptions.php index bdf4db2ae..b728382cc 100644 --- a/lib/WebDriverOptions.php +++ b/lib/WebDriverOptions.php @@ -54,7 +54,7 @@ public function __construct(ExecuteMethod $executor) */ public function addCookie(array $cookie) { - $this->validate($cookie); + $this->validateCookie($cookie); $this->executor->execute( DriverCommand::ADD_COOKIE, ['cookie' => $cookie] @@ -119,30 +119,6 @@ public function getCookies() return $this->executor->execute(DriverCommand::GET_ALL_COOKIES); } - private function validate(array $cookie) - { - if (!isset($cookie['name']) || - $cookie['name'] === '' || - mb_strpos($cookie['name'], ';') !== false - ) { - throw new InvalidArgumentException( - '"name" should be non-empty and does not contain a ";"' - ); - } - - if (!isset($cookie['value'])) { - throw new InvalidArgumentException( - '"value" is required when setting a cookie.' - ); - } - - if (isset($cookie['domain']) && mb_strpos($cookie['domain'], ':') !== false) { - throw new InvalidArgumentException( - '"domain" should not contain a port:' . (string) $cookie['domain'] - ); - } - } - /** * Return the interface for managing driver timeouts. * @@ -189,4 +165,23 @@ public function getAvailableLogTypes() { return $this->executor->execute(DriverCommand::GET_AVAILABLE_LOG_TYPES); } + + /** + * @param array $cookie + * @throws \InvalidArgumentException + */ + private function validateCookie(array $cookie) + { + if (!isset($cookie['name']) || $cookie['name'] === '' || mb_strpos($cookie['name'], ';') !== false) { + throw new InvalidArgumentException('"name" should be non-empty and does not contain a ";"'); + } + + if (!isset($cookie['value'])) { + throw new InvalidArgumentException('"value" is required when setting a cookie.'); + } + + if (isset($cookie['domain']) && mb_strpos($cookie['domain'], ':') !== false) { + throw new InvalidArgumentException('"domain" should not contain a port:' . (string) $cookie['domain']); + } + } } From ccab174d84cca426220800be0b79d2efb7065825 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 17 Jan 2017 02:50:48 +0100 Subject: [PATCH 295/784] Do not suggest phpdocumentor, the API docs is now generated using Sami --- composer.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/composer.json b/composer.json index 55780368b..941a816c3 100644 --- a/composer.json +++ b/composer.json @@ -22,9 +22,6 @@ "php-mock/php-mock-phpunit": "^1.1", "satooshi/php-coveralls": "^1.0" }, - "suggest": { - "phpdocumentor/phpdocumentor": "2.*" - }, "autoload": { "psr-4": { "Facebook\\WebDriver\\": "lib/" From 37d5925bcb63af1fb409a5e3d9374770f9c6c8d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 17 Jan 2017 02:53:58 +0100 Subject: [PATCH 296/784] Update API documentation URL (fixes #378) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bc3e9fbb0..37fb7f393 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ The concepts of this library are very similar to the "official" Java, .NET, Pyth **This is new version of PHP client, rewritten from scratch starting 2013.** Using the old version? Check out [Adam Goucher's fork](https://github.com/Element-34/php-webdriver) of it. -Looking for API documentation of php-webdriver? See http://facebook.github.io/php-webdriver/ +Looking for API documentation of php-webdriver? See [https://facebook.github.io/php-webdriver/](https://facebook.github.io/php-webdriver/latest/) Any complaint, question, idea? You can post it on the user group https://www.facebook.com/groups/phpwebdriver/. From f3e1c4576feabc76999cb33af63282b6690c3f4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 17 Jan 2017 03:32:38 +0100 Subject: [PATCH 297/784] Update links in README, add link to another php-webdriver integrations --- README.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 37fb7f393..d2a8d6132 100644 --- a/README.md +++ b/README.md @@ -77,9 +77,18 @@ For latest changes see [CHANGELOG.md](CHANGELOG.md) file. ## More information -Check out the Selenium docs and wiki at http://docs.seleniumhq.org/docs/ and https://code.google.com/p/selenium/wiki +Some how-tos are provided right here in [our GitHub wiki](https://github.com/facebook/php-webdriver/wiki). -Learn how to integrate it with PHPUnit [Blogpost](http://codeception.com/11-12-2013/working-with-phpunit-and-selenium-webdriver.html) | [Demo Project](https://github.com/DavertMik/php-webdriver-demo) +You may also want to check out the Selenium [docs](http://docs.seleniumhq.org/docs/) and [wiki](https://github.com/SeleniumHQ/selenium/wiki). + +## Testing framework integration + +To take advantage of automatized testing you will most probably want to integrate php-webdriver to your testing framework. +There are some project already providing this: + +- [Steward](https://github.com/lmc-eu/steward) integrates php-webdriver directly to [PHPUnit](https://phpunit.de/), also providers parallelization. +- [Codeception](http://codeception.com) testing framework provides BDD-layer on top of php-webdriver in its [WebDriver module](http://codeception.com/docs/modules/WebDriver). +- You can also check out this [blogpost](http://codeception.com/11-12-2013/working-with-phpunit-and-selenium-webdriver.html) + [demo project](https://github.com/DavertMik/php-webdriver-demo), describing simple [PHPUnit](https://phpunit.de/) integration. ## Support From 1fdbab925e26893ba8a0cb93ddf5c6b613e307a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 20 Jan 2017 20:39:13 +0100 Subject: [PATCH 298/784] Specify covered methods to have more accurate code coverage --- tests/functional/RemoteWebElementTest.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tests/functional/RemoteWebElementTest.php b/tests/functional/RemoteWebElementTest.php index 1a04cf1a8..c74b5d384 100644 --- a/tests/functional/RemoteWebElementTest.php +++ b/tests/functional/RemoteWebElementTest.php @@ -16,10 +16,13 @@ namespace Facebook\WebDriver; /** - * @covers Facebook\WebDriver\Remote\RemoteWebElement + * @coversDefaultClass Facebook\WebDriver\Remote\RemoteWebElement */ class RemoteWebElementTest extends WebDriverTestCase { + /** + * @covers ::getText + */ public function testShouldGetText() { $this->driver->get($this->getTestPath('index.html')); @@ -30,6 +33,9 @@ public function testShouldGetText() $this->assertEquals('Multiple spaces are stripped', $elementWithTextWithSpaces->getText()); } + /** + * @covers ::getAttribute + */ public function testShouldGetAttributeValue() { $this->driver->get($this->getTestPath('index.html')); @@ -41,6 +47,9 @@ public function testShouldGetAttributeValue() $this->assertSame('text-simple', $element->getAttribute('id')); } + /** + * @covers ::getLocation + */ public function testShouldGetLocation() { $this->driver->get($this->getTestPath('index.html')); @@ -53,6 +62,9 @@ public function testShouldGetLocation() $this->assertSame(500, $elementLocation->getY()); } + /** + * @covers ::getSize + */ public function testShouldGetSize() { $this->driver->get($this->getTestPath('index.html')); @@ -65,6 +77,9 @@ public function testShouldGetSize() $this->assertSame(66, $elementSize->getHeight()); } + /** + * @covers ::getCSSValue + */ public function testShouldGetCssValue() { $this->driver->get($this->getTestPath('index.html')); From 4ab3d675cd9bf2714d0841e558db7b00231f968d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 20 Jan 2017 21:20:43 +0100 Subject: [PATCH 299/784] Add more functional tests for RemoteWebElement --- lib/Remote/RemoteWebElement.php | 4 +- tests/functional/RemoteWebElementTest.php | 164 ++++++++++++++++++++++ tests/functional/web/form.html | 28 +++- tests/functional/web/index.html | 7 + tests/functional/web/submit.php | 28 ++++ tests/functional/web/upload.html | 2 +- 6 files changed, 227 insertions(+), 6 deletions(-) create mode 100644 tests/functional/web/submit.php diff --git a/lib/Remote/RemoteWebElement.php b/lib/Remote/RemoteWebElement.php index c10bfbf32..71fdb4305 100644 --- a/lib/Remote/RemoteWebElement.php +++ b/lib/Remote/RemoteWebElement.php @@ -244,13 +244,13 @@ public function getSize() } /** - * Get the tag name of this element. + * Get the (lowercase) tag name of this element. * * @return string The tag name. */ public function getTagName() { - // Force tag name to be lowercase as expected by protocol for Opera driver + // Force tag name to be lowercase as expected by JsonWire protocol for Opera driver // until this issue is not resolved : // https://github.com/operasoftware/operadriver/issues/102 // Remove it when fixed to be consistent with the protocol. diff --git a/tests/functional/RemoteWebElementTest.php b/tests/functional/RemoteWebElementTest.php index c74b5d384..48983a14e 100644 --- a/tests/functional/RemoteWebElementTest.php +++ b/tests/functional/RemoteWebElementTest.php @@ -93,4 +93,168 @@ public function testShouldGetCssValue() $this->assertSame('rgba(0, 0, 0, 1)', $elementWithBorder->getCSSValue('border-left-color')); $this->assertSame('rgba(0, 0, 0, 1)', $elementWithoutBorder->getCSSValue('border-left-color')); } + + /** + * @covers ::getTagName + */ + public function testShouldGetTagName() + { + $this->driver->get($this->getTestPath('index.html')); + + $paragraphElement = $this->driver->findElement(WebDriverBy::id('id_test')); + + $this->assertSame('p', $paragraphElement->getTagName()); + } + + /** + * @covers ::click + */ + public function testShouldClick() + { + $this->driver->get($this->getTestPath('index.html')); + $linkElement = $this->driver->findElement(WebDriverBy::id('a-form')); + + $linkElement->click(); + + $this->driver->wait()->until( + WebDriverExpectedCondition::urlContains('form.html') + ); + } + + /** + * @covers ::clear + */ + public function testShouldClearFormElementText() + { + $this->driver->get($this->getTestPath('form.html')); + + $input = $this->driver->findElement(WebDriverBy::id('input-text')); + $textarea = $this->driver->findElement(WebDriverBy::id('textarea')); + + $this->assertSame('Default input text', $input->getAttribute('value')); + $input->clear(); + $this->assertSame('', $input->getAttribute('value')); + + $this->assertSame('Default textarea text', $textarea->getAttribute('value')); + $textarea->clear(); + $this->assertSame('', $textarea->getAttribute('value')); + } + + /** + * @covers ::sendKeys + */ + public function testShouldSendKeysToFormElement() + { + $this->driver->get($this->getTestPath('form.html')); + + $input = $this->driver->findElement(WebDriverBy::id('input-text')); + $textarea = $this->driver->findElement(WebDriverBy::id('textarea')); + + $input->clear(); + $input->sendKeys('foo bar'); + $this->assertSame('foo bar', $input->getAttribute('value')); + $input->sendKeys(' baz'); + $this->assertSame('foo bar baz', $input->getAttribute('value')); + + $textarea->clear(); + $textarea->sendKeys('foo bar'); + $this->assertSame('foo bar', $textarea->getAttribute('value')); + $textarea->sendKeys(' baz'); + $this->assertSame('foo bar baz', $textarea->getAttribute('value')); + } + + /** + * @covers ::isEnabled + */ + public function testShouldDetectEnabledInputs() + { + $this->driver->get($this->getTestPath('form.html')); + + $inputEnabled = $this->driver->findElement(WebDriverBy::id('input-text')); + $inputDisabled = $this->driver->findElement(WebDriverBy::id('input-text-disabled')); + + $this->assertTrue($inputEnabled->isEnabled()); + $this->assertFalse($inputDisabled->isEnabled()); + } + + /** + * @covers ::isSelected + */ + public function testShouldSelectedInputsOrOptions() + { + $this->driver->get($this->getTestPath('form.html')); + + $checkboxSelected = $this->driver->findElement( + WebDriverBy::cssSelector('input[name=checkbox][value=second]') + ); + $checkboxNotSelected = $this->driver->findElement( + WebDriverBy::cssSelector('input[name=checkbox][value=first]') + ); + $this->assertTrue($checkboxSelected->isSelected()); + $this->assertFalse($checkboxNotSelected->isSelected()); + + $radioSelected = $this->driver->findElement(WebDriverBy::cssSelector('input[name=radio][value=second]')); + $radioNotSelected = $this->driver->findElement(WebDriverBy::cssSelector('input[name=radio][value=first]')); + $this->assertTrue($radioSelected->isSelected()); + $this->assertFalse($radioNotSelected->isSelected()); + + $optionSelected = $this->driver->findElement(WebDriverBy::cssSelector('#select option[value=first]')); + $optionNotSelected = $this->driver->findElement(WebDriverBy::cssSelector('#select option[value=second]')); + $this->assertTrue($optionSelected->isSelected()); + $this->assertFalse($optionNotSelected->isSelected()); + } + + /** + * @covers ::submit + */ + public function testShouldSubmitFormBySubmitEventOnForm() + { + $this->driver->get($this->getTestPageUrl('form.html')); + + $formElement = $this->driver->findElement(WebDriverBy::cssSelector('form')); + + $formElement->submit(); + + $this->driver->wait()->until( + WebDriverExpectedCondition::titleIs('Form submit endpoint') + ); + + $this->assertSame('Received POST data', $this->driver->findElement(WebDriverBy::cssSelector('h2'))->getText()); + } + + /** + * @covers ::submit + */ + public function testShouldSubmitFormBySubmitEventOnFormInputElement() + { + $this->driver->get($this->getTestPageUrl('form.html')); + + $inputTextElement = $this->driver->findElement(WebDriverBy::id('input-text')); + + $inputTextElement->submit(); + + $this->driver->wait()->until( + WebDriverExpectedCondition::titleIs('Form submit endpoint') + ); + + $this->assertSame('Received POST data', $this->driver->findElement(WebDriverBy::cssSelector('h2'))->getText()); + } + + /** + * @covers ::click + */ + public function testShouldSubmitFormByClickOnSubmitInput() + { + $this->driver->get($this->getTestPageUrl('form.html')); + + $submitElement = $this->driver->findElement(WebDriverBy::id('submit')); + + $submitElement->click(); + + $this->driver->wait()->until( + WebDriverExpectedCondition::titleIs('Form submit endpoint') + ); + + $this->assertSame('Received POST data', $this->driver->findElement(WebDriverBy::cssSelector('h2'))->getText()); + } } diff --git a/tests/functional/web/form.html b/tests/functional/web/form.html index ac91336b1..c1570df8a 100644 --- a/tests/functional/web/form.html +++ b/tests/functional/web/form.html @@ -5,16 +5,22 @@ php-webdriver form test page -
    + +
    + +

    @@ -38,6 +44,22 @@
    +
    + Checkboxes + First
    + Second (preselected)
    + Third (preselected)
    + Fourth
    +
    + +
    + Radio buttons + First
    + Second (preselected)
    + Third
    + Fourth
    +
    +

    diff --git a/tests/functional/web/index.html b/tests/functional/web/index.html index 282706cce..f0dc03af4 100644 --- a/tests/functional/web/index.html +++ b/tests/functional/web/index.html @@ -6,6 +6,13 @@

    Welcome to the facebook/php-webdriver testing page.

    + + Form test page + | + Form with file upload + | + New window opener test page +

    Test by ID

    Test by Class

    Click here diff --git a/tests/functional/web/submit.php b/tests/functional/web/submit.php new file mode 100644 index 000000000..4d8219ec5 --- /dev/null +++ b/tests/functional/web/submit.php @@ -0,0 +1,28 @@ + + + + + Form submit endpoint + + + +POST data not detected'; +} else { + echo '

    Received POST data

    '; + echo '
      '; + foreach ($_POST as $key => $value) { + echo sprintf( + '
    • %s: %s
    • ' . "\n", + $key, + $key, + $value + ); + } + echo '
    '; +} +?> + + + diff --git a/tests/functional/web/upload.html b/tests/functional/web/upload.html index d02c5ed4b..65a622c50 100644 --- a/tests/functional/web/upload.html +++ b/tests/functional/web/upload.html @@ -5,7 +5,7 @@ Upload a file - +

    From c8e3f5ac5015773691b92bf224a11909a38a338f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 20 Jan 2017 21:25:51 +0100 Subject: [PATCH 300/784] Test equals() method of RemoteWebElementTest --- tests/functional/RemoteWebElementTest.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/functional/RemoteWebElementTest.php b/tests/functional/RemoteWebElementTest.php index 48983a14e..e5d1ead06 100644 --- a/tests/functional/RemoteWebElementTest.php +++ b/tests/functional/RemoteWebElementTest.php @@ -257,4 +257,23 @@ public function testShouldSubmitFormByClickOnSubmitInput() $this->assertSame('Received POST data', $this->driver->findElement(WebDriverBy::cssSelector('h2'))->getText()); } + + /** + * @covers ::equals + */ + public function testShouldCompareEqualsElement() + { + $this->driver->get($this->getTestPath('index.html')); + + $firstElement = $this->driver->findElement(WebDriverBy::cssSelector('ul.list')); + $differentElement = $this->driver->findElement(WebDriverBy::cssSelector('#text-simple')); + $againTheFirstElement = $this->driver->findElement(WebDriverBy::cssSelector('ul.list')); + + $this->assertTrue($firstElement->equals($againTheFirstElement)); + $this->assertTrue($againTheFirstElement->equals($firstElement)); + + $this->assertFalse($differentElement->equals($firstElement)); + $this->assertFalse($firstElement->equals($differentElement)); + $this->assertFalse($differentElement->equals($againTheFirstElement)); + } } From 9f7019aeeb975d61a7929a73c5809983aac27ea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 25 Jan 2017 23:53:49 +0100 Subject: [PATCH 301/784] Improve phpdoc formatting to make apidoc more readable --- lib/Remote/RemoteWebDriver.php | 3 ++- lib/Remote/RemoteWebElement.php | 2 +- lib/Support/XPathEscaper.php | 2 +- lib/WebDriverExpectedCondition.php | 2 +- lib/WebDriverNavigation.php | 2 +- lib/WebDriverOptions.php | 2 +- lib/WebDriverSelect.php | 2 +- lib/WebDriverSelectInterface.php | 16 ++++++++-------- 8 files changed, 16 insertions(+), 15 deletions(-) diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index a06beb132..ce7450720 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -340,10 +340,11 @@ public function takeScreenshot($save_as = null) * Construct a new WebDriverWait by the current WebDriver instance. * Sample usage: * + * ``` * $driver->wait(20, 1000)->until( * WebDriverExpectedCondition::titleIs('WebDriver Page') * ); - * + * ``` * @param int $timeout_in_second * @param int $interval_in_millisecond * diff --git a/lib/Remote/RemoteWebElement.php b/lib/Remote/RemoteWebElement.php index 71fdb4305..17fa258c4 100644 --- a/lib/Remote/RemoteWebElement.php +++ b/lib/Remote/RemoteWebElement.php @@ -349,7 +349,7 @@ public function sendKeys($value) * Basically, if you want WebDriver trying to send a file, set the fileDetector * to be LocalFileDetector. Otherwise, keep it UselessFileDetector. * - * eg. $element->setFileDetector(new LocalFileDetector); + * eg. `$element->setFileDetector(new LocalFileDetector);` * * @param FileDetector $detector * @return RemoteWebElement diff --git a/lib/Support/XPathEscaper.php b/lib/Support/XPathEscaper.php index dc5907f01..c90cefa87 100644 --- a/lib/Support/XPathEscaper.php +++ b/lib/Support/XPathEscaper.php @@ -19,7 +19,7 @@ class XPathEscaper { /** * Converts xpath strings with both quotes and ticks into: - * foo'"bar -> concat('foo', "'" ,'"bar') + * `foo'"bar` -> `concat('foo', "'" ,'"bar')` * * @param string $xpathToEscape The xpath to be converted. * @return string The escaped string. diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index 58ba939e9..5612a5bbe 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -66,7 +66,7 @@ function (WebDriver $driver) use ($title) { * An expectation for checking substring of a page Title. * * @param string $title The expected substring of Title. - * @return WebDriverExpectedCondition Condition returns whether current page title contains given string. + * @return WebDriverExpectedCondition Condition returns whether current page title contains given string. */ public static function titleContains($title) { diff --git a/lib/WebDriverNavigation.php b/lib/WebDriverNavigation.php index 6c7857d1d..ccc8cee30 100644 --- a/lib/WebDriverNavigation.php +++ b/lib/WebDriverNavigation.php @@ -25,7 +25,7 @@ * Note that they are all blocking functions until the page is loaded by * by default. It could be overridden by 'webdriver.load.strategy' in the * FirefoxProfile preferences. - * https://code.google.com/p/selenium/wiki/DesiredCapabilities#settings + * https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities#firefoxprofile-settings */ class WebDriverNavigation { diff --git a/lib/WebDriverOptions.php b/lib/WebDriverOptions.php index b728382cc..e02d24136 100644 --- a/lib/WebDriverOptions.php +++ b/lib/WebDriverOptions.php @@ -37,7 +37,7 @@ public function __construct(ExecuteMethod $executor) /** * Add a specific cookie. * - * Here are the valid attributes of a cookie array. + * Valid attributes of a cookie array: * 'name' : string The name of the cookie; may not be null or an empty string. * 'value' : string The cookie value; may not be null. * 'path' : string OPTIONAL The path the cookie is visible to. Defaults to "/" if omitted. diff --git a/lib/WebDriverSelect.php b/lib/WebDriverSelect.php index dc6a84038..abe6b54fe 100644 --- a/lib/WebDriverSelect.php +++ b/lib/WebDriverSelect.php @@ -21,7 +21,7 @@ use Facebook\WebDriver\Support\XPathEscaper; /** - * Models a default HTML ` tag, providing helper methods to select and deselect options. */ class WebDriverSelect implements WebDriverSelectInterface { diff --git a/lib/WebDriverSelectInterface.php b/lib/WebDriverSelectInterface.php index cec06a33f..bd4db90e4 100644 --- a/lib/WebDriverSelectInterface.php +++ b/lib/WebDriverSelectInterface.php @@ -27,8 +27,8 @@ public function getAllSelectedOptions(); /** * @throws NoSuchElementException * - * @return WebDriverElement The first selected option in this select tag (or - * the currently selected option in a normal select) + * @return WebDriverElement The first selected option in this select tag (or the currently selected option in a + * normal select) */ public function getFirstSelectedOption(); @@ -45,7 +45,7 @@ public function selectByIndex($index); * Select all options that have value attribute matching the argument. That is, when given "foo" this would * select an option like: * - * ; + * `` * * @param string $value The value to match against. * @@ -57,7 +57,7 @@ public function selectByValue($value); * Select all options that display text matching the argument. That is, when given "Bar" this would * select an option like: * - * ; + * `` * * @param string $text The visible text to match against. * @@ -69,7 +69,7 @@ public function selectByVisibleText($text); * Select all options that display text partially matching the argument. That is, when given "Bar" this would * select an option like: * - * ; + * `` * * @param string $text The visible text to match against. * @@ -96,7 +96,7 @@ public function deselectByIndex($index); * Deselect all options that have value attribute matching the argument. That is, when given "foo" this would * deselect an option like: * - * ; + * `` * * @param string $value The value to match against. * @throws UnsupportedOperationException If the SELECT does not support multiple selections @@ -107,7 +107,7 @@ public function deselectByValue($value); * Deselect all options that display text matching the argument. That is, when given "Bar" this would * deselect an option like: * - * ; + * `` * * @param string $text The visible text to match against. * @throws UnsupportedOperationException If the SELECT does not support multiple selections @@ -118,7 +118,7 @@ public function deselectByVisibleText($text); * Deselect all options that display text matching the argument. That is, when given "Bar" this would * deselect an option like: * - * ; + * `` * * @param string $text The visible text to match against. * @throws UnsupportedOperationException If the SELECT does not support multiple selections From 85aa68020ef2cf4fd261b1f1a690052afe67a9e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Thu, 26 Jan 2017 00:07:01 +0100 Subject: [PATCH 302/784] Update links to Selenium wiki --- lib/Remote/DesiredCapabilities.php | 4 ++-- lib/Remote/HttpCommandExecutor.php | 3 +-- lib/WebDriverExpectedCondition.php | 2 +- lib/WebDriverOptions.php | 4 ++-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/Remote/DesiredCapabilities.php b/lib/Remote/DesiredCapabilities.php index 12060ab7b..94d8e1de2 100644 --- a/lib/Remote/DesiredCapabilities.php +++ b/lib/Remote/DesiredCapabilities.php @@ -136,7 +136,7 @@ public function isJavascriptEnabled() * @param bool $enabled * @throws Exception * @return DesiredCapabilities - * @see https://code.google.com/p/selenium/wiki/DesiredCapabilities#Read-write_capabilities + * @see https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities#read-write-capabilities */ public function setJavascriptEnabled($enabled) { @@ -144,7 +144,7 @@ public function setJavascriptEnabled($enabled) if ($browser && $browser !== WebDriverBrowserType::HTMLUNIT) { throw new Exception( 'isJavascriptEnable() is a htmlunit-only option. ' . - 'See https://code.google.com/p/selenium/wiki/DesiredCapabilities#Read-write_capabilities.' + 'See https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities#read-write-capabilities.' ); } diff --git a/lib/Remote/HttpCommandExecutor.php b/lib/Remote/HttpCommandExecutor.php index 2f6c1778f..09bf000d0 100644 --- a/lib/Remote/HttpCommandExecutor.php +++ b/lib/Remote/HttpCommandExecutor.php @@ -27,8 +27,7 @@ class HttpCommandExecutor implements WebDriverCommandExecutor { /** - * @see - * http://code.google.com/p/selenium/wiki/JsonWireProtocol#Command_Reference + * @see https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#command-reference */ protected static $commands = [ DriverCommand::ACCEPT_ALERT => ['method' => 'POST', 'url' => '/session/:sessionId/accept_alert'], diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index 5612a5bbe..58ba939e9 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -66,7 +66,7 @@ function (WebDriver $driver) use ($title) { * An expectation for checking substring of a page Title. * * @param string $title The expected substring of Title. - * @return WebDriverExpectedCondition Condition returns whether current page title contains given string. + * @return WebDriverExpectedCondition Condition returns whether current page title contains given string. */ public static function titleContains($title) { diff --git a/lib/WebDriverOptions.php b/lib/WebDriverOptions.php index e02d24136..14cacd176 100644 --- a/lib/WebDriverOptions.php +++ b/lib/WebDriverOptions.php @@ -145,7 +145,7 @@ public function window() * * @param string $log_type The log type. * @return array The list of log entries. - * @see https://code.google.com/p/selenium/wiki/JsonWireProtocol#Log_Type + * @see https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#log-type */ public function getLog($log_type) { @@ -159,7 +159,7 @@ public function getLog($log_type) * Get available log types. * * @return array The list of available log types. - * @see https://code.google.com/p/selenium/wiki/JsonWireProtocol#Log_Type + * @see https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#log-type */ public function getAvailableLogTypes() { From 122ae7abd1b495fcbfe432d75d99f5403ad76e29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 27 Jan 2017 19:48:01 +0100 Subject: [PATCH 303/784] Add value object to hold cookie data --- lib/Cookie.php | 208 ++++++++++++++++++++++++++++++++++++++ tests/unit/CookieTest.php | 138 +++++++++++++++++++++++++ 2 files changed, 346 insertions(+) create mode 100644 lib/Cookie.php create mode 100644 tests/unit/CookieTest.php diff --git a/lib/Cookie.php b/lib/Cookie.php new file mode 100644 index 000000000..a3b86dbf0 --- /dev/null +++ b/lib/Cookie.php @@ -0,0 +1,208 @@ + null, + 'value' => null, + 'path' => null, + 'domain' => null, + 'expiry' => null, + 'secure' => null, + 'httpOnly' => null, + ]; + + /** + * @param string $name The name of the cookie; may not be null or an empty string. + * @param string $value The cookie value; may not be null. + */ + public function __construct($name, $value) + { + $this->cookie['name'] = $name; + $this->cookie['value'] = $value; + } + + /** + * @param array $cookieArray + * @return Cookie + */ + public static function createFromArray(array $cookieArray) + { + $cookie = new self($cookieArray['name'], $cookieArray['value']); + + if (isset($cookieArray['path'])) { + $cookie->setPath($cookieArray['path']); + } + if (isset($cookieArray['domain'])) { + $cookie->setDomain($cookieArray['domain']); + } + if (isset($cookieArray['expiry'])) { + $cookie->setExpiry($cookieArray['expiry']); + } + if (isset($cookieArray['secure'])) { + $cookie->setSecure($cookieArray['secure']); + } + if (isset($cookieArray['httpOnly'])) { + $cookie->setHttpOnly($cookieArray['httpOnly']); + } + + return $cookie; + } + + /** + * @return string + */ + public function getName() + { + return $this->cookie['name']; + } + + /** + * @return string + */ + public function getValue() + { + return $this->cookie['value']; + } + + /** + * The path the cookie is visible to. Defaults to "/" if omitted. + * + * @param string $path + */ + public function setPath($path) + { + $this->cookie['path'] = $path; + } + + /** + * @return string + */ + public function getPath() + { + return $this->cookie['path']; + } + + /** + * The domain the cookie is visible to. Defaults to the current browsing context's document's URL domain if omitted. + * + * @param string $domain + */ + public function setDomain($domain) + { + $this->cookie['domain'] = $domain; + } + + /** + * @return string + */ + public function getDomain() + { + return $this->cookie['domain']; + } + + /** + * The cookie's expiration date, specified in seconds since Unix Epoch. + * + * @param int $expiry + */ + public function setExpiry($expiry) + { + $this->cookie['expiry'] = (int) $expiry; + } + + /** + * @return int + */ + public function getExpiry() + { + return $this->cookie['expiry']; + } + + /** + * Whether this cookie requires a secure connection (https). Defaults to false if omitted. + * + * @param bool $secure + */ + public function setSecure($secure) + { + $this->cookie['secure'] = $secure; + } + + /** + * @return bool + */ + public function isSecure() + { + return $this->cookie['secure']; + } + + /** + * Whether the cookie is an HTTP only cookie. Defaults to false if omitted. + * + * @param bool $httpOnly + */ + public function setHttpOnly($httpOnly) + { + $this->cookie['httpOnly'] = $httpOnly; + } + + /** + * @return bool + */ + public function isHttpOnly() + { + return $this->cookie['httpOnly']; + } + + /** + * @return array + */ + public function toArray() + { + return $this->cookie; + } + + public function offsetExists($offset) + { + return isset($this->cookie[$offset]); + } + + public function offsetGet($offset) + { + return $this->cookie[$offset]; + } + + public function offsetSet($offset, $value) + { + $this->cookie[$offset] = $value; + } + + public function offsetUnset($offset) + { + unset($this->cookie[$offset]); + } +} diff --git a/tests/unit/CookieTest.php b/tests/unit/CookieTest.php new file mode 100644 index 000000000..1ed18b39c --- /dev/null +++ b/tests/unit/CookieTest.php @@ -0,0 +1,138 @@ +setPath('/bar'); + $cookie->setDomain('foo.com'); + $cookie->setExpiry(1485388387); + $cookie->setSecure(true); + $cookie->setHttpOnly(true); + + $this->assertSame('cookieName', $cookie->getName()); + $this->assertSame('someValue', $cookie->getValue()); + $this->assertSame('/bar', $cookie->getPath()); + $this->assertSame('foo.com', $cookie->getDomain()); + $this->assertSame(1485388387, $cookie->getExpiry()); + $this->assertTrue($cookie->isSecure()); + $this->assertTrue($cookie->isHttpOnly()); + + return $cookie; + } + + /** + * @depends testShouldSetAllProperties + * @param Cookie $cookie + */ + public function testShouldBeConvertibleToArray(Cookie $cookie) + { + $this->assertSame( + [ + 'name' => 'cookieName', + 'value' => 'someValue', + 'path' => '/bar', + 'domain' => 'foo.com', + 'expiry' => 1485388387, + 'secure' => true, + 'httpOnly' => true, + ], + $cookie->toArray() + ); + } + + /** + * @depends testShouldSetAllProperties + * @param Cookie $cookie + */ + public function testShouldProvideArrayAccessToProperties(Cookie $cookie) + { + $this->assertSame('cookieName', $cookie['name']); + $this->assertSame('someValue', $cookie['value']); + $this->assertSame('/bar', $cookie['path']); + $this->assertSame('foo.com', $cookie['domain']); + $this->assertSame(1485388387, $cookie['expiry']); + $this->assertTrue($cookie['secure']); + $this->assertTrue($cookie['httpOnly']); + + $cookie->offsetSet('domain', 'bar.com'); + $this->assertSame('bar.com', $cookie['domain']); + $cookie->offsetUnset('domain'); + $this->assertFalse(isset($cookie['domain'])); + } + + public function testShouldBeCreatableFromAnArrayWithBasicValues() + { + $sourceArray = [ + 'name' => 'cookieName', + 'value' => 'someValue', + ]; + + $cookie = Cookie::createFromArray($sourceArray); + + $this->assertSame('cookieName', $cookie['name']); + $this->assertSame('someValue', $cookie['value']); + + $this->assertFalse(isset($cookie['path'])); + $this->assertNull($cookie['path']); + $this->assertNull($cookie->getPath()); + + $this->assertFalse(isset($cookie['domain'])); + $this->assertNull($cookie['domain']); + $this->assertNull($cookie->getDomain()); + + $this->assertFalse(isset($cookie['expiry'])); + $this->assertNull($cookie['expiry']); + $this->assertNull($cookie->getExpiry()); + + $this->assertFalse(isset($cookie['secure'])); + $this->assertNull($cookie['secure']); + $this->assertNull($cookie->isSecure()); + + $this->assertFalse(isset($cookie['httpOnly'])); + $this->assertNull($cookie['httpOnly']); + $this->assertNull($cookie->isHttpOnly()); + } + + public function testShouldBeCreatableFromAnArrayWithAllValues() + { + $sourceArray = [ + 'name' => 'cookieName', + 'value' => 'someValue', + 'path' => '/bar', + 'domain' => 'foo', + 'expiry' => 1485388333, + 'secure' => false, + 'httpOnly' => false, + ]; + + $cookie = Cookie::createFromArray($sourceArray); + + $this->assertSame('cookieName', $cookie['name']); + $this->assertSame('someValue', $cookie['value']); + $this->assertSame('/bar', $cookie['path']); + $this->assertSame('foo', $cookie['domain']); + $this->assertSame(1485388333, $cookie['expiry']); + $this->assertFalse($cookie['secure']); + $this->assertFalse($cookie['httpOnly']); + } +} From 33224c27e3f1fffd4ea62d5c33968496677ac79f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 27 Jan 2017 20:15:55 +0100 Subject: [PATCH 304/784] Validate cookie values on creation --- lib/Cookie.php | 33 +++++++++++++++++++++++++++++++ tests/unit/CookieTest.php | 41 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/lib/Cookie.php b/lib/Cookie.php index a3b86dbf0..0434a128b 100644 --- a/lib/Cookie.php +++ b/lib/Cookie.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use InvalidArgumentException; + /** * Set values of an cookie. * @@ -41,6 +43,9 @@ class Cookie implements \ArrayAccess */ public function __construct($name, $value) { + $this->validateCookieName($name); + $this->validateCookieValue($value); + $this->cookie['name'] = $name; $this->cookie['value'] = $value; } @@ -113,6 +118,10 @@ public function getPath() */ public function setDomain($domain) { + if (mb_strpos($domain, ':') !== false) { + throw new InvalidArgumentException(sprintf('Cookie domain "%s" should not contain a port', $domain)); + } + $this->cookie['domain'] = $domain; } @@ -205,4 +214,28 @@ public function offsetUnset($offset) { unset($this->cookie[$offset]); } + + /** + * @param string $name + */ + protected function validateCookieName($name) + { + if ($name === null || $name === '') { + throw new InvalidArgumentException('Cookie name should be non-empty'); + } + + if (mb_strpos($name, ';') !== false) { + throw new InvalidArgumentException('Cookie name should not contain a ";"'); + } + } + + /** + * @param string $value + */ + protected function validateCookieValue($value) + { + if ($value === null) { + throw new InvalidArgumentException('Cookie value is required when setting a cookie'); + } + } } diff --git a/tests/unit/CookieTest.php b/tests/unit/CookieTest.php index 1ed18b39c..0742a0789 100644 --- a/tests/unit/CookieTest.php +++ b/tests/unit/CookieTest.php @@ -135,4 +135,45 @@ public function testShouldBeCreatableFromAnArrayWithAllValues() $this->assertFalse($cookie['secure']); $this->assertFalse($cookie['httpOnly']); } + + /** + * @dataProvider invalidCookieProvider + * @param string $name + * @param string $value + * @param string $domain + * @param string $expectedMessage + */ + public function testShouldValidateCookie($name, $value, $domain, $expectedMessage) + { + if ($expectedMessage) { + $this->setExpectedException(\InvalidArgumentException::class, $expectedMessage); + } + + $cookie = new Cookie($name, $value); + if ($domain !== null) { + $cookie->setDomain($domain); + } + } + + /** + * @return array[] + */ + public function invalidCookieProvider() + { + return [ + // $name, $value, $domain, $expectedMessage + 'name cannot be empty' => ['', 'foo', null, 'Cookie name should be non-empty'], + 'name cannot be null' => [null, 'foo', null, 'Cookie name should be non-empty'], + 'name cannot contain semicolon' => ['name;semicolon', 'foo', null, 'Cookie name should not contain a ";"'], + 'value could be empty string' => ['name', '', null, null], + 'value cannot be null' => ['name', null, null, 'Cookie value is required when setting a cookie'], + 'domain cannot containt port' => [ + 'name', + 'value', + 'localhost:443', + 'Cookie domain "localhost:443" should not contain a port', + ], + 'cookie with valid values' => ['name', 'value', '*.localhost', null], + ]; + } } From 865e9b2c44eb8b1d7f21b4149f319875e5681d1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 27 Jan 2017 20:34:00 +0100 Subject: [PATCH 305/784] Add unit test to cookie setting and retrieval in WebDriverOptions class --- tests/unit/WebDriverOptionsTest.php | 152 ++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 tests/unit/WebDriverOptionsTest.php diff --git a/tests/unit/WebDriverOptionsTest.php b/tests/unit/WebDriverOptionsTest.php new file mode 100644 index 000000000..f95671470 --- /dev/null +++ b/tests/unit/WebDriverOptionsTest.php @@ -0,0 +1,152 @@ +executor = $this->getMockBuilder(ExecuteMethod::class) + ->disableOriginalConstructor() + ->getMock(); + } + + public function testShouldAddCookieFromArray() + { + $cookieInArray = [ + 'name' => 'cookieName', + 'value' => 'someValue', + 'path' => '/bar', + 'domain' => 'foo', + 'expiry' => 1485388333, + 'secure' => false, + 'httpOnly' => false, + ]; + + $this->executor->expects($this->once()) + ->method('execute') + ->with(DriverCommand::ADD_COOKIE, ['cookie' => $cookieInArray]); + + $options = new WebDriverOptions($this->executor); + + $options->addCookie($cookieInArray); + } + + public function testShouldGetAllCookies() + { + $this->executor->expects($this->once()) + ->method('execute') + ->with(DriverCommand::GET_ALL_COOKIES) + ->willReturn( + [ + [ + 'path' => '/', + 'domain' => '*.seleniumhq.org', + 'name' => 'firstCookie', + 'httpOnly' => false, + 'secure' => true, + 'value' => 'value', + ], + [ + 'path' => '/', + 'domain' => 'docs.seleniumhq.org', + 'name' => 'secondCookie', + 'httpOnly' => false, + 'secure' => false, + 'value' => 'foo', + ], + ] + ); + + $options = new WebDriverOptions($this->executor); + + $cookies = $options->getCookies(); + + $this->assertCount(2, $cookies); + $this->assertSame('firstCookie', $cookies[0]['name']); + $this->assertSame('secondCookie', $cookies[1]['name']); + } + + public function testShouldGetCookieByName() + { + $this->executor->expects($this->once()) + ->method('execute') + ->with(DriverCommand::GET_ALL_COOKIES) + ->willReturn( + [ + [ + 'path' => '/', + 'domain' => '*.seleniumhq.org', + 'name' => 'cookieToFind', + 'httpOnly' => false, + 'secure' => true, + 'value' => 'value', + ], + [ + 'path' => '/', + 'domain' => 'docs.seleniumhq.org', + 'name' => 'otherCookie', + 'httpOnly' => false, + 'secure' => false, + 'value' => 'foo', + ], + ] + ); + + $options = new WebDriverOptions($this->executor); + + $cookie = $options->getCookieNamed('cookieToFind'); + + $this->assertSame('cookieToFind', $cookie['name']); + $this->assertSame('value', $cookie['value']); + $this->assertSame('/', $cookie['path']); + $this->assertSame('*.seleniumhq.org', $cookie['domain']); + $this->assertFalse($cookie['httpOnly']); + $this->assertTrue($cookie['secure']); + } + + public function testShouldReturnNullIfCookieWithNameNotFound() + { + $this->executor->expects($this->once()) + ->method('execute') + ->with(DriverCommand::GET_ALL_COOKIES) + ->willReturn( + [ + [ + 'path' => '/', + 'domain' => '*.seleniumhq.org', + 'name' => 'cookieToNotFind', + 'httpOnly' => false, + 'secure' => true, + 'value' => 'value', + ], + ] + ); + + $options = new WebDriverOptions($this->executor); + + $this->assertNull($options->getCookieNamed('notExistingCookie')); + } +} From c2e3e30af9d6880f2b07cea0e6b280196aea03ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 27 Jan 2017 20:54:04 +0100 Subject: [PATCH 306/784] Set/receive cookie using Cookie value object instead of an array --- CHANGELOG.md | 3 ++ lib/WebDriverOptions.php | 59 ++++++++++------------------- tests/unit/WebDriverOptionsTest.php | 59 +++++++++++++++++++++++++---- 3 files changed, 75 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04ce2d4dc..1d24e1582 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +### Changed +- Cookies should now be set using `Cookie` value object instead of an array when passed to to `addCookie()` method of `WebDriverOptions`. +- Cookies retrieved using `getCookieNamed()` and `getCookies()` methods of `WebDriverOptions` are now encapsulated in `Cookie` object instead of an plain array. The object implements `ArrayAccess` interface to provide backward compatibility. ## 1.3.0 - 2017-01-13 ### Added diff --git a/lib/WebDriverOptions.php b/lib/WebDriverOptions.php index 14cacd176..9791b9f1c 100644 --- a/lib/WebDriverOptions.php +++ b/lib/WebDriverOptions.php @@ -37,27 +37,22 @@ public function __construct(ExecuteMethod $executor) /** * Add a specific cookie. * - * Valid attributes of a cookie array: - * 'name' : string The name of the cookie; may not be null or an empty string. - * 'value' : string The cookie value; may not be null. - * 'path' : string OPTIONAL The path the cookie is visible to. Defaults to "/" if omitted. - * 'domain' : string OPTIONAL The domain the cookie is visible to. Defaults to the current browsing context's - * document's URL domain if omitted. - * 'secure' : bool OPTIONAL Whether this cookie requires a secure connection (https). Defaults to false if - * omitted. - * 'httpOnly': bool OPTIONAL Whether the cookie is an HTTP only cookie. Defaults to false if omitted. - * 'expiry' : int OPTIONAL The cookie's expiration date, specified in seconds since Unix Epoch. - * - * @see https://w3c.github.io/webdriver/webdriver-spec.html#cookies - * @param array $cookie An array with key as the attributes mentioned above. + * @see Facebook\WebDriver\Cookie for description of possible cookie properties + * @param Cookie|array $cookie Cookie object. May be also created from array for compatibility reasons. * @return WebDriverOptions The current instance. */ - public function addCookie(array $cookie) + public function addCookie($cookie) { - $this->validateCookie($cookie); + if (is_array($cookie)) { + $cookie = Cookie::createFromArray($cookie); + } + if (!$cookie instanceof Cookie) { + throw new InvalidArgumentException('Cookie must be set from instance of Cookie class or from array.'); + } + $this->executor->execute( DriverCommand::ADD_COOKIE, - ['cookie' => $cookie] + ['cookie' => $cookie->toArray()] ); return $this; @@ -95,7 +90,7 @@ public function deleteCookieNamed($name) * Get the cookie with a given name. * * @param string $name - * @return array The cookie, or null if no cookie with the given name is presented. + * @return Cookie The cookie, or null if no cookie with the given name is presented. */ public function getCookieNamed($name) { @@ -112,11 +107,18 @@ public function getCookieNamed($name) /** * Get all the cookies for the current domain. * - * @return array The array of cookies presented. + * @return Cookie[] The array of cookies presented. */ public function getCookies() { - return $this->executor->execute(DriverCommand::GET_ALL_COOKIES); + $cookieArrays = $this->executor->execute(DriverCommand::GET_ALL_COOKIES); + $cookies = []; + + foreach ($cookieArrays as $cookieArray) { + $cookies[] = Cookie::createFromArray($cookieArray); + } + + return $cookies; } /** @@ -165,23 +167,4 @@ public function getAvailableLogTypes() { return $this->executor->execute(DriverCommand::GET_AVAILABLE_LOG_TYPES); } - - /** - * @param array $cookie - * @throws \InvalidArgumentException - */ - private function validateCookie(array $cookie) - { - if (!isset($cookie['name']) || $cookie['name'] === '' || mb_strpos($cookie['name'], ';') !== false) { - throw new InvalidArgumentException('"name" should be non-empty and does not contain a ";"'); - } - - if (!isset($cookie['value'])) { - throw new InvalidArgumentException('"value" is required when setting a cookie.'); - } - - if (isset($cookie['domain']) && mb_strpos($cookie['domain'], ':') !== false) { - throw new InvalidArgumentException('"domain" should not contain a port:' . (string) $cookie['domain']); - } - } } diff --git a/tests/unit/WebDriverOptionsTest.php b/tests/unit/WebDriverOptionsTest.php index f95671470..38f329726 100644 --- a/tests/unit/WebDriverOptionsTest.php +++ b/tests/unit/WebDriverOptionsTest.php @@ -54,6 +54,47 @@ public function testShouldAddCookieFromArray() $options->addCookie($cookieInArray); } + public function testShouldAddCookieFromCookieObject() + { + $cookieObject = new Cookie('cookieName', 'someValue'); + $cookieObject->setPath('/bar'); + $cookieObject->setDomain('foo'); + $cookieObject->setExpiry(1485388333); + $cookieObject->setSecure(false); + $cookieObject->setHttpOnly(false); + + $expectedCookieData = [ + 'name' => 'cookieName', + 'value' => 'someValue', + 'path' => '/bar', + 'domain' => 'foo', + 'expiry' => 1485388333, + 'secure' => false, + 'httpOnly' => false, + ]; + + $this->executor->expects($this->once()) + ->method('execute') + ->with(DriverCommand::ADD_COOKIE, ['cookie' => $expectedCookieData]); + + $options = new WebDriverOptions($this->executor); + + $options->addCookie($cookieObject); + } + + public function testShouldNotAllowToCreateCookieFromDifferentObjectThanCookie() + { + $notCookie = new \stdClass(); + + $options = new WebDriverOptions($this->executor); + + $this->setExpectedException( + \InvalidArgumentException::class, + 'Cookie must be set from instance of Cookie class or from array.' + ); + $options->addCookie($notCookie); + } + public function testShouldGetAllCookies() { $this->executor->expects($this->once()) @@ -85,8 +126,9 @@ public function testShouldGetAllCookies() $cookies = $options->getCookies(); $this->assertCount(2, $cookies); - $this->assertSame('firstCookie', $cookies[0]['name']); - $this->assertSame('secondCookie', $cookies[1]['name']); + $this->assertContainsOnlyInstancesOf(Cookie::class, $cookies); + $this->assertSame('firstCookie', $cookies[0]->getName()); + $this->assertSame('secondCookie', $cookies[1]->getName()); } public function testShouldGetCookieByName() @@ -119,12 +161,13 @@ public function testShouldGetCookieByName() $cookie = $options->getCookieNamed('cookieToFind'); - $this->assertSame('cookieToFind', $cookie['name']); - $this->assertSame('value', $cookie['value']); - $this->assertSame('/', $cookie['path']); - $this->assertSame('*.seleniumhq.org', $cookie['domain']); - $this->assertFalse($cookie['httpOnly']); - $this->assertTrue($cookie['secure']); + $this->assertInstanceOf(Cookie::class, $cookie); + $this->assertSame('cookieToFind', $cookie->getName()); + $this->assertSame('value', $cookie->getValue()); + $this->assertSame('/', $cookie->getPath()); + $this->assertSame('*.seleniumhq.org', $cookie->getDomain()); + $this->assertFalse($cookie->isHttpOnly()); + $this->assertTrue($cookie->isSecure()); } public function testShouldReturnNullIfCookieWithNameNotFound() From e722283fc5b6d9fe8a420b32eb269a13684af527 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 28 Jan 2017 12:45:34 +0100 Subject: [PATCH 307/784] Update example.php to use the Cookie object --- example.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/example.php b/example.php index 03b16728e..7bebd10b5 100644 --- a/example.php +++ b/example.php @@ -18,10 +18,10 @@ // adding cookie $driver->manage()->deleteAllCookies(); -$driver->manage()->addCookie([ - 'name' => 'cookie_name', - 'value' => 'cookie_value', -]); + +$cookie = new Cookie('cookie_name', 'cookie_value'); +$driver->manage()->addCookie($cookie); + $cookies = $driver->manage()->getCookies(); print_r($cookies); From 1b303fdbed19c7825a92b8e225c25031f338fdf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Thu, 2 Feb 2017 22:37:31 +0100 Subject: [PATCH 308/784] Add functional tests for WebDriverTimeouts --- tests/functional/WebDriverTimeoutsTest.php | 68 ++++++++++++++++++++++ tests/functional/web/delayed_element.html | 19 ++++++ tests/functional/web/index.html | 4 ++ tests/functional/web/slow_loading.html | 14 +++++ tests/functional/web/slow_pixel.png.php | 10 ++++ 5 files changed, 115 insertions(+) create mode 100644 tests/functional/WebDriverTimeoutsTest.php create mode 100644 tests/functional/web/delayed_element.html create mode 100644 tests/functional/web/slow_loading.html create mode 100644 tests/functional/web/slow_pixel.png.php diff --git a/tests/functional/WebDriverTimeoutsTest.php b/tests/functional/WebDriverTimeoutsTest.php new file mode 100644 index 000000000..b7a7eb183 --- /dev/null +++ b/tests/functional/WebDriverTimeoutsTest.php @@ -0,0 +1,68 @@ +driver->get($this->getTestPath('delayed_element.html')); + + $this->setExpectedException(NoSuchElementException::class); + $this->driver->findElement(WebDriverBy::id('delayed')); + } + + /** + * @covers ::implicitlyWait + */ + public function testShouldGetDelayedElementWithImplicitWait() + { + $this->driver->get($this->getTestPath('delayed_element.html')); + + $this->driver->manage()->timeouts()->implicitlyWait(1); + $element = $this->driver->findElement(WebDriverBy::id('delayed')); + + $this->assertInstanceOf(RemoteWebElement::class, $element); + } + + /** + * @covers ::pageLoadTimeout + */ + public function testShouldFailIfPageIsLoadingLongerThanPageLoadTimeout() + { + if ($this->desiredCapabilities->getBrowserName() == WebDriverBrowserType::HTMLUNIT) { + $this->markTestSkipped('Not supported by HtmlUnit browser'); + } + + $this->driver->manage()->timeouts()->pageLoadTimeout(1); + + try { + $this->driver->get($this->getTestPageUrl('slow_loading.html')); + $this->fail('ScriptTimeoutException or TimeOutException exception should be thrown'); + } catch (TimeOutException $e) { // thrown by Selenium 3.0.0+ + } catch (ScriptTimeoutException $e) { // thrown by Selenium 2 + } + } +} diff --git a/tests/functional/web/delayed_element.html b/tests/functional/web/delayed_element.html new file mode 100644 index 000000000..b0f057a9a --- /dev/null +++ b/tests/functional/web/delayed_element.html @@ -0,0 +1,19 @@ + + + + + php-webdriver test page with delayed element appearing + + + +

    + + + + + diff --git a/tests/functional/web/index.html b/tests/functional/web/index.html index f0dc03af4..c3d53c4a3 100644 --- a/tests/functional/web/index.html +++ b/tests/functional/web/index.html @@ -12,6 +12,10 @@

    Welcome to the facebook/php-webdriver testing page.

    Form with file upload | New window opener test page + | + Delayed render + | + Slow loading page

    Test by ID

    Test by Class

    diff --git a/tests/functional/web/slow_loading.html b/tests/functional/web/slow_loading.html new file mode 100644 index 000000000..984272bf3 --- /dev/null +++ b/tests/functional/web/slow_loading.html @@ -0,0 +1,14 @@ + + + + + php-webdriver test page which is taking long to load + + + +

    This page is loading slowly

    + +Slowly loading pixel + + + diff --git a/tests/functional/web/slow_pixel.png.php b/tests/functional/web/slow_pixel.png.php new file mode 100644 index 000000000..d95805e21 --- /dev/null +++ b/tests/functional/web/slow_pixel.png.php @@ -0,0 +1,10 @@ + Date: Fri, 3 Feb 2017 01:08:44 +0100 Subject: [PATCH 309/784] Minor phpdoc formatting fixes --- lib/Remote/RemoteWebDriver.php | 14 ++++++-------- lib/WebDriverTimeouts.php | 9 +++------ 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index ce7450720..ed69c23ac 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -274,9 +274,8 @@ public function quit() } /** - * Inject a snippet of JavaScript into the page for execution in the context - * of the currently selected frame. The executed script is assumed to be - * synchronous and the result of evaluating the script will be returned. + * Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. + * The executed script is assumed to be synchronous and the result of evaluating the script will be returned. * * @param string $script The script to inject. * @param array $arguments The arguments of the script. @@ -293,13 +292,12 @@ public function executeScript($script, array $arguments = []) } /** - * Inject a snippet of JavaScript into the page for asynchronous execution in - * the context of the currently selected frame. + * Inject a snippet of JavaScript into the page for asynchronous execution in the context of the currently selected + * frame. * - * The driver will pass a callback as the last argument to the snippet, and - * block until the callback is invoked. + * The driver will pass a callback as the last argument to the snippet, and block until the callback is invoked. * - * @see WebDriverExecuteAsyncScriptTestCase + * You may need to define script timeout using `setScriptTimeout()` method of `WebDriverTimeouts` first. * * @param string $script The script to inject. * @param array $arguments The arguments of the script. diff --git a/lib/WebDriverTimeouts.php b/lib/WebDriverTimeouts.php index d62f2a124..6903f7080 100644 --- a/lib/WebDriverTimeouts.php +++ b/lib/WebDriverTimeouts.php @@ -34,8 +34,7 @@ public function __construct(ExecuteMethod $executor) } /** - * Specify the amount of time the driver should wait when searching for an - * element if it is not immediately present. + * Specify the amount of time the driver should wait when searching for an element if it is not immediately present. * * @param int $seconds Wait time in second. * @return WebDriverTimeouts The current instance. @@ -51,8 +50,7 @@ public function implicitlyWait($seconds) } /** - * Set the amount of time to wait for an asynchronous script to finish - * execution before throwing an error. + * Set the amount of time to wait for an asynchronous script to finish execution before throwing an error. * * @param int $seconds Wait time in second. * @return WebDriverTimeouts The current instance. @@ -68,8 +66,7 @@ public function setScriptTimeout($seconds) } /** - * Set the amount of time to wait for a page load to complete before throwing - * an error. + * Set the amount of time to wait for a page load to complete before throwing an error. * * @param int $seconds Wait time in second. * @return WebDriverTimeouts The current instance. From 91b92332630c24556b608d7c9b31274d9bd36358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 3 Feb 2017 01:12:28 +0100 Subject: [PATCH 310/784] Add some more unit tests for WebDriverOptions --- tests/unit/WebDriverOptionsTest.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/unit/WebDriverOptionsTest.php b/tests/unit/WebDriverOptionsTest.php index 38f329726..5e335854f 100644 --- a/tests/unit/WebDriverOptionsTest.php +++ b/tests/unit/WebDriverOptionsTest.php @@ -192,4 +192,20 @@ public function testShouldReturnNullIfCookieWithNameNotFound() $this->assertNull($options->getCookieNamed('notExistingCookie')); } + + public function testShouldReturnTimeoutsInstance() + { + $options = new WebDriverOptions($this->executor); + + $timeouts = $options->timeouts(); + $this->assertInstanceOf(WebDriverTimeouts::class, $timeouts); + } + + public function testShouldReturnWindowInstance() + { + $options = new WebDriverOptions($this->executor); + + $window = $options->window(); + $this->assertInstanceOf(WebDriverWindow::class, $window); + } } From 7a6bf0dd9c785e11660c798e3d895d83babf2306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 7 Feb 2017 23:45:13 +0100 Subject: [PATCH 311/784] Fix incorrect covers annotation --- tests/functional/RemoteWebDriverTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/functional/RemoteWebDriverTest.php b/tests/functional/RemoteWebDriverTest.php index 918b3514b..847479afa 100644 --- a/tests/functional/RemoteWebDriverTest.php +++ b/tests/functional/RemoteWebDriverTest.php @@ -131,7 +131,7 @@ public function testShouldGetWindowHandles() } /** - * @covers ::getWindowHandles + * @covers ::close */ public function testShouldCloseWindow() { From 2a7a3537450331d9c6a7f6f9e06587858a8ce903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 7 Feb 2017 23:52:33 +0100 Subject: [PATCH 312/784] Add missing phpdoc --- lib/Remote/RemoteWebDriver.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index ed69c23ac..58381cff4 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -59,6 +59,11 @@ class RemoteWebDriver implements WebDriver, JavaScriptExecutor, WebDriverHasInpu */ protected $executeMethod; + /** + * @param HttpCommandExecutor $commandExecutor + * @param string $sessionId + * @param WebDriverCapabilities|null $capabilities + */ protected function __construct( HttpCommandExecutor $commandExecutor, $sessionId, From ca4300c0be26750dd94eb4694f9ca78ee96cf8d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 7 Feb 2017 23:57:58 +0100 Subject: [PATCH 313/784] Add unit tests for parts of RemoteWebDriver which do not interact with the real remote --- tests/unit/Remote/HttpCommandExecutorTest.php | 1 + tests/unit/Remote/RemoteWebDriverTest.php | 117 ++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 tests/unit/Remote/RemoteWebDriverTest.php diff --git a/tests/unit/Remote/HttpCommandExecutorTest.php b/tests/unit/Remote/HttpCommandExecutorTest.php index 268b3e873..63d004e6b 100644 --- a/tests/unit/Remote/HttpCommandExecutorTest.php +++ b/tests/unit/Remote/HttpCommandExecutorTest.php @@ -20,6 +20,7 @@ class HttpCommandExecutorTest extends \PHPUnit_Framework_TestCase { use PHPMock; + /** @var HttpCommandExecutor */ private $executor; diff --git a/tests/unit/Remote/RemoteWebDriverTest.php b/tests/unit/Remote/RemoteWebDriverTest.php new file mode 100644 index 000000000..48b149f84 --- /dev/null +++ b/tests/unit/Remote/RemoteWebDriverTest.php @@ -0,0 +1,117 @@ +driver = RemoteWebDriver::createBySessionID('session-id', 'http://foo.bar:4444/'); + } + + /** + * @covers ::manage + */ + public function testShouldCreateWebDriverOptionsInstance() + { + $wait = $this->driver->manage(); + + $this->assertInstanceOf(WebDriverOptions::class, $wait); + } + + /** + * @covers ::navigate + */ + public function testShouldCreateWebDriverNavigationInstance() + { + $wait = $this->driver->navigate(); + + $this->assertInstanceOf(WebDriverNavigation::class, $wait); + } + + /** + * @covers ::switchTo + */ + public function testShouldCreateRemoteTargetLocatorInstance() + { + $wait = $this->driver->switchTo(); + + $this->assertInstanceOf(RemoteTargetLocator::class, $wait); + } + + /** + * @covers ::getMouse + */ + public function testShouldCreateRemoteMouseInstance() + { + $wait = $this->driver->getMouse(); + + $this->assertInstanceOf(RemoteMouse::class, $wait); + } + + /** + * @covers ::getKeyboard + */ + public function testShouldCreateRemoteKeyboardInstance() + { + $wait = $this->driver->getKeyboard(); + + $this->assertInstanceOf(RemoteKeyboard::class, $wait); + } + + /** + * @covers ::getTouch + */ + public function testShouldCreateRemoteTouchScreenInstance() + { + $wait = $this->driver->getTouch(); + + $this->assertInstanceOf(RemoteTouchScreen::class, $wait); + } + + /** + * @covers ::action + */ + public function testShouldCreateWebDriverActionsInstance() + { + $wait = $this->driver->action(); + + $this->assertInstanceOf(WebDriverActions::class, $wait); + } + + /** + * @covers ::wait + */ + public function testShouldCreateWebDriverWaitInstance() + { + $wait = $this->driver->wait(15, 1337); + + $this->assertInstanceOf(WebDriverWait::class, $wait); + } +} From 4eb204b350c4647775b0137908a62a9f3b912c09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 8 Feb 2017 00:51:28 +0100 Subject: [PATCH 314/784] Test reusing WebDriver session ID --- lib/Remote/RemoteWebDriver.php | 2 +- tests/functional/RemoteWebDriverCreateTest.php | 17 +++++++++++++++++ tests/functional/WebDriverTestCase.php | 1 - 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index 58381cff4..f8b8e5e6e 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -135,7 +135,7 @@ public static function create( * [Experimental] Construct the RemoteWebDriver by an existing session. * * This constructor can boost the performance a lot by reusing the same browser for the whole test suite. - * You cannot the desired capabilities because the session was created before. + * You cannot pass the desired capabilities because the session was created before. * * @param string $selenium_server_url The url of the remote Selenium WebDriver server * @param string $session_id The existing session id diff --git a/tests/functional/RemoteWebDriverCreateTest.php b/tests/functional/RemoteWebDriverCreateTest.php index 4f05a4319..161adb2bf 100644 --- a/tests/functional/RemoteWebDriverCreateTest.php +++ b/tests/functional/RemoteWebDriverCreateTest.php @@ -60,4 +60,21 @@ public function testShouldCreateWebDriverWithRequiredCapabilities() $this->assertInstanceOf(RemoteWebDriver::class, $this->driver); } + + public function testShouldCreateInstanceFromExistingSessionId() + { + // Create driver instance and load page "index.html" + $originalDriver = RemoteWebDriver::create($this->serverUrl, $this->desiredCapabilities); + $originalDriver->get($this->getTestPath('index.html')); + $this->assertContains('/index.html', $originalDriver->getCurrentURL()); + + // Store session ID + $sessionId = $originalDriver->getSessionID(); + + // Create new RemoteWebDriver instance based on the session ID + $this->driver = RemoteWebDriver::createBySessionID($sessionId); + + // Check we reused the previous instance (window) and it has the same URL + $this->assertContains('/index.html', $this->driver->getCurrentURL()); + } } diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index 8c2fd4b8d..5626d1e82 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -29,7 +29,6 @@ class WebDriverTestCase extends \PHPUnit_Framework_TestCase protected $createWebDriver = true; /** @var string */ protected $serverUrl = 'http://localhost:4444/wd/hub'; - /** @var RemoteWebDriver $driver */ protected $driver; /** @var DesiredCapabilities */ From 67cb575fc727530d6c4cb4a852dd34b45f036074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 8 Feb 2017 01:04:42 +0100 Subject: [PATCH 315/784] Add new php-cs-fixer rule --- .php_cs.dist | 1 + 1 file changed, 1 insertion(+) diff --git a/.php_cs.dist b/.php_cs.dist index c40510179..d95f9d0fc 100644 --- a/.php_cs.dist +++ b/.php_cs.dist @@ -71,6 +71,7 @@ return PhpCsFixer\Config::create() 'trailing_comma_in_multiline_array' => true, 'trim_array_spaces' => true, 'unary_operator_spaces' => true, + 'visibility_required' => true, 'whitespace_after_comma_in_array' => true, ]) ->setRiskyAllowed(true) From 7cd8e163883a6dd22f0c5f6372fba05e5b8d2785 Mon Sep 17 00:00:00 2001 From: Nino Date: Wed, 8 Feb 2017 13:09:02 +0100 Subject: [PATCH 316/784] Added ext-zip to require section of composer.json (#410) * Added ext-zip to require section of composer.json, as it is required by file upload and firefox profile. --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 9114afdd8..3523361f9 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,8 @@ "require": { "php": "^5.5 || ~7.0", "symfony/process": "^2.8 || ^3.1", - "ext-curl": "*" + "ext-curl": "*", + "ext-zip": "*" }, "require-dev": { "phpunit/phpunit": "4.6.* || ~5.0", From 7b5d48850ad5f8085363c839fc2d250a7af62732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 8 Feb 2017 14:30:47 +0100 Subject: [PATCH 317/784] Mark executeSQL command deprecated - as it was removed from officialn java bindings in 2014 --- lib/Remote/DriverCommand.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/Remote/DriverCommand.php b/lib/Remote/DriverCommand.php index e2ce958b5..1b86c71c6 100644 --- a/lib/Remote/DriverCommand.php +++ b/lib/Remote/DriverCommand.php @@ -83,6 +83,7 @@ class DriverCommand const SET_TIMEOUT = 'setTimeout'; const IMPLICITLY_WAIT = 'implicitlyWait'; const SET_SCRIPT_TIMEOUT = 'setScriptTimeout'; + /** @deprecated */ const EXECUTE_SQL = 'executeSQL'; const GET_LOCATION = 'getLocation'; const SET_LOCATION = 'setLocation'; @@ -91,18 +92,21 @@ class DriverCommand const CLEAR_APP_CACHE = 'clearAppCache'; const IS_BROWSER_ONLINE = 'isBrowserOnline'; const SET_BROWSER_ONLINE = 'setBrowserOnline'; + // Local storage const GET_LOCAL_STORAGE_ITEM = 'getLocalStorageItem'; const GET_LOCAL_STORAGE_KEYS = 'getLocalStorageKeys'; const SET_LOCAL_STORAGE_ITEM = 'setLocalStorageItem'; const REMOVE_LOCAL_STORAGE_ITEM = 'removeLocalStorageItem'; const CLEAR_LOCAL_STORAGE = 'clearLocalStorage'; const GET_LOCAL_STORAGE_SIZE = 'getLocalStorageSize'; + // Session storage const GET_SESSION_STORAGE_ITEM = 'getSessionStorageItem'; const GET_SESSION_STORAGE_KEYS = 'getSessionStorageKey'; const SET_SESSION_STORAGE_ITEM = 'setSessionStorageItem'; const REMOVE_SESSION_STORAGE_ITEM = 'removeSessionStorageItem'; const CLEAR_SESSION_STORAGE = 'clearSessionStorage'; const GET_SESSION_STORAGE_SIZE = 'getSessionStorageSize'; + // Screen orientation const SET_SCREEN_ORIENTATION = 'setScreenOrientation'; const GET_SCREEN_ORIENTATION = 'getScreenOrientation'; // These belong to the Advanced user interactions - an element is optional for these commands. From 58a942c1091939e02eb6aa2f56c0ebb2d2c9aaa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 8 Feb 2017 20:49:38 +0100 Subject: [PATCH 318/784] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d24e1582..6b99a4f66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ### Changed - Cookies should now be set using `Cookie` value object instead of an array when passed to to `addCookie()` method of `WebDriverOptions`. - Cookies retrieved using `getCookieNamed()` and `getCookies()` methods of `WebDriverOptions` are now encapsulated in `Cookie` object instead of an plain array. The object implements `ArrayAccess` interface to provide backward compatibility. +- `ext-zip` is now specified as required dependency in composer.json (but the extension was already required by the code, though). ## 1.3.0 - 2017-01-13 ### Added From 47191c71d0024d1158326a5178dc931a1915ebd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 8 Feb 2017 01:53:36 +0100 Subject: [PATCH 319/784] Add WebDriverAlert functional test --- tests/functional/WebDriverAlertTest.php | 103 ++++++++++++++++++++++++ tests/functional/web/alert.html | 35 ++++++++ tests/functional/web/index.html | 2 + 3 files changed, 140 insertions(+) create mode 100644 tests/functional/WebDriverAlertTest.php create mode 100644 tests/functional/web/alert.html diff --git a/tests/functional/WebDriverAlertTest.php b/tests/functional/WebDriverAlertTest.php new file mode 100644 index 000000000..ce403c549 --- /dev/null +++ b/tests/functional/WebDriverAlertTest.php @@ -0,0 +1,103 @@ +driver->get($this->getTestPath('alert.html')); + } + + public function testShouldAcceptAlert() + { + // Open alert + $this->driver->findElement(WebDriverBy::id('open-alert'))->click(); + + // Wait until present + $this->driver->wait()->until(WebDriverExpectedCondition::alertIsPresent()); + + $this->assertSame('This is alert', $this->driver->switchTo()->alert()->getText()); + + $this->driver->switchTo()->alert()->accept(); + + $this->setExpectedException(NoAlertOpenException::class); + $this->driver->switchTo()->alert()->accept(); + } + + public function testShouldAcceptAndDismissConfirmation() + { + if ($this->desiredCapabilities->getBrowserName() == WebDriverBrowserType::HTMLUNIT) { + /** @see https://github.com/SeleniumHQ/htmlunit-driver/issues/14 */ + $this->markTestSkipped('Not supported by HtmlUnit browser'); + } + + // Open confirmation + $this->driver->findElement(WebDriverBy::id('open-confirm'))->click(); + + // Wait until present + $this->driver->wait()->until(WebDriverExpectedCondition::alertIsPresent()); + + $this->assertSame('Do you confirm?', $this->driver->switchTo()->alert()->getText()); + + // Test accepting + $this->driver->switchTo()->alert()->accept(); + $this->assertSame('accepted', $this->getResultText()); + + // Open confirmation + $this->driver->findElement(WebDriverBy::id('open-confirm'))->click(); + + // Test dismissal + $this->driver->switchTo()->alert()->dismiss(); + $this->assertSame('dismissed', $this->getResultText()); + } + + public function testShouldSubmitPromptText() + { + if ($this->desiredCapabilities->getBrowserName() == WebDriverBrowserType::HTMLUNIT) { + /** @see https://github.com/SeleniumHQ/htmlunit-driver/issues/14 */ + $this->markTestSkipped('Not supported by HtmlUnit browser'); + } + + // Open confirmation + $this->driver->findElement(WebDriverBy::id('open-prompt'))->click(); + + // Wait until present + $this->driver->wait()->until(WebDriverExpectedCondition::alertIsPresent()); + + $this->assertSame('Enter prompt value', $this->driver->switchTo()->alert()->getText()); + + $this->driver->switchTo()->alert()->sendKeys('Text entered to prompt'); + $this->driver->switchTo()->alert()->accept(); + + $this->assertSame('Text entered to prompt', $this->getResultText()); + } + + private function getResultText() + { + return $this->driver + ->findElement(WebDriverBy::id('result')) + ->getText(); + } +} diff --git a/tests/functional/web/alert.html b/tests/functional/web/alert.html new file mode 100644 index 000000000..079d75130 --- /dev/null +++ b/tests/functional/web/alert.html @@ -0,0 +1,35 @@ + + + + + Open an alert + + + +

    + Open alert +
    + + Open confirm +
    + + Open prompt +
    +

    + +
    + + + + + diff --git a/tests/functional/web/index.html b/tests/functional/web/index.html index c3d53c4a3..8e314f798 100644 --- a/tests/functional/web/index.html +++ b/tests/functional/web/index.html @@ -16,6 +16,8 @@

    Welcome to the facebook/php-webdriver testing page.

    Delayed render | Slow loading page + | + Javascript alerts

    Test by ID

    Test by Class

    From ff3c556707cb1524ad99d4752db496ab574bf41d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 10 Feb 2017 15:02:01 +0100 Subject: [PATCH 320/784] Prepare toArray() method to be added to WebDriverCapabilities interface in next major version --- lib/WebDriver.php | 2 +- lib/WebDriverCapabilities.php | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/WebDriver.php b/lib/WebDriver.php index ea413f883..f6e8200ae 100755 --- a/lib/WebDriver.php +++ b/lib/WebDriver.php @@ -128,9 +128,9 @@ public function navigate(); */ public function switchTo(); + // TODO: Add in next major release (BC) ///** // * @return WebDriverTouchScreen - // * @todo Add in next major release (BC) // */ //public function getTouch(); diff --git a/lib/WebDriverCapabilities.php b/lib/WebDriverCapabilities.php index 6fce03c08..b489a1e6e 100644 --- a/lib/WebDriverCapabilities.php +++ b/lib/WebDriverCapabilities.php @@ -48,4 +48,10 @@ public function is($capability_name); * @return bool Whether javascript is enabled. */ public function isJavascriptEnabled(); + + // TODO: Add in next major release (BC) + ///** + // * @return array + // */ + //public function toArray(); } From 85f8ac1e4705f92ea2b4d2abe4f164c36cce6809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 18 Dec 2016 01:27:57 +0100 Subject: [PATCH 321/784] Run tests on SauceLabs --- .travis.yml | 18 ++++++- tests/functional/FileUploadTest.php | 2 +- .../functional/RemoteWebDriverCreateTest.php | 6 +-- .../RemoteWebDriverFindElementTest.php | 8 +-- tests/functional/RemoteWebDriverTest.php | 28 ++++++----- tests/functional/RemoteWebElementTest.php | 24 ++++----- tests/functional/WebDriverAlertTest.php | 2 +- tests/functional/WebDriverByTest.php | 2 +- tests/functional/WebDriverSelectTest.php | 2 +- tests/functional/WebDriverTestCase.php | 50 +++++++++++++------ tests/functional/WebDriverTimeoutsTest.php | 4 +- 11 files changed, 93 insertions(+), 53 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7c0cd3e77..f7229a2c3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,12 +8,25 @@ php: matrix: include: - # Add build to run tests against Firefox (other runs are agains HtmlUnit by default) + # Add build to run tests against Firefox inside Travis environment (other runs are agains HtmlUnit by default) - php: 7.0 env: BROWSER_NAME="firefox" + # Build with lowest possible dependencies - php: 7.0 env: dependencies="--prefer-lowest" + + # Saucelabs builds + - php: 7.0 + env: SAUCELABS=1 BROWSER_NAME="firefox" VERSION="47.0" PLATFORM="Windows 10" + before_script: php -S localhost:8000 -t tests/functional/web/ &>>./logs/php-server.log & + - php: 7.0 + env: SAUCELABS=1 BROWSER_NAME="firefox" VERSION="45.0" PLATFORM="Linux" + before_script: php -S localhost:8000 -t tests/functional/web/ &>>./logs/php-server.log & + - php: 7.0 + env: SAUCELABS=1 BROWSER_NAME="chrome" VERSION="latest" PLATFORM="Windows 10" + before_script: php -S localhost:8000 -t tests/functional/web/ &>>./logs/php-server.log & + # Add PHP 7 build to check codestyle only in PHP 7 build - php: 7.0 env: CHECK_CODESTYLE=1 @@ -66,3 +79,6 @@ addons: apt: packages: - oracle-java8-installer + sauce_connect: true + jwt: + secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= diff --git a/tests/functional/FileUploadTest.php b/tests/functional/FileUploadTest.php index e8878e642..ef6cf1bb2 100644 --- a/tests/functional/FileUploadTest.php +++ b/tests/functional/FileUploadTest.php @@ -52,7 +52,7 @@ public function testShouldUploadAFile() public function xtestUselessFileDetectorSendKeys() { - $this->driver->get($this->getTestPath('upload.html')); + $this->driver->get($this->getTestPageUrl('upload.html')); $file_input = $this->driver->findElement(WebDriverBy::id('upload')); $file_input->sendKeys($this->getTestFilePath()); diff --git a/tests/functional/RemoteWebDriverCreateTest.php b/tests/functional/RemoteWebDriverCreateTest.php index 161adb2bf..95ff4851c 100644 --- a/tests/functional/RemoteWebDriverCreateTest.php +++ b/tests/functional/RemoteWebDriverCreateTest.php @@ -34,7 +34,7 @@ public function testShouldStartBrowserAndCreateInstanceOfRemoteWebDriver() $this->assertInstanceOf(RemoteWebDriver::class, $this->driver); $this->assertInstanceOf(HttpCommandExecutor::class, $this->driver->getCommandExecutor()); - $this->assertSame($this->serverUrl, $this->driver->getCommandExecutor()->getAddressOfRemoteServer()); + $this->assertNotEmpty($this->driver->getCommandExecutor()->getAddressOfRemoteServer()); $this->assertInternalType('string', $this->driver->getSessionID()); $this->assertNotEmpty($this->driver->getSessionID()); @@ -65,14 +65,14 @@ public function testShouldCreateInstanceFromExistingSessionId() { // Create driver instance and load page "index.html" $originalDriver = RemoteWebDriver::create($this->serverUrl, $this->desiredCapabilities); - $originalDriver->get($this->getTestPath('index.html')); + $originalDriver->get($this->getTestPageUrl('index.html')); $this->assertContains('/index.html', $originalDriver->getCurrentURL()); // Store session ID $sessionId = $originalDriver->getSessionID(); // Create new RemoteWebDriver instance based on the session ID - $this->driver = RemoteWebDriver::createBySessionID($sessionId); + $this->driver = RemoteWebDriver::createBySessionID($sessionId, $this->serverUrl); // Check we reused the previous instance (window) and it has the same URL $this->assertContains('/index.html', $this->driver->getCurrentURL()); diff --git a/tests/functional/RemoteWebDriverFindElementTest.php b/tests/functional/RemoteWebDriverFindElementTest.php index ad1daf348..808763bad 100644 --- a/tests/functional/RemoteWebDriverFindElementTest.php +++ b/tests/functional/RemoteWebDriverFindElementTest.php @@ -26,7 +26,7 @@ class RemoteWebDriverFindElementTest extends WebDriverTestCase { public function testShouldThrowExceptionOfElementCannotBeFound() { - $this->driver->get($this->getTestPath('index.html')); + $this->driver->get($this->getTestPageUrl('index.html')); $this->setExpectedException(NoSuchElementException::class, 'Unable to locate element'); $this->driver->findElement(WebDriverBy::id('not_existing')); @@ -34,7 +34,7 @@ public function testShouldThrowExceptionOfElementCannotBeFound() public function testShouldFindElementIfExistsOnAPage() { - $this->driver->get($this->getTestPath('index.html')); + $this->driver->get($this->getTestPageUrl('index.html')); $element = $this->driver->findElement(WebDriverBy::id('id_test')); @@ -43,7 +43,7 @@ public function testShouldFindElementIfExistsOnAPage() public function testShouldReturnEmptyArrayIfElementsCannotBeFound() { - $this->driver->get($this->getTestPath('index.html')); + $this->driver->get($this->getTestPageUrl('index.html')); $elements = $this->driver->findElements(WebDriverBy::cssSelector('not_existing')); @@ -53,7 +53,7 @@ public function testShouldReturnEmptyArrayIfElementsCannotBeFound() public function testShouldFindMultipleElements() { - $this->driver->get($this->getTestPath('index.html')); + $this->driver->get($this->getTestPageUrl('index.html')); $elements = $this->driver->findElements(WebDriverBy::cssSelector('ul > li')); diff --git a/tests/functional/RemoteWebDriverTest.php b/tests/functional/RemoteWebDriverTest.php index 847479afa..0f38d0f3c 100644 --- a/tests/functional/RemoteWebDriverTest.php +++ b/tests/functional/RemoteWebDriverTest.php @@ -29,7 +29,7 @@ class RemoteWebDriverTest extends WebDriverTestCase */ public function testShouldGetPageTitle() { - $this->driver->get($this->getTestPath('index.html')); + $this->driver->get($this->getTestPageUrl('index.html')); $this->assertEquals( 'php-webdriver test page', @@ -43,7 +43,7 @@ public function testShouldGetPageTitle() */ public function testShouldGetCurrentUrl() { - $this->driver->get($this->getTestPath('index.html')); + $this->driver->get($this->getTestPageUrl('index.html')); $this->assertContains( '/index.html', @@ -56,7 +56,7 @@ public function testShouldGetCurrentUrl() */ public function testShouldGetPageSource() { - $this->driver->get($this->getTestPath('index.html')); + $this->driver->get($this->getTestPageUrl('index.html')); $source = $this->driver->getPageSource(); $this->assertContains('

    ', $source); @@ -79,7 +79,9 @@ public function testShouldGetSessionId() */ public function testShouldGetAllSessions() { - $sessions = RemoteWebDriver::getAllSessions(); + $this->skipOnSauceLabs('getAllSessions() is not supported on SauceLabs'); + + $sessions = RemoteWebDriver::getAllSessions($this->serverUrl); $this->assertInternalType('array', $sessions); $this->assertCount(1, $sessions); @@ -96,12 +98,14 @@ public function testShouldGetAllSessions() */ public function testShouldQuitAndUnsetExecutor() { - $this->assertCount(1, RemoteWebDriver::getAllSessions()); + $this->skipOnSauceLabs('getAllSessions() is not supported on SauceLabs'); + + $this->assertCount(1, RemoteWebDriver::getAllSessions($this->serverUrl)); $this->assertInstanceOf(HttpCommandExecutor::class, $this->driver->getCommandExecutor()); $this->driver->quit(); - $this->assertCount(0, RemoteWebDriver::getAllSessions()); + $this->assertCount(0, RemoteWebDriver::getAllSessions($this->serverUrl)); $this->assertNull($this->driver->getCommandExecutor()); } @@ -111,7 +115,7 @@ public function testShouldQuitAndUnsetExecutor() */ public function testShouldGetWindowHandles() { - $this->driver->get($this->getTestPath('open_new_window.html')); + $this->driver->get($this->getTestPageUrl('open_new_window.html')); $windowHandle = $this->driver->getWindowHandle(); $windowHandles = $this->driver->getWindowHandles(); @@ -135,7 +139,7 @@ public function testShouldGetWindowHandles() */ public function testShouldCloseWindow() { - $this->driver->get($this->getTestPath('open_new_window.html')); + $this->driver->get($this->getTestPageUrl('open_new_window.html')); $this->driver->findElement(WebDriverBy::cssSelector('a'))->click(); $this->assertCount(2, $this->driver->getWindowHandles()); @@ -150,7 +154,7 @@ public function testShouldCloseWindow() */ public function testShouldExecuteScriptAndDoNotBlockExecution() { - $this->driver->get($this->getTestPath('index.html')); + $this->driver->get($this->getTestPageUrl('index.html')); $element = $this->driver->findElement(WebDriverBy::id('id_test')); $this->assertSame('Test by ID', $element->getText()); @@ -176,7 +180,7 @@ public function testShouldExecuteAsyncScriptAndWaitUntilItIsFinished() { $this->driver->manage()->timeouts()->setScriptTimeout(1); - $this->driver->get($this->getTestPath('index.html')); + $this->driver->get($this->getTestPageUrl('index.html')); $element = $this->driver->findElement(WebDriverBy::id('id_test')); $this->assertSame('Test by ID', $element->getText()); @@ -209,7 +213,7 @@ public function testShouldTakeScreenshot() $this->markTestSkipped('Screenshots are not supported by HtmlUnit browser'); } - $this->driver->get($this->getTestPath('index.html')); + $this->driver->get($this->getTestPageUrl('index.html')); $outputPng = $this->driver->takeScreenshot(); @@ -234,7 +238,7 @@ public function testShouldSaveScreenshotToFile() $screenshotPath = sys_get_temp_dir() . '/selenium-screenshot.png'; - $this->driver->get($this->getTestPath('index.html')); + $this->driver->get($this->getTestPageUrl('index.html')); $this->driver->takeScreenshot($screenshotPath); diff --git a/tests/functional/RemoteWebElementTest.php b/tests/functional/RemoteWebElementTest.php index e5d1ead06..26d13f6e2 100644 --- a/tests/functional/RemoteWebElementTest.php +++ b/tests/functional/RemoteWebElementTest.php @@ -25,7 +25,7 @@ class RemoteWebElementTest extends WebDriverTestCase */ public function testShouldGetText() { - $this->driver->get($this->getTestPath('index.html')); + $this->driver->get($this->getTestPageUrl('index.html')); $elementWithSimpleText = $this->driver->findElement(WebDriverBy::id('text-simple')); $elementWithTextWithSpaces = $this->driver->findElement(WebDriverBy::id('text-with-spaces')); @@ -38,7 +38,7 @@ public function testShouldGetText() */ public function testShouldGetAttributeValue() { - $this->driver->get($this->getTestPath('index.html')); + $this->driver->get($this->getTestPageUrl('index.html')); $element = $this->driver->findElement(WebDriverBy::id('text-simple')); @@ -52,7 +52,7 @@ public function testShouldGetAttributeValue() */ public function testShouldGetLocation() { - $this->driver->get($this->getTestPath('index.html')); + $this->driver->get($this->getTestPageUrl('index.html')); $element = $this->driver->findElement(WebDriverBy::id('element-with-location')); @@ -67,7 +67,7 @@ public function testShouldGetLocation() */ public function testShouldGetSize() { - $this->driver->get($this->getTestPath('index.html')); + $this->driver->get($this->getTestPageUrl('index.html')); $element = $this->driver->findElement(WebDriverBy::id('element-with-location')); @@ -82,7 +82,7 @@ public function testShouldGetSize() */ public function testShouldGetCssValue() { - $this->driver->get($this->getTestPath('index.html')); + $this->driver->get($this->getTestPageUrl('index.html')); $elementWithBorder = $this->driver->findElement(WebDriverBy::id('text-simple')); $elementWithoutBorder = $this->driver->findElement(WebDriverBy::id('text-with-spaces')); @@ -99,7 +99,7 @@ public function testShouldGetCssValue() */ public function testShouldGetTagName() { - $this->driver->get($this->getTestPath('index.html')); + $this->driver->get($this->getTestPageUrl('index.html')); $paragraphElement = $this->driver->findElement(WebDriverBy::id('id_test')); @@ -111,7 +111,7 @@ public function testShouldGetTagName() */ public function testShouldClick() { - $this->driver->get($this->getTestPath('index.html')); + $this->driver->get($this->getTestPageUrl('index.html')); $linkElement = $this->driver->findElement(WebDriverBy::id('a-form')); $linkElement->click(); @@ -126,7 +126,7 @@ public function testShouldClick() */ public function testShouldClearFormElementText() { - $this->driver->get($this->getTestPath('form.html')); + $this->driver->get($this->getTestPageUrl('form.html')); $input = $this->driver->findElement(WebDriverBy::id('input-text')); $textarea = $this->driver->findElement(WebDriverBy::id('textarea')); @@ -145,7 +145,7 @@ public function testShouldClearFormElementText() */ public function testShouldSendKeysToFormElement() { - $this->driver->get($this->getTestPath('form.html')); + $this->driver->get($this->getTestPageUrl('form.html')); $input = $this->driver->findElement(WebDriverBy::id('input-text')); $textarea = $this->driver->findElement(WebDriverBy::id('textarea')); @@ -168,7 +168,7 @@ public function testShouldSendKeysToFormElement() */ public function testShouldDetectEnabledInputs() { - $this->driver->get($this->getTestPath('form.html')); + $this->driver->get($this->getTestPageUrl('form.html')); $inputEnabled = $this->driver->findElement(WebDriverBy::id('input-text')); $inputDisabled = $this->driver->findElement(WebDriverBy::id('input-text-disabled')); @@ -182,7 +182,7 @@ public function testShouldDetectEnabledInputs() */ public function testShouldSelectedInputsOrOptions() { - $this->driver->get($this->getTestPath('form.html')); + $this->driver->get($this->getTestPageUrl('form.html')); $checkboxSelected = $this->driver->findElement( WebDriverBy::cssSelector('input[name=checkbox][value=second]') @@ -263,7 +263,7 @@ public function testShouldSubmitFormByClickOnSubmitInput() */ public function testShouldCompareEqualsElement() { - $this->driver->get($this->getTestPath('index.html')); + $this->driver->get($this->getTestPageUrl('index.html')); $firstElement = $this->driver->findElement(WebDriverBy::cssSelector('ul.list')); $differentElement = $this->driver->findElement(WebDriverBy::cssSelector('#text-simple')); diff --git a/tests/functional/WebDriverAlertTest.php b/tests/functional/WebDriverAlertTest.php index ce403c549..eddf3a9ae 100644 --- a/tests/functional/WebDriverAlertTest.php +++ b/tests/functional/WebDriverAlertTest.php @@ -27,7 +27,7 @@ protected function setUp() { parent::setUp(); - $this->driver->get($this->getTestPath('alert.html')); + $this->driver->get($this->getTestPageUrl('alert.html')); } public function testShouldAcceptAlert() diff --git a/tests/functional/WebDriverByTest.php b/tests/functional/WebDriverByTest.php index 753790248..43d8c0457 100644 --- a/tests/functional/WebDriverByTest.php +++ b/tests/functional/WebDriverByTest.php @@ -36,7 +36,7 @@ public function testShouldFindTextElementByLocator( $expectedText = null, $expectedAttributeValue = null ) { - $this->driver->get($this->getTestPath('index.html')); + $this->driver->get($this->getTestPageUrl('index.html')); $by = call_user_func([WebDriverBy::class, $webDriverByLocatorMethod], $webDriverByLocatorValue); $element = $this->driver->findElement($by); diff --git a/tests/functional/WebDriverSelectTest.php b/tests/functional/WebDriverSelectTest.php index 3a7d55f24..ac32cbca7 100644 --- a/tests/functional/WebDriverSelectTest.php +++ b/tests/functional/WebDriverSelectTest.php @@ -29,7 +29,7 @@ protected function setUp() { parent::setUp(); - $this->driver->get($this->getTestPath('form.html')); + $this->driver->get($this->getTestPageUrl('form.html')); } public function testShouldCreateNewInstanceForSelectElementAndDetectIfItIsMultiple() diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index 5626d1e82..62f98b5d1 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -38,13 +38,17 @@ protected function setUp() { $this->desiredCapabilities = new DesiredCapabilities(); - if (getenv('BROWSER_NAME')) { - $browserName = getenv('BROWSER_NAME'); + if (getenv('SAUCELABS')) { + $this->setUpSauceLabs(); } else { - $browserName = WebDriverBrowserType::HTMLUNIT; - } + if (getenv('BROWSER_NAME')) { + $browserName = getenv('BROWSER_NAME'); + } else { + $browserName = WebDriverBrowserType::HTMLUNIT; + } - $this->desiredCapabilities->setBrowserName($browserName); + $this->desiredCapabilities->setBrowserName($browserName); + } if ($this->createWebDriver) { $this->driver = RemoteWebDriver::create($this->serverUrl, $this->desiredCapabilities); @@ -63,24 +67,40 @@ protected function tearDown() } /** - * Get the URL of the test html on filesystem. + * Get the URL of given test HTML on running webserver. * - * @param $path + * @param string $path * @return string */ - protected function getTestPath($path) + protected function getTestPageUrl($path) { - return 'file:///' . __DIR__ . '/web/' . $path; + return 'http://localhost:8000/' . $path; + } + + protected function setUpSauceLabs() + { + $this->serverUrl = sprintf( + 'http://%s:%s@ondemand.saucelabs.com/wd/hub', + getenv('SAUCE_USERNAME'), + getenv('SAUCE_ACCESS_KEY') + ); + $this->desiredCapabilities->setBrowserName(getenv('BROWSER_NAME')); + $this->desiredCapabilities->setVersion(getenv('VERSION')); + $this->desiredCapabilities->setPlatform(getenv('PLATFORM')); + + if (getenv('TRAVIS_JOB_NUMBER')) { + $this->desiredCapabilities->setCapability('tunnel-identifier', getenv('TRAVIS_JOB_NUMBER')); + $this->desiredCapabilities->setCapability('build', getenv('TRAVIS_JOB_NUMBER')); + } } /** - * Get the URL of given test HTML on running webserver. - * - * @param string $path - * @return string + * @param string $message */ - protected function getTestPageUrl($path) + protected function skipOnSauceLabs($message = 'Not supported by SauceLabs') { - return 'http://localhost:8000/' . $path; + if (getenv('SAUCELABS')) { + $this->markTestSkipped($message); + } } } diff --git a/tests/functional/WebDriverTimeoutsTest.php b/tests/functional/WebDriverTimeoutsTest.php index b7a7eb183..51be6e13a 100644 --- a/tests/functional/WebDriverTimeoutsTest.php +++ b/tests/functional/WebDriverTimeoutsTest.php @@ -28,7 +28,7 @@ class WebDriverTimeoutsTest extends WebDriverTestCase { public function testShouldFailGettingDelayedElementWithoutWait() { - $this->driver->get($this->getTestPath('delayed_element.html')); + $this->driver->get($this->getTestPageUrl('delayed_element.html')); $this->setExpectedException(NoSuchElementException::class); $this->driver->findElement(WebDriverBy::id('delayed')); @@ -39,7 +39,7 @@ public function testShouldFailGettingDelayedElementWithoutWait() */ public function testShouldGetDelayedElementWithImplicitWait() { - $this->driver->get($this->getTestPath('delayed_element.html')); + $this->driver->get($this->getTestPageUrl('delayed_element.html')); $this->driver->manage()->timeouts()->implicitlyWait(1); $element = $this->driver->findElement(WebDriverBy::id('delayed')); From 87ec0a905e74b3054ba6eda6aad9941caf4b7c34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 10 Feb 2017 18:00:44 +0100 Subject: [PATCH 322/784] Extend wait as an attempt to make the script more stable in slower network environments... --- tests/functional/RemoteWebDriverTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/functional/RemoteWebDriverTest.php b/tests/functional/RemoteWebDriverTest.php index 0f38d0f3c..858bcd786 100644 --- a/tests/functional/RemoteWebDriverTest.php +++ b/tests/functional/RemoteWebDriverTest.php @@ -162,14 +162,14 @@ public function testShouldExecuteScriptAndDoNotBlockExecution() $this->driver->executeScript(' setTimeout( function(){document.getElementById("id_test").innerHTML = "Text changed by script"}, - 250 + 500 )'); // Make sure the script don't block the test execution $this->assertSame('Test by ID', $element->getText()); // If we wait, the script should be executed - usleep(300000); // wait 300 ms + usleep(550000); // wait 550 ms $this->assertSame('Text changed by script', $element->getText()); } From 91c98338ea4638890f6d29e662e048c747b9cf41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 11 Feb 2017 14:40:41 +0100 Subject: [PATCH 323/784] Enable sauce connect addon only on SauceLabs builds This will improve performace of other builds, also otherwise we reach the SauceLabs concurrency tunel limit. --- .travis.yml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index f7229a2c3..c2aa30aa9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,12 +20,24 @@ matrix: - php: 7.0 env: SAUCELABS=1 BROWSER_NAME="firefox" VERSION="47.0" PLATFORM="Windows 10" before_script: php -S localhost:8000 -t tests/functional/web/ &>>./logs/php-server.log & + addons: + sauce_connect: true + jwt: + secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= - php: 7.0 env: SAUCELABS=1 BROWSER_NAME="firefox" VERSION="45.0" PLATFORM="Linux" before_script: php -S localhost:8000 -t tests/functional/web/ &>>./logs/php-server.log & + addons: + sauce_connect: true + jwt: + secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= - php: 7.0 env: SAUCELABS=1 BROWSER_NAME="chrome" VERSION="latest" PLATFORM="Windows 10" before_script: php -S localhost:8000 -t tests/functional/web/ &>>./logs/php-server.log & + addons: + sauce_connect: true + jwt: + secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= # Add PHP 7 build to check codestyle only in PHP 7 build - php: 7.0 @@ -79,6 +91,3 @@ addons: apt: packages: - oracle-java8-installer - sauce_connect: true - jwt: - secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= From 6f3e3403cf8e9215203ec05a7bddbd3c4cda251c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 11 Feb 2017 20:41:58 +0100 Subject: [PATCH 324/784] Install Firefox only on Firefox build (to not slow down other builds) --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c2aa30aa9..f8fc22fe6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,8 @@ matrix: # Add build to run tests against Firefox inside Travis environment (other runs are agains HtmlUnit by default) - php: 7.0 env: BROWSER_NAME="firefox" + addons: + firefox: "latest-esr" # Build with lowest possible dependencies - php: 7.0 @@ -87,7 +89,6 @@ after_success: - travis_retry php vendor/bin/coveralls -v addons: - firefox: "latest-esr" apt: packages: - oracle-java8-installer From a59ed83f5079fdefa75cf4ac694325b4ef699180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 22 Feb 2017 23:14:33 +0000 Subject: [PATCH 325/784] Upgrade to Selenium 3.1.0 --- .travis.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index f8fc22fe6..b771dd496 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,9 @@ matrix: env: BROWSER_NAME="firefox" addons: firefox: "latest-esr" + apt: + packages: + - oracle-java8-installer # Build with lowest possible dependencies - php: 7.0 @@ -68,13 +71,8 @@ install: before_script: - sh -e /etc/init.d/xvfb start - # TODO: upgrade to Selenium 3.0.2 (with latest HtmlUnit) once released, as HtmlUnit in 3.0.1 is broken - - if [ ! -f jar/selenium-server-standalone-2.53.1.jar ]; then wget -q -t 3 -P jar https://selenium-release.storage.googleapis.com/2.53/selenium-server-standalone-2.53.1.jar; fi - - if [ ! -f jar/htmlunit-driver-standalone-2.20.jar ]; then wget -q -t 3 -P jar https://github.com/SeleniumHQ/htmlunit-driver/releases/download/2.20/htmlunit-driver-standalone-2.20.jar; fi - # Temporarily run HtmlUnit from standalone jar file (it was not part of Selenium server standalone in version 2.53) - - java -cp "jar/selenium-server-standalone-2.53.1.jar:jar/htmlunit-driver-standalone-2.20.jar" org.openqa.grid.selenium.GridLauncher -log ./logs/selenium.log & - # TODO: use this after upgrade to Selenium 3.0.2 - #- /usr/lib/jvm/java-8-oracle/bin/java -Dwebdriver.firefox.marionette=false -jar jar/selenium-server-standalone-3.0.2.jar -log selenium.log & + - if [ ! -f jar/selenium-server-standalone-3.1.0.jar ]; then wget -q -t 3 -P jar https://selenium-release.storage.googleapis.com/3.1/selenium-server-standalone-3.1.0.jar; fi + - /usr/lib/jvm/java-8-oracle/bin/java -Dwebdriver.firefox.marionette=false -jar jar/selenium-server-standalone-3.1.0.jar -log ./logs/selenium.log & - until $(echo | nc localhost 4444); do sleep 1; echo waiting for selenium-server...; done - php -S localhost:8000 -t tests/functional/web/ &>>./logs/php-server.log & From 8900b1fc26f071724c04774ea129ddfc402684f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Thu, 23 Feb 2017 19:03:54 +0000 Subject: [PATCH 326/784] Identify SauceLabs tests by name and tags --- tests/functional/WebDriverTestCase.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index 62f98b5d1..3673d0a8e 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -87,6 +87,8 @@ protected function setUpSauceLabs() $this->desiredCapabilities->setBrowserName(getenv('BROWSER_NAME')); $this->desiredCapabilities->setVersion(getenv('VERSION')); $this->desiredCapabilities->setPlatform(getenv('PLATFORM')); + $this->desiredCapabilities->setCapability('name', get_class($this) . '::' . $this->getName()); + $this->desiredCapabilities->setCapability('tags', [get_class($this)]); if (getenv('TRAVIS_JOB_NUMBER')) { $this->desiredCapabilities->setCapability('tunnel-identifier', getenv('TRAVIS_JOB_NUMBER')); From bab090739c5bbc7d6c4efc8da1505665b15ca144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Thu, 23 Feb 2017 20:04:13 +0000 Subject: [PATCH 327/784] Report test results to saucelabs API to show the results on their dashboard --- composer.json | 2 +- phpunit.xml.dist | 5 ++ .../ReportSauceLabsStatusListener.php | 88 +++++++++++++++++++ tests/functional/WebDriverTestCase.php | 16 +++- 4 files changed, 106 insertions(+), 5 deletions(-) create mode 100644 tests/functional/ReportSauceLabsStatusListener.php diff --git a/composer.json b/composer.json index 3523361f9..a80697c47 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,7 @@ }, "autoload-dev": { "psr-4": { - "Facebook\\WebDriver\\": "tests/unit" + "Facebook\\WebDriver\\": ["tests/unit", "tests/functional"] }, "classmap": ["tests/functional/"] } diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 894ba470a..430a8fb5c 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -29,4 +29,9 @@ ./lib + + + + + diff --git a/tests/functional/ReportSauceLabsStatusListener.php b/tests/functional/ReportSauceLabsStatusListener.php new file mode 100644 index 000000000..b88b1cdf7 --- /dev/null +++ b/tests/functional/ReportSauceLabsStatusListener.php @@ -0,0 +1,88 @@ +driver instanceof RemoteWebDriver) { + return; + } + + /** @var WebDriverTestCase $test */ + if (!$test->isSauceLabsBuild()) { + return; + } + + $testStatus = $test->getStatus(); + + if ($this->testWasSkippedOrIncomplete($testStatus)) { + return; + } + + $endpointUrl = sprintf( + 'https://saucelabs.com/rest/v1/%s/jobs/%s', + getenv('SAUCE_USERNAME'), + $test->driver->getSessionID() + ); + + $data = [ + 'passed' => ($testStatus === \PHPUnit_Runner_BaseTestRunner::STATUS_PASSED), + 'custom-data' => ['message' => $test->getStatusMessage()], + ]; + + $this->submitToSauceLabs($endpointUrl, $data); + } + + /** + * @param int $testStatus + * @return bool + */ + private function testWasSkippedOrIncomplete($testStatus) + { + if ($testStatus === \PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED + || $testStatus === \PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE) { + return true; + } + + return false; + } + + /** + * @param string $url + * @param array $data + */ + private function submitToSauceLabs($url, array $data) + { + $curl = curl_init($url); + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT'); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); + curl_setopt($curl, CURLOPT_USERPWD, getenv('SAUCE_USERNAME') . ':' . getenv('SAUCE_ACCESS_KEY')); + curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data)); + + curl_exec($curl); + + if (curl_errno($curl)) { + throw new \Exception(sprintf('Error publishing test results to SauceLabs: %s', curl_error($curl))); + } + + curl_close($curl); + } +} diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index 3673d0a8e..a2639bae7 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -25,12 +25,12 @@ */ class WebDriverTestCase extends \PHPUnit_Framework_TestCase { + /** @var RemoteWebDriver $driver */ + public $driver; /** @var bool Indicate whether WebDriver should be created on setUp */ protected $createWebDriver = true; /** @var string */ protected $serverUrl = 'http://localhost:4444/wd/hub'; - /** @var RemoteWebDriver $driver */ - protected $driver; /** @var DesiredCapabilities */ protected $desiredCapabilities; @@ -38,7 +38,7 @@ protected function setUp() { $this->desiredCapabilities = new DesiredCapabilities(); - if (getenv('SAUCELABS')) { + if ($this->isSauceLabsBuild()) { $this->setUpSauceLabs(); } else { if (getenv('BROWSER_NAME')) { @@ -66,6 +66,14 @@ protected function tearDown() } } + /** + * @return bool + */ + public function isSauceLabsBuild() + { + return getenv('SAUCELABS') ? true : false; + } + /** * Get the URL of given test HTML on running webserver. * @@ -101,7 +109,7 @@ protected function setUpSauceLabs() */ protected function skipOnSauceLabs($message = 'Not supported by SauceLabs') { - if (getenv('SAUCELABS')) { + if ($this->isSauceLabsBuild()) { $this->markTestSkipped($message); } } From 1cdbf31156271381c65eab169923c3f744648a08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 24 Feb 2017 00:36:39 +0000 Subject: [PATCH 328/784] Extend wait once more to make the script more stable in slower network environments like with SauceLabs --- tests/functional/RemoteWebDriverTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/functional/RemoteWebDriverTest.php b/tests/functional/RemoteWebDriverTest.php index 858bcd786..52f1d9cb7 100644 --- a/tests/functional/RemoteWebDriverTest.php +++ b/tests/functional/RemoteWebDriverTest.php @@ -169,7 +169,7 @@ function(){document.getElementById("id_test").innerHTML = "Text changed by scrip $this->assertSame('Test by ID', $element->getText()); // If we wait, the script should be executed - usleep(550000); // wait 550 ms + usleep(1000000); // wait 1000 ms $this->assertSame('Text changed by script', $element->getText()); } From 3c4c512e15011b674bb9f409ef365854ed7bd3a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 24 Feb 2017 11:17:29 +0000 Subject: [PATCH 329/784] Do not even start (ie. exclude) tests not working on saucelabs, instead of skipping them --- .travis.yml | 3 ++- tests/functional/RemoteWebDriverTest.php | 6 ++---- tests/functional/WebDriverTestCase.php | 10 ---------- 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index b771dd496..353936986 100644 --- a/.travis.yml +++ b/.travis.yml @@ -77,7 +77,8 @@ before_script: - php -S localhost:8000 -t tests/functional/web/ &>>./logs/php-server.log & script: - - ./vendor/bin/phpunit --coverage-clover ./logs/coverage-clover.xml + - if [ -n "$SAUCELABS" ]; then EXTRA_PARAMS="--exclude-group exclude-saucelabs"; fi + - ./vendor/bin/phpunit --coverage-clover ./logs/coverage-clover.xml $EXTRA_PARAMS after_script: - cat ./logs/selenium.log diff --git a/tests/functional/RemoteWebDriverTest.php b/tests/functional/RemoteWebDriverTest.php index 52f1d9cb7..7b60b69d7 100644 --- a/tests/functional/RemoteWebDriverTest.php +++ b/tests/functional/RemoteWebDriverTest.php @@ -75,12 +75,11 @@ public function testShouldGetSessionId() } /** + * @group exclude-saucelabs * @covers ::getAllSessions */ public function testShouldGetAllSessions() { - $this->skipOnSauceLabs('getAllSessions() is not supported on SauceLabs'); - $sessions = RemoteWebDriver::getAllSessions($this->serverUrl); $this->assertInternalType('array', $sessions); @@ -92,14 +91,13 @@ public function testShouldGetAllSessions() } /** + * @group exclude-saucelabs * @covers ::getAllSessions * @covers ::getCommandExecutor * @covers ::quit */ public function testShouldQuitAndUnsetExecutor() { - $this->skipOnSauceLabs('getAllSessions() is not supported on SauceLabs'); - $this->assertCount(1, RemoteWebDriver::getAllSessions($this->serverUrl)); $this->assertInstanceOf(HttpCommandExecutor::class, $this->driver->getCommandExecutor()); diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index a2639bae7..84883574a 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -103,14 +103,4 @@ protected function setUpSauceLabs() $this->desiredCapabilities->setCapability('build', getenv('TRAVIS_JOB_NUMBER')); } } - - /** - * @param string $message - */ - protected function skipOnSauceLabs($message = 'Not supported by SauceLabs') - { - if ($this->isSauceLabsBuild()) { - $this->markTestSkipped($message); - } - } } From 6fb60b020e39b89dc3e913c294bc780bf545b9dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 26 Feb 2017 18:45:37 +0000 Subject: [PATCH 330/784] Add travis and saucelabs badge --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d2a8d6132..cfdf0bc3b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # php-webdriver – Selenium WebDriver bindings for PHP [![Latest Stable Version](https://img.shields.io/packagist/v/facebook/webdriver.svg?style=flat-square)](https://packagist.org/packages/facebook/webdriver) +[![Travis Build](https://img.shields.io/travis/facebook/php-webdriver/community.svg?style=flat-square)](https://travis-ci.org/facebook/php-webdriver) +[![Sauce Test Status](https://saucelabs.com/buildstatus/php-webdriver)](https://saucelabs.com/u/php-webdriver) [![Total Downloads](https://img.shields.io/packagist/dt/facebook/webdriver.svg?style=flat-square)](https://packagist.org/packages/facebook/webdriver) [![License](https://img.shields.io/packagist/l/facebook/webdriver.svg?style=flat-square)](https://packagist.org/packages/facebook/webdriver) From 75af11ac9661ff76cf857ead31b30cfac9528ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Mon, 6 Mar 2017 21:49:43 +0000 Subject: [PATCH 331/784] Do not throw fatal error when null is passed to sendKeys (fixes #419) --- CHANGELOG.md | 3 ++ lib/Interactions/WebDriverCompositeAction.php | 2 +- lib/WebDriverKeys.php | 12 +++-- tests/unit/WebDriverKeysTest.php | 54 +++++++++++++++++++ 4 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 tests/unit/WebDriverKeysTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b99a4f66..87407e0c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). - Cookies retrieved using `getCookieNamed()` and `getCookies()` methods of `WebDriverOptions` are now encapsulated in `Cookie` object instead of an plain array. The object implements `ArrayAccess` interface to provide backward compatibility. - `ext-zip` is now specified as required dependency in composer.json (but the extension was already required by the code, though). +### Fixed +- Do not throw fatal error when `null` is passed to `sendKeys()`. + ## 1.3.0 - 2017-01-13 ### Added - Added `getCapabilities()` method of `RemoteWebDriver`, to retrieve actual capabilities acknowledged by the remote driver on startup. diff --git a/lib/Interactions/WebDriverCompositeAction.php b/lib/Interactions/WebDriverCompositeAction.php index 75b879082..75a4837e1 100644 --- a/lib/Interactions/WebDriverCompositeAction.php +++ b/lib/Interactions/WebDriverCompositeAction.php @@ -23,7 +23,7 @@ class WebDriverCompositeAction implements WebDriverAction { /** - * @var array + * @var WebDriverAction[] */ private $actions = []; diff --git a/lib/WebDriverKeys.php b/lib/WebDriverKeys.php index 57d37c1eb..c25748e8c 100644 --- a/lib/WebDriverKeys.php +++ b/lib/WebDriverKeys.php @@ -88,24 +88,28 @@ class WebDriverKeys /** * Encode input of `sendKeys()`. - * @param string|array $keys + * @param string|array|int|float $keys * @return array */ public static function encode($keys) { if (is_numeric($keys)) { - $keys = '' . $keys; + $keys = (string) $keys; } if (is_string($keys)) { $keys = [$keys]; } + if (!is_array($keys)) { + return []; + } + $encoded = []; foreach ($keys as $key) { if (is_array($key)) { - // handle modified keys - $key = implode('', $key) . self::NULL; + // handle key modifiers + $key = implode('', $key) . self::NULL; // the NULL clears the input state (eg. previous modifiers) } $encoded[] = (string) $key; } diff --git a/tests/unit/WebDriverKeysTest.php b/tests/unit/WebDriverKeysTest.php new file mode 100644 index 000000000..9a205c7de --- /dev/null +++ b/tests/unit/WebDriverKeysTest.php @@ -0,0 +1,54 @@ +assertSame($expectedOutput, WebDriverKeys::encode($keys)); + } + + /** + * @return array[] + */ + public function provideKeys() + { + return [ + 'empty string' => ['', ['']], + 'simple string' => ['foo', ['foo']], + 'string as an array' => [['foo'], ['foo']], + 'string with modifier as an array' => [[WebDriverKeys::SHIFT, 'foo'], [WebDriverKeys::SHIFT, 'foo']], + 'string with concatenated modifier' => [[WebDriverKeys::SHIFT . 'foo'], [WebDriverKeys::SHIFT . 'foo']], + 'simple numeric value' => [3, ['3']], + 'multiple numeric values' => [[1, 3.33], ['1', '3.33']], + 'multiple mixed values ' => [['foo', WebDriverKeys::END, '1.234'], ['foo', WebDriverKeys::END, '1.234']], + 'array of strings with modifiers should separate them with NULL character' => [ + [[WebDriverKeys::SHIFT, 'foo'], [WebDriverKeys::META, 'bar']], + [WebDriverKeys::SHIFT . 'foo' . WebDriverKeys::NULL, WebDriverKeys::META . 'bar' . WebDriverKeys::NULL], + ], + 'null' => [null, []], + ]; + } +} From ecc272a4ece0975ee320e87e2ed5f5ee737cfdf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 8 Mar 2017 10:28:01 +0000 Subject: [PATCH 332/784] Add composer scripts for simple codestyle check/fix --- .travis.yml | 4 +--- CONTRIBUTING.md | 21 +++++++++++++++++---- composer.json | 10 ++++++++++ 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 353936986..2eaa8fd02 100644 --- a/.travis.yml +++ b/.travis.yml @@ -48,9 +48,7 @@ matrix: - php: 7.0 env: CHECK_CODESTYLE=1 before_script: ~ - script: - - ./vendor/bin/php-cs-fixer fix --diff --dry-run - - ./vendor/bin/phpcs --standard=PSR2 ./lib/ ./tests/ + script: composer codestyle:check after_script: ~ after_success: ~ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a73c9eafd..3bea30bba 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,15 +29,28 @@ To execute all tests simply run: If you want to execute just the unit tests, run: ./vendor/bin/phpunit --testsuite unit + +For the functional tests you must first [download](http://selenium-release.storage.googleapis.com/index.html) and start +the selenium standalone server, start the local PHP server which will serve the test pages and then run the `functional` +test suite: + + java -jar selenium-server-standalone-2.53.1.jar -log selenium.log & + php -S localhost:8000 -t tests/functional/web/ & + ./vendor/bin/phpunit --testsuite functional -For the functional tests you must first download and start the selenium server, then run the `functional` test suite: +The functional tests will be started in HtmlUnit headless browser by default. If you want to run them in eg. Firefox, +simply set the `BROWSER` environment variable: - java -jar selenium-server-standalone-2.48.2.jar -log selenium.log & + ... + export BROWSER_NAME="firefox" ./vendor/bin/phpunit --testsuite functional ### Check coding style Your code-style should comply with [PSR-2](http://www.php-fig.org/psr/psr-2/). To make sure your code matches this requirement run: - ./vendor/bin/php-cs-fixer fix --diff --dry-run - ./vendor/bin/phpcs --standard=PSR2 ./lib/ ./tests/ + composer codestyle:check + +To auto-fix the codestyle simply run: + + composer codestyle:fix diff --git a/composer.json b/composer.json index a80697c47..24825d658 100644 --- a/composer.json +++ b/composer.json @@ -33,5 +33,15 @@ "Facebook\\WebDriver\\": ["tests/unit", "tests/functional"] }, "classmap": ["tests/functional/"] + }, + "scripts": { + "codestyle:check": [ + "vendor/bin/php-cs-fixer fix --diff --dry-run", + "vendor/bin/phpcs --standard=PSR2 ./lib/ ./tests/" + ], + "codestyle:fix": [ + "vendor/bin/php-cs-fixer fix --diff || exit 0", + "vendor/bin/phpcbf --standard=PSR2 ./lib/ ./tests/" + ] } } From b10102f60f097108d783aa97fa5f3186a146c961 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 11 Mar 2017 22:46:23 +0000 Subject: [PATCH 333/784] Deprecate isJavascriptEnabled method. See https://github.com/SeleniumHQ/selenium/commit/5b0f88ef3256595148b357dec6209735cab25bea --- CHANGELOG.md | 1 + lib/Remote/DesiredCapabilities.php | 2 ++ lib/WebDriverCapabilities.php | 2 ++ 3 files changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87407e0c1..b63abff80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). - Cookies should now be set using `Cookie` value object instead of an array when passed to to `addCookie()` method of `WebDriverOptions`. - Cookies retrieved using `getCookieNamed()` and `getCookies()` methods of `WebDriverOptions` are now encapsulated in `Cookie` object instead of an plain array. The object implements `ArrayAccess` interface to provide backward compatibility. - `ext-zip` is now specified as required dependency in composer.json (but the extension was already required by the code, though). +- Deprecate `WebDriverCapabilities::isJavascriptEnabled()` method. ### Fixed - Do not throw fatal error when `null` is passed to `sendKeys()`. diff --git a/lib/Remote/DesiredCapabilities.php b/lib/Remote/DesiredCapabilities.php index 94d8e1de2..3990343af 100644 --- a/lib/Remote/DesiredCapabilities.php +++ b/lib/Remote/DesiredCapabilities.php @@ -123,6 +123,8 @@ public function is($capability_name) } /** + * @todo Remove in next major release (BC) + * @deprecated All browsers are always JS enabled except HtmlUnit and it's not meaningful to disable JS execution. * @return bool Whether javascript is enabled. */ public function isJavascriptEnabled() diff --git a/lib/WebDriverCapabilities.php b/lib/WebDriverCapabilities.php index b489a1e6e..9ac851d90 100644 --- a/lib/WebDriverCapabilities.php +++ b/lib/WebDriverCapabilities.php @@ -45,6 +45,8 @@ public function getVersion(); public function is($capability_name); /** + * @todo Remove in next major release (BC) + * @deprecated All browsers are always JS enabled except HtmlUnit and it's not meaningful to disable JS execution. * @return bool Whether javascript is enabled. */ public function isJavascriptEnabled(); From 89a6ce780387202ccbdb511eab613a5691613034 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Thu, 16 Mar 2017 13:02:52 +0000 Subject: [PATCH 334/784] Workaround in example script for Selenium bug (fixes #402) --- example.php | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/example.php b/example.php index 7bebd10b5..263d0c1d6 100644 --- a/example.php +++ b/example.php @@ -13,8 +13,8 @@ $capabilities = DesiredCapabilities::firefox(); $driver = RemoteWebDriver::create($host, $capabilities, 5000); -// navigate to 'http://docs.seleniumhq.org/' -$driver->get('http://docs.seleniumhq.org/'); +// navigate to 'http://www.seleniumhq.org/' +$driver->get('http://www.seleniumhq.org/'); // adding cookie $driver->manage()->deleteAllCookies(); @@ -31,17 +31,24 @@ ); $link->click(); +// wait until the page is loaded +$driver->wait()->until( + WebDriverExpectedCondition::titleContains('About') +); + // print the title of the current page echo "The title is '" . $driver->getTitle() . "'\n"; // print the URI of the current page echo "The current URI is '" . $driver->getCurrentURL() . "'\n"; -// Search 'php' in the search box -$input = $driver->findElement( - WebDriverBy::id('q') -); -$input->sendKeys('php')->submit(); +// write 'php' in the search box +$driver->findElement(WebDriverBy::id('q')) + ->sendKeys('php'); + +// submit the form +$driver->findElement(WebDriverBy::id('submit')) + ->click(); // submit() does not work in Selenium 3 because of bug https://github.com/SeleniumHQ/selenium/issues/3398 // wait at most 10 seconds until at least one result is shown $driver->wait(10)->until( From f6ae7db59f4be0a5a8f791448c72d9d4d920e514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Thu, 16 Mar 2017 14:44:20 +0000 Subject: [PATCH 335/784] Use previous Firefox ESR, as new ESR is based on Firefox 52 (which requires Geckodriver) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2eaa8fd02..a42bfbe20 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ matrix: - php: 7.0 env: BROWSER_NAME="firefox" addons: - firefox: "latest-esr" + firefox: "45.8.0esr" apt: packages: - oracle-java8-installer From 4f141e058d55ebd762c11201ac129c7cb98bd925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 18 Mar 2017 12:00:54 +0000 Subject: [PATCH 336/784] Remove Firefox 45 build, bacause it is unstable and slow --- .travis.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index a42bfbe20..0c987bc87 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,13 +29,6 @@ matrix: sauce_connect: true jwt: secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= - - php: 7.0 - env: SAUCELABS=1 BROWSER_NAME="firefox" VERSION="45.0" PLATFORM="Linux" - before_script: php -S localhost:8000 -t tests/functional/web/ &>>./logs/php-server.log & - addons: - sauce_connect: true - jwt: - secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= - php: 7.0 env: SAUCELABS=1 BROWSER_NAME="chrome" VERSION="latest" PLATFORM="Windows 10" before_script: php -S localhost:8000 -t tests/functional/web/ &>>./logs/php-server.log & From 48b9c7aebed26b252ead3e15a621db46b405fd78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 18 Mar 2017 12:57:15 +0000 Subject: [PATCH 337/784] Setup branch alias to allow simplier installation of development versions --- composer.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/composer.json b/composer.json index 24825d658..1381c13d5 100644 --- a/composer.json +++ b/composer.json @@ -43,5 +43,10 @@ "vendor/bin/php-cs-fixer fix --diff || exit 0", "vendor/bin/phpcbf --standard=PSR2 ./lib/ ./tests/" ] + }, + "extra": { + "branch-alias": { + "dev-community": "1.4-dev" + } } } From 51ef9da2b689d2680ad006d4cc3c9ec95977e015 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 19 Mar 2017 11:17:02 +0000 Subject: [PATCH 338/784] Rename textToBePresentInElementValue expected condition to make its name systematic with other conditions --- CHANGELOG.md | 1 + lib/WebDriverExpectedCondition.php | 14 ++++++++ tests/unit/WebDriverExpectedConditionTest.php | 35 +++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b63abff80..2f6b5e772 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). - Cookies retrieved using `getCookieNamed()` and `getCookies()` methods of `WebDriverOptions` are now encapsulated in `Cookie` object instead of an plain array. The object implements `ArrayAccess` interface to provide backward compatibility. - `ext-zip` is now specified as required dependency in composer.json (but the extension was already required by the code, though). - Deprecate `WebDriverCapabilities::isJavascriptEnabled()` method. +- Deprecate `textToBePresentInElementValue` expected condition in favor of `elementValueContains`. ### Fixed - Do not throw fatal error when `null` is passed to `sendKeys()`. diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index 58ba939e9..347a5d28a 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -292,11 +292,25 @@ function (WebDriver $driver) use ($by, $regexp) { /** * An expectation for checking if the given text is present in the specified elements value attribute. * + * @codeCoverageIgnore + * @deprecated Use WebDriverExpectedCondition::elementValueContains() instead * @param WebDriverBy $by The locator used to find the element. * @param string $text The text to be presented in the element value. * @return WebDriverExpectedCondition Condition returns whether the text is present in value attribute. */ public static function textToBePresentInElementValue(WebDriverBy $by, $text) + { + return self::elementValueContains($by, $text); + } + + /** + * An expectation for checking if the given text is present in the specified elements value attribute. + * + * @param WebDriverBy $by The locator used to find the element. + * @param string $text The text to be presented in the element value. + * @return WebDriverExpectedCondition Condition returns whether the text is present in value attribute. + */ + public static function elementValueContains(WebDriverBy $by, $text) { return new static( function (WebDriver $driver) use ($by, $text) { diff --git a/tests/unit/WebDriverExpectedConditionTest.php b/tests/unit/WebDriverExpectedConditionTest.php index 93d98b392..c2605a97d 100644 --- a/tests/unit/WebDriverExpectedConditionTest.php +++ b/tests/unit/WebDriverExpectedConditionTest.php @@ -292,6 +292,41 @@ public function testShouldDetectElementTextMatchesCondition() $this->assertTrue($this->wait->until($condition)); } + public function testShouldDetectElementValueContainsCondition() + { + // Set-up the consecutive calls to apply() as follows: + // Call #1: throws NoSuchElementException + // Call #2: return Element, but getAttribute will throw StaleElementReferenceException + // Call #3: return Element, getAttribute('value') will return not-matching text + // Call #4: return Element, getAttribute('value') will return matching text + + $element = $this->createRemoteWebElementMock(); + + $element->expects($this->at(0)) + ->method('getAttribute') + ->with('value') + ->willThrowException(new StaleElementReferenceException('')); + + $element->expects($this->at(1)) + ->method('getAttribute') + ->with('value') + ->willReturn('wrong text'); + + $element->expects($this->at(2)) + ->method('getAttribute') + ->with('value') + ->willReturn('matching text'); + + $this->setupDriverToReturnElementAfterAnException($element, 4); + + $condition = WebDriverExpectedCondition::elementValueContains( + WebDriverBy::cssSelector('.foo'), + 'matching' + ); + + $this->assertTrue($this->wait->until($condition)); + } + public function testShouldDetectNumberOfWindowsToBeCondition() { $this->driverMock->expects($this->any()) From 7a855dd1b82d350e4fff9509b5031b37bcd0434f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 19 Mar 2017 11:17:30 +0000 Subject: [PATCH 339/784] Add UT for invisibilityOfElementLocated expected contition --- tests/unit/WebDriverExpectedConditionTest.php | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/tests/unit/WebDriverExpectedConditionTest.php b/tests/unit/WebDriverExpectedConditionTest.php index c2605a97d..e786167a8 100644 --- a/tests/unit/WebDriverExpectedConditionTest.php +++ b/tests/unit/WebDriverExpectedConditionTest.php @@ -185,6 +185,73 @@ public function testShouldDetectVisibilityOfElementLocatedCondition() $this->assertSame($element, $this->wait->until($condition)); } + public function testShouldDetectInvisibilityOfElementLocatedConditionOnNoSuchElementException() + { + $element = $this->createRemoteWebElementMock(); + + $this->driverMock->expects($this->at(0)) + ->method('findElement') + ->with($this->isInstanceOf(WebDriverBy::class)) + ->willReturn($element); + + $element->expects($this->at(0)) + ->method('isDisplayed') + ->willReturn(true); + + $this->driverMock->expects($this->at(1)) + ->method('findElement') + ->with($this->isInstanceOf(WebDriverBy::class)) + ->willThrowException(new NoSuchElementException('')); + + $condition = WebDriverExpectedCondition::invisibilityOfElementLocated(WebDriverBy::cssSelector('.foo')); + + $this->assertTrue($this->wait->until($condition)); + } + + public function testShouldDetectInvisibilityOfElementLocatedConditionOnStaleElementReferenceException() + { + $element = $this->createRemoteWebElementMock(); + + $this->driverMock->expects($this->exactly(2)) + ->method('findElement') + ->with($this->isInstanceOf(WebDriverBy::class)) + ->willReturn($element); + + $element->expects($this->at(0)) + ->method('isDisplayed') + ->willReturn(true); + + $element->expects($this->at(1)) + ->method('isDisplayed') + ->willThrowException(new StaleElementReferenceException('')); + + $condition = WebDriverExpectedCondition::invisibilityOfElementLocated(WebDriverBy::cssSelector('.foo')); + + $this->assertTrue($this->wait->until($condition)); + } + + public function testShouldDetectInvisibilityOfElementLocatedConditionWhenElementBecamesInvisible() + { + $element = $this->createRemoteWebElementMock(); + + $this->driverMock->expects($this->exactly(2)) + ->method('findElement') + ->with($this->isInstanceOf(WebDriverBy::class)) + ->willReturn($element); + + $element->expects($this->at(0)) + ->method('isDisplayed') + ->willReturn(true); + + $element->expects($this->at(1)) + ->method('isDisplayed') + ->willReturn(false); + + $condition = WebDriverExpectedCondition::invisibilityOfElementLocated(WebDriverBy::cssSelector('.foo')); + + $this->assertTrue($this->wait->until($condition)); + } + public function testShouldDetectVisibilityOfCondition() { $element = $this->createRemoteWebElementMock(); From 3ea034c056189e11c0ce7985332a9f4b5b2b5db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 22 Mar 2017 11:55:12 +0100 Subject: [PATCH 340/784] Release version 1.4.0 --- CHANGELOG.md | 2 ++ composer.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f6b5e772..89c93fadd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased + +## 1.4.0 - 2017-03-22 ### Changed - Cookies should now be set using `Cookie` value object instead of an array when passed to to `addCookie()` method of `WebDriverOptions`. - Cookies retrieved using `getCookieNamed()` and `getCookies()` methods of `WebDriverOptions` are now encapsulated in `Cookie` object instead of an plain array. The object implements `ArrayAccess` interface to provide backward compatibility. diff --git a/composer.json b/composer.json index 1381c13d5..0a87cb3ed 100644 --- a/composer.json +++ b/composer.json @@ -46,7 +46,7 @@ }, "extra": { "branch-alias": { - "dev-community": "1.4-dev" + "dev-community": "1.5-dev" } } } From 905b0e3ea21286d7839c939ae0a70ff47c20c34c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Mon, 24 Apr 2017 23:25:02 +0200 Subject: [PATCH 341/784] Update https link --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3bea30bba..6c59bbe84 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,7 +13,7 @@ send a pull request (see bellow) with your contribution. 4. When implementing notable change, fix or a new feature, add record to Unreleased section of [CHANGELOG.md](CHANGELOG.md) 5. Submit your [pull request](https://github.com/facebook/php-webdriver/pulls) against community branch -Note before any pull request can be accepted, a [Contributors Licensing Agreement](http://developers.facebook.com/opensource/cla) must be signed. +Note before any pull request can be accepted, a [Contributors Licensing Agreement](https://developers.facebook.com/opensource/cla) must be signed. When you are going to contribute, please keep in mind that this webdriver client aims to be as close as possible to other languages Java/Ruby/Python/C#. FYI, here is the overview of [the official Java API](http://seleniumhq.github.io/selenium/docs/api/java/) From d06347f10ef20989f1fe705b7692c23a4ebe00dc Mon Sep 17 00:00:00 2001 From: toniperic Date: Thu, 27 Apr 2017 10:13:47 +0200 Subject: [PATCH 342/784] Correct constant checking Prior to this change I would be getting `Constant CURLOPT_CONNECTTIMEOUT_MS already defined` since PHP would try to re-define a constant. --- lib/Net/URLChecker.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Net/URLChecker.php b/lib/Net/URLChecker.php index 575daac56..00ad62593 100644 --- a/lib/Net/URLChecker.php +++ b/lib/Net/URLChecker.php @@ -66,7 +66,7 @@ private function getHTTPResponseCode($url) curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // The PHP doc indicates that CURLOPT_CONNECTTIMEOUT_MS constant is added in cURL 7.16.2 // available since PHP 5.2.3. - if (!defined(CURLOPT_CONNECTTIMEOUT_MS)) { + if (!defined('CURLOPT_CONNECTTIMEOUT_MS')) { define('CURLOPT_CONNECTTIMEOUT_MS', 156); // default value for CURLOPT_CONNECTTIMEOUT_MS } curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, self::CONNECT_TIMEOUT_MS); From 94f64e54e50b2b4b0883d25aefb743d006eaa98d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 28 Apr 2017 12:37:04 +0200 Subject: [PATCH 343/784] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89c93fadd..9a4410c09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +### Fixed +- Do not throw notice `Constant CURLOPT_CONNECTTIMEOUT_MS already defined`. ## 1.4.0 - 2017-03-22 ### Changed From 75c22b51131ed6b11276672a8a39b5b7976c0ecf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 28 Apr 2017 02:52:01 +0200 Subject: [PATCH 344/784] Make sure sudo mode is disabled in all travis builds --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 0c987bc87..1c2146bb3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,8 @@ php: - 7.0 - 7.1 +sudo: false + matrix: include: # Add build to run tests against Firefox inside Travis environment (other runs are agains HtmlUnit by default) From 4a3bb63e73b9e30f6ac601a7b237a44d3c07f1f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 28 Apr 2017 12:30:57 +0200 Subject: [PATCH 345/784] Print logs in travis only if created --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1c2146bb3..c957fd41e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -74,8 +74,8 @@ script: - ./vendor/bin/phpunit --coverage-clover ./logs/coverage-clover.xml $EXTRA_PARAMS after_script: - - cat ./logs/selenium.log - - cat ./logs/php-server.log + - if [ -f ./logs/selenium.log ]; then cat ./logs/selenium.log; fi + - if [ -f ./logs/php-server.log ]; then cat ./logs/php-server.log; fi after_success: - travis_retry php vendor/bin/coveralls -v From 66e37cfb00b698bfc96dd47f71ae1bd4659e6bda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 28 Apr 2017 15:07:40 +0200 Subject: [PATCH 346/784] Bind PHP server to 127.0.0.1 to overcome Bad Gateway error when using 'localhost' --- .travis.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index c957fd41e..5c5ca4c0e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,14 +26,18 @@ matrix: # Saucelabs builds - php: 7.0 env: SAUCELABS=1 BROWSER_NAME="firefox" VERSION="47.0" PLATFORM="Windows 10" - before_script: php -S localhost:8000 -t tests/functional/web/ &>>./logs/php-server.log & + before_script: + - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & + - until $(echo | nc localhost 8000); do sleep 1; echo waiting for PHP server on port 8000...; done; echo "PHP server started" addons: sauce_connect: true jwt: secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= - php: 7.0 env: SAUCELABS=1 BROWSER_NAME="chrome" VERSION="latest" PLATFORM="Windows 10" - before_script: php -S localhost:8000 -t tests/functional/web/ &>>./logs/php-server.log & + before_script: + - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & + - until $(echo | nc localhost 8000); do sleep 1; echo waiting for PHP server on port 8000...; done; echo "PHP server started" addons: sauce_connect: true jwt: @@ -66,8 +70,9 @@ before_script: - sh -e /etc/init.d/xvfb start - if [ ! -f jar/selenium-server-standalone-3.1.0.jar ]; then wget -q -t 3 -P jar https://selenium-release.storage.googleapis.com/3.1/selenium-server-standalone-3.1.0.jar; fi - /usr/lib/jvm/java-8-oracle/bin/java -Dwebdriver.firefox.marionette=false -jar jar/selenium-server-standalone-3.1.0.jar -log ./logs/selenium.log & - - until $(echo | nc localhost 4444); do sleep 1; echo waiting for selenium-server...; done - - php -S localhost:8000 -t tests/functional/web/ &>>./logs/php-server.log & + - until $(echo | nc localhost 4444); do sleep 1; echo Waiting for Selenium server on port 4444...; done; echo "Selenium server started" + - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & + - until $(echo | nc localhost 8000); do sleep 1; echo waiting for PHP server on port 8000...; done; echo "PHP server started" script: - if [ -n "$SAUCELABS" ]; then EXTRA_PARAMS="--exclude-group exclude-saucelabs"; fi From eadb0b7a7c3e6578185197fd40158b08c3164c83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 28 Apr 2017 16:54:49 +0200 Subject: [PATCH 347/784] Release version 1.4.1 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a4410c09..c7d018435 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased + +## 1.4.1 - 2017-04-28 ### Fixed - Do not throw notice `Constant CURLOPT_CONNECTTIMEOUT_MS already defined`. From 10c8c8449713fc79a672b2636e10284ab92b110e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 21 Jun 2017 11:15:17 +0200 Subject: [PATCH 348/784] Add LICENCE.md --- LICENCE.md | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 LICENCE.md diff --git a/LICENCE.md b/LICENCE.md new file mode 100644 index 000000000..0b3f67bd7 --- /dev/null +++ b/LICENCE.md @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2004-present Facebook + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. From 8fee7dceac5e3f867fe91d45743e3bc74b3b6efd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 4 Aug 2017 21:37:11 +0200 Subject: [PATCH 349/784] Build on PHP 7.1 by default --- .travis.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5c5ca4c0e..fde500451 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,8 +10,8 @@ sudo: false matrix: include: - # Add build to run tests against Firefox inside Travis environment (other runs are agains HtmlUnit by default) - - php: 7.0 + # Add build to run tests against Firefox inside Travis environment (other runs are against HtmlUnit by default) + - php: 7.1 env: BROWSER_NAME="firefox" addons: firefox: "45.8.0esr" @@ -20,11 +20,11 @@ matrix: - oracle-java8-installer # Build with lowest possible dependencies - - php: 7.0 + - php: 7.1 env: dependencies="--prefer-lowest" # Saucelabs builds - - php: 7.0 + - php: 7.1 env: SAUCELABS=1 BROWSER_NAME="firefox" VERSION="47.0" PLATFORM="Windows 10" before_script: - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & @@ -33,7 +33,7 @@ matrix: sauce_connect: true jwt: secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= - - php: 7.0 + - php: 7.1 env: SAUCELABS=1 BROWSER_NAME="chrome" VERSION="latest" PLATFORM="Windows 10" before_script: - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & @@ -43,8 +43,8 @@ matrix: jwt: secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= - # Add PHP 7 build to check codestyle only in PHP 7 build - - php: 7.0 + # Codestyle check build + - php: 7.1 env: CHECK_CODESTYLE=1 before_script: ~ script: composer codestyle:check From 6a3b3520d85c63434f00eb15bd4eebfcc0d5e750 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 4 Aug 2017 21:38:09 +0200 Subject: [PATCH 350/784] Build on Ubuntu Trusty, so we don't need to install Java 8 by ourselves --- .travis.yml | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index fde500451..5ae58d50e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,7 @@ language: php +dist: trusty + php: - 5.5 - 5.6 @@ -15,9 +17,6 @@ matrix: env: BROWSER_NAME="firefox" addons: firefox: "45.8.0esr" - apt: - packages: - - oracle-java8-installer # Build with lowest possible dependencies - php: 7.1 @@ -69,7 +68,7 @@ install: before_script: - sh -e /etc/init.d/xvfb start - if [ ! -f jar/selenium-server-standalone-3.1.0.jar ]; then wget -q -t 3 -P jar https://selenium-release.storage.googleapis.com/3.1/selenium-server-standalone-3.1.0.jar; fi - - /usr/lib/jvm/java-8-oracle/bin/java -Dwebdriver.firefox.marionette=false -jar jar/selenium-server-standalone-3.1.0.jar -log ./logs/selenium.log & + - java -Dwebdriver.firefox.marionette=false -jar jar/selenium-server-standalone-3.1.0.jar -log ./logs/selenium.log & - until $(echo | nc localhost 4444); do sleep 1; echo Waiting for Selenium server on port 4444...; done; echo "Selenium server started" - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & - until $(echo | nc localhost 8000); do sleep 1; echo waiting for PHP server on port 8000...; done; echo "PHP server started" @@ -84,8 +83,3 @@ after_script: after_success: - travis_retry php vendor/bin/coveralls -v - -addons: - apt: - packages: - - oracle-java8-installer From 3289cd39ab82d53b09853d98cf5bb780685eb791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 4 Aug 2017 21:49:57 +0200 Subject: [PATCH 351/784] Add headless chrome travis build --- .travis.yml | 24 ++++++++++++++++-------- tests/functional/WebDriverAlertTest.php | 6 ++++++ tests/functional/WebDriverTestCase.php | 7 +++++++ 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5ae58d50e..b12b404db 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: php - +sudo: false dist: trusty php: @@ -8,16 +8,26 @@ php: - 7.0 - 7.1 -sudo: false +env: + global: + - DISPLAY=:99.0 + - BROWSER_NAME="htmlunit" + - CHROMEDRIVER_VERSION="2.31" matrix: include: - # Add build to run tests against Firefox inside Travis environment (other runs are against HtmlUnit by default) + # Add build to run tests against Firefox inside Travis environment - php: 7.1 env: BROWSER_NAME="firefox" addons: firefox: "45.8.0esr" + # Add build to run tests against Chrome inside Travis environment + - php: 7.1 + env: BROWSER_NAME="chrome" CHROME_HEADLESS="1" + addons: + chrome: beta + # Build with lowest possible dependencies - php: 7.1 env: dependencies="--prefer-lowest" @@ -50,10 +60,6 @@ matrix: after_script: ~ after_success: ~ -env: - global: - - DISPLAY=:99.0 - cache: directories: - $HOME/.composer/cache @@ -66,9 +72,11 @@ install: - travis_retry composer update --no-interaction $dependencies before_script: + - if [ "$BROWSER_NAME" = "chrome" ]; then mkdir chromedriver; wget -q -t 3 https://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip; unzip chromedriver_linux64 -d chromedriver; fi + - if [ "$BROWSER_NAME" = "chrome" ]; then export CHROMEDRIVER_PATH=./chromedriver/chromedriver; fi - sh -e /etc/init.d/xvfb start - if [ ! -f jar/selenium-server-standalone-3.1.0.jar ]; then wget -q -t 3 -P jar https://selenium-release.storage.googleapis.com/3.1/selenium-server-standalone-3.1.0.jar; fi - - java -Dwebdriver.firefox.marionette=false -jar jar/selenium-server-standalone-3.1.0.jar -log ./logs/selenium.log & + - java -Dwebdriver.firefox.marionette=false -Dwebdriver.chrome.driver="$CHROMEDRIVER_PATH" -jar jar/selenium-server-standalone-3.1.0.jar -log ./logs/selenium.log & - until $(echo | nc localhost 4444); do sleep 1; echo Waiting for Selenium server on port 4444...; done; echo "Selenium server started" - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & - until $(echo | nc localhost 8000); do sleep 1; echo waiting for PHP server on port 8000...; done; echo "PHP server started" diff --git a/tests/functional/WebDriverAlertTest.php b/tests/functional/WebDriverAlertTest.php index eddf3a9ae..61126b9bd 100644 --- a/tests/functional/WebDriverAlertTest.php +++ b/tests/functional/WebDriverAlertTest.php @@ -25,6 +25,12 @@ class WebDriverAlertTest extends WebDriverTestCase { protected function setUp() { + if (getenv('CHROME_HEADLESS') === '1') { + // Alerts in headless mode should be available in next Chrome version (61), see: + // https://bugs.chromium.org/p/chromium/issues/detail?id=718235 + $this->markTestSkipped('Alerts not yet supported by headless Chrome'); + } + parent::setUp(); $this->driver->get($this->getTestPageUrl('alert.html')); diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index 84883574a..0c11e3fb8 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -15,6 +15,7 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Chrome\ChromeOptions; use Facebook\WebDriver\Exception\NoSuchWindowException; use Facebook\WebDriver\Remote\DesiredCapabilities; use Facebook\WebDriver\Remote\RemoteWebDriver; @@ -47,6 +48,12 @@ protected function setUp() $browserName = WebDriverBrowserType::HTMLUNIT; } + if ($browserName === WebDriverBrowserType::CHROME) { + $chromeOptions = new ChromeOptions(); + $chromeOptions->addArguments(['--headless', 'window-size=1024,768']); + $this->desiredCapabilities->setCapability(ChromeOptions::CAPABILITY, $chromeOptions); + } + $this->desiredCapabilities->setBrowserName($browserName); } From 23b1d70c7671443ed686313f71c5ae293e676d8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 4 Aug 2017 22:43:45 +0200 Subject: [PATCH 352/784] Upgrade Selenium server in Travis buils to 3.4.0 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index b12b404db..68db86dfb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -75,8 +75,8 @@ before_script: - if [ "$BROWSER_NAME" = "chrome" ]; then mkdir chromedriver; wget -q -t 3 https://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip; unzip chromedriver_linux64 -d chromedriver; fi - if [ "$BROWSER_NAME" = "chrome" ]; then export CHROMEDRIVER_PATH=./chromedriver/chromedriver; fi - sh -e /etc/init.d/xvfb start - - if [ ! -f jar/selenium-server-standalone-3.1.0.jar ]; then wget -q -t 3 -P jar https://selenium-release.storage.googleapis.com/3.1/selenium-server-standalone-3.1.0.jar; fi - - java -Dwebdriver.firefox.marionette=false -Dwebdriver.chrome.driver="$CHROMEDRIVER_PATH" -jar jar/selenium-server-standalone-3.1.0.jar -log ./logs/selenium.log & + - if [ ! -f jar/selenium-server-standalone-3.4.0.jar ]; then wget -q -t 3 -P jar https://selenium-release.storage.googleapis.com/3.4/selenium-server-standalone-3.4.0.jar; fi + - java -Dwebdriver.firefox.marionette=false -Dwebdriver.chrome.driver="$CHROMEDRIVER_PATH" -jar jar/selenium-server-standalone-3.4.0.jar -log ./logs/selenium.log & - until $(echo | nc localhost 4444); do sleep 1; echo Waiting for Selenium server on port 4444...; done; echo "Selenium server started" - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & - until $(echo | nc localhost 8000); do sleep 1; echo waiting for PHP server on port 8000...; done; echo "PHP server started" From 5f5d0fd96e984d31d80ec06e866ff126dfce496e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 5 Aug 2017 01:40:55 +0200 Subject: [PATCH 353/784] Add MS Edge build on SauceLabs --- .travis.yml | 13 +++++- tests/functional/FileUploadTest.php | 14 ++---- .../RemoteWebDriverFindElementTest.php | 2 +- tests/functional/RemoteWebElementTest.php | 10 ++++- tests/functional/WebDriverSelectTest.php | 44 +++++++++++++++++-- 5 files changed, 65 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index 68db86dfb..65e48e036 100644 --- a/.travis.yml +++ b/.travis.yml @@ -51,6 +51,15 @@ matrix: sauce_connect: true jwt: secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= + - php: 7.1 + env: SAUCELABS=1 BROWSER_NAME="MicrosoftEdge" VERSION="15.15063" PLATFORM="Windows 10" + before_script: + - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & + - until $(echo | nc localhost 8000); do sleep 1; echo waiting for PHP server on port 8000...; done; echo "PHP server started" + addons: + sauce_connect: true + jwt: + secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= # Codestyle check build - php: 7.1 @@ -82,7 +91,9 @@ before_script: - until $(echo | nc localhost 8000); do sleep 1; echo waiting for PHP server on port 8000...; done; echo "PHP server started" script: - - if [ -n "$SAUCELABS" ]; then EXTRA_PARAMS="--exclude-group exclude-saucelabs"; fi + - if [ -n "$SAUCELABS" ]; then EXCLUDE_GROUP+="exclude-saucelabs,"; fi + - if [ "$BROWSER_NAME" = "MicrosoftEdge" ]; then EXCLUDE_GROUP+="exclude-edge,"; fi + - if [ -n "$EXCLUDE_GROUP" ]; then EXTRA_PARAMS+=" --exclude-group $EXCLUDE_GROUP"; fi - ./vendor/bin/phpunit --coverage-clover ./logs/coverage-clover.xml $EXTRA_PARAMS after_script: diff --git a/tests/functional/FileUploadTest.php b/tests/functional/FileUploadTest.php index ef6cf1bb2..e88139953 100644 --- a/tests/functional/FileUploadTest.php +++ b/tests/functional/FileUploadTest.php @@ -23,6 +23,10 @@ */ class FileUploadTest extends WebDriverTestCase { + /** + * @group exclude-edge + * https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/6052385/ + */ public function testShouldUploadAFile() { $this->driver->get($this->getTestPageUrl('upload.html')); @@ -50,16 +54,6 @@ public function testShouldUploadAFile() $this->assertSame('10', $uploadedFileSize); } - public function xtestUselessFileDetectorSendKeys() - { - $this->driver->get($this->getTestPageUrl('upload.html')); - - $file_input = $this->driver->findElement(WebDriverBy::id('upload')); - $file_input->sendKeys($this->getTestFilePath()); - - $this->assertEquals($this->getTestFilePath(), $file_input->getAttribute('value')); - } - private function getTestFilePath() { return __DIR__ . '/Fixtures/FileUploadTestFile.txt'; diff --git a/tests/functional/RemoteWebDriverFindElementTest.php b/tests/functional/RemoteWebDriverFindElementTest.php index 808763bad..004a554b8 100644 --- a/tests/functional/RemoteWebDriverFindElementTest.php +++ b/tests/functional/RemoteWebDriverFindElementTest.php @@ -28,7 +28,7 @@ public function testShouldThrowExceptionOfElementCannotBeFound() { $this->driver->get($this->getTestPageUrl('index.html')); - $this->setExpectedException(NoSuchElementException::class, 'Unable to locate element'); + $this->setExpectedException(NoSuchElementException::class); $this->driver->findElement(WebDriverBy::id('not_existing')); } diff --git a/tests/functional/RemoteWebElementTest.php b/tests/functional/RemoteWebElementTest.php index 26d13f6e2..643e2a336 100644 --- a/tests/functional/RemoteWebElementTest.php +++ b/tests/functional/RemoteWebElementTest.php @@ -22,6 +22,8 @@ class RemoteWebElementTest extends WebDriverTestCase { /** * @covers ::getText + * @group exclude-edge + * https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/5569343/ */ public function testShouldGetText() { @@ -90,8 +92,11 @@ public function testShouldGetCssValue() $this->assertSame('solid', $elementWithBorder->getCSSValue('border-left-style')); $this->assertSame('none', $elementWithoutBorder->getCSSValue('border-left-style')); - $this->assertSame('rgba(0, 0, 0, 1)', $elementWithBorder->getCSSValue('border-left-color')); - $this->assertSame('rgba(0, 0, 0, 1)', $elementWithoutBorder->getCSSValue('border-left-color')); + // Browser could report color in either rgb (like MS Edge) or rgba (like everyone else) + $this->assertRegExp( + '/rgba?\(0, 0, 0(, 1)?\)/', + $elementWithBorder->getCSSValue('border-left-color') + ); } /** @@ -206,6 +211,7 @@ public function testShouldSelectedInputsOrOptions() /** * @covers ::submit + * @group exclude-edge */ public function testShouldSubmitFormBySubmitEventOnForm() { diff --git a/tests/functional/WebDriverSelectTest.php b/tests/functional/WebDriverSelectTest.php index ac32cbca7..33ebe38f9 100644 --- a/tests/functional/WebDriverSelectTest.php +++ b/tests/functional/WebDriverSelectTest.php @@ -129,6 +129,10 @@ public function testShouldSelectOptionOfSimpleSelectByIndex() $this->assertSame('fourth', $select->getFirstSelectedOption()->getAttribute('value')); } + /** + * @group exclude-edge + * https://connect.microsoft.com/IE/feedback/details/2020772/-microsoft-edge-webdriver-cannot-select-multiple-on-select-html-tag + */ public function testShouldSelectOptionOfMultipleSelectByIndex() { $select = $this->getWebDriverSelectForMultipleSelect(); @@ -171,6 +175,10 @@ public function testShouldSelectOptionOfSimpleSelectByValue() $this->assertSame('fourth', $select->getFirstSelectedOption()->getAttribute('value')); } + /** + * @group exclude-edge + * https://connect.microsoft.com/IE/feedback/details/2020772/-microsoft-edge-webdriver-cannot-select-multiple-on-select-html-tag + */ public function testShouldSelectOptionOfMultipleSelectByValue() { $select = $this->getWebDriverSelectForMultipleSelect(); @@ -213,6 +221,10 @@ public function testShouldSelectOptionOfSimpleSelectByVisibleText() $this->assertSame('fifth', $select->getFirstSelectedOption()->getAttribute('value')); } + /** + * @group exclude-edge + * https://connect.microsoft.com/IE/feedback/details/2020772/-microsoft-edge-webdriver-cannot-select-multiple-on-select-html-tag + */ public function testShouldSelectOptionOfMultipleSelectByVisibleText() { $select = $this->getWebDriverSelectForMultipleSelect(); @@ -255,6 +267,10 @@ public function testShouldSelectOptionOfSimpleSelectByVisiblePartialText() $this->assertSame('fourth', $select->getFirstSelectedOption()->getAttribute('value')); } + /** + * @group exclude-edge + * https://connect.microsoft.com/IE/feedback/details/2020772/-microsoft-edge-webdriver-cannot-select-multiple-on-select-html-tag + */ public function testShouldSelectOptionOfMultipleSelectByVisiblePartialText() { $select = $this->getWebDriverSelectForMultipleSelect(); @@ -298,6 +314,10 @@ public function testShouldThrowExceptionWhenDeselectingOnSimpleSelect() $select->deselectAll(); } + /** + * @group exclude-edge + * https://connect.microsoft.com/IE/feedback/details/2020772/-microsoft-edge-webdriver-cannot-select-multiple-on-select-html-tag + */ public function testShouldDeselectAllOptionsOnMultipleSelect() { $select = $this->getWebDriverSelectForMultipleSelect(); @@ -312,7 +332,11 @@ public function testShouldDeselectAllOptionsOnMultipleSelect() $this->assertCount(0, $select->getAllSelectedOptions()); } - public function testShouldDeselectOptionByIndex() + /** + * @group exclude-edge + * https://connect.microsoft.com/IE/feedback/details/2020772/-microsoft-edge-webdriver-cannot-select-multiple-on-select-html-tag + */ + public function testShouldDeselectOptionOnMultipleSelectByIndex() { $select = $this->getWebDriverSelectForMultipleSelect(); $select->selectByValue('fourth'); // index 3 @@ -336,7 +360,11 @@ public function testShouldThrowExceptionIfDeselectingSimpleSelectByIndex() $select->deselectByIndex(0); } - public function testShouldDeselectOptionByValue() + /** + * @group exclude-edge + * https://connect.microsoft.com/IE/feedback/details/2020772/-microsoft-edge-webdriver-cannot-select-multiple-on-select-html-tag + */ + public function testShouldDeselectOptionOnMultipleSelectByValue() { $select = $this->getWebDriverSelectForMultipleSelect(); $select->selectByValue('third'); @@ -360,7 +388,11 @@ public function testShouldThrowExceptionIfDeselectingSimpleSelectByValue() $select->deselectByValue('first'); } - public function testShouldDeselectOptionByVisibleText() + /** + * @group exclude-edge + * https://connect.microsoft.com/IE/feedback/details/2020772/-microsoft-edge-webdriver-cannot-select-multiple-on-select-html-tag + */ + public function testShouldDeselectOptionOnMultipleSelectByVisibleText() { $select = $this->getWebDriverSelectForMultipleSelect(); $select->selectByValue('fourth'); // text 'Fourth with spaces inside' @@ -386,7 +418,11 @@ public function testShouldThrowExceptionIfDeselectingSimpleSelectByVisibleText() $select->deselectByVisibleText('First'); } - public function testShouldDeselectOptionByVisiblePartialText() + /** + * @group exclude-edge + * https://connect.microsoft.com/IE/feedback/details/2020772/-microsoft-edge-webdriver-cannot-select-multiple-on-select-html-tag + */ + public function testShouldDeselectOptionOnMultipleSelectByVisiblePartialText() { $select = $this->getWebDriverSelectForMultipleSelect(); $select->selectByValue('fourth'); // text 'Fourth with spaces inside' From 735a6156617d62fe95ed20e6d038daa22b98e74b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 5 Aug 2017 15:20:28 +0200 Subject: [PATCH 354/784] Extend connection timeout, because Edge is slow... --- tests/functional/RemoteWebDriverCreateTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/functional/RemoteWebDriverCreateTest.php b/tests/functional/RemoteWebDriverCreateTest.php index 95ff4851c..466e1601c 100644 --- a/tests/functional/RemoteWebDriverCreateTest.php +++ b/tests/functional/RemoteWebDriverCreateTest.php @@ -29,7 +29,7 @@ class RemoteWebDriverCreateTest extends WebDriverTestCase public function testShouldStartBrowserAndCreateInstanceOfRemoteWebDriver() { - $this->driver = RemoteWebDriver::create($this->serverUrl, $this->desiredCapabilities, 10000, 13370); + $this->driver = RemoteWebDriver::create($this->serverUrl, $this->desiredCapabilities, 30000, 33370); $this->assertInstanceOf(RemoteWebDriver::class, $this->driver); From cb1f8bd54058ff3ded938e811d50e72e6c3a13ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 4 Aug 2017 22:20:51 +0200 Subject: [PATCH 355/784] Drop PHP 5.5 support --- .travis.yml | 1 - CHANGELOG.md | 2 ++ lib/Support/Events/EventFiringWebDriver.php | 5 ++--- lib/Support/Events/EventFiringWebDriverNavigation.php | 5 ++--- lib/Support/Events/EventFiringWebElement.php | 6 +++--- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 65e48e036..9b2b5894e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,6 @@ sudo: false dist: trusty php: - - 5.5 - 5.6 - 7.0 - 7.1 diff --git a/CHANGELOG.md b/CHANGELOG.md index c7d018435..182aeda87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +### Changed +- Drop PHP 5.5 support, the minimal required version of PHP is now PHP 5.6. ## 1.4.1 - 2017-04-28 ### Fixed diff --git a/lib/Support/Events/EventFiringWebDriver.php b/lib/Support/Events/EventFiringWebDriver.php index ffac00e5c..c129ef015 100644 --- a/lib/Support/Events/EventFiringWebDriver.php +++ b/lib/Support/Events/EventFiringWebDriver.php @@ -396,15 +396,14 @@ protected function newElement(WebDriverElement $element) /** * @param mixed $method + * @param mixed $arguments,... */ - protected function dispatch($method) + protected function dispatch($method, ...$arguments) { if (!$this->dispatcher) { return; } - $arguments = func_get_args(); - unset($arguments[0]); $this->dispatcher->dispatch($method, $arguments); } diff --git a/lib/Support/Events/EventFiringWebDriverNavigation.php b/lib/Support/Events/EventFiringWebDriverNavigation.php index 5aeaf510b..0008ebbdc 100644 --- a/lib/Support/Events/EventFiringWebDriverNavigation.php +++ b/lib/Support/Events/EventFiringWebDriverNavigation.php @@ -149,15 +149,14 @@ public function to($url) /** * @param mixed $method + * @param mixed $arguments,... */ - protected function dispatch($method) + protected function dispatch($method, ...$arguments) { if (!$this->dispatcher) { return; } - $arguments = func_get_args(); - unset($arguments[0]); $this->dispatcher->dispatch($method, $arguments); } diff --git a/lib/Support/Events/EventFiringWebElement.php b/lib/Support/Events/EventFiringWebElement.php index f932b20a3..099bb3573 100644 --- a/lib/Support/Events/EventFiringWebElement.php +++ b/lib/Support/Events/EventFiringWebElement.php @@ -392,14 +392,14 @@ protected function dispatchOnException(WebDriverException $exception) /** * @param mixed $method + * @param mixed $arguments,... */ - protected function dispatch($method) + protected function dispatch($method, ...$arguments) { if (!$this->dispatcher) { return; } - $arguments = func_get_args(); - unset($arguments[0]); + $this->dispatcher->dispatch($method, $arguments); } From 1c5e7f08d670f1ad921d3425903f852204fd8977 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 25 Aug 2017 20:29:48 +0200 Subject: [PATCH 356/784] Extend connection timeout further more to make SauceLabs tests hopefully more stable --- tests/functional/RemoteWebDriverCreateTest.php | 18 ++++++++++++++---- tests/functional/WebDriverTestCase.php | 11 ++++++++++- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/tests/functional/RemoteWebDriverCreateTest.php b/tests/functional/RemoteWebDriverCreateTest.php index 466e1601c..3140b26b0 100644 --- a/tests/functional/RemoteWebDriverCreateTest.php +++ b/tests/functional/RemoteWebDriverCreateTest.php @@ -29,7 +29,12 @@ class RemoteWebDriverCreateTest extends WebDriverTestCase public function testShouldStartBrowserAndCreateInstanceOfRemoteWebDriver() { - $this->driver = RemoteWebDriver::create($this->serverUrl, $this->desiredCapabilities, 30000, 33370); + $this->driver = RemoteWebDriver::create( + $this->serverUrl, + $this->desiredCapabilities, + $this->connectionTimeout, + $this->requestTimeout + ); $this->assertInstanceOf(RemoteWebDriver::class, $this->driver); @@ -51,8 +56,8 @@ public function testShouldCreateWebDriverWithRequiredCapabilities() $this->driver = RemoteWebDriver::create( $this->serverUrl, $this->desiredCapabilities, - null, - null, + $this->connectionTimeout, + $this->requestTimeout, null, null, $requiredCapabilities @@ -64,7 +69,12 @@ public function testShouldCreateWebDriverWithRequiredCapabilities() public function testShouldCreateInstanceFromExistingSessionId() { // Create driver instance and load page "index.html" - $originalDriver = RemoteWebDriver::create($this->serverUrl, $this->desiredCapabilities); + $originalDriver = RemoteWebDriver::create( + $this->serverUrl, + $this->desiredCapabilities, + $this->connectionTimeout, + $this->requestTimeout + ); $originalDriver->get($this->getTestPageUrl('index.html')); $this->assertContains('/index.html', $originalDriver->getCurrentURL()); diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index 0c11e3fb8..77a98f884 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -34,6 +34,10 @@ class WebDriverTestCase extends \PHPUnit_Framework_TestCase protected $serverUrl = 'http://localhost:4444/wd/hub'; /** @var DesiredCapabilities */ protected $desiredCapabilities; + /** @var int */ + protected $connectionTimeout = 60000; + /** @var int */ + protected $requestTimeout = 60000; protected function setUp() { @@ -58,7 +62,12 @@ protected function setUp() } if ($this->createWebDriver) { - $this->driver = RemoteWebDriver::create($this->serverUrl, $this->desiredCapabilities); + $this->driver = RemoteWebDriver::create( + $this->serverUrl, + $this->desiredCapabilities, + $this->connectionTimeout, + $this->requestTimeout + ); } } From 3581da1e816335f09b3508c6d64baf2a91512cb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Thu, 31 Aug 2017 17:13:20 +0200 Subject: [PATCH 357/784] Use only PHPUnit 5.4+, drop deprecated calls --- composer.json | 4 +- .../RemoteWebDriverFindElementTest.php | 2 +- tests/functional/WebDriverAlertTest.php | 2 +- tests/functional/WebDriverSelectTest.php | 66 +++++++------------ tests/functional/WebDriverTimeoutsTest.php | 2 +- tests/unit/CookieTest.php | 3 +- tests/unit/WebDriverOptionsTest.php | 6 +- 7 files changed, 31 insertions(+), 54 deletions(-) diff --git a/composer.json b/composer.json index 0a87cb3ed..cbf3155a9 100644 --- a/composer.json +++ b/composer.json @@ -11,13 +11,13 @@ "source": "https://github.com/facebook/php-webdriver" }, "require": { - "php": "^5.5 || ~7.0", + "php": "^5.6 || ~7.0", "symfony/process": "^2.8 || ^3.1", "ext-curl": "*", "ext-zip": "*" }, "require-dev": { - "phpunit/phpunit": "4.6.* || ~5.0", + "phpunit/phpunit": "^5.4", "friendsofphp/php-cs-fixer": "^2.0", "squizlabs/php_codesniffer": "^2.6", "php-mock/php-mock-phpunit": "^1.1", diff --git a/tests/functional/RemoteWebDriverFindElementTest.php b/tests/functional/RemoteWebDriverFindElementTest.php index 004a554b8..106d5d90f 100644 --- a/tests/functional/RemoteWebDriverFindElementTest.php +++ b/tests/functional/RemoteWebDriverFindElementTest.php @@ -28,7 +28,7 @@ public function testShouldThrowExceptionOfElementCannotBeFound() { $this->driver->get($this->getTestPageUrl('index.html')); - $this->setExpectedException(NoSuchElementException::class); + $this->expectException(NoSuchElementException::class); $this->driver->findElement(WebDriverBy::id('not_existing')); } diff --git a/tests/functional/WebDriverAlertTest.php b/tests/functional/WebDriverAlertTest.php index 61126b9bd..08d8ef73c 100644 --- a/tests/functional/WebDriverAlertTest.php +++ b/tests/functional/WebDriverAlertTest.php @@ -48,7 +48,7 @@ public function testShouldAcceptAlert() $this->driver->switchTo()->alert()->accept(); - $this->setExpectedException(NoAlertOpenException::class); + $this->expectException(NoAlertOpenException::class); $this->driver->switchTo()->alert()->accept(); } diff --git a/tests/functional/WebDriverSelectTest.php b/tests/functional/WebDriverSelectTest.php index 33ebe38f9..9cd6cf250 100644 --- a/tests/functional/WebDriverSelectTest.php +++ b/tests/functional/WebDriverSelectTest.php @@ -51,10 +51,8 @@ public function testShouldThrowExceptionWhenNotInstantiatedOnSelectElement() { $notSelectElement = $this->driver->findElement(WebDriverBy::cssSelector('textarea')); - $this->setExpectedException( - UnexpectedTagNameException::class, - 'Element should have been "select" but was "textarea"' - ); + $this->expectException(UnexpectedTagNameException::class); + $this->expectExceptionMessage('Element should have been "select" but was "textarea"'); new WebDriverSelect($notSelectElement); } @@ -109,10 +107,8 @@ public function testShouldThrowExceptionIfThereIsNoFirstSelectedOptionOfMultiple { $select = $this->getWebDriverSelectForMultipleSelect(); - $this->setExpectedException( - NoSuchElementException::class, - 'No options are selected' - ); + $this->expectException(NoSuchElementException::class); + $this->expectExceptionMessage('No options are selected'); $select->getFirstSelectedOption(); } @@ -155,10 +151,8 @@ public function testShouldThrowExceptionIfThereIsNoOptionIndexToSelect() { $select = $this->getWebDriverSelectForSimpleSelect(); - $this->setExpectedException( - NoSuchElementException::class, - 'Cannot locate option with index: 1337' - ); + $this->expectException(NoSuchElementException::class); + $this->expectExceptionMessage('Cannot locate option with index: 1337'); $select->selectByIndex(1337); } @@ -201,10 +195,8 @@ public function testShouldThrowExceptionIfThereIsNoOptionValueToSelect() { $select = $this->getWebDriverSelectForSimpleSelect(); - $this->setExpectedException( - NoSuchElementException::class, - 'Cannot locate option with value: 1337' - ); + $this->expectException(NoSuchElementException::class); + $this->expectExceptionMessage('Cannot locate option with value: 1337'); $select->selectByValue(1337); } @@ -247,10 +239,8 @@ public function testShouldThrowExceptionIfThereIsNoOptionVisibleTextToSelect() { $select = $this->getWebDriverSelectForSimpleSelect(); - $this->setExpectedException( - NoSuchElementException::class, - 'Cannot locate option with text: second' - ); + $this->expectException(NoSuchElementException::class); + $this->expectExceptionMessage('Cannot locate option with text: second'); $select->selectByVisibleText('second'); // the option is "This is second option" } @@ -296,10 +286,8 @@ public function testShouldThrowExceptionIfThereIsNoOptionVisiblePartialTextToSel { $select = $this->getWebDriverSelectForSimpleSelect(); - $this->setExpectedException( - NoSuchElementException::class, - 'Cannot locate option with text: Not existing option' - ); + $this->expectException(NoSuchElementException::class); + $this->expectExceptionMessage('Cannot locate option with text: Not existing option'); $select->selectByVisiblePartialText('Not existing option'); } @@ -307,10 +295,8 @@ public function testShouldThrowExceptionWhenDeselectingOnSimpleSelect() { $select = $this->getWebDriverSelectForSimpleSelect(); - $this->setExpectedException( - UnsupportedOperationException::class, - 'You may only deselect all options of a multi-select' - ); + $this->expectException(UnsupportedOperationException::class); + $this->expectExceptionMessage('You may only deselect all options of a multi-select'); $select->deselectAll(); } @@ -353,10 +339,8 @@ public function testShouldThrowExceptionIfDeselectingSimpleSelectByIndex() { $select = $this->getWebDriverSelectForSimpleSelect(); - $this->setExpectedException( - UnsupportedOperationException::class, - 'You may only deselect options of a multi-select' - ); + $this->expectException(UnsupportedOperationException::class); + $this->expectExceptionMessage('You may only deselect options of a multi-select'); $select->deselectByIndex(0); } @@ -381,10 +365,8 @@ public function testShouldThrowExceptionIfDeselectingSimpleSelectByValue() { $select = $this->getWebDriverSelectForSimpleSelect(); - $this->setExpectedException( - UnsupportedOperationException::class, - 'You may only deselect options of a multi-select' - ); + $this->expectException(UnsupportedOperationException::class); + $this->expectExceptionMessage('You may only deselect options of a multi-select'); $select->deselectByValue('first'); } @@ -411,10 +393,8 @@ public function testShouldThrowExceptionIfDeselectingSimpleSelectByVisibleText() { $select = $this->getWebDriverSelectForSimpleSelect(); - $this->setExpectedException( - UnsupportedOperationException::class, - 'You may only deselect options of a multi-select' - ); + $this->expectException(UnsupportedOperationException::class); + $this->expectExceptionMessage('You may only deselect options of a multi-select'); $select->deselectByVisibleText('First'); } @@ -447,10 +427,8 @@ public function testShouldThrowExceptionIfDeselectingSimpleSelectByVisiblePartia { $select = $this->getWebDriverSelectForSimpleSelect(); - $this->setExpectedException( - UnsupportedOperationException::class, - 'You may only deselect options of a multi-select' - ); + $this->expectException(UnsupportedOperationException::class); + $this->expectExceptionMessage('You may only deselect options of a multi-select'); $select->deselectByVisiblePartialText('First'); } diff --git a/tests/functional/WebDriverTimeoutsTest.php b/tests/functional/WebDriverTimeoutsTest.php index 51be6e13a..47edc886d 100644 --- a/tests/functional/WebDriverTimeoutsTest.php +++ b/tests/functional/WebDriverTimeoutsTest.php @@ -30,7 +30,7 @@ public function testShouldFailGettingDelayedElementWithoutWait() { $this->driver->get($this->getTestPageUrl('delayed_element.html')); - $this->setExpectedException(NoSuchElementException::class); + $this->expectException(NoSuchElementException::class); $this->driver->findElement(WebDriverBy::id('delayed')); } diff --git a/tests/unit/CookieTest.php b/tests/unit/CookieTest.php index 0742a0789..ccf2a1e6f 100644 --- a/tests/unit/CookieTest.php +++ b/tests/unit/CookieTest.php @@ -146,7 +146,8 @@ public function testShouldBeCreatableFromAnArrayWithAllValues() public function testShouldValidateCookie($name, $value, $domain, $expectedMessage) { if ($expectedMessage) { - $this->setExpectedException(\InvalidArgumentException::class, $expectedMessage); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage($expectedMessage); } $cookie = new Cookie($name, $value); diff --git a/tests/unit/WebDriverOptionsTest.php b/tests/unit/WebDriverOptionsTest.php index 5e335854f..8bc47b96f 100644 --- a/tests/unit/WebDriverOptionsTest.php +++ b/tests/unit/WebDriverOptionsTest.php @@ -88,10 +88,8 @@ public function testShouldNotAllowToCreateCookieFromDifferentObjectThanCookie() $options = new WebDriverOptions($this->executor); - $this->setExpectedException( - \InvalidArgumentException::class, - 'Cookie must be set from instance of Cookie class or from array.' - ); + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Cookie must be set from instance of Cookie class or from array.'); $options->addCookie($notCookie); } From 11b1d4dcf40a0b382acb9322358cea2d97679d1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Thu, 31 Aug 2017 16:47:09 +0200 Subject: [PATCH 358/784] Add functional tests for findElement for child elements --- .../RemoteWebDriverFindElementTest.php | 4 +- tests/functional/RemoteWebElementTest.php | 52 +++++++++++++++++++ tests/functional/web/index.html | 5 ++ tests/unit/Remote/RemoteWebElementTest.php | 36 +++++++++++++ 4 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 tests/unit/Remote/RemoteWebElementTest.php diff --git a/tests/functional/RemoteWebDriverFindElementTest.php b/tests/functional/RemoteWebDriverFindElementTest.php index 106d5d90f..46affc025 100644 --- a/tests/functional/RemoteWebDriverFindElementTest.php +++ b/tests/functional/RemoteWebDriverFindElementTest.php @@ -24,7 +24,7 @@ */ class RemoteWebDriverFindElementTest extends WebDriverTestCase { - public function testShouldThrowExceptionOfElementCannotBeFound() + public function testShouldThrowExceptionIfElementCannotBeFound() { $this->driver->get($this->getTestPageUrl('index.html')); @@ -58,7 +58,7 @@ public function testShouldFindMultipleElements() $elements = $this->driver->findElements(WebDriverBy::cssSelector('ul > li')); $this->assertInternalType('array', $elements); - $this->assertCount(3, $elements); + $this->assertCount(5, $elements); $this->assertContainsOnlyInstancesOf(RemoteWebElement::class, $elements); } } diff --git a/tests/functional/RemoteWebElementTest.php b/tests/functional/RemoteWebElementTest.php index 643e2a336..51f414a93 100644 --- a/tests/functional/RemoteWebElementTest.php +++ b/tests/functional/RemoteWebElementTest.php @@ -15,6 +15,9 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Exception\NoSuchElementException; +use Facebook\WebDriver\Remote\RemoteWebElement; + /** * @coversDefaultClass Facebook\WebDriver\Remote\RemoteWebElement */ @@ -282,4 +285,53 @@ public function testShouldCompareEqualsElement() $this->assertFalse($firstElement->equals($differentElement)); $this->assertFalse($differentElement->equals($againTheFirstElement)); } + + /** + * @covers ::findElement + */ + public function testShouldThrowExceptionIfChildElementCannotBeFound() + { + $this->driver->get($this->getTestPageUrl('index.html')); + $element = $this->driver->findElement(WebDriverBy::cssSelector('ul.list')); + + $this->expectException(NoSuchElementException::class); + $element->findElement(WebDriverBy::id('not_existing')); + } + + public function testShouldFindChildElementIfExistsOnAPage() + { + $this->driver->get($this->getTestPageUrl('index.html')); + $element = $this->driver->findElement(WebDriverBy::cssSelector('ul.list')); + + $childElement = $element->findElement(WebDriverBy::cssSelector('li')); + + $this->assertInstanceOf(RemoteWebElement::class, $childElement); + $this->assertSame('li', $childElement->getTagName()); + $this->assertSame('First', $childElement->getText()); + } + + public function testShouldReturnEmptyArrayIfChildElementsCannotBeFound() + { + $this->driver->get($this->getTestPageUrl('index.html')); + $element = $this->driver->findElement(WebDriverBy::cssSelector('ul.list')); + + $childElements = $element->findElements(WebDriverBy::cssSelector('not_existing')); + + $this->assertInternalType('array', $childElements); + $this->assertCount(0, $childElements); + } + + public function testShouldFindMultipleChildElements() + { + $this->driver->get($this->getTestPageUrl('index.html')); + $element = $this->driver->findElement(WebDriverBy::cssSelector('ul.list')); + + $allElements = $this->driver->findElements(WebDriverBy::cssSelector('li')); + $childElements = $element->findElements(WebDriverBy::cssSelector('li')); + + $this->assertInternalType('array', $childElements); + $this->assertCount(5, $allElements); // there should be 5
  • elements on page + $this->assertCount(3, $childElements); // but we should find only subelements of one
      + $this->assertContainsOnlyInstancesOf(RemoteWebElement::class, $childElements); + } } diff --git a/tests/functional/web/index.html b/tests/functional/web/index.html index 8e314f798..1a92f255e 100644 --- a/tests/functional/web/index.html +++ b/tests/functional/web/index.html @@ -30,6 +30,11 @@

      Welcome to the facebook/php-webdriver testing page.

    • Third
    +
      +
    • Foo
    • +
    • Bar
    • +
    +

    Foo bar text

    Multiple spaces are diff --git a/tests/unit/Remote/RemoteWebElementTest.php b/tests/unit/Remote/RemoteWebElementTest.php new file mode 100644 index 000000000..45c057751 --- /dev/null +++ b/tests/unit/Remote/RemoteWebElementTest.php @@ -0,0 +1,36 @@ +createMock(RemoteExecuteMethod::class); + $element = new RemoteWebElement($executeMethod, 333); + + $this->assertSame(333, $element->getID()); + } +} From e8ebc12da32a019612e8874c7e81a884535d1894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 5 Sep 2017 23:37:38 +0200 Subject: [PATCH 359/784] Improve code-coverage settings --- lib/Firefox/FirefoxDriver.php | 3 +++ lib/Firefox/FirefoxPreferences.php | 2 ++ lib/Remote/DriverCommand.php | 2 ++ lib/Remote/WebDriverBrowserType.php | 4 +++- lib/Remote/WebDriverCapabilityType.php | 2 ++ lib/WebDriverPlatform.php | 2 ++ tests/functional/RemoteWebDriverTest.php | 6 ++---- tests/functional/WebDriverTimeoutsTest.php | 2 ++ 8 files changed, 18 insertions(+), 5 deletions(-) diff --git a/lib/Firefox/FirefoxDriver.php b/lib/Firefox/FirefoxDriver.php index 9e0751238..f2883e642 100644 --- a/lib/Firefox/FirefoxDriver.php +++ b/lib/Firefox/FirefoxDriver.php @@ -15,6 +15,9 @@ namespace Facebook\WebDriver\Firefox; +/** + * @codeCoverageIgnore + */ class FirefoxDriver { const PROFILE = 'firefox_profile'; diff --git a/lib/Firefox/FirefoxPreferences.php b/lib/Firefox/FirefoxPreferences.php index b869a2667..be1199c24 100644 --- a/lib/Firefox/FirefoxPreferences.php +++ b/lib/Firefox/FirefoxPreferences.php @@ -18,6 +18,8 @@ /** * Constants of common Firefox profile preferences (about:config values). * @see http://kb.mozillazine.org/Firefox_:_FAQs_:_About:config_Entries + * + * @codeCoverageIgnore */ class FirefoxPreferences { diff --git a/lib/Remote/DriverCommand.php b/lib/Remote/DriverCommand.php index 1b86c71c6..c69052030 100644 --- a/lib/Remote/DriverCommand.php +++ b/lib/Remote/DriverCommand.php @@ -17,6 +17,8 @@ /** * This list of command defined in the WebDriver json wire protocol. + * + * @codeCoverageIgnore */ class DriverCommand { diff --git a/lib/Remote/WebDriverBrowserType.php b/lib/Remote/WebDriverBrowserType.php index 5dd61505e..53b6ab977 100644 --- a/lib/Remote/WebDriverBrowserType.php +++ b/lib/Remote/WebDriverBrowserType.php @@ -16,7 +16,9 @@ namespace Facebook\WebDriver\Remote; /** - * All the browsers supported by selenium + * All the browsers supported by selenium. + * + * @codeCoverageIgnore */ class WebDriverBrowserType { diff --git a/lib/Remote/WebDriverCapabilityType.php b/lib/Remote/WebDriverCapabilityType.php index 131b16561..c452e771c 100644 --- a/lib/Remote/WebDriverCapabilityType.php +++ b/lib/Remote/WebDriverCapabilityType.php @@ -17,6 +17,8 @@ /** * WebDriverCapabilityType contains all constants defined in the WebDriver Wire Protocol. + * + * @codeCoverageIgnore */ class WebDriverCapabilityType { diff --git a/lib/WebDriverPlatform.php b/lib/WebDriverPlatform.php index bb1923556..5609eb0b8 100644 --- a/lib/WebDriverPlatform.php +++ b/lib/WebDriverPlatform.php @@ -17,6 +17,8 @@ /** * The platforms supported by WebDriver. + * + * @codeCoverageIgnore */ class WebDriverPlatform { diff --git a/tests/functional/RemoteWebDriverTest.php b/tests/functional/RemoteWebDriverTest.php index 7b60b69d7..006b17c7b 100644 --- a/tests/functional/RemoteWebDriverTest.php +++ b/tests/functional/RemoteWebDriverTest.php @@ -45,10 +45,7 @@ public function testShouldGetCurrentUrl() { $this->driver->get($this->getTestPageUrl('index.html')); - $this->assertContains( - '/index.html', - $this->driver->getCurrentURL() - ); + $this->assertStringEndsWith('/index.html', $this->driver->getCurrentURL()); } /** @@ -173,6 +170,7 @@ function(){document.getElementById("id_test").innerHTML = "Text changed by scrip /** * @covers ::executeAsyncScript + * @covers Facebook\WebDriver\WebDriverTimeouts::setScriptTimeout */ public function testShouldExecuteAsyncScriptAndWaitUntilItIsFinished() { diff --git a/tests/functional/WebDriverTimeoutsTest.php b/tests/functional/WebDriverTimeoutsTest.php index 47edc886d..808a494ab 100644 --- a/tests/functional/WebDriverTimeoutsTest.php +++ b/tests/functional/WebDriverTimeoutsTest.php @@ -36,6 +36,7 @@ public function testShouldFailGettingDelayedElementWithoutWait() /** * @covers ::implicitlyWait + * @covers ::__construct */ public function testShouldGetDelayedElementWithImplicitWait() { @@ -49,6 +50,7 @@ public function testShouldGetDelayedElementWithImplicitWait() /** * @covers ::pageLoadTimeout + * @covers ::__construct */ public function testShouldFailIfPageIsLoadingLongerThanPageLoadTimeout() { From 7672fe48b2c11784e71156108ae5b3568d31278c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 6 Sep 2017 01:18:38 +0200 Subject: [PATCH 360/784] Add functional tests for WebDriverNavigation --- lib/WebDriverNavigation.php | 1 + tests/functional/WebDriverNavigationTest.php | 85 ++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 tests/functional/WebDriverNavigationTest.php diff --git a/lib/WebDriverNavigation.php b/lib/WebDriverNavigation.php index ccc8cee30..6de59b035 100644 --- a/lib/WebDriverNavigation.php +++ b/lib/WebDriverNavigation.php @@ -75,6 +75,7 @@ public function refresh() /** * Navigate to the given URL. * + * @see WebDriver::get() * @param string $url * @return WebDriverNavigation The instance. */ diff --git a/tests/functional/WebDriverNavigationTest.php b/tests/functional/WebDriverNavigationTest.php new file mode 100644 index 000000000..4f7dba252 --- /dev/null +++ b/tests/functional/WebDriverNavigationTest.php @@ -0,0 +1,85 @@ +driver->navigate()->to($this->getTestPageUrl('index.html')); + + $this->assertStringEndsWith('/index.html', $this->driver->getCurrentURL()); + } + + /** + * @covers ::back + * @covers ::forward + */ + public function testShouldNavigateBackAndForward() + { + $this->driver->get($this->getTestPageUrl('index.html')); + $linkElement = $this->driver->findElement(WebDriverBy::id('a-form')); + + $linkElement->click(); + + $this->driver->wait()->until( + WebDriverExpectedCondition::urlContains('form.html') + ); + + $this->driver->navigate()->back(); + + $this->driver->wait()->until( + WebDriverExpectedCondition::urlContains('index.html') + ); + + $this->driver->navigate()->forward(); + + $this->driver->wait()->until( + WebDriverExpectedCondition::urlContains('form.html') + ); + } + + /** + * @covers ::refresh + */ + public function testShouldRefreshPage() + { + $this->driver->get($this->getTestPageUrl('index.html')); + + // Change input element content, to make sure it was refreshed (=> cleared to original value) + $inputElement = $this->driver->findElement(WebDriverBy::name('test_name')); + $inputElementOriginalValue = $inputElement->getAttribute('value'); + $inputElement->clear()->sendKeys('New value'); + $this->assertSame('New value', $inputElement->getAttribute('value')); + + $this->driver->navigate()->refresh(); + + $this->driver->wait()->until( + WebDriverExpectedCondition::stalenessOf($inputElement) + ); + + $inputElementAfterRefresh = $this->driver->findElement(WebDriverBy::name('test_name')); + + $this->assertSame($inputElementOriginalValue, $inputElementAfterRefresh->getAttribute('value')); + } +} From 61f547414294b8188e149594486d1a91d0f7c8cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 17 Sep 2017 09:54:20 +0200 Subject: [PATCH 361/784] Add symfony/var-dumper dev dependency for easier development --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index cbf3155a9..8eff450f7 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,8 @@ "friendsofphp/php-cs-fixer": "^2.0", "squizlabs/php_codesniffer": "^2.6", "php-mock/php-mock-phpunit": "^1.1", - "satooshi/php-coveralls": "^1.0" + "satooshi/php-coveralls": "^1.0", + "symfony/var-dumper": "^3.3" }, "autoload": { "psr-4": { From 944c76eb61403ee9479a58285c4cd2abae00526e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 13 Oct 2017 23:59:03 +0200 Subject: [PATCH 362/784] Update readme - passThrough mode, mention Java 8 is required for Selenium server --- README.md | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index cfdf0bc3b..5b331d349 100644 --- a/README.md +++ b/README.md @@ -39,10 +39,14 @@ Then install the library: All you need as the server for this client is the `selenium-server-standalone-#.jar` file provided here: http://selenium-release.storage.googleapis.com/index.html -Download and run that file, replacing # with the current server version. +Download and run that file, replacing # with the current server version. Keep in mind you must have Java 8+ installed to start this command. java -jar selenium-server-standalone-#.jar +When using Selenium server 3.5 and newer with some remote end clients (eg. Firefox with Geckodriver), you MUST disable so called "pass-through" mode, so that remote browser's protocol is translated to the protocol supported by php-webdriver (see [issue #469](https://github.com/facebook/php-webdriver/issues/469)): + + java -jar selenium-server-standalone-#.jar -enablePassThrough false + Then when you create a session, be sure to pass the url to where your server is running. ```php @@ -50,19 +54,23 @@ Then when you create a session, be sure to pass the url to where your server is $host = 'http://localhost:4444/wd/hub'; // this is the default ``` -* Launch Firefox: +##### Launch Firefox + +Make sure to have latest Firefox and [Geckodriver](https://github.com/mozilla/geckodriver/releases) installed. + +```php +$driver = RemoteWebDriver::create($host, DesiredCapabilities::firefox()); +``` - ```php - $driver = RemoteWebDriver::create($host, DesiredCapabilities::firefox()); - ``` +##### Launch Chrome -* Launch Chrome: +Make sure to have latest Chrome and [Chromedriver](https://sites.google.com/a/chromium.org/chromedriver/downloads) installed. - ```php - $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome()); - ``` +```php +$driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome()); +``` -You can also customize the desired capabilities: +##### You can also customize the desired capabilities ```php $desired_capabilities = DesiredCapabilities::firefox(); From 4c2710810148b8c266ced5aad55ac4ad70a36aa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 14 Oct 2017 03:50:51 +0200 Subject: [PATCH 363/784] Add functional tests for basic actions (click, double click etc.) --- lib/Interactions/WebDriverCompositeAction.php | 2 +- tests/functional/WebDriverActionsTest.php | 140 ++++++++++++++++++ tests/functional/web/events.html | 86 +++++++++++ tests/functional/web/index.html | 2 + 4 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 tests/functional/WebDriverActionsTest.php create mode 100644 tests/functional/web/events.html diff --git a/lib/Interactions/WebDriverCompositeAction.php b/lib/Interactions/WebDriverCompositeAction.php index 75a4837e1..d4ca94c5d 100644 --- a/lib/Interactions/WebDriverCompositeAction.php +++ b/lib/Interactions/WebDriverCompositeAction.php @@ -51,7 +51,7 @@ public function getNumberOfActions() } /** - * Perform the seqeunce of actions. + * Perform the sequence of actions. */ public function perform() { diff --git a/tests/functional/WebDriverActionsTest.php b/tests/functional/WebDriverActionsTest.php new file mode 100644 index 000000000..173f7794c --- /dev/null +++ b/tests/functional/WebDriverActionsTest.php @@ -0,0 +1,140 @@ +driver->get($this->getTestPageUrl('events.html')); + } + + /** + * @covers ::__construct + * @covers ::click + * @covers ::perform + */ + public function testShouldClickOnElement() + { + if ($this->desiredCapabilities->getBrowserName() === WebDriverBrowserType::HTMLUNIT) { + $this->markTestSkipped('Not supported by HtmlUnit browser'); + } + + $element = $this->driver->findElement(WebDriverBy::id('item-1')); + + $this->driver->action() + ->click($element) + ->perform(); + + $this->assertSame( + ['mouseover item-1', 'mousedown item-1', 'mouseup item-1', 'click item-1'], + $this->retrieveLoggedEvents() + ); + } + + /** + * @covers ::__construct + * @covers ::clickAndHold + * @covers ::release + * @covers ::perform + */ + public function testShouldClickAndHoldOnElementAndRelease() + { + if ($this->desiredCapabilities->getBrowserName() === WebDriverBrowserType::HTMLUNIT) { + $this->markTestSkipped('Not supported by HtmlUnit browser'); + } + + $element = $this->driver->findElement(WebDriverBy::id('item-1')); + + $this->driver->action() + ->clickAndHold($element) + ->release() + ->perform(); + + $this->assertSame( + ['mouseover item-1', 'mousedown item-1', 'mouseup item-1', 'click item-1'], + $this->retrieveLoggedEvents() + ); + } + + /** + * @covers ::__construct + * @covers ::contextClick + * @covers ::perform + */ + public function testShouldContextClickOnElement() + { + if ($this->desiredCapabilities->getBrowserName() === WebDriverBrowserType::HTMLUNIT) { + $this->markTestSkipped('Not supported by HtmlUnit browser'); + } + + if ($this->desiredCapabilities->getBrowserName() === WebDriverBrowserType::MICROSOFT_EDGE) { + $this->markTestSkipped('Getting stuck in EdgeDriver'); + } + + $element = $this->driver->findElement(WebDriverBy::id('item-2')); + + $this->driver->action() + ->contextClick($element) + ->perform(); + + $loggedEvents = $this->retrieveLoggedEvents(); + + $this->assertContains('mousedown item-2', $loggedEvents); + $this->assertContains('mouseup item-2', $loggedEvents); + $this->assertContains('contextmenu item-2', $loggedEvents); + } + + /** + * @covers ::__construct + * @covers ::doubleClick + * @covers ::perform + */ + public function testShouldDoubleClickOnElement() + { + if ($this->desiredCapabilities->getBrowserName() === WebDriverBrowserType::HTMLUNIT) { + $this->markTestSkipped('Not supported by HtmlUnit browser'); + } + + $element = $this->driver->findElement(WebDriverBy::id('item-3')); + + $this->driver->action() + ->doubleClick($element) + ->perform(); + + $this->assertSame( + ['mouseover item-3', 'mousedown item-3', 'mouseup item-3', 'click item-3', 'dblclick item-3'], + $this->retrieveLoggedEvents() + ); + } + + /** + * @return array + */ + private function retrieveLoggedEvents() + { + $logElement = $this->driver->findElement(WebDriverBy::id('log')); + + return explode("\n", $logElement->getText()); + } +} diff --git a/tests/functional/web/events.html b/tests/functional/web/events.html new file mode 100644 index 000000000..e915a89a0 --- /dev/null +++ b/tests/functional/web/events.html @@ -0,0 +1,86 @@ + + + + + Events + + + + +

      + +
    + +
      +
    • First item
    • +
    • Second item
    • +
    • Third item
    • +
    + +
    
    +
    +
    +
    +
    +
    diff --git a/tests/functional/web/index.html b/tests/functional/web/index.html
    index 1a92f255e..cf5b9c6c1 100644
    --- a/tests/functional/web/index.html
    +++ b/tests/functional/web/index.html
    @@ -18,6 +18,8 @@ 

    Welcome to the facebook/php-webdriver testing page.

    Slow loading page | Javascript alerts + | + Events

    Test by ID

    Test by Class

    From cae27962e3b1e4fae70c951769c00204bd927eca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 25 Oct 2017 23:05:52 +0200 Subject: [PATCH 364/784] Add tests for ChromeDriverService and ChromeDriver --- .travis.yml | 12 ++- .../Chrome/ChromeDriverServiceTest.php | 82 +++++++++++++++++++ tests/functional/Chrome/ChromeDriverTest.php | 60 ++++++++++++++ 3 files changed, 151 insertions(+), 3 deletions(-) create mode 100644 tests/functional/Chrome/ChromeDriverServiceTest.php create mode 100644 tests/functional/Chrome/ChromeDriverTest.php diff --git a/.travis.yml b/.travis.yml index 9b2b5894e..7484f1cfc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,13 @@ matrix: # Build with lowest possible dependencies - php: 7.1 - env: dependencies="--prefer-lowest" + env: DEPENDENCIES="--prefer-lowest" + + # Chrome on Travis build with lowest possible dependencies + - php: 7.1 + env: BROWSER_NAME="chrome" CHROME_HEADLESS="1" DEPENDENCIES="--prefer-lowest" + addons: + chrome: beta # Saucelabs builds - php: 7.1 @@ -77,11 +83,11 @@ before_install: - travis_retry composer self-update install: - - travis_retry composer update --no-interaction $dependencies + - travis_retry composer update --no-interaction $DEPENDENCIES before_script: - if [ "$BROWSER_NAME" = "chrome" ]; then mkdir chromedriver; wget -q -t 3 https://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip; unzip chromedriver_linux64 -d chromedriver; fi - - if [ "$BROWSER_NAME" = "chrome" ]; then export CHROMEDRIVER_PATH=./chromedriver/chromedriver; fi + - if [ "$BROWSER_NAME" = "chrome" ]; then export CHROMEDRIVER_PATH=$PWD/chromedriver/chromedriver; fi - sh -e /etc/init.d/xvfb start - if [ ! -f jar/selenium-server-standalone-3.4.0.jar ]; then wget -q -t 3 -P jar https://selenium-release.storage.googleapis.com/3.4/selenium-server-standalone-3.4.0.jar; fi - java -Dwebdriver.firefox.marionette=false -Dwebdriver.chrome.driver="$CHROMEDRIVER_PATH" -jar jar/selenium-server-standalone-3.4.0.jar -log ./logs/selenium.log & diff --git a/tests/functional/Chrome/ChromeDriverServiceTest.php b/tests/functional/Chrome/ChromeDriverServiceTest.php new file mode 100644 index 000000000..6f6073fda --- /dev/null +++ b/tests/functional/Chrome/ChromeDriverServiceTest.php @@ -0,0 +1,82 @@ +markTestSkipped('ChromeDriverServiceTest is run only when running against local chrome'); + } + } + + public function testShouldStartAndStopServiceCreatedUsingShortcutConstructor() + { + // The createDefaultService() method expect path to the executable to be present in the environment variable + putenv(ChromeDriverService::CHROME_DRIVER_EXE_PROPERTY . '=' . getenv('CHROMEDRIVER_PATH')); + + $driverService = ChromeDriverService::createDefaultService(); + + $this->assertSame('http://localhost:9515/', $driverService->getURL()); + + $this->assertInstanceOf(ChromeDriverService::class, $driverService->start()); + $this->assertTrue($driverService->isRunning()); + + $this->assertInstanceOf(ChromeDriverService::class, $driverService->start()); + + $this->assertInstanceOf(ChromeDriverService::class, $driverService->stop()); + $this->assertFalse($driverService->isRunning()); + + $this->assertInstanceOf(ChromeDriverService::class, $driverService->stop()); + } + + public function testShouldStartAndStopServiceCreatedUsingDefaultConstructor() + { + $driverService = new ChromeDriverService(getenv('CHROMEDRIVER_PATH'), 9515, ['--port=9515']); + + $this->assertSame('http://localhost:9515/', $driverService->getURL()); + + $driverService->start(); + $this->assertTrue($driverService->isRunning()); + + $driverService->stop(); + $this->assertFalse($driverService->isRunning()); + } + + public function testShouldThrowExceptionIfExecutableCannotBeFound() + { + putenv(ChromeDriverService::CHROME_DRIVER_EXE_PROPERTY . '=/not/existing'); + + $this->expectException(\Exception::class); + $this->expectExceptionMessage('\'/not/existing\' is not a file.'); + ChromeDriverService::createDefaultService(); + } + + public function testShouldThrowExceptionIfExecutableIsNotExecutable() + { + putenv(ChromeDriverService::CHROME_DRIVER_EXE_PROPERTY . '=' . __FILE__); + + $this->expectException(\Exception::class); + $this->expectExceptionMessage('is not executable'); + ChromeDriverService::createDefaultService(); + } +} diff --git a/tests/functional/Chrome/ChromeDriverTest.php b/tests/functional/Chrome/ChromeDriverTest.php new file mode 100644 index 000000000..f3567d9d7 --- /dev/null +++ b/tests/functional/Chrome/ChromeDriverTest.php @@ -0,0 +1,60 @@ +markTestSkipped('ChromeDriverServiceTest is run only when running against local chrome'); + } + } + + protected function tearDown() + { + if ($this->driver instanceof RemoteWebDriver && $this->driver->getCommandExecutor() !== null) { + $this->driver->quit(); + } + } + + public function testShouldStartChromeDriver() + { + // The createDefaultService() method expect path to the executable to be present in the environment variable + putenv(ChromeDriverService::CHROME_DRIVER_EXE_PROPERTY . '=' . getenv('CHROMEDRIVER_PATH')); + + $this->driver = ChromeDriver::start(); + + $this->assertInstanceOf(ChromeDriver::class, $this->driver); + $this->assertInstanceOf(DriverCommandExecutor::class, $this->driver->getCommandExecutor()); + + $this->driver->get('http://localhost:8000/'); + + $this->assertSame('http://localhost:8000/', $this->driver->getCurrentURL()); + + $this->driver->quit(); + } +} From 2b1d15359f88ea246d4a18f5dda4cbdeec48eb73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Thu, 26 Oct 2017 10:14:17 +0200 Subject: [PATCH 365/784] Bump sebastian/environment version to fix code-coverage in lowest dependencies build See https://github.com/sebastianbergmann/phpunit/issues/1976 --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8eff450f7..6203b6238 100644 --- a/composer.json +++ b/composer.json @@ -18,10 +18,11 @@ }, "require-dev": { "phpunit/phpunit": "^5.4", + "sebastian/environment": "^1.3.4 || ^2.0 || ^3.0", "friendsofphp/php-cs-fixer": "^2.0", "squizlabs/php_codesniffer": "^2.6", "php-mock/php-mock-phpunit": "^1.1", - "satooshi/php-coveralls": "^1.0", + "php-coveralls/php-coveralls": "^1.0.2", "symfony/var-dumper": "^3.3" }, "autoload": { From c85b872ba733b303ca363ecf27f87ae45a543b2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Thu, 26 Oct 2017 15:17:50 +0200 Subject: [PATCH 366/784] Bump guzzle version to fix coveralls in lowest dependencies build --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 6203b6238..6b7685be9 100644 --- a/composer.json +++ b/composer.json @@ -23,6 +23,7 @@ "squizlabs/php_codesniffer": "^2.6", "php-mock/php-mock-phpunit": "^1.1", "php-coveralls/php-coveralls": "^1.0.2", + "guzzle/guzzle": "^3.4.1", "symfony/var-dumper": "^3.3" }, "autoload": { From f6e0ad46640248112b636593d59db8032fa13c73 Mon Sep 17 00:00:00 2001 From: VolCh Date: Thu, 2 Nov 2017 19:07:27 +0200 Subject: [PATCH 367/784] Fix code style --- lib/WebDriverSelectInterface.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/WebDriverSelectInterface.php b/lib/WebDriverSelectInterface.php index bd4db90e4..030a783e9 100644 --- a/lib/WebDriverSelectInterface.php +++ b/lib/WebDriverSelectInterface.php @@ -1,4 +1,5 @@ Date: Fri, 3 Nov 2017 10:41:52 +0200 Subject: [PATCH 368/784] Fix code style --- lib/WebDriverDimension.php | 2 +- lib/WebDriverExpectedCondition.php | 4 ++-- lib/WebDriverPoint.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/WebDriverDimension.php b/lib/WebDriverDimension.php index 111a77821..308c1990f 100644 --- a/lib/WebDriverDimension.php +++ b/lib/WebDriverDimension.php @@ -65,7 +65,7 @@ public function getWidth() * @param WebDriverDimension $dimension The dimension to be compared with. * @return bool Whether the height and the width are the same as the instance. */ - public function equals(WebDriverDimension $dimension) + public function equals(self $dimension) { return $this->height === $dimension->getHeight() && $this->width === $dimension->getWidth(); } diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index 347a5d28a..bce6bfee4 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -453,7 +453,7 @@ function () use ($element) { * @return WebDriverExpectedCondition Condition returns the return value of the getApply() of the given * condition. */ - public static function refreshed(WebDriverExpectedCondition $condition) + public static function refreshed(self $condition) { return new static( function (WebDriver $driver) use ($condition) { @@ -558,7 +558,7 @@ function (WebDriver $driver) use ($expectedNumberOfWindows) { * @param WebDriverExpectedCondition $condition The condition to be negated. * @return mixed The negation of the result of the given condition. */ - public static function not(WebDriverExpectedCondition $condition) + public static function not(self $condition) { return new static( function (WebDriver $driver) use ($condition) { diff --git a/lib/WebDriverPoint.php b/lib/WebDriverPoint.php index e12977b22..4e2dbd211 100644 --- a/lib/WebDriverPoint.php +++ b/lib/WebDriverPoint.php @@ -85,7 +85,7 @@ public function moveBy($x_offset, $y_offset) * @param WebDriverPoint $point The point to be compared with. * @return bool Whether the x and y coordinates are the same as the instance. */ - public function equals(WebDriverPoint $point) + public function equals(self $point) { return $this->x === $point->getX() && $this->y === $point->getY(); From 4eee996a85b6fee638f5f95990c95f8832a18755 Mon Sep 17 00:00:00 2001 From: Quentin Headen Date: Tue, 7 Nov 2017 04:37:32 +0000 Subject: [PATCH 369/784] Add WebDriverExpectedCondition::visibilityOfAnyElementsLocated --- CHANGELOG.md | 3 ++ lib/WebDriverExpectedCondition.php | 29 ++++++++++++++++++ tests/unit/WebDriverExpectedConditionTest.php | 30 +++++++++++++++++++ 3 files changed, 62 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 182aeda87..c8b503b1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ### Changed - Drop PHP 5.5 support, the minimal required version of PHP is now PHP 5.6. +### Added +- Added a visibilityOfAnyElementsLocated method to WebDriverExpectedCondition. + ## 1.4.1 - 2017-04-28 ### Fixed - Do not throw notice `Constant CURLOPT_CONNECTTIMEOUT_MS already defined`. diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index bce6bfee4..433ee1a3a 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -193,6 +193,35 @@ function (WebDriver $driver) use ($by) { ); } + /** + * An expectation for checking than at least one element in an array of elements is present on the + * DOM of a page and visible. + * Visibility means that the element is not only displayed but also has a height and width that is greater than 0. + * + * @param WebDriverBy $by The located used to find the element. + * @return WebDriverExpectedCondition Condition returns the elements that are located and visible. + */ + public static function visibilityOfAnyElementLocated(WebDriverBy $by) + { + return new static( + function (WebDriver $driver) use ($by) { + $elements = $driver->findElements($by); + $visibleElements = []; + + foreach ($elements as $element) { + try { + if ($element->isDisplayed()) { + $visibleElements[] = $element; + } + } catch (StateElementReferenceException $e) { + } + } + + return count($visibleElements) > 0 ? $visibleElements : null; + } + ); + } + /** * An expectation for checking that an element, known to be present on the DOM of a page, is visible. * Visibility means that the element is not only displayed but also has a height and width that is greater than 0. diff --git a/tests/unit/WebDriverExpectedConditionTest.php b/tests/unit/WebDriverExpectedConditionTest.php index e786167a8..603829c02 100644 --- a/tests/unit/WebDriverExpectedConditionTest.php +++ b/tests/unit/WebDriverExpectedConditionTest.php @@ -185,6 +185,36 @@ public function testShouldDetectVisibilityOfElementLocatedCondition() $this->assertSame($element, $this->wait->until($condition)); } + public function testShouldDetectVisibilityOfAnyElementLocated() + { + $elementList = [ + $this->createRemoteWebElementMock(), + $this->createRemoteWebElementMock(), + $this->createRemoteWebElementMock(), + ]; + + $elementList[0]->expects($this->once()) + ->method('isDisplayed') + ->willReturn(false); + + $elementList[1]->expects($this->once()) + ->method('isDisplayed') + ->willReturn(true); + + $elementList[2]->expects($this->once()) + ->method('isDisplayed') + ->willReturn(true); + + $this->driverMock->expects($this->once()) + ->method('findElements') + ->with($this->isInstanceOf(WebDriverBy::class)) + ->willReturn($elementList); + + $condition = WebDriverExpectedCondition::visibilityOfAnyElementLocated(WebDriverBy::cssSelector('.foo')); + + $this->assertSame([$elementList[1], $elementList[2]], $this->wait->until($condition)); + } + public function testShouldDetectInvisibilityOfElementLocatedConditionOnNoSuchElementException() { $element = $this->createRemoteWebElementMock(); From 017b8d7daee5c070235b8c74d335180f2bd15aa2 Mon Sep 17 00:00:00 2001 From: Gabriel Caruso Date: Sat, 4 Nov 2017 17:27:25 -0200 Subject: [PATCH 370/784] Use namespaces for PHPUnit forward compatiblitiy --- composer.json | 2 +- tests/functional/Chrome/ChromeDriverServiceTest.php | 4 +++- tests/functional/Chrome/ChromeDriverTest.php | 3 ++- tests/functional/ReportSauceLabsStatusListener.php | 3 ++- tests/functional/WebDriverTestCase.php | 3 ++- tests/unit/CookieTest.php | 4 +++- tests/unit/Exception/WebDriverExceptionTest.php | 4 +++- .../Internal/WebDriverButtonReleaseActionTest.php | 3 ++- tests/unit/Interactions/Internal/WebDriverClickActionTest.php | 3 ++- .../Interactions/Internal/WebDriverClickAndHoldActionTest.php | 3 ++- .../Interactions/Internal/WebDriverContextClickActionTest.php | 3 ++- tests/unit/Interactions/Internal/WebDriverCoordinatesTest.php | 4 +++- .../Interactions/Internal/WebDriverDoubleClickActionTest.php | 3 ++- .../unit/Interactions/Internal/WebDriverKeyDownActionTest.php | 3 ++- tests/unit/Interactions/Internal/WebDriverKeyUpActionTest.php | 3 ++- .../Interactions/Internal/WebDriverMouseMoveActionTest.php | 3 ++- .../Internal/WebDriverMouseToOffsetActionTest.php | 3 ++- .../Interactions/Internal/WebDriverSendKeysActionTest.php | 3 ++- tests/unit/Remote/DesiredCapabilitiesTest.php | 3 ++- tests/unit/Remote/HttpCommandExecutorTest.php | 3 ++- tests/unit/Remote/RemoteWebDriverTest.php | 3 ++- tests/unit/Remote/RemoteWebElementTest.php | 4 +++- tests/unit/Remote/WebDriverCommandTest.php | 4 +++- tests/unit/Support/XPathEscaperTest.php | 4 +++- tests/unit/WebDriverExpectedConditionTest.php | 3 ++- tests/unit/WebDriverKeysTest.php | 4 +++- tests/unit/WebDriverOptionsTest.php | 3 ++- 27 files changed, 61 insertions(+), 27 deletions(-) diff --git a/composer.json b/composer.json index 6b7685be9..94b7f8a36 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ "ext-zip": "*" }, "require-dev": { - "phpunit/phpunit": "^5.4", + "phpunit/phpunit": "^5.7", "sebastian/environment": "^1.3.4 || ^2.0 || ^3.0", "friendsofphp/php-cs-fixer": "^2.0", "squizlabs/php_codesniffer": "^2.6", diff --git a/tests/functional/Chrome/ChromeDriverServiceTest.php b/tests/functional/Chrome/ChromeDriverServiceTest.php index 6f6073fda..bc1a1b92f 100644 --- a/tests/functional/Chrome/ChromeDriverServiceTest.php +++ b/tests/functional/Chrome/ChromeDriverServiceTest.php @@ -15,12 +15,14 @@ namespace Facebook\WebDriver\Chrome; +use PHPUnit\Framework\TestCase; + /** * @group exclude-saucelabs * @covers Facebook\WebDriver\Chrome\ChromeDriverService * @covers Facebook\WebDriver\Remote\Service\DriverService */ -class ChromeDriverServiceTest extends \PHPUnit_Framework_TestCase +class ChromeDriverServiceTest extends TestCase { protected function setUp() { diff --git a/tests/functional/Chrome/ChromeDriverTest.php b/tests/functional/Chrome/ChromeDriverTest.php index f3567d9d7..476033839 100644 --- a/tests/functional/Chrome/ChromeDriverTest.php +++ b/tests/functional/Chrome/ChromeDriverTest.php @@ -17,12 +17,13 @@ use Facebook\WebDriver\Remote\RemoteWebDriver; use Facebook\WebDriver\Remote\Service\DriverCommandExecutor; +use PHPUnit\Framework\TestCase; /** * @group exclude-saucelabs * @covers Facebook\WebDriver\Chrome\ChromeDriver */ -class ChromeDriverTest extends \PHPUnit_Framework_TestCase +class ChromeDriverTest extends TestCase { /** @var ChromeDriver */ protected $driver; diff --git a/tests/functional/ReportSauceLabsStatusListener.php b/tests/functional/ReportSauceLabsStatusListener.php index b88b1cdf7..f2a3c9f7d 100644 --- a/tests/functional/ReportSauceLabsStatusListener.php +++ b/tests/functional/ReportSauceLabsStatusListener.php @@ -16,8 +16,9 @@ namespace Facebook\WebDriver; use Facebook\WebDriver\Remote\RemoteWebDriver; +use PHPUnit\Framework\BaseTestListener; -class ReportSauceLabsStatusListener extends \PHPUnit_Framework_BaseTestListener +class ReportSauceLabsStatusListener extends BaseTestListener { public function endTest(\PHPUnit_Framework_Test $test, $time) { diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index 77a98f884..4abaf7c03 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -20,11 +20,12 @@ use Facebook\WebDriver\Remote\DesiredCapabilities; use Facebook\WebDriver\Remote\RemoteWebDriver; use Facebook\WebDriver\Remote\WebDriverBrowserType; +use PHPUnit\Framework\TestCase; /** * The base class for test cases. */ -class WebDriverTestCase extends \PHPUnit_Framework_TestCase +class WebDriverTestCase extends TestCase { /** @var RemoteWebDriver $driver */ public $driver; diff --git a/tests/unit/CookieTest.php b/tests/unit/CookieTest.php index ccf2a1e6f..5fc62fb6c 100644 --- a/tests/unit/CookieTest.php +++ b/tests/unit/CookieTest.php @@ -15,10 +15,12 @@ namespace Facebook\WebDriver; +use PHPUnit\Framework\TestCase; + /** * @covers Facebook\WebDriver\Cookie */ -class CookieTest extends \PHPUnit_Framework_TestCase +class CookieTest extends TestCase { public function testShouldSetAllProperties() { diff --git a/tests/unit/Exception/WebDriverExceptionTest.php b/tests/unit/Exception/WebDriverExceptionTest.php index 1dfd94fac..f9aadd207 100644 --- a/tests/unit/Exception/WebDriverExceptionTest.php +++ b/tests/unit/Exception/WebDriverExceptionTest.php @@ -15,7 +15,9 @@ namespace Facebook\WebDriver\Exception; -class WebDriverExceptionTest extends \PHPUnit_Framework_TestCase +use PHPUnit\Framework\TestCase; + +class WebDriverExceptionTest extends TestCase { public function testShouldStoreResultsOnInstantiation() { diff --git a/tests/unit/Interactions/Internal/WebDriverButtonReleaseActionTest.php b/tests/unit/Interactions/Internal/WebDriverButtonReleaseActionTest.php index f2bb1b647..db8574a0b 100644 --- a/tests/unit/Interactions/Internal/WebDriverButtonReleaseActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverButtonReleaseActionTest.php @@ -17,8 +17,9 @@ use Facebook\WebDriver\Internal\WebDriverLocatable; use Facebook\WebDriver\WebDriverMouse; +use PHPUnit\Framework\TestCase; -class WebDriverButtonReleaseActionTest extends \PHPUnit_Framework_TestCase +class WebDriverButtonReleaseActionTest extends TestCase { /** @var WebDriverButtonReleaseAction */ private $webDriverButtonReleaseAction; diff --git a/tests/unit/Interactions/Internal/WebDriverClickActionTest.php b/tests/unit/Interactions/Internal/WebDriverClickActionTest.php index fdb868141..8041d7ae7 100644 --- a/tests/unit/Interactions/Internal/WebDriverClickActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverClickActionTest.php @@ -17,8 +17,9 @@ use Facebook\WebDriver\Internal\WebDriverLocatable; use Facebook\WebDriver\WebDriverMouse; +use PHPUnit\Framework\TestCase; -class WebDriverClickActionTest extends \PHPUnit_Framework_TestCase +class WebDriverClickActionTest extends TestCase { /** @var WebDriverClickAction */ private $webDriverClickAction; diff --git a/tests/unit/Interactions/Internal/WebDriverClickAndHoldActionTest.php b/tests/unit/Interactions/Internal/WebDriverClickAndHoldActionTest.php index eb3f4bc6f..ebe933f8c 100644 --- a/tests/unit/Interactions/Internal/WebDriverClickAndHoldActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverClickAndHoldActionTest.php @@ -17,8 +17,9 @@ use Facebook\WebDriver\Internal\WebDriverLocatable; use Facebook\WebDriver\WebDriverMouse; +use PHPUnit\Framework\TestCase; -class WebDriverClickAndHoldActionTest extends \PHPUnit_Framework_TestCase +class WebDriverClickAndHoldActionTest extends TestCase { /** @var WebDriverClickAndHoldAction */ private $webDriverClickAndHoldAction; diff --git a/tests/unit/Interactions/Internal/WebDriverContextClickActionTest.php b/tests/unit/Interactions/Internal/WebDriverContextClickActionTest.php index e9162f239..67ca63e4c 100644 --- a/tests/unit/Interactions/Internal/WebDriverContextClickActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverContextClickActionTest.php @@ -17,8 +17,9 @@ use Facebook\WebDriver\Internal\WebDriverLocatable; use Facebook\WebDriver\WebDriverMouse; +use PHPUnit\Framework\TestCase; -class WebDriverContextClickActionTest extends \PHPUnit_Framework_TestCase +class WebDriverContextClickActionTest extends TestCase { /** @var WebDriverContextClickAction */ private $webDriverContextClickAction; diff --git a/tests/unit/Interactions/Internal/WebDriverCoordinatesTest.php b/tests/unit/Interactions/Internal/WebDriverCoordinatesTest.php index d782edf8c..209daa63f 100644 --- a/tests/unit/Interactions/Internal/WebDriverCoordinatesTest.php +++ b/tests/unit/Interactions/Internal/WebDriverCoordinatesTest.php @@ -15,7 +15,9 @@ namespace Facebook\WebDriver\Interactions\Internal; -class WebDriverCoordinatesTest extends \PHPUnit_Framework_TestCase +use PHPUnit\Framework\TestCase; + +class WebDriverCoordinatesTest extends TestCase { public function testConstruct() { diff --git a/tests/unit/Interactions/Internal/WebDriverDoubleClickActionTest.php b/tests/unit/Interactions/Internal/WebDriverDoubleClickActionTest.php index acd74550f..86710d330 100644 --- a/tests/unit/Interactions/Internal/WebDriverDoubleClickActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverDoubleClickActionTest.php @@ -17,8 +17,9 @@ use Facebook\WebDriver\Internal\WebDriverLocatable; use Facebook\WebDriver\WebDriverMouse; +use PHPUnit\Framework\TestCase; -class WebDriverDoubleClickActionTest extends \PHPUnit_Framework_TestCase +class WebDriverDoubleClickActionTest extends TestCase { /** @var WebDriverDoubleClickAction */ private $webDriverDoubleClickAction; diff --git a/tests/unit/Interactions/Internal/WebDriverKeyDownActionTest.php b/tests/unit/Interactions/Internal/WebDriverKeyDownActionTest.php index 267b58b3e..a03791fd9 100644 --- a/tests/unit/Interactions/Internal/WebDriverKeyDownActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverKeyDownActionTest.php @@ -18,8 +18,9 @@ use Facebook\WebDriver\Internal\WebDriverLocatable; use Facebook\WebDriver\WebDriverKeyboard; use Facebook\WebDriver\WebDriverMouse; +use PHPUnit\Framework\TestCase; -class WebDriverKeyDownActionTest extends \PHPUnit_Framework_TestCase +class WebDriverKeyDownActionTest extends TestCase { /** @var WebDriverKeyDownAction */ private $webDriverKeyDownAction; diff --git a/tests/unit/Interactions/Internal/WebDriverKeyUpActionTest.php b/tests/unit/Interactions/Internal/WebDriverKeyUpActionTest.php index 970a35b0f..7ebc17ac0 100644 --- a/tests/unit/Interactions/Internal/WebDriverKeyUpActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverKeyUpActionTest.php @@ -18,8 +18,9 @@ use Facebook\WebDriver\Internal\WebDriverLocatable; use Facebook\WebDriver\WebDriverKeyboard; use Facebook\WebDriver\WebDriverMouse; +use PHPUnit\Framework\TestCase; -class WebDriverKeyUpActionTest extends \PHPUnit_Framework_TestCase +class WebDriverKeyUpActionTest extends TestCase { /** @var WebDriverKeyUpAction */ private $webDriverKeyUpAction; diff --git a/tests/unit/Interactions/Internal/WebDriverMouseMoveActionTest.php b/tests/unit/Interactions/Internal/WebDriverMouseMoveActionTest.php index 565530ad8..584231f9d 100644 --- a/tests/unit/Interactions/Internal/WebDriverMouseMoveActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverMouseMoveActionTest.php @@ -17,8 +17,9 @@ use Facebook\WebDriver\Internal\WebDriverLocatable; use Facebook\WebDriver\WebDriverMouse; +use PHPUnit\Framework\TestCase; -class WebDriverMouseMoveActionTest extends \PHPUnit_Framework_TestCase +class WebDriverMouseMoveActionTest extends TestCase { /** @var WebDriverMouseMoveAction */ private $webDriverMouseMoveAction; diff --git a/tests/unit/Interactions/Internal/WebDriverMouseToOffsetActionTest.php b/tests/unit/Interactions/Internal/WebDriverMouseToOffsetActionTest.php index d2d5286a1..a055c746d 100644 --- a/tests/unit/Interactions/Internal/WebDriverMouseToOffsetActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverMouseToOffsetActionTest.php @@ -17,8 +17,9 @@ use Facebook\WebDriver\Internal\WebDriverLocatable; use Facebook\WebDriver\WebDriverMouse; +use PHPUnit\Framework\TestCase; -class WebDriverMouseToOffsetActionTest extends \PHPUnit_Framework_TestCase +class WebDriverMouseToOffsetActionTest extends TestCase { /** * @type WebDriverMoveToOffsetAction diff --git a/tests/unit/Interactions/Internal/WebDriverSendKeysActionTest.php b/tests/unit/Interactions/Internal/WebDriverSendKeysActionTest.php index 9b06b3df7..22cb47e9d 100644 --- a/tests/unit/Interactions/Internal/WebDriverSendKeysActionTest.php +++ b/tests/unit/Interactions/Internal/WebDriverSendKeysActionTest.php @@ -18,8 +18,9 @@ use Facebook\WebDriver\Internal\WebDriverLocatable; use Facebook\WebDriver\WebDriverKeyboard; use Facebook\WebDriver\WebDriverMouse; +use PHPUnit\Framework\TestCase; -class WebDriverSendKeysActionTest extends \PHPUnit_Framework_TestCase +class WebDriverSendKeysActionTest extends TestCase { /** @var WebDriverSendKeysAction */ private $webDriverSendKeysAction; diff --git a/tests/unit/Remote/DesiredCapabilitiesTest.php b/tests/unit/Remote/DesiredCapabilitiesTest.php index dacdcd139..559a21f7f 100644 --- a/tests/unit/Remote/DesiredCapabilitiesTest.php +++ b/tests/unit/Remote/DesiredCapabilitiesTest.php @@ -19,8 +19,9 @@ use Facebook\WebDriver\Firefox\FirefoxPreferences; use Facebook\WebDriver\Firefox\FirefoxProfile; use Facebook\WebDriver\WebDriverPlatform; +use PHPUnit\Framework\TestCase; -class DesiredCapabilitiesTest extends \PHPUnit_Framework_TestCase +class DesiredCapabilitiesTest extends TestCase { public function testShouldInstantiateWithCapabilitiesGivenInConstructor() { diff --git a/tests/unit/Remote/HttpCommandExecutorTest.php b/tests/unit/Remote/HttpCommandExecutorTest.php index 63d004e6b..a3810e731 100644 --- a/tests/unit/Remote/HttpCommandExecutorTest.php +++ b/tests/unit/Remote/HttpCommandExecutorTest.php @@ -16,8 +16,9 @@ namespace Facebook\WebDriver\Remote; use phpmock\phpunit\PHPMock; +use PHPUnit\Framework\TestCase; -class HttpCommandExecutorTest extends \PHPUnit_Framework_TestCase +class HttpCommandExecutorTest extends TestCase { use PHPMock; diff --git a/tests/unit/Remote/RemoteWebDriverTest.php b/tests/unit/Remote/RemoteWebDriverTest.php index 48b149f84..c8fee7e5d 100644 --- a/tests/unit/Remote/RemoteWebDriverTest.php +++ b/tests/unit/Remote/RemoteWebDriverTest.php @@ -19,13 +19,14 @@ use Facebook\WebDriver\WebDriverNavigation; use Facebook\WebDriver\WebDriverOptions; use Facebook\WebDriver\WebDriverWait; +use PHPUnit\Framework\TestCase; /** * Unit part of RemoteWebDriver tests. Ie. tests for behavior which do not interact with the real remote server. * * @coversDefaultClass Facebook\WebDriver\Remote\RemoteWebDriver */ -class RemoteWebDriverTest extends \PHPUnit_Framework_TestCase +class RemoteWebDriverTest extends TestCase { /** @var RemoteWebDriver */ private $driver; diff --git a/tests/unit/Remote/RemoteWebElementTest.php b/tests/unit/Remote/RemoteWebElementTest.php index 45c057751..80bc92931 100644 --- a/tests/unit/Remote/RemoteWebElementTest.php +++ b/tests/unit/Remote/RemoteWebElementTest.php @@ -15,12 +15,14 @@ namespace Facebook\WebDriver\Remote; +use PHPUnit\Framework\TestCase; + /** * Unit part of RemoteWebDriver tests. Ie. tests for behavior which do not interact with the real remote server. * * @coversDefaultClass Facebook\WebDriver\Remote\RemoteWebElement */ -class RemoteWebElementTest extends \PHPUnit_Framework_TestCase +class RemoteWebElementTest extends TestCase { /** * @covers ::__construct diff --git a/tests/unit/Remote/WebDriverCommandTest.php b/tests/unit/Remote/WebDriverCommandTest.php index 9993c6ce5..2e1a0ad9f 100644 --- a/tests/unit/Remote/WebDriverCommandTest.php +++ b/tests/unit/Remote/WebDriverCommandTest.php @@ -15,7 +15,9 @@ namespace Facebook\WebDriver\Remote; -class WebDriverCommandTest extends \PHPUnit_Framework_TestCase +use PHPUnit\Framework\TestCase; + +class WebDriverCommandTest extends TestCase { public function testShouldSetOptionsUsingConstructor() { diff --git a/tests/unit/Support/XPathEscaperTest.php b/tests/unit/Support/XPathEscaperTest.php index 21ac4aea0..96853ed4f 100644 --- a/tests/unit/Support/XPathEscaperTest.php +++ b/tests/unit/Support/XPathEscaperTest.php @@ -15,7 +15,9 @@ namespace Facebook\WebDriver\Support; -class XPathEscaperTest extends \PHPUnit_Framework_TestCase +use PHPUnit\Framework\TestCase; + +class XPathEscaperTest extends TestCase { /** * @dataProvider xpathProvider diff --git a/tests/unit/WebDriverExpectedConditionTest.php b/tests/unit/WebDriverExpectedConditionTest.php index e786167a8..1860e4585 100644 --- a/tests/unit/WebDriverExpectedConditionTest.php +++ b/tests/unit/WebDriverExpectedConditionTest.php @@ -20,11 +20,12 @@ use Facebook\WebDriver\Remote\RemoteExecuteMethod; use Facebook\WebDriver\Remote\RemoteWebDriver; use Facebook\WebDriver\Remote\RemoteWebElement; +use PHPUnit\Framework\TestCase; /** * @covers Facebook\WebDriver\WebDriverExpectedCondition */ -class WebDriverExpectedConditionTest extends \PHPUnit_Framework_TestCase +class WebDriverExpectedConditionTest extends TestCase { /** @var RemoteWebDriver|\PHPUnit_Framework_MockObject_MockObject */ private $driverMock; diff --git a/tests/unit/WebDriverKeysTest.php b/tests/unit/WebDriverKeysTest.php index 9a205c7de..a309402b8 100644 --- a/tests/unit/WebDriverKeysTest.php +++ b/tests/unit/WebDriverKeysTest.php @@ -15,10 +15,12 @@ namespace Facebook\WebDriver; +use PHPUnit\Framework\TestCase; + /** * @covers Facebook\WebDriver\WebDriverKeys */ -class WebDriverKeysTest extends \PHPUnit_Framework_TestCase +class WebDriverKeysTest extends TestCase { /** * @dataProvider provideKeys diff --git a/tests/unit/WebDriverOptionsTest.php b/tests/unit/WebDriverOptionsTest.php index 8bc47b96f..07c721c48 100644 --- a/tests/unit/WebDriverOptionsTest.php +++ b/tests/unit/WebDriverOptionsTest.php @@ -17,11 +17,12 @@ use Facebook\WebDriver\Remote\DriverCommand; use Facebook\WebDriver\Remote\ExecuteMethod; +use PHPUnit\Framework\TestCase; /** * @covers Facebook\WebDriver\WebDriverOptions */ -class WebDriverOptionsTest extends \PHPUnit_Framework_TestCase +class WebDriverOptionsTest extends TestCase { /** @var ExecuteMethod|\PHPUnit_Framework_MockObject_MockObject */ private $executor; From d3af34e78f8ca4edc7cff3dbcfbe8c0219d43c97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 8 Nov 2017 13:45:10 +0100 Subject: [PATCH 371/784] Avoid useless test warning on PHPUnit 6 --- tests/unit/CookieTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/unit/CookieTest.php b/tests/unit/CookieTest.php index 5fc62fb6c..43215acb8 100644 --- a/tests/unit/CookieTest.php +++ b/tests/unit/CookieTest.php @@ -145,7 +145,7 @@ public function testShouldBeCreatableFromAnArrayWithAllValues() * @param string $domain * @param string $expectedMessage */ - public function testShouldValidateCookie($name, $value, $domain, $expectedMessage) + public function testShouldValidateCookieOnConstruction($name, $value, $domain, $expectedMessage) { if ($expectedMessage) { $this->expectException(\InvalidArgumentException::class); @@ -156,6 +156,8 @@ public function testShouldValidateCookie($name, $value, $domain, $expectedMessag if ($domain !== null) { $cookie->setDomain($domain); } + + $this->assertInstanceOf(Cookie::class, $cookie); } /** From 1bb077b2fd7273569f63293bf623406d8a6c3cbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Re=C3=A9nse?= Date: Tue, 6 Jun 2017 19:19:18 +0200 Subject: [PATCH 372/784] Fix typo in isJavascriptEnabled --- lib/Remote/DesiredCapabilities.php | 2 +- tests/unit/Remote/DesiredCapabilitiesTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Remote/DesiredCapabilities.php b/lib/Remote/DesiredCapabilities.php index 3990343af..940fcf98c 100644 --- a/lib/Remote/DesiredCapabilities.php +++ b/lib/Remote/DesiredCapabilities.php @@ -145,7 +145,7 @@ public function setJavascriptEnabled($enabled) $browser = $this->getBrowserName(); if ($browser && $browser !== WebDriverBrowserType::HTMLUNIT) { throw new Exception( - 'isJavascriptEnable() is a htmlunit-only option. ' . + 'isJavascriptEnabled() is a htmlunit-only option. ' . 'See https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities#read-write-capabilities.' ); } diff --git a/tests/unit/Remote/DesiredCapabilitiesTest.php b/tests/unit/Remote/DesiredCapabilitiesTest.php index dacdcd139..1edea2522 100644 --- a/tests/unit/Remote/DesiredCapabilitiesTest.php +++ b/tests/unit/Remote/DesiredCapabilitiesTest.php @@ -63,7 +63,7 @@ public function testShouldProvideAccessToCapabilitiesUsingSettersAndGetters() /** * @expectedException \Exception - * @expectedExceptionMessage isJavascriptEnable() is a htmlunit-only option + * @expectedExceptionMessage isJavascriptEnabled() is a htmlunit-only option */ public function testShouldNotAllowToDisableJavascriptForNonHtmlUnitBrowser() { From b643bf3a465ca8eec35c781e8ac8c40d003e3151 Mon Sep 17 00:00:00 2001 From: VolCh Date: Sat, 4 Nov 2017 15:52:32 +0200 Subject: [PATCH 373/784] Extract DriverService::createProcess() --- lib/Remote/Service/DriverService.php | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/lib/Remote/Service/DriverService.php b/lib/Remote/Service/DriverService.php index c15ef94f9..e3fea5823 100644 --- a/lib/Remote/Service/DriverService.php +++ b/lib/Remote/Service/DriverService.php @@ -81,12 +81,7 @@ public function start() return $this; } - $processBuilder = (new ProcessBuilder()) - ->setPrefix($this->executable) - ->setArguments($this->args) - ->addEnvironmentVariables($this->environment); - - $this->process = $processBuilder->getProcess(); + $this->process = $this->createProcess(); $this->process->start(); $checker = new URLChecker(); @@ -144,4 +139,17 @@ protected static function checkExecutable($executable) return $executable; } + + /** + * @return Process + */ + private function createProcess() + { + $processBuilder = (new ProcessBuilder()) + ->setPrefix($this->executable) + ->setArguments($this->args) + ->addEnvironmentVariables($this->environment); + + return $processBuilder->getProcess(); + } } From 3a2ecdf0e4a10b9e4c91e3aece999fbf6ccb1776 Mon Sep 17 00:00:00 2001 From: VolCh Date: Sat, 4 Nov 2017 16:13:40 +0200 Subject: [PATCH 374/784] Enable beta stability for project development only --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 94b7f8a36..8392c5738 100644 --- a/composer.json +++ b/composer.json @@ -10,6 +10,7 @@ "forum": "https://www.facebook.com/groups/phpwebdriver/", "source": "https://github.com/facebook/php-webdriver" }, + "minimum-stability": "beta", "require": { "php": "^5.6 || ~7.0", "symfony/process": "^2.8 || ^3.1", From a19477c5a1177ef5da36884b7144232ba5a65d4d Mon Sep 17 00:00:00 2001 From: VolCh Date: Sat, 4 Nov 2017 16:16:11 +0200 Subject: [PATCH 375/784] Allow Symfony 4 and avoid deprecation warning with Symfony 3.4 --- composer.json | 4 ++-- lib/Remote/Service/DriverService.php | 19 ++++++++++++++----- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 8392c5738..069cb6df5 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ "minimum-stability": "beta", "require": { "php": "^5.6 || ~7.0", - "symfony/process": "^2.8 || ^3.1", + "symfony/process": "^2.8 || ^3.1 || ^4.0", "ext-curl": "*", "ext-zip": "*" }, @@ -25,7 +25,7 @@ "php-mock/php-mock-phpunit": "^1.1", "php-coveralls/php-coveralls": "^1.0.2", "guzzle/guzzle": "^3.4.1", - "symfony/var-dumper": "^3.3" + "symfony/var-dumper": "^3.3 || ^4.0" }, "autoload": { "psr-4": { diff --git a/lib/Remote/Service/DriverService.php b/lib/Remote/Service/DriverService.php index e3fea5823..eabf24e7a 100644 --- a/lib/Remote/Service/DriverService.php +++ b/lib/Remote/Service/DriverService.php @@ -145,11 +145,20 @@ protected static function checkExecutable($executable) */ private function createProcess() { - $processBuilder = (new ProcessBuilder()) - ->setPrefix($this->executable) - ->setArguments($this->args) - ->addEnvironmentVariables($this->environment); + // BC: ProcessBuilder deprecated since Symfony 3.4 and removed in Symfony 4.0. + if (class_exists(ProcessBuilder::class) + && false === mb_strpos('@deprecated', (new \ReflectionClass(ProcessBuilder::class))->getDocComment()) + ) { + $processBuilder = (new ProcessBuilder()) + ->setPrefix($this->executable) + ->setArguments($this->args) + ->addEnvironmentVariables($this->environment); + + return $processBuilder->getProcess(); + } + // Safe to use since Symfony 3.3 + $commandLine = array_merge([$this->executable], $this->args); - return $processBuilder->getProcess(); + return new Process($commandLine, null, $this->environment); } } From 8d08a8d34ab20e3663ac2c1ff88e30edbc25a287 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 15 Nov 2017 02:04:18 +0100 Subject: [PATCH 376/784] Update changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8b503b1d..0d71ee44d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,10 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased ### Changed - Drop PHP 5.5 support, the minimal required version of PHP is now PHP 5.6. +- Allow installation of Symfony 4 components. ### Added -- Added a visibilityOfAnyElementsLocated method to WebDriverExpectedCondition. +- Add a `visibilityOfAnyElementsLocated()` method to `WebDriverExpectedCondition`. ## 1.4.1 - 2017-04-28 ### Fixed From 86b5ca2f67173c9d34340845dd690149c886a605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 15 Nov 2017 12:08:09 +0100 Subject: [PATCH 377/784] Release version 1.5.0 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d71ee44d..3f42c31ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased + +## 1.5.0 - 2017-11-15 ### Changed - Drop PHP 5.5 support, the minimal required version of PHP is now PHP 5.6. - Allow installation of Symfony 4 components. From d9623ed86e1f4b88609ff0dd054b62682c2419e4 Mon Sep 17 00:00:00 2001 From: Flarnie Marchan Date: Sun, 26 Nov 2017 16:25:29 -0800 Subject: [PATCH 378/784] Link to COC from `CONTRIBUTING.md` We are about to add a `CODE_OF_CONDUCT.md` doc and it makes sense to surface it here. --- CONTRIBUTING.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6c59bbe84..d7b93736c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,6 +5,9 @@ We love to have your help to make php-webdriver better! Feel free to open an [issue](https://github.com/facebook/php-webdriver/issues) if you run into any problem, or send a pull request (see bellow) with your contribution. +## Code of Conduct +The code of conduct is described in [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) + ## Workflow when contributing a patch 1. Fork the project on GitHub From 90c7dcbff5a545d63520c83ab490d6e24ad9ba3a Mon Sep 17 00:00:00 2001 From: Flarnie Marchan Date: Sun, 26 Nov 2017 16:27:33 -0800 Subject: [PATCH 379/784] Add `CODE_OF_CONDUCT.md` In the past Facebook didn't promote including a Code of Conduct when creating new projects, and many projects skipped this important document. Let's fix it. :) **why make this change?:** Facebook Open Source provides a Code of Conduct statement for all projects to follow, to promote a welcoming and safe open source community. Exposing the COC via a separate markdown file is a standard being promoted by Github via the Community Profile in order to meet their Open Source Guide's recommended community standards. As you can see, adding this file will improve [the php-webdriver community profile](https://github.com/facebook/php-webdriver/community) checklist and increase the visibility of our COC. **test plan:** Viewing it on my branch - (Flarnie will insert screenshots) **issue:** internal task t23481323 --- CODE_OF_CONDUCT.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..0a45f9bd5 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,3 @@ +# Code of Conduct + +Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please [read the full text](https://code.facebook.com/codeofconduct) so that you can understand what actions will and will not be tolerated. From 52052a7e21075653de8a8b449097d16461ce5bc2 Mon Sep 17 00:00:00 2001 From: Gabriel Caruso Date: Thu, 30 Nov 2017 19:13:05 -0200 Subject: [PATCH 380/784] Test against PHP 7.2 --- .travis.yml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7484f1cfc..81266034f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ php: - 5.6 - 7.0 - 7.1 + - 7.2 env: global: @@ -16,29 +17,29 @@ env: matrix: include: # Add build to run tests against Firefox inside Travis environment - - php: 7.1 + - php: 7.2 env: BROWSER_NAME="firefox" addons: firefox: "45.8.0esr" # Add build to run tests against Chrome inside Travis environment - - php: 7.1 + - php: 7.2 env: BROWSER_NAME="chrome" CHROME_HEADLESS="1" addons: chrome: beta # Build with lowest possible dependencies - - php: 7.1 + - php: 7.2 env: DEPENDENCIES="--prefer-lowest" # Chrome on Travis build with lowest possible dependencies - - php: 7.1 + - php: 7.2 env: BROWSER_NAME="chrome" CHROME_HEADLESS="1" DEPENDENCIES="--prefer-lowest" addons: chrome: beta # Saucelabs builds - - php: 7.1 + - php: 7.2 env: SAUCELABS=1 BROWSER_NAME="firefox" VERSION="47.0" PLATFORM="Windows 10" before_script: - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & @@ -47,7 +48,7 @@ matrix: sauce_connect: true jwt: secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= - - php: 7.1 + - php: 7.2 env: SAUCELABS=1 BROWSER_NAME="chrome" VERSION="latest" PLATFORM="Windows 10" before_script: - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & @@ -56,7 +57,7 @@ matrix: sauce_connect: true jwt: secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= - - php: 7.1 + - php: 7.2 env: SAUCELABS=1 BROWSER_NAME="MicrosoftEdge" VERSION="15.15063" PLATFORM="Windows 10" before_script: - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & @@ -67,7 +68,7 @@ matrix: secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= # Codestyle check build - - php: 7.1 + - php: 7.2 env: CHECK_CODESTYLE=1 before_script: ~ script: composer codestyle:check From d7cabc7fd357c1d8ccf43b5dbfb2116a74a193e0 Mon Sep 17 00:00:00 2001 From: Gabriel Caruso Date: Wed, 6 Dec 2017 05:31:52 -0200 Subject: [PATCH 381/784] Use assertArrayNotHasKey --- tests/unit/CookieTest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/unit/CookieTest.php b/tests/unit/CookieTest.php index 43215acb8..ade9af68f 100644 --- a/tests/unit/CookieTest.php +++ b/tests/unit/CookieTest.php @@ -79,7 +79,7 @@ public function testShouldProvideArrayAccessToProperties(Cookie $cookie) $cookie->offsetSet('domain', 'bar.com'); $this->assertSame('bar.com', $cookie['domain']); $cookie->offsetUnset('domain'); - $this->assertFalse(isset($cookie['domain'])); + $this->assertArrayNotHasKey('domain', $cookie); } public function testShouldBeCreatableFromAnArrayWithBasicValues() @@ -94,23 +94,23 @@ public function testShouldBeCreatableFromAnArrayWithBasicValues() $this->assertSame('cookieName', $cookie['name']); $this->assertSame('someValue', $cookie['value']); - $this->assertFalse(isset($cookie['path'])); + $this->assertArrayNotHasKey('path', $cookie); $this->assertNull($cookie['path']); $this->assertNull($cookie->getPath()); - $this->assertFalse(isset($cookie['domain'])); + $this->assertArrayNotHasKey('domain', $cookie); $this->assertNull($cookie['domain']); $this->assertNull($cookie->getDomain()); - $this->assertFalse(isset($cookie['expiry'])); + $this->assertArrayNotHasKey('expiry', $cookie); $this->assertNull($cookie['expiry']); $this->assertNull($cookie->getExpiry()); - $this->assertFalse(isset($cookie['secure'])); + $this->assertArrayNotHasKey('secure', $cookie); $this->assertNull($cookie['secure']); $this->assertNull($cookie->isSecure()); - $this->assertFalse(isset($cookie['httpOnly'])); + $this->assertArrayNotHasKey('httpOnly', $cookie); $this->assertNull($cookie['httpOnly']); $this->assertNull($cookie->isHttpOnly()); } From 5f41a0bbec16fc719712089fc12399b0c1342f59 Mon Sep 17 00:00:00 2001 From: Dmitry Matora Date: Fri, 3 Nov 2017 20:29:01 +0300 Subject: [PATCH 382/784] Implemented timeout support. Solves #496 --- lib/Remote/RemoteWebDriver.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index f8b8e5e6e..3a8d3563f 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -139,11 +139,20 @@ public static function create( * * @param string $selenium_server_url The url of the remote Selenium WebDriver server * @param string $session_id The existing session id + * @param int|null $connection_timeout_in_ms Set timeout for the connect phase to remote Selenium WebDriver server + * @param int|null $request_timeout_in_ms Set the maximum time of a request to remote Selenium WebDriver server * @return RemoteWebDriver */ - public static function createBySessionID($session_id, $selenium_server_url = 'http://localhost:4444/wd/hub') + public static function createBySessionID($session_id, $selenium_server_url = 'http://localhost:4444/wd/hub', $connection_timeout_in_ms = null, $request_timeout_in_ms = null) { + $executor = new HttpCommandExecutor($selenium_server_url); + if ($connection_timeout_in_ms !== null) { + $executor->setConnectionTimeout($connection_timeout_in_ms); + } + if ($request_timeout_in_ms !== null) { + $executor->setRequestTimeout($request_timeout_in_ms); + } return new static($executor, $session_id); } From 21b62c4ceec300bbe63482c9027e3fc639aed3be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 6 Dec 2017 18:35:19 +0100 Subject: [PATCH 383/784] Update chagnelog --- CHANGELOG.md | 2 ++ lib/Remote/RemoteWebDriver.php | 11 +++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f42c31ef..a3adb0988 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +### Added +- Connection and request timeouts could be specified also when creating RemoteWebDriver from existing session ID. ## 1.5.0 - 2017-11-15 ### Changed diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index 3a8d3563f..becab6b98 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -85,7 +85,7 @@ protected function __construct( * @param int|null $connection_timeout_in_ms Set timeout for the connect phase to remote Selenium WebDriver server * @param int|null $request_timeout_in_ms Set the maximum time of a request to remote Selenium WebDriver server * @param string|null $http_proxy The proxy to tunnel requests to the remote Selenium WebDriver through - * @param int|null $http_proxy_port The proxy port to tunnel requests to the remote Selenium WebDriver through + * @param int|null $http_proxy_port The proxy port to tunnel requests to the remote Selenium WebDriver through * @param DesiredCapabilities $required_capabilities The required capabilities * @return RemoteWebDriver */ @@ -143,9 +143,12 @@ public static function create( * @param int|null $request_timeout_in_ms Set the maximum time of a request to remote Selenium WebDriver server * @return RemoteWebDriver */ - public static function createBySessionID($session_id, $selenium_server_url = 'http://localhost:4444/wd/hub', $connection_timeout_in_ms = null, $request_timeout_in_ms = null) - { - + public static function createBySessionID( + $session_id, + $selenium_server_url = 'http://localhost:4444/wd/hub', + $connection_timeout_in_ms = null, + $request_timeout_in_ms = null + ) { $executor = new HttpCommandExecutor($selenium_server_url); if ($connection_timeout_in_ms !== null) { $executor->setConnectionTimeout($connection_timeout_in_ms); From 32d5b8d8ba1161bff5838ebc70689560f6964211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Thu, 7 Dec 2017 00:35:05 +0100 Subject: [PATCH 384/784] Fix ChromeDriver declaration to match the parent class --- lib/Chrome/ChromeDriver.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/Chrome/ChromeDriver.php b/lib/Chrome/ChromeDriver.php index 8ba76583c..832ca17a8 100644 --- a/lib/Chrome/ChromeDriver.php +++ b/lib/Chrome/ChromeDriver.php @@ -82,13 +82,16 @@ public static function create( * * @param string $session_id The existing session id * @param string $selenium_server_url The url of the remote Selenium WebDriver server - * + * @param int|null $connection_timeout_in_ms Set timeout for the connect phase to remote Selenium WebDriver server + * @param int|null $request_timeout_in_ms Set the maximum time of a request to remote Selenium WebDriver server * @throws WebDriverException * @return RemoteWebDriver|void */ public static function createBySessionID( $session_id, - $selenium_server_url = 'http://localhost:4444/wd/hub' + $selenium_server_url = 'http://localhost:4444/wd/hub', + $connection_timeout_in_ms = null, + $request_timeout_in_ms = null ) { throw new WebDriverException('Please use ChromeDriver::start() instead.'); } From 6baf65f9c62378a775900da2c6168888649b6f28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Mon, 11 Dec 2017 12:19:10 +0100 Subject: [PATCH 385/784] Upgrade php-coveralls to v 2.0.0 --- .travis.yml | 2 +- composer.json | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7484f1cfc..18db2fc36 100644 --- a/.travis.yml +++ b/.travis.yml @@ -106,4 +106,4 @@ after_script: - if [ -f ./logs/php-server.log ]; then cat ./logs/php-server.log; fi after_success: - - travis_retry php vendor/bin/coveralls -v + - travis_retry php vendor/bin/php-coveralls -v diff --git a/composer.json b/composer.json index 069cb6df5..6aa6ef61b 100644 --- a/composer.json +++ b/composer.json @@ -23,8 +23,7 @@ "friendsofphp/php-cs-fixer": "^2.0", "squizlabs/php_codesniffer": "^2.6", "php-mock/php-mock-phpunit": "^1.1", - "php-coveralls/php-coveralls": "^1.0.2", - "guzzle/guzzle": "^3.4.1", + "php-coveralls/php-coveralls": "^2.0", "symfony/var-dumper": "^3.3 || ^4.0" }, "autoload": { From cec193f66be978d107ad50112d1ad4546b255e5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 9 Dec 2017 01:04:31 +0100 Subject: [PATCH 386/784] Use PHPStan for static analysis --- .travis.yml | 5 ++++- composer.json | 3 +++ lib/Firefox/FirefoxProfile.php | 2 +- lib/Support/Events/EventFiringWebDriver.php | 6 +++--- lib/Support/Events/EventFiringWebDriverNavigation.php | 2 +- lib/Support/Events/EventFiringWebElement.php | 2 +- lib/WebDriverExpectedCondition.php | 4 ++-- lib/WebDriverHasInputDevices.php | 2 +- phpstan.neon | 10 ++++++++++ tests/functional/WebDriverByTest.php | 4 ++-- 10 files changed, 28 insertions(+), 12 deletions(-) create mode 100644 phpstan.neon diff --git a/.travis.yml b/.travis.yml index 18db2fc36..07687e845 100644 --- a/.travis.yml +++ b/.travis.yml @@ -70,7 +70,10 @@ matrix: - php: 7.1 env: CHECK_CODESTYLE=1 before_script: ~ - script: composer codestyle:check + script: + - composer require phpstan/phpstan-shim # Not part of require-dev, because it won't install on PHP 5.6 + - composer analyze + - composer codestyle:check after_script: ~ after_success: ~ diff --git a/composer.json b/composer.json index 6aa6ef61b..c865ad691 100644 --- a/composer.json +++ b/composer.json @@ -45,6 +45,9 @@ "codestyle:fix": [ "vendor/bin/php-cs-fixer fix --diff || exit 0", "vendor/bin/phpcbf --standard=PSR2 ./lib/ ./tests/" + ], + "analyze": [ + "vendor/bin/phpstan.phar analyze ./lib ./tests --level 2 -c phpstan.neon --ansi" ] }, "extra": { diff --git a/lib/Firefox/FirefoxProfile.php b/lib/Firefox/FirefoxProfile.php index 8086198ca..b9d36b30e 100644 --- a/lib/Firefox/FirefoxProfile.php +++ b/lib/Firefox/FirefoxProfile.php @@ -110,7 +110,7 @@ public function setPreference($key, $value) } /** - * @param $key + * @param mixed $key * @return mixed */ public function getPreference($key) diff --git a/lib/Support/Events/EventFiringWebDriver.php b/lib/Support/Events/EventFiringWebDriver.php index c129ef015..5a75dbe1f 100644 --- a/lib/Support/Events/EventFiringWebDriver.php +++ b/lib/Support/Events/EventFiringWebDriver.php @@ -133,7 +133,7 @@ public function findElement(WebDriverBy $by) } /** - * @param $script + * @param string $script * @param array $arguments * @throws WebDriverException * @return mixed @@ -161,7 +161,7 @@ public function executeScript($script, array $arguments = []) } /** - * @param $script + * @param string $script * @param array $arguments * @throws WebDriverException * @return mixed @@ -396,7 +396,7 @@ protected function newElement(WebDriverElement $element) /** * @param mixed $method - * @param mixed $arguments,... + * @param mixed ...$arguments */ protected function dispatch($method, ...$arguments) { diff --git a/lib/Support/Events/EventFiringWebDriverNavigation.php b/lib/Support/Events/EventFiringWebDriverNavigation.php index 0008ebbdc..7d8920eb1 100644 --- a/lib/Support/Events/EventFiringWebDriverNavigation.php +++ b/lib/Support/Events/EventFiringWebDriverNavigation.php @@ -149,7 +149,7 @@ public function to($url) /** * @param mixed $method - * @param mixed $arguments,... + * @param mixed ...$arguments */ protected function dispatch($method, ...$arguments) { diff --git a/lib/Support/Events/EventFiringWebElement.php b/lib/Support/Events/EventFiringWebElement.php index 099bb3573..9595953cf 100644 --- a/lib/Support/Events/EventFiringWebElement.php +++ b/lib/Support/Events/EventFiringWebElement.php @@ -392,7 +392,7 @@ protected function dispatchOnException(WebDriverException $exception) /** * @param mixed $method - * @param mixed $arguments,... + * @param mixed ...$arguments */ protected function dispatch($method, ...$arguments) { diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index 433ee1a3a..d9ceb5dde 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -213,7 +213,7 @@ function (WebDriver $driver) use ($by) { if ($element->isDisplayed()) { $visibleElements[] = $element; } - } catch (StateElementReferenceException $e) { + } catch (StaleElementReferenceException $e) { } } @@ -399,7 +399,7 @@ function (WebDriver $driver) use ($by) { /** * An expectation for checking that an element with text is either invisible or not present on the DOM. * - * @param WebdriverBy $by The locator used to find the element. + * @param WebDriverBy $by The locator used to find the element. * @param string $text The text of the element. * @return WebDriverExpectedCondition Condition returns whether the text is found in the element located. */ diff --git a/lib/WebDriverHasInputDevices.php b/lib/WebDriverHasInputDevices.php index 93e42a30a..7cb1992eb 100644 --- a/lib/WebDriverHasInputDevices.php +++ b/lib/WebDriverHasInputDevices.php @@ -21,7 +21,7 @@ interface WebDriverHasInputDevices { /** - * @return WebDriverKeyBoard + * @return WebDriverKeyboard */ public function getKeyboard(); diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 000000000..7023c466e --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,10 @@ +parameters: + ignoreErrors: + - '#Class Symfony\\Component\\Process\\ProcessBuilder not found.#' + - '#Instantiated class Symfony\\Component\\Process\\ProcessBuilder not found.#' + - '#Call to method setPrefix\(\) on an unknown class Symfony\\Component\\Process\\ProcessBuilder#' + # To be fixed: + - '#Call to an undefined method RecursiveIteratorIterator::getSubPathName\(\)#' + - '#Call to an undefined method Facebook\\WebDriver\\WebDriver::getTouch\(\)#' + - '#Call to an undefined method Facebook\\WebDriver\\WebDriverElement::getCoordinates\(\)#' + - '#Call to an undefined method Facebook\\WebDriver\\WebDriverElement::equals\(\)#' diff --git a/tests/functional/WebDriverByTest.php b/tests/functional/WebDriverByTest.php index 43d8c0457..534b145f0 100644 --- a/tests/functional/WebDriverByTest.php +++ b/tests/functional/WebDriverByTest.php @@ -25,8 +25,8 @@ class WebDriverByTest extends WebDriverTestCase { /** * @dataProvider textElementsProvider - * @param $webDriverByLocatorMethod - * @param $webDriverByLocatorValue + * @param string $webDriverByLocatorMethod + * @param string $webDriverByLocatorValue * @param string $expectedText * @param string $expectedAttributeValue */ From cc69cf0bbd807be3b8111098e03c46621d47e695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 9 Dec 2017 01:06:04 +0100 Subject: [PATCH 387/784] Use createMock shortcut contained in new PHPUnit --- tests/unit/WebDriverExpectedConditionTest.php | 45 ++++++------------- 1 file changed, 14 insertions(+), 31 deletions(-) diff --git a/tests/unit/WebDriverExpectedConditionTest.php b/tests/unit/WebDriverExpectedConditionTest.php index c4d734015..abcd5537b 100644 --- a/tests/unit/WebDriverExpectedConditionTest.php +++ b/tests/unit/WebDriverExpectedConditionTest.php @@ -34,11 +34,7 @@ class WebDriverExpectedConditionTest extends TestCase protected function setUp() { - // TODO: replace with createMock() once PHP 5.5 support is dropped - $this->driverMock = $this - ->getMockBuilder(RemoteWebDriver::class) - ->disableOriginalConstructor() - ->getMock(); + $this->driverMock = $this->createMock(RemoteWebDriver::class); $this->wait = new WebDriverWait($this->driverMock, 1, 1); } @@ -141,7 +137,7 @@ public function testShouldDetectPresenceOfElementLocatedCondition() public function testShouldDetectPresenceOfAllElementsLocatedByCondition() { - $element = $this->createRemoteWebElementMock(); + $element = $this->createMock(RemoteWebElement::class); $this->driverMock->expects($this->at(0)) ->method('findElements') @@ -166,7 +162,7 @@ public function testShouldDetectVisibilityOfElementLocatedCondition() // Call #3: return Element, but isDisplayed will return false // Call #4: return Element, isDisplayed will true and condition will match - $element = $this->createRemoteWebElementMock(); + $element = $this->createMock(RemoteWebElement::class); $element->expects($this->at(0)) ->method('isDisplayed') ->willThrowException(new StaleElementReferenceException('')); @@ -189,9 +185,9 @@ public function testShouldDetectVisibilityOfElementLocatedCondition() public function testShouldDetectVisibilityOfAnyElementLocated() { $elementList = [ - $this->createRemoteWebElementMock(), - $this->createRemoteWebElementMock(), - $this->createRemoteWebElementMock(), + $this->createMock(RemoteWebElement::class), + $this->createMock(RemoteWebElement::class), + $this->createMock(RemoteWebElement::class), ]; $elementList[0]->expects($this->once()) @@ -218,7 +214,7 @@ public function testShouldDetectVisibilityOfAnyElementLocated() public function testShouldDetectInvisibilityOfElementLocatedConditionOnNoSuchElementException() { - $element = $this->createRemoteWebElementMock(); + $element = $this->createMock(RemoteWebElement::class); $this->driverMock->expects($this->at(0)) ->method('findElement') @@ -241,7 +237,7 @@ public function testShouldDetectInvisibilityOfElementLocatedConditionOnNoSuchEle public function testShouldDetectInvisibilityOfElementLocatedConditionOnStaleElementReferenceException() { - $element = $this->createRemoteWebElementMock(); + $element = $this->createMock(RemoteWebElement::class); $this->driverMock->expects($this->exactly(2)) ->method('findElement') @@ -263,7 +259,7 @@ public function testShouldDetectInvisibilityOfElementLocatedConditionOnStaleElem public function testShouldDetectInvisibilityOfElementLocatedConditionWhenElementBecamesInvisible() { - $element = $this->createRemoteWebElementMock(); + $element = $this->createMock(RemoteWebElement::class); $this->driverMock->expects($this->exactly(2)) ->method('findElement') @@ -285,7 +281,7 @@ public function testShouldDetectInvisibilityOfElementLocatedConditionWhenElement public function testShouldDetectVisibilityOfCondition() { - $element = $this->createRemoteWebElementMock(); + $element = $this->createMock(RemoteWebElement::class); $element->expects($this->at(0)) ->method('isDisplayed') ->willReturn(false); @@ -307,7 +303,7 @@ public function testShouldDetectElementTextContainsCondition() // Call #3: return Element, but getText will throw StaleElementReferenceException // Call #4: return Element, getText will return new text and condition will match - $element = $this->createRemoteWebElementMock(); + $element = $this->createMock(RemoteWebElement::class); $element->expects($this->at(0)) ->method('getText') ->willReturn('this is an old text'); @@ -335,7 +331,7 @@ public function testShouldDetectElementTextIsCondition() // Call #3: return Element, getText will return not-matching text // Call #4: return Element, getText will return new text and condition will match - $element = $this->createRemoteWebElementMock(); + $element = $this->createMock(RemoteWebElement::class); $element->expects($this->at(0)) ->method('getText') ->willThrowException(new StaleElementReferenceException('')); @@ -366,7 +362,7 @@ public function testShouldDetectElementTextMatchesCondition() // Call #3: return Element, getText will return not-matching text // Call #4: return Element, getText will return matching text - $element = $this->createRemoteWebElementMock(); + $element = $this->createMock(RemoteWebElement::class); $element->expects($this->at(0)) ->method('getText') @@ -398,7 +394,7 @@ public function testShouldDetectElementValueContainsCondition() // Call #3: return Element, getAttribute('value') will return not-matching text // Call #4: return Element, getAttribute('value') will return matching text - $element = $this->createRemoteWebElementMock(); + $element = $this->createMock(RemoteWebElement::class); $element->expects($this->at(0)) ->method('getAttribute') @@ -456,17 +452,4 @@ private function setupDriverToReturnElementAfterAnException($element, $expectedN ->willReturn($element); } } - - /** - * @todo Replace with createMock() once PHP 5.5 support is dropped - * @return \PHPUnit_Framework_MockObject_MockObject|RemoteWebElement - */ - private function createRemoteWebElementMock() - { - return $this->getMockBuilder(RemoteWebElement::class) - ->disableOriginalConstructor() - ->disableOriginalClone() - ->disableArgumentCloning() - ->getMock(); - } } From 4962d348f5e71c284bebc59ab7dd54607518ee4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 9 Dec 2017 01:07:34 +0100 Subject: [PATCH 388/784] Use absolute FQCN in annotation --- tests/functional/Chrome/ChromeDriverServiceTest.php | 4 ++-- tests/functional/Chrome/ChromeDriverTest.php | 2 +- tests/functional/FileUploadTest.php | 4 ++-- tests/functional/RemoteWebDriverCreateTest.php | 4 ++-- tests/functional/RemoteWebDriverFindElementTest.php | 2 +- tests/functional/RemoteWebDriverTest.php | 4 ++-- tests/functional/RemoteWebElementTest.php | 2 +- tests/functional/WebDriverActionsTest.php | 2 +- tests/functional/WebDriverAlertTest.php | 2 +- tests/functional/WebDriverByTest.php | 2 +- tests/functional/WebDriverNavigationTest.php | 2 +- tests/functional/WebDriverSelectTest.php | 4 ++-- tests/functional/WebDriverTimeoutsTest.php | 2 +- tests/unit/CookieTest.php | 2 +- tests/unit/Remote/RemoteWebDriverTest.php | 2 +- tests/unit/Remote/RemoteWebElementTest.php | 2 +- tests/unit/WebDriverExpectedConditionTest.php | 2 +- tests/unit/WebDriverKeysTest.php | 2 +- tests/unit/WebDriverOptionsTest.php | 2 +- 19 files changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/functional/Chrome/ChromeDriverServiceTest.php b/tests/functional/Chrome/ChromeDriverServiceTest.php index bc1a1b92f..781a68bae 100644 --- a/tests/functional/Chrome/ChromeDriverServiceTest.php +++ b/tests/functional/Chrome/ChromeDriverServiceTest.php @@ -19,8 +19,8 @@ /** * @group exclude-saucelabs - * @covers Facebook\WebDriver\Chrome\ChromeDriverService - * @covers Facebook\WebDriver\Remote\Service\DriverService + * @covers \Facebook\WebDriver\Chrome\ChromeDriverService + * @covers \Facebook\WebDriver\Remote\Service\DriverService */ class ChromeDriverServiceTest extends TestCase { diff --git a/tests/functional/Chrome/ChromeDriverTest.php b/tests/functional/Chrome/ChromeDriverTest.php index 476033839..b8066156e 100644 --- a/tests/functional/Chrome/ChromeDriverTest.php +++ b/tests/functional/Chrome/ChromeDriverTest.php @@ -21,7 +21,7 @@ /** * @group exclude-saucelabs - * @covers Facebook\WebDriver\Chrome\ChromeDriver + * @covers \Facebook\WebDriver\Chrome\ChromeDriver */ class ChromeDriverTest extends TestCase { diff --git a/tests/functional/FileUploadTest.php b/tests/functional/FileUploadTest.php index e88139953..5b2f6d2d3 100644 --- a/tests/functional/FileUploadTest.php +++ b/tests/functional/FileUploadTest.php @@ -18,8 +18,8 @@ use Facebook\WebDriver\Remote\LocalFileDetector; /** - * @covers Facebook\WebDriver\Remote\LocalFileDetector - * @covers Facebook\WebDriver\Remote\RemoteWebElement + * @covers \Facebook\WebDriver\Remote\LocalFileDetector + * @covers \Facebook\WebDriver\Remote\RemoteWebElement */ class FileUploadTest extends WebDriverTestCase { diff --git a/tests/functional/RemoteWebDriverCreateTest.php b/tests/functional/RemoteWebDriverCreateTest.php index 3140b26b0..f9d7e809e 100644 --- a/tests/functional/RemoteWebDriverCreateTest.php +++ b/tests/functional/RemoteWebDriverCreateTest.php @@ -20,8 +20,8 @@ use Facebook\WebDriver\Remote\RemoteWebDriver; /** - * @covers Facebook\WebDriver\Remote\RemoteWebDriver - * @covers Facebook\WebDriver\Remote\HttpCommandExecutor + * @covers \Facebook\WebDriver\Remote\RemoteWebDriver + * @covers \Facebook\WebDriver\Remote\HttpCommandExecutor */ class RemoteWebDriverCreateTest extends WebDriverTestCase { diff --git a/tests/functional/RemoteWebDriverFindElementTest.php b/tests/functional/RemoteWebDriverFindElementTest.php index 46affc025..eea14b6e5 100644 --- a/tests/functional/RemoteWebDriverFindElementTest.php +++ b/tests/functional/RemoteWebDriverFindElementTest.php @@ -20,7 +20,7 @@ /** * Tests for findElement() and findElements() method of RemoteWebDriver. - * @covers Facebook\WebDriver\Remote\RemoteWebDriver + * @covers \Facebook\WebDriver\Remote\RemoteWebDriver */ class RemoteWebDriverFindElementTest extends WebDriverTestCase { diff --git a/tests/functional/RemoteWebDriverTest.php b/tests/functional/RemoteWebDriverTest.php index 006b17c7b..440776ad5 100644 --- a/tests/functional/RemoteWebDriverTest.php +++ b/tests/functional/RemoteWebDriverTest.php @@ -20,7 +20,7 @@ use Facebook\WebDriver\Remote\WebDriverBrowserType; /** - * @coversDefaultClass Facebook\WebDriver\Remote\RemoteWebDriver + * @coversDefaultClass \Facebook\WebDriver\Remote\RemoteWebDriver */ class RemoteWebDriverTest extends WebDriverTestCase { @@ -170,7 +170,7 @@ function(){document.getElementById("id_test").innerHTML = "Text changed by scrip /** * @covers ::executeAsyncScript - * @covers Facebook\WebDriver\WebDriverTimeouts::setScriptTimeout + * @covers \Facebook\WebDriver\WebDriverTimeouts::setScriptTimeout */ public function testShouldExecuteAsyncScriptAndWaitUntilItIsFinished() { diff --git a/tests/functional/RemoteWebElementTest.php b/tests/functional/RemoteWebElementTest.php index 51f414a93..d4614a431 100644 --- a/tests/functional/RemoteWebElementTest.php +++ b/tests/functional/RemoteWebElementTest.php @@ -19,7 +19,7 @@ use Facebook\WebDriver\Remote\RemoteWebElement; /** - * @coversDefaultClass Facebook\WebDriver\Remote\RemoteWebElement + * @coversDefaultClass \Facebook\WebDriver\Remote\RemoteWebElement */ class RemoteWebElementTest extends WebDriverTestCase { diff --git a/tests/functional/WebDriverActionsTest.php b/tests/functional/WebDriverActionsTest.php index 173f7794c..188c76cd9 100644 --- a/tests/functional/WebDriverActionsTest.php +++ b/tests/functional/WebDriverActionsTest.php @@ -18,7 +18,7 @@ use Facebook\WebDriver\Remote\WebDriverBrowserType; /** - * @coversDefaultClass Facebook\WebDriver\Interactions\WebDriverActions + * @coversDefaultClass \Facebook\WebDriver\Interactions\WebDriverActions */ class WebDriverActionsTest extends WebDriverTestCase { diff --git a/tests/functional/WebDriverAlertTest.php b/tests/functional/WebDriverAlertTest.php index 08d8ef73c..163bee157 100644 --- a/tests/functional/WebDriverAlertTest.php +++ b/tests/functional/WebDriverAlertTest.php @@ -19,7 +19,7 @@ use Facebook\WebDriver\Remote\WebDriverBrowserType; /** - * @covers Facebook\WebDriver\WebDriverAlert + * @covers \Facebook\WebDriver\WebDriverAlert */ class WebDriverAlertTest extends WebDriverTestCase { diff --git a/tests/functional/WebDriverByTest.php b/tests/functional/WebDriverByTest.php index 534b145f0..028db7920 100644 --- a/tests/functional/WebDriverByTest.php +++ b/tests/functional/WebDriverByTest.php @@ -19,7 +19,7 @@ /** * Tests for locator strategies provided by WebDriverBy. - * @covers Facebook\WebDriver\WebDriverBy + * @covers \Facebook\WebDriver\WebDriverBy */ class WebDriverByTest extends WebDriverTestCase { diff --git a/tests/functional/WebDriverNavigationTest.php b/tests/functional/WebDriverNavigationTest.php index 4f7dba252..d3aaebcb6 100644 --- a/tests/functional/WebDriverNavigationTest.php +++ b/tests/functional/WebDriverNavigationTest.php @@ -16,7 +16,7 @@ namespace Facebook\WebDriver; /** - * @coversDefaultClass Facebook\WebDriver\WebDriverNavigation + * @coversDefaultClass \Facebook\WebDriver\WebDriverNavigation */ class WebDriverNavigationTest extends WebDriverTestCase { diff --git a/tests/functional/WebDriverSelectTest.php b/tests/functional/WebDriverSelectTest.php index 9cd6cf250..37ad416af 100644 --- a/tests/functional/WebDriverSelectTest.php +++ b/tests/functional/WebDriverSelectTest.php @@ -20,8 +20,8 @@ use Facebook\WebDriver\Exception\UnsupportedOperationException; /** - * @covers Facebook\WebDriver\WebDriverSelect - * @covers Facebook\WebDriver\Exception\UnexpectedTagNameException + * @covers \Facebook\WebDriver\WebDriverSelect + * @covers \Facebook\WebDriver\Exception\UnexpectedTagNameException */ class WebDriverSelectTest extends WebDriverTestCase { diff --git a/tests/functional/WebDriverTimeoutsTest.php b/tests/functional/WebDriverTimeoutsTest.php index 808a494ab..69d143cc4 100644 --- a/tests/functional/WebDriverTimeoutsTest.php +++ b/tests/functional/WebDriverTimeoutsTest.php @@ -22,7 +22,7 @@ use Facebook\WebDriver\Remote\WebDriverBrowserType; /** - * @coversDefaultClass Facebook\WebDriver\WebDriverTimeouts + * @coversDefaultClass \Facebook\WebDriver\WebDriverTimeouts */ class WebDriverTimeoutsTest extends WebDriverTestCase { diff --git a/tests/unit/CookieTest.php b/tests/unit/CookieTest.php index ade9af68f..3a0679d2c 100644 --- a/tests/unit/CookieTest.php +++ b/tests/unit/CookieTest.php @@ -18,7 +18,7 @@ use PHPUnit\Framework\TestCase; /** - * @covers Facebook\WebDriver\Cookie + * @covers \Facebook\WebDriver\Cookie */ class CookieTest extends TestCase { diff --git a/tests/unit/Remote/RemoteWebDriverTest.php b/tests/unit/Remote/RemoteWebDriverTest.php index c8fee7e5d..c5e397e00 100644 --- a/tests/unit/Remote/RemoteWebDriverTest.php +++ b/tests/unit/Remote/RemoteWebDriverTest.php @@ -24,7 +24,7 @@ /** * Unit part of RemoteWebDriver tests. Ie. tests for behavior which do not interact with the real remote server. * - * @coversDefaultClass Facebook\WebDriver\Remote\RemoteWebDriver + * @coversDefaultClass \Facebook\WebDriver\Remote\RemoteWebDriver */ class RemoteWebDriverTest extends TestCase { diff --git a/tests/unit/Remote/RemoteWebElementTest.php b/tests/unit/Remote/RemoteWebElementTest.php index 80bc92931..e1b0a2b47 100644 --- a/tests/unit/Remote/RemoteWebElementTest.php +++ b/tests/unit/Remote/RemoteWebElementTest.php @@ -20,7 +20,7 @@ /** * Unit part of RemoteWebDriver tests. Ie. tests for behavior which do not interact with the real remote server. * - * @coversDefaultClass Facebook\WebDriver\Remote\RemoteWebElement + * @coversDefaultClass \Facebook\WebDriver\Remote\RemoteWebElement */ class RemoteWebElementTest extends TestCase { diff --git a/tests/unit/WebDriverExpectedConditionTest.php b/tests/unit/WebDriverExpectedConditionTest.php index abcd5537b..8cd4203a9 100644 --- a/tests/unit/WebDriverExpectedConditionTest.php +++ b/tests/unit/WebDriverExpectedConditionTest.php @@ -23,7 +23,7 @@ use PHPUnit\Framework\TestCase; /** - * @covers Facebook\WebDriver\WebDriverExpectedCondition + * @covers \Facebook\WebDriver\WebDriverExpectedCondition */ class WebDriverExpectedConditionTest extends TestCase { diff --git a/tests/unit/WebDriverKeysTest.php b/tests/unit/WebDriverKeysTest.php index a309402b8..71fef3b9e 100644 --- a/tests/unit/WebDriverKeysTest.php +++ b/tests/unit/WebDriverKeysTest.php @@ -18,7 +18,7 @@ use PHPUnit\Framework\TestCase; /** - * @covers Facebook\WebDriver\WebDriverKeys + * @covers \Facebook\WebDriver\WebDriverKeys */ class WebDriverKeysTest extends TestCase { diff --git a/tests/unit/WebDriverOptionsTest.php b/tests/unit/WebDriverOptionsTest.php index 07c721c48..dd7494c67 100644 --- a/tests/unit/WebDriverOptionsTest.php +++ b/tests/unit/WebDriverOptionsTest.php @@ -20,7 +20,7 @@ use PHPUnit\Framework\TestCase; /** - * @covers Facebook\WebDriver\WebDriverOptions + * @covers \Facebook\WebDriver\WebDriverOptions */ class WebDriverOptionsTest extends TestCase { From bc2b2d520ac8dfb6576b2c86d00999538c4c57d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 9 Dec 2017 01:19:25 +0100 Subject: [PATCH 389/784] Lint PHP files --- composer.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index c865ad691..aaff428b5 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,8 @@ "squizlabs/php_codesniffer": "^2.6", "php-mock/php-mock-phpunit": "^1.1", "php-coveralls/php-coveralls": "^2.0", - "symfony/var-dumper": "^3.3 || ^4.0" + "symfony/var-dumper": "^3.3 || ^4.0", + "jakub-onderka/php-parallel-lint": "^0.9.2" }, "autoload": { "psr-4": { @@ -47,6 +48,7 @@ "vendor/bin/phpcbf --standard=PSR2 ./lib/ ./tests/" ], "analyze": [ + "vendor/bin/parallel-lint -j 10 ./lib ./tests", "vendor/bin/phpstan.phar analyze ./lib ./tests --level 2 -c phpstan.neon --ansi" ] }, From 0750ede674372496e7564882e7d673265b35f055 Mon Sep 17 00:00:00 2001 From: Alexandr Motuzov Date: Fri, 29 Dec 2017 23:03:50 +0500 Subject: [PATCH 390/784] Add `ext-mbstring` to requirements `mb_strpos` function is used in several places in the project. Many features will not work without `ext-mbstring` installed. --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index aaff428b5..a96b82fe5 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,8 @@ "php": "^5.6 || ~7.0", "symfony/process": "^2.8 || ^3.1 || ^4.0", "ext-curl": "*", - "ext-zip": "*" + "ext-zip": "*", + "ext-mbstring": "*" }, "require-dev": { "phpunit/phpunit": "^5.7", From 7c69d51ed8b2ce845b4b39fe01b822628f429587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 2 Jan 2018 12:32:43 +0100 Subject: [PATCH 391/784] Remove xdebug to spped up codestyle check build --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 07687e845..1c6c75cd9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -69,6 +69,8 @@ matrix: # Codestyle check build - php: 7.1 env: CHECK_CODESTYLE=1 + before_install: + - phpenv config-rm xdebug.ini before_script: ~ script: - composer require phpstan/phpstan-shim # Not part of require-dev, because it won't install on PHP 5.6 @@ -82,10 +84,8 @@ cache: - $HOME/.composer/cache - jar -before_install: - - travis_retry composer self-update - install: + - travis_retry composer self-update - travis_retry composer update --no-interaction $DEPENDENCIES before_script: From fda6f7f6d45ed5baa2f6ce2cd9ba3d57e165b42d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 14 Jan 2018 00:21:39 +0100 Subject: [PATCH 392/784] Use a workaround for Chrome crashing on startup on Travis https://github.com/SeleniumHQ/selenium/issues/4961 --- tests/functional/Chrome/ChromeDriverTest.php | 9 ++++++++- tests/functional/WebDriverTestCase.php | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/functional/Chrome/ChromeDriverTest.php b/tests/functional/Chrome/ChromeDriverTest.php index b8066156e..89eb766cd 100644 --- a/tests/functional/Chrome/ChromeDriverTest.php +++ b/tests/functional/Chrome/ChromeDriverTest.php @@ -15,6 +15,7 @@ namespace Facebook\WebDriver\Chrome; +use Facebook\WebDriver\Remote\DesiredCapabilities; use Facebook\WebDriver\Remote\RemoteWebDriver; use Facebook\WebDriver\Remote\Service\DriverCommandExecutor; use PHPUnit\Framework\TestCase; @@ -47,7 +48,13 @@ public function testShouldStartChromeDriver() // The createDefaultService() method expect path to the executable to be present in the environment variable putenv(ChromeDriverService::CHROME_DRIVER_EXE_PROPERTY . '=' . getenv('CHROMEDRIVER_PATH')); - $this->driver = ChromeDriver::start(); + // Add --no-sandbox as a workaround for Chrome crashing: https://github.com/SeleniumHQ/selenium/issues/4961 + $chromeOptions = new ChromeOptions(); + $chromeOptions->addArguments(['--no-sandbox']); + $desiredCapabilities = DesiredCapabilities::chrome(); + $desiredCapabilities->setCapability(ChromeOptions::CAPABILITY, $chromeOptions); + + $this->driver = ChromeDriver::start($desiredCapabilities); $this->assertInstanceOf(ChromeDriver::class, $this->driver); $this->assertInstanceOf(DriverCommandExecutor::class, $this->driver->getCommandExecutor()); diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index 4abaf7c03..e9714a87c 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -55,7 +55,8 @@ protected function setUp() if ($browserName === WebDriverBrowserType::CHROME) { $chromeOptions = new ChromeOptions(); - $chromeOptions->addArguments(['--headless', 'window-size=1024,768']); + // --no-sandbox is a workaround for Chrome crashing: https://github.com/SeleniumHQ/selenium/issues/4961 + $chromeOptions->addArguments(['--headless', 'window-size=1024,768', '--no-sandbox']); $this->desiredCapabilities->setCapability(ChromeOptions::CAPABILITY, $chromeOptions); } From 21412fe9ce48ec8c23508879b73d78aa36c038ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 14 Jan 2018 00:25:19 +0100 Subject: [PATCH 393/784] Update Chromedriver and use stable chrome in Travis builds --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1c6c75cd9..3ee125011 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ env: global: - DISPLAY=:99.0 - BROWSER_NAME="htmlunit" - - CHROMEDRIVER_VERSION="2.31" + - CHROMEDRIVER_VERSION="2.35" matrix: include: @@ -25,7 +25,7 @@ matrix: - php: 7.1 env: BROWSER_NAME="chrome" CHROME_HEADLESS="1" addons: - chrome: beta + chrome: stable # Build with lowest possible dependencies - php: 7.1 @@ -35,7 +35,7 @@ matrix: - php: 7.1 env: BROWSER_NAME="chrome" CHROME_HEADLESS="1" DEPENDENCIES="--prefer-lowest" addons: - chrome: beta + chrome: stable # Saucelabs builds - php: 7.1 From 04b741060ea0f4fc0a4e3822a10b461005362a52 Mon Sep 17 00:00:00 2001 From: Stephanyan Date: Thu, 8 Feb 2018 22:53:17 +0100 Subject: [PATCH 394/784] Add .vscode folder to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 42ef8b562..deb25f3ae 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ logs/ *~ *.swp .idea +.vscode From 5c724f1b73e20a8241179df36db1b636170cd405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 16 Feb 2018 00:33:29 +0000 Subject: [PATCH 395/784] Remove invalid phpDoc return tags --- lib/WebDriverExpectedCondition.php | 58 ++++++++++++++---------------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index d9ceb5dde..505474dfd 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -51,7 +51,7 @@ public function getApply() * An expectation for checking the title of a page. * * @param string $title The expected title, which must be an exact match. - * @return WebDriverExpectedCondition Condition returns whether current page title equals given string. + * @return static Condition returns whether current page title equals given string. */ public static function titleIs($title) { @@ -66,7 +66,7 @@ function (WebDriver $driver) use ($title) { * An expectation for checking substring of a page Title. * * @param string $title The expected substring of Title. - * @return WebDriverExpectedCondition Condition returns whether current page title contains given string. + * @return static Condition returns whether current page title contains given string. */ public static function titleContains($title) { @@ -81,8 +81,7 @@ function (WebDriver $driver) use ($title) { * An expectation for checking current page title matches the given regular expression. * * @param string $titleRegexp The regular expression to test against. - * @return WebDriverExpectedCondition Condition returns whether current page title matches the regular - * expression. + * @return static Condition returns whether current page title matches the regular expression. */ public static function titleMatches($titleRegexp) { @@ -97,7 +96,7 @@ function (WebDriver $driver) use ($titleRegexp) { * An expectation for checking the URL of a page. * * @param string $url The expected URL, which must be an exact match. - * @return WebDriverExpectedCondition Condition returns whether current URL equals given one. + * @return static Condition returns whether current URL equals given one. */ public static function urlIs($url) { @@ -112,7 +111,7 @@ function (WebDriver $driver) use ($url) { * An expectation for checking substring of the URL of a page. * * @param string $url The expected substring of the URL - * @return WebDriverExpectedCondition Condition returns whether current URL contains given string. + * @return static Condition returns whether current URL contains given string. */ public static function urlContains($url) { @@ -127,7 +126,7 @@ function (WebDriver $driver) use ($url) { * An expectation for checking current page URL matches the given regular expression. * * @param string $urlRegexp The regular expression to test against. - * @return WebDriverExpectedCondition Condition returns whether current URL matches the regular expression. + * @return static Condition returns whether current URL matches the regular expression. */ public static function urlMatches($urlRegexp) { @@ -143,7 +142,7 @@ function (WebDriver $driver) use ($urlRegexp) { * This does not necessarily mean that the element is visible. * * @param WebDriverBy $by The locator used to find the element. - * @return WebDriverExpectedCondition Condition returns the element which is located. + * @return static Condition returns the WebDriverElement which is located. */ public static function presenceOfElementLocated(WebDriverBy $by) { @@ -158,7 +157,7 @@ function (WebDriver $driver) use ($by) { * An expectation for checking that there is at least one element present on a web page. * * @param WebDriverBy $by The locator used to find the element. - * @return WebDriverExpectedCondition Condition returns an array of WebDriverElements once they are located. + * @return static Condition return an array of WebDriverElement once they are located. */ public static function presenceOfAllElementsLocatedBy(WebDriverBy $by) { @@ -176,7 +175,7 @@ function (WebDriver $driver) use ($by) { * Visibility means that the element is not only displayed but also has a height and width that is greater than 0. * * @param WebDriverBy $by The locator used to find the element. - * @return WebDriverExpectedCondition Condition returns the element which is located and visible. + * @return static Condition returns the WebDriverElement which is located and visible. */ public static function visibilityOfElementLocated(WebDriverBy $by) { @@ -199,7 +198,7 @@ function (WebDriver $driver) use ($by) { * Visibility means that the element is not only displayed but also has a height and width that is greater than 0. * * @param WebDriverBy $by The located used to find the element. - * @return WebDriverExpectedCondition Condition returns the elements that are located and visible. + * @return static Condition returns the array of WebDriverElement that are located and visible. */ public static function visibilityOfAnyElementLocated(WebDriverBy $by) { @@ -227,8 +226,7 @@ function (WebDriver $driver) use ($by) { * Visibility means that the element is not only displayed but also has a height and width that is greater than 0. * * @param WebDriverElement $element The element to be checked. - * @return WebDriverExpectedCondition Condition returns the same WebDriverElement once it is - * visible. + * @return static Condition returns the same WebDriverElement once it is visible. */ public static function visibilityOf(WebDriverElement $element) { @@ -247,7 +245,7 @@ function () use ($element) { * @deprecated Use WebDriverExpectedCondition::elementTextContains() instead * @param WebDriverBy $by The locator used to find the element. * @param string $text The text to be presented in the element. - * @return WebDriverExpectedCondition Condition returns whether the text is present in the element. + * @return static Condition returns whether the text is present in the element. */ public static function textToBePresentInElement(WebDriverBy $by, $text) { @@ -260,7 +258,7 @@ public static function textToBePresentInElement(WebDriverBy $by, $text) * * @param WebDriverBy $by The locator used to find the element. * @param string $text The text to be presented in the element. - * @return WebDriverExpectedCondition Condition returns whether the partial text is present in the element. + * @return static Condition returns whether the partial text is present in the element. */ public static function elementTextContains(WebDriverBy $by, $text) { @@ -283,7 +281,7 @@ function (WebDriver $driver) use ($by, $text) { * * @param WebDriverBy $by The locator used to find the element. * @param string $text The expected text of the element. - * @return WebDriverExpectedCondition Condition returns whether the element has text value equal to given one. + * @return static Condition returns whether the element has text value equal to given one. */ public static function elementTextIs(WebDriverBy $by, $text) { @@ -303,7 +301,7 @@ function (WebDriver $driver) use ($by, $text) { * * @param WebDriverBy $by The locator used to find the element. * @param string $regexp The regular expression to test against. - * @return WebDriverExpectedCondition Condition returns whether the element has text value equal to given one. + * @return static Condition returns whether the element has text value equal to given one. */ public static function elementTextMatches(WebDriverBy $by, $regexp) { @@ -325,7 +323,7 @@ function (WebDriver $driver) use ($by, $regexp) { * @deprecated Use WebDriverExpectedCondition::elementValueContains() instead * @param WebDriverBy $by The locator used to find the element. * @param string $text The text to be presented in the element value. - * @return WebDriverExpectedCondition Condition returns whether the text is present in value attribute. + * @return static Condition returns whether the text is present in value attribute. */ public static function textToBePresentInElementValue(WebDriverBy $by, $text) { @@ -337,7 +335,7 @@ public static function textToBePresentInElementValue(WebDriverBy $by, $text) * * @param WebDriverBy $by The locator used to find the element. * @param string $text The text to be presented in the element value. - * @return WebDriverExpectedCondition Condition returns whether the text is present in value attribute. + * @return static Condition returns whether the text is present in value attribute. */ public static function elementValueContains(WebDriverBy $by, $text) { @@ -359,8 +357,7 @@ function (WebDriver $driver) use ($by, $text) { * * @param string $frame_locator The locator used to find the iFrame * expected to be either the id or name value of the i/frame - * @return WebDriverExpectedCondition Condition returns object focused on new frame when frame is - * found, false otherwise. + * @return static Condition returns object focused on new frame when frame is found, false otherwise. */ public static function frameToBeAvailableAndSwitchToIt($frame_locator) { @@ -379,7 +376,7 @@ function (WebDriver $driver) use ($frame_locator) { * An expectation for checking that an element is either invisible or not present on the DOM. * * @param WebDriverBy $by The locator used to find the element. - * @return WebDriverExpectedCondition Condition returns whether no visible element located. + * @return static Condition returns whether no visible element located. */ public static function invisibilityOfElementLocated(WebDriverBy $by) { @@ -401,7 +398,7 @@ function (WebDriver $driver) use ($by) { * * @param WebDriverBy $by The locator used to find the element. * @param string $text The text of the element. - * @return WebDriverExpectedCondition Condition returns whether the text is found in the element located. + * @return static Condition returns whether the text is found in the element located. */ public static function invisibilityOfElementWithText(WebDriverBy $by, $text) { @@ -422,8 +419,7 @@ function (WebDriver $driver) use ($by, $text) { * An expectation for checking an element is visible and enabled such that you can click it. * * @param WebDriverBy $by The locator used to find the element - * @return WebDriverExpectedCondition Condition return the WebDriverElement once it is located, - * visible and clickable. + * @return static Condition return the WebDriverElement once it is located, visible and clickable. */ public static function elementToBeClickable(WebDriverBy $by) { @@ -453,7 +449,7 @@ function (WebDriver $driver) use ($visibility_of_element_located) { * Wait until an element is no longer attached to the DOM. * * @param WebDriverElement $element The element to wait for. - * @return WebDriverExpectedCondition Condition returns whether the element is still attached to the DOM. + * @return static Condition returns whether the element is still attached to the DOM. */ public static function stalenessOf(WebDriverElement $element) { @@ -479,8 +475,7 @@ function () use ($element) { * the condition is checked. * * @param WebDriverExpectedCondition $condition The condition wrapped. - * @return WebDriverExpectedCondition Condition returns the return value of the getApply() of the given - * condition. + * @return static Condition returns the return value of the getApply() of the given condition. */ public static function refreshed(self $condition) { @@ -499,7 +494,7 @@ function (WebDriver $driver) use ($condition) { * An expectation for checking if the given element is selected. * * @param mixed $element_or_by Either the element or the locator. - * @return WebDriverExpectedCondition Condition returns whether the element is selected. + * @return static Condition returns whether the element is selected. */ public static function elementToBeSelected($element_or_by) { @@ -514,7 +509,7 @@ public static function elementToBeSelected($element_or_by) * * @param mixed $element_or_by Either the element or the locator. * @param bool $selected The required state. - * @return WebDriverExpectedCondition Condition returns whether the element is selected. + * @return static Condition returns whether the element is selected. */ public static function elementSelectionStateToBe($element_or_by, $selected) { @@ -544,8 +539,7 @@ function (WebDriver $driver) use ($element_or_by, $selected) { /** * An expectation for whether an alert() box is present. * - * @return WebDriverExpectedCondition Condition returns WebDriverAlert if alert() is present, - * null otherwise. + * @return static Condition returns WebDriverAlert if alert() is present, null otherwise. */ public static function alertIsPresent() { From 372fcba2b549a2f7a982e5eacb45614961dcddd5 Mon Sep 17 00:00:00 2001 From: Antonin Rykalsky Date: Mon, 12 Feb 2018 12:58:01 +0100 Subject: [PATCH 396/784] Disable sending Expect header in POST requests --- lib/Remote/HttpCommandExecutor.php | 6 +++++ .../ReportSauceLabsStatusListener.php | 2 ++ tests/unit/Remote/HttpCommandExecutorTest.php | 26 ++++++++++++++++--- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/lib/Remote/HttpCommandExecutor.php b/lib/Remote/HttpCommandExecutor.php index 09bf000d0..6a795080c 100644 --- a/lib/Remote/HttpCommandExecutor.php +++ b/lib/Remote/HttpCommandExecutor.php @@ -263,6 +263,12 @@ public function execute(WebDriverCommand $command) curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $http_method); } + if (in_array($http_method, ['POST', 'PUT'])) { + // Disable sending 'Expect: 100-Continue' header, as it is causing issues with eg. squid proxy + // https://tools.ietf.org/html/rfc7231#section-5.1.1 + curl_setopt($this->curl, CURLOPT_HTTPHEADER, ['Expect:']); + } + $encoded_params = null; if ($http_method === 'POST' && $params && is_array($params)) { diff --git a/tests/functional/ReportSauceLabsStatusListener.php b/tests/functional/ReportSauceLabsStatusListener.php index f2a3c9f7d..8d25b76ff 100644 --- a/tests/functional/ReportSauceLabsStatusListener.php +++ b/tests/functional/ReportSauceLabsStatusListener.php @@ -77,6 +77,8 @@ private function submitToSauceLabs($url, array $data) curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); curl_setopt($curl, CURLOPT_USERPWD, getenv('SAUCE_USERNAME') . ':' . getenv('SAUCE_ACCESS_KEY')); curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data)); + // Disable sending 'Expect: 100-Continue' header, as it is causing issues with eg. squid proxy + curl_setopt($curl, CURLOPT_HTTPHEADER, ['Expect:']); curl_exec($curl); diff --git a/tests/unit/Remote/HttpCommandExecutorTest.php b/tests/unit/Remote/HttpCommandExecutorTest.php index a3810e731..5519fa0e4 100644 --- a/tests/unit/Remote/HttpCommandExecutorTest.php +++ b/tests/unit/Remote/HttpCommandExecutorTest.php @@ -34,19 +34,32 @@ public function setUp() * @dataProvider commandProvider * @param int $command * @param array $params + * @param bool $shouldResetExpectHeader * @param string $expectedUrl * @param string $expectedPostData */ - public function testShouldSendRequestToAssembledUrl($command, array $params, $expectedUrl, $expectedPostData) - { + public function testShouldSendRequestToAssembledUrl( + $command, + array $params, + $shouldResetExpectHeader, + $expectedUrl, + $expectedPostData + ) { $command = new WebDriverCommand('foo-123', $command, $params); $curlSetoptMock = $this->getFunctionMock(__NAMESPACE__, 'curl_setopt'); $curlSetoptMock->expects($this->at(0)) ->with($this->anything(), CURLOPT_URL, $expectedUrl); - $curlSetoptMock->expects($this->at(2)) - ->with($this->anything(), CURLOPT_POSTFIELDS, $expectedPostData); + if ($shouldResetExpectHeader) { + $curlSetoptMock->expects($this->at(2)) + ->with($this->anything(), CURLOPT_HTTPHEADER, ['Expect:']); + $curlSetoptMock->expects($this->at(3)) + ->with($this->anything(), CURLOPT_POSTFIELDS, $expectedPostData); + } else { + $curlSetoptMock->expects($this->at(2)) + ->with($this->anything(), CURLOPT_POSTFIELDS, $expectedPostData); + } $curlExecMock = $this->getFunctionMock(__NAMESPACE__, 'curl_exec'); $curlExecMock->expects($this->once()) @@ -64,30 +77,35 @@ public function commandProvider() 'POST command having :id placeholder in url' => [ DriverCommand::SEND_KEYS_TO_ELEMENT, ['value' => 'submitted-value', ':id' => '1337'], + true, 'http://localhost:4444/session/foo-123/element/1337/value', '{"value":"submitted-value"}', ], 'POST command without :id placeholder in url' => [ DriverCommand::TOUCH_UP, ['x' => 3, 'y' => 6], + true, 'http://localhost:4444/session/foo-123/touch/up', '{"x":3,"y":6}', ], 'Extra useless placeholder parameter should be removed' => [ DriverCommand::TOUCH_UP, ['x' => 3, 'y' => 6, ':useless' => 'foo'], + true, 'http://localhost:4444/session/foo-123/touch/up', '{"x":3,"y":6}', ], 'DELETE command' => [ DriverCommand::DELETE_COOKIE, [':name' => 'cookie-name'], + false, 'http://localhost:4444/session/foo-123/cookie/cookie-name', null, ], 'GET command without session in URL' => [ DriverCommand::GET_ALL_SESSIONS, [], + false, 'http://localhost:4444/sessions', null, ], From 42e7b6554f30689baf43827b791a678b2f7ecc8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 17 Feb 2018 01:19:28 +0000 Subject: [PATCH 397/784] Update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3adb0988..67969e3f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ### Added - Connection and request timeouts could be specified also when creating RemoteWebDriver from existing session ID. +### Changed +- Disable sending 'Expect: 100-Continue' header with POST requests, as they may more easily fail when sending via eg. squid proxy. + ## 1.5.0 - 2017-11-15 ### Changed - Drop PHP 5.5 support, the minimal required version of PHP is now PHP 5.6. From 2d40e31c8911c4e0e9df43ca771623266bb978da Mon Sep 17 00:00:00 2001 From: Drew Budwin Date: Fri, 2 Feb 2018 18:37:19 -0500 Subject: [PATCH 398/784] Update PHPDoc for functions that return static instances of a class Previously, functions that contained functionality similar to `return new static(...)` had their `@return` PHPDoc tag to specify the class name like `@return SomeClass` where the preferred documentation should be `@return static`. Some support for this decision: https://github.com/phpDocumentor/fig-standards/blob/master/proposed/phpdoc.md#keyword https://netbeans.org/bugzilla/show_bug.cgi?id=196565 https://blog.madewithlove.be/post/return-types/ --- CHANGELOG.md | 1 + lib/Chrome/ChromeDriver.php | 3 +++ lib/Chrome/ChromeDriverService.php | 3 +++ lib/Remote/DesiredCapabilities.php | 24 ++++++++++---------- lib/Remote/RemoteWebDriver.php | 4 ++-- lib/Remote/RemoteWebElement.php | 2 +- lib/Support/Events/EventFiringWebElement.php | 2 +- lib/WebDriverBy.php | 16 ++++++------- lib/WebDriverExpectedCondition.php | 2 +- 9 files changed, 32 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3adb0988..0b7288a90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased ### Added - Connection and request timeouts could be specified also when creating RemoteWebDriver from existing session ID. +- Update PHPDoc for functions that return static instances of a class. ## 1.5.0 - 2017-11-15 ### Changed diff --git a/lib/Chrome/ChromeDriver.php b/lib/Chrome/ChromeDriver.php index 832ca17a8..107854b4a 100644 --- a/lib/Chrome/ChromeDriver.php +++ b/lib/Chrome/ChromeDriver.php @@ -24,6 +24,9 @@ class ChromeDriver extends RemoteWebDriver { + /** + * @return static + */ public static function start(DesiredCapabilities $desired_capabilities = null, ChromeDriverService $service = null) { if ($desired_capabilities === null) { diff --git a/lib/Chrome/ChromeDriverService.php b/lib/Chrome/ChromeDriverService.php index 90b3d24f7..c9525126d 100644 --- a/lib/Chrome/ChromeDriverService.php +++ b/lib/Chrome/ChromeDriverService.php @@ -22,6 +22,9 @@ class ChromeDriverService extends DriverService // The environment variable storing the path to the chrome driver executable. const CHROME_DRIVER_EXE_PROPERTY = 'webdriver.chrome.driver'; + /** + * @return static + */ public static function createDefaultService() { $exe = getenv(self::CHROME_DRIVER_EXE_PROPERTY); diff --git a/lib/Remote/DesiredCapabilities.php b/lib/Remote/DesiredCapabilities.php index 940fcf98c..0e1a1ab25 100644 --- a/lib/Remote/DesiredCapabilities.php +++ b/lib/Remote/DesiredCapabilities.php @@ -178,7 +178,7 @@ public function toArray() } /** - * @return DesiredCapabilities + * @return static */ public static function android() { @@ -189,7 +189,7 @@ public static function android() } /** - * @return DesiredCapabilities + * @return static */ public static function chrome() { @@ -200,7 +200,7 @@ public static function chrome() } /** - * @return DesiredCapabilities + * @return static */ public static function firefox() { @@ -218,7 +218,7 @@ public static function firefox() } /** - * @return DesiredCapabilities + * @return static */ public static function htmlUnit() { @@ -229,7 +229,7 @@ public static function htmlUnit() } /** - * @return DesiredCapabilities + * @return static */ public static function htmlUnitWithJS() { @@ -242,7 +242,7 @@ public static function htmlUnitWithJS() } /** - * @return DesiredCapabilities + * @return static */ public static function internetExplorer() { @@ -253,7 +253,7 @@ public static function internetExplorer() } /** - * @return DesiredCapabilities + * @return static */ public static function microsoftEdge() { @@ -264,7 +264,7 @@ public static function microsoftEdge() } /** - * @return DesiredCapabilities + * @return static */ public static function iphone() { @@ -275,7 +275,7 @@ public static function iphone() } /** - * @return DesiredCapabilities + * @return static */ public static function ipad() { @@ -286,7 +286,7 @@ public static function ipad() } /** - * @return DesiredCapabilities + * @return static */ public static function opera() { @@ -297,7 +297,7 @@ public static function opera() } /** - * @return DesiredCapabilities + * @return static */ public static function safari() { @@ -308,7 +308,7 @@ public static function safari() } /** - * @return DesiredCapabilities + * @return static */ public static function phantomjs() { diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index becab6b98..1487689ec 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -87,7 +87,7 @@ protected function __construct( * @param string|null $http_proxy The proxy to tunnel requests to the remote Selenium WebDriver through * @param int|null $http_proxy_port The proxy port to tunnel requests to the remote Selenium WebDriver through * @param DesiredCapabilities $required_capabilities The required capabilities - * @return RemoteWebDriver + * @return static */ public static function create( $selenium_server_url = 'http://localhost:4444/wd/hub', @@ -141,7 +141,7 @@ public static function create( * @param string $session_id The existing session id * @param int|null $connection_timeout_in_ms Set timeout for the connect phase to remote Selenium WebDriver server * @param int|null $request_timeout_in_ms Set the maximum time of a request to remote Selenium WebDriver server - * @return RemoteWebDriver + * @return static */ public static function createBySessionID( $session_id, diff --git a/lib/Remote/RemoteWebElement.php b/lib/Remote/RemoteWebElement.php index 17fa258c4..26936d8b9 100644 --- a/lib/Remote/RemoteWebElement.php +++ b/lib/Remote/RemoteWebElement.php @@ -408,7 +408,7 @@ public function equals(WebDriverElement $other) * * @param string $id * - * @return RemoteWebElement + * @return static */ protected function newElement($id) { diff --git a/lib/Support/Events/EventFiringWebElement.php b/lib/Support/Events/EventFiringWebElement.php index 9595953cf..8df5cbb78 100644 --- a/lib/Support/Events/EventFiringWebElement.php +++ b/lib/Support/Events/EventFiringWebElement.php @@ -405,7 +405,7 @@ protected function dispatch($method, ...$arguments) /** * @param WebDriverElement $element - * @return EventFiringWebElement + * @return static */ protected function newElement(WebDriverElement $element) { diff --git a/lib/WebDriverBy.php b/lib/WebDriverBy.php index f882683b3..822a5c5fc 100644 --- a/lib/WebDriverBy.php +++ b/lib/WebDriverBy.php @@ -60,7 +60,7 @@ public function getValue() * names are not permitted. * * @param string $class_name - * @return WebDriverBy + * @return static */ public static function className($class_name) { @@ -71,7 +71,7 @@ public static function className($class_name) * Locates elements matching a CSS selector. * * @param string $css_selector - * @return WebDriverBy + * @return static */ public static function cssSelector($css_selector) { @@ -82,7 +82,7 @@ public static function cssSelector($css_selector) * Locates elements whose ID attribute matches the search value. * * @param string $id - * @return WebDriverBy + * @return static */ public static function id($id) { @@ -93,7 +93,7 @@ public static function id($id) * Locates elements whose NAME attribute matches the search value. * * @param string $name - * @return WebDriverBy + * @return static */ public static function name($name) { @@ -104,7 +104,7 @@ public static function name($name) * Locates anchor elements whose visible text matches the search value. * * @param string $link_text - * @return WebDriverBy + * @return static */ public static function linkText($link_text) { @@ -116,7 +116,7 @@ public static function linkText($link_text) * value. * * @param string $partial_link_text - * @return WebDriverBy + * @return static */ public static function partialLinkText($partial_link_text) { @@ -127,7 +127,7 @@ public static function partialLinkText($partial_link_text) * Locates elements whose tag name matches the search value. * * @param string $tag_name - * @return WebDriverBy + * @return static */ public static function tagName($tag_name) { @@ -138,7 +138,7 @@ public static function tagName($tag_name) * Locates elements matching an XPath expression. * * @param string $xpath - * @return WebDriverBy + * @return static */ public static function xpath($xpath) { diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index 505474dfd..15c7b3d2d 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -564,7 +564,7 @@ function (WebDriver $driver) { * An expectation checking the number of opened windows. * * @param int $expectedNumberOfWindows - * @return WebDriverExpectedCondition + * @return static */ public static function numberOfWindowsToBe($expectedNumberOfWindows) { From c4dcacf1978e680573042823606a40c1f990dd3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 25 Feb 2018 17:45:57 +0000 Subject: [PATCH 399/784] Describe a bit more how to use php-webdriver with Firefox --- README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5b331d349..9bbb228c6 100644 --- a/README.md +++ b/README.md @@ -43,9 +43,7 @@ Download and run that file, replacing # with the current server version. Keep in java -jar selenium-server-standalone-#.jar -When using Selenium server 3.5 and newer with some remote end clients (eg. Firefox with Geckodriver), you MUST disable so called "pass-through" mode, so that remote browser's protocol is translated to the protocol supported by php-webdriver (see [issue #469](https://github.com/facebook/php-webdriver/issues/469)): - - java -jar selenium-server-standalone-#.jar -enablePassThrough false +(Please see note below when using Firefox.) Then when you create a session, be sure to pass the url to where your server is running. @@ -58,6 +56,13 @@ $host = 'http://localhost:4444/wd/hub'; // this is the default Make sure to have latest Firefox and [Geckodriver](https://github.com/mozilla/geckodriver/releases) installed. +Because Firefox (and Geckodriver) only supports new W3C WebDriver protocol (which is yet to be implemented by php-wedbriver - see [issue #469](https://github.com/facebook/php-webdriver/issues/469)), +the protocols must be translated by Selenium server - this feature is *partially* available in Selenium server version 3.5.0-3.8.1 and you can enable it like this: + + java -jar selenium-server-standalone-3.8.1.jar -enablePassThrough false + +Now you can start Firefox from your code: + ```php $driver = RemoteWebDriver::create($host, DesiredCapabilities::firefox()); ``` From a6d99922c0c9812ee4a663b5796be734b5a40257 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 9 Mar 2018 11:10:25 +0100 Subject: [PATCH 400/784] Add missing required extensions to composer.json --- composer.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index a96b82fe5..5e5fce576 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,8 @@ "symfony/process": "^2.8 || ^3.1 || ^4.0", "ext-curl": "*", "ext-zip": "*", - "ext-mbstring": "*" + "ext-mbstring": "*", + "ext-json": "*" }, "require-dev": { "phpunit/phpunit": "^5.7", @@ -28,6 +29,9 @@ "symfony/var-dumper": "^3.3 || ^4.0", "jakub-onderka/php-parallel-lint": "^0.9.2" }, + "suggest": { + "ext-SimpleXML": "For Firefox profile creation" + }, "autoload": { "psr-4": { "Facebook\\WebDriver\\": "lib/" From 17881d2832df05301185b3ae96081f25c484d12f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 9 Mar 2018 11:13:31 +0100 Subject: [PATCH 401/784] Prefer Chrome in example script --- example.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/example.php b/example.php index 263d0c1d6..513b918b3 100644 --- a/example.php +++ b/example.php @@ -1,5 +1,6 @@ get('http://www.seleniumhq.org/'); +$driver->get('https://www.seleniumhq.org/'); // adding cookie $driver->manage()->deleteAllCookies(); @@ -57,5 +58,5 @@ ) ); -// close the Firefox +// close the browser $driver->quit(); From d4d655e958658eb0ab0050aea8f4d6c11f471c42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 9 Mar 2018 11:28:50 +0100 Subject: [PATCH 402/784] Remove workaround for selenium bug https://github.com/SeleniumHQ/selenium/issues/3398 --- example.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/example.php b/example.php index 513b918b3..2a9d0b298 100644 --- a/example.php +++ b/example.php @@ -45,11 +45,8 @@ // write 'php' in the search box $driver->findElement(WebDriverBy::id('q')) - ->sendKeys('php'); - -// submit the form -$driver->findElement(WebDriverBy::id('submit')) - ->click(); // submit() does not work in Selenium 3 because of bug https://github.com/SeleniumHQ/selenium/issues/3398 + ->sendKeys('php') // fill the search box + ->submit(); // submit the whole form // wait at most 10 seconds until at least one result is shown $driver->wait(10)->until( From bc08cfaddb1bb1a1f25d1981c637b92fa9d3d6f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 9 Mar 2018 11:38:17 +0100 Subject: [PATCH 403/784] Suggest Chrome on the first place in readme --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 9bbb228c6..c0bd89d1f 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,14 @@ Then when you create a session, be sure to pass the url to where your server is $host = 'http://localhost:4444/wd/hub'; // this is the default ``` +##### Launch Chrome + +Make sure to have latest Chrome and [Chromedriver](https://sites.google.com/a/chromium.org/chromedriver/downloads) installed. + +```php +$driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome()); +``` + ##### Launch Firefox Make sure to have latest Firefox and [Geckodriver](https://github.com/mozilla/geckodriver/releases) installed. @@ -67,14 +75,6 @@ Now you can start Firefox from your code: $driver = RemoteWebDriver::create($host, DesiredCapabilities::firefox()); ``` -##### Launch Chrome - -Make sure to have latest Chrome and [Chromedriver](https://sites.google.com/a/chromium.org/chromedriver/downloads) installed. - -```php -$driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome()); -``` - ##### You can also customize the desired capabilities ```php From 50be1fdd1d69119f7b6ad95f983a27b2b61f387b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 12 Mar 2018 16:34:11 +0100 Subject: [PATCH 404/784] PHPDoc: WebDriverElement::getAttribute may return null --- lib/WebDriverElement.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/WebDriverElement.php b/lib/WebDriverElement.php index 2505368b3..7253cb238 100644 --- a/lib/WebDriverElement.php +++ b/lib/WebDriverElement.php @@ -38,7 +38,7 @@ public function click(); * Get the value of a the given attribute of the element. * * @param string $attribute_name The name of the attribute. - * @return string The value of the attribute. + * @return string|null The value of the attribute. */ public function getAttribute($attribute_name); From cb4696490461d95c80784eb8e45008a296663092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 13 Mar 2018 10:21:01 +0100 Subject: [PATCH 405/784] Remove useless parenthesis in WebDriverSelect (minor) --- lib/WebDriverSelect.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/WebDriverSelect.php b/lib/WebDriverSelect.php index abe6b54fe..1dfbe268b 100644 --- a/lib/WebDriverSelect.php +++ b/lib/WebDriverSelect.php @@ -39,7 +39,7 @@ public function __construct(WebDriverElement $element) } $this->element = $element; $value = $element->getAttribute('multiple'); - $this->isMulti = ($value === 'true'); + $this->isMulti = $value === 'true'; } public function isMultiple() From cbcc53cd9c53a1e3ea91947fac8a730b7dd39e8f Mon Sep 17 00:00:00 2001 From: Antonin Rykalsky Date: Tue, 13 Mar 2018 15:07:32 +0100 Subject: [PATCH 406/784] Fix other http headers being not sent in case of adding Except header --- lib/Remote/HttpCommandExecutor.php | 18 +++++++++--------- tests/unit/Remote/HttpCommandExecutorTest.php | 12 +++++++++++- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/lib/Remote/HttpCommandExecutor.php b/lib/Remote/HttpCommandExecutor.php index 6a795080c..f584324b7 100644 --- a/lib/Remote/HttpCommandExecutor.php +++ b/lib/Remote/HttpCommandExecutor.php @@ -26,6 +26,11 @@ */ class HttpCommandExecutor implements WebDriverCommandExecutor { + const DEFAULT_HTTP_HEADERS = [ + 'Content-Type: application/json;charset=UTF-8', + 'Accept: application/json', + ]; + /** * @see https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#command-reference */ @@ -169,14 +174,7 @@ public function __construct($url, $http_proxy = null, $http_proxy_port = null) curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); - curl_setopt( - $this->curl, - CURLOPT_HTTPHEADER, - [ - 'Content-Type: application/json;charset=UTF-8', - 'Accept: application/json', - ] - ); + curl_setopt($this->curl, CURLOPT_HTTPHEADER, static::DEFAULT_HTTP_HEADERS); $this->setRequestTimeout(30000); $this->setConnectionTimeout(30000); } @@ -266,7 +264,9 @@ public function execute(WebDriverCommand $command) if (in_array($http_method, ['POST', 'PUT'])) { // Disable sending 'Expect: 100-Continue' header, as it is causing issues with eg. squid proxy // https://tools.ietf.org/html/rfc7231#section-5.1.1 - curl_setopt($this->curl, CURLOPT_HTTPHEADER, ['Expect:']); + curl_setopt($this->curl, CURLOPT_HTTPHEADER, array_merge(static::DEFAULT_HTTP_HEADERS, ['Expect:'])); + } else { + curl_setopt($this->curl, CURLOPT_HTTPHEADER, static::DEFAULT_HTTP_HEADERS); } $encoded_params = null; diff --git a/tests/unit/Remote/HttpCommandExecutorTest.php b/tests/unit/Remote/HttpCommandExecutorTest.php index 5519fa0e4..d6aae04b2 100644 --- a/tests/unit/Remote/HttpCommandExecutorTest.php +++ b/tests/unit/Remote/HttpCommandExecutorTest.php @@ -53,11 +53,21 @@ public function testShouldSendRequestToAssembledUrl( if ($shouldResetExpectHeader) { $curlSetoptMock->expects($this->at(2)) - ->with($this->anything(), CURLOPT_HTTPHEADER, ['Expect:']); + ->with( + $this->anything(), + CURLOPT_HTTPHEADER, + ['Content-Type: application/json;charset=UTF-8', 'Accept: application/json', 'Expect:'] + ); $curlSetoptMock->expects($this->at(3)) ->with($this->anything(), CURLOPT_POSTFIELDS, $expectedPostData); } else { $curlSetoptMock->expects($this->at(2)) + ->with( + $this->anything(), + CURLOPT_HTTPHEADER, + ['Content-Type: application/json;charset=UTF-8', 'Accept: application/json'] + ); + $curlSetoptMock->expects($this->at(3)) ->with($this->anything(), CURLOPT_POSTFIELDS, $expectedPostData); } From 8d368c65e6503aef11c545b1ec0cfb883b42b65d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 14 Mar 2018 22:44:11 +0100 Subject: [PATCH 407/784] Add more php-cs-fixer rules --- .php_cs.dist | 5 +++++ tests/unit/Remote/DesiredCapabilitiesTest.php | 7 +++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.php_cs.dist b/.php_cs.dist index d95f9d0fc..48aa29de7 100644 --- a/.php_cs.dist +++ b/.php_cs.dist @@ -12,6 +12,7 @@ return PhpCsFixer\Config::create() 'cast_spaces' => true, 'concat_space' => ['spacing' => 'one'], 'function_typehint_space' => true, + 'general_phpdoc_annotation_remove' => ['author'], 'linebreak_after_opening_tag' => true, 'lowercase_cast' => true, 'mb_str_functions' => true, @@ -50,6 +51,9 @@ return PhpCsFixer\Config::create() 'ordered_imports' => true, 'php_unit_construct' => true, 'php_unit_dedicate_assert' => true, + 'php_unit_expectation' => true, + 'php_unit_mock' => true, + 'php_unit_no_expectation_annotation' => true, 'phpdoc_add_missing_param_annotation' => true, 'phpdoc_indent' => true, 'phpdoc_no_access' => true, @@ -73,6 +77,7 @@ return PhpCsFixer\Config::create() 'unary_operator_spaces' => true, 'visibility_required' => true, 'whitespace_after_comma_in_array' => true, + 'yoda_style' => false, ]) ->setRiskyAllowed(true) ->setFinder($finder); diff --git a/tests/unit/Remote/DesiredCapabilitiesTest.php b/tests/unit/Remote/DesiredCapabilitiesTest.php index 7d39c3675..6e14ef044 100644 --- a/tests/unit/Remote/DesiredCapabilitiesTest.php +++ b/tests/unit/Remote/DesiredCapabilitiesTest.php @@ -62,12 +62,11 @@ public function testShouldProvideAccessToCapabilitiesUsingSettersAndGetters() $this->assertSame(333, $capabilities->getVersion()); } - /** - * @expectedException \Exception - * @expectedExceptionMessage isJavascriptEnabled() is a htmlunit-only option - */ public function testShouldNotAllowToDisableJavascriptForNonHtmlUnitBrowser() { + $this->expectException(\Exception::class); + $this->expectExceptionMessage('isJavascriptEnabled() is a htmlunit-only option'); + $capabilities = new DesiredCapabilities(); $capabilities->setBrowserName(WebDriverBrowserType::FIREFOX); $capabilities->setJavascriptEnabled(false); From 316dd0b7c056694a056bfc4e5217896eec2d1fd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 14 Mar 2018 23:32:35 +0100 Subject: [PATCH 408/784] Use udiff format in php-cs-fixer for more readable diffs --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 5e5fce576..2a9929725 100644 --- a/composer.json +++ b/composer.json @@ -45,11 +45,11 @@ }, "scripts": { "codestyle:check": [ - "vendor/bin/php-cs-fixer fix --diff --dry-run", + "vendor/bin/php-cs-fixer fix --diff --diff-format=udiff --dry-run -vvv --ansi", "vendor/bin/phpcs --standard=PSR2 ./lib/ ./tests/" ], "codestyle:fix": [ - "vendor/bin/php-cs-fixer fix --diff || exit 0", + "vendor/bin/php-cs-fixer fix --diff --diff-format=udiff -vvv || exit 0", "vendor/bin/phpcbf --standard=PSR2 ./lib/ ./tests/" ], "analyze": [ From 8a2df15749421bd6685b87c4574ad3c283d9d057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 16 Mar 2018 10:28:07 +0100 Subject: [PATCH 409/784] Fix @see in WebDriverOptions::addCookie --- lib/WebDriverOptions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/WebDriverOptions.php b/lib/WebDriverOptions.php index 9791b9f1c..a610a9e6a 100644 --- a/lib/WebDriverOptions.php +++ b/lib/WebDriverOptions.php @@ -37,7 +37,7 @@ public function __construct(ExecuteMethod $executor) /** * Add a specific cookie. * - * @see Facebook\WebDriver\Cookie for description of possible cookie properties + * @see Cookie for description of possible cookie properties * @param Cookie|array $cookie Cookie object. May be also created from array for compatibility reasons. * @return WebDriverOptions The current instance. */ From c95385adff0858e21446be5b49474056c1c06164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 16 Mar 2018 15:54:52 +0100 Subject: [PATCH 410/784] Fix the PHPDoc's types of Cookie.php --- lib/Cookie.php | 10 +++++----- lib/WebDriverOptions.php | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/Cookie.php b/lib/Cookie.php index 0434a128b..57ec7e13a 100644 --- a/lib/Cookie.php +++ b/lib/Cookie.php @@ -104,7 +104,7 @@ public function setPath($path) } /** - * @return string + * @return string|null */ public function getPath() { @@ -126,7 +126,7 @@ public function setDomain($domain) } /** - * @return string + * @return string|null */ public function getDomain() { @@ -144,7 +144,7 @@ public function setExpiry($expiry) } /** - * @return int + * @return int|null */ public function getExpiry() { @@ -162,7 +162,7 @@ public function setSecure($secure) } /** - * @return bool + * @return bool|null */ public function isSecure() { @@ -180,7 +180,7 @@ public function setHttpOnly($httpOnly) } /** - * @return bool + * @return bool|null */ public function isHttpOnly() { diff --git a/lib/WebDriverOptions.php b/lib/WebDriverOptions.php index a610a9e6a..bec7fd18b 100644 --- a/lib/WebDriverOptions.php +++ b/lib/WebDriverOptions.php @@ -90,7 +90,7 @@ public function deleteCookieNamed($name) * Get the cookie with a given name. * * @param string $name - * @return Cookie The cookie, or null if no cookie with the given name is presented. + * @return Cookie|null The cookie, or null if no cookie with the given name is presented. */ public function getCookieNamed($name) { From 933a114472777c72f781166ce4bccd29d61abe7b Mon Sep 17 00:00:00 2001 From: agentFinland Date: Tue, 10 Apr 2018 12:13:13 -0700 Subject: [PATCH 411/784] Clarified README (#557) * Clarified README - simplified some word choice for those new to the project and non-primary English speakers - corrected grammar - removed unnecessary words (clutter) - corrected sentence fragments - corrected improper verb choices - added extra headers to clarify purpose of each set of steps - rearranged some sentences so the focus of the sentence came earlier and/or became the subject --- README.md | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index c0bd89d1f..b25bee453 100644 --- a/README.md +++ b/README.md @@ -16,12 +16,12 @@ by the Selenium server and will also implement the [W3C WebDriver](https://w3c.g The concepts of this library are very similar to the "official" Java, .NET, Python and Ruby bindings from the [Selenium project](https://github.com/SeleniumHQ/selenium/). -**This is new version of PHP client, rewritten from scratch starting 2013.** +**As of 2013, this PHP client has been rewritten from scratch.** Using the old version? Check out [Adam Goucher's fork](https://github.com/Element-34/php-webdriver) of it. Looking for API documentation of php-webdriver? See [https://facebook.github.io/php-webdriver/](https://facebook.github.io/php-webdriver/latest/) -Any complaint, question, idea? You can post it on the user group https://www.facebook.com/groups/phpwebdriver/. +Any complaints, questions, or ideas? Post them in the user group https://www.facebook.com/groups/phpwebdriver/. ## Installation @@ -37,15 +37,19 @@ Then install the library: ## Getting started -All you need as the server for this client is the `selenium-server-standalone-#.jar` file provided here: http://selenium-release.storage.googleapis.com/index.html +### Start Server -Download and run that file, replacing # with the current server version. Keep in mind you must have Java 8+ installed to start this command. +The required server is the `selenium-server-standalone-#.jar` file provided here: http://selenium-release.storage.googleapis.com/index.html + +Download and run the server by replacing # with the current server version. Keep in mind **you must have Java 8+ installed to run this command**. java -jar selenium-server-standalone-#.jar -(Please see note below when using Firefox.) +**NOTE:** If using Firefox, see alternate command below. + +### Create a Browser Session -Then when you create a session, be sure to pass the url to where your server is running. +When creating a browser session, be sure to pass the url of your running server. ```php // This would be the url of the host running the server-standalone.jar @@ -54,7 +58,7 @@ $host = 'http://localhost:4444/wd/hub'; // this is the default ##### Launch Chrome -Make sure to have latest Chrome and [Chromedriver](https://sites.google.com/a/chromium.org/chromedriver/downloads) installed. +Make sure to have latest Chrome and [Chromedriver](https://sites.google.com/a/chromium.org/chromedriver/downloads) versions installed. ```php $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome()); @@ -64,8 +68,8 @@ $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome()); Make sure to have latest Firefox and [Geckodriver](https://github.com/mozilla/geckodriver/releases) installed. -Because Firefox (and Geckodriver) only supports new W3C WebDriver protocol (which is yet to be implemented by php-wedbriver - see [issue #469](https://github.com/facebook/php-webdriver/issues/469)), -the protocols must be translated by Selenium server - this feature is *partially* available in Selenium server version 3.5.0-3.8.1 and you can enable it like this: +Because Firefox (and Geckodriver) only support the new W3C WebDriver protocol (which is yet to be implemented by php-webdriver - see [issue #469](https://github.com/facebook/php-webdriver/issues/469)), +the protocols must be translated by Selenium Server - this feature is *partially* available in Selenium Server versions 3.5.0-3.8.1 and you can enable it like this: java -jar selenium-server-standalone-3.8.1.jar -enablePassThrough false @@ -75,7 +79,7 @@ Now you can start Firefox from your code: $driver = RemoteWebDriver::create($host, DesiredCapabilities::firefox()); ``` -##### You can also customize the desired capabilities +### Customize Desired Capabilities ```php $desired_capabilities = DesiredCapabilities::firefox(); @@ -85,7 +89,7 @@ $driver = RemoteWebDriver::create($host, $desired_capabilities); * See https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities for more details. -* Above snippets are not intended to be a working example by simply copy pasting. See [example.php](example.php) for working example. +**NOTE:** Above snippets are not intended to be a working example by simply copy-pasting. See [example.php](example.php) for working example. ## Changelog For latest changes see [CHANGELOG.md](CHANGELOG.md) file. @@ -98,22 +102,21 @@ You may also want to check out the Selenium [docs](http://docs.seleniumhq.org/do ## Testing framework integration -To take advantage of automatized testing you will most probably want to integrate php-webdriver to your testing framework. -There are some project already providing this: +To take advantage of automatized testing you may want to integrate php-webdriver to your testing framework. +There are some projects already providing this: -- [Steward](https://github.com/lmc-eu/steward) integrates php-webdriver directly to [PHPUnit](https://phpunit.de/), also providers parallelization. -- [Codeception](http://codeception.com) testing framework provides BDD-layer on top of php-webdriver in its [WebDriver module](http://codeception.com/docs/modules/WebDriver). -- You can also check out this [blogpost](http://codeception.com/11-12-2013/working-with-phpunit-and-selenium-webdriver.html) + [demo project](https://github.com/DavertMik/php-webdriver-demo), describing simple [PHPUnit](https://phpunit.de/) integration. +- [Steward](https://github.com/lmc-eu/steward) integrates php-webdriver directly to [PHPUnit](https://phpunit.de/), and provides parallelization +- [Codeception](http://codeception.com) testing framework provides BDD-layer on top of php-webdriver in its [WebDriver module](http://codeception.com/docs/modules/WebDriver) +- You can also check out this [blogpost](http://codeception.com/11-12-2013/working-with-phpunit-and-selenium-webdriver.html) + [demo project](https://github.com/DavertMik/php-webdriver-demo), describing simple [PHPUnit](https://phpunit.de/) integration ## Support -We have a great community willing to try and help you! +We have a great community willing to help you! -- **Via our Facebook Group** - If you have questions or are an active contributor consider joining our [facebook group](https://www.facebook.com/groups/phpwebdriver/) and contributing to the communal discussion and support. -- **Via StackOverflow** - You can also [ask a question](https://stackoverflow.com/questions/ask?tags=php+selenium-webdriver) or find many already answered question on StackOverflow. -- **Via GitHub** - Another option if you have a question (or bug report) is to [submit it here](https://github.com/facebook/php-webdriver/issues/new) as an new issue. +- **Via our Facebook Group** - If you have questions or are an active contributor consider joining our [facebook group](https://www.facebook.com/groups/phpwebdriver/) and contribute to communal discussion and support +- **Via StackOverflow** - You can also [ask a question](https://stackoverflow.com/questions/ask?tags=php+selenium-webdriver) or find many already answered question on StackOverflow +- **Via GitHub** - Another option if you have a question (or bug report) is to [submit it here](https://github.com/facebook/php-webdriver/issues/new) as an new issue ## Contributing -We love to have your help to make php-webdriver better. See [CONTRIBUTING.md](CONTRIBUTING.md) for more information -about contributing and developing php-webdriver. +We love to have your help to make php-webdriver better. See [CONTRIBUTING.md](CONTRIBUTING.md) for more information about contributing and developing php-webdriver. From f9a1a6ba4f57be77cc92122ae13df3dad6d3191e Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Wed, 16 May 2018 10:34:50 -0700 Subject: [PATCH 412/784] Update changelog for release --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b76cce76d..0f3088da9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased + +--- + +## 1.6.0 - 2018-05-16 ### Added - Connection and request timeouts could be specified also when creating RemoteWebDriver from existing session ID. - Update PHPDoc for functions that return static instances of a class. From a1784b20ea64afdb0613e5164b3cb42773df4578 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Mon, 28 May 2018 16:32:37 +0200 Subject: [PATCH 413/784] Update Selenium to 3.8.1 and Chromedriver to 2.38 --- .travis.yml | 6 +++--- tests/functional/RemoteWebDriverTest.php | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3c9c5c1a3..4a2cada83 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ env: global: - DISPLAY=:99.0 - BROWSER_NAME="htmlunit" - - CHROMEDRIVER_VERSION="2.35" + - CHROMEDRIVER_VERSION="2.38" matrix: include: @@ -93,8 +93,8 @@ before_script: - if [ "$BROWSER_NAME" = "chrome" ]; then mkdir chromedriver; wget -q -t 3 https://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip; unzip chromedriver_linux64 -d chromedriver; fi - if [ "$BROWSER_NAME" = "chrome" ]; then export CHROMEDRIVER_PATH=$PWD/chromedriver/chromedriver; fi - sh -e /etc/init.d/xvfb start - - if [ ! -f jar/selenium-server-standalone-3.4.0.jar ]; then wget -q -t 3 -P jar https://selenium-release.storage.googleapis.com/3.4/selenium-server-standalone-3.4.0.jar; fi - - java -Dwebdriver.firefox.marionette=false -Dwebdriver.chrome.driver="$CHROMEDRIVER_PATH" -jar jar/selenium-server-standalone-3.4.0.jar -log ./logs/selenium.log & + - if [ ! -f jar/selenium-server-standalone-3.8.1.jar ]; then wget -q -t 3 -P jar https://selenium-release.storage.googleapis.com/3.8/selenium-server-standalone-3.8.1.jar; fi + - java -Dwebdriver.firefox.marionette=false -Dwebdriver.chrome.driver="$CHROMEDRIVER_PATH" -jar jar/selenium-server-standalone-3.8.1.jar -enablePassThrough false -log ./logs/selenium.log & - until $(echo | nc localhost 4444); do sleep 1; echo Waiting for Selenium server on port 4444...; done; echo "Selenium server started" - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & - until $(echo | nc localhost 8000); do sleep 1; echo waiting for PHP server on port 8000...; done; echo "PHP server started" diff --git a/tests/functional/RemoteWebDriverTest.php b/tests/functional/RemoteWebDriverTest.php index 440776ad5..818a9da5a 100644 --- a/tests/functional/RemoteWebDriverTest.php +++ b/tests/functional/RemoteWebDriverTest.php @@ -84,7 +84,6 @@ public function testShouldGetAllSessions() $this->assertArrayHasKey('capabilities', $sessions[0]); $this->assertArrayHasKey('id', $sessions[0]); - $this->assertArrayHasKey('class', $sessions[0]); } /** From 6c885357678c692ee76d97d21ba03fbfbd19b46d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 29 May 2018 15:03:45 +0200 Subject: [PATCH 414/784] Add utility classes to interact with checkboxes and radio buttons (#545) * Add an utility class to manipulate checkboxes and radio buttons --- lib/AbstractWebDriverCheckboxOrRadio.php | 248 ++++++++++++++++++ lib/WebDriverCheckboxes.php | 66 +++++ lib/WebDriverRadios.php | 65 +++++ tests/functional/WebDriverCheckboxesTest.php | 197 ++++++++++++++ tests/functional/WebDriverRadiosTest.php | 184 +++++++++++++ tests/functional/web/form_checkbox_radio.html | 43 +++ 6 files changed, 803 insertions(+) create mode 100644 lib/AbstractWebDriverCheckboxOrRadio.php create mode 100644 lib/WebDriverCheckboxes.php create mode 100644 lib/WebDriverRadios.php create mode 100644 tests/functional/WebDriverCheckboxesTest.php create mode 100644 tests/functional/WebDriverRadiosTest.php create mode 100644 tests/functional/web/form_checkbox_radio.html diff --git a/lib/AbstractWebDriverCheckboxOrRadio.php b/lib/AbstractWebDriverCheckboxOrRadio.php new file mode 100644 index 000000000..46288592b --- /dev/null +++ b/lib/AbstractWebDriverCheckboxOrRadio.php @@ -0,0 +1,248 @@ +getTagName(); + if ($tagName !== 'input') { + throw new UnexpectedTagNameException('input', $tagName); + } + + $this->name = $element->getAttribute('name'); + if ($this->name === null) { + throw new WebDriverException('The input does not have a "name" attribute.'); + } + + $this->element = $element; + } + + public function getOptions() + { + return $this->getRelatedElements(); + } + + public function getAllSelectedOptions() + { + $selectedElement = []; + foreach ($this->getRelatedElements() as $element) { + if ($element->isSelected()) { + $selectedElement[] = $element; + + if (!$this->isMultiple()) { + return $selectedElement; + } + } + } + + return $selectedElement; + } + + public function getFirstSelectedOption() + { + foreach ($this->getRelatedElements() as $element) { + if ($element->isSelected()) { + return $element; + } + } + + throw new NoSuchElementException( + sprintf('No %s are selected', 'radio' === $this->type ? 'radio buttons' : 'checkboxes') + ); + } + + public function selectByIndex($index) + { + $this->byIndex($index); + } + + public function selectByValue($value) + { + $this->byValue($value); + } + + public function selectByVisibleText($text) + { + $this->byVisibleText($text); + } + + public function selectByVisiblePartialText($text) + { + $this->byVisibleText($text, true); + } + + /** + * Selects or deselects a checkbox or a radio button by its value. + * + * @param string $value + * @param bool $select + * @throws NoSuchElementException + */ + protected function byValue($value, $select = true) + { + $matched = false; + foreach ($this->getRelatedElements($value) as $element) { + $select ? $this->selectOption($element) : $this->deselectOption($element); + if (!$this->isMultiple()) { + return; + } + + $matched = true; + } + + if (!$matched) { + throw new NoSuchElementException( + sprintf('Cannot locate %s with value: %s', $this->type, $value) + ); + } + } + + /** + * Selects or deselects a checkbox or a radio button by its index. + * + * @param int $index + * @param bool $select + * @throws NoSuchElementException + */ + protected function byIndex($index, $select = true) + { + $elements = $this->getRelatedElements(); + if (!isset($elements[$index])) { + throw new NoSuchElementException(sprintf('Cannot locate %s with index: %d', $this->type, $index)); + } + + $select ? $this->selectOption($elements[$index]) : $this->deselectOption($elements[$index]); + } + + /** + * Selects or deselects a checkbox or a radio button by its visible text. + * + * @param string $text + * @param bool $partial + * @param bool $select + */ + protected function byVisibleText($text, $partial = false, $select = true) + { + foreach ($this->getRelatedElements() as $element) { + $normalizeFilter = sprintf( + $partial ? 'contains(normalize-space(.), %s)' : 'normalize-space(.) = %s', + XPathEscaper::escapeQuotes($text) + ); + + $xpath = 'ancestor::label'; + $xpathNormalize = sprintf('%s[%s]', $xpath, $normalizeFilter); + + $id = $element->getAttribute('id'); + if ($id !== null) { + $idFilter = sprintf('@for = %s', XPathEscaper::escapeQuotes($id)); + + $xpath .= sprintf(' | //label[%s]', $idFilter); + $xpathNormalize .= sprintf(' | //label[%s and %s]', $idFilter, $normalizeFilter); + } + + try { + $element->findElement(WebDriverBy::xpath($xpathNormalize)); + } catch (NoSuchElementException $e) { + if ($partial) { + continue; + } + + try { + // Since the mechanism of getting the text in xpath is not the same as + // webdriver, use the expensive getText() to check if nothing is matched. + if ($text !== $element->findElement(WebDriverBy::xpath($xpath))->getText()) { + continue; + } + } catch (NoSuchElementException $e) { + continue; + } + } + + $select ? $this->selectOption($element) : $this->deselectOption($element); + if (!$this->isMultiple()) { + return; + } + } + } + + /** + * Gets checkboxes or radio buttons with the same name. + * + * @param string|null $value + * @return WebDriverElement[] + */ + protected function getRelatedElements($value = null) + { + $valueSelector = $value ? sprintf(' and @value = %s', XPathEscaper::escapeQuotes($value)) : ''; + $formId = $this->element->getAttribute('form'); + if ($formId === null) { + $form = $this->element->findElement(WebDriverBy::xpath('ancestor::form')); + + $formId = $form->getAttribute('id'); + if ($formId === '') { + return $form->findElements(WebDriverBy::xpath( + sprintf('.//input[@name = %s%s]', XPathEscaper::escapeQuotes($this->name), $valueSelector) + )); + } + } + + return $this->element->findElements(WebDriverBy::xpath(sprintf( + '//form[@id = %1$s]//input[@name = %2$s%3$s] | //input[@form = %1$s and @name = %2$s%3$s]', + XPathEscaper::escapeQuotes($formId), + XPathEscaper::escapeQuotes($this->name), + $valueSelector + ))); + } + + /** + * Selects a checkbox or a radio button. + */ + protected function selectOption(WebDriverElement $element) + { + if (!$element->isSelected()) { + $element->click(); + } + } + + /** + * Deselects a checkbox or a radio button. + */ + protected function deselectOption(WebDriverElement $element) + { + if ($element->isSelected()) { + $element->click(); + } + } +} diff --git a/lib/WebDriverCheckboxes.php b/lib/WebDriverCheckboxes.php new file mode 100644 index 000000000..1ac00093d --- /dev/null +++ b/lib/WebDriverCheckboxes.php @@ -0,0 +1,66 @@ +type = $element->getAttribute('type'); + if ($this->type !== 'checkbox') { + throw new WebDriverException('The input must be of type "checkbox".'); + } + } + + public function isMultiple() + { + return true; + } + + public function deselectAll() + { + foreach ($this->getRelatedElements() as $checkbox) { + $this->deselectOption($checkbox); + } + } + + public function deselectByIndex($index) + { + $this->byIndex($index, false); + } + + public function deselectByValue($value) + { + $this->byValue($value, false); + } + + public function deselectByVisibleText($text) + { + $this->byVisibleText($text, false, false); + } + + public function deselectByVisiblePartialText($text) + { + $this->byVisibleText($text, true, false); + } +} diff --git a/lib/WebDriverRadios.php b/lib/WebDriverRadios.php new file mode 100644 index 000000000..d6a4d2ac7 --- /dev/null +++ b/lib/WebDriverRadios.php @@ -0,0 +1,65 @@ +type = $element->getAttribute('type'); + if ($this->type !== 'radio') { + throw new WebDriverException('The input must be of type "radio".'); + } + } + + public function isMultiple() + { + return false; + } + + public function deselectAll() + { + throw new UnsupportedOperationException('You cannot deselect radio buttons'); + } + + public function deselectByIndex($index) + { + throw new UnsupportedOperationException('You cannot deselect radio buttons'); + } + + public function deselectByValue($value) + { + throw new UnsupportedOperationException('You cannot deselect radio buttons'); + } + + public function deselectByVisibleText($text) + { + throw new UnsupportedOperationException('You cannot deselect radio buttons'); + } + + public function deselectByVisiblePartialText($text) + { + throw new UnsupportedOperationException('You cannot deselect radio buttons'); + } +} diff --git a/tests/functional/WebDriverCheckboxesTest.php b/tests/functional/WebDriverCheckboxesTest.php new file mode 100644 index 000000000..3bf8ccffd --- /dev/null +++ b/tests/functional/WebDriverCheckboxesTest.php @@ -0,0 +1,197 @@ +driver->get($this->getTestPageUrl('form_checkbox_radio.html')); + } + + public function testIsMultiple() + { + $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); + $this->assertTrue($c->isMultiple()); + } + + public function testGetOptions() + { + $c = new WebDriverCheckboxes( + $this->driver->findElement(WebDriverBy::xpath('//form[2]//input[@type="checkbox"]')) + ); + $this->assertNotEmpty($c->getOptions()); + } + + public function testGetFirstSelectedOption() + { + $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); + $c->selectByValue('j2a'); + $this->assertSame('j2a', $c->getFirstSelectedOption()->getAttribute('value')); + } + + public function testSelectByValue() + { + $selectedOptions = ['j2b', 'j2c']; + + $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); + foreach ($selectedOptions as $index => $selectedOption) { + $c->selectByValue($selectedOption); + } + + $selectedValues = []; + foreach ($c->getAllSelectedOptions() as $option) { + $selectedValues[] = $option->getAttribute('value'); + } + $this->assertSame($selectedOptions, $selectedValues); + } + + public function testSelectByValueInvalid() + { + $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); + + $this->expectException(NoSuchElementException::class); + $this->expectExceptionMessage('Cannot locate checkbox with value: notexist'); + $c->selectByValue('notexist'); + } + + public function testSelectByIndex() + { + $selectedOptions = [1 => 'j2b', 2 => 'j2c']; + + $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); + foreach ($selectedOptions as $index => $selectedOption) { + $c->selectByIndex($index); + } + + $selectedValues = []; + foreach ($c->getAllSelectedOptions() as $option) { + $selectedValues[] = $option->getAttribute('value'); + } + $this->assertSame(array_values($selectedOptions), $selectedValues); + } + + public function testSelectByIndexInvalid() + { + $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); + + $this->expectException(NoSuchElementException::class); + $this->expectExceptionMessage('Cannot locate checkbox with index: ' . PHP_INT_MAX); + $c->selectByIndex(PHP_INT_MAX); + } + + /** + * @dataProvider selectByVisibleTextDataProvider + * + * @param string $text + * @param string $value + */ + public function testSelectByVisibleText($text, $value) + { + $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); + $c->selectByVisibleText($text); + $this->assertSame($value, $c->getFirstSelectedOption()->getAttribute('value')); + } + + /** + * @return array + */ + public function selectByVisibleTextDataProvider() + { + return [ + ['J 2 B', 'j2b'], + ['J2C', 'j2c'], + ]; + } + + /** + * @dataProvider selectByVisiblePartialTextDataProvider + * + * @param string $text + * @param string $value + */ + public function testSelectByVisiblePartialText($text, $value) + { + $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); + $c->selectByVisiblePartialText($text); + $this->assertSame($value, $c->getFirstSelectedOption()->getAttribute('value')); + } + + /** + * @return array + */ + public function selectByVisiblePartialTextDataProvider() + { + return [ + ['2 B', 'j2b'], + ['2C', 'j2c'], + ]; + } + + public function testDeselectAll() + { + $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); + + $c->selectByIndex(0); + $this->assertCount(1, $c->getAllSelectedOptions()); + $c->deselectAll(); + $this->assertEmpty($c->getAllSelectedOptions()); + } + + public function testDeselectByIndex() + { + $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); + + $c->selectByIndex(0); + $this->assertCount(1, $c->getAllSelectedOptions()); + $c->deselectByIndex(0); + $this->assertEmpty($c->getAllSelectedOptions()); + } + + public function testDeselectByValue() + { + $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); + + $c->selectByValue('j2a'); + $this->assertCount(1, $c->getAllSelectedOptions()); + $c->deselectByValue('j2a'); + $this->assertEmpty($c->getAllSelectedOptions()); + } + + public function testDeselectByVisibleText() + { + $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); + + $c->selectByVisibleText('J 2 B'); + $this->assertCount(1, $c->getAllSelectedOptions()); + $c->deselectByVisibleText('J 2 B'); + $this->assertEmpty($c->getAllSelectedOptions()); + } + + public function testDeselectByVisiblePartialText() + { + $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); + + $c->selectByVisiblePartialText('2C'); + $this->assertCount(1, $c->getAllSelectedOptions()); + $c->deselectByVisiblePartialText('2C'); + $this->assertEmpty($c->getAllSelectedOptions()); + } +} diff --git a/tests/functional/WebDriverRadiosTest.php b/tests/functional/WebDriverRadiosTest.php new file mode 100644 index 000000000..f28417ac4 --- /dev/null +++ b/tests/functional/WebDriverRadiosTest.php @@ -0,0 +1,184 @@ +driver->get($this->getTestPageUrl('form_checkbox_radio.html')); + } + + public function testIsMultiple() + { + $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + $this->assertFalse($c->isMultiple()); + } + + public function testGetOptions() + { + $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + $values = []; + foreach ($c->getOptions() as $option) { + $values[] = $option->getAttribute('value'); + } + + $this->assertSame(['j3a', 'j3b', 'j3c'], $values); + } + + public function testGetFirstSelectedOption() + { + $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + $c->selectByValue('j3a'); + $this->assertSame('j3a', $c->getFirstSelectedOption()->getAttribute('value')); + } + + public function testSelectByValue() + { + $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + $c->selectByValue('j3b'); + + $selectedOptions = $c->getAllSelectedOptions(); + $this->assertCount(1, $selectedOptions); + $this->assertSame('j3b', $selectedOptions[0]->getAttribute('value')); + } + + public function testSelectByValueInvalid() + { + $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + + $this->expectException(NoSuchElementException::class); + $this->expectExceptionMessage('Cannot locate radio with value: notexist'); + $c->selectByValue('notexist'); + } + + public function testSelectByIndex() + { + $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + $c->selectByIndex(1); + + $allSelectedOptions = $c->getAllSelectedOptions(); + $this->assertCount(1, $allSelectedOptions); + $this->assertSame('j3b', $allSelectedOptions[0]->getAttribute('value')); + } + + public function testSelectByIndexInvalid() + { + $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + + $this->expectException(NoSuchElementException::class); + $this->expectExceptionMessage('Cannot locate radio with index: ' . PHP_INT_MAX); + $c->selectByIndex(PHP_INT_MAX); + } + + /** + * @dataProvider selectByVisibleTextDataProvider + * + * @param string $text + * @param string $value + */ + public function testSelectByVisibleText($text, $value) + { + $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + $c->selectByVisibleText($text); + $this->assertSame($value, $c->getFirstSelectedOption()->getAttribute('value')); + } + + /** + * @return array + */ + public function selectByVisibleTextDataProvider() + { + return [ + ['J 3 B', 'j3b'], + ['J3C', 'j3c'], + ]; + } + + /** + * @dataProvider selectByVisiblePartialTextDataProvider + * + * @param string $text + * @param string $value + */ + public function testSelectByVisiblePartialText($text, $value) + { + $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + $c->selectByVisiblePartialText($text); + $this->assertSame($value, $c->getFirstSelectedOption()->getAttribute('value')); + } + + /** + * @return array + */ + public function selectByVisiblePartialTextDataProvider() + { + return [ + ['3 B', 'j3b'], + ['3C', 'j3c'], + ]; + } + + public function testDeselectAllRadio() + { + $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + + $this->expectException(UnsupportedOperationException::class); + $this->expectExceptionMessage('You cannot deselect radio buttons'); + $c->deselectAll(); + } + + public function testDeselectByIndexRadio() + { + $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + + $this->expectException(UnsupportedOperationException::class); + $this->expectExceptionMessage('You cannot deselect radio buttons'); + $c->deselectByIndex(0); + } + + public function testDeselectByValueRadio() + { + $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + + $this->expectException(UnsupportedOperationException::class); + $this->expectExceptionMessage('You cannot deselect radio buttons'); + $c->deselectByValue('val'); + } + + public function testDeselectByVisibleTextRadio() + { + $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + + $this->expectException(UnsupportedOperationException::class); + $this->expectExceptionMessage('You cannot deselect radio buttons'); + $c->deselectByVisibleText('AB'); + } + + public function testDeselectByVisiblePartialTextRadio() + { + $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + + $this->expectException(UnsupportedOperationException::class); + $this->expectExceptionMessage('You cannot deselect radio buttons'); + $c->deselectByVisiblePartialText('AB'); + } +} diff --git a/tests/functional/web/form_checkbox_radio.html b/tests/functional/web/form_checkbox_radio.html new file mode 100644 index 000000000..b51dcfe47 --- /dev/null +++ b/tests/functional/web/form_checkbox_radio.html @@ -0,0 +1,43 @@ + + + + + Form + + + + + + + + + + + + + + + + + + + + + +
    + +
    + + From ce44465b74b1707a7e76b4f70f7d2fee6014ce94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 29 May 2018 15:17:26 +0200 Subject: [PATCH 415/784] Update changelog --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f3088da9..95a4c6c73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,8 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased - ---- +### Added +- `WebDriverCheckboxes` and `WebDriverRadios` helper classes to simplify interaction with checkboxes and radio buttons. ## 1.6.0 - 2018-05-16 ### Added From 37c7b04a453d88d79e41e8ac4425603a04d17fd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sat, 16 Jun 2018 14:26:38 +0200 Subject: [PATCH 416/784] Fix the name of a env var in CONTRIBUTING.md (#583) --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d7b93736c..1a01c7adb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,7 +42,7 @@ test suite: ./vendor/bin/phpunit --testsuite functional The functional tests will be started in HtmlUnit headless browser by default. If you want to run them in eg. Firefox, -simply set the `BROWSER` environment variable: +simply set the `BROWSER_NAME` environment variable: ... export BROWSER_NAME="firefox" From be2985897851adca3e941d8c07c28512e24ee4a1 Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Thu, 18 Oct 2018 13:53:38 -0700 Subject: [PATCH 417/784] Renamed license file. --- LICENCE.md => LICENSE.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename LICENCE.md => LICENSE.md (100%) diff --git a/LICENCE.md b/LICENSE.md similarity index 100% rename from LICENCE.md rename to LICENSE.md From e020ae2811098d55cce705c66c52f1a4fbf2f9df Mon Sep 17 00:00:00 2001 From: Fosco Marotto Date: Thu, 18 Oct 2018 13:58:23 -0700 Subject: [PATCH 418/784] Added copyright headers to 2 codefiles --- example.php | 14 ++++++++++++++ tests/bootstrap.php | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/example.php b/example.php index 2a9d0b298..f1109ed54 100644 --- a/example.php +++ b/example.php @@ -1,4 +1,18 @@ Date: Thu, 18 Oct 2018 14:14:22 -0700 Subject: [PATCH 419/784] Added a few more copyright headers. --- lib/Exception/IndexOutOfBoundsException.php | 13 +++++++++++++ lib/Exception/NoCollectionException.php | 13 +++++++++++++ lib/Exception/NoStringException.php | 13 +++++++++++++ lib/WebDriverSelectInterface.php | 13 +++++++++++++ tests/functional/web/slow_pixel.png.php | 13 +++++++++++++ tests/functional/web/submit.php | 16 +++++++++++++++- tests/functional/web/upload.php | 16 +++++++++++++++- 7 files changed, 95 insertions(+), 2 deletions(-) diff --git a/lib/Exception/IndexOutOfBoundsException.php b/lib/Exception/IndexOutOfBoundsException.php index ad52d21e9..de166b61e 100644 --- a/lib/Exception/IndexOutOfBoundsException.php +++ b/lib/Exception/IndexOutOfBoundsException.php @@ -1,4 +1,17 @@ + diff --git a/tests/functional/web/upload.php b/tests/functional/web/upload.php index 91a61bbcf..0bac36c3a 100644 --- a/tests/functional/web/upload.php +++ b/tests/functional/web/upload.php @@ -1,4 +1,18 @@ - + From 799fc83fb9bb0f61bfcb725db336a955774c22c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Thu, 6 Jun 2019 18:10:13 +0200 Subject: [PATCH 420/784] Improve test stability on SauceLabs; simplify doubleClick test to make it temporarily, as this action is not part of W3C WebDriver --- .travis.yml | 2 +- tests/functional/RemoteWebDriverTest.php | 26 +++++++++++++++------- tests/functional/WebDriverActionsTest.php | 5 +---- tests/functional/WebDriverTestCase.php | 4 ++-- tests/functional/WebDriverTimeoutsTest.php | 4 ++-- tests/functional/web/delayed_element.html | 2 +- 6 files changed, 25 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4a2cada83..a268f0b4d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -58,7 +58,7 @@ matrix: jwt: secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= - php: 7.2 - env: SAUCELABS=1 BROWSER_NAME="MicrosoftEdge" VERSION="15.15063" PLATFORM="Windows 10" + env: SAUCELABS=1 BROWSER_NAME="MicrosoftEdge" VERSION="16.16299" PLATFORM="Windows 10" before_script: - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & - until $(echo | nc localhost 8000); do sleep 1; echo waiting for PHP server on port 8000...; done; echo "PHP server started" diff --git a/tests/functional/RemoteWebDriverTest.php b/tests/functional/RemoteWebDriverTest.php index 818a9da5a..d996d304a 100644 --- a/tests/functional/RemoteWebDriverTest.php +++ b/tests/functional/RemoteWebDriverTest.php @@ -145,6 +145,7 @@ public function testShouldCloseWindow() /** * @covers ::executeScript + * @group exclude-saucelabs */ public function testShouldExecuteScriptAndDoNotBlockExecution() { @@ -153,17 +154,18 @@ public function testShouldExecuteScriptAndDoNotBlockExecution() $element = $this->driver->findElement(WebDriverBy::id('id_test')); $this->assertSame('Test by ID', $element->getText()); + $start = microtime(true); $this->driver->executeScript(' setTimeout( - function(){document.getElementById("id_test").innerHTML = "Text changed by script"}, - 500 + function(){document.getElementById("id_test").innerHTML = "Text changed by script";}, + 250 )'); + $end = microtime(true); - // Make sure the script don't block the test execution - $this->assertSame('Test by ID', $element->getText()); + $this->assertLessThan(250, $end - $start, 'executeScript() should not block execution'); - // If we wait, the script should be executed - usleep(1000000); // wait 1000 ms + // If we wait, the script should be executed and its value changed + usleep(300000); // wait 300 ms $this->assertSame('Text changed by script', $element->getText()); } @@ -180,6 +182,7 @@ public function testShouldExecuteAsyncScriptAndWaitUntilItIsFinished() $element = $this->driver->findElement(WebDriverBy::id('id_test')); $this->assertSame('Test by ID', $element->getText()); + $start = microtime(true); $this->driver->executeAsyncScript( 'var callback = arguments[arguments.length - 1]; setTimeout( @@ -190,6 +193,13 @@ function(){ 250 );' ); + $end = microtime(true); + + $this->assertGreaterThan( + 0.250, + $end - $start, + 'executeAsyncScript() should block execution until callback() is called' + ); // The result must be immediately available, as the executeAsyncScript should block the execution until the // callback is called. @@ -204,7 +214,7 @@ public function testShouldTakeScreenshot() if (!extension_loaded('gd')) { $this->markTestSkipped('GD extension must be enabled'); } - if ($this->desiredCapabilities->getBrowserName() == WebDriverBrowserType::HTMLUNIT) { + if ($this->desiredCapabilities->getBrowserName() === WebDriverBrowserType::HTMLUNIT) { $this->markTestSkipped('Screenshots are not supported by HtmlUnit browser'); } @@ -227,7 +237,7 @@ public function testShouldSaveScreenshotToFile() if (!extension_loaded('gd')) { $this->markTestSkipped('GD extension must be enabled'); } - if ($this->desiredCapabilities->getBrowserName() == WebDriverBrowserType::HTMLUNIT) { + if ($this->desiredCapabilities->getBrowserName() === WebDriverBrowserType::HTMLUNIT) { $this->markTestSkipped('Screenshots are not supported by HtmlUnit browser'); } diff --git a/tests/functional/WebDriverActionsTest.php b/tests/functional/WebDriverActionsTest.php index 188c76cd9..3df984810 100644 --- a/tests/functional/WebDriverActionsTest.php +++ b/tests/functional/WebDriverActionsTest.php @@ -122,10 +122,7 @@ public function testShouldDoubleClickOnElement() ->doubleClick($element) ->perform(); - $this->assertSame( - ['mouseover item-3', 'mousedown item-3', 'mouseup item-3', 'click item-3', 'dblclick item-3'], - $this->retrieveLoggedEvents() - ); + $this->assertContains('dblclick item-3', $this->retrieveLoggedEvents()); } /** diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index e9714a87c..5fe6a7e8a 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -44,7 +44,7 @@ protected function setUp() { $this->desiredCapabilities = new DesiredCapabilities(); - if ($this->isSauceLabsBuild()) { + if (static::isSauceLabsBuild()) { $this->setUpSauceLabs(); } else { if (getenv('BROWSER_NAME')) { @@ -87,7 +87,7 @@ protected function tearDown() /** * @return bool */ - public function isSauceLabsBuild() + public static function isSauceLabsBuild() { return getenv('SAUCELABS') ? true : false; } diff --git a/tests/functional/WebDriverTimeoutsTest.php b/tests/functional/WebDriverTimeoutsTest.php index 69d143cc4..733be545c 100644 --- a/tests/functional/WebDriverTimeoutsTest.php +++ b/tests/functional/WebDriverTimeoutsTest.php @@ -42,7 +42,7 @@ public function testShouldGetDelayedElementWithImplicitWait() { $this->driver->get($this->getTestPageUrl('delayed_element.html')); - $this->driver->manage()->timeouts()->implicitlyWait(1); + $this->driver->manage()->timeouts()->implicitlyWait(2); $element = $this->driver->findElement(WebDriverBy::id('delayed')); $this->assertInstanceOf(RemoteWebElement::class, $element); @@ -54,7 +54,7 @@ public function testShouldGetDelayedElementWithImplicitWait() */ public function testShouldFailIfPageIsLoadingLongerThanPageLoadTimeout() { - if ($this->desiredCapabilities->getBrowserName() == WebDriverBrowserType::HTMLUNIT) { + if ($this->desiredCapabilities->getBrowserName() === WebDriverBrowserType::HTMLUNIT) { $this->markTestSkipped('Not supported by HtmlUnit browser'); } diff --git a/tests/functional/web/delayed_element.html b/tests/functional/web/delayed_element.html index b0f057a9a..4572cd342 100644 --- a/tests/functional/web/delayed_element.html +++ b/tests/functional/web/delayed_element.html @@ -12,7 +12,7 @@ setTimeout(function () { var wrapper = document.getElementById("wrapper"); wrapper.innerHTML = '
    Element appearing after 500ms
    '; - }, 500); + }, 1500); From 6d488eacd23db77822a748725a1c9dafa6d0221e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 8 Jun 2019 12:33:18 +0200 Subject: [PATCH 421/784] Force Chrome 74 on saucelabs, as 75 uses W3C protocol by default --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a268f0b4d..c97b22525 100644 --- a/.travis.yml +++ b/.travis.yml @@ -49,7 +49,7 @@ matrix: jwt: secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= - php: 7.2 - env: SAUCELABS=1 BROWSER_NAME="chrome" VERSION="latest" PLATFORM="Windows 10" + env: SAUCELABS=1 BROWSER_NAME="chrome" VERSION="74.0" PLATFORM="Windows 10" before_script: - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & - until $(echo | nc localhost 8000); do sleep 1; echo waiting for PHP server on port 8000...; done; echo "PHP server started" From 5f7a311bde888283615e8b3767a92302c5e29515 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 7 Jun 2019 17:29:22 +0200 Subject: [PATCH 422/784] Use PHP 7.3 as the main PHP version for travis builds --- .travis.yml | 55 +++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/.travis.yml b/.travis.yml index c97b22525..082a6efb8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,10 +3,11 @@ sudo: false dist: trusty php: - - 5.6 - - 7.0 - - 7.1 - - 7.2 + - '5.6' + - '7.0' + - '7.1' + - '7.2' + - '7.3' env: global: @@ -16,30 +17,43 @@ env: matrix: include: + # Codestyle check build + - php: '7.3' + env: CHECK_CODESTYLE=1 + before_install: + - phpenv config-rm xdebug.ini + before_script: ~ + script: + - composer require phpstan/phpstan-shim # Not part of require-dev, because it won't install on PHP 5.6 + - composer analyze + - composer codestyle:check + after_script: ~ + after_success: ~ + + # Build with lowest possible dependencies on lowest possible PHP + - php: '5.6' + env: DEPENDENCIES="--prefer-lowest" + # Add build to run tests against Firefox inside Travis environment - - php: 7.2 + - php: '7.3' env: BROWSER_NAME="firefox" addons: firefox: "45.8.0esr" # Add build to run tests against Chrome inside Travis environment - - php: 7.2 + - php: '7.3' env: BROWSER_NAME="chrome" CHROME_HEADLESS="1" addons: chrome: stable - # Build with lowest possible dependencies - - php: 7.2 - env: DEPENDENCIES="--prefer-lowest" - # Chrome on Travis build with lowest possible dependencies - - php: 7.2 + - php: '7.3' env: BROWSER_NAME="chrome" CHROME_HEADLESS="1" DEPENDENCIES="--prefer-lowest" addons: chrome: stable # Saucelabs builds - - php: 7.2 + - php: '7.3' env: SAUCELABS=1 BROWSER_NAME="firefox" VERSION="47.0" PLATFORM="Windows 10" before_script: - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & @@ -48,7 +62,7 @@ matrix: sauce_connect: true jwt: secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= - - php: 7.2 + - php: '7.3' env: SAUCELABS=1 BROWSER_NAME="chrome" VERSION="74.0" PLATFORM="Windows 10" before_script: - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & @@ -57,7 +71,7 @@ matrix: sauce_connect: true jwt: secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= - - php: 7.2 + - php: '7.3' env: SAUCELABS=1 BROWSER_NAME="MicrosoftEdge" VERSION="16.16299" PLATFORM="Windows 10" before_script: - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & @@ -67,19 +81,6 @@ matrix: jwt: secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= - # Codestyle check build - - php: 7.2 - env: CHECK_CODESTYLE=1 - before_install: - - phpenv config-rm xdebug.ini - before_script: ~ - script: - - composer require phpstan/phpstan-shim # Not part of require-dev, because it won't install on PHP 5.6 - - composer analyze - - composer codestyle:check - after_script: ~ - after_success: ~ - cache: directories: - $HOME/.composer/cache From 242fffeb4caf279a87f75a01b29a87e66a3e1a74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 8 Jun 2019 15:02:51 +0200 Subject: [PATCH 423/784] Disable WebDriverSelectTest on saucelabs - it is too slow and has minimal value --- tests/functional/WebDriverCheckboxesTest.php | 4 ++++ tests/functional/WebDriverRadiosTest.php | 4 ++++ tests/functional/WebDriverSelectTest.php | 1 + 3 files changed, 9 insertions(+) diff --git a/tests/functional/WebDriverCheckboxesTest.php b/tests/functional/WebDriverCheckboxesTest.php index 3bf8ccffd..128d298d5 100644 --- a/tests/functional/WebDriverCheckboxesTest.php +++ b/tests/functional/WebDriverCheckboxesTest.php @@ -17,6 +17,10 @@ use Facebook\WebDriver\Exception\NoSuchElementException; +/** + * @covers \Facebook\WebDriver\WebDriverCheckboxes + * @covers \Facebook\WebDriver\AbstractWebDriverCheckboxOrRadio + */ class WebDriverCheckboxesTest extends WebDriverTestCase { protected function setUp() diff --git a/tests/functional/WebDriverRadiosTest.php b/tests/functional/WebDriverRadiosTest.php index f28417ac4..2a1a9869d 100644 --- a/tests/functional/WebDriverRadiosTest.php +++ b/tests/functional/WebDriverRadiosTest.php @@ -18,6 +18,10 @@ use Facebook\WebDriver\Exception\NoSuchElementException; use Facebook\WebDriver\Exception\UnsupportedOperationException; +/** + * @covers \Facebook\WebDriver\WebDriverRadios + * @covers \Facebook\WebDriver\AbstractWebDriverCheckboxOrRadio + */ class WebDriverRadiosTest extends WebDriverTestCase { protected function setUp() diff --git a/tests/functional/WebDriverSelectTest.php b/tests/functional/WebDriverSelectTest.php index 37ad416af..b25dd03af 100644 --- a/tests/functional/WebDriverSelectTest.php +++ b/tests/functional/WebDriverSelectTest.php @@ -20,6 +20,7 @@ use Facebook\WebDriver\Exception\UnsupportedOperationException; /** + * @group exclude-saucelabs * @covers \Facebook\WebDriver\WebDriverSelect * @covers \Facebook\WebDriver\Exception\UnexpectedTagNameException */ From 9be6cbbd8006a24fb180df75cb4b9796a2aad770 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 8 Jun 2019 15:42:49 +0200 Subject: [PATCH 424/784] Remove mostly redundant second lowest-deps build --- .travis.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 082a6efb8..b3ee784e8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -46,12 +46,6 @@ matrix: addons: chrome: stable - # Chrome on Travis build with lowest possible dependencies - - php: '7.3' - env: BROWSER_NAME="chrome" CHROME_HEADLESS="1" DEPENDENCIES="--prefer-lowest" - addons: - chrome: stable - # Saucelabs builds - php: '7.3' env: SAUCELABS=1 BROWSER_NAME="firefox" VERSION="47.0" PLATFORM="Windows 10" From 0f3933c41606fd076d79ff064bc0def2b774e67d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 8 Jun 2019 22:50:56 +0200 Subject: [PATCH 425/784] Disable default W3C protocol in Chrome 75+ --- .travis.yml | 27 ++++++++++++++++++++++----- lib/Remote/HttpCommandExecutor.php | 5 +++++ lib/Remote/RemoteWebDriver.php | 14 ++++++++++++++ 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index b3ee784e8..b6850baf1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,6 @@ env: global: - DISPLAY=:99.0 - BROWSER_NAME="htmlunit" - - CHROMEDRIVER_VERSION="2.38" matrix: include: @@ -34,15 +33,21 @@ matrix: - php: '5.6' env: DEPENDENCIES="--prefer-lowest" - # Add build to run tests against Firefox inside Travis environment + # Firefox inside Travis environment - php: '7.3' env: BROWSER_NAME="firefox" addons: firefox: "45.8.0esr" - # Add build to run tests against Chrome inside Travis environment + # Stable Chrome + Chromedriver 74 inside Travis environment - php: '7.3' - env: BROWSER_NAME="chrome" CHROME_HEADLESS="1" + env: BROWSER_NAME="chrome" CHROME_HEADLESS="1" CHROMEDRIVER_VERSION="74.0.3729.6" + addons: + chrome: stable + + # Stable Chrome + Chromedriver 75+ inside Travis environment + - php: '7.3' + env: BROWSER_NAME="chrome" CHROME_HEADLESS="1" CHROMEDRIVER_VERSION="75.0.3770.8" addons: chrome: stable @@ -56,8 +61,9 @@ matrix: sauce_connect: true jwt: secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= + - php: '7.3' - env: SAUCELABS=1 BROWSER_NAME="chrome" VERSION="74.0" PLATFORM="Windows 10" + env: SAUCELABS=1 BROWSER_NAME="chrome" VERSION="74.0" PLATFORM="Windows 10" # 74 is the last version which don't use W3C WebDriver by default before_script: - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & - until $(echo | nc localhost 8000); do sleep 1; echo waiting for PHP server on port 8000...; done; echo "PHP server started" @@ -65,6 +71,17 @@ matrix: sauce_connect: true jwt: secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= + + - php: '7.3' + env: SAUCELABS=1 BROWSER_NAME="chrome" VERSION="75.0" PLATFORM="Windows 10" + before_script: + - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & + - until $(echo | nc localhost 8000); do sleep 1; echo waiting for PHP server on port 8000...; done; echo "PHP server started" + addons: + sauce_connect: true + jwt: + secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= + - php: '7.3' env: SAUCELABS=1 BROWSER_NAME="MicrosoftEdge" VERSION="16.16299" PLATFORM="Windows 10" before_script: diff --git a/lib/Remote/HttpCommandExecutor.php b/lib/Remote/HttpCommandExecutor.php index f584324b7..1891fdb35 100644 --- a/lib/Remote/HttpCommandExecutor.php +++ b/lib/Remote/HttpCommandExecutor.php @@ -273,6 +273,11 @@ public function execute(WebDriverCommand $command) if ($http_method === 'POST' && $params && is_array($params)) { $encoded_params = json_encode($params); + } elseif ($http_method === 'POST' && $encoded_params === null) { + // Workaround for bug https://bugs.chromium.org/p/chromedriver/issues/detail?id=2943 in Chrome 75. + // Chromedriver now erroneously does not allow POST body to be empty even for the JsonWire protocol. + // If the command POST is empty, here we send some dummy data as a workaround: + $encoded_params = json_encode(['_' => '_']); } curl_setopt($this->curl, CURLOPT_POSTFIELDS, $encoded_params); diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index 1487689ec..538ae282f 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -15,6 +15,7 @@ namespace Facebook\WebDriver\Remote; +use Facebook\WebDriver\Chrome\ChromeOptions; use Facebook\WebDriver\Interactions\WebDriverActions; use Facebook\WebDriver\JavaScriptExecutor; use Facebook\WebDriver\WebDriver; @@ -102,6 +103,19 @@ public static function create( $desired_capabilities = self::castToDesiredCapabilitiesObject($desired_capabilities); + // Hotfix: W3C WebDriver protocol is not yet supported by php-webdriver, so we must force Chromedriver to + // not use the W3C protocol by default (which is what Chromedriver does starting with version 75). + if ($desired_capabilities->getBrowserName() === WebDriverBrowserType::CHROME) { + $currentChromeOptions = $desired_capabilities->getCapability(ChromeOptions::CAPABILITY); + $chromeOptions = !empty($currentChromeOptions) ? $currentChromeOptions : new ChromeOptions(); + + if (!isset($chromeOptions->toArray()['w3c'])) { + $chromeOptions->setExperimentalOption('w3c', false); + } + + $desired_capabilities->setCapability(ChromeOptions::CAPABILITY, $chromeOptions); + } + $executor = new HttpCommandExecutor($selenium_server_url, $http_proxy, $http_proxy_port); if ($connection_timeout_in_ms !== null) { $executor->setConnectionTimeout($connection_timeout_in_ms); From 550edf5a815694f60654a0a82d0bbe818eeb1514 Mon Sep 17 00:00:00 2001 From: JorisVanEijden Date: Mon, 25 Feb 2019 12:38:04 +0100 Subject: [PATCH 426/784] Do not send null values in cookie array (fixes #626) --- lib/Cookie.php | 50 ++++++++++++++++++++------------------- tests/unit/CookieTest.php | 22 +++++++++++++++++ 2 files changed, 48 insertions(+), 24 deletions(-) diff --git a/lib/Cookie.php b/lib/Cookie.php index 57ec7e13a..216ac3033 100644 --- a/lib/Cookie.php +++ b/lib/Cookie.php @@ -27,15 +27,7 @@ class Cookie implements \ArrayAccess { /** @var array */ - protected $cookie = [ - 'name' => null, - 'value' => null, - 'path' => null, - 'domain' => null, - 'expiry' => null, - 'secure' => null, - 'httpOnly' => null, - ]; + protected $cookie = []; /** * @param string $name The name of the cookie; may not be null or an empty string. @@ -51,11 +43,17 @@ public function __construct($name, $value) } /** - * @param array $cookieArray + * @param array $cookieArray The cookie fields; must contain name and value. * @return Cookie */ public static function createFromArray(array $cookieArray) { + if (!isset($cookieArray['name'])) { + throw new InvalidArgumentException('Cookie name should be set'); + } + if (!isset($cookieArray['value'])) { + throw new InvalidArgumentException('Cookie value should be set'); + } $cookie = new self($cookieArray['name'], $cookieArray['value']); if (isset($cookieArray['path'])) { @@ -82,7 +80,7 @@ public static function createFromArray(array $cookieArray) */ public function getName() { - return $this->cookie['name']; + return $this->offsetGet('name'); } /** @@ -90,7 +88,7 @@ public function getName() */ public function getValue() { - return $this->cookie['value']; + return $this->offsetGet('value'); } /** @@ -100,7 +98,7 @@ public function getValue() */ public function setPath($path) { - $this->cookie['path'] = $path; + $this->offsetSet('path', $path); } /** @@ -108,7 +106,7 @@ public function setPath($path) */ public function getPath() { - return $this->cookie['path']; + return $this->offsetGet('path'); } /** @@ -122,7 +120,7 @@ public function setDomain($domain) throw new InvalidArgumentException(sprintf('Cookie domain "%s" should not contain a port', $domain)); } - $this->cookie['domain'] = $domain; + $this->offsetSet('domain', $domain); } /** @@ -130,7 +128,7 @@ public function setDomain($domain) */ public function getDomain() { - return $this->cookie['domain']; + return $this->offsetGet('domain'); } /** @@ -140,7 +138,7 @@ public function getDomain() */ public function setExpiry($expiry) { - $this->cookie['expiry'] = (int) $expiry; + $this->offsetSet('expiry', (int) $expiry); } /** @@ -148,7 +146,7 @@ public function setExpiry($expiry) */ public function getExpiry() { - return $this->cookie['expiry']; + return $this->offsetGet('expiry'); } /** @@ -158,7 +156,7 @@ public function getExpiry() */ public function setSecure($secure) { - $this->cookie['secure'] = $secure; + $this->offsetSet('secure', $secure); } /** @@ -166,7 +164,7 @@ public function setSecure($secure) */ public function isSecure() { - return $this->cookie['secure']; + return $this->offsetGet('secure'); } /** @@ -176,7 +174,7 @@ public function isSecure() */ public function setHttpOnly($httpOnly) { - $this->cookie['httpOnly'] = $httpOnly; + $this->offsetSet('httpOnly', $httpOnly); } /** @@ -184,7 +182,7 @@ public function setHttpOnly($httpOnly) */ public function isHttpOnly() { - return $this->cookie['httpOnly']; + return $this->offsetGet('httpOnly'); } /** @@ -202,12 +200,16 @@ public function offsetExists($offset) public function offsetGet($offset) { - return $this->cookie[$offset]; + return $this->offsetExists($offset) ? $this->cookie[$offset] : null; } public function offsetSet($offset, $value) { - $this->cookie[$offset] = $value; + if ($value === null) { + unset($this->cookie[$offset]); + } else { + $this->cookie[$offset] = $value; + } } public function offsetUnset($offset) diff --git a/tests/unit/CookieTest.php b/tests/unit/CookieTest.php index 3a0679d2c..5fdb43038 100644 --- a/tests/unit/CookieTest.php +++ b/tests/unit/CookieTest.php @@ -62,6 +62,28 @@ public function testShouldBeConvertibleToArray(Cookie $cookie) ); } + /** + * Test that there are no null values in the cookie array. + * + * Both JsonWireProtocol and w3c protocol say to leave an entry off + * rather than having a null value. + * + * https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol + * https://w3c.github.io/webdriver/#add-cookie + */ + public function testShouldNotContainNullValues() + { + $cookie = new Cookie('cookieName', 'someValue'); + + $cookie->setHttpOnly(null); + $cookie->setPath(null); + $cookieArray = $cookie->toArray(); + + foreach ($cookieArray as $key => $value) { + $this->assertNotNull($value, $key . ' should not be null'); + } + } + /** * @depends testShouldSetAllProperties * @param Cookie $cookie From d1ad0b14b4f34f3d3eca10c1587b991f612e6746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Mon, 10 Jun 2019 13:28:48 +0200 Subject: [PATCH 427/784] Update changelog --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95a4c6c73..e27bd1b89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ### Added - `WebDriverCheckboxes` and `WebDriverRadios` helper classes to simplify interaction with checkboxes and radio buttons. +### Fixed +- Stop sending null values in Cookie object, which is against the protocol and may cause request to remote ends to fail. + +### Changed +- Force Chrome to not use W3C WebDriver protocol. +- Add workaround for Chromedriver bug [2943](https://bugs.chromium.org/p/chromedriver/issues/detail?id=2943) which breaks the protocol in Chromedriver 75. + ## 1.6.0 - 2018-05-16 ### Added - Connection and request timeouts could be specified also when creating RemoteWebDriver from existing session ID. From 12ac107aba8af2cc08c549884f5a5844899509e9 Mon Sep 17 00:00:00 2001 From: Oleg Andreyev Date: Mon, 31 Dec 2018 02:23:12 +0200 Subject: [PATCH 428/784] Improved xpath matching related elements to handle input associated to different
    Added @form attribute check, because it's possible to put into a form which is not related to it, see MDN https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#form --- lib/AbstractWebDriverCheckboxOrRadio.php | 17 +++++++++++------ tests/functional/WebDriverCheckboxesTest.php | 6 ++++++ tests/functional/WebDriverRadiosTest.php | 6 ++++++ tests/functional/web/form_checkbox_radio.html | 14 +++++++++++++- 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/lib/AbstractWebDriverCheckboxOrRadio.php b/lib/AbstractWebDriverCheckboxOrRadio.php index 46288592b..f70a2ef04 100644 --- a/lib/AbstractWebDriverCheckboxOrRadio.php +++ b/lib/AbstractWebDriverCheckboxOrRadio.php @@ -218,12 +218,17 @@ protected function getRelatedElements($value = null) } } - return $this->element->findElements(WebDriverBy::xpath(sprintf( - '//form[@id = %1$s]//input[@name = %2$s%3$s] | //input[@form = %1$s and @name = %2$s%3$s]', - XPathEscaper::escapeQuotes($formId), - XPathEscaper::escapeQuotes($this->name), - $valueSelector - ))); + // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#form + return $this->element->findElements( + WebDriverBy::xpath(sprintf( + '//form[@id = %1$s]//input[@name = %2$s%3$s' + . ' and ((boolean(@form) = true() and @form = %1$s) or boolean(@form) = false())]' + . ' | //input[@form = %1$s and @name = %2$s%3$s]', + XPathEscaper::escapeQuotes($formId), + XPathEscaper::escapeQuotes($this->name), + $valueSelector + )) + ); } /** diff --git a/tests/functional/WebDriverCheckboxesTest.php b/tests/functional/WebDriverCheckboxesTest.php index 128d298d5..f7e1407b6 100644 --- a/tests/functional/WebDriverCheckboxesTest.php +++ b/tests/functional/WebDriverCheckboxesTest.php @@ -51,6 +51,12 @@ public function testGetFirstSelectedOption() $this->assertSame('j2a', $c->getFirstSelectedOption()->getAttribute('value')); } + public function testGetFirstSelectedOptionWithSameNameDifferentForm() + { + $radio = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@id="j5b"]'))); + $this->assertEquals('j5b', $radio->getFirstSelectedOption()->getAttribute('value')); + } + public function testSelectByValue() { $selectedOptions = ['j2b', 'j2c']; diff --git a/tests/functional/WebDriverRadiosTest.php b/tests/functional/WebDriverRadiosTest.php index 2a1a9869d..369717eb2 100644 --- a/tests/functional/WebDriverRadiosTest.php +++ b/tests/functional/WebDriverRadiosTest.php @@ -55,6 +55,12 @@ public function testGetFirstSelectedOption() $this->assertSame('j3a', $c->getFirstSelectedOption()->getAttribute('value')); } + public function testGetFirstSelectedOptionWithSameNameDifferentForm() + { + $radio = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@id="j4b"]'))); + $this->assertEquals('j4b', $radio->getFirstSelectedOption()->getAttribute('value')); + } + public function testSelectByValue() { $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); diff --git a/tests/functional/web/form_checkbox_radio.html b/tests/functional/web/form_checkbox_radio.html index b51dcfe47..1e13d74e4 100644 --- a/tests/functional/web/form_checkbox_radio.html +++ b/tests/functional/web/form_checkbox_radio.html @@ -27,6 +27,12 @@ + + + + + +
    @@ -36,7 +42,13 @@ -
    + + + + + + +
    From 87f9d0f4dbaf8ecf7c87415cccd3f00ea9e0311c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Mon, 10 Jun 2019 13:06:00 +0200 Subject: [PATCH 429/784] Improve readability of tests by structuring theme more in arrange-act-assert way --- tests/functional/WebDriverCheckboxesTest.php | 139 +++++++++++------- tests/functional/WebDriverRadiosTest.php | 73 ++++----- tests/functional/web/form_checkbox_radio.html | 18 ++- 3 files changed, 137 insertions(+), 93 deletions(-) diff --git a/tests/functional/WebDriverCheckboxesTest.php b/tests/functional/WebDriverCheckboxesTest.php index f7e1407b6..a37fde342 100644 --- a/tests/functional/WebDriverCheckboxesTest.php +++ b/tests/functional/WebDriverCheckboxesTest.php @@ -32,42 +32,55 @@ protected function setUp() public function testIsMultiple() { - $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); - $this->assertTrue($c->isMultiple()); + $checkboxes = new WebDriverCheckboxes( + $this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]')) + ); + + $this->assertTrue($checkboxes->isMultiple()); } public function testGetOptions() { - $c = new WebDriverCheckboxes( + $checkboxes = new WebDriverCheckboxes( $this->driver->findElement(WebDriverBy::xpath('//form[2]//input[@type="checkbox"]')) ); - $this->assertNotEmpty($c->getOptions()); + + $this->assertNotEmpty($checkboxes->getOptions()); } public function testGetFirstSelectedOption() { - $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); - $c->selectByValue('j2a'); - $this->assertSame('j2a', $c->getFirstSelectedOption()->getAttribute('value')); + $checkboxes = new WebDriverCheckboxes( + $this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]')) + ); + + $checkboxes->selectByValue('j2a'); + + $this->assertSame('j2a', $checkboxes->getFirstSelectedOption()->getAttribute('value')); } - public function testGetFirstSelectedOptionWithSameNameDifferentForm() + public function testShouldGetFirstSelectedOptionConsideringOnlyElementsAssociatedWithCurrentForm() { - $radio = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@id="j5b"]'))); - $this->assertEquals('j5b', $radio->getFirstSelectedOption()->getAttribute('value')); + $checkboxes = new WebDriverCheckboxes( + $this->driver->findElement(WebDriverBy::xpath('//input[@id="j5b"]')) + ); + + $this->assertEquals('j5b', $checkboxes->getFirstSelectedOption()->getAttribute('value')); } public function testSelectByValue() { $selectedOptions = ['j2b', 'j2c']; - $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); + $checkboxes = new WebDriverCheckboxes( + $this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]')) + ); foreach ($selectedOptions as $index => $selectedOption) { - $c->selectByValue($selectedOption); + $checkboxes->selectByValue($selectedOption); } $selectedValues = []; - foreach ($c->getAllSelectedOptions() as $option) { + foreach ($checkboxes->getAllSelectedOptions() as $option) { $selectedValues[] = $option->getAttribute('value'); } $this->assertSame($selectedOptions, $selectedValues); @@ -75,24 +88,28 @@ public function testSelectByValue() public function testSelectByValueInvalid() { - $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); + $checkboxes = new WebDriverCheckboxes( + $this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]')) + ); $this->expectException(NoSuchElementException::class); $this->expectExceptionMessage('Cannot locate checkbox with value: notexist'); - $c->selectByValue('notexist'); + $checkboxes->selectByValue('notexist'); } public function testSelectByIndex() { $selectedOptions = [1 => 'j2b', 2 => 'j2c']; - $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); + $checkboxes = new WebDriverCheckboxes( + $this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]')) + ); foreach ($selectedOptions as $index => $selectedOption) { - $c->selectByIndex($index); + $checkboxes->selectByIndex($index); } $selectedValues = []; - foreach ($c->getAllSelectedOptions() as $option) { + foreach ($checkboxes->getAllSelectedOptions() as $option) { $selectedValues[] = $option->getAttribute('value'); } $this->assertSame(array_values($selectedOptions), $selectedValues); @@ -100,11 +117,13 @@ public function testSelectByIndex() public function testSelectByIndexInvalid() { - $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); + $checkboxes = new WebDriverCheckboxes( + $this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]')) + ); $this->expectException(NoSuchElementException::class); $this->expectExceptionMessage('Cannot locate checkbox with index: ' . PHP_INT_MAX); - $c->selectByIndex(PHP_INT_MAX); + $checkboxes->selectByIndex(PHP_INT_MAX); } /** @@ -115,9 +134,13 @@ public function testSelectByIndexInvalid() */ public function testSelectByVisibleText($text, $value) { - $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); - $c->selectByVisibleText($text); - $this->assertSame($value, $c->getFirstSelectedOption()->getAttribute('value')); + $checkboxes = new WebDriverCheckboxes( + $this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]')) + ); + + $checkboxes->selectByVisibleText($text); + + $this->assertSame($value, $checkboxes->getFirstSelectedOption()->getAttribute('value')); } /** @@ -139,9 +162,13 @@ public function selectByVisibleTextDataProvider() */ public function testSelectByVisiblePartialText($text, $value) { - $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); - $c->selectByVisiblePartialText($text); - $this->assertSame($value, $c->getFirstSelectedOption()->getAttribute('value')); + $checkboxes = new WebDriverCheckboxes( + $this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]')) + ); + + $checkboxes->selectByVisiblePartialText($text); + + $this->assertSame($value, $checkboxes->getFirstSelectedOption()->getAttribute('value')); } /** @@ -157,51 +184,61 @@ public function selectByVisiblePartialTextDataProvider() public function testDeselectAll() { - $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); + $checkboxes = new WebDriverCheckboxes( + $this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]')) + ); - $c->selectByIndex(0); - $this->assertCount(1, $c->getAllSelectedOptions()); - $c->deselectAll(); - $this->assertEmpty($c->getAllSelectedOptions()); + $checkboxes->selectByIndex(0); + $this->assertCount(1, $checkboxes->getAllSelectedOptions()); + $checkboxes->deselectAll(); + $this->assertEmpty($checkboxes->getAllSelectedOptions()); } public function testDeselectByIndex() { - $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); + $checkboxes = new WebDriverCheckboxes( + $this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]')) + ); - $c->selectByIndex(0); - $this->assertCount(1, $c->getAllSelectedOptions()); - $c->deselectByIndex(0); - $this->assertEmpty($c->getAllSelectedOptions()); + $checkboxes->selectByIndex(0); + $this->assertCount(1, $checkboxes->getAllSelectedOptions()); + $checkboxes->deselectByIndex(0); + $this->assertEmpty($checkboxes->getAllSelectedOptions()); } public function testDeselectByValue() { - $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); + $checkboxes = new WebDriverCheckboxes( + $this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]')) + ); - $c->selectByValue('j2a'); - $this->assertCount(1, $c->getAllSelectedOptions()); - $c->deselectByValue('j2a'); - $this->assertEmpty($c->getAllSelectedOptions()); + $checkboxes->selectByValue('j2a'); + $this->assertCount(1, $checkboxes->getAllSelectedOptions()); + $checkboxes->deselectByValue('j2a'); + $this->assertEmpty($checkboxes->getAllSelectedOptions()); } public function testDeselectByVisibleText() { - $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); + $checkboxes = new WebDriverCheckboxes( + $this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]')) + ); - $c->selectByVisibleText('J 2 B'); - $this->assertCount(1, $c->getAllSelectedOptions()); - $c->deselectByVisibleText('J 2 B'); - $this->assertEmpty($c->getAllSelectedOptions()); + $checkboxes->selectByVisibleText('J 2 B'); + $this->assertCount(1, $checkboxes->getAllSelectedOptions()); + $checkboxes->deselectByVisibleText('J 2 B'); + $this->assertEmpty($checkboxes->getAllSelectedOptions()); } public function testDeselectByVisiblePartialText() { - $c = new WebDriverCheckboxes($this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]'))); + $checkboxes = new WebDriverCheckboxes( + $this->driver->findElement(WebDriverBy::xpath('//input[@type="checkbox"]')) + ); - $c->selectByVisiblePartialText('2C'); - $this->assertCount(1, $c->getAllSelectedOptions()); - $c->deselectByVisiblePartialText('2C'); - $this->assertEmpty($c->getAllSelectedOptions()); + $checkboxes->selectByVisiblePartialText('2C'); + $this->assertCount(1, $checkboxes->getAllSelectedOptions()); + $checkboxes->deselectByVisiblePartialText('2C'); + $this->assertEmpty($checkboxes->getAllSelectedOptions()); } } diff --git a/tests/functional/WebDriverRadiosTest.php b/tests/functional/WebDriverRadiosTest.php index 369717eb2..2350a401d 100644 --- a/tests/functional/WebDriverRadiosTest.php +++ b/tests/functional/WebDriverRadiosTest.php @@ -33,15 +33,16 @@ protected function setUp() public function testIsMultiple() { - $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); - $this->assertFalse($c->isMultiple()); + $radios = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + + $this->assertFalse($radios->isMultiple()); } public function testGetOptions() { - $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + $radios = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); $values = []; - foreach ($c->getOptions() as $option) { + foreach ($radios->getOptions() as $option) { $values[] = $option->getAttribute('value'); } @@ -50,53 +51,57 @@ public function testGetOptions() public function testGetFirstSelectedOption() { - $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); - $c->selectByValue('j3a'); - $this->assertSame('j3a', $c->getFirstSelectedOption()->getAttribute('value')); + $radios = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + + $radios->selectByValue('j3a'); + + $this->assertSame('j3a', $radios->getFirstSelectedOption()->getAttribute('value')); } - public function testGetFirstSelectedOptionWithSameNameDifferentForm() + public function testShouldGetFirstSelectedOptionConsideringOnlyElementsAssociatedWithCurrentForm() { $radio = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@id="j4b"]'))); + $this->assertEquals('j4b', $radio->getFirstSelectedOption()->getAttribute('value')); } public function testSelectByValue() { - $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); - $c->selectByValue('j3b'); + $radios = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + $radios->selectByValue('j3b'); + + $selectedOptions = $radios->getAllSelectedOptions(); - $selectedOptions = $c->getAllSelectedOptions(); $this->assertCount(1, $selectedOptions); $this->assertSame('j3b', $selectedOptions[0]->getAttribute('value')); } public function testSelectByValueInvalid() { - $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + $radios = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); $this->expectException(NoSuchElementException::class); $this->expectExceptionMessage('Cannot locate radio with value: notexist'); - $c->selectByValue('notexist'); + $radios->selectByValue('notexist'); } public function testSelectByIndex() { - $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); - $c->selectByIndex(1); + $radios = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + $radios->selectByIndex(1); - $allSelectedOptions = $c->getAllSelectedOptions(); + $allSelectedOptions = $radios->getAllSelectedOptions(); $this->assertCount(1, $allSelectedOptions); $this->assertSame('j3b', $allSelectedOptions[0]->getAttribute('value')); } public function testSelectByIndexInvalid() { - $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + $radios = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); $this->expectException(NoSuchElementException::class); $this->expectExceptionMessage('Cannot locate radio with index: ' . PHP_INT_MAX); - $c->selectByIndex(PHP_INT_MAX); + $radios->selectByIndex(PHP_INT_MAX); } /** @@ -107,9 +112,9 @@ public function testSelectByIndexInvalid() */ public function testSelectByVisibleText($text, $value) { - $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); - $c->selectByVisibleText($text); - $this->assertSame($value, $c->getFirstSelectedOption()->getAttribute('value')); + $radios = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + $radios->selectByVisibleText($text); + $this->assertSame($value, $radios->getFirstSelectedOption()->getAttribute('value')); } /** @@ -131,9 +136,9 @@ public function selectByVisibleTextDataProvider() */ public function testSelectByVisiblePartialText($text, $value) { - $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); - $c->selectByVisiblePartialText($text); - $this->assertSame($value, $c->getFirstSelectedOption()->getAttribute('value')); + $radios = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + $radios->selectByVisiblePartialText($text); + $this->assertSame($value, $radios->getFirstSelectedOption()->getAttribute('value')); } /** @@ -149,46 +154,46 @@ public function selectByVisiblePartialTextDataProvider() public function testDeselectAllRadio() { - $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + $radios = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); $this->expectException(UnsupportedOperationException::class); $this->expectExceptionMessage('You cannot deselect radio buttons'); - $c->deselectAll(); + $radios->deselectAll(); } public function testDeselectByIndexRadio() { - $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + $radios = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); $this->expectException(UnsupportedOperationException::class); $this->expectExceptionMessage('You cannot deselect radio buttons'); - $c->deselectByIndex(0); + $radios->deselectByIndex(0); } public function testDeselectByValueRadio() { - $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + $radios = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); $this->expectException(UnsupportedOperationException::class); $this->expectExceptionMessage('You cannot deselect radio buttons'); - $c->deselectByValue('val'); + $radios->deselectByValue('val'); } public function testDeselectByVisibleTextRadio() { - $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + $radios = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); $this->expectException(UnsupportedOperationException::class); $this->expectExceptionMessage('You cannot deselect radio buttons'); - $c->deselectByVisibleText('AB'); + $radios->deselectByVisibleText('AB'); } public function testDeselectByVisiblePartialTextRadio() { - $c = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); + $radios = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@type="radio"]'))); $this->expectException(UnsupportedOperationException::class); $this->expectExceptionMessage('You cannot deselect radio buttons'); - $c->deselectByVisiblePartialText('AB'); + $radios->deselectByVisiblePartialText('AB'); } } diff --git a/tests/functional/web/form_checkbox_radio.html b/tests/functional/web/form_checkbox_radio.html index 1e13d74e4..3e7c2a19a 100644 --- a/tests/functional/web/form_checkbox_radio.html +++ b/tests/functional/web/form_checkbox_radio.html @@ -5,7 +5,7 @@ Form -
    + @@ -27,28 +27,30 @@ + - + - +
    + - + - + - + - + -
    +
    From e8accbdea92c617e0bfea7bcd5aea522e0c19c9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Mon, 10 Jun 2019 13:20:45 +0200 Subject: [PATCH 430/784] Extend testcases to cover also form without id --- tests/functional/WebDriverCheckboxesTest.php | 9 +++++++++ tests/functional/WebDriverRadiosTest.php | 13 +++++++++++-- tests/functional/web/form_checkbox_radio.html | 12 ++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/tests/functional/WebDriverCheckboxesTest.php b/tests/functional/WebDriverCheckboxesTest.php index a37fde342..48b72a53c 100644 --- a/tests/functional/WebDriverCheckboxesTest.php +++ b/tests/functional/WebDriverCheckboxesTest.php @@ -68,6 +68,15 @@ public function testShouldGetFirstSelectedOptionConsideringOnlyElementsAssociate $this->assertEquals('j5b', $checkboxes->getFirstSelectedOption()->getAttribute('value')); } + public function testShouldGetFirstSelectedOptionConsideringOnlyElementsAssociatedWithCurrentFormWithoutId() + { + $checkboxes = new WebDriverCheckboxes( + $this->driver->findElement(WebDriverBy::xpath('//input[@id="j5d"]')) + ); + + $this->assertEquals('j5c', $checkboxes->getFirstSelectedOption()->getAttribute('value')); + } + public function testSelectByValue() { $selectedOptions = ['j2b', 'j2c']; diff --git a/tests/functional/WebDriverRadiosTest.php b/tests/functional/WebDriverRadiosTest.php index 2350a401d..4d659772b 100644 --- a/tests/functional/WebDriverRadiosTest.php +++ b/tests/functional/WebDriverRadiosTest.php @@ -60,9 +60,18 @@ public function testGetFirstSelectedOption() public function testShouldGetFirstSelectedOptionConsideringOnlyElementsAssociatedWithCurrentForm() { - $radio = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@id="j4b"]'))); + $radios = new WebDriverRadios($this->driver->findElement(WebDriverBy::xpath('//input[@id="j4b"]'))); - $this->assertEquals('j4b', $radio->getFirstSelectedOption()->getAttribute('value')); + $this->assertEquals('j4b', $radios->getFirstSelectedOption()->getAttribute('value')); + } + + public function testShouldGetFirstSelectedOptionConsideringOnlyElementsAssociatedWithCurrentFormWithoutId() + { + $radios = new WebDriverRadios( + $this->driver->findElement(WebDriverBy::xpath('//input[@id="j4c"]')) + ); + + $this->assertEquals('j4c', $radios->getFirstSelectedOption()->getAttribute('value')); } public function testSelectByValue() diff --git a/tests/functional/web/form_checkbox_radio.html b/tests/functional/web/form_checkbox_radio.html index 3e7c2a19a..fe59896d9 100644 --- a/tests/functional/web/form_checkbox_radio.html +++ b/tests/functional/web/form_checkbox_radio.html @@ -53,5 +53,17 @@
    + + +
    + + + + + + + +
    + From 9a52b1ac036743c31bc127fd7f2f4710e2bc968a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Mon, 10 Jun 2019 16:32:25 +0200 Subject: [PATCH 431/784] Release version 1.7.0 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e27bd1b89..9b5487916 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased + +## 1.7.0 - 2019-06-10 ### Added - `WebDriverCheckboxes` and `WebDriverRadios` helper classes to simplify interaction with checkboxes and radio buttons. From ec7ce5b611e3a73eb789c783760487c89b4999a1 Mon Sep 17 00:00:00 2001 From: Lctrs Date: Tue, 11 Jun 2019 11:47:33 +0200 Subject: [PATCH 432/784] Do not fail if ChromeOptions is already an array DesiredCapabilities::toArray() is a mutable operation which can lead to undesirable side effect of converting ChromeOptions to an array. --- lib/Remote/DesiredCapabilities.php | 1 + lib/Remote/RemoteWebDriver.php | 4 +++- tests/functional/RemoteWebDriverCreateTest.php | 13 +++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/Remote/DesiredCapabilities.php b/lib/Remote/DesiredCapabilities.php index 0e1a1ab25..533c8873a 100644 --- a/lib/Remote/DesiredCapabilities.php +++ b/lib/Remote/DesiredCapabilities.php @@ -156,6 +156,7 @@ public function setJavascriptEnabled($enabled) } /** + * @todo Remove side-effects - not change ie. ChromeOptions::CAPABILITY from instance of ChromeOptions to an array * @return array */ public function toArray() diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index 538ae282f..af729f16e 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -109,8 +109,10 @@ public static function create( $currentChromeOptions = $desired_capabilities->getCapability(ChromeOptions::CAPABILITY); $chromeOptions = !empty($currentChromeOptions) ? $currentChromeOptions : new ChromeOptions(); - if (!isset($chromeOptions->toArray()['w3c'])) { + if ($chromeOptions instanceof ChromeOptions && !isset($chromeOptions->toArray()['w3c'])) { $chromeOptions->setExperimentalOption('w3c', false); + } elseif (is_array($chromeOptions) && !isset($chromeOptions['w3c'])) { + $chromeOptions['w3c'] = false; } $desired_capabilities->setCapability(ChromeOptions::CAPABILITY, $chromeOptions); diff --git a/tests/functional/RemoteWebDriverCreateTest.php b/tests/functional/RemoteWebDriverCreateTest.php index f9d7e809e..90c072922 100644 --- a/tests/functional/RemoteWebDriverCreateTest.php +++ b/tests/functional/RemoteWebDriverCreateTest.php @@ -49,6 +49,19 @@ public function testShouldStartBrowserAndCreateInstanceOfRemoteWebDriver() $this->assertSame($this->desiredCapabilities->getBrowserName(), $returnedCapabilities->getBrowserName()); } + public function testShouldAcceprCapabilitiesAsAnArray() + { + // Method has a side-effect of converting whole content of desiredCapabilities to an array + $this->desiredCapabilities->toArray(); + + $this->driver = RemoteWebDriver::create( + $this->serverUrl, + $this->desiredCapabilities, + $this->connectionTimeout, + $this->requestTimeout + ); + } + public function testShouldCreateWebDriverWithRequiredCapabilities() { $requiredCapabilities = new DesiredCapabilities(); From f650ee73645a3e95fb0567b25d4f33c13664cbde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Wed, 12 Jun 2019 11:32:08 +0200 Subject: [PATCH 433/784] Do not send w3c capability as a workaround for browsestack schema validation (fixes #644) --- lib/Remote/RemoteWebDriver.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index af729f16e..71f45704e 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -105,7 +105,9 @@ public static function create( // Hotfix: W3C WebDriver protocol is not yet supported by php-webdriver, so we must force Chromedriver to // not use the W3C protocol by default (which is what Chromedriver does starting with version 75). - if ($desired_capabilities->getBrowserName() === WebDriverBrowserType::CHROME) { + if ($desired_capabilities->getBrowserName() === WebDriverBrowserType::CHROME + && mb_strpos($selenium_server_url, 'browserstack') === false // see https://github.com/facebook/php-webdriver/issues/644 + ) { $currentChromeOptions = $desired_capabilities->getCapability(ChromeOptions::CAPABILITY); $chromeOptions = !empty($currentChromeOptions) ? $currentChromeOptions : new ChromeOptions(); From e43de70f3c7166169d0f14a374505392734160e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Thu, 13 Jun 2019 10:02:18 +0200 Subject: [PATCH 434/784] Release version 1.7.1 --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b5487916..a5e4ca748 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,11 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +## 1.7.1 - 2019-06-13 +### Fixed +- Error `Call to a member function toArray()` if capabilities were already converted to an array. +- Temporarily do not send capabilities to disable W3C WebDriver protocol when BrowserStack hub is used. + ## 1.7.0 - 2019-06-10 ### Added - `WebDriverCheckboxes` and `WebDriverRadios` helper classes to simplify interaction with checkboxes and radio buttons. From 3f73de8364e7285115750e7e47b9a27e08c730d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 14 Jun 2019 11:33:44 +0200 Subject: [PATCH 435/784] Revert Chromedriver bug workaround, which is fixed in Chromedriver 75.0.3770.90 --- .travis.yml | 2 +- CHANGELOG.md | 3 +++ lib/Remote/HttpCommandExecutor.php | 5 ----- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index b6850baf1..ac6cc1e24 100644 --- a/.travis.yml +++ b/.travis.yml @@ -47,7 +47,7 @@ matrix: # Stable Chrome + Chromedriver 75+ inside Travis environment - php: '7.3' - env: BROWSER_NAME="chrome" CHROME_HEADLESS="1" CHROMEDRIVER_VERSION="75.0.3770.8" + env: BROWSER_NAME="chrome" CHROME_HEADLESS="1" CHROMEDRIVER_VERSION="75.0.3770.90" addons: chrome: stable diff --git a/CHANGELOG.md b/CHANGELOG.md index a5e4ca748..f1e733516 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +### Changed +- Revert no longer needed workaround for Chromedriver bug [2943](https://bugs.chromium.org/p/chromedriver/issues/detail?id=2943). + ## 1.7.1 - 2019-06-13 ### Fixed - Error `Call to a member function toArray()` if capabilities were already converted to an array. diff --git a/lib/Remote/HttpCommandExecutor.php b/lib/Remote/HttpCommandExecutor.php index 1891fdb35..f584324b7 100644 --- a/lib/Remote/HttpCommandExecutor.php +++ b/lib/Remote/HttpCommandExecutor.php @@ -273,11 +273,6 @@ public function execute(WebDriverCommand $command) if ($http_method === 'POST' && $params && is_array($params)) { $encoded_params = json_encode($params); - } elseif ($http_method === 'POST' && $encoded_params === null) { - // Workaround for bug https://bugs.chromium.org/p/chromedriver/issues/detail?id=2943 in Chrome 75. - // Chromedriver now erroneously does not allow POST body to be empty even for the JsonWire protocol. - // If the command POST is empty, here we send some dummy data as a workaround: - $encoded_params = json_encode(['_' => '_']); } curl_setopt($this->curl, CURLOPT_POSTFIELDS, $encoded_params); From 4f8b32289daa41c9c96b6a9dbfcb352a24e5af1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 1 Nov 2019 19:16:13 +0000 Subject: [PATCH 436/784] Download latest chromedriver without a need of manual version bumping --- .travis.yml | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index ac6cc1e24..37dfc2cf1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,15 +39,9 @@ matrix: addons: firefox: "45.8.0esr" - # Stable Chrome + Chromedriver 74 inside Travis environment + # Stable Chrome + Chromedriver inside Travis environment - php: '7.3' - env: BROWSER_NAME="chrome" CHROME_HEADLESS="1" CHROMEDRIVER_VERSION="74.0.3729.6" - addons: - chrome: stable - - # Stable Chrome + Chromedriver 75+ inside Travis environment - - php: '7.3' - env: BROWSER_NAME="chrome" CHROME_HEADLESS="1" CHROMEDRIVER_VERSION="75.0.3770.90" + env: BROWSER_NAME="chrome" CHROME_HEADLESS="1" addons: chrome: stable @@ -102,7 +96,7 @@ install: - travis_retry composer update --no-interaction $DEPENDENCIES before_script: - - if [ "$BROWSER_NAME" = "chrome" ]; then mkdir chromedriver; wget -q -t 3 https://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip; unzip chromedriver_linux64 -d chromedriver; fi + - if [ "$BROWSER_NAME" = "chrome" ]; then mkdir chromedriver; CHROMEDRIVER_VERSION=$(wget -qO- "https://chromedriver.storage.googleapis.com/LATEST_RELEASE"); wget -q -t 3 https://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip; unzip chromedriver_linux64 -d chromedriver; fi - if [ "$BROWSER_NAME" = "chrome" ]; then export CHROMEDRIVER_PATH=$PWD/chromedriver/chromedriver; fi - sh -e /etc/init.d/xvfb start - if [ ! -f jar/selenium-server-standalone-3.8.1.jar ]; then wget -q -t 3 -P jar https://selenium-release.storage.googleapis.com/3.8/selenium-server-standalone-3.8.1.jar; fi From 87be63361d6670b8110b7d084887746b1adc685b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 9 Apr 2018 16:25:57 +0200 Subject: [PATCH 437/784] W3C-compatible implementation --- .travis.yml | 12 +- CONTRIBUTING.md | 10 +- lib/AbstractWebDriverCheckboxOrRadio.php | 2 +- lib/Cookie.php | 8 +- lib/Exception/WebDriverException.php | 50 ++++- lib/Interactions/WebDriverActions.php | 1 - lib/Remote/DriverCommand.php | 4 + lib/Remote/HttpCommandExecutor.php | 63 ++++++- lib/Remote/JsonWireCompat.php | 102 ++++++++++ lib/Remote/RemoteMouse.php | 174 +++++++++++++++++- lib/Remote/RemoteTargetLocator.php | 4 +- lib/Remote/RemoteWebDriver.php | 82 ++++++--- lib/Remote/RemoteWebElement.php | 112 ++++++++--- lib/WebDriverDimension.php | 12 +- lib/WebDriverOptions.php | 9 +- lib/WebDriverPoint.php | 4 +- lib/WebDriverTimeouts.php | 34 +++- .../functional/RemoteWebDriverCreateTest.php | 5 +- .../RemoteWebDriverFindElementTest.php | 20 ++ tests/functional/RemoteWebDriverTest.php | 23 ++- tests/functional/RemoteWebElementTest.php | 4 + tests/functional/WebDriverActionsTest.php | 24 ++- tests/functional/WebDriverTestCase.php | 7 +- tests/functional/web/escape_css.html | 14 ++ tests/functional/web/upload.html | 2 +- 25 files changed, 699 insertions(+), 83 deletions(-) create mode 100644 lib/Remote/JsonWireCompat.php create mode 100644 tests/functional/web/escape_css.html diff --git a/.travis.yml b/.travis.yml index 37dfc2cf1..47ddb461e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,11 +34,21 @@ matrix: env: DEPENDENCIES="--prefer-lowest" # Firefox inside Travis environment - - php: '7.3' + - name: 'Firefox 45 on Travis (OSS protocol)' + php: '7.3' env: BROWSER_NAME="firefox" addons: firefox: "45.8.0esr" + # Firefox with Geckodriver (W3C mode) inside Travis environment + - name: 'Firefox latest on Travis (W3C protocol)' + php: 7.3 + env: + - BROWSER_NAME="firefox" + - GECKODRIVER="1" + addons: + firefox: latest + # Stable Chrome + Chromedriver inside Travis environment - php: '7.3' env: BROWSER_NAME="chrome" CHROME_HEADLESS="1" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1a01c7adb..741a140a9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,10 +37,10 @@ For the functional tests you must first [download](http://selenium-release.stora the selenium standalone server, start the local PHP server which will serve the test pages and then run the `functional` test suite: - java -jar selenium-server-standalone-2.53.1.jar -log selenium.log & + java -jar selenium-server-standalone-3.9.1.jar -log selenium.log & php -S localhost:8000 -t tests/functional/web/ & ./vendor/bin/phpunit --testsuite functional - + The functional tests will be started in HtmlUnit headless browser by default. If you want to run them in eg. Firefox, simply set the `BROWSER_NAME` environment variable: @@ -48,6 +48,12 @@ simply set the `BROWSER_NAME` environment variable: export BROWSER_NAME="firefox" ./vendor/bin/phpunit --testsuite functional +To test with Geckodriver, [download](https://github.com/mozilla/geckodriver/releases) and start the server, then run: + + export GECKODRIVER=1 + export BROWSER_NAME=firefox + ./vendor/bin/phpunit --testsuite functional + ### Check coding style Your code-style should comply with [PSR-2](http://www.php-fig.org/psr/psr-2/). To make sure your code matches this requirement run: diff --git a/lib/AbstractWebDriverCheckboxOrRadio.php b/lib/AbstractWebDriverCheckboxOrRadio.php index f70a2ef04..1268ce7c0 100644 --- a/lib/AbstractWebDriverCheckboxOrRadio.php +++ b/lib/AbstractWebDriverCheckboxOrRadio.php @@ -211,7 +211,7 @@ protected function getRelatedElements($value = null) $form = $this->element->findElement(WebDriverBy::xpath('ancestor::form')); $formId = $form->getAttribute('id'); - if ($formId === '') { + if (!$formId) { return $form->findElements(WebDriverBy::xpath( sprintf('.//input[@name = %s%s]', XPathEscaper::escapeQuotes($this->name), $valueSelector) )); diff --git a/lib/Cookie.php b/lib/Cookie.php index 216ac3033..170b46486 100644 --- a/lib/Cookie.php +++ b/lib/Cookie.php @@ -190,7 +190,13 @@ public function isHttpOnly() */ public function toArray() { - return $this->cookie; + $cookie = $this->cookie; + if (!isset($cookie['secure'])) { + // Passing a boolean value for the "secure" flag is mandatory when using geckodriver + $cookie['secure'] = false; + } + + return $cookie; } public function offsetExists($offset) diff --git a/lib/Exception/WebDriverException.php b/lib/Exception/WebDriverException.php index 8545729ad..b17b2f70f 100644 --- a/lib/Exception/WebDriverException.php +++ b/lib/Exception/WebDriverException.php @@ -42,7 +42,7 @@ public function getResults() /** * Throw WebDriverExceptions based on WebDriver status code. * - * @param int $status_code + * @param int|string $status_code * @param string $message * @param mixed $results * @@ -85,6 +85,54 @@ public function getResults() */ public static function throwException($status_code, $message, $results) { + if (is_string($status_code)) { + // see https://w3c.github.io/webdriver/webdriver-spec.html#handling-errors + switch ($status_code) { + case 'no such element': + throw new NoSuchElementException($message, $results); + case 'no such frame': + throw new NoSuchFrameException($message, $results); + case 'unknown command': + throw new UnknownCommandException($message, $results); + case 'stale element reference': + throw new StaleElementReferenceException($message, $results); + case 'invalid element state': + throw new InvalidElementStateException($message, $results); + case 'unknown error': + throw new UnknownServerException($message, $results); + case 'unsupported operation': + throw new ExpectedException($message, $results); + case 'element not interactable': + throw new ElementNotSelectableException($message, $results); + case 'no such window': + throw new NoSuchDocumentException($message, $results); + case 'javascript error': + throw new UnexpectedJavascriptException($message, $results); + case 'timeout': + throw new TimeOutException($message, $results); + case 'no such window': + throw new NoSuchWindowException($message, $results); + case 'invalid cookie domain': + throw new InvalidCookieDomainException($message, $results); + case 'unable to set cookie': + throw new UnableToSetCookieException($message, $results); + case 'unexpected alert open': + throw new UnexpectedAlertOpenException($message, $results); + case 'no such alert': + throw new NoAlertOpenException($message, $results); + case 'script timeout': + throw new ScriptTimeoutException($message, $results); + case 'invalid selector': + throw new InvalidSelectorException($message, $results); + case 'session not created': + throw new SessionNotCreatedException($message, $results); + case 'move target out of bounds': + throw new MoveTargetOutOfBoundsException($message, $results); + default: + throw new UnrecognizedExceptionException($message, $results); + } + } + switch ($status_code) { case 1: throw new IndexOutOfBoundsException($message, $results); diff --git a/lib/Interactions/WebDriverActions.php b/lib/Interactions/WebDriverActions.php index e97796854..66ac7c1ab 100644 --- a/lib/Interactions/WebDriverActions.php +++ b/lib/Interactions/WebDriverActions.php @@ -25,7 +25,6 @@ use Facebook\WebDriver\Interactions\Internal\WebDriverMouseMoveAction; use Facebook\WebDriver\Interactions\Internal\WebDriverMoveToOffsetAction; use Facebook\WebDriver\Interactions\Internal\WebDriverSendKeysAction; -use Facebook\WebDriver\WebDriver; use Facebook\WebDriver\WebDriverElement; use Facebook\WebDriver\WebDriverHasInputDevices; diff --git a/lib/Remote/DriverCommand.php b/lib/Remote/DriverCommand.php index c69052030..fd24a691c 100644 --- a/lib/Remote/DriverCommand.php +++ b/lib/Remote/DriverCommand.php @@ -146,6 +146,10 @@ class DriverCommand const GET_NETWORK_CONNECTION = 'getNetworkConnection'; const SET_NETWORK_CONNECTION = 'setNetworkConnection'; + // W3C specific + const ACTIONS = 'actions'; + const GET_ELEMENT_PROPERTY = 'getElementProperty'; + private function __construct() { } diff --git a/lib/Remote/HttpCommandExecutor.php b/lib/Remote/HttpCommandExecutor.php index f584324b7..c783b2892 100644 --- a/lib/Remote/HttpCommandExecutor.php +++ b/lib/Remote/HttpCommandExecutor.php @@ -137,6 +137,29 @@ class HttpCommandExecutor implements WebDriverCommandExecutor DriverCommand::TOUCH_SCROLL => ['method' => 'POST', 'url' => '/session/:sessionId/touch/scroll'], DriverCommand::TOUCH_UP => ['method' => 'POST', 'url' => '/session/:sessionId/touch/up'], ]; + /** + * @var array Will be merged with $commands + */ + protected static $w3cCompliantCommands = [ + DriverCommand::ACCEPT_ALERT => ['method' => 'POST', 'url' => '/session/:sessionId/alert/accept'], + DriverCommand::ACTIONS => ['method' => 'POST', 'url' => '/session/:sessionId/actions'], + DriverCommand::DISMISS_ALERT => ['method' => 'POST', 'url' => '/session/:sessionId/alert/dismiss'], + DriverCommand::EXECUTE_SCRIPT => ['method' => 'POST', 'url' => '/session/:sessionId/execute/sync'], + DriverCommand::EXECUTE_ASYNC_SCRIPT => ['method' => 'POST', 'url' => '/session/:sessionId/execute/async'], + DriverCommand::GET_CURRENT_WINDOW_HANDLE => ['method' => 'GET', 'url' => '/session/:sessionId/window'], + DriverCommand::GET_ELEMENT_LOCATION => ['method' => 'GET', 'url' => '/session/:sessionId/element/:id/rect'], + DriverCommand::GET_ELEMENT_PROPERTY => [ + 'method' => 'GET', + 'url' => '/session/:sessionId/element/:id/property/:name', + ], + DriverCommand::GET_ELEMENT_SIZE => ['method' => 'GET', 'url' => '/session/:sessionId/element/:id/rect'], + DriverCommand::GET_WINDOW_HANDLES => ['method' => 'GET', 'url' => '/session/:sessionId/window/handles'], + DriverCommand::GET_ALERT_TEXT => ['method' => 'GET', 'url' => '/session/:sessionId/alert/text'], + DriverCommand::IMPLICITLY_WAIT => ['method' => 'POST', 'url' => '/session/:sessionId/timeouts'], + DriverCommand::SET_ALERT_VALUE => ['method' => 'POST', 'url' => '/session/:sessionId/alert/text'], + DriverCommand::SET_SCRIPT_TIMEOUT => ['method' => 'POST', 'url' => '/session/:sessionId/timeouts'], + DriverCommand::SET_TIMEOUT => ['method' => 'POST', 'url' => '/session/:sessionId/timeouts'], + ]; /** * @var string */ @@ -145,6 +168,10 @@ class HttpCommandExecutor implements WebDriverCommandExecutor * @var resource */ protected $curl; + /** + * @var bool + */ + protected $w3cCompliant = true; /** * @param string $url @@ -153,6 +180,8 @@ class HttpCommandExecutor implements WebDriverCommandExecutor */ public function __construct($url, $http_proxy = null, $http_proxy_port = null) { + self::$w3cCompliantCommands = array_merge(self::$commands, self::$w3cCompliantCommands); + $this->url = $url; $this->curl = curl_init(); @@ -179,6 +208,11 @@ public function __construct($url, $http_proxy = null, $http_proxy_port = null) $this->setConnectionTimeout(30000); } + public function disableW3CCompliance() + { + $this->w3cCompliant = false; + } + /** * Set timeout for the connect phase * @@ -226,11 +260,19 @@ public function setRequestTimeout($timeout_in_ms) */ public function execute(WebDriverCommand $command) { - if (!isset(self::$commands[$command->getName()])) { - throw new InvalidArgumentException($command->getName() . ' is not a valid command.'); + $commandName = $command->getName(); + if (!isset(self::$commands[$commandName])) { + if ($this->w3cCompliant && !isset(self::$w3cCompliantCommands[$commandName])) { + throw new InvalidArgumentException($command->getName() . ' is not a valid command.'); + } + } + + if ($this->w3cCompliant) { + $raw = self::$w3cCompliantCommands[$command->getName()]; + } else { + $raw = self::$commands[$command->getName()]; } - $raw = self::$commands[$command->getName()]; $http_method = $raw['method']; $url = $raw['url']; $url = str_replace(':sessionId', $command->getSessionID(), $url); @@ -317,12 +359,23 @@ public function execute(WebDriverCommand $command) } $sessionId = null; - if (is_array($results) && array_key_exists('sessionId', $results)) { + if (is_array($value) && array_key_exists('sessionId', $value)) { + // W3C's WebDriver + $sessionId = $value['sessionId']; + } elseif (is_array($results) && array_key_exists('sessionId', $results)) { + // Legacy JsonWire $sessionId = $results['sessionId']; } + // @see https://w3c.github.io/webdriver/webdriver-spec.html#handling-errors + if (isset($value['error'])) { + // W3C's WebDriver + WebDriverException::throwException($value['error'], $message, $results); + } + $status = isset($results['status']) ? $results['status'] : 0; - if ($status != 0) { + if ($status !== 0) { + // Legacy JsonWire WebDriverException::throwException($status, $message, $results); } diff --git a/lib/Remote/JsonWireCompat.php b/lib/Remote/JsonWireCompat.php new file mode 100644 index 000000000..78b9cba0e --- /dev/null +++ b/lib/Remote/JsonWireCompat.php @@ -0,0 +1,102 @@ +getMechanism(); + $value = $by->getValue(); + + if ($w3cCompliant) { + switch ($mechanism) { + // Convert to CSS selectors + case 'class name': + $mechanism = 'css selector'; + $value = sprintf('.%s', self::escapeSelector($value)); + break; + case 'id': + $mechanism = 'css selector'; + $value = sprintf('#%s', self::escapeSelector($value)); + break; + case 'name': + $mechanism = 'css selector'; + $value = sprintf('[name=\'%s\']', self::escapeSelector($value)); + break; + } + } + + return ['using' => $mechanism, 'value' => $value]; + } + + /** + * Escapes a CSS selector. + * + * Code adapted from the Zend Escaper project. + * + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @see https://github.com/zendframework/zend-escaper/blob/master/src/Escaper.php + * + * @param string $selector + * @return string + */ + private static function escapeSelector($selector) + { + return preg_replace_callback('/[^a-z0-9]/iSu', function ($matches) { + $chr = $matches[0]; + if (mb_strlen($chr) == 1) { + $ord = ord($chr); + } else { + $chr = mb_convert_encoding($chr, 'UTF-32BE', 'UTF-8'); + $ord = hexdec(bin2hex($chr)); + } + + return sprintf('\\%X ', $ord); + }, $selector); + } +} diff --git a/lib/Remote/RemoteMouse.php b/lib/Remote/RemoteMouse.php index 48c578df7..aa0d59829 100644 --- a/lib/Remote/RemoteMouse.php +++ b/lib/Remote/RemoteMouse.php @@ -27,13 +27,19 @@ class RemoteMouse implements WebDriverMouse * @var RemoteExecuteMethod */ private $executor; + /** + * @var bool + */ + private $w3cCompliant; /** * @param RemoteExecuteMethod $executor + * @param bool $w3cCompliant */ - public function __construct(RemoteExecuteMethod $executor) + public function __construct(RemoteExecuteMethod $executor, $w3cCompliant = false) { $this->executor = $executor; + $this->w3cCompliant = $w3cCompliant; } /** @@ -43,6 +49,22 @@ public function __construct(RemoteExecuteMethod $executor) */ public function click(WebDriverCoordinates $where = null) { + if ($this->w3cCompliant) { + $moveAction = $where ? [$this->createMoveAction($where)] : []; + $this->executor->execute(DriverCommand::ACTIONS, [ + 'actions' => [ + [ + 'type' => 'pointer', + 'id' => 'mouse', + 'parameters' => ['pointerType' => 'mouse'], + 'actions' => array_merge($moveAction, $this->createClickActions()), + ], + ], + ]); + + return $this; + } + $this->moveIfNeeded($where); $this->executor->execute(DriverCommand::CLICK, [ 'button' => 0, @@ -58,6 +80,33 @@ public function click(WebDriverCoordinates $where = null) */ public function contextClick(WebDriverCoordinates $where = null) { + if ($this->w3cCompliant) { + $moveAction = $where ? [$this->createMoveAction($where)] : []; + $this->executor->execute(DriverCommand::ACTIONS, [ + 'actions' => [ + [ + 'type' => 'pointer', + 'id' => 'mouse', + 'parameters' => ['pointerType' => 'mouse'], + 'actions' => array_merge($moveAction, [ + [ + 'type' => 'pointerDown', + 'duration' => 0, + 'button' => 2, + ], + [ + 'type' => 'pointerUp', + 'duration' => 0, + 'button' => 2, + ], + ]), + ], + ], + ]); + + return $this; + } + $this->moveIfNeeded($where); $this->executor->execute(DriverCommand::CLICK, [ 'button' => 2, @@ -73,6 +122,23 @@ public function contextClick(WebDriverCoordinates $where = null) */ public function doubleClick(WebDriverCoordinates $where = null) { + if ($this->w3cCompliant) { + $clickActions = $this->createClickActions(); + $moveAction = null === $where ? [] : [$this->createMoveAction($where)]; + $this->executor->execute(DriverCommand::ACTIONS, [ + 'actions' => [ + [ + 'type' => 'pointer', + 'id' => 'mouse', + 'parameters' => ['pointerType' => 'mouse'], + 'actions' => array_merge($moveAction, $clickActions, $clickActions), + ], + ], + ]); + + return $this; + } + $this->moveIfNeeded($where); $this->executor->execute(DriverCommand::DOUBLE_CLICK); @@ -86,6 +152,28 @@ public function doubleClick(WebDriverCoordinates $where = null) */ public function mouseDown(WebDriverCoordinates $where = null) { + if ($this->w3cCompliant) { + $this->executor->execute(DriverCommand::ACTIONS, [ + 'actions' => [ + [ + 'type' => 'pointer', + 'id' => 'mouse', + 'parameters' => ['pointerType' => 'mouse'], + 'actions' => [ + $this->createMoveAction($where), + [ + 'type' => 'pointerDown', + 'duration' => 0, + 'button' => 0, + ], + ], + ], + ], + ]); + + return $this; + } + $this->moveIfNeeded($where); $this->executor->execute(DriverCommand::MOUSE_DOWN); @@ -104,6 +192,21 @@ public function mouseMove( $x_offset = null, $y_offset = null ) { + if ($this->w3cCompliant) { + $this->executor->execute(DriverCommand::ACTIONS, [ + 'actions' => [ + [ + 'type' => 'pointer', + 'id' => 'mouse', + 'parameters' => ['pointerType' => 'mouse'], + 'actions' => [$this->createMoveAction($where, $x_offset, $y_offset)], + ], + ], + ]); + + return $this; + } + $params = []; if ($where !== null) { $params['element'] = $where->getAuxiliary(); @@ -114,6 +217,7 @@ public function mouseMove( if ($y_offset !== null) { $params['yoffset'] = $y_offset; } + $this->executor->execute(DriverCommand::MOVE_TO, $params); return $this; @@ -126,6 +230,29 @@ public function mouseMove( */ public function mouseUp(WebDriverCoordinates $where = null) { + if ($this->w3cCompliant) { + $moveAction = $where ? [$this->createMoveAction($where)] : []; + + $this->executor->execute(DriverCommand::ACTIONS, [ + 'actions' => [ + [ + 'type' => 'pointer', + 'id' => 'mouse', + 'parameters' => ['pointerType' => 'mouse'], + 'actions' => array_merge($moveAction, [ + [ + 'type' => 'pointerDown', + 'duration' => 0, + 'button' => 0, + ], + ]), + ], + ], + ]); + + return $this; + } + $this->moveIfNeeded($where); $this->executor->execute(DriverCommand::MOUSE_UP); @@ -141,4 +268,49 @@ protected function moveIfNeeded(WebDriverCoordinates $where = null) $this->mouseMove($where); } } + + /** + * @param WebDriverCoordinates $where + * @param int|null $x_offset + * @param int|null $y_offset + * + * @return array + */ + private function createMoveAction( + WebDriverCoordinates $where = null, + $x_offset = null, + $y_offset = null + ) { + $move_action = [ + 'type' => 'pointerMove', + 'duration' => 0, + 'x' => $x_offset === null ? 0 : $x_offset, + 'y' => $y_offset === null ? 0 : $y_offset, + ]; + + if ($where !== null) { + $move_action['origin'] = [JsonWireCompat::WEB_DRIVER_ELEMENT_IDENTIFIER => $where->getAuxiliary()]; + } + + return $move_action; + } + + /** + * @return array + */ + private function createClickActions() + { + return [ + [ + 'type' => 'pointerDown', + 'duration' => 0, + 'button' => 0, + ], + [ + 'type' => 'pointerUp', + 'duration' => 0, + 'button' => 0, + ], + ]; + } } diff --git a/lib/Remote/RemoteTargetLocator.php b/lib/Remote/RemoteTargetLocator.php index 5c218075d..55a879c0d 100644 --- a/lib/Remote/RemoteTargetLocator.php +++ b/lib/Remote/RemoteTargetLocator.php @@ -112,6 +112,8 @@ public function activeElement() $response = $this->driver->execute(DriverCommand::GET_ACTIVE_ELEMENT, []); $method = new RemoteExecuteMethod($this->driver); - return new RemoteWebElement($method, $response['ELEMENT']); + $w3cCompliant = $this->driver instanceof RemoteWebDriver ? $this->driver->isW3cCompliant() : false; + + return new RemoteWebElement($method, JsonWireCompat::getElement($response), $w3cCompliant); } } diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index 71f45704e..6d3a7d833 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -59,19 +59,26 @@ class RemoteWebDriver implements WebDriver, JavaScriptExecutor, WebDriverHasInpu * @var RemoteExecuteMethod */ protected $executeMethod; + /** + * @var bool + */ + protected $w3cCompliant; /** * @param HttpCommandExecutor $commandExecutor * @param string $sessionId * @param WebDriverCapabilities|null $capabilities + * @param bool $w3cCompliant false to use the legacy JsonWire protocol, true for the W3C WebDriver spec */ protected function __construct( HttpCommandExecutor $commandExecutor, $sessionId, - WebDriverCapabilities $capabilities = null + WebDriverCapabilities $capabilities = null, + $w3cCompliant = false ) { $this->executor = $commandExecutor; $this->sessionID = $sessionId; + $this->w3cCompliant = $w3cCompliant; if ($capabilities !== null) { $this->capabilities = $capabilities; @@ -88,6 +95,7 @@ protected function __construct( * @param string|null $http_proxy The proxy to tunnel requests to the remote Selenium WebDriver through * @param int|null $http_proxy_port The proxy port to tunnel requests to the remote Selenium WebDriver through * @param DesiredCapabilities $required_capabilities The required capabilities + * * @return static */ public static function create( @@ -99,6 +107,7 @@ public static function create( $http_proxy_port = null, DesiredCapabilities $required_capabilities = null ) { + // BC layer to not break the method signature $selenium_server_url = preg_replace('#/+$#', '', $selenium_server_url); $desired_capabilities = self::castToDesiredCapabilitiesObject($desired_capabilities); @@ -128,23 +137,43 @@ public static function create( $executor->setRequestTimeout($request_timeout_in_ms); } + // W3C + $parameters = [ + 'capabilities' => [ + 'firstMatch' => [$desired_capabilities->toArray()], + ], + ]; + + // Legacy protocol + if (null !== $required_capabilities && $required_capabilities_array = $required_capabilities->toArray()) { + $parameters['capabilities']['alwaysMatch'] = $required_capabilities_array; + } + if ($required_capabilities !== null) { // TODO: Selenium (as of v3.0.1) does accept requiredCapabilities only as a property of desiredCapabilities. - // This will probably change in future with the W3C WebDriver spec, but is the only way how to pass these - // values now. + // This has changed with the W3C WebDriver spec, but is the only way how to pass these + // values with the legacy protocol. $desired_capabilities->setCapability('requiredCapabilities', $required_capabilities->toArray()); } + $parameters['desiredCapabilities'] = $desired_capabilities->toArray(); + $command = new WebDriverCommand( null, DriverCommand::NEW_SESSION, - ['desiredCapabilities' => $desired_capabilities->toArray()] + $parameters ); $response = $executor->execute($command); - $returnedCapabilities = new DesiredCapabilities($response->getValue()); + $value = $response->getValue(); + + if (!$w3c_compliant = isset($value['capabilities'])) { + $executor->disableW3CCompliance(); + } - $driver = new static($executor, $response->getSessionID(), $returnedCapabilities); + $returnedCapabilities = new DesiredCapabilities($w3c_compliant ? $value['capabilities'] : $value); + + $driver = new static($executor, $response->getSessionID(), $returnedCapabilities, $w3c_compliant); return $driver; } @@ -167,7 +196,9 @@ public static function createBySessionID( $connection_timeout_in_ms = null, $request_timeout_in_ms = null ) { - $executor = new HttpCommandExecutor($selenium_server_url); + // BC layer to not break the method signature + $w3c_compliant = func_num_args() > 3 ? func_get_arg(3) : false; + $executor = new HttpCommandExecutor($selenium_server_url, null, null); if ($connection_timeout_in_ms !== null) { $executor->setConnectionTimeout($connection_timeout_in_ms); } @@ -175,7 +206,7 @@ public static function createBySessionID( $executor->setRequestTimeout($request_timeout_in_ms); } - return new static($executor, $session_id); + return new static($executor, $session_id, null, $w3c_compliant); } /** @@ -199,13 +230,12 @@ public function close() */ public function findElement(WebDriverBy $by) { - $params = ['using' => $by->getMechanism(), 'value' => $by->getValue()]; $raw_element = $this->execute( DriverCommand::FIND_ELEMENT, - $params + JsonWireCompat::getUsing($by, $this->w3cCompliant) ); - return $this->newElement($raw_element['ELEMENT']); + return $this->newElement(JsonWireCompat::getElement($raw_element)); } /** @@ -217,15 +247,14 @@ public function findElement(WebDriverBy $by) */ public function findElements(WebDriverBy $by) { - $params = ['using' => $by->getMechanism(), 'value' => $by->getValue()]; $raw_elements = $this->execute( DriverCommand::FIND_ELEMENTS, - $params + JsonWireCompat::getUsing($by, $this->w3cCompliant) ); $elements = []; foreach ($raw_elements as $raw_element) { - $elements[] = $this->newElement($raw_element['ELEMENT']); + $elements[] = $this->newElement(JsonWireCompat::getElement($raw_element)); } return $elements; @@ -399,7 +428,7 @@ public function wait($timeout_in_second = 30, $interval_in_millisecond = 250) */ public function manage() { - return new WebDriverOptions($this->getExecuteMethod()); + return new WebDriverOptions($this->getExecuteMethod(), $this->w3cCompliant); } /** @@ -430,7 +459,7 @@ public function switchTo() public function getMouse() { if (!$this->mouse) { - $this->mouse = new RemoteMouse($this->getExecuteMethod()); + $this->mouse = new RemoteMouse($this->getExecuteMethod(), $this->w3cCompliant); } return $this->mouse; @@ -541,7 +570,7 @@ public function getCapabilities() */ public static function getAllSessions($selenium_server_url = 'http://localhost:4444/wd/hub', $timeout_in_ms = 30000) { - $executor = new HttpCommandExecutor($selenium_server_url); + $executor = new HttpCommandExecutor($selenium_server_url, null, null); $executor->setConnectionTimeout($timeout_in_ms); $command = new WebDriverCommand( @@ -570,6 +599,15 @@ public function execute($command_name, $params = []) return null; } + /** + * @internal + * @return bool + */ + public function isW3cCompliant() + { + return $this->w3cCompliant; + } + /** * Prepare arguments for JavaScript injection * @@ -581,9 +619,11 @@ protected function prepareScriptArguments(array $arguments) $args = []; foreach ($arguments as $key => $value) { if ($value instanceof WebDriverElement) { - $args[$key] = ['ELEMENT' => $value->getID()]; + $args[$key] = [ + $this->w3cCompliant ? JsonWireCompat::WEB_DRIVER_ELEMENT_IDENTIFIER : 'ELEMENT' => $value->getID(), + ]; } else { - if (is_array($value)) { + if (\is_array($value)) { $value = $this->prepareScriptArguments($value); } $args[$key] = $value; @@ -613,7 +653,7 @@ protected function getExecuteMethod() */ protected function newElement($id) { - return new RemoteWebElement($this->getExecuteMethod(), $id); + return new RemoteWebElement($this->getExecuteMethod(), $id, $this->w3cCompliant); } /** @@ -629,7 +669,7 @@ protected static function castToDesiredCapabilitiesObject($desired_capabilities return new DesiredCapabilities(); } - if (is_array($desired_capabilities)) { + if (\is_array($desired_capabilities)) { return new DesiredCapabilities($desired_capabilities); } diff --git a/lib/Remote/RemoteWebElement.php b/lib/Remote/RemoteWebElement.php index 26936d8b9..b07b18227 100644 --- a/lib/Remote/RemoteWebElement.php +++ b/lib/Remote/RemoteWebElement.php @@ -15,6 +15,7 @@ namespace Facebook\WebDriver\Remote; +use Facebook\WebDriver\Exception\UnsupportedOperationException; use Facebook\WebDriver\Exception\WebDriverException; use Facebook\WebDriver\Interactions\Internal\WebDriverCoordinates; use Facebook\WebDriver\Internal\WebDriverLocatable; @@ -42,16 +43,22 @@ class RemoteWebElement implements WebDriverElement, WebDriverLocatable * @var UselessFileDetector */ protected $fileDetector; + /** + * @var bool + */ + protected $w3cCompliant; /** * @param RemoteExecuteMethod $executor * @param string $id + * @param bool $w3cCompliant */ - public function __construct(RemoteExecuteMethod $executor, $id) + public function __construct(RemoteExecuteMethod $executor, $id, $w3cCompliant = false) { $this->executor = $executor; $this->id = $id; $this->fileDetector = new UselessFileDetector(); + $this->w3cCompliant = $w3cCompliant; } /** @@ -66,6 +73,23 @@ public function clear() [':id' => $this->id] ); + if ($this->w3cCompliant) { + $this->executor->execute(DriverCommand::ACTIONS, [ + 'actions' => [[ + 'type' => 'key', + 'id' => 'keyboard', + 'actions' => [ + ['type' => 'keyDown' , 'value' => WebDriverKeys::CONTROL], + ['type' => 'keyDown' , 'value' => 'a'], + ['type' => 'keyUp' , 'value' => WebDriverKeys::CONTROL], + ['type' => 'keyUp' , 'value' => 'a'], + ['type' => 'keyDown' , 'value' => WebDriverKeys::BACKSPACE], + ['type' => 'keyUp' , 'value' => WebDriverKeys::BACKSPACE], + ], + ]], + ]); + } + return $this; } @@ -94,17 +118,15 @@ public function click() */ public function findElement(WebDriverBy $by) { - $params = [ - 'using' => $by->getMechanism(), - 'value' => $by->getValue(), - ':id' => $this->id, - ]; + $params = JsonWireCompat::getUsing($by, $this->w3cCompliant); + $params[':id'] = $this->id; + $raw_element = $this->executor->execute( DriverCommand::FIND_CHILD_ELEMENT, $params ); - return $this->newElement($raw_element['ELEMENT']); + return $this->newElement(JsonWireCompat::getElement($raw_element)); } /** @@ -117,11 +139,8 @@ public function findElement(WebDriverBy $by) */ public function findElements(WebDriverBy $by) { - $params = [ - 'using' => $by->getMechanism(), - 'value' => $by->getValue(), - ':id' => $this->id, - ]; + $params = JsonWireCompat::getUsing($by, $this->w3cCompliant); + $params[':id'] = $this->id; $raw_elements = $this->executor->execute( DriverCommand::FIND_CHILD_ELEMENTS, $params @@ -129,7 +148,7 @@ public function findElements(WebDriverBy $by) $elements = []; foreach ($raw_elements as $raw_element) { - $elements[] = $this->newElement($raw_element['ELEMENT']); + $elements[] = $this->newElement(JsonWireCompat::getElement($raw_element)); } return $elements; @@ -148,10 +167,23 @@ public function getAttribute($attribute_name) ':id' => $this->id, ]; - return $this->executor->execute( - DriverCommand::GET_ELEMENT_ATTRIBUTE, - $params - ); + if ($this->w3cCompliant && ($attribute_name === 'value' || $attribute_name === 'index')) { + $value = $this->executor->execute(DriverCommand::GET_ELEMENT_PROPERTY, $params); + + if ($value === true) { + return 'true'; + } + + if ($value === false) { + return 'false'; + } + + if ($value !== null) { + return (string) $value; + } + } + + return $this->executor->execute(DriverCommand::GET_ELEMENT_ATTRIBUTE, $params); } /** @@ -325,20 +357,37 @@ public function sendKeys($value) { $local_file = $this->fileDetector->getLocalFile($value); if ($local_file === null) { + if ($this->w3cCompliant) { + $params = [ + 'text' => (string) $value, + ':id' => $this->id, + ]; + } else { + $params = [ + 'value' => WebDriverKeys::encode($value), + ':id' => $this->id, + ]; + } + + $this->executor->execute(DriverCommand::SEND_KEYS_TO_ELEMENT, $params); + + return $this; + } + + if ($this->w3cCompliant) { $params = [ - 'value' => WebDriverKeys::encode($value), + 'text' => $local_file, ':id' => $this->id, ]; - $this->executor->execute(DriverCommand::SEND_KEYS_TO_ELEMENT, $params); } else { - $remote_path = $this->upload($local_file); $params = [ - 'value' => WebDriverKeys::encode($remote_path), + 'value' => WebDriverKeys::encode($this->upload($local_file)), ':id' => $this->id, ]; - $this->executor->execute(DriverCommand::SEND_KEYS_TO_ELEMENT, $params); } + $this->executor->execute(DriverCommand::SEND_KEYS_TO_ELEMENT, $params); + return $this; } @@ -371,6 +420,19 @@ public function setFileDetector(FileDetector $detector) */ public function submit() { + if ($this->w3cCompliant) { + $this->executor->execute(DriverCommand::EXECUTE_SCRIPT, [ + // cannot call the submit method directly in case an input of this form is named "submit" + 'script' => sprintf( + 'return Object.getPrototypeOf(%1$s).submit.call(%1$s);', + 'form' === $this->getTagName() ? 'arguments[0]' : 'arguments[0].form' + ), + 'args' => [[JsonWireCompat::WEB_DRIVER_ELEMENT_IDENTIFIER => $this->id]], + ]); + + return $this; + } + $this->executor->execute( DriverCommand::SUBMIT_ELEMENT, [':id' => $this->id] @@ -397,6 +459,10 @@ public function getID() */ public function equals(WebDriverElement $other) { + if ($this->w3cCompliant) { + throw new UnsupportedOperationException('"elementEquals" is not supported by the W3C specification'); + } + return $this->executor->execute(DriverCommand::ELEMENT_EQUALS, [ ':id' => $this->id, ':other' => $other->getID(), @@ -412,7 +478,7 @@ public function equals(WebDriverElement $other) */ protected function newElement($id) { - return new static($this->executor, $id); + return new static($this->executor, $id, $this->w3cCompliant); } /** diff --git a/lib/WebDriverDimension.php b/lib/WebDriverDimension.php index 308c1990f..81a223989 100644 --- a/lib/WebDriverDimension.php +++ b/lib/WebDriverDimension.php @@ -21,17 +21,17 @@ class WebDriverDimension { /** - * @var int + * @var int|float */ private $height; /** - * @var int + * @var int|float */ private $width; /** - * @param int $width - * @param int $height + * @param int|float $width + * @param int|float $height */ public function __construct($width, $height) { @@ -46,7 +46,7 @@ public function __construct($width, $height) */ public function getHeight() { - return $this->height; + return (int) $this->height; } /** @@ -56,7 +56,7 @@ public function getHeight() */ public function getWidth() { - return $this->width; + return (int) $this->width; } /** diff --git a/lib/WebDriverOptions.php b/lib/WebDriverOptions.php index bec7fd18b..4c584bd07 100644 --- a/lib/WebDriverOptions.php +++ b/lib/WebDriverOptions.php @@ -28,10 +28,15 @@ class WebDriverOptions * @var ExecuteMethod */ protected $executor; + /** + * @var bool + */ + protected $w3cCompliant; - public function __construct(ExecuteMethod $executor) + public function __construct(ExecuteMethod $executor, $w3cCompliant = false) { $this->executor = $executor; + $this->w3cCompliant = $w3cCompliant; } /** @@ -128,7 +133,7 @@ public function getCookies() */ public function timeouts() { - return new WebDriverTimeouts($this->executor); + return new WebDriverTimeouts($this->executor, $this->w3cCompliant); } /** diff --git a/lib/WebDriverPoint.php b/lib/WebDriverPoint.php index 4e2dbd211..9600af9d8 100644 --- a/lib/WebDriverPoint.php +++ b/lib/WebDriverPoint.php @@ -36,7 +36,7 @@ public function __construct($x, $y) */ public function getX() { - return $this->x; + return (int) $this->x; } /** @@ -46,7 +46,7 @@ public function getX() */ public function getY() { - return $this->y; + return (int) $this->y; } /** diff --git a/lib/WebDriverTimeouts.php b/lib/WebDriverTimeouts.php index 6903f7080..eeba9a10e 100644 --- a/lib/WebDriverTimeouts.php +++ b/lib/WebDriverTimeouts.php @@ -27,10 +27,15 @@ class WebDriverTimeouts * @var ExecuteMethod */ protected $executor; + /** + * @var bool + */ + protected $w3cCompliant; - public function __construct(ExecuteMethod $executor) + public function __construct(ExecuteMethod $executor, $w3cCompliant = false) { $this->executor = $executor; + $this->w3cCompliant = $w3cCompliant; } /** @@ -41,6 +46,15 @@ public function __construct(ExecuteMethod $executor) */ public function implicitlyWait($seconds) { + if ($this->w3cCompliant) { + $this->executor->execute( + DriverCommand::IMPLICITLY_WAIT, + ['implicit' => $seconds * 1000] + ); + + return $this; + } + $this->executor->execute( DriverCommand::IMPLICITLY_WAIT, ['ms' => $seconds * 1000] @@ -57,6 +71,15 @@ public function implicitlyWait($seconds) */ public function setScriptTimeout($seconds) { + if ($this->w3cCompliant) { + $this->executor->execute( + DriverCommand::SET_SCRIPT_TIMEOUT, + ['script' => $seconds * 1000] + ); + + return $this; + } + $this->executor->execute( DriverCommand::SET_SCRIPT_TIMEOUT, ['ms' => $seconds * 1000] @@ -73,6 +96,15 @@ public function setScriptTimeout($seconds) */ public function pageLoadTimeout($seconds) { + if ($this->w3cCompliant) { + $this->executor->execute( + DriverCommand::SET_SCRIPT_TIMEOUT, + ['pageLoad' => $seconds * 1000] + ); + + return $this; + } + $this->executor->execute(DriverCommand::SET_TIMEOUT, [ 'type' => 'page load', 'ms' => $seconds * 1000, diff --git a/tests/functional/RemoteWebDriverCreateTest.php b/tests/functional/RemoteWebDriverCreateTest.php index 90c072922..a2f6e9d0f 100644 --- a/tests/functional/RemoteWebDriverCreateTest.php +++ b/tests/functional/RemoteWebDriverCreateTest.php @@ -33,7 +33,10 @@ public function testShouldStartBrowserAndCreateInstanceOfRemoteWebDriver() $this->serverUrl, $this->desiredCapabilities, $this->connectionTimeout, - $this->requestTimeout + $this->requestTimeout, + null, + null, + null ); $this->assertInstanceOf(RemoteWebDriver::class, $this->driver); diff --git a/tests/functional/RemoteWebDriverFindElementTest.php b/tests/functional/RemoteWebDriverFindElementTest.php index eea14b6e5..066179f1f 100644 --- a/tests/functional/RemoteWebDriverFindElementTest.php +++ b/tests/functional/RemoteWebDriverFindElementTest.php @@ -61,4 +61,24 @@ public function testShouldFindMultipleElements() $this->assertCount(5, $elements); $this->assertContainsOnlyInstancesOf(RemoteWebElement::class, $elements); } + + public function testEscapeCssSelector() + { + if (getenv('GECKODRIVER') !== '1') { + $this->markTestSkipped( + 'CSS selectors containing special characters are not supported by the legacy protocol' + ); + } + + $this->driver->get($this->getTestPageUrl('escape_css.html')); + + $element = $this->driver->findElement(WebDriverBy::id('.fo\'oo')); + $this->assertSame('Foo', $element->getText()); + + $element = $this->driver->findElement(WebDriverBy::className('#ba\'r')); + $this->assertSame('Bar', $element->getText()); + + $element = $this->driver->findElement(WebDriverBy::name('.#ba\'z')); + $this->assertSame('Baz', $element->getText()); + } } diff --git a/tests/functional/RemoteWebDriverTest.php b/tests/functional/RemoteWebDriverTest.php index d996d304a..9105aa93f 100644 --- a/tests/functional/RemoteWebDriverTest.php +++ b/tests/functional/RemoteWebDriverTest.php @@ -77,7 +77,11 @@ public function testShouldGetSessionId() */ public function testShouldGetAllSessions() { - $sessions = RemoteWebDriver::getAllSessions($this->serverUrl); + if (getenv('GECKODRIVER') === '1') { + $this->markTestSkipped('"getAllSessions" is not supported by the W3C specification'); + } + + $sessions = RemoteWebDriver::getAllSessions($this->serverUrl, 30000); $this->assertInternalType('array', $sessions); $this->assertCount(1, $sessions); @@ -94,12 +98,22 @@ public function testShouldGetAllSessions() */ public function testShouldQuitAndUnsetExecutor() { - $this->assertCount(1, RemoteWebDriver::getAllSessions($this->serverUrl)); + if (getenv('GECKODRIVER') === '1') { + $this->markTestSkipped('"getAllSessions" is not supported by the W3C specification'); + } + + $this->assertCount( + 1, + RemoteWebDriver::getAllSessions($this->serverUrl, 30000) + ); $this->assertInstanceOf(HttpCommandExecutor::class, $this->driver->getCommandExecutor()); $this->driver->quit(); - $this->assertCount(0, RemoteWebDriver::getAllSessions($this->serverUrl)); + $this->assertCount( + 0, + RemoteWebDriver::getAllSessions($this->serverUrl, 30000) + ); $this->assertNull($this->driver->getCommandExecutor()); } @@ -136,6 +150,9 @@ public function testShouldCloseWindow() $this->driver->get($this->getTestPageUrl('open_new_window.html')); $this->driver->findElement(WebDriverBy::cssSelector('a'))->click(); + // Mandatory for Geckodriver + $this->driver->wait()->until(WebDriverExpectedCondition::numberOfWindowsToBe(2)); + $this->assertCount(2, $this->driver->getWindowHandles()); $this->driver->close(); diff --git a/tests/functional/RemoteWebElementTest.php b/tests/functional/RemoteWebElementTest.php index d4614a431..a4684ace3 100644 --- a/tests/functional/RemoteWebElementTest.php +++ b/tests/functional/RemoteWebElementTest.php @@ -272,6 +272,10 @@ public function testShouldSubmitFormByClickOnSubmitInput() */ public function testShouldCompareEqualsElement() { + if (getenv('GECKODRIVER') === '1') { + $this->markTestSkipped('"equals" is not supported by the W3C specification'); + } + $this->driver->get($this->getTestPageUrl('index.html')); $firstElement = $this->driver->findElement(WebDriverBy::cssSelector('ul.list')); diff --git a/tests/functional/WebDriverActionsTest.php b/tests/functional/WebDriverActionsTest.php index 3df984810..b2bd51835 100644 --- a/tests/functional/WebDriverActionsTest.php +++ b/tests/functional/WebDriverActionsTest.php @@ -46,10 +46,16 @@ public function testShouldClickOnElement() ->click($element) ->perform(); - $this->assertSame( - ['mouseover item-1', 'mousedown item-1', 'mouseup item-1', 'click item-1'], - $this->retrieveLoggedEvents() - ); + $logs = ['mouseover item-1', 'mousedown item-1', 'mouseup item-1', 'click item-1']; + $loggedEvents = $this->retrieveLoggedEvents(); + + if ('1' === getenv('GECKODRIVER')) { + $loggedEvents = array_slice($loggedEvents, 0, count($logs)); + // Firefox sometimes triggers some extra events + // it's not related to Geckodriver, it's Firefox's own behavior + } + + $this->assertSame($logs, $loggedEvents); } /** @@ -71,10 +77,12 @@ public function testShouldClickAndHoldOnElementAndRelease() ->release() ->perform(); - $this->assertSame( - ['mouseover item-1', 'mousedown item-1', 'mouseup item-1', 'click item-1'], - $this->retrieveLoggedEvents() - ); + if ('1' === getenv('GECKODRIVER')) { + $logs = ['mouseover item-1', 'mousedown item-1', 'dragstart item-1']; + } else { + $logs = ['mouseover item-1', 'mousedown item-1', 'mouseup item-1', 'click item-1']; + } + $this->assertSame($logs, $this->retrieveLoggedEvents()); } /** diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index 5fe6a7e8a..7a0f8af23 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -58,6 +58,8 @@ protected function setUp() // --no-sandbox is a workaround for Chrome crashing: https://github.com/SeleniumHQ/selenium/issues/4961 $chromeOptions->addArguments(['--headless', 'window-size=1024,768', '--no-sandbox']); $this->desiredCapabilities->setCapability(ChromeOptions::CAPABILITY, $chromeOptions); + } elseif (getenv('GECKODRIVER') === '1') { + $this->serverUrl = 'http://localhost:4444/'; } $this->desiredCapabilities->setBrowserName($browserName); @@ -68,7 +70,10 @@ protected function setUp() $this->serverUrl, $this->desiredCapabilities, $this->connectionTimeout, - $this->requestTimeout + $this->requestTimeout, + null, + null, + null ); } } diff --git a/tests/functional/web/escape_css.html b/tests/functional/web/escape_css.html new file mode 100644 index 000000000..48213084a --- /dev/null +++ b/tests/functional/web/escape_css.html @@ -0,0 +1,14 @@ + + + + + Test CSS selector escaping + + + +
    Foo
    +
    Bar
    +
    Baz
    + + + diff --git a/tests/functional/web/upload.html b/tests/functional/web/upload.html index 65a622c50..6762873c3 100644 --- a/tests/functional/web/upload.html +++ b/tests/functional/web/upload.html @@ -8,7 +8,7 @@

    - +

    From 4a65bed00dd2bdbbfa81206590df29d2060221c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 20 Aug 2019 16:18:50 +0200 Subject: [PATCH 438/784] Add back Geckodriver to the Travis matrix --- .travis.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 47ddb461e..906951171 100644 --- a/.travis.yml +++ b/.travis.yml @@ -108,9 +108,14 @@ install: before_script: - if [ "$BROWSER_NAME" = "chrome" ]; then mkdir chromedriver; CHROMEDRIVER_VERSION=$(wget -qO- "https://chromedriver.storage.googleapis.com/LATEST_RELEASE"); wget -q -t 3 https://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip; unzip chromedriver_linux64 -d chromedriver; fi - if [ "$BROWSER_NAME" = "chrome" ]; then export CHROMEDRIVER_PATH=$PWD/chromedriver/chromedriver; fi + - if [ "$GECKODRIVER" = "1" ]; then mkdir geckodriver; wget -q -t 3 https://github.com/mozilla/geckodriver/releases/download/v0.24.0/geckodriver-v0.24.0-linux64.tar.gz; tar xzf geckodriver-v0.24.0-linux64.tar.gz -C geckodriver; fi - sh -e /etc/init.d/xvfb start - if [ ! -f jar/selenium-server-standalone-3.8.1.jar ]; then wget -q -t 3 -P jar https://selenium-release.storage.googleapis.com/3.8/selenium-server-standalone-3.8.1.jar; fi - - java -Dwebdriver.firefox.marionette=false -Dwebdriver.chrome.driver="$CHROMEDRIVER_PATH" -jar jar/selenium-server-standalone-3.8.1.jar -enablePassThrough false -log ./logs/selenium.log & + - if [ "$GECKODRIVER" = "1" ]; then + geckodriver/geckodriver &> ./logs/geckodriver.log & + else + java -Dwebdriver.firefox.marionette=false -Dwebdriver.chrome.driver="$CHROMEDRIVER_PATH" -jar jar/selenium-server-standalone-3.8.1.jar -enablePassThrough false -log ./logs/selenium.log & + fi - until $(echo | nc localhost 4444); do sleep 1; echo Waiting for Selenium server on port 4444...; done; echo "Selenium server started" - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & - until $(echo | nc localhost 8000); do sleep 1; echo waiting for PHP server on port 8000...; done; echo "PHP server started" @@ -124,6 +129,7 @@ script: after_script: - if [ -f ./logs/selenium.log ]; then cat ./logs/selenium.log; fi - if [ -f ./logs/php-server.log ]; then cat ./logs/php-server.log; fi + - if [ -f ./logs/geckodriver.log ]; then cat ./logs/geckodriver.log; fi after_success: - travis_retry php vendor/bin/php-coveralls -v From 5729355c5d37953d6a1a5a2f55afc7ba1c23bf57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 20 Aug 2019 17:06:26 +0200 Subject: [PATCH 439/784] Improve tests stability --- tests/functional/WebDriverActionsTest.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/functional/WebDriverActionsTest.php b/tests/functional/WebDriverActionsTest.php index b2bd51835..1f03c8899 100644 --- a/tests/functional/WebDriverActionsTest.php +++ b/tests/functional/WebDriverActionsTest.php @@ -78,11 +78,13 @@ public function testShouldClickAndHoldOnElementAndRelease() ->perform(); if ('1' === getenv('GECKODRIVER')) { - $logs = ['mouseover item-1', 'mousedown item-1', 'dragstart item-1']; + $this->assertArraySubset(['mouseover item-1', 'mousedown item-1'], $this->retrieveLoggedEvents()); } else { - $logs = ['mouseover item-1', 'mousedown item-1', 'mouseup item-1', 'click item-1']; + $this->assertSame( + ['mouseover item-1', 'mousedown item-1', 'mouseup item-1', 'click item-1'], + $this->retrieveLoggedEvents() + ); } - $this->assertSame($logs, $this->retrieveLoggedEvents()); } /** From 721a7c2737ea8353c01e76ec7752aa0751e667eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Mon, 4 Nov 2019 19:36:50 +0000 Subject: [PATCH 440/784] Use latest geckodriver --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 906951171..950e8fe64 100644 --- a/.travis.yml +++ b/.travis.yml @@ -108,7 +108,7 @@ install: before_script: - if [ "$BROWSER_NAME" = "chrome" ]; then mkdir chromedriver; CHROMEDRIVER_VERSION=$(wget -qO- "https://chromedriver.storage.googleapis.com/LATEST_RELEASE"); wget -q -t 3 https://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip; unzip chromedriver_linux64 -d chromedriver; fi - if [ "$BROWSER_NAME" = "chrome" ]; then export CHROMEDRIVER_PATH=$PWD/chromedriver/chromedriver; fi - - if [ "$GECKODRIVER" = "1" ]; then mkdir geckodriver; wget -q -t 3 https://github.com/mozilla/geckodriver/releases/download/v0.24.0/geckodriver-v0.24.0-linux64.tar.gz; tar xzf geckodriver-v0.24.0-linux64.tar.gz -C geckodriver; fi + - if [ "$GECKODRIVER" = "1" ]; then mkdir geckodriver; wget -q -t 3 https://github.com/mozilla/geckodriver/releases/download/v0.26.0/geckodriver-v0.26.0-linux64.tar.gz; tar xzf geckodriver-v0.26.0-linux64.tar.gz -C geckodriver; fi - sh -e /etc/init.d/xvfb start - if [ ! -f jar/selenium-server-standalone-3.8.1.jar ]; then wget -q -t 3 -P jar https://selenium-release.storage.googleapis.com/3.8/selenium-server-standalone-3.8.1.jar; fi - if [ "$GECKODRIVER" = "1" ]; then From 71a6698227485b368d4212980ed9efcde15b292f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 5 Nov 2019 15:35:40 +0000 Subject: [PATCH 441/784] Make POST body always valid JSON in W3C mode --- lib/Remote/HttpCommandExecutor.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/Remote/HttpCommandExecutor.php b/lib/Remote/HttpCommandExecutor.php index c783b2892..8114d7817 100644 --- a/lib/Remote/HttpCommandExecutor.php +++ b/lib/Remote/HttpCommandExecutor.php @@ -313,8 +313,13 @@ public function execute(WebDriverCommand $command) $encoded_params = null; - if ($http_method === 'POST' && $params && is_array($params)) { - $encoded_params = json_encode($params); + if ($http_method === 'POST') { + if ($params && is_array($params)) { + $encoded_params = json_encode($params); + } elseif ($this->w3cCompliant) { + // POST body must be valid JSON in W3C, even if empty: https://www.w3.org/TR/webdriver/#processing-model + $encoded_params = '{}'; + } } curl_setopt($this->curl, CURLOPT_POSTFIELDS, $encoded_params); From 7119d7fc97c5291768cd8632a15bfa7d75bff145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 5 Nov 2019 15:37:36 +0000 Subject: [PATCH 442/784] Codestyle: unify casing in w3c methods --- lib/Remote/HttpCommandExecutor.php | 12 +++---- lib/Remote/JsonWireCompat.php | 8 ++--- lib/Remote/RemoteMouse.php | 20 ++++++------ lib/Remote/RemoteTargetLocator.php | 4 +-- lib/Remote/RemoteWebDriver.php | 30 +++++++++--------- lib/Remote/RemoteWebElement.php | 50 ++++++++++++++++-------------- lib/WebDriverOptions.php | 8 ++--- lib/WebDriverTimeouts.php | 12 +++---- 8 files changed, 74 insertions(+), 70 deletions(-) diff --git a/lib/Remote/HttpCommandExecutor.php b/lib/Remote/HttpCommandExecutor.php index 8114d7817..b87c94069 100644 --- a/lib/Remote/HttpCommandExecutor.php +++ b/lib/Remote/HttpCommandExecutor.php @@ -171,7 +171,7 @@ class HttpCommandExecutor implements WebDriverCommandExecutor /** * @var bool */ - protected $w3cCompliant = true; + protected $isW3cCompliant = true; /** * @param string $url @@ -208,9 +208,9 @@ public function __construct($url, $http_proxy = null, $http_proxy_port = null) $this->setConnectionTimeout(30000); } - public function disableW3CCompliance() + public function disableW3cCompliance() { - $this->w3cCompliant = false; + $this->isW3cCompliant = false; } /** @@ -262,12 +262,12 @@ public function execute(WebDriverCommand $command) { $commandName = $command->getName(); if (!isset(self::$commands[$commandName])) { - if ($this->w3cCompliant && !isset(self::$w3cCompliantCommands[$commandName])) { + if ($this->isW3cCompliant && !isset(self::$w3cCompliantCommands[$commandName])) { throw new InvalidArgumentException($command->getName() . ' is not a valid command.'); } } - if ($this->w3cCompliant) { + if ($this->isW3cCompliant) { $raw = self::$w3cCompliantCommands[$command->getName()]; } else { $raw = self::$commands[$command->getName()]; @@ -316,7 +316,7 @@ public function execute(WebDriverCommand $command) if ($http_method === 'POST') { if ($params && is_array($params)) { $encoded_params = json_encode($params); - } elseif ($this->w3cCompliant) { + } elseif ($this->isW3cCompliant) { // POST body must be valid JSON in W3C, even if empty: https://www.w3.org/TR/webdriver/#processing-model $encoded_params = '{}'; } diff --git a/lib/Remote/JsonWireCompat.php b/lib/Remote/JsonWireCompat.php index 78b9cba0e..3488b8604 100644 --- a/lib/Remote/JsonWireCompat.php +++ b/lib/Remote/JsonWireCompat.php @@ -44,16 +44,16 @@ public static function getElement(array $rawElement) /** * @param WebDriverBy $by - * @param bool $w3cCompliant + * @param bool $isW3cCompliant * * @return array */ - public static function getUsing(WebDriverBy $by, $w3cCompliant) + public static function getUsing(WebDriverBy $by, $isW3cCompliant) { $mechanism = $by->getMechanism(); $value = $by->getValue(); - if ($w3cCompliant) { + if ($isW3cCompliant) { switch ($mechanism) { // Convert to CSS selectors case 'class name': @@ -89,7 +89,7 @@ private static function escapeSelector($selector) { return preg_replace_callback('/[^a-z0-9]/iSu', function ($matches) { $chr = $matches[0]; - if (mb_strlen($chr) == 1) { + if (mb_strlen($chr) === 1) { $ord = ord($chr); } else { $chr = mb_convert_encoding($chr, 'UTF-32BE', 'UTF-8'); diff --git a/lib/Remote/RemoteMouse.php b/lib/Remote/RemoteMouse.php index aa0d59829..4bd4a849b 100644 --- a/lib/Remote/RemoteMouse.php +++ b/lib/Remote/RemoteMouse.php @@ -30,16 +30,16 @@ class RemoteMouse implements WebDriverMouse /** * @var bool */ - private $w3cCompliant; + private $isW3cCompliant; /** * @param RemoteExecuteMethod $executor - * @param bool $w3cCompliant + * @param bool $isW3cCompliant */ - public function __construct(RemoteExecuteMethod $executor, $w3cCompliant = false) + public function __construct(RemoteExecuteMethod $executor, $isW3cCompliant = false) { $this->executor = $executor; - $this->w3cCompliant = $w3cCompliant; + $this->isW3cCompliant = $isW3cCompliant; } /** @@ -49,7 +49,7 @@ public function __construct(RemoteExecuteMethod $executor, $w3cCompliant = false */ public function click(WebDriverCoordinates $where = null) { - if ($this->w3cCompliant) { + if ($this->isW3cCompliant) { $moveAction = $where ? [$this->createMoveAction($where)] : []; $this->executor->execute(DriverCommand::ACTIONS, [ 'actions' => [ @@ -80,7 +80,7 @@ public function click(WebDriverCoordinates $where = null) */ public function contextClick(WebDriverCoordinates $where = null) { - if ($this->w3cCompliant) { + if ($this->isW3cCompliant) { $moveAction = $where ? [$this->createMoveAction($where)] : []; $this->executor->execute(DriverCommand::ACTIONS, [ 'actions' => [ @@ -122,7 +122,7 @@ public function contextClick(WebDriverCoordinates $where = null) */ public function doubleClick(WebDriverCoordinates $where = null) { - if ($this->w3cCompliant) { + if ($this->isW3cCompliant) { $clickActions = $this->createClickActions(); $moveAction = null === $where ? [] : [$this->createMoveAction($where)]; $this->executor->execute(DriverCommand::ACTIONS, [ @@ -152,7 +152,7 @@ public function doubleClick(WebDriverCoordinates $where = null) */ public function mouseDown(WebDriverCoordinates $where = null) { - if ($this->w3cCompliant) { + if ($this->isW3cCompliant) { $this->executor->execute(DriverCommand::ACTIONS, [ 'actions' => [ [ @@ -192,7 +192,7 @@ public function mouseMove( $x_offset = null, $y_offset = null ) { - if ($this->w3cCompliant) { + if ($this->isW3cCompliant) { $this->executor->execute(DriverCommand::ACTIONS, [ 'actions' => [ [ @@ -230,7 +230,7 @@ public function mouseMove( */ public function mouseUp(WebDriverCoordinates $where = null) { - if ($this->w3cCompliant) { + if ($this->isW3cCompliant) { $moveAction = $where ? [$this->createMoveAction($where)] : []; $this->executor->execute(DriverCommand::ACTIONS, [ diff --git a/lib/Remote/RemoteTargetLocator.php b/lib/Remote/RemoteTargetLocator.php index 55a879c0d..8bd89ef44 100644 --- a/lib/Remote/RemoteTargetLocator.php +++ b/lib/Remote/RemoteTargetLocator.php @@ -112,8 +112,8 @@ public function activeElement() $response = $this->driver->execute(DriverCommand::GET_ACTIVE_ELEMENT, []); $method = new RemoteExecuteMethod($this->driver); - $w3cCompliant = $this->driver instanceof RemoteWebDriver ? $this->driver->isW3cCompliant() : false; + $isW3cCompliant = ($this->driver instanceof RemoteWebDriver) ? $this->driver->isW3cCompliant() : false; - return new RemoteWebElement($method, JsonWireCompat::getElement($response), $w3cCompliant); + return new RemoteWebElement($method, JsonWireCompat::getElement($response), $isW3cCompliant); } } diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index 6d3a7d833..4d3573c0c 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -62,23 +62,23 @@ class RemoteWebDriver implements WebDriver, JavaScriptExecutor, WebDriverHasInpu /** * @var bool */ - protected $w3cCompliant; + protected $isW3cCompliant; /** * @param HttpCommandExecutor $commandExecutor * @param string $sessionId * @param WebDriverCapabilities|null $capabilities - * @param bool $w3cCompliant false to use the legacy JsonWire protocol, true for the W3C WebDriver spec + * @param bool $isW3cCompliant false to use the legacy JsonWire protocol, true for the W3C WebDriver spec */ protected function __construct( HttpCommandExecutor $commandExecutor, $sessionId, WebDriverCapabilities $capabilities = null, - $w3cCompliant = false + $isW3cCompliant = false ) { $this->executor = $commandExecutor; $this->sessionID = $sessionId; - $this->w3cCompliant = $w3cCompliant; + $this->isW3cCompliant = $isW3cCompliant; if ($capabilities !== null) { $this->capabilities = $capabilities; @@ -168,7 +168,7 @@ public static function create( $value = $response->getValue(); if (!$w3c_compliant = isset($value['capabilities'])) { - $executor->disableW3CCompliance(); + $executor->disableW3cCompliance(); } $returnedCapabilities = new DesiredCapabilities($w3c_compliant ? $value['capabilities'] : $value); @@ -232,7 +232,7 @@ public function findElement(WebDriverBy $by) { $raw_element = $this->execute( DriverCommand::FIND_ELEMENT, - JsonWireCompat::getUsing($by, $this->w3cCompliant) + JsonWireCompat::getUsing($by, $this->isW3cCompliant) ); return $this->newElement(JsonWireCompat::getElement($raw_element)); @@ -249,7 +249,7 @@ public function findElements(WebDriverBy $by) { $raw_elements = $this->execute( DriverCommand::FIND_ELEMENTS, - JsonWireCompat::getUsing($by, $this->w3cCompliant) + JsonWireCompat::getUsing($by, $this->isW3cCompliant) ); $elements = []; @@ -428,7 +428,7 @@ public function wait($timeout_in_second = 30, $interval_in_millisecond = 250) */ public function manage() { - return new WebDriverOptions($this->getExecuteMethod(), $this->w3cCompliant); + return new WebDriverOptions($this->getExecuteMethod(), $this->isW3cCompliant); } /** @@ -459,7 +459,7 @@ public function switchTo() public function getMouse() { if (!$this->mouse) { - $this->mouse = new RemoteMouse($this->getExecuteMethod(), $this->w3cCompliant); + $this->mouse = new RemoteMouse($this->getExecuteMethod(), $this->isW3cCompliant); } return $this->mouse; @@ -605,7 +605,7 @@ public function execute($command_name, $params = []) */ public function isW3cCompliant() { - return $this->w3cCompliant; + return $this->isW3cCompliant; } /** @@ -620,10 +620,12 @@ protected function prepareScriptArguments(array $arguments) foreach ($arguments as $key => $value) { if ($value instanceof WebDriverElement) { $args[$key] = [ - $this->w3cCompliant ? JsonWireCompat::WEB_DRIVER_ELEMENT_IDENTIFIER : 'ELEMENT' => $value->getID(), + $this->isW3cCompliant ? + JsonWireCompat::WEB_DRIVER_ELEMENT_IDENTIFIER + : 'ELEMENT' => $value->getID(), ]; } else { - if (\is_array($value)) { + if (is_array($value)) { $value = $this->prepareScriptArguments($value); } $args[$key] = $value; @@ -653,7 +655,7 @@ protected function getExecuteMethod() */ protected function newElement($id) { - return new RemoteWebElement($this->getExecuteMethod(), $id, $this->w3cCompliant); + return new RemoteWebElement($this->getExecuteMethod(), $id, $this->isW3cCompliant); } /** @@ -669,7 +671,7 @@ protected static function castToDesiredCapabilitiesObject($desired_capabilities return new DesiredCapabilities(); } - if (\is_array($desired_capabilities)) { + if (is_array($desired_capabilities)) { return new DesiredCapabilities($desired_capabilities); } diff --git a/lib/Remote/RemoteWebElement.php b/lib/Remote/RemoteWebElement.php index b07b18227..75dfa3ba2 100644 --- a/lib/Remote/RemoteWebElement.php +++ b/lib/Remote/RemoteWebElement.php @@ -46,19 +46,19 @@ class RemoteWebElement implements WebDriverElement, WebDriverLocatable /** * @var bool */ - protected $w3cCompliant; + protected $isW3cCompliant; /** * @param RemoteExecuteMethod $executor * @param string $id - * @param bool $w3cCompliant + * @param bool $isW3cCompliant */ - public function __construct(RemoteExecuteMethod $executor, $id, $w3cCompliant = false) + public function __construct(RemoteExecuteMethod $executor, $id, $isW3cCompliant = false) { $this->executor = $executor; $this->id = $id; $this->fileDetector = new UselessFileDetector(); - $this->w3cCompliant = $w3cCompliant; + $this->isW3cCompliant = $isW3cCompliant; } /** @@ -73,20 +73,22 @@ public function clear() [':id' => $this->id] ); - if ($this->w3cCompliant) { + if ($this->isW3cCompliant) { $this->executor->execute(DriverCommand::ACTIONS, [ - 'actions' => [[ - 'type' => 'key', - 'id' => 'keyboard', - 'actions' => [ - ['type' => 'keyDown' , 'value' => WebDriverKeys::CONTROL], - ['type' => 'keyDown' , 'value' => 'a'], - ['type' => 'keyUp' , 'value' => WebDriverKeys::CONTROL], - ['type' => 'keyUp' , 'value' => 'a'], - ['type' => 'keyDown' , 'value' => WebDriverKeys::BACKSPACE], - ['type' => 'keyUp' , 'value' => WebDriverKeys::BACKSPACE], + 'actions' => [ + [ + 'type' => 'key', + 'id' => 'keyboard', + 'actions' => [ + ['type' => 'keyDown', 'value' => WebDriverKeys::CONTROL], + ['type' => 'keyDown', 'value' => 'a'], + ['type' => 'keyUp', 'value' => WebDriverKeys::CONTROL], + ['type' => 'keyUp', 'value' => 'a'], + ['type' => 'keyDown', 'value' => WebDriverKeys::BACKSPACE], + ['type' => 'keyUp', 'value' => WebDriverKeys::BACKSPACE], + ], ], - ]], + ], ]); } @@ -118,7 +120,7 @@ public function click() */ public function findElement(WebDriverBy $by) { - $params = JsonWireCompat::getUsing($by, $this->w3cCompliant); + $params = JsonWireCompat::getUsing($by, $this->isW3cCompliant); $params[':id'] = $this->id; $raw_element = $this->executor->execute( @@ -139,7 +141,7 @@ public function findElement(WebDriverBy $by) */ public function findElements(WebDriverBy $by) { - $params = JsonWireCompat::getUsing($by, $this->w3cCompliant); + $params = JsonWireCompat::getUsing($by, $this->isW3cCompliant); $params[':id'] = $this->id; $raw_elements = $this->executor->execute( DriverCommand::FIND_CHILD_ELEMENTS, @@ -167,7 +169,7 @@ public function getAttribute($attribute_name) ':id' => $this->id, ]; - if ($this->w3cCompliant && ($attribute_name === 'value' || $attribute_name === 'index')) { + if ($this->isW3cCompliant && ($attribute_name === 'value' || $attribute_name === 'index')) { $value = $this->executor->execute(DriverCommand::GET_ELEMENT_PROPERTY, $params); if ($value === true) { @@ -357,7 +359,7 @@ public function sendKeys($value) { $local_file = $this->fileDetector->getLocalFile($value); if ($local_file === null) { - if ($this->w3cCompliant) { + if ($this->isW3cCompliant) { $params = [ 'text' => (string) $value, ':id' => $this->id, @@ -374,7 +376,7 @@ public function sendKeys($value) return $this; } - if ($this->w3cCompliant) { + if ($this->isW3cCompliant) { $params = [ 'text' => $local_file, ':id' => $this->id, @@ -420,7 +422,7 @@ public function setFileDetector(FileDetector $detector) */ public function submit() { - if ($this->w3cCompliant) { + if ($this->isW3cCompliant) { $this->executor->execute(DriverCommand::EXECUTE_SCRIPT, [ // cannot call the submit method directly in case an input of this form is named "submit" 'script' => sprintf( @@ -459,7 +461,7 @@ public function getID() */ public function equals(WebDriverElement $other) { - if ($this->w3cCompliant) { + if ($this->isW3cCompliant) { throw new UnsupportedOperationException('"elementEquals" is not supported by the W3C specification'); } @@ -478,7 +480,7 @@ public function equals(WebDriverElement $other) */ protected function newElement($id) { - return new static($this->executor, $id, $this->w3cCompliant); + return new static($this->executor, $id, $this->isW3cCompliant); } /** diff --git a/lib/WebDriverOptions.php b/lib/WebDriverOptions.php index 4c584bd07..682918a17 100644 --- a/lib/WebDriverOptions.php +++ b/lib/WebDriverOptions.php @@ -31,12 +31,12 @@ class WebDriverOptions /** * @var bool */ - protected $w3cCompliant; + protected $isW3cCompliant; - public function __construct(ExecuteMethod $executor, $w3cCompliant = false) + public function __construct(ExecuteMethod $executor, $isW3cCompliant = false) { $this->executor = $executor; - $this->w3cCompliant = $w3cCompliant; + $this->isW3cCompliant = $isW3cCompliant; } /** @@ -133,7 +133,7 @@ public function getCookies() */ public function timeouts() { - return new WebDriverTimeouts($this->executor, $this->w3cCompliant); + return new WebDriverTimeouts($this->executor, $this->isW3cCompliant); } /** diff --git a/lib/WebDriverTimeouts.php b/lib/WebDriverTimeouts.php index eeba9a10e..5735cb48d 100644 --- a/lib/WebDriverTimeouts.php +++ b/lib/WebDriverTimeouts.php @@ -30,12 +30,12 @@ class WebDriverTimeouts /** * @var bool */ - protected $w3cCompliant; + protected $isW3cCompliant; - public function __construct(ExecuteMethod $executor, $w3cCompliant = false) + public function __construct(ExecuteMethod $executor, $isW3cCompliant = false) { $this->executor = $executor; - $this->w3cCompliant = $w3cCompliant; + $this->isW3cCompliant = $isW3cCompliant; } /** @@ -46,7 +46,7 @@ public function __construct(ExecuteMethod $executor, $w3cCompliant = false) */ public function implicitlyWait($seconds) { - if ($this->w3cCompliant) { + if ($this->isW3cCompliant) { $this->executor->execute( DriverCommand::IMPLICITLY_WAIT, ['implicit' => $seconds * 1000] @@ -71,7 +71,7 @@ public function implicitlyWait($seconds) */ public function setScriptTimeout($seconds) { - if ($this->w3cCompliant) { + if ($this->isW3cCompliant) { $this->executor->execute( DriverCommand::SET_SCRIPT_TIMEOUT, ['script' => $seconds * 1000] @@ -96,7 +96,7 @@ public function setScriptTimeout($seconds) */ public function pageLoadTimeout($seconds) { - if ($this->w3cCompliant) { + if ($this->isW3cCompliant) { $this->executor->execute( DriverCommand::SET_SCRIPT_TIMEOUT, ['pageLoad' => $seconds * 1000] From bd34170cb3c17322dbc785fede30b6c88ffd651c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 28 Oct 2019 18:21:02 +0100 Subject: [PATCH 443/784] Compatibility with Symfony 5 --- CHANGELOG.md | 1 + composer.json | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1e733516..e2662351d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ### Changed - Revert no longer needed workaround for Chromedriver bug [2943](https://bugs.chromium.org/p/chromedriver/issues/detail?id=2943). +- Allow installation of Symfony 5 components. ## 1.7.1 - 2019-06-13 ### Fixed diff --git a/composer.json b/composer.json index 2a9929725..3a841a504 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ "minimum-stability": "beta", "require": { "php": "^5.6 || ~7.0", - "symfony/process": "^2.8 || ^3.1 || ^4.0", + "symfony/process": "^2.8 || ^3.1 || ^4.0 || ^5.0", "ext-curl": "*", "ext-zip": "*", "ext-mbstring": "*", @@ -26,7 +26,7 @@ "squizlabs/php_codesniffer": "^2.6", "php-mock/php-mock-phpunit": "^1.1", "php-coveralls/php-coveralls": "^2.0", - "symfony/var-dumper": "^3.3 || ^4.0", + "symfony/var-dumper": "^3.3 || ^4.0 || ^5.0", "jakub-onderka/php-parallel-lint": "^0.9.2" }, "suggest": { From e9277912d553971c2b73bf19df3fb44323f1f8b7 Mon Sep 17 00:00:00 2001 From: Mohammadreza Yektamaram Date: Tue, 1 Oct 2019 14:51:24 +0330 Subject: [PATCH 444/784] Minor grammar fixes --- README.md | 2 +- example.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b25bee453..0fa9db31c 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ We have a great community willing to help you! - **Via our Facebook Group** - If you have questions or are an active contributor consider joining our [facebook group](https://www.facebook.com/groups/phpwebdriver/) and contribute to communal discussion and support - **Via StackOverflow** - You can also [ask a question](https://stackoverflow.com/questions/ask?tags=php+selenium-webdriver) or find many already answered question on StackOverflow -- **Via GitHub** - Another option if you have a question (or bug report) is to [submit it here](https://github.com/facebook/php-webdriver/issues/new) as an new issue +- **Via GitHub** - Another option if you have a question (or bug report) is to [submit it here](https://github.com/facebook/php-webdriver/issues/new) as a new issue ## Contributing diff --git a/example.php b/example.php index f1109ed54..4dbb93900 100644 --- a/example.php +++ b/example.php @@ -23,7 +23,7 @@ require_once('vendor/autoload.php'); -// start Chrome with 5 second timeout +// start Chrome with 5 seconds timeout $host = 'http://localhost:4444/wd/hub'; // this is the default $capabilities = DesiredCapabilities::chrome(); $driver = RemoteWebDriver::create($host, $capabilities, 5000); From a21b3c82dabb8a777e81aed5a8239cba67efc115 Mon Sep 17 00:00:00 2001 From: "Benjamin R. White" Date: Tue, 27 Feb 2018 17:21:16 +0000 Subject: [PATCH 445/784] Allow combined not() and presenceOfElementLocated() functionality --- CHANGELOG.md | 3 +++ lib/WebDriverExpectedCondition.php | 9 ++++--- tests/unit/WebDriverExpectedConditionTest.php | 24 ++++++++++++++++++- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2662351d..bbd2f4d52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). - Revert no longer needed workaround for Chromedriver bug [2943](https://bugs.chromium.org/p/chromedriver/issues/detail?id=2943). - Allow installation of Symfony 5 components. +### Fixed +- `WebDriverExpectedCondition::presenceOfElementLocated()` works correctly when used within `WebDriverExpectedCondition::not()`. + ## 1.7.1 - 2019-06-13 ### Fixed - Error `Call to a member function toArray()` if capabilities were already converted to an array. diff --git a/lib/WebDriverExpectedCondition.php b/lib/WebDriverExpectedCondition.php index 15c7b3d2d..4bab4707b 100644 --- a/lib/WebDriverExpectedCondition.php +++ b/lib/WebDriverExpectedCondition.php @@ -148,7 +148,11 @@ public static function presenceOfElementLocated(WebDriverBy $by) { return new static( function (WebDriver $driver) use ($by) { - return $driver->findElement($by); + try { + return $driver->findElement($by); + } catch (NoSuchElementException $e) { + return false; + } } ); } @@ -423,8 +427,7 @@ function (WebDriver $driver) use ($by, $text) { */ public static function elementToBeClickable(WebDriverBy $by) { - $visibility_of_element_located = - self::visibilityOfElementLocated($by); + $visibility_of_element_located = self::visibilityOfElementLocated($by); return new static( function (WebDriver $driver) use ($visibility_of_element_located) { diff --git a/tests/unit/WebDriverExpectedConditionTest.php b/tests/unit/WebDriverExpectedConditionTest.php index 8cd4203a9..6dde484ef 100644 --- a/tests/unit/WebDriverExpectedConditionTest.php +++ b/tests/unit/WebDriverExpectedConditionTest.php @@ -135,6 +135,28 @@ public function testShouldDetectPresenceOfElementLocatedCondition() $this->assertSame($element, $this->wait->until($condition)); } + public function testShouldDetectNotPresenceOfElementLocatedCondition() + { + $element = new RemoteWebElement(new RemoteExecuteMethod($this->driverMock), 'id'); + + $this->driverMock->expects($this->at(0)) + ->method('findElement') + ->with($this->isInstanceOf(WebDriverBy::class)) + ->willReturn($element); + + $this->driverMock->expects($this->at(1)) + ->method('findElement') + ->with($this->isInstanceOf(WebDriverBy::class)) + ->willThrowException(new NoSuchElementException('')); + + $condition = WebDriverExpectedCondition::not( + WebDriverExpectedCondition::presenceOfElementLocated(WebDriverBy::cssSelector('.foo')) + ); + + $this->assertFalse(call_user_func($condition->getApply(), $this->driverMock)); + $this->assertTrue(call_user_func($condition->getApply(), $this->driverMock)); + } + public function testShouldDetectPresenceOfAllElementsLocatedByCondition() { $element = $this->createMock(RemoteWebElement::class); @@ -160,7 +182,7 @@ public function testShouldDetectVisibilityOfElementLocatedCondition() // Call #1: throws NoSuchElementException // Call #2: return Element, but isDisplayed will throw StaleElementReferenceException // Call #3: return Element, but isDisplayed will return false - // Call #4: return Element, isDisplayed will true and condition will match + // Call #4: return Element, isDisplayed will return true and condition will match $element = $this->createMock(RemoteWebElement::class); $element->expects($this->at(0)) From 1f8d242f98310b12d8dbfc39859aad6b13f35708 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 1 Oct 2018 12:16:55 +0200 Subject: [PATCH 446/784] Use polyfill-mbstring when ext-mbstring isn't available --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 3a841a504..e5aef5a03 100644 --- a/composer.json +++ b/composer.json @@ -14,9 +14,9 @@ "require": { "php": "^5.6 || ~7.0", "symfony/process": "^2.8 || ^3.1 || ^4.0 || ^5.0", + "symfony/polyfill-mbstring": "^1.12", "ext-curl": "*", "ext-zip": "*", - "ext-mbstring": "*", "ext-json": "*" }, "require-dev": { From dc50f3f0fd5506230f4fcc48670bf1edcf1d65ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Mon, 11 Nov 2019 00:04:33 +0100 Subject: [PATCH 447/784] Skipped tests must be completely excluded from Saucelabs to avoid starting the driver there, otherwise the build is not marked passed on Saucelabs dashboard --- tests/functional/RemoteWebDriverFindElementTest.php | 3 +++ tests/functional/WebDriverActionsTest.php | 1 + 2 files changed, 4 insertions(+) diff --git a/tests/functional/RemoteWebDriverFindElementTest.php b/tests/functional/RemoteWebDriverFindElementTest.php index 066179f1f..2eb3e38c7 100644 --- a/tests/functional/RemoteWebDriverFindElementTest.php +++ b/tests/functional/RemoteWebDriverFindElementTest.php @@ -62,6 +62,9 @@ public function testShouldFindMultipleElements() $this->assertContainsOnlyInstancesOf(RemoteWebElement::class, $elements); } + /** + * @group exclude-saucelabs + */ public function testEscapeCssSelector() { if (getenv('GECKODRIVER') !== '1') { diff --git a/tests/functional/WebDriverActionsTest.php b/tests/functional/WebDriverActionsTest.php index 1f03c8899..07af88085 100644 --- a/tests/functional/WebDriverActionsTest.php +++ b/tests/functional/WebDriverActionsTest.php @@ -88,6 +88,7 @@ public function testShouldClickAndHoldOnElementAndRelease() } /** + * @group exclude-saucelabs * @covers ::__construct * @covers ::contextClick * @covers ::perform From a29494a551b8efb8afef51dc4f7af2cb7af98d9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 10 Nov 2019 23:01:03 +0100 Subject: [PATCH 448/784] Add Chromedriver Travis build (without Selenium server proxy) --- .travis.yml | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 950e8fe64..986df3e31 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,8 @@ env: matrix: include: # Codestyle check build - - php: '7.3' + - name: 'Code style and static analysis' + php: '7.3' env: CHECK_CODESTYLE=1 before_install: - phpenv config-rm xdebug.ini @@ -30,18 +31,19 @@ matrix: after_success: ~ # Build with lowest possible dependencies on lowest possible PHP - - php: '5.6' + - name: 'Lowest dependencies build' + php: '5.6' env: DEPENDENCIES="--prefer-lowest" # Firefox inside Travis environment - - name: 'Firefox 45 on Travis (OSS protocol)' + - name: 'Firefox 45 on Travis (OSS protocol); via Selenium server' php: '7.3' env: BROWSER_NAME="firefox" addons: firefox: "45.8.0esr" # Firefox with Geckodriver (W3C mode) inside Travis environment - - name: 'Firefox latest on Travis (W3C protocol)' + - name: 'Firefox latest on Travis (W3C protocol); no Selenium server' php: 7.3 env: - BROWSER_NAME="firefox" @@ -49,9 +51,22 @@ matrix: addons: firefox: latest - # Stable Chrome + Chromedriver inside Travis environment - - php: '7.3' - env: BROWSER_NAME="chrome" CHROME_HEADLESS="1" + # Stable Chrome + Chromedriver inside Travis environment via Selenium server proxy + - name: 'Chrome stable on Travis; via Selenium server' + php: '7.3' + env: + - BROWSER_NAME="chrome" + - CHROME_HEADLESS="1" + addons: + chrome: stable + + # Stable Chrome + Chromedriver inside Travis environment directly via Chromedriver + - name: 'Chrome stable on Travis; no Selenium server' + php: '7.3' + env: + - BROWSER_NAME="chrome" + - CHROME_HEADLESS="1" + - CHROMEDRIVER="1" addons: chrome: stable @@ -113,6 +128,8 @@ before_script: - if [ ! -f jar/selenium-server-standalone-3.8.1.jar ]; then wget -q -t 3 -P jar https://selenium-release.storage.googleapis.com/3.8/selenium-server-standalone-3.8.1.jar; fi - if [ "$GECKODRIVER" = "1" ]; then geckodriver/geckodriver &> ./logs/geckodriver.log & + elif [ "$CHROMEDRIVER" = "1" ]; then + chromedriver/chromedriver --port=4444 --url-base=/wd/hub &> ./logs/chromedriver.log & else java -Dwebdriver.firefox.marionette=false -Dwebdriver.chrome.driver="$CHROMEDRIVER_PATH" -jar jar/selenium-server-standalone-3.8.1.jar -enablePassThrough false -log ./logs/selenium.log & fi @@ -130,6 +147,7 @@ after_script: - if [ -f ./logs/selenium.log ]; then cat ./logs/selenium.log; fi - if [ -f ./logs/php-server.log ]; then cat ./logs/php-server.log; fi - if [ -f ./logs/geckodriver.log ]; then cat ./logs/geckodriver.log; fi + - if [ -f ./logs/chromedriver.log ]; then cat ./logs/chromedriver.log; fi after_success: - travis_retry php vendor/bin/php-coveralls -v From 61ab881143846201c314bc9f9988a8831a75f26f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 10 Nov 2019 23:51:18 +0100 Subject: [PATCH 449/784] Use newer Selenium server where possible But we can easily update only to 3.14.0 (latest version which includes HtmlUnit). However update to 3.14.159 should be done soon (but HtmlUnit needs to be sideloaded). --- .travis.yml | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 986df3e31..fc7368965 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,7 @@ env: global: - DISPLAY=:99.0 - BROWSER_NAME="htmlunit" + - SELENIUM_SERVER="https://selenium-release.storage.googleapis.com/3.14/selenium-server-standalone-3.14.0.jar" # Latest version including HtmlUnit matrix: include: @@ -36,9 +37,11 @@ matrix: env: DEPENDENCIES="--prefer-lowest" # Firefox inside Travis environment - - name: 'Firefox 45 on Travis (OSS protocol); via Selenium server' + - name: 'Firefox 45 on Travis (OSS protocol); via legacy Selenium server' php: '7.3' - env: BROWSER_NAME="firefox" + env: + - BROWSER_NAME="firefox" + - SELENIUM_SERVER="legacy" addons: firefox: "45.8.0esr" @@ -114,7 +117,6 @@ matrix: cache: directories: - $HOME/.composer/cache - - jar install: - travis_retry composer self-update @@ -123,15 +125,24 @@ install: before_script: - if [ "$BROWSER_NAME" = "chrome" ]; then mkdir chromedriver; CHROMEDRIVER_VERSION=$(wget -qO- "https://chromedriver.storage.googleapis.com/LATEST_RELEASE"); wget -q -t 3 https://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip; unzip chromedriver_linux64 -d chromedriver; fi - if [ "$BROWSER_NAME" = "chrome" ]; then export CHROMEDRIVER_PATH=$PWD/chromedriver/chromedriver; fi - - if [ "$GECKODRIVER" = "1" ]; then mkdir geckodriver; wget -q -t 3 https://github.com/mozilla/geckodriver/releases/download/v0.26.0/geckodriver-v0.26.0-linux64.tar.gz; tar xzf geckodriver-v0.26.0-linux64.tar.gz -C geckodriver; fi - - sh -e /etc/init.d/xvfb start - - if [ ! -f jar/selenium-server-standalone-3.8.1.jar ]; then wget -q -t 3 -P jar https://selenium-release.storage.googleapis.com/3.8/selenium-server-standalone-3.8.1.jar; fi + - if [ "$GECKODRIVER" = "1" ]; then mkdir -p geckodriver; wget -q -t 3 https://github.com/mozilla/geckodriver/releases/download/v0.26.0/geckodriver-v0.26.0-linux64.tar.gz; tar xzf geckodriver-v0.26.0-linux64.tar.gz -C geckodriver; fi + - sh -e /etc/init.d/xvfb start # TODO: start only when needed (ie. not in headless mode) + - if [ ! -f jar/selenium-server-standalone.jar ] && [ -n "$SELENIUM_SERVER" ]; then + mkdir -p jar; + if [ "$SELENIUM_SERVER" = "legacy" ]; then + wget -q -t 3 -O jar/selenium-server-standalone.jar https://selenium-release.storage.googleapis.com/3.8/selenium-server-standalone-3.8.1.jar; + else + wget -q -t 3 -O jar/selenium-server-standalone.jar $SELENIUM_SERVER; + fi + fi - if [ "$GECKODRIVER" = "1" ]; then geckodriver/geckodriver &> ./logs/geckodriver.log & elif [ "$CHROMEDRIVER" = "1" ]; then chromedriver/chromedriver --port=4444 --url-base=/wd/hub &> ./logs/chromedriver.log & + elif [ "$SELENIUM_SERVER" = "legacy" ]; then + java -Dwebdriver.firefox.marionette=false -Dwebdriver.chrome.driver="$PWD/chromedriver/chromedriver" -jar jar/selenium-server-standalone.jar -enablePassThrough false -log ./logs/selenium.log & else - java -Dwebdriver.firefox.marionette=false -Dwebdriver.chrome.driver="$CHROMEDRIVER_PATH" -jar jar/selenium-server-standalone-3.8.1.jar -enablePassThrough false -log ./logs/selenium.log & + java -Dwebdriver.chrome.driver="$PWD/chromedriver/chromedriver" -Dwebdriver.gecko.driver="$PWD/geckodriver/geckodriver" -jar jar/selenium-server-standalone.jar -log ./logs/selenium.log & fi - until $(echo | nc localhost 4444); do sleep 1; echo Waiting for Selenium server on port 4444...; done; echo "Selenium server started" - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & From a4b0d7130ed35c2083f62ae0bb135c563df68364 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Mon, 11 Nov 2019 10:21:11 +0100 Subject: [PATCH 450/784] Convert W3C invalid capabilities to corresponding ones This avoids `Facebook\WebDriver\Exception\UnknownServerException: Illegal key values seen in w3c capabilities: [chromeOptions]` error with new Selenium server. This conversion is necessary to maintain BC - simply renaming chromeOptions to goog:chromeOptions will break capabilities with Chromedriver <2.31. --- lib/Chrome/ChromeOptions.php | 7 ++++++- lib/Remote/RemoteWebDriver.php | 32 ++++++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/lib/Chrome/ChromeOptions.php b/lib/Chrome/ChromeOptions.php index 901dc5388..949d6708b 100644 --- a/lib/Chrome/ChromeOptions.php +++ b/lib/Chrome/ChromeOptions.php @@ -25,9 +25,14 @@ class ChromeOptions { /** - * The key of chrome options in desired capabilities. + * The key of chrome options desired capabilities (in legacy OSS JsonWire protocol) + * @deprecated */ const CAPABILITY = 'chromeOptions'; + /** + * The key of chrome options desired capabilities (in W3C compatible protocol) + */ + const CAPABILITY_W3C = 'goog:chromeOptions'; /** * @var array */ diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index 4d3573c0c..c87a572f9 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -140,15 +140,15 @@ public static function create( // W3C $parameters = [ 'capabilities' => [ - 'firstMatch' => [$desired_capabilities->toArray()], + 'firstMatch' => [static::convertCapabilitiesToW3c($desired_capabilities->toArray())], ], ]; - // Legacy protocol - if (null !== $required_capabilities && $required_capabilities_array = $required_capabilities->toArray()) { - $parameters['capabilities']['alwaysMatch'] = $required_capabilities_array; + if ($required_capabilities !== null && $required_capabilities_array = $required_capabilities->toArray()) { + $parameters['capabilities']['alwaysMatch'] = static::convertCapabilitiesToW3c($required_capabilities_array); } + // Legacy protocol if ($required_capabilities !== null) { // TODO: Selenium (as of v3.0.1) does accept requiredCapabilities only as a property of desiredCapabilities. // This has changed with the W3C WebDriver spec, but is the only way how to pass these @@ -677,4 +677,28 @@ protected static function castToDesiredCapabilitiesObject($desired_capabilities return $desired_capabilities; } + + /** + * Convert keys invalid in W3C capabilities to corresponding ones for W3C. + * + * @param array $capabilitiesArray + * @return array + */ + protected static function convertCapabilitiesToW3c(array $capabilitiesArray) + { + if (array_key_exists(ChromeOptions::CAPABILITY, $capabilitiesArray)) { + if (array_key_exists(ChromeOptions::CAPABILITY_W3C, $capabilitiesArray)) { + $capabilitiesArray[ChromeOptions::CAPABILITY_W3C] = array_merge( + $capabilitiesArray[ChromeOptions::CAPABILITY], + $capabilitiesArray[ChromeOptions::CAPABILITY_W3C] + ); + } else { + $capabilitiesArray[ChromeOptions::CAPABILITY_W3C] = $capabilitiesArray[ChromeOptions::CAPABILITY]; + } + + unset($capabilitiesArray[ChromeOptions::CAPABILITY]); + } + + return $capabilitiesArray; + } } From 3597a6bcaddb2a462d71cf81620346892991ad47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Mon, 11 Nov 2019 10:37:25 +0100 Subject: [PATCH 451/784] =?UTF-8?q?Enable=20W3C=20protocol=20for=20Chromed?= =?UTF-8?q?river=20=F0=9F=8E=89=20#469?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Until now, W3C was forcily disabled for Chromedriver using Capabilities on startup. As we now experimentaly support W3C protocol, this is no longer needed. If W3C is detected during initial handshake, the browser will be started using W3C dialect (otherwise it will use legacy OSS JsonWire protocol). --- lib/Remote/RemoteWebDriver.php | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index c87a572f9..d2e302f44 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -112,23 +112,6 @@ public static function create( $desired_capabilities = self::castToDesiredCapabilitiesObject($desired_capabilities); - // Hotfix: W3C WebDriver protocol is not yet supported by php-webdriver, so we must force Chromedriver to - // not use the W3C protocol by default (which is what Chromedriver does starting with version 75). - if ($desired_capabilities->getBrowserName() === WebDriverBrowserType::CHROME - && mb_strpos($selenium_server_url, 'browserstack') === false // see https://github.com/facebook/php-webdriver/issues/644 - ) { - $currentChromeOptions = $desired_capabilities->getCapability(ChromeOptions::CAPABILITY); - $chromeOptions = !empty($currentChromeOptions) ? $currentChromeOptions : new ChromeOptions(); - - if ($chromeOptions instanceof ChromeOptions && !isset($chromeOptions->toArray()['w3c'])) { - $chromeOptions->setExperimentalOption('w3c', false); - } elseif (is_array($chromeOptions) && !isset($chromeOptions['w3c'])) { - $chromeOptions['w3c'] = false; - } - - $desired_capabilities->setCapability(ChromeOptions::CAPABILITY, $chromeOptions); - } - $executor = new HttpCommandExecutor($selenium_server_url, $http_proxy, $http_proxy_port); if ($connection_timeout_in_ms !== null) { $executor->setConnectionTimeout($connection_timeout_in_ms); From a9685bf2aa22de07d97ca93ff452e5016ee3141d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Mon, 11 Nov 2019 12:41:45 +0100 Subject: [PATCH 452/784] Add JsonWire travis build on Chromedriver to make sure we won't break the old protocol --- .travis.yml | 19 +++++++++++++++---- tests/functional/WebDriverTestCase.php | 5 +++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index fc7368965..4a8a268a8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -54,8 +54,8 @@ matrix: addons: firefox: latest - # Stable Chrome + Chromedriver inside Travis environment via Selenium server proxy - - name: 'Chrome stable on Travis; via Selenium server' + # Stable Chrome + Chromedriver (W3C mode) inside Travis environment via Selenium server proxy + - name: 'Chrome stable on Travis (W3C protocol); via Selenium server' php: '7.3' env: - BROWSER_NAME="chrome" @@ -63,8 +63,8 @@ matrix: addons: chrome: stable - # Stable Chrome + Chromedriver inside Travis environment directly via Chromedriver - - name: 'Chrome stable on Travis; no Selenium server' + # Stable Chrome + Chromedriver (W3C mode) inside Travis environment directly via Chromedriver + - name: 'Chrome stable on Travis (W3C protocol); no Selenium server' php: '7.3' env: - BROWSER_NAME="chrome" @@ -73,6 +73,17 @@ matrix: addons: chrome: stable + # Stable Chrome + Chromedriver (JsonWire OSS mode) inside Travis environment directly via Chromedriver + - name: 'Chrome stable on Travis (OSS protocol); no Selenium server' + php: '7.3' + env: + - BROWSER_NAME="chrome" + - CHROME_HEADLESS="1" + - CHROMEDRIVER="1" + - DISABLE_W3C_PROTOCOL="1" + addons: + chrome: stable + # Saucelabs builds - php: '7.3' env: SAUCELABS=1 BROWSER_NAME="firefox" VERSION="47.0" PLATFORM="Windows 10" diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index 7a0f8af23..920eb86a7 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -57,6 +57,11 @@ protected function setUp() $chromeOptions = new ChromeOptions(); // --no-sandbox is a workaround for Chrome crashing: https://github.com/SeleniumHQ/selenium/issues/4961 $chromeOptions->addArguments(['--headless', 'window-size=1024,768', '--no-sandbox']); + + if (getenv('DISABLE_W3C_PROTOCOL')) { + $chromeOptions->setExperimentalOption('w3c', false); + } + $this->desiredCapabilities->setCapability(ChromeOptions::CAPABILITY, $chromeOptions); } elseif (getenv('GECKODRIVER') === '1') { $this->serverUrl = 'http://localhost:4444/'; From 041658be9e1284578f5fba1198b10dc8922ceb0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Mon, 11 Nov 2019 13:25:45 +0100 Subject: [PATCH 453/784] Improve W3C builds detection in conditionally-run tests --- .../RemoteWebDriverFindElementTest.php | 8 +++--- tests/functional/RemoteWebDriverTest.php | 1 - tests/functional/RemoteWebElementTest.php | 4 +-- tests/functional/WebDriverActionsTest.php | 4 +-- tests/functional/WebDriverTestCase.php | 26 +++++++++++++++++++ 5 files changed, 32 insertions(+), 11 deletions(-) diff --git a/tests/functional/RemoteWebDriverFindElementTest.php b/tests/functional/RemoteWebDriverFindElementTest.php index 2eb3e38c7..c5671b497 100644 --- a/tests/functional/RemoteWebDriverFindElementTest.php +++ b/tests/functional/RemoteWebDriverFindElementTest.php @@ -67,11 +67,9 @@ public function testShouldFindMultipleElements() */ public function testEscapeCssSelector() { - if (getenv('GECKODRIVER') !== '1') { - $this->markTestSkipped( - 'CSS selectors containing special characters are not supported by the legacy protocol' - ); - } + self::skipForJsonWireProtocol( + 'CSS selectors containing special characters are not supported by the legacy protocol' + ); $this->driver->get($this->getTestPageUrl('escape_css.html')); diff --git a/tests/functional/RemoteWebDriverTest.php b/tests/functional/RemoteWebDriverTest.php index 9105aa93f..72fc30505 100644 --- a/tests/functional/RemoteWebDriverTest.php +++ b/tests/functional/RemoteWebDriverTest.php @@ -150,7 +150,6 @@ public function testShouldCloseWindow() $this->driver->get($this->getTestPageUrl('open_new_window.html')); $this->driver->findElement(WebDriverBy::cssSelector('a'))->click(); - // Mandatory for Geckodriver $this->driver->wait()->until(WebDriverExpectedCondition::numberOfWindowsToBe(2)); $this->assertCount(2, $this->driver->getWindowHandles()); diff --git a/tests/functional/RemoteWebElementTest.php b/tests/functional/RemoteWebElementTest.php index a4684ace3..52877dcda 100644 --- a/tests/functional/RemoteWebElementTest.php +++ b/tests/functional/RemoteWebElementTest.php @@ -272,9 +272,7 @@ public function testShouldSubmitFormByClickOnSubmitInput() */ public function testShouldCompareEqualsElement() { - if (getenv('GECKODRIVER') === '1') { - $this->markTestSkipped('"equals" is not supported by the W3C specification'); - } + self::skipForW3cProtocol('"equals" is not supported by the W3C specification'); $this->driver->get($this->getTestPageUrl('index.html')); diff --git a/tests/functional/WebDriverActionsTest.php b/tests/functional/WebDriverActionsTest.php index 07af88085..9798f6e5a 100644 --- a/tests/functional/WebDriverActionsTest.php +++ b/tests/functional/WebDriverActionsTest.php @@ -49,7 +49,7 @@ public function testShouldClickOnElement() $logs = ['mouseover item-1', 'mousedown item-1', 'mouseup item-1', 'click item-1']; $loggedEvents = $this->retrieveLoggedEvents(); - if ('1' === getenv('GECKODRIVER')) { + if (getenv('GECKODRIVER') === '1') { $loggedEvents = array_slice($loggedEvents, 0, count($logs)); // Firefox sometimes triggers some extra events // it's not related to Geckodriver, it's Firefox's own behavior @@ -77,7 +77,7 @@ public function testShouldClickAndHoldOnElementAndRelease() ->release() ->perform(); - if ('1' === getenv('GECKODRIVER')) { + if (self::isW3cProtocolBuild()) { $this->assertArraySubset(['mouseover item-1', 'mousedown item-1'], $this->retrieveLoggedEvents()); } else { $this->assertSame( diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index 920eb86a7..8b35a7700 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -102,6 +102,32 @@ public static function isSauceLabsBuild() return getenv('SAUCELABS') ? true : false; } + /** + * @return bool + */ + public static function isW3cProtocolBuild() + { + return getenv('GECKODRIVER') === '1' + || (getenv('BROWSER_NAME') === 'chrome' + && getenv('DISABLE_W3C_PROTOCOL') !== '1' + && !self::isSauceLabsBuild()); + } + + public static function skipForW3cProtocol($message = 'Not supported by W3C specification') + { + if (static::isW3cProtocolBuild()) { + static::markTestSkipped($message); + } + } + + public static function skipForJsonWireProtocol($message = 'Not supported by JsonWire protocol') + { + if (getenv('GECKODRIVER') !== '1' + && (getenv('CHROMEDRIVER') !== '1' || getenv('DISABLE_W3C_PROTOCOL') === '1')) { + static::markTestSkipped($message); + } + } + /** * Get the URL of given test HTML on running webserver. * From d249dea3f0da638c2d44c028b4a5d9247cc2fa87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Mon, 11 Nov 2019 16:36:05 +0100 Subject: [PATCH 454/784] Update changelog and readme to let the world know about W3C protocol experimental support --- CHANGELOG.md | 3 +++ README.md | 38 ++++++++++++++++++-------------------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bbd2f4d52..b83a21743 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ This project versioning adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +### Added +- Experimental W3C WebDriver protocol support. The protocol will be used automatically when remote end (like Geckodriver, newer Chromedriver etc.) supports it. + ### Changed - Revert no longer needed workaround for Chromedriver bug [2943](https://bugs.chromium.org/p/chromedriver/issues/detail?id=2943). - Allow installation of Symfony 5 components. diff --git a/README.md b/README.md index 0fa9db31c..71742583b 100644 --- a/README.md +++ b/README.md @@ -9,16 +9,16 @@ ## Description Php-webdriver library is PHP language binding for Selenium WebDriver, which allows you to control web browsers from PHP. -This library is compatible with Selenium server version 2.x and 3.x. -It implements the [JsonWireProtocol](https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol), which is currently supported -by the Selenium server and will also implement the [W3C WebDriver](https://w3c.github.io/webdriver/webdriver-spec.html) specification in the future. +This library is compatible with Selenium server version 2.x, 3.x and 4.x. + +The library supports [JsonWireProtocol](https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol) and also +implements **experimental support** of [W3C WebDriver](https://w3c.github.io/webdriver/webdriver-spec.html). +The W3C WebDriver support is not yet full-featured, however it should allow to control Firefox via Geckodriver and new +versions of Chrome and Chromedriver with just a slight limitations. The concepts of this library are very similar to the "official" Java, .NET, Python and Ruby bindings from the [Selenium project](https://github.com/SeleniumHQ/selenium/). -**As of 2013, this PHP client has been rewritten from scratch.** -Using the old version? Check out [Adam Goucher's fork](https://github.com/Element-34/php-webdriver) of it. - Looking for API documentation of php-webdriver? See [https://facebook.github.io/php-webdriver/](https://facebook.github.io/php-webdriver/latest/) Any complaints, questions, or ideas? Post them in the user group https://www.facebook.com/groups/phpwebdriver/. @@ -41,24 +41,25 @@ Then install the library: The required server is the `selenium-server-standalone-#.jar` file provided here: http://selenium-release.storage.googleapis.com/index.html -Download and run the server by replacing # with the current server version. Keep in mind **you must have Java 8+ installed to run this command**. +Download and run the server by **replacing #** with the current server version. Keep in mind **you must have Java 8+ installed to run this command**. java -jar selenium-server-standalone-#.jar -**NOTE:** If using Firefox, see alternate command below. - ### Create a Browser Session When creating a browser session, be sure to pass the url of your running server. ```php // This would be the url of the host running the server-standalone.jar -$host = 'http://localhost:4444/wd/hub'; // this is the default +$host = 'http://localhost:4444/wd/hub'; // this is the default url and port where Selenium server starts ``` ##### Launch Chrome -Make sure to have latest Chrome and [Chromedriver](https://sites.google.com/a/chromium.org/chromedriver/downloads) versions installed. +Install latest Chrome and [Chromedriver](https://sites.google.com/a/chromium.org/chromedriver/downloads). + +The `chromedriver` binary must be placed in system `PATH` directory, otherwise you must provide the path when starting Selenium server +(eg. `java -Dwebdriver.chrome.driver="/path/to/chromedriver" -jar selenium-server-standalone-#.jar`). ```php $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome()); @@ -66,14 +67,11 @@ $driver = RemoteWebDriver::create($host, DesiredCapabilities::chrome()); ##### Launch Firefox -Make sure to have latest Firefox and [Geckodriver](https://github.com/mozilla/geckodriver/releases) installed. - -Because Firefox (and Geckodriver) only support the new W3C WebDriver protocol (which is yet to be implemented by php-webdriver - see [issue #469](https://github.com/facebook/php-webdriver/issues/469)), -the protocols must be translated by Selenium Server - this feature is *partially* available in Selenium Server versions 3.5.0-3.8.1 and you can enable it like this: +Install latest Firefox and [Geckodriver](https://github.com/mozilla/geckodriver/releases). - java -jar selenium-server-standalone-3.8.1.jar -enablePassThrough false +The `geckodriver` binary must be placed in system `PATH` directory, otherwise you must provide the path when starting Selenium server +(eg. `java -Dwebdriver.gecko.driver="/path/to/geckodriver" -jar selenium-server-standalone-#.jar`). -Now you can start Firefox from your code: ```php $driver = RemoteWebDriver::create($host, DesiredCapabilities::firefox()); @@ -82,9 +80,9 @@ $driver = RemoteWebDriver::create($host, DesiredCapabilities::firefox()); ### Customize Desired Capabilities ```php -$desired_capabilities = DesiredCapabilities::firefox(); -$desired_capabilities->setCapability('acceptSslCerts', false); -$driver = RemoteWebDriver::create($host, $desired_capabilities); +$desiredCapabilities = DesiredCapabilities::firefox(); +$desiredCapabilities->setCapability('acceptSslCerts', false); +$driver = RemoteWebDriver::create($host, $desiredCapabilities); ``` * See https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities for more details. From 42f82dd233ea52f64f36f143a57c6d6df89c22c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 12 Nov 2019 23:54:22 +0100 Subject: [PATCH 455/784] Define branch alias for version 1.8 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index e5aef5a03..a6aec98ae 100644 --- a/composer.json +++ b/composer.json @@ -59,7 +59,7 @@ }, "extra": { "branch-alias": { - "dev-community": "1.5-dev" + "dev-community": "1.8.x-dev" } } } From a6cad80b88fcb3c3823afe85d653d0c46c05944c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Thu, 14 Nov 2019 19:10:16 +0100 Subject: [PATCH 456/784] Add convertor to W3C compatible capabilities (fixes #676, part of #469) --- lib/Remote/DesiredCapabilities.php | 73 ++++++++++ lib/Remote/RemoteWebDriver.php | 31 +--- tests/unit/Remote/DesiredCapabilitiesTest.php | 137 ++++++++++++++++++ 3 files changed, 213 insertions(+), 28 deletions(-) diff --git a/lib/Remote/DesiredCapabilities.php b/lib/Remote/DesiredCapabilities.php index 533c8873a..c78d2302b 100644 --- a/lib/Remote/DesiredCapabilities.php +++ b/lib/Remote/DesiredCapabilities.php @@ -178,6 +178,79 @@ public function toArray() return $this->capabilities; } + /** + * @return array + */ + public function toW3cCompatibleArray() + { + $ossToW3c = [ + WebDriverCapabilityType::PLATFORM => 'platformName', + WebDriverCapabilityType::VERSION => 'browserVersion', + WebDriverCapabilityType::ACCEPT_SSL_CERTS => 'acceptInsecureCerts', + ChromeOptions::CAPABILITY => ChromeOptions::CAPABILITY_W3C, + ]; + + $allowedW3cCapabilities = [ + 'browserName', + 'browserVersion', + 'platformName', + 'acceptInsecureCerts', + 'pageLoadStrategy', + 'proxy', + 'setWindowRect', + 'timeouts', + 'strictFileInteractability', + 'unhandledPromptBehavior', + ]; + + $ossCapabilities = $this->toArray(); + $w3cCapabilities = []; + + foreach ($ossCapabilities as $capabilityKey => $capabilityValue) { + // Copy already W3C compatible capabilities + if (in_array($capabilityKey, $allowedW3cCapabilities, true)) { + $w3cCapabilities[$capabilityKey] = $capabilityValue; + } + + // Convert capabilitites with changed name + if (array_key_exists($capabilityKey, $ossToW3c)) { + if ($capabilityKey === 'platform') { + $w3cCapabilities[$ossToW3c[$capabilityKey]] = mb_strtolower($capabilityValue); + } else { + $w3cCapabilities[$ossToW3c[$capabilityKey]] = $capabilityValue; + } + } + + // Copy vendor extensions + if (mb_strpos($capabilityKey, ':') !== false) { + $w3cCapabilities[$capabilityKey] = $capabilityValue; + } + } + + // Convert ChromeOptions + if (array_key_exists(ChromeOptions::CAPABILITY, $ossCapabilities)) { + if (array_key_exists(ChromeOptions::CAPABILITY_W3C, $ossCapabilities)) { + $w3cCapabilities[ChromeOptions::CAPABILITY_W3C] = array_merge_recursive( + $ossCapabilities[ChromeOptions::CAPABILITY], + $ossCapabilities[ChromeOptions::CAPABILITY_W3C] + ); + } else { + $w3cCapabilities[ChromeOptions::CAPABILITY_W3C] = $ossCapabilities[ChromeOptions::CAPABILITY]; + } + } + + // Convert Firefox profile + if (array_key_exists(FirefoxDriver::PROFILE, $ossCapabilities)) { + // Convert profile only if not already set in moz:firefoxOptions + if (!array_key_exists('moz:firefoxOptions', $ossCapabilities) + || !array_key_exists('profile', $ossCapabilities['moz:firefoxOptions'])) { + $w3cCapabilities['moz:firefoxOptions']['profile'] = $ossCapabilities[FirefoxDriver::PROFILE]; + } + } + + return $w3cCapabilities; + } + /** * @return static */ diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index d2e302f44..1762f44a8 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -15,7 +15,6 @@ namespace Facebook\WebDriver\Remote; -use Facebook\WebDriver\Chrome\ChromeOptions; use Facebook\WebDriver\Interactions\WebDriverActions; use Facebook\WebDriver\JavaScriptExecutor; use Facebook\WebDriver\WebDriver; @@ -123,12 +122,12 @@ public static function create( // W3C $parameters = [ 'capabilities' => [ - 'firstMatch' => [static::convertCapabilitiesToW3c($desired_capabilities->toArray())], + 'firstMatch' => [$desired_capabilities->toW3cCompatibleArray()], ], ]; - if ($required_capabilities !== null && $required_capabilities_array = $required_capabilities->toArray()) { - $parameters['capabilities']['alwaysMatch'] = static::convertCapabilitiesToW3c($required_capabilities_array); + if ($required_capabilities !== null && !empty($required_capabilities->toArray())) { + $parameters['capabilities']['alwaysMatch'] = $required_capabilities->toW3cCompatibleArray(); } // Legacy protocol @@ -660,28 +659,4 @@ protected static function castToDesiredCapabilitiesObject($desired_capabilities return $desired_capabilities; } - - /** - * Convert keys invalid in W3C capabilities to corresponding ones for W3C. - * - * @param array $capabilitiesArray - * @return array - */ - protected static function convertCapabilitiesToW3c(array $capabilitiesArray) - { - if (array_key_exists(ChromeOptions::CAPABILITY, $capabilitiesArray)) { - if (array_key_exists(ChromeOptions::CAPABILITY_W3C, $capabilitiesArray)) { - $capabilitiesArray[ChromeOptions::CAPABILITY_W3C] = array_merge( - $capabilitiesArray[ChromeOptions::CAPABILITY], - $capabilitiesArray[ChromeOptions::CAPABILITY_W3C] - ); - } else { - $capabilitiesArray[ChromeOptions::CAPABILITY_W3C] = $capabilitiesArray[ChromeOptions::CAPABILITY]; - } - - unset($capabilitiesArray[ChromeOptions::CAPABILITY]); - } - - return $capabilitiesArray; - } } diff --git a/tests/unit/Remote/DesiredCapabilitiesTest.php b/tests/unit/Remote/DesiredCapabilitiesTest.php index 6e14ef044..4ef4a055a 100644 --- a/tests/unit/Remote/DesiredCapabilitiesTest.php +++ b/tests/unit/Remote/DesiredCapabilitiesTest.php @@ -15,6 +15,7 @@ namespace Facebook\WebDriver\Remote; +use Facebook\WebDriver\Chrome\ChromeOptions; use Facebook\WebDriver\Firefox\FirefoxDriver; use Facebook\WebDriver\Firefox\FirefoxPreferences; use Facebook\WebDriver\Firefox\FirefoxProfile; @@ -130,4 +131,140 @@ public function testShouldSetupFirefoxProfileAndDisableReaderViewForFirefoxBrows $this->assertSame('false', $firefoxProfile->getPreference(FirefoxPreferences::READER_PARSE_ON_LOAD_ENABLED)); } + + /** + * @dataProvider provideW3cCapabilities + * @param DesiredCapabilities $inputJsonWireCapabilities + * @param array $expectedW3cCapabilities + */ + public function testShouldConvertCapabilitiesToW3cCompatible( + DesiredCapabilities $inputJsonWireCapabilities, + array $expectedW3cCapabilities + ) { + $this->assertEquals( + $expectedW3cCapabilities, + $inputJsonWireCapabilities->toW3cCompatibleArray() + ); + } + + /** + * @return array[] + */ + public function provideW3cCapabilities() + { + $chromeOptions = new ChromeOptions(); + $chromeOptions->addArguments([ + '--headless', + ]); + + $firefoxProfileEncoded = (new FirefoxProfile())->encode(); + + return [ + 'changed name' => [ + new DesiredCapabilities([ + WebDriverCapabilityType::BROWSER_NAME => WebDriverBrowserType::CHROME, + WebDriverCapabilityType::VERSION => '67.0.1', + WebDriverCapabilityType::PLATFORM => WebDriverPlatform::LINUX, + WebDriverCapabilityType::ACCEPT_SSL_CERTS => true, + ]), + [ + 'browserName' => 'chrome', + 'browserVersion' => '67.0.1', + 'platformName' => 'linux', + 'acceptInsecureCerts' => true, + ], + ], + 'removed capabilitites' => [ + new DesiredCapabilities([ + WebDriverCapabilityType::WEB_STORAGE_ENABLED => true, + WebDriverCapabilityType::TAKES_SCREENSHOT => false, + ]), + [], + ], + 'custom invalid capability should be removed' => [ + new DesiredCapabilities([ + 'customInvalidCapability' => 'shouldBeRemoved', + ]), + [], + ], + 'already W3C capabilitites' => [ + new DesiredCapabilities([ + 'pageLoadStrategy' => 'eager', + 'strictFileInteractability' => false, + ]), + [ + 'pageLoadStrategy' => 'eager', + 'strictFileInteractability' => false, + ], + ], + 'custom vendor extension' => [ + new DesiredCapabilities([ + 'vendor:prefix' => 'vendor extension should be kept', + ]), + [ + 'vendor:prefix' => 'vendor extension should be kept', + ], + ], + 'chromeOptions should be converted' => [ + new DesiredCapabilities([ + ChromeOptions::CAPABILITY => $chromeOptions, + ]), + [ + 'goog:chromeOptions' => [ + 'args' => ['--headless'], + 'binary' => '', + ], + ], + ], + 'chromeOptions should be merged if already defined' => [ + new DesiredCapabilities([ + ChromeOptions::CAPABILITY => $chromeOptions, + ChromeOptions::CAPABILITY_W3C => [ + 'debuggerAddress' => '127.0.0.1:38947', + 'args' => ['window-size=1024,768'], + ], + ]), + [ + 'goog:chromeOptions' => [ + 'args' => ['--headless', 'window-size=1024,768'], + 'binary' => '', + 'debuggerAddress' => '127.0.0.1:38947', + ], + ], + ], + 'firefox_profile should be converted' => [ + new DesiredCapabilities([ + FirefoxDriver::PROFILE => $firefoxProfileEncoded, + ]), + [ + 'moz:firefoxOptions' => [ + 'profile' => $firefoxProfileEncoded, + ], + ], + ], + 'firefox_profile should not be overwritten if already present' => [ + new DesiredCapabilities([ + FirefoxDriver::PROFILE => $firefoxProfileEncoded, + 'moz:firefoxOptions' => ['profile' => 'w3cProfile'], + ]), + [ + 'moz:firefoxOptions' => [ + 'profile' => 'w3cProfile', + ], + ], + ], + 'firefox_profile should be merged with moz:firefoxOptions if they already exists' => [ + new DesiredCapabilities([ + FirefoxDriver::PROFILE => $firefoxProfileEncoded, + 'moz:firefoxOptions' => ['args' => ['-headless']], + ]), + [ + 'moz:firefoxOptions' => [ + 'profile' => $firefoxProfileEncoded, + 'args' => ['-headless'], + ], + ], + ], + ]; + } } From f81659eaa82820b7a55be5ac173f56188af186c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 15 Nov 2019 00:39:53 +0100 Subject: [PATCH 457/784] Run geckodriver tests in headless mode --- tests/functional/WebDriverTestCase.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index 8b35a7700..1f125634e 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -65,6 +65,10 @@ protected function setUp() $this->desiredCapabilities->setCapability(ChromeOptions::CAPABILITY, $chromeOptions); } elseif (getenv('GECKODRIVER') === '1') { $this->serverUrl = 'http://localhost:4444/'; + $this->desiredCapabilities->setCapability( + 'moz:firefoxOptions', + ['args' => ['-headless']] + ); } $this->desiredCapabilities->setBrowserName($browserName); From b4b82e2ccada9a7d251ae4703478e94b5b593370 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 15 Nov 2019 00:38:54 +0100 Subject: [PATCH 458/784] Add W3C window size and position commands --- lib/Remote/HttpCommandExecutor.php | 9 ++- tests/functional/WebDriverWindowTest.php | 81 ++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 tests/functional/WebDriverWindowTest.php diff --git a/lib/Remote/HttpCommandExecutor.php b/lib/Remote/HttpCommandExecutor.php index b87c94069..d137030a4 100644 --- a/lib/Remote/HttpCommandExecutor.php +++ b/lib/Remote/HttpCommandExecutor.php @@ -144,8 +144,9 @@ class HttpCommandExecutor implements WebDriverCommandExecutor DriverCommand::ACCEPT_ALERT => ['method' => 'POST', 'url' => '/session/:sessionId/alert/accept'], DriverCommand::ACTIONS => ['method' => 'POST', 'url' => '/session/:sessionId/actions'], DriverCommand::DISMISS_ALERT => ['method' => 'POST', 'url' => '/session/:sessionId/alert/dismiss'], - DriverCommand::EXECUTE_SCRIPT => ['method' => 'POST', 'url' => '/session/:sessionId/execute/sync'], DriverCommand::EXECUTE_ASYNC_SCRIPT => ['method' => 'POST', 'url' => '/session/:sessionId/execute/async'], + DriverCommand::EXECUTE_SCRIPT => ['method' => 'POST', 'url' => '/session/:sessionId/execute/sync'], + DriverCommand::GET_ALERT_TEXT => ['method' => 'GET', 'url' => '/session/:sessionId/alert/text'], DriverCommand::GET_CURRENT_WINDOW_HANDLE => ['method' => 'GET', 'url' => '/session/:sessionId/window'], DriverCommand::GET_ELEMENT_LOCATION => ['method' => 'GET', 'url' => '/session/:sessionId/element/:id/rect'], DriverCommand::GET_ELEMENT_PROPERTY => [ @@ -154,11 +155,15 @@ class HttpCommandExecutor implements WebDriverCommandExecutor ], DriverCommand::GET_ELEMENT_SIZE => ['method' => 'GET', 'url' => '/session/:sessionId/element/:id/rect'], DriverCommand::GET_WINDOW_HANDLES => ['method' => 'GET', 'url' => '/session/:sessionId/window/handles'], - DriverCommand::GET_ALERT_TEXT => ['method' => 'GET', 'url' => '/session/:sessionId/alert/text'], + DriverCommand::GET_WINDOW_POSITION => ['method' => 'GET', 'url' => '/session/:sessionId/window/rect'], + DriverCommand::GET_WINDOW_SIZE => ['method' => 'GET', 'url' => '/session/:sessionId/window/rect'], DriverCommand::IMPLICITLY_WAIT => ['method' => 'POST', 'url' => '/session/:sessionId/timeouts'], + DriverCommand::MAXIMIZE_WINDOW => ['method' => 'POST', 'url' => '/session/:sessionId/window/maximize'], DriverCommand::SET_ALERT_VALUE => ['method' => 'POST', 'url' => '/session/:sessionId/alert/text'], DriverCommand::SET_SCRIPT_TIMEOUT => ['method' => 'POST', 'url' => '/session/:sessionId/timeouts'], DriverCommand::SET_TIMEOUT => ['method' => 'POST', 'url' => '/session/:sessionId/timeouts'], + DriverCommand::SET_WINDOW_SIZE => ['method' => 'POST', 'url' => '/session/:sessionId/window/rect'], + DriverCommand::SET_WINDOW_POSITION => ['method' => 'POST', 'url' => '/session/:sessionId/window/rect'], ]; /** * @var string diff --git a/tests/functional/WebDriverWindowTest.php b/tests/functional/WebDriverWindowTest.php new file mode 100644 index 000000000..ccf041b16 --- /dev/null +++ b/tests/functional/WebDriverWindowTest.php @@ -0,0 +1,81 @@ +driver->manage() + ->window() + ->getPosition(); + + $this->assertGreaterThanOrEqual(0, $position->getX()); + $this->assertGreaterThanOrEqual(0, $position->getY()); + } + + public function testShouldGetSize() + { + $size = $this->driver->manage() + ->window() + ->getSize(); + + $this->assertGreaterThan(0, $size->getWidth()); + $this->assertGreaterThan(0, $size->getHeight()); + } + + public function testShouldMaximizeWindow() + { + $sizeBefore = $this->driver->manage() + ->window() + ->getSize(); + + $this->driver->manage() + ->window() + ->maximize(); + + $sizeAfter = $this->driver->manage() + ->window() + ->getSize(); + + $this->assertGreaterThanOrEqual($sizeBefore->getWidth(), $sizeAfter->getWidth()); + $this->assertGreaterThanOrEqual($sizeBefore->getHeight(), $sizeAfter->getHeight()); + } + + public function testShouldSetSize() + { + $sizeBefore = $this->driver->manage() + ->window() + ->getSize(); + $this->assertNotSame(500, $sizeBefore->getWidth()); + $this->assertNotSame(666, $sizeBefore->getHeight()); + + $this->driver->manage() + ->window() + ->setSize(new WebDriverDimension(500, 666)); + + $sizeAfter = $this->driver->manage() + ->window() + ->getSize(); + + $this->assertSame(500, $sizeAfter->getWidth()); + $this->assertSame(666, $sizeAfter->getHeight()); + } + + public function testShouldSetWindowPosition() + { + $this->driver->manage() + ->window() + ->setPosition(new WebDriverPoint(33, 66)); + + $positionAfter = $this->driver->manage() + ->window() + ->getPosition(); + + $this->assertSame(33, $positionAfter->getX()); + $this->assertSame(66, $positionAfter->getY()); + } +} From c7ee5e1852b42d73bc597bb70a1b03344bdcb233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Fri, 15 Nov 2019 12:17:12 +0100 Subject: [PATCH 459/784] Exclude window tests on Saucelabs, because they are not sane --- tests/functional/WebDriverWindowTest.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/functional/WebDriverWindowTest.php b/tests/functional/WebDriverWindowTest.php index ccf041b16..8de61d3e8 100644 --- a/tests/functional/WebDriverWindowTest.php +++ b/tests/functional/WebDriverWindowTest.php @@ -7,6 +7,9 @@ */ class WebDriverWindowTest extends WebDriverTestCase { + /** + * @group exclude-saucelabs + */ public function testShouldGetPosition() { $position = $this->driver->manage() @@ -45,6 +48,9 @@ public function testShouldMaximizeWindow() $this->assertGreaterThanOrEqual($sizeBefore->getHeight(), $sizeAfter->getHeight()); } + /** + * @group exclude-saucelabs + */ public function testShouldSetSize() { $sizeBefore = $this->driver->manage() From e9f4ec88e7ed10388613aa8b05cf1e3f4d2231d3 Mon Sep 17 00:00:00 2001 From: Lctrs Date: Fri, 22 Nov 2019 00:38:58 +0100 Subject: [PATCH 460/784] Download a compatible version of chromedriver with chrome Following the [algorithm described on the official chromedriver website](https://chromedriver.chromium.org/downloads/version-selection) : > Here are the steps to select the version of ChromeDriver to download: > > - First, find out which version of Chrome you are using. Let's say you have Chrome 72.0.3626.81. > - Take the Chrome version number, remove the last part, and append the result to URL "https://chromedriver.storage.googleapis.com/LATEST_RELEASE_". For example, with Chrome version 72.0.3626.81, you'd get a URL "https://chromedriver.storage.googleapis.com/LATEST_RELEASE_72.0.3626". > - Use the URL created in the last step to retrieve a small file containing the version of ChromeDriver to use. For example, the above URL will get your a file containing "72.0.3626.69". (The actual number may change in the future, of course.) > - Use the version number retrieved from the previous step to construct the URL to download ChromeDriver. With version 72.0.3626.69, the URL would be "https://chromedriver.storage.googleapis.com/index.html?path=72.0.3626.69/". --- .travis.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4a8a268a8..0340b80e7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -134,7 +134,13 @@ install: - travis_retry composer update --no-interaction $DEPENDENCIES before_script: - - if [ "$BROWSER_NAME" = "chrome" ]; then mkdir chromedriver; CHROMEDRIVER_VERSION=$(wget -qO- "https://chromedriver.storage.googleapis.com/LATEST_RELEASE"); wget -q -t 3 https://chromedriver.storage.googleapis.com/$CHROMEDRIVER_VERSION/chromedriver_linux64.zip; unzip chromedriver_linux64 -d chromedriver; fi + - if [ "$BROWSER_NAME" = "chrome" ]; then + mkdir chromedriver; + CHROME_VERSION=$(google-chrome --product-version); + CHROME_VERSION=${CHROME_VERSION%.*}; + wget -q -t 3 https://chromedriver.storage.googleapis.com/$(curl -L https://chromedriver.storage.googleapis.com/LATEST_RELEASE_${CHROME_VERSION})/chromedriver_linux64.zip; + unzip chromedriver_linux64.zip -d chromedriver; + fi - if [ "$BROWSER_NAME" = "chrome" ]; then export CHROMEDRIVER_PATH=$PWD/chromedriver/chromedriver; fi - if [ "$GECKODRIVER" = "1" ]; then mkdir -p geckodriver; wget -q -t 3 https://github.com/mozilla/geckodriver/releases/download/v0.26.0/geckodriver-v0.26.0-linux64.tar.gz; tar xzf geckodriver-v0.26.0-linux64.tar.gz -C geckodriver; fi - sh -e /etc/init.d/xvfb start # TODO: start only when needed (ie. not in headless mode) From ee14c4392399a9fc7b362f488226141ca67e8348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 19 Nov 2019 13:14:34 +0100 Subject: [PATCH 461/784] Use W3C protocol on some Saucelabs builds --- .travis.yml | 20 +++++++------ tests/functional/WebDriverTestCase.php | 33 +++++++++++++++++----- tests/functional/WebDriverTimeoutsTest.php | 3 ++ 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0340b80e7..2c80cbb18 100644 --- a/.travis.yml +++ b/.travis.yml @@ -85,8 +85,9 @@ matrix: chrome: stable # Saucelabs builds - - php: '7.3' - env: SAUCELABS=1 BROWSER_NAME="firefox" VERSION="47.0" PLATFORM="Windows 10" + - name: 'Sauce Labs, Firefox 47, OSS protocol' + php: '7.3' + env: SAUCELABS=1 BROWSER_NAME="firefox" VERSION="47.0" PLATFORM="Windows 10" DISABLE_W3C_PROTOCOL="1" before_script: - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & - until $(echo | nc localhost 8000); do sleep 1; echo waiting for PHP server on port 8000...; done; echo "PHP server started" @@ -95,8 +96,9 @@ matrix: jwt: secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= - - php: '7.3' - env: SAUCELABS=1 BROWSER_NAME="chrome" VERSION="74.0" PLATFORM="Windows 10" # 74 is the last version which don't use W3C WebDriver by default + - name: 'Sauce Labs, Chrome 74, OSS protocol' + php: '7.3' + env: SAUCELABS=1 BROWSER_NAME="chrome" VERSION="74.0" PLATFORM="Windows 10" DISABLE_W3C_PROTOCOL="1" # 74 is the last version which don't use W3C WebDriver by default before_script: - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & - until $(echo | nc localhost 8000); do sleep 1; echo waiting for PHP server on port 8000...; done; echo "PHP server started" @@ -105,8 +107,9 @@ matrix: jwt: secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= - - php: '7.3' - env: SAUCELABS=1 BROWSER_NAME="chrome" VERSION="75.0" PLATFORM="Windows 10" + - name: 'Sauce Labs, Chrome latest, W3C protocol' + php: '7.3' + env: SAUCELABS=1 BROWSER_NAME="chrome" VERSION="latest" PLATFORM="Windows 10" before_script: - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & - until $(echo | nc localhost 8000); do sleep 1; echo waiting for PHP server on port 8000...; done; echo "PHP server started" @@ -115,8 +118,9 @@ matrix: jwt: secure: HPq5xFhosa1eSGnaRdJzeyEuaE0mhRlG1gf3G7+dKS0VniF30husSyrxZhbGCCKBGxmIySoAQzd43BCwL69EkUEVKDN87Cpid1Ce9KrSfU3cnN8XIb+4QINyy7x1a47RUAfaaOEx53TrW0ShalvjD+ZwDE8LrgagSox6KQ+nQLE= - - php: '7.3' - env: SAUCELABS=1 BROWSER_NAME="MicrosoftEdge" VERSION="16.16299" PLATFORM="Windows 10" + - name: 'Sauce Labs, Edge latest, W3C protocol' + php: '7.3' + env: SAUCELABS=1 BROWSER_NAME="MicrosoftEdge" VERSION="latest" PLATFORM="Windows 10" before_script: - php -S 127.0.0.1:8000 -t tests/functional/web/ &>>./logs/php-server.log & - until $(echo | nc localhost 8000); do sleep 1; echo waiting for PHP server on port 8000...; done; echo "PHP server started" diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index 1f125634e..f012d9068 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -112,9 +112,8 @@ public static function isSauceLabsBuild() public static function isW3cProtocolBuild() { return getenv('GECKODRIVER') === '1' - || (getenv('BROWSER_NAME') === 'chrome' - && getenv('DISABLE_W3C_PROTOCOL') !== '1' - && !self::isSauceLabsBuild()); + || (getenv('BROWSER_NAME') === 'chrome' && getenv('DISABLE_W3C_PROTOCOL') !== '1') + || getenv('BROWSER_NAME') === 'MicrosoftEdge'; } public static function skipForW3cProtocol($message = 'Not supported by W3C specification') @@ -153,12 +152,32 @@ protected function setUpSauceLabs() $this->desiredCapabilities->setBrowserName(getenv('BROWSER_NAME')); $this->desiredCapabilities->setVersion(getenv('VERSION')); $this->desiredCapabilities->setPlatform(getenv('PLATFORM')); - $this->desiredCapabilities->setCapability('name', get_class($this) . '::' . $this->getName()); - $this->desiredCapabilities->setCapability('tags', [get_class($this)]); + $name = get_class($this) . '::' . $this->getName(); + $tags = [get_class($this)]; if (getenv('TRAVIS_JOB_NUMBER')) { - $this->desiredCapabilities->setCapability('tunnel-identifier', getenv('TRAVIS_JOB_NUMBER')); - $this->desiredCapabilities->setCapability('build', getenv('TRAVIS_JOB_NUMBER')); + $tunnelIdentifier = getenv('TRAVIS_JOB_NUMBER'); + $build = getenv('TRAVIS_JOB_NUMBER'); + } + + if (!getenv('DISABLE_W3C_PROTOCOL')) { + $sauceOptions = [ + 'name' => $name, + 'tags' => $tags, + ]; + if (isset($tunnelIdentifier, $build)) { + $sauceOptions['tunnelIdentifier'] = $tunnelIdentifier; + $sauceOptions['build'] = $build; + } + $this->desiredCapabilities->setCapability('sauce:options', (object) $sauceOptions); + } else { + $this->desiredCapabilities->setCapability('name', $name); + $this->desiredCapabilities->setCapability('tags', $tags); + + if (isset($tunnelIdentifier, $build)) { + $this->desiredCapabilities->setCapability('tunnel-identifier', $tunnelIdentifier); + $this->desiredCapabilities->setCapability('build', $build); + } } } } diff --git a/tests/functional/WebDriverTimeoutsTest.php b/tests/functional/WebDriverTimeoutsTest.php index 733be545c..cd3e10d99 100644 --- a/tests/functional/WebDriverTimeoutsTest.php +++ b/tests/functional/WebDriverTimeoutsTest.php @@ -26,6 +26,9 @@ */ class WebDriverTimeoutsTest extends WebDriverTestCase { + /** + * @group exclude-saucelabs + */ public function testShouldFailGettingDelayedElementWithoutWait() { $this->driver->get($this->getTestPageUrl('delayed_element.html')); From a0d6be9a5fb351fe1a554bbd4f4a76f896727414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 19 Nov 2019 13:23:30 +0100 Subject: [PATCH 462/784] Simplify builds --- .travis.yml | 3 --- tests/functional/WebDriverAlertTest.php | 6 ------ tests/functional/WebDriverTestCase.php | 2 +- 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2c80cbb18..9bb73cc1e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -59,7 +59,6 @@ matrix: php: '7.3' env: - BROWSER_NAME="chrome" - - CHROME_HEADLESS="1" addons: chrome: stable @@ -68,7 +67,6 @@ matrix: php: '7.3' env: - BROWSER_NAME="chrome" - - CHROME_HEADLESS="1" - CHROMEDRIVER="1" addons: chrome: stable @@ -78,7 +76,6 @@ matrix: php: '7.3' env: - BROWSER_NAME="chrome" - - CHROME_HEADLESS="1" - CHROMEDRIVER="1" - DISABLE_W3C_PROTOCOL="1" addons: diff --git a/tests/functional/WebDriverAlertTest.php b/tests/functional/WebDriverAlertTest.php index 163bee157..b99dad1fa 100644 --- a/tests/functional/WebDriverAlertTest.php +++ b/tests/functional/WebDriverAlertTest.php @@ -25,12 +25,6 @@ class WebDriverAlertTest extends WebDriverTestCase { protected function setUp() { - if (getenv('CHROME_HEADLESS') === '1') { - // Alerts in headless mode should be available in next Chrome version (61), see: - // https://bugs.chromium.org/p/chromium/issues/detail?id=718235 - $this->markTestSkipped('Alerts not yet supported by headless Chrome'); - } - parent::setUp(); $this->driver->get($this->getTestPageUrl('alert.html')); diff --git a/tests/functional/WebDriverTestCase.php b/tests/functional/WebDriverTestCase.php index f012d9068..9b302a1f3 100644 --- a/tests/functional/WebDriverTestCase.php +++ b/tests/functional/WebDriverTestCase.php @@ -113,7 +113,7 @@ public static function isW3cProtocolBuild() { return getenv('GECKODRIVER') === '1' || (getenv('BROWSER_NAME') === 'chrome' && getenv('DISABLE_W3C_PROTOCOL') !== '1') - || getenv('BROWSER_NAME') === 'MicrosoftEdge'; + || (self::isSauceLabsBuild() && getenv('DISABLE_W3C_PROTOCOL') !== '1'); } public static function skipForW3cProtocol($message = 'Not supported by W3C specification') From b54d50371b68926a60d2832db2ed94c1d3e95c12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 23 Nov 2019 14:11:55 +0100 Subject: [PATCH 463/784] Skip tests utilizing xPath selectors, which are not properly supported in Edge --- tests/functional/WebDriverCheckboxesTest.php | 1 + tests/functional/WebDriverRadiosTest.php | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/functional/WebDriverCheckboxesTest.php b/tests/functional/WebDriverCheckboxesTest.php index 48b72a53c..91513bd94 100644 --- a/tests/functional/WebDriverCheckboxesTest.php +++ b/tests/functional/WebDriverCheckboxesTest.php @@ -20,6 +20,7 @@ /** * @covers \Facebook\WebDriver\WebDriverCheckboxes * @covers \Facebook\WebDriver\AbstractWebDriverCheckboxOrRadio + * @group exclude-edge */ class WebDriverCheckboxesTest extends WebDriverTestCase { diff --git a/tests/functional/WebDriverRadiosTest.php b/tests/functional/WebDriverRadiosTest.php index 4d659772b..cf7b8378c 100644 --- a/tests/functional/WebDriverRadiosTest.php +++ b/tests/functional/WebDriverRadiosTest.php @@ -21,6 +21,7 @@ /** * @covers \Facebook\WebDriver\WebDriverRadios * @covers \Facebook\WebDriver\AbstractWebDriverCheckboxOrRadio + * @group exclude-edge */ class WebDriverRadiosTest extends WebDriverTestCase { From a419816547eed70cfcf54fd0763df33c94adcce2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sat, 23 Nov 2019 17:56:26 +0100 Subject: [PATCH 464/784] Skip file upload tests on Saucelabs, because W3C protocol does not support remote file upload See https://github.com/w3c/webdriver/issues/1355 --- lib/Remote/RemoteWebElement.php | 27 ++++++++++++--------------- tests/functional/FileUploadTest.php | 2 ++ 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/lib/Remote/RemoteWebElement.php b/lib/Remote/RemoteWebElement.php index 75dfa3ba2..33286504b 100644 --- a/lib/Remote/RemoteWebElement.php +++ b/lib/Remote/RemoteWebElement.php @@ -358,6 +358,7 @@ public function isSelected() public function sendKeys($value) { $local_file = $this->fileDetector->getLocalFile($value); + if ($local_file === null) { if ($this->isW3cCompliant) { $params = [ @@ -370,22 +371,18 @@ public function sendKeys($value) ':id' => $this->id, ]; } - - $this->executor->execute(DriverCommand::SEND_KEYS_TO_ELEMENT, $params); - - return $this; - } - - if ($this->isW3cCompliant) { - $params = [ - 'text' => $local_file, - ':id' => $this->id, - ]; } else { - $params = [ - 'value' => WebDriverKeys::encode($this->upload($local_file)), - ':id' => $this->id, - ]; + if ($this->isW3cCompliant) { + $params = [ + 'text' => $local_file, + ':id' => $this->id, + ]; + } else { + $params = [ + 'value' => WebDriverKeys::encode($this->upload($local_file)), + ':id' => $this->id, + ]; + } } $this->executor->execute(DriverCommand::SEND_KEYS_TO_ELEMENT, $params); diff --git a/tests/functional/FileUploadTest.php b/tests/functional/FileUploadTest.php index 5b2f6d2d3..1029a2363 100644 --- a/tests/functional/FileUploadTest.php +++ b/tests/functional/FileUploadTest.php @@ -26,6 +26,8 @@ class FileUploadTest extends WebDriverTestCase /** * @group exclude-edge * https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/6052385/ + * @group exclude-saucelabs + * W3C protocol does not support remote file upload: https://github.com/w3c/webdriver/issues/1355 */ public function testShouldUploadAFile() { From 9d5623f40ab320601f8b2cee2bb463d722bb4393 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Mon, 25 Nov 2019 15:10:50 +0800 Subject: [PATCH 465/784] Fix mouseUp W3C action --- lib/Remote/RemoteMouse.php | 2 +- tests/functional/WebDriverActionsTest.php | 24 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/Remote/RemoteMouse.php b/lib/Remote/RemoteMouse.php index 4bd4a849b..6b7375834 100644 --- a/lib/Remote/RemoteMouse.php +++ b/lib/Remote/RemoteMouse.php @@ -241,7 +241,7 @@ public function mouseUp(WebDriverCoordinates $where = null) 'parameters' => ['pointerType' => 'mouse'], 'actions' => array_merge($moveAction, [ [ - 'type' => 'pointerDown', + 'type' => 'pointerUp', 'duration' => 0, 'button' => 0, ], diff --git a/tests/functional/WebDriverActionsTest.php b/tests/functional/WebDriverActionsTest.php index 9798f6e5a..6799ef1d3 100644 --- a/tests/functional/WebDriverActionsTest.php +++ b/tests/functional/WebDriverActionsTest.php @@ -136,6 +136,30 @@ public function testShouldDoubleClickOnElement() $this->assertContains('dblclick item-3', $this->retrieveLoggedEvents()); } + /** + * @covers ::__construct + * @covers ::dragAndDrop + * @covers ::perform + */ + public function testShouldDragAndDrop() + { + if ($this->desiredCapabilities->getBrowserName() === WebDriverBrowserType::HTMLUNIT) { + $this->markTestSkipped('Not supported by HtmlUnit browser'); + } + + $element = $this->driver->findElement(WebDriverBy::id('item-3')); + $target = $this->driver->findElement(WebDriverBy::id('item-1')); + + $this->driver->action() + ->dragAndDrop($element, $target) + ->perform(); + + $this->assertContains('mouseover item-3', $this->retrieveLoggedEvents()); + $this->assertContains('mousedown item-3', $this->retrieveLoggedEvents()); + $this->assertContains('mouseover item-1', $this->retrieveLoggedEvents()); + $this->assertContains('mouseup item-1', $this->retrieveLoggedEvents()); + } + /** * @return array */ From a94e33b99a8330c90c56128e430ffc55c507d304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Mon, 25 Nov 2019 17:13:57 +0100 Subject: [PATCH 466/784] Exclude unstable drag and drop test on SauceLabs --- tests/functional/WebDriverActionsTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/functional/WebDriverActionsTest.php b/tests/functional/WebDriverActionsTest.php index 6799ef1d3..cb4359183 100644 --- a/tests/functional/WebDriverActionsTest.php +++ b/tests/functional/WebDriverActionsTest.php @@ -140,6 +140,7 @@ public function testShouldDoubleClickOnElement() * @covers ::__construct * @covers ::dragAndDrop * @covers ::perform + * @group exclude-saucelabs */ public function testShouldDragAndDrop() { From 574684f29b8d513ae213c4567f2f71da92734db7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Sun, 24 Nov 2019 10:10:35 +0100 Subject: [PATCH 467/784] Add all W3C WebDriver exceptions --- .../ElementClickInterceptedException.php | 24 +++++ .../ElementNotInteractableException.php | 23 +++++ .../ElementNotSelectableException.php | 5 +- lib/Exception/ElementNotVisibleException.php | 3 + lib/Exception/ExpectedException.php | 3 + .../IMEEngineActivationFailedException.php | 3 + lib/Exception/IMENotAvailableException.php | 3 + lib/Exception/IndexOutOfBoundsException.php | 3 + .../InsecureCertificateException.php | 24 +++++ lib/Exception/InvalidArgumentException.php | 23 +++++ .../InvalidCookieDomainException.php | 3 + lib/Exception/InvalidCoordinatesException.php | 3 + .../InvalidElementStateException.php | 4 + lib/Exception/InvalidSelectorException.php | 3 + lib/Exception/InvalidSessionIdException.php | 24 +++++ lib/Exception/JavascriptErrorException.php | 23 +++++ .../MoveTargetOutOfBoundsException.php | 3 + lib/Exception/NoAlertOpenException.php | 5 +- lib/Exception/NoCollectionException.php | 3 + lib/Exception/NoScriptResultException.php | 3 + lib/Exception/NoStringException.php | 3 + lib/Exception/NoStringLengthException.php | 3 + lib/Exception/NoStringWrapperException.php | 3 + lib/Exception/NoSuchAlertException.php | 23 +++++ lib/Exception/NoSuchCollectionException.php | 3 + lib/Exception/NoSuchCookieException.php | 24 +++++ lib/Exception/NoSuchDocumentException.php | 5 +- lib/Exception/NoSuchDriverException.php | 3 + lib/Exception/NoSuchElementException.php | 3 + lib/Exception/NoSuchFrameException.php | 3 + lib/Exception/NoSuchWindowException.php | 3 + lib/Exception/NullPointerException.php | 3 + lib/Exception/ScriptTimeoutException.php | 3 + lib/Exception/SessionNotCreatedException.php | 3 + .../StaleElementReferenceException.php | 3 + lib/Exception/TimeoutException.php | 23 +++++ ...php => UnableToCaptureScreenException.php} | 5 +- lib/Exception/UnableToSetCookieException.php | 3 + .../UnexpectedAlertOpenException.php | 3 + .../UnexpectedJavascriptException.php | 5 +- lib/Exception/UnknownCommandException.php | 3 + lib/Exception/UnknownErrorException.php | 23 +++++ lib/Exception/UnknownMethodException.php | 23 +++++ lib/Exception/UnknownServerException.php | 5 +- .../UnsupportedOperationException.php | 3 + lib/Exception/WebDriverException.php | 92 ++++++++++++------- lib/Exception/XPathLookupException.php | 3 + lib/Net/URLChecker.php | 6 +- lib/WebDriverWait.php | 6 +- tests/functional/WebDriverAlertTest.php | 8 +- tests/functional/WebDriverTimeoutsTest.php | 6 +- .../unit/Exception/WebDriverExceptionTest.php | 49 ++++++++-- 52 files changed, 487 insertions(+), 55 deletions(-) create mode 100644 lib/Exception/ElementClickInterceptedException.php create mode 100644 lib/Exception/ElementNotInteractableException.php create mode 100644 lib/Exception/InsecureCertificateException.php create mode 100644 lib/Exception/InvalidArgumentException.php create mode 100644 lib/Exception/InvalidSessionIdException.php create mode 100644 lib/Exception/JavascriptErrorException.php create mode 100644 lib/Exception/NoSuchAlertException.php create mode 100644 lib/Exception/NoSuchCookieException.php create mode 100644 lib/Exception/TimeoutException.php rename lib/Exception/{TimeOutException.php => UnableToCaptureScreenException.php} (85%) create mode 100644 lib/Exception/UnknownErrorException.php create mode 100644 lib/Exception/UnknownMethodException.php diff --git a/lib/Exception/ElementClickInterceptedException.php b/lib/Exception/ElementClickInterceptedException.php new file mode 100644 index 000000000..e4b3a529e --- /dev/null +++ b/lib/Exception/ElementClickInterceptedException.php @@ -0,0 +1,24 @@ +driver->switchTo()->alert()->accept(); - $this->expectException(NoAlertOpenException::class); + if (self::isW3cProtocolBuild()) { + $this->expectException(NoSuchAlertException::class); + } else { + $this->expectException(NoAlertOpenException::class); + } + $this->driver->switchTo()->alert()->accept(); } diff --git a/tests/functional/WebDriverTimeoutsTest.php b/tests/functional/WebDriverTimeoutsTest.php index cd3e10d99..ca85075b8 100644 --- a/tests/functional/WebDriverTimeoutsTest.php +++ b/tests/functional/WebDriverTimeoutsTest.php @@ -17,7 +17,7 @@ use Facebook\WebDriver\Exception\NoSuchElementException; use Facebook\WebDriver\Exception\ScriptTimeoutException; -use Facebook\WebDriver\Exception\TimeOutException; +use Facebook\WebDriver\Exception\TimeoutException; use Facebook\WebDriver\Remote\RemoteWebElement; use Facebook\WebDriver\Remote\WebDriverBrowserType; @@ -65,8 +65,8 @@ public function testShouldFailIfPageIsLoadingLongerThanPageLoadTimeout() try { $this->driver->get($this->getTestPageUrl('slow_loading.html')); - $this->fail('ScriptTimeoutException or TimeOutException exception should be thrown'); - } catch (TimeOutException $e) { // thrown by Selenium 3.0.0+ + $this->fail('ScriptTimeoutException or TimeoutException exception should be thrown'); + } catch (TimeoutException $e) { // thrown by Selenium 3.0.0+ } catch (ScriptTimeoutException $e) { // thrown by Selenium 2 } } diff --git a/tests/unit/Exception/WebDriverExceptionTest.php b/tests/unit/Exception/WebDriverExceptionTest.php index f9aadd207..be3ab964c 100644 --- a/tests/unit/Exception/WebDriverExceptionTest.php +++ b/tests/unit/Exception/WebDriverExceptionTest.php @@ -29,14 +29,15 @@ public function testShouldStoreResultsOnInstantiation() } /** - * @dataProvider statusCodeProvider - * @param int $statusCode + * @dataProvider jsonWireStatusCodeProvider + * @dataProvider w3CWebDriverErrorCodeProvider + * @param int $errorCode * @param string $expectedExceptionType */ - public function testShouldThrowProperExceptionBasedOnSeleniumStatusCode($statusCode, $expectedExceptionType) + public function testShouldThrowProperExceptionBasedOnWebDriverErrorCode($errorCode, $expectedExceptionType) { try { - WebDriverException::throwException($statusCode, 'exception message', ['results']); + WebDriverException::throwException($errorCode, 'exception message', ['results']); } catch (WebDriverException $e) { $this->assertInstanceOf($expectedExceptionType, $e); @@ -48,7 +49,7 @@ public function testShouldThrowProperExceptionBasedOnSeleniumStatusCode($statusC /** * @return array[] */ - public function statusCodeProvider() + public function jsonWireStatusCodeProvider() { return [ [1337, UnrecognizedExceptionException::class], @@ -72,7 +73,7 @@ public function statusCodeProvider() [18, NoScriptResultException::class], [19, XPathLookupException::class], [20, NoSuchCollectionException::class], - [21, TimeOutException::class], + [21, TimeoutException::class], [22, NullPointerException::class], [23, NoSuchWindowException::class], [24, InvalidCookieDomainException::class], @@ -88,4 +89,40 @@ public function statusCodeProvider() [34, MoveTargetOutOfBoundsException::class], ]; } + + /** + * @return array[] + */ + public function w3CWebDriverErrorCodeProvider() + { + return [ + ['element click intercepted', ElementClickInterceptedException::class], + ['element not interactable', ElementNotInteractableException::class], + ['element not interactable', ElementNotInteractableException::class], + ['insecure certificate', InsecureCertificateException::class], + ['invalid argument', InvalidArgumentException::class], + ['invalid cookie domain', InvalidCookieDomainException::class], + ['invalid element state', InvalidElementStateException::class], + ['invalid selector', InvalidSelectorException::class], + ['invalid session id', InvalidSessionIdException::class], + ['javascript error', JavascriptErrorException::class], + ['move target out of bounds', MoveTargetOutOfBoundsException::class], + ['no such alert', NoSuchAlertException::class], + ['no such cookie', NoSuchCookieException::class], + ['no such element', NoSuchElementException::class], + ['no such frame', NoSuchFrameException::class], + ['no such window', NoSuchWindowException::class], + ['script timeout', ScriptTimeoutException::class], + ['session not created', SessionNotCreatedException::class], + ['stale element reference', StaleElementReferenceException::class], + ['timeout', TimeoutException::class], + ['unable to set cookie', UnableToSetCookieException::class], + ['unable to capture screen', UnableToCaptureScreenException::class], + ['unexpected alert open', UnexpectedAlertOpenException::class], + ['unknown command', UnknownCommandException::class], + ['unknown error', UnknownErrorException::class], + ['unknown method', UnknownMethodException::class], + ['unsupported operation', UnsupportedOperationException::class], + ]; + } } From 88fff59dac637265906d100fb91142d3f5475aca Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Thu, 21 Nov 2019 09:32:34 +0800 Subject: [PATCH 468/784] Pass W3C Compliance to RemoteTargetLocator --- lib/Remote/RemoteTargetLocator.php | 11 +++++++---- lib/Remote/RemoteWebDriver.php | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/Remote/RemoteTargetLocator.php b/lib/Remote/RemoteTargetLocator.php index 8bd89ef44..1f8cb9270 100644 --- a/lib/Remote/RemoteTargetLocator.php +++ b/lib/Remote/RemoteTargetLocator.php @@ -33,11 +33,16 @@ class RemoteTargetLocator implements WebDriverTargetLocator * @var WebDriver */ protected $driver; + /** + * @var bool + */ + protected $isW3cCompliant; - public function __construct($executor, $driver) + public function __construct($executor, $driver, $isW3cCompliant = false) { $this->executor = $executor; $this->driver = $driver; + $this->isW3cCompliant = $isW3cCompliant; } /** @@ -112,8 +117,6 @@ public function activeElement() $response = $this->driver->execute(DriverCommand::GET_ACTIVE_ELEMENT, []); $method = new RemoteExecuteMethod($this->driver); - $isW3cCompliant = ($this->driver instanceof RemoteWebDriver) ? $this->driver->isW3cCompliant() : false; - - return new RemoteWebElement($method, JsonWireCompat::getElement($response), $isW3cCompliant); + return new RemoteWebElement($method, JsonWireCompat::getElement($response), $this->isW3cCompliant); } } diff --git a/lib/Remote/RemoteWebDriver.php b/lib/Remote/RemoteWebDriver.php index 1762f44a8..3164bad5e 100644 --- a/lib/Remote/RemoteWebDriver.php +++ b/lib/Remote/RemoteWebDriver.php @@ -432,7 +432,7 @@ public function navigate() */ public function switchTo() { - return new RemoteTargetLocator($this->getExecuteMethod(), $this); + return new RemoteTargetLocator($this->getExecuteMethod(), $this, $this->isW3cCompliant); } /** From 57f871eaa558b1108ece0fc4a713dd57796e4d50 Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Wed, 20 Nov 2019 20:54:38 +0800 Subject: [PATCH 469/784] W3C switchToWindow takes a handle The W3C specification dictates that the parameter used to select the window should be named `handle`. Source: https://www.w3.org/TR/webdriver/#switch-to-window --- lib/Remote/RemoteTargetLocator.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/Remote/RemoteTargetLocator.php b/lib/Remote/RemoteTargetLocator.php index 1f8cb9270..7e8dbcd1f 100644 --- a/lib/Remote/RemoteTargetLocator.php +++ b/lib/Remote/RemoteTargetLocator.php @@ -89,7 +89,12 @@ public function frame($frame) */ public function window($handle) { - $params = ['name' => (string) $handle]; + if ($this->isW3cCompliant) { + $params = ['handle' => (string) $handle]; + } else { + $params = ['name' => (string) $handle]; + } + $this->executor->execute(DriverCommand::SWITCH_TO_WINDOW, $params); return $this->driver; From 98686d91d96db975e1e22f6a8bdc5ccda2b54319 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Mon, 25 Nov 2019 18:54:33 +0100 Subject: [PATCH 470/784] Add tests for switchTo()->window() of RemoteTargetLocator --- tests/functional/RemoteTargetLocatorTest.php | 55 ++++++++++++++++++++ tests/functional/WebDriverAlertTest.php | 1 + tests/functional/web/index.html | 2 + tests/functional/web/open_new_window.html | 2 +- 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 tests/functional/RemoteTargetLocatorTest.php diff --git a/tests/functional/RemoteTargetLocatorTest.php b/tests/functional/RemoteTargetLocatorTest.php new file mode 100644 index 000000000..210e90b18 --- /dev/null +++ b/tests/functional/RemoteTargetLocatorTest.php @@ -0,0 +1,55 @@ +driver->get($this->getTestPageUrl('open_new_window.html')); + $originalWindowHandle = $this->driver->getWindowHandle(); + $windowHandlesBefore = $this->driver->getWindowHandles(); + + $this->driver->findElement(WebDriverBy::cssSelector('a#open-new-window')) + ->click(); + + $this->driver->wait()->until( + WebDriverExpectedCondition::numberOfWindowsToBe(2) + ); + + // At first the window should not be switched + $this->assertContains('open_new_window.html', $this->driver->getCurrentURL()); + $this->assertSame($originalWindowHandle, $this->driver->getWindowHandle()); + + /** + * @see https://w3c.github.io/webdriver/#get-window-handles + * > "The order in which the window handles are returned is arbitrary." + * Thus we must first find out which window handle is the new one + */ + $windowHandlesAfter = $this->driver->getWindowHandles(); + $newWindowHandle = array_diff($windowHandlesAfter, $windowHandlesBefore); + $newWindowHandle = reset($newWindowHandle); + + $this->driver->switchTo()->window($newWindowHandle); + + // After switchTo() is called, the active window should be changed + $this->assertContains('index.html', $this->driver->getCurrentURL()); + $this->assertNotSame($originalWindowHandle, $this->driver->getWindowHandle()); + } +} diff --git a/tests/functional/WebDriverAlertTest.php b/tests/functional/WebDriverAlertTest.php index b5fd3dec5..72d38d82a 100644 --- a/tests/functional/WebDriverAlertTest.php +++ b/tests/functional/WebDriverAlertTest.php @@ -21,6 +21,7 @@ /** * @covers \Facebook\WebDriver\WebDriverAlert + * @covers \Facebook\WebDriver\Remote\RemoteTargetLocator */ class WebDriverAlertTest extends WebDriverTestCase { diff --git a/tests/functional/web/index.html b/tests/functional/web/index.html index cf5b9c6c1..ff80fe025 100644 --- a/tests/functional/web/index.html +++ b/tests/functional/web/index.html @@ -11,6 +11,8 @@

    Welcome to the facebook/php-webdriver testing page.

    | Form with file upload | + Form with checkboxes and radios + | New window opener test page | Delayed render diff --git a/tests/functional/web/open_new_window.html b/tests/functional/web/open_new_window.html index b56e93d69..3c790226a 100644 --- a/tests/functional/web/open_new_window.html +++ b/tests/functional/web/open_new_window.html @@ -5,6 +5,6 @@ php-webdriver test page - open new window + open new window From 51353795e94ed34d23f2657bb690827a072ad14a Mon Sep 17 00:00:00 2001 From: Andrew Nicols Date: Thu, 21 Nov 2019 08:32:22 +0800 Subject: [PATCH 471/784] Make GET_ACTIVE_ELEMENT a GET for W3C As defined in the specification 12.2.6: HTTP Method URI Template GET /session/{session id}/element/active Source: https://www.w3.org/TR/webdriver/#get-active-element --- lib/Remote/HttpCommandExecutor.php | 1 + tests/functional/RemoteTargetLocatorTest.php | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/lib/Remote/HttpCommandExecutor.php b/lib/Remote/HttpCommandExecutor.php index d137030a4..a1b05c5ff 100644 --- a/lib/Remote/HttpCommandExecutor.php +++ b/lib/Remote/HttpCommandExecutor.php @@ -146,6 +146,7 @@ class HttpCommandExecutor implements WebDriverCommandExecutor DriverCommand::DISMISS_ALERT => ['method' => 'POST', 'url' => '/session/:sessionId/alert/dismiss'], DriverCommand::EXECUTE_ASYNC_SCRIPT => ['method' => 'POST', 'url' => '/session/:sessionId/execute/async'], DriverCommand::EXECUTE_SCRIPT => ['method' => 'POST', 'url' => '/session/:sessionId/execute/sync'], + DriverCommand::GET_ACTIVE_ELEMENT => ['method' => 'GET', 'url' => '/session/:sessionId/element/active'], DriverCommand::GET_ALERT_TEXT => ['method' => 'GET', 'url' => '/session/:sessionId/alert/text'], DriverCommand::GET_CURRENT_WINDOW_HANDLE => ['method' => 'GET', 'url' => '/session/:sessionId/window'], DriverCommand::GET_ELEMENT_LOCATION => ['method' => 'GET', 'url' => '/session/:sessionId/element/:id/rect'], diff --git a/tests/functional/RemoteTargetLocatorTest.php b/tests/functional/RemoteTargetLocatorTest.php index 210e90b18..becc194c8 100644 --- a/tests/functional/RemoteTargetLocatorTest.php +++ b/tests/functional/RemoteTargetLocatorTest.php @@ -15,6 +15,8 @@ namespace Facebook\WebDriver; +use Facebook\WebDriver\Remote\RemoteWebElement; + /** * @covers \Facebook\WebDriver\Remote\RemoteTargetLocator */ @@ -52,4 +54,21 @@ public function testShouldSwitchToWindow() $this->assertContains('index.html', $this->driver->getCurrentURL()); $this->assertNotSame($originalWindowHandle, $this->driver->getWindowHandle()); } + + /** + * @cover ::activeElement + */ + public function testActiveElement() + { + $this->driver->get($this->getTestPageUrl('index.html')); + + $activeElement = $this->driver->switchTo()->activeElement(); + $this->assertInstanceOf(RemoteWebElement::class, $activeElement); + $this->assertSame('body', $activeElement->getTagName()); + + $this->driver->findElement(WebDriverBy::name('test_name'))->click(); + $activeElement = $this->driver->switchTo()->activeElement(); + $this->assertSame('input', $activeElement->getTagName()); + $this->assertSame('test_name', $activeElement->getAttribute('name')); + } } From 1dcec4bcda282ae4ea6a4e1314a1cd3c953974d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Machulda?= Date: Tue, 26 Nov 2019 17:12:40 +0100 Subject: [PATCH 472/784] Minor codestyle improvements and unifications --- .php_cs.dist | 10 +++++++++- phpstan.neon | 16 ++++++++-------- tests/functional/RemoteWebDriverCreateTest.php | 2 +- tests/functional/RemoteWebDriverTest.php | 2 +- tests/functional/WebDriverActionsTest.php | 2 +- tests/functional/WebDriverAlertTest.php | 2 +- tests/functional/WebDriverByTest.php | 7 +++++-- tests/functional/WebDriverCheckboxesTest.php | 14 +++++++------- tests/functional/WebDriverNavigationTest.php | 2 +- tests/functional/WebDriverRadiosTest.php | 14 +++++++------- tests/functional/WebDriverSelectTest.php | 9 ++++++--- tests/functional/WebDriverTimeoutsTest.php | 4 ++-- tests/unit/CookieTest.php | 4 ++-- tests/unit/Exception/WebDriverExceptionTest.php | 8 ++++---- .../WebDriverButtonReleaseActionTest.php | 4 ++-- .../Internal/WebDriverClickActionTest.php | 4 ++-- .../Internal/WebDriverClickAndHoldActionTest.php | 4 ++-- .../Internal/WebDriverContextClickActionTest.php | 4 ++-- .../Internal/WebDriverCoordinatesTest.php | 10 +++++----- .../Internal/WebDriverDoubleClickActionTest.php | 4 ++-- .../Internal/WebDriverKeyDownActionTest.php | 4 ++-- .../Internal/WebDriverKeyUpActionTest.php | 4 ++-- .../Internal/WebDriverMouseMoveActionTest.php | 4 ++-- .../WebDriverMouseToOffsetActionTest.php | 4 ++-- .../Internal/WebDriverSendKeysActionTest.php | 4 ++-- tests/unit/Remote/DesiredCapabilitiesTest.php | 6 +++--- tests/unit/Remote/HttpCommandExecutorTest.php | 6 +++--- tests/unit/Remote/RemoteWebDriverTest.php | 2 +- tests/unit/Support/XPathEscaperTest.php | 4 ++-- tests/unit/WebDriverOptionsTest.php | 2 +- 30 files changed, 90 insertions(+), 76 deletions(-) diff --git a/.php_cs.dist b/.php_cs.dist index 48aa29de7..b771f8b04 100644 --- a/.php_cs.dist +++ b/.php_cs.dist @@ -13,6 +13,8 @@ return PhpCsFixer\Config::create() 'concat_space' => ['spacing' => 'one'], 'function_typehint_space' => true, 'general_phpdoc_annotation_remove' => ['author'], + 'implode_call' => true, + 'is_null' => true, 'linebreak_after_opening_tag' => true, 'lowercase_cast' => true, 'mb_str_functions' => true, @@ -51,9 +53,15 @@ return PhpCsFixer\Config::create() 'ordered_imports' => true, 'php_unit_construct' => true, 'php_unit_dedicate_assert' => true, - 'php_unit_expectation' => true, + 'php_unit_expectation' => ['target' => '5.6'], + 'php_unit_method_casing' => ['case' => 'camel_case'], 'php_unit_mock' => true, + 'php_unit_mock_short_will_return' => true, + 'php_unit_namespaced' => ['target' => '5.7'], 'php_unit_no_expectation_annotation' => true, + 'php_unit_ordered_covers' => true, + 'php_unit_set_up_tear_down_visibility' => true, + 'php_unit_test_case_static_method_calls' => ['call_type' => 'this'], 'phpdoc_add_missing_param_annotation' => true, 'phpdoc_indent' => true, 'phpdoc_no_access' => true, diff --git a/phpstan.neon b/phpstan.neon index 7023c466e..3ea02aee5 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,10 +1,10 @@ parameters: - ignoreErrors: - - '#Class Symfony\\Component\\Process\\ProcessBuilder not found.#' - - '#Instantiated class Symfony\\Component\\Process\\ProcessBuilder not found.#' - - '#Call to method setPrefix\(\) on an unknown class Symfony\\Component\\Process\\ProcessBuilder#' + ignoreErrors: + - '#Class Symfony\\Component\\Process\\ProcessBuilder not found.#' + - '#Instantiated class Symfony\\Component\\Process\\ProcessBuilder not found.#' + - '#Call to method setPrefix\(\) on an unknown class Symfony\\Component\\Process\\ProcessBuilder#' # To be fixed: - - '#Call to an undefined method RecursiveIteratorIterator::getSubPathName\(\)#' - - '#Call to an undefined method Facebook\\WebDriver\\WebDriver::getTouch\(\)#' - - '#Call to an undefined method Facebook\\WebDriver\\WebDriverElement::getCoordinates\(\)#' - - '#Call to an undefined method Facebook\\WebDriver\\WebDriverElement::equals\(\)#' + - '#Call to an undefined method RecursiveIteratorIterator::getSubPathName\(\)#' + - '#Call to an undefined method Facebook\\WebDriver\\WebDriver::getTouch\(\)#' + - '#Call to an undefined method Facebook\\WebDriver\\WebDriverElement::getCoordinates\(\)#' + - '#Call to an undefined method Facebook\\WebDriver\\WebDriverElement::equals\(\)#' diff --git a/tests/functional/RemoteWebDriverCreateTest.php b/tests/functional/RemoteWebDriverCreateTest.php index a2f6e9d0f..5abec763b 100644 --- a/tests/functional/RemoteWebDriverCreateTest.php +++ b/tests/functional/RemoteWebDriverCreateTest.php @@ -20,8 +20,8 @@ use Facebook\WebDriver\Remote\RemoteWebDriver; /** - * @covers \Facebook\WebDriver\Remote\RemoteWebDriver * @covers \Facebook\WebDriver\Remote\HttpCommandExecutor + * @covers \Facebook\WebDriver\Remote\RemoteWebDriver */ class RemoteWebDriverCreateTest extends WebDriverTestCase { diff --git a/tests/functional/RemoteWebDriverTest.php b/tests/functional/RemoteWebDriverTest.php index 72fc30505..6f3becb0b 100644 --- a/tests/functional/RemoteWebDriverTest.php +++ b/tests/functional/RemoteWebDriverTest.php @@ -38,8 +38,8 @@ public function testShouldGetPageTitle() } /** - * @covers ::getCurrentURL * @covers ::get + * @covers ::getCurrentURL */ public function testShouldGetCurrentUrl() { diff --git a/tests/functional/WebDriverActionsTest.php b/tests/functional/WebDriverActionsTest.php index cb4359183..deb700575 100644 --- a/tests/functional/WebDriverActionsTest.php +++ b/tests/functional/WebDriverActionsTest.php @@ -61,8 +61,8 @@ public function testShouldClickOnElement() /** * @covers ::__construct * @covers ::clickAndHold - * @covers ::release * @covers ::perform + * @covers ::release */ public function testShouldClickAndHoldOnElementAndRelease() { diff --git a/tests/functional/WebDriverAlertTest.php b/tests/functional/WebDriverAlertTest.php index 72d38d82a..d6f5c91a2 100644 --- a/tests/functional/WebDriverAlertTest.php +++ b/tests/functional/WebDriverAlertTest.php @@ -20,8 +20,8 @@ use Facebook\WebDriver\Remote\WebDriverBrowserType; /** - * @covers \Facebook\WebDriver\WebDriverAlert * @covers \Facebook\WebDriver\Remote\RemoteTargetLocator + * @covers \Facebook\WebDriver\WebDriverAlert */ class WebDriverAlertTest extends WebDriverTestCase { diff --git a/tests/functional/WebDriverByTest.php b/tests/functional/WebDriverByTest.php index 028db7920..4ff114751 100644 --- a/tests/functional/WebDriverByTest.php +++ b/tests/functional/WebDriverByTest.php @@ -24,7 +24,7 @@ class WebDriverByTest extends WebDriverTestCase { /** - * @dataProvider textElementsProvider + * @dataProvider provideTextElements * @param string $webDriverByLocatorMethod * @param string $webDriverByLocatorValue * @param string $expectedText @@ -52,7 +52,10 @@ public function testShouldFindTextElementByLocator( } } - public function textElementsProvider() + /** + * @return array[] + */ + public function provideTextElements() { return [ 'id' => ['id', 'id_test', 'Test by ID'], diff --git a/tests/functional/WebDriverCheckboxesTest.php b/tests/functional/WebDriverCheckboxesTest.php index 91513bd94..0ddcccd0d 100644 --- a/tests/functional/WebDriverCheckboxesTest.php +++ b/tests/functional/WebDriverCheckboxesTest.php @@ -18,8 +18,8 @@ use Facebook\WebDriver\Exception\NoSuchElementException; /** - * @covers \Facebook\WebDriver\WebDriverCheckboxes * @covers \Facebook\WebDriver\AbstractWebDriverCheckboxOrRadio + * @covers \Facebook\WebDriver\WebDriverCheckboxes * @group exclude-edge */ class WebDriverCheckboxesTest extends WebDriverTestCase @@ -137,7 +137,7 @@ public function testSelectByIndexInvalid() } /** - * @dataProvider selectByVisibleTextDataProvider + * @dataProvider provideSelectByVisibleTextData * * @param string $text * @param string $value @@ -154,9 +154,9 @@ public function testSelectByVisibleText($text, $value) } /** - * @return array + * @return array[] */ - public function selectByVisibleTextDataProvider() + public function provideSelectByVisibleTextData() { return [ ['J 2 B', 'j2b'], @@ -165,7 +165,7 @@ public function selectByVisibleTextDataProvider() } /** - * @dataProvider selectByVisiblePartialTextDataProvider + * @dataProvider provideSelectByVisiblePartialTextData * * @param string $text * @param string $value @@ -182,9 +182,9 @@ public function testSelectByVisiblePartialText($text, $value) } /** - * @return array + * @return array[] */ - public function selectByVisiblePartialTextDataProvider() + public function provideSelectByVisiblePartialTextData() { return [ ['2 B', 'j2b'], diff --git a/tests/functional/WebDriverNavigationTest.php b/tests/functional/WebDriverNavigationTest.php index d3aaebcb6..c2286f3b2 100644 --- a/tests/functional/WebDriverNavigationTest.php +++ b/tests/functional/WebDriverNavigationTest.php @@ -21,8 +21,8 @@ class WebDriverNavigationTest extends WebDriverTestCase { /** - * @covers ::to * @covers ::__construct + * @covers ::to */ public function testShouldNavigateToUrl() { diff --git a/tests/functional/WebDriverRadiosTest.php b/tests/functional/WebDriverRadiosTest.php index cf7b8378c..bb0eaa41e 100644 --- a/tests/functional/WebDriverRadiosTest.php +++ b/tests/functional/WebDriverRadiosTest.php @@ -19,8 +19,8 @@ use Facebook\WebDriver\Exception\UnsupportedOperationException; /** - * @covers \Facebook\WebDriver\WebDriverRadios * @covers \Facebook\WebDriver\AbstractWebDriverCheckboxOrRadio + * @covers \Facebook\WebDriver\WebDriverRadios * @group exclude-edge */ class WebDriverRadiosTest extends WebDriverTestCase @@ -115,7 +115,7 @@ public function testSelectByIndexInvalid() } /** - * @dataProvider selectByVisibleTextDataProvider + * @dataProvider provideSelectByVisibleTextData * * @param string $text * @param string $value @@ -128,9 +128,9 @@ public function testSelectByVisibleText($text, $value) } /** - * @return array + * @return array[] */ - public function selectByVisibleTextDataProvider() + public function provideSelectByVisibleTextData() { return [ ['J 3 B', 'j3b'], @@ -139,7 +139,7 @@ public function selectByVisibleTextDataProvider() } /** - * @dataProvider selectByVisiblePartialTextDataProvider + * @dataProvider provideSelectByVisiblePartialTextData * * @param string $text * @param string $value @@ -152,9 +152,9 @@ public function testSelectByVisiblePartialText($text, $value) } /** - * @return array + * @return array[] */ - public function selectByVisiblePartialTextDataProvider() + public function provideSelectByVisiblePartialTextData() { return [ ['3 B', 'j3b'], diff --git a/tests/functional/WebDriverSelectTest.php b/tests/functional/WebDriverSelectTest.php index b25dd03af..8d96a1944 100644 --- a/tests/functional/WebDriverSelectTest.php +++ b/tests/functional/WebDriverSelectTest.php @@ -21,8 +21,8 @@ /** * @group exclude-saucelabs - * @covers \Facebook\WebDriver\WebDriverSelect * @covers \Facebook\WebDriver\Exception\UnexpectedTagNameException + * @covers \Facebook\WebDriver\WebDriverSelect */ class WebDriverSelectTest extends WebDriverTestCase { @@ -58,7 +58,7 @@ public function testShouldThrowExceptionWhenNotInstantiatedOnSelectElement() } /** - * @dataProvider selectSelectorProvider + * @dataProvider provideSelectSelector * @param string $selector */ public function testShouldGetOptionsOfSelect($selector) @@ -72,7 +72,10 @@ public function testShouldGetOptionsOfSelect($selector) $this->assertCount(5, $options); } - public function selectSelectorProvider() + /** + * @return array[] + */ + public function provideSelectSelector() { return [ 'simple + +
    +