br.ufmg.dcc.saotome.beholder.selenium.WebDriverAdapter.java Source code

Java tutorial

Introduction

Here is the source code for br.ufmg.dcc.saotome.beholder.selenium.WebDriverAdapter.java

Source

/*  Copyright 2014 ?caro Clever da Fonseca Braga
    
   Licensed to the Apache Software Foundation (ASF) under one
   or more contributor license agreements.  See the NOTICE file
   distributed with this work for additional information
   regarding copyright ownership.  The ASF licenses this file
   to you under the Apache License, Version 2.0 (the
   "License"); you may not use this file except in compliance
   with the License.  You may obtain a copy of the License at
       
 http://www.apache.org/licenses/LICENSE-2.0
       
   Unless required by applicable law or agreed to in writing,
   software distributed under the License is distributed on an
   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   KIND, either express or implied.  See the License for the
   specific language governing permissions and limitations
   under the License.
 */
package br.ufmg.dcc.saotome.beholder.selenium;

import java.util.List;
import java.util.Set;

import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.internal.Killable;
import org.openqa.selenium.remote.RemoteWebDriver;

import br.ufmg.dcc.saotome.beholder.selenium.message.ErrorMessages;

/** 
 * The class WebDriverAdapter was created to solve the DOM reference lost in Selenium when 
 * an Ajax call reload an object in HTML page. Webdriver sends a StaleElementReferenceException
 * when it idenfifies a WebElement manipulating a DOM object that doesn't exit anymore and gives
 * the responsability of identify this problem to tester. So, to solve this problem, this class
 * implements the WebDriver interface and encapsule the WebDriver object returned by WebDriver, 
 * trying to request a new web element when the StaleElementReferenceException occurs.
 * 
 * @author ?caro Clever F. Braga (icaroclever@gmail.com)
 * @see StaleElementReferenceException
 */
class WebDriverAdapter extends RemoteWebDriver implements TakesScreenshot, Killable, WebDriver {

    /** Webdriver original instance */
    private WebDriver driver;

    /** Constructor that encapsule the original WebDriver.
     * @param driver
     */
    public WebDriverAdapter(WebDriver driver) {

        // Driver cannot be null
        if (driver == null) {
            throw new IllegalArgumentException(String.format(ErrorMessages.ERROR_TEMPLATE_VARIABLE_NULL, "driver"));
        }

        // The driver must be a original drive, if it's not, the class get the original WebDriver
        if (driver instanceof WebDriverAdapter) {
            this.driver = ((WebDriverAdapter) driver).getWebDriver();
        } else {
            this.driver = driver;
        }
    }

    @Override
    public void get(String url) {
        this.driver.get(url);
    }

    @Override
    public String getCurrentUrl() {
        return this.driver.getCurrentUrl();
    }

    @Override
    public String getTitle() {
        return this.driver.getTitle();
    }

    @Override
    public List<WebElement> findElements(final By by) {

        // It's instanced a html element to reuse the findElements of WebElementAdapter      
        WebElement html = this.driver.findElement(By.tagName("html"));
        WebElement htmlAdapter = new WebElementAdapter(html, null, By.tagName("html"));

        return htmlAdapter.findElements(by);
    }

    @Override
    public WebElement findElement(final By by) {

        final String tag = "html";

        // It's instanced a html element to reuse the findElement of WebElementAdapter
        WebElement html = this.driver.findElement(By.tagName(tag));
        WebElement htmlAdapter = new WebElementAdapter(html, null, By.tagName(tag));

        return htmlAdapter.findElement(by);
    }

    @Override
    public String getPageSource() {
        return this.driver.getPageSource();
    }

    @Override
    public void close() {
        this.driver.close();
    }

    @Override
    public void quit() {
        this.driver.quit();
    }

    @Override
    public Set<String> getWindowHandles() {
        return this.driver.getWindowHandles();
    }

    @Override
    public String getWindowHandle() {
        return this.driver.getWindowHandle();
    }

    @Override
    public TargetLocator switchTo() {
        return new TargetLocatorAdapter(this.driver.switchTo());
    }

    @Override
    public Navigation navigate() {
        return this.driver.navigate();
    }

    @Override
    public Options manage() {
        return this.driver.manage();
    }

    /**
     * Returns the WebDriver that it's been used by the adapter.
     * @return
     *       Return the WebDriver 
     */
    public final WebDriver getWebDriver() {
        return this.driver;
    }

    @Override
    public void kill() {
        ((Killable) driver).kill();
    }

    @Override
    public <X> X getScreenshotAs(OutputType<X> target) {
        return ((TakesScreenshot) driver).<X>getScreenshotAs(target);
    }

    private static class TargetLocatorAdapter implements TargetLocator {

        private TargetLocator targetLocator;

        public TargetLocatorAdapter(TargetLocator targetLocator) {
            this.targetLocator = targetLocator;
        }

        @Override
        public WebDriver frame(int index) {
            return this.targetLocator.frame(index);
        }

        @Override
        public WebDriver frame(String nameOrId) {
            return this.targetLocator.frame(nameOrId);
        }

        @Override
        public WebDriver frame(WebElement frameElement) {
            WebElement element;
            if (frameElement instanceof WebElementAdapter) {
                element = ((WebElementAdapter) frameElement).getElement();
            } else {
                element = frameElement;
            }
            return this.targetLocator.frame(element);
        }

        @Override
        public WebDriver window(String nameOrHandle) {
            return this.targetLocator.window(nameOrHandle);
        }

        @Override
        public WebDriver defaultContent() {
            return this.targetLocator.defaultContent();
        }

        @Override
        public WebElement activeElement() {
            return this.targetLocator.activeElement();
        }

        @Override
        public Alert alert() {
            return this.targetLocator.alert();
        }

        @Override
        public WebDriver parentFrame() {
            return this.targetLocator.parentFrame();
        }

    }
}