Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blur at end of setValue causes StaleElementReference #292

Open
phil-davis opened this issue Jul 24, 2018 · 7 comments
Open

Blur at end of setValue causes StaleElementReference #292

phil-davis opened this issue Jul 24, 2018 · 7 comments

Comments

@phil-davis
Copy link

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:
owncloud/core#32143

After #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.

@phil-davis
Copy link
Author

phil-davis commented Jul 24, 2018

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

@phil-davis
Copy link
Author

phil-davis commented Jul 24, 2018

Issue for workarounds in ownCloud: owncloud/core#32143
PR for workarounds in ownCloud: owncloud/core#32144
It might help someone else work around this.

Acknowledgement: bits of code taken from the workaround mentioned in the comment at #286 (comment) - thanks @pfrenssen

@aik099
Copy link
Member

aik099 commented Jul 24, 2018

@phil-davis , that shouldn't be a problem if, in #286 discussion, we decide to return to original code prior to #244.

@phil-davis
Copy link
Author

If something can be done so that fillField/setValue ends up leaving focus on the field, then auto-complete has a chance...

@aik099
Copy link
Member

aik099 commented Jul 24, 2018

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.

@JordiGiros
Copy link

JordiGiros commented Oct 17, 2018

@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.

@robindrost
Copy link

robindrost commented May 16, 2019

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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants