Blur at end of setValue causes StaleElementReference
If fillField - setValue is called with an input that makes the field go away, then the recent code that tries to do a blur out of the field fails with StaleElementReference
e.g. put an ENTER at the end of the field. In ownCloud, when creating a new folder, a dialog pops up and you type the new folder name and press enter. The dialog disappears and the new folder is created. See: https://github.com/owncloud/core/issues/32143
After https://github.com/minkphp/MinkSelenium2Driver/pull/286 the above sequence fails with StaleElementReference because the new code in setValue tries to do a blur on the element after the data has been typed in the field, and the field has gone away.
It is possible to workaround by catching and ignoring the StaleElementReference exception. But it would be nice if the exception was not thrown in the first place.
It is worse. We have text fields where you type in the field and do not press enter. The UI underneath fires off code to find matches of what you have typed (matching user names, group names, file names, whatever). But setValue is removing focus from the field, so the underlying code to display the matches never triggers, and in any case we are unexpectedly taken away from the field.
Doing $shareWithField->focus(); again does not help - it puts us back in the field at the end of the typed text, but then there needs to be another change to the value in the field to trigger the match code. If we type again in the field with setValue then it takes away the focus!!!
I can't think how to work-around that. And I see that this auto-complete regression is discussed in the PR #286
Issue for workarounds in ownCloud: https://github.com/owncloud/core/issues/32143 PR for workarounds in ownCloud: https://github.com/owncloud/core/pull/32144 It might help someone else work around this.
Acknowledgement: bits of code taken from the workaround mentioned in the comment at https://github.com/minkphp/MinkSelenium2Driver/pull/286#issuecomment-406897543 - thanks @pfrenssen
@phil-davis , that shouldn't be a problem if, in #286 discussion, we decide to return to original code prior to #244.
If something can be done so that fillField/setValue ends up leaving focus on the field, then auto-complete has a chance...
No change event is fired in real browser until focus leaves the field. This way no matter how we try we can't both support auto-complete controls and fire change event. Another point made in #286 is that no auto-complete control relies on change event. I guess it's likely that blur event happens on focus loss and that causes auto-complete to close.
@phil-davis Another option I've found on this is using javascript injection. Filling the input element by javascript and then executing a keyDown adding a space. Spaghetti code power (that's horrible)! But it works (almost always).
$this->featureContext->getSession()->executeScript("document.getElementById('id').value = 'value';");
$this->featureContext->getSession()->getDriver()->keyDown("//*[@id=''']", " ");
I found some inputs, specially using google places that there is no way of filling it with the dropdown. That behaviour is explained in 301 but it's basically the same problem.
Alternative solution without JS:
$element = $this->getSession()->getPage()->findField($fieldName);
$this->getSession()
->getDriver()
->getWebDriverSession()
->element('xpath', $element->getXpath())
->postValue(array('value' => array($text)));
This somewhat does the same as the setValue method. Please see that method if you need any changes (like keeping old texts etc).