Skip to content

Commit e0dbda0

Browse files
committed
Handle the case where a proxied element from PageFactory causes a FluentWait to timeout.
It's common for an ExpectedCondition to include a message containing the output of "element.toString" in the friendly error message. In the case of a proxied element created by the PageFactory, this will cause a NoSuchElementException to be thrown, whereas we expect some string or another to be returned. Handle this case.
1 parent 4437901 commit e0dbda0

File tree

3 files changed

+36
-3
lines changed

3 files changed

+36
-3
lines changed

java/client/src/org/openqa/selenium/support/pagefactory/internal/LocatingElementHandler.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.openqa.selenium.support.pagefactory.internal;
1818

19+
import org.openqa.selenium.NoSuchElementException;
1920
import org.openqa.selenium.WebElement;
2021
import org.openqa.selenium.support.pagefactory.ElementLocator;
2122

@@ -31,7 +32,15 @@ public LocatingElementHandler(ElementLocator locator) {
3132
}
3233

3334
public Object invoke(Object object, Method method, Object[] objects) throws Throwable {
34-
WebElement element = locator.findElement();
35+
WebElement element;
36+
try {
37+
element = locator.findElement();
38+
} catch (NoSuchElementException e) {
39+
if ("toString".equals(method.getName())) {
40+
return "Proxy element for: " + locator.toString();
41+
}
42+
else throw e;
43+
}
3544

3645
if ("getWrappedElement".equals(method.getName())) {
3746
return element;

java/client/src/org/openqa/selenium/support/ui/WebDriverWait.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public WebDriverWait(WebDriver driver, long timeOutInSeconds, long sleepInMillis
6565
* @param timeOutInSeconds The timeout in seconds when an expectation is
6666
* @param sleepTimeOut The timeout used whilst sleeping. Defaults to 500ms called.
6767
*/
68-
protected WebDriverWait(WebDriver driver, Clock clock, Sleeper sleeper, long timeOutInSeconds,
68+
public WebDriverWait(WebDriver driver, Clock clock, Sleeper sleeper, long timeOutInSeconds,
6969
long sleepTimeOut) {
7070
super(driver, clock, sleeper);
7171
withTimeout(timeOutInSeconds, TimeUnit.SECONDS);

java/client/test/org/openqa/selenium/support/PageFactoryTest.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,27 @@
2323
import static org.junit.Assert.assertThat;
2424
import static org.junit.Assert.fail;
2525
import static org.mockito.Mockito.mock;
26+
import static org.mockito.Mockito.when;
2627

2728
import org.junit.Test;
29+
import org.mockito.Mockito;
30+
import org.openqa.selenium.By;
31+
import org.openqa.selenium.NoSuchElementException;
32+
import org.openqa.selenium.TimeoutException;
2833
import org.openqa.selenium.WebDriver;
2934
import org.openqa.selenium.WebElement;
3035
import org.openqa.selenium.support.pagefactory.FieldDecorator;
36+
import org.openqa.selenium.support.ui.ExpectedConditions;
37+
import org.openqa.selenium.support.ui.TickingClock;
38+
import org.openqa.selenium.support.ui.Wait;
39+
import org.openqa.selenium.support.ui.WebDriverWait;
3140

3241
import java.lang.reflect.Field;
3342
import java.util.List;
3443

3544
public class PageFactoryTest {
3645

37-
private WebDriver driver = null;
46+
private WebDriver driver;
3847

3948
@Test
4049
public void shouldProxyElementsInAnInstantiatedPage() {
@@ -175,6 +184,21 @@ public void shouldComplainWhenMoreThanOneFindByShortFormAttributeIsSet() {
175184
}
176185
}
177186

187+
@Test(expected = TimeoutException.class)
188+
public void shouldNotThrowANoSuchElementExceptionWhenUsedWithAFluentWait() {
189+
driver = mock(WebDriver.class);
190+
when(driver.findElement(Mockito.<By>any())).thenThrow(new NoSuchElementException("because"));
191+
192+
TickingClock clock = new TickingClock(10);
193+
Wait<WebDriver> wait = new WebDriverWait(driver, clock, clock, 1, 1001);
194+
195+
PublicPage page = new PublicPage();
196+
PageFactory.initElements(driver, page);
197+
WebElement element = page.q;
198+
199+
wait.until(ExpectedConditions.visibilityOf(element));
200+
}
201+
178202
public static class PublicPage {
179203

180204
@FindBy(name = "q")

0 commit comments

Comments
 (0)