Add automatic handling of "ElementNotInteractable" exceptions
In the WebDriver protocol, when a command fails because it can not interact with the target element, an "element not interactable" error is generated. It can be a transitive issue (for example, due to an animation), so when the error is received the command should be tried again, just like done, for example, with "ElementNotVisible" exceptions. However, the last version of the "instaclick/php-webdriver" library compatible with the Selenium Driver of Mink did not support yet that WebDriver error. And even if Chrome is run using the old protocol an unknown "element not interactable" error can be received anyway in some cases. When an unknown error is received by the "instaclick/php-webdriver" library it is thrown as a generic Exception so, until the library can be updated, the message of generic exceptions is checked and the command is retried if it matched. For the time being "element not interactable" errors are handled like "ElementNotVisible" exceptions; this may need to change once the error is better understood. Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
This commit is contained in:
parent
9e1246eba5
commit
4b376a107b
|
@ -66,6 +66,11 @@
|
|||
* exception instead of an ElementNotVisible exception, so those cases are
|
||||
* handled like ElementNotVisible exceptions.
|
||||
*
|
||||
* ElementNotInteractable exceptions are thrown in Selenium 3 when the command
|
||||
* needs to interact with an element but that is not possible. This could be a
|
||||
* transitive situation (for example, due to an animation), so the command is
|
||||
* executed again after a small timeout.
|
||||
*
|
||||
* Despite the automatic handling it is possible for the commands to throw those
|
||||
* exceptions when they are executed again; this class does not handle cases
|
||||
* like an element becoming stale several times in a row (uncommon) or an
|
||||
|
@ -73,7 +78,10 @@
|
|||
* that the timeout is too short or that the test has to, indeed, fail). In a
|
||||
* similar way, MoveTargetOutOfBounds exceptions would be thrown again if
|
||||
* originally they were thrown because the element was visible but "out of
|
||||
* reach".
|
||||
* reach". ElementNotInteractable exceptions would be thrown again if it is not
|
||||
* possible to interact yet with the element after the wait (which could mean
|
||||
* that the test has to, indeed, fail, although it could mean too that the
|
||||
* automatic handling needs to be improved).
|
||||
*
|
||||
* If needed, automatically handling failed commands can be disabled calling
|
||||
* "doNotHandleFailedCommands()"; as it returns the ElementWrapper it can be
|
||||
|
@ -279,6 +287,13 @@ class ElementWrapper {
|
|||
* If an ElementNotVisible or a MoveTargetOutOfBounds exception is thrown it
|
||||
* is waited for the wrapped element to be visible and, then, the command is
|
||||
* executed again.
|
||||
* If an ElementNotInteractable exception is thrown it is also waited for
|
||||
* the wrapped element to be visible. It is very likely that the element was
|
||||
* visible already, but it is not possible to easily check if the element
|
||||
* can be interacted with, retrying will be only useful if it was a
|
||||
* transitive situation that resolves itself with a wait (for example, due
|
||||
* to an animation) and waiting for the element to be visible will always
|
||||
* start with a wait.
|
||||
*
|
||||
* @param \Closure $commandCallback the command to execute.
|
||||
* @param string $errorMessage an error message that describes the failed
|
||||
|
@ -295,6 +310,14 @@ class ElementWrapper {
|
|||
$this->printFailedCommandMessage($exception, $errorMessage);
|
||||
} catch (\WebDriver\Exception\MoveTargetOutOfBounds $exception) {
|
||||
$this->printFailedCommandMessage($exception, $errorMessage);
|
||||
} catch (\Exception $exception) {
|
||||
// The "ElementNotInteractable" exception is not available yet in
|
||||
// the current "instaclick/php-webdriver" version, so it is thrown
|
||||
// as a generic exception with a specific message.
|
||||
if (stripos($exception->getMessage(), "element not interactable") === false) {
|
||||
throw $exception;
|
||||
}
|
||||
$this->printFailedCommandMessage($exception, $errorMessage);
|
||||
}
|
||||
|
||||
$this->waitForElementToBeVisible();
|
||||
|
|
Loading…
Reference in New Issue