Chris@14
|
1 <?php
|
Chris@14
|
2 /**
|
Chris@14
|
3 * Copyright 2014-2017 Anthon Pang. All Rights Reserved.
|
Chris@14
|
4 *
|
Chris@14
|
5 * Licensed under the Apache License, Version 2.0 (the "License");
|
Chris@14
|
6 * you may not use this file except in compliance with the License.
|
Chris@14
|
7 * You may obtain a copy of the License at
|
Chris@14
|
8 *
|
Chris@14
|
9 * http://www.apache.org/licenses/LICENSE-2.0
|
Chris@14
|
10 *
|
Chris@14
|
11 * Unless required by applicable law or agreed to in writing, software
|
Chris@14
|
12 * distributed under the License is distributed on an "AS IS" BASIS,
|
Chris@14
|
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
Chris@14
|
14 * See the License for the specific language governing permissions and
|
Chris@14
|
15 * limitations under the License.
|
Chris@14
|
16 *
|
Chris@14
|
17 * @package WebDriver
|
Chris@14
|
18 *
|
Chris@14
|
19 * @author Anthon Pang <apang@softwaredevelopment.ca>
|
Chris@14
|
20 * @author Damian Mooyman <damian@silverstripe.com>
|
Chris@14
|
21 */
|
Chris@14
|
22
|
Chris@14
|
23 namespace Test\WebDriver;
|
Chris@14
|
24
|
Chris@14
|
25 use WebDriver\ServiceFactory;
|
Chris@14
|
26 use WebDriver\WebDriver;
|
Chris@14
|
27
|
Chris@14
|
28 /**
|
Chris@14
|
29 * Test WebDriver\WebDriver class
|
Chris@14
|
30 *
|
Chris@14
|
31 * @package WebDriver
|
Chris@14
|
32 *
|
Chris@14
|
33 * @group Functional
|
Chris@14
|
34 */
|
Chris@14
|
35 class WebDriverTest extends \PHPUnit_Framework_TestCase
|
Chris@14
|
36 {
|
Chris@14
|
37 private $driver;
|
Chris@14
|
38 private $session;
|
Chris@14
|
39 private $testDocumentRootUrl = 'http://localhost';
|
Chris@14
|
40 private $testSeleniumRootUrl = 'http://localhost:4444/wd/hub';
|
Chris@14
|
41
|
Chris@14
|
42 /**
|
Chris@14
|
43 * {@inheritdoc}
|
Chris@14
|
44 */
|
Chris@14
|
45 protected function setUp()
|
Chris@14
|
46 {
|
Chris@14
|
47 ServiceFactory::getInstance()->setServiceClass('service.curl', '\\WebDriver\\Service\\CurlService');
|
Chris@14
|
48
|
Chris@14
|
49 if ($url = getenv('ROOT_URL')) {
|
Chris@14
|
50 $this->testDocumentRootUrl = $url;
|
Chris@14
|
51 }
|
Chris@14
|
52
|
Chris@14
|
53 if ($url = getenv('SELENIUM_URL')) {
|
Chris@14
|
54 $this->testSeleniumRootUrl = $url;
|
Chris@14
|
55 }
|
Chris@14
|
56
|
Chris@14
|
57 $this->driver = new WebDriver($this->getTestSeleniumRootUrl());
|
Chris@14
|
58 $this->session = null;
|
Chris@14
|
59 }
|
Chris@14
|
60
|
Chris@14
|
61 /**
|
Chris@14
|
62 * {@inheritdoc}
|
Chris@14
|
63 */
|
Chris@14
|
64 protected function tearDown()
|
Chris@14
|
65 {
|
Chris@14
|
66 if ($this->session) {
|
Chris@14
|
67 $this->session->close();
|
Chris@14
|
68 }
|
Chris@14
|
69 }
|
Chris@14
|
70
|
Chris@14
|
71 /**
|
Chris@14
|
72 * Returns the full url to the test site (corresponding to the root dir of the library).
|
Chris@14
|
73 * You can set this via env var ROOT_URL
|
Chris@14
|
74 *
|
Chris@14
|
75 * @return string
|
Chris@14
|
76 */
|
Chris@14
|
77 protected function getTestDocumentRootUrl()
|
Chris@14
|
78 {
|
Chris@14
|
79 return $this->testDocumentRootUrl;
|
Chris@14
|
80 }
|
Chris@14
|
81
|
Chris@14
|
82 /**
|
Chris@14
|
83 * Returns the full url to the Selenium server used for functional tests
|
Chris@14
|
84 *
|
Chris@14
|
85 * @return string
|
Chris@14
|
86 *
|
Chris@14
|
87 * @todo make this configurable via env var
|
Chris@14
|
88 */
|
Chris@14
|
89 protected function getTestSeleniumRootUrl()
|
Chris@14
|
90 {
|
Chris@14
|
91 return $this->testSeleniumRootUrl;
|
Chris@14
|
92 }
|
Chris@14
|
93
|
Chris@14
|
94 /**
|
Chris@14
|
95 * Is Selenium down?
|
Chris@14
|
96 *
|
Chris@14
|
97 * @param \Exception $exception
|
Chris@14
|
98 *
|
Chris@14
|
99 * @return boolean
|
Chris@14
|
100 */
|
Chris@14
|
101 protected function isSeleniumDown($exception)
|
Chris@14
|
102 {
|
Chris@14
|
103 return preg_match('/Failed to connect to .* Connection refused/', $exception->getMessage()) != false
|
Chris@14
|
104 || strpos($exception->getMessage(), 'couldn\'t connect to host') !== false
|
Chris@14
|
105 || strpos($exception->getMessage(), 'Unable to connect to host') !== false;
|
Chris@14
|
106 }
|
Chris@14
|
107
|
Chris@14
|
108 /**
|
Chris@14
|
109 * Test driver sessions
|
Chris@14
|
110 */
|
Chris@14
|
111 public function testSessions()
|
Chris@14
|
112 {
|
Chris@14
|
113 try {
|
Chris@14
|
114 $this->assertCount(0, $this->driver->sessions());
|
Chris@14
|
115
|
Chris@14
|
116 $this->session = $this->driver->session();
|
Chris@14
|
117 } catch (\Exception $e) {
|
Chris@14
|
118 if ($this->isSeleniumDown($e)) {
|
Chris@14
|
119 $this->markTestSkipped('selenium server not running');
|
Chris@14
|
120
|
Chris@14
|
121 return;
|
Chris@14
|
122 }
|
Chris@14
|
123
|
Chris@14
|
124 throw $e;
|
Chris@14
|
125 }
|
Chris@14
|
126
|
Chris@14
|
127 $this->assertCount(1, $this->driver->sessions());
|
Chris@14
|
128 $this->assertEquals($this->getTestSeleniumRootUrl(), $this->driver->getUrl());
|
Chris@14
|
129 }
|
Chris@14
|
130
|
Chris@14
|
131 /**
|
Chris@14
|
132 * Test driver status
|
Chris@14
|
133 */
|
Chris@14
|
134 public function testStatus()
|
Chris@14
|
135 {
|
Chris@14
|
136 try {
|
Chris@14
|
137 $status = $this->driver->status();
|
Chris@14
|
138 } catch (\Exception $e) {
|
Chris@14
|
139 if ($this->isSeleniumDown($e)) {
|
Chris@14
|
140 $this->markTestSkipped('selenium server not running');
|
Chris@14
|
141
|
Chris@14
|
142 return;
|
Chris@14
|
143 }
|
Chris@14
|
144
|
Chris@14
|
145 throw $e;
|
Chris@14
|
146 }
|
Chris@14
|
147
|
Chris@14
|
148 $this->assertCount(3, $status);
|
Chris@14
|
149 $this->assertTrue(isset($status['java']));
|
Chris@14
|
150 $this->assertTrue(isset($status['os']));
|
Chris@14
|
151 $this->assertTrue(isset($status['build']));
|
Chris@14
|
152 }
|
Chris@14
|
153
|
Chris@14
|
154 /**
|
Chris@14
|
155 * Checks that an error connecting to Selenium gives back the expected exception
|
Chris@14
|
156 */
|
Chris@14
|
157 public function testSeleniumError()
|
Chris@14
|
158 {
|
Chris@14
|
159 try {
|
Chris@14
|
160 $this->driver = new WebDriver($this->getTestSeleniumRootUrl() . '/../invalidurl');
|
Chris@14
|
161
|
Chris@14
|
162 $status = $this->driver->status();
|
Chris@14
|
163
|
Chris@14
|
164 $this->fail('Exception not thrown while connecting to invalid Selenium url');
|
Chris@14
|
165 } catch (\Exception $e) {
|
Chris@14
|
166 if ($this->isSeleniumDown($e)) {
|
Chris@14
|
167 $this->markTestSkipped('selenium server not running');
|
Chris@14
|
168
|
Chris@14
|
169 return;
|
Chris@14
|
170 }
|
Chris@14
|
171
|
Chris@14
|
172 $this->assertEquals('WebDriver\Exception\CurlExec', get_class($e));
|
Chris@14
|
173 }
|
Chris@14
|
174 }
|
Chris@14
|
175
|
Chris@14
|
176 /**
|
Chris@14
|
177 * Checks that a successful command to Selenium which returns an http error response gives back the expected exception
|
Chris@14
|
178 */
|
Chris@14
|
179 public function testSeleniumErrorResponse()
|
Chris@14
|
180 {
|
Chris@14
|
181 try {
|
Chris@14
|
182 $status = $this->driver->status();
|
Chris@14
|
183 } catch (\Exception $e) {
|
Chris@14
|
184 if ($this->isSeleniumDown($e)) {
|
Chris@14
|
185 $this->markTestSkipped('selenium server not running');
|
Chris@14
|
186
|
Chris@14
|
187 return;
|
Chris@14
|
188 }
|
Chris@14
|
189
|
Chris@14
|
190 throw $e;
|
Chris@14
|
191 }
|
Chris@14
|
192
|
Chris@14
|
193 try {
|
Chris@14
|
194 $this->session = $this->driver->session();
|
Chris@14
|
195 $this->session->open($this->getTestDocumentRootUrl().'/test/Assets/index.html');
|
Chris@14
|
196
|
Chris@14
|
197 $element = $this->session->element('id', 'a-quite-unlikely-html-element-id');
|
Chris@14
|
198
|
Chris@14
|
199 $this->fail('Exception not thrown while looking for missing element in page');
|
Chris@14
|
200 } catch (\Exception $e) {
|
Chris@14
|
201 $this->assertEquals('WebDriver\Exception\NoSuchElement', get_class($e));
|
Chris@14
|
202 }
|
Chris@14
|
203 }
|
Chris@14
|
204
|
Chris@14
|
205 /**
|
Chris@14
|
206 * Checks that a successful command to Selenium which returns 'nothing' according to spec does not raise an error
|
Chris@14
|
207 */
|
Chris@14
|
208 public function testSeleniumNoResponse()
|
Chris@14
|
209 {
|
Chris@14
|
210 try {
|
Chris@14
|
211 $status = $this->driver->status();
|
Chris@14
|
212 } catch (\Exception $e) {
|
Chris@14
|
213 if ($this->isSeleniumDown($e)) {
|
Chris@14
|
214 $this->markTestSkipped('selenium server not running');
|
Chris@14
|
215
|
Chris@14
|
216 return;
|
Chris@14
|
217 }
|
Chris@14
|
218
|
Chris@14
|
219 throw $e;
|
Chris@14
|
220 }
|
Chris@14
|
221
|
Chris@14
|
222 $this->session = $this->driver->session();
|
Chris@14
|
223 $timeouts = $this->session->timeouts();
|
Chris@14
|
224 $out = $timeouts->async_script(array('type' => 'implicit', 'ms' => 1000));
|
Chris@14
|
225
|
Chris@14
|
226 $this->assertEquals(null, $out);
|
Chris@14
|
227 }
|
Chris@14
|
228
|
Chris@14
|
229 /**
|
Chris@14
|
230 * Assert that empty response does not trigger exception, but invalid JSON does
|
Chris@14
|
231 */
|
Chris@14
|
232 public function testNonJsonResponse()
|
Chris@14
|
233 {
|
Chris@14
|
234 $mockCurlService = $this->createMock('WebDriver\Service\CurlService');
|
Chris@14
|
235 $mockCurlService->expects($this->once())
|
Chris@14
|
236 ->method('execute')
|
Chris@14
|
237 ->will($this->returnCallback(function ($requestMethod, $url) {
|
Chris@14
|
238 $info = array(
|
Chris@14
|
239 'url' => $url,
|
Chris@14
|
240 'request_method' => $requestMethod,
|
Chris@14
|
241 'http_code' => 200,
|
Chris@14
|
242 );
|
Chris@14
|
243
|
Chris@14
|
244 $result = preg_match('#.*session$#', $url)
|
Chris@14
|
245 ? $result = 'some invalid json'
|
Chris@14
|
246 : $result = '';
|
Chris@14
|
247
|
Chris@14
|
248 return array($result, $info);
|
Chris@14
|
249 }));
|
Chris@14
|
250
|
Chris@14
|
251 ServiceFactory::getInstance()->setService('service.curl', $mockCurlService);
|
Chris@14
|
252
|
Chris@14
|
253 $result = $this->driver->status();
|
Chris@14
|
254
|
Chris@14
|
255 $this->assertNull($result);
|
Chris@14
|
256
|
Chris@14
|
257 // Test /session should error
|
Chris@14
|
258 $this->setExpectedException(
|
Chris@14
|
259 'WebDriver\Exception\CurlExec',
|
Chris@14
|
260 'Payload received from webdriver is not valid json: some invalid json'
|
Chris@14
|
261 );
|
Chris@14
|
262
|
Chris@14
|
263 $result = $this->driver->session();
|
Chris@14
|
264
|
Chris@14
|
265 $this->assertNull($result);
|
Chris@14
|
266 }
|
Chris@14
|
267 }
|