Skip to content

Commit 8b6f31b

Browse files
committed
openUri method implementation (W3C client)
1 parent 513ab20 commit 8b6f31b

5 files changed

Lines changed: 50 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2020
- `WebDriverFactory` as a shortcut for driver instantiation.
2121
- `Timeout\Interceptor` to prevent unresolved (hanging) driver promises, whenever it fails
2222
(using [reactphp/promise-timer](https://github.com/reactphp/promise-timer)).
23-
- `ClientInterface::createSession()` method implementation (opening Selenium hub session to interact with remote
23+
- `ClientInterface::createSession()` method implementation (opening a Selenium hub session to interact with remote
2424
browser instance).
2525

2626
This early development version doesn't yet contain full implementation for the introduced `WebDriverInterface`, only

src/Client/W3CClient.php

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,41 @@ public function setActiveTab(string $sessionIdentifier, string $tabIdentifier):
269269
*/
270270
public function openUri(string $sessionIdentifier, string $uri): PromiseInterface
271271
{
272-
// TODO: Implement openUri() method.
272+
$requestUri = sprintf(
273+
'http://%s:%d/wd/hub/session/%s/url',
274+
$this->_options['server']['host'],
275+
$this->_options['server']['port'],
276+
$sessionIdentifier
277+
);
273278

274-
return reject(new RuntimeException('Not implemented.'));
279+
$requestHeaders = [
280+
'Content-Type' => 'application/json; charset=UTF-8',
281+
];
282+
283+
$requestContents = json_encode(['url' => $uri]);
284+
285+
$responsePromise = $this->httpClient->post($requestUri, $requestHeaders, $requestContents);
286+
287+
$navigationPromise = $responsePromise
288+
->then(
289+
function (ResponseInterface $response) {
290+
$responseBody = (string) $response->getBody();
291+
292+
// todo: locate an error message or set it as "undefined error"
293+
if ('{"value":null}' !== $responseBody) {
294+
throw new RuntimeException('URI navigation is not confirmed.');
295+
}
296+
}
297+
)
298+
->then(
299+
null,
300+
function (Throwable $rejectionReason) {
301+
throw new RuntimeException('Unable to open an URI (request).', 0, $rejectionReason);
302+
}
303+
)
304+
;
305+
306+
return $navigationPromise;
275307
}
276308

277309
/**

src/SeleniumHubDriver.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Symfony\Component\OptionsResolver\Exception\ExceptionInterface as ConfigurationExceptionInterface;
2323
use Symfony\Component\OptionsResolver\OptionsResolver;
2424
use function React\Promise\reject;
25+
use function React\Promise\resolve;
2526

2627
/**
2728
* Sends action requests to the Selenium Grid server (hub) and controls their async execution
@@ -172,9 +173,9 @@ public function setActiveTab(string $sessionIdentifier, string $tabIdentifier):
172173
*/
173174
public function openUri(string $sessionIdentifier, string $uri): PromiseInterface
174175
{
175-
// TODO: Implement openUri() method.
176+
$navigationPromise = $this->hubClient->openUri($sessionIdentifier, $uri);
176177

177-
return reject(new RuntimeException('Not implemented.'));
178+
return $this->timeoutInterceptor->applyTimeout($navigationPromise, 'Unable to complete an open URI command.');
178179
}
179180

180181
/**

src/Timeout/Interceptor.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
use React\EventLoop\LoopInterface;
1919
use React\Promise\PromiseInterface;
20+
use React\Promise\Timer\TimeoutException;
2021
use RuntimeException;
2122
use Throwable;
2223
use function React\Promise\Timer\timeout;
@@ -69,7 +70,14 @@ public function applyTimeout(
6970
$timedPromise = $timedPromise->then(
7071
null,
7172
function (Throwable $rejectionReason) use ($rejectionMessage) {
72-
throw new RuntimeException($rejectionMessage, 0, $rejectionReason);
73+
if (!$rejectionReason instanceof TimeoutException) {
74+
throw $rejectionReason;
75+
}
76+
77+
$promiseTimerExceptionMessage = $rejectionReason->getMessage();
78+
$timeoutRejectionMessage = sprintf('%s %s.', $rejectionMessage, $promiseTimerExceptionMessage);
79+
80+
throw new RuntimeException($timeoutRejectionMessage);
7381
}
7482
);
7583

src/WebDriverFactory.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ function (OptionsResolver $commandOptionsResolver) {
108108
'Maximum time to wait (in seconds) for command execution '
109109
. '(do not correlate with HTTP timeouts)'
110110
)
111-
->allowedTypes('int')
112-
->default(30)
111+
->allowedTypes('float')
112+
->default(30.0)
113113
;
114114
}
115115
)
@@ -121,7 +121,7 @@ function (OptionsResolver $commandOptionsResolver) {
121121
$httpClient = new Browser($loop, $socketConnector);
122122

123123
// Selenium hub sends some valid responses with 5xx status codes, so we need to disable eager promise rejection
124-
// to properly parse error message and other details from the body.
124+
// to properly parse error messages and other details from the body.
125125
$httpClient = $httpClient->withRejectErrorResponse(false);
126126

127127
$hubClient = new W3CClient($httpClient, ['server' => $optionsResolved['hub']]);

0 commit comments

Comments
 (0)