Skip to content
September 6, 2012 / selenium34

Better Optional Elements

In yesterday’s post we discussed ways to allow Selenium to better handle items which may or may not have been on the page. We ended the post with something that might be considered a bit of a nuisance when attempting to utilize one of these non-located elements. Let’s take a look at the two tests we ended the post with:

public void ensureNullValue() {
  Assert.assertNull("A null value is expected for optional elements which do not exist on the page.", homePage.getOptionalIntroDivWithDefault());
@Test(expected = NoSuchElementException.class)
public void ensureNoSuchElementExceptionThrown() {

Unfortunately the way proxies work in Java our proposed solution yesterday will not allow both of these two tests to pass. So, how can we ensure that the item is not located and retain the information from the NoSuchElementException?

Well, the easiest way is to create our own implementation of a WebElement. Here’s a portion of the class below:

public class MissingWebElement implements WebElement {
  private final NoSuchElementException nsee;
  public MissingWebElement(final NoSuchElementException nsee) {
    this.nsee = nsee;
  public void click() {
    throw nsee;
  //Throw the NoSuchElementException for all methods the interface requires us to implement

It’s okay, you can admit it; you thought we were going to name that class CustomWebElement didn’t you?

Now we need to modify the CustomFieldDecorator to return a MissingWebElement when we have an optional item that was not located. We need to simply replace our decorate method from yesterday’s post, to what is shown below:

public Object decorate(final ClassLoader loader, final Field field) {
  if (!(WebElement.class.isAssignableFrom(field.getType()) || isDecoratableList(field))) {
    return null;
  final CustomElementLocator locator = (CustomElementLocator) factory.createLocator(field);
  if (locator == null) {
    return null;
  if (WebElement.class.isAssignableFrom(field.getType())) {
    final WebElement proxy = proxyForLocator(loader, locator);
    try {
      return proxy;
    } catch (final NoSuchElementException nsee) {
      if (!locator.isOptionalElement()) {
        throw nsee;
      return new MissingWebElement(nsee);
  } else if (List.class.isAssignableFrom(field.getType())) {
    return proxyForListLocator(loader, locator);
  } else {
   return null;

We now instruct our test to expect to receive a MissingWebElement:

public void ensureMissingElement() {
  Assert.assertTrue("A MissingWebElement is expected for optional elements which do not exist on the page.", homePage.getOptionalIntroDivWithDefault() instanceof MissingWebElement);

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: