I use selendroid in order to test an hybrid application. I have my own logger which logs and also use WebDriverWait to wait for specific behavior. My question is how can I use my logger before WebDriverWait is failed and throws timeoutException?
2 Answers
First, I know nothing about selendroid.
A simple solution could be:
public void waitForCondition(WebElement element){
try{
new WebDriverWait(driver, 60)
.until(ExpectedConditions.visibilityOf(element)); // your condition
} catch (TimeoutException e){
// do log or whatever
}
}
Anyway, You usually do this by implementing WebDriverEventListener and register this with EventFiringWebDriver, then invoke it something like:
EventFiringWebDriver eventFiringWebDriver = new EventFiringWebDriver(new FirefoxDriver());
MyWebDriverEventListener listener = new MyWebDriverEventListener();
eventFiringWebDriver.register(listener);
where MyWebDriverEventListener
is something like
class MyWebDriverEventListener implements WebDriverEventListener {
// .. skipped
}
So, basically what WebDriverWait
's until
method is doing, is that it is executing the driver.findElement
until:
Repeatedly applies this instance's input value to the given function until one of the following occurs:
- the function returns neither null nor false,
- the function throws an unignored exception,
- the timeout expires,
- the current thread is interrupted
So what you could do, is implement your logging in WebDriverEventListener
public void afterFindBy(By by, WebElement element, WebDriver driver) {
// Do logging
}
This would be applyed every time element is found (not only wait, but regular driver.findElement also). Anyway, this does not cover the case when exception is thrown. You also have a chance to log in onException
method, using something like
if (throwable instanceof TimeoutException){
// log
}
I would not do it but it's your code.
That being said, I usually don't do this because I do not care about such verbose log level, I just have 2 helper methods that can take care of all the waits I ever need:
public void waitUntil(WebElement element) {
new WebDriverWait(driver, 60)
.ignoring(NoSuchElementException.class)
.ignoring(StaleElementReferenceException.class)
.until(ExpectedConditions.visibilityOf(element));
}
public void waitUntil(List<WebElement> elements) {
new WebDriverWait(driver, 60)
.ignoring(NoSuchElementException.class)
.ignoring(StaleElementReferenceException.class)
.until(ExpectedConditions.visibilityOfAllElements(elements));
}
It would be trivial to add logging there.
Edit: i have following solution working:
public class Demo {
@Test
public void testEventFire(){
EventFiringWebDriver firingWebDriver = new EventFiringWebDriver(new FirefoxDriver());
firingWebDriver.register(new MyListener());
try {
firingWebDriver.navigate().to(new URL("http://www.google.com"));
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
private static class MyListener extends AbstractWebDriverEventListener {
@Override
public void beforeNavigateTo(String url, WebDriver driver) {
System.out.println("beforeNavigateTo");
}
}

- 5,022
- 1
- 48
- 74
-
I tried the solution using EventFiringWebDriver using the following code: driver = new SelendroidDriver(caps); EventFiringWebDriver eventFiringWebDriver = new EventFiringWebDriver(driver); eventFiringWebDriver.register(new MyWebDriverEventListener()); where MyWebDriverEventListener is listener as in your answer. Actually I don't see any logs, do you know what can be the problem? – galvan Aug 17 '14 at 08:38
-
Actually not. I put System.out.println in every callback and it looks like the code don't reach any of them – galvan Aug 17 '14 at 15:05
-
check my edit. If it is not working, it might be an issue with selendroid. – Erki M. Aug 18 '14 at 06:22
There is a Message property of WebDriverWait which you may set your failure message.
It is a good idea to wrap a Wait function in a static class like this (you may avoid creating the WebDriverWait object all the time) and set the Message:
private static IWebDriver activeDriver;
private static WebDriverWait activeWait;
public static WebDriverWait Wait(this IWebDriver driver, string message = "Test has timed out while finding a UI element")
{
if (driver != activeDriver)
{
activeDriver = driver;
try
{
activeWait = new WebDriverWait(driver, timeout);
}
catch (Exception)
{
throw Exception(message);
}
}
activeWait.Message = message;
return activeWait;
}
To call the Wait wrapper above (since it is written as an extension method):
YourDriverObject.Wait("Your failure message").Until(ExpectedConditions);
If you want the simplest form (without wrapping etc.):
var webDriverWait = new WebDriverWait(driver, timeout);
webDriverWait.Message = "Your message when exception is thrown";

- 60
- 1
- 7