WebDriver Selenium API: ElementNotFoundErrorException when Element is clearly there ! - webdriver

sometimes when running tests on WebDriver with Javascript turned off, WebDriver crashes due to an ElementNotFound Error when it finds an element, and attempts to click it.
However, the element is clearly there !
After reading this : http://code.google.com/p/selenium/wiki/FrequentlyAskedQuestions#Q:_My_XPath_finds_elements_in_one_browser,_but_not_in_others._Wh
I came to the conclusion that webdriver must not be waiting until the web page has completed loaded. How do I use the Webdriver Wait class ? Can someone provide an example ?

This example was posted on Google Groups. According to Google developers:
1 Use implicit waits. Here the driver will wait up until the designated
timeout until the element is found. Be sure to read the javadoc for the
caveats. Usage:
driver.get("http://www.google.com");
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
WebElement element = driver.findElement(By.name("q"));
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
// continue with test...
2 Use the org.openqa.selenium.support.ui.WebDriverWait class. This will
poll until the expected condition is true, returning that condition's result
(if it's looking for an element). This is much more flexible than implicit
waits, as you can define any custom behavior. Usage:
Function<WebDriver, WebElement> presenceOfElementLocated(final By locator) {
return new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
};
}
// ...
driver.get("http://www.google.com");
WebDriverWait wait = new WebDriverWait(driver, /*seconds=*/3);
WebElement element = wait.until(presenceOfElementLocated(By.name("q"));

Taking nilesh's answer a step further, you can also allow finer-tuned searches (eg, within the context of a WebElement) by using the SearchContext interface:
Function<SearchContext, WebElement> elementLocated(final By by) {
return new Function<SearchContext, WebElement>() {
public WebElement apply(SearchContext context) {
return context.findElement(by);
}
};
}
Execution is performed by a FluentWait<SearchContext> instance (instead of WebDriverWait). Give yourself a nice programming interface by wrapping its execution and necessary exception handling in a utility method (the root of your PageObject type hierarchy is a good spot):
/**
* #return The element if found before timeout, otherwise null
*/
protected WebElement findElement(SearchContext context, By by,
long timeoutSeconds, long sleepMilliseconds) {
#SuppressWarnings("unchecked")
FluentWait<SearchContext> wait = new FluentWait<SearchContext>(context)
.withTimeout(timeoutSeconds, TimeUnit.SECONDS)
.pollingEvery(sleepMilliseconds, TimeUnit.MILLISECONDS)
.ignoring(NotFoundException.class);
WebElement element = null;
try {
element = wait.until(elementLocated(by));
}
catch (TimeoutException te) {
element = null;
}
return element;
}
/**
* overloaded with defaults for convenience
*/
protected WebElement findElement(SearchContext context, By by) {
return findElement(context, by, DEFAULT_TIMEOUT, DEFAULT_POLL_SLEEP);
}
static long DEFAULT_TIMEOUT = 3; // seconds
static long DEFAULT_POLL_SLEEP = 500; // milliseconds
Example usage:
WebElement div = this.findElement(driver, By.id("resultsContainer"));
if (div != null) {
asyncSubmit.click();
WebElement results = this.findElement(div, By.id("results"), 30, 500);
if (results == null) {
// handle timeout
}
}

Fluent Wait - Best approach as it's the most flexible and configurable on the fly (has ignore exceptions option, polling every, timeout):
public Wait<WebDriver> getFluentWait() {
return new FluentWait<>(this.driver)
.withTimeout(driverTimeoutSeconds, TimeUnit.SECONDS)
.pollingEvery(500, TimeUnit.MILLISECONDS)
.ignoring(StaleElementReferenceException.class)
.ignoring(NoSuchElementException.class)
.ignoring(ElementNotVisibleException.class)
}
Use like so:
WebElement webElement = getFluentWait().until(x -> { return driver.findElement(elementBy); } );
Explicit Wait - Well it's the same as FluentWait but with pre-configured pollingEvery and the type of Wait e.g. FluentWait<WebDriver> (faster to use):
WebDriverWait wait = new WebDriverWait(driver, 30000);
WebElement item = wait.until(ExpectedConditions.visibilityOfElementLocated(yourBy));
ImplicitWait - Not recommended as it is configured once for all your session. This also is used for every find element and waits for presence only (no ExpectedConditions etc...):
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

Related

How to use a JavaFX binding to disable a button if TextField has invalid input

I got the following code from The Definitive Guide to Modern Java Clients with JavaFX:
updateButton.disableProperty()
.bind(listView.getSelectionModel().selectedItemProperty().isNull()
.or(wordTextField.textProperty().isEmpty())
.or(definitionTextArea.textProperty().isEmpty()));
I would like to modify it so the button is disabled if the String entered into frequencyTextField is not a nonnegative integer. I added a term to the conjunction as shown:
updateButton.disableProperty()
.bind(listView.getSelectionModel().selectedItemProperty().isNull()
.or(isLegalFrequency(frequencyTextField.textProperty()).not())
.or(wordTextField.textProperty().isEmpty())
.or(definitionTextArea.textProperty().isEmpty()));
Although it is probably not relevant, here is the method that tests validity:
private BooleanProperty isLegalFrequency(StringProperty sp) {
System.out.println("isLegalFrequency(" + sp.get() + ")");
try {
int value = Integer.parseInt(sp.get());
return new SimpleBooleanProperty(value >= 0);
} catch (NumberFormatException e) {
return new SimpleBooleanProperty(false);
}
}
My problem is that the button is always disabled. I have established that isLegalFrequency() is called only once, when the scene is being created. This makes sense, since I am passing frequencyTextField.textProperty(), not calling a method on it (which presumably sets up a listener behind the scenes).
Is there a way to modify the program without adding an explicit listener so it behaves as I'd like, or is it necessary to create a ChangeListener on frequencyTextField.textProperty?
Very generally, you can create an arbitrary method:
private Boolean validate() {
// arbitrary implementation here...
// in your case something like
if (listView.getSelectionModel().getSelectedItem() == null) return false ;
if (wordTextField.getText().isEmpty()) return false ;
if (definitionTextArea.getText().isEmpty()) return false ;
if (! isLegalFrequency(frequencyTextField.getText())) return false ;
return true ;
}
and then do
updateButton.disableProperty().bind(Bindings.createBooleanBinding(
() -> ! validate(),
listView.getSelectionModel().selectedItemProperty(),
frequencyTextField.textProperty(),
wordTextField.textProperty(),
definitionTextArea.textProperty()));
The parameters to the createBooleanBinding() method are a Callable<Boolean> (i.e. a method taking no parameters and returning a Boolean) followed by zero or more instances of javafx.beans.Observable (any property or ObservableList, etc, will work). You should include any property (or other observable) here that should trigger a recalculation of the disableProperty() when it changes.

Unity3d with Firebase: Can't Start Coroutine

Greeting,
I'm currently facing a problem that my coroutine can't start. This is the first time I facing this issues and I can't find a proper solution online. Much appreciated if anyone can point me to the right direction to solve this issue.
Here are the code.
path_reference.GetDownloadUrlAsync().ContinueWith((Task<Uri> task) => {
if (!task.IsFaulted && !task.IsCanceled)
{
Debug.Log("Download URL: " + task.Result);
StartCoroutine(DownloadStuff(task.Result));
}
else
{
Debug.Log(task.Exception.ToString());
}
});
}
IEnumerator DownloadStuff(Uri uri)
{
Debug.Log("Start Download");
using (var www = UnityWebRequestTexture.GetTexture(uri))
{
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
else
{
var texture = DownloadHandlerTexture.GetContent(www);
//Texture2D texture = new Texture2D(1, 1);
//if you need sprite for SpriteRenderer or Image
Sprite sprite = Sprite.Create(texture, new Rect(0.0f, 0.0f, texture.width,
texture.height), new Vector2(0.5f, 0.5f), 100.0f);
Debug.Log("Finished downloading!");
}
Debug.Log(www.downloadProgress);
}
}'
The task returned by Firebase probably finishes execution on a thread other than the main thread, and Unity coroutines can only run on the main thread.
Unity's support of multithreading and async is pretty spotty, including "eating" some errors if the continuations of those errors would execute on another thread other than the main thread.
To fix this, you need to change the function that starts your coroutine:
try {
// Important: ConfigureAwait(true) ensures the code after this will run in the
// same thread as the code before (which is the main thread!)
var url = await path_reference.GetDownloadUrlAsync().ConfigureAwait(true);
StartCoroutine(DownloadStuff(url));
} catch (Exception ex) {
// Tip: when logging errors, use LogException and pass the whole exception,
// that way you will get pretty links to the error line in the whole stack trace.
Debug.LogException(ex);
}
As an aside, I usually have a few extension methods on all my projects to deal with that while staying in async-world instead of coroutine-world (because at least with async I can catch errors and not just "halt and catch fire" like Unity's coroutines)
The main ones are:
public static Task ToTask(this YieldInstruction self, MonoBehaviour owner) {
var source = new TaskCompletionSource<object>();
IEnumerable Routine() {
yield return self;
source.SetResult(null);
}
return source.Task;
}
private static Task SendAsync(this UnityWebRequest self, MonoBehaviour owner) {
var source = new TaskCompletionSource<object>();
await self.SendWebRequest().ToTask(owner);
if (
self.isHttpError
|| self.isNetworkError
) {
source.SetException(new Exception(request.error));
yield break;
}
source.SetResult(null);
}
Which you can use like this, inside a MonoBehaviour:
await new WaitForSeconds(0.2f).ToTask(this);
UnityWebRequest request = /* etc */;
await request.SendAsync(this);
var texture = DownloadHandlerTexture.GetContent(request);
Note that these methods do not require ConfigureAwait, since their SetResult/SetException invocations are ran from Unity-provided coroutine continuations.

org.openqa.selenium.ElementNotVisibleException: element not visible/Tried with ID as well as other combinations of CSS selector

boolean display=driver.findElement(By.cssSelector("input#txtkeyword[placeholder='Job title']")).isDisplayed();=false
boolean select=driver.findElement(By.cssSelector("input#txtkeyword[placeholder='Job title']")).isSelected();=false
boolean enable=driver.findElement(By.cssSelector("input#txtkeyword[placeholder='Job title']")).isEnabled();=true
There are many reasons for an element to not be visible. It could be covered by a pop-up, the DOM could still be loading, you may have to scroll it into view.
For the first instance, take a screenshot on failure and see if the element is covered. I use the following for cucumber-jvm. You can google how to do it for whatever framework you are using.
#After
public void captureScreenshotOnFailure(Scenario scenario){
try {
if (scenario.isFailed() && driver !=null) {
System.out.println("***>> Scenario failed: "+scenario.getStatus());
try {
driver augemented = new Augmenter().augment(webDriver);
byte[] screenshot = ((TakesScreenshot) augemented).getScreenshotAs(OutputType.BYTES);
scenario.embed(screenshot, "image/png");
} catch (Exception e) {
e.printStackTrace();
}
}
} finally {
if (driver !=null) {
driver.quit();
}
}
}
For the DOM not finished loading, wait for it.
Wait<driver> wait_element = new WebDriverWait(driver, 80);
WebElement jobTitleElement = wait_element.until(
ExpectedConditions.visibilityOfElementLocated(By.cssSelector(
"input#txtkeyword[placeholder='Job title']")));
If the wait fails then the element just isn't there.
If the wait succeeds then scroll to the element. If the element was a button you could click() it after the moveToElement(). It is not but including the code just to be complete.
Actions action = new Actions(driver);
action.moveToElement(jobTitleElement).click().build().perform();

CodenameOne filter optimization on set of containers

In my app, I have a searchbox which allows users to filter as they type. For some reason I can't get an InfinteProgress to properly display while the filtering is being executed.
Here's my code:
Pass 1
public void renderForumList(){
try{
magnify = mStateMachine.findForumSearchIcon(form);
}catch(NullPointerException ex){
System.out.println("User typed additional character in search term before previous term finished executing");
}
InfiniteProgress infi = new InfiniteProgress();
magnify.getParent().replace(magnify, infi, null);
Display.getInstance().invokeAndBlock(new Runnable() {
#Override
public void run() {
for (int i = 0;i < containerStates.length;i++){
if(containerStates[i] != listItems[i].isVisible()){
listItems[i].setHidden(!containerStates[i]);
listItems[i].setVisible(containerStates[i]);
}
}
Display.getInstance().callSerially(new Runnable() {
#Override
public void run() {
mStateMachine.findForumsListComponent(form).animateLayout(200);
mStateMachine.findContainer2(form).replace(infi, magnify, null);
}
});
}
});
}
In this version, the infinite progress shows up in the proper position, but it doesn't spin.
Pass 2
public void renderForumList(){
try{
magnify = mStateMachine.findForumSearchIcon(form);
}catch(NullPointerException ex){
System.out.println("User typed additional character in search term before previous term finished executing");
}
InfiniteProgress infi = new InfiniteProgress();
magnify.getParent().replace(magnify, infi, null);
for (int i = 0;i < containerStates.length;i++){
if(containerStates[i] != listItems[i].isVisible()){
listItems[i].setHidden(!containerStates[i]);
listItems[i].setVisible(containerStates[i]);
}
}
mStateMachine.findForumsListComponent(form).animateLayout(200);
mStateMachine.findContainer2(form).replace(infi, magnify, null);
}
}
}
In this version, the magnifier icon just flashes briefly, but the InfiniteProgress spinner is never visible.
I get the same results on the simulator and on an Android device.
How can I get the InfiniteProgress to spin while the search is taking place?
invokeAndBlock opens a new thread and thus violates the EDT as you access UI components on a separate thread.
Try using callSerially instead to postpone the following code into the next EDT cycle although I'm not sure that will help as everything is still happening on the EDT.
Alternatively I'm guessing the method isVisible takes time, so you can enclose that call alone in invokeAndBlock.
To understand invokeAndBlock check out the developer guide https://www.codenameone.com/manual/edt.html

Enable no timeout for one specific page

I have a page that doing something, it can take 1,2 hours or even more...
After a while I get request timed out, I want that this specific page will NOT get request timed out - ever(or at least 24 hours).
How do I do it?
Thanks.
You can make a thread with a signal in it to know it its still running or not.
I suggest to use a mutex signal because is the only one that can be the same across many pools and threads.
The thread code can be:
public class RunThreadProcess
{
// Some parametres
public int cProductID;
// my thread
private Thread t = null;
// start it
public Thread Start()
{
t = new Thread(new ThreadStart(this.work));
t.IsBackground = true;
t.SetApartmentState(ApartmentState.MTA);
t.Start();
return t;
}
// actually work
private void work()
{
// while the mutex is locked, the thread is still working
Mutex mut = new Mutex("WorkA");
try
{
mut.WaitOne();
// do thread work
all parametres are available here
}
finally
{
mut.ReleaseMutex();
}
}
}
And you call it as
Mutex mut = new Mutex("WorkA");
try
{
if(mut.WaitOne(1000))
{
// release it here to start it from the thread as signal
mut.ReleaseMutex();
// you start the thread
var OneAction = new RunThreadProcess();
OneAction.cProductID = 100;
OneAction.Start();
}
else
{
// still running
}
}
finally
{
mut.ReleaseMutex();
}

Resources