br.ufmg.dcc.saotome.beholder.selenium.ui.form.SeleniumSelectField.java Source code

Java tutorial

Introduction

Here is the source code for br.ufmg.dcc.saotome.beholder.selenium.ui.form.SeleniumSelectField.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.ui.form;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;

import br.ufmg.dcc.saotome.beholder.selenium.ui.SeleniumComponent;
import br.ufmg.dcc.saotome.beholder.ui.form.Select;

/**
 * This abstract class implements the interface Select using the
 * Selenium-Webdriver to simulate the interaction between the component and a
 * system user.
 * 
 * @author ?caro Clever F. Braga (icaroclever@gmail.com)
 * @see SeleniumComponent
 * @see br.ufmg.dcc.saotome.beholder.ui.form.Select
 * 
 */
public class SeleniumSelectField extends SeleniumComponent implements Select {

    public SeleniumSelectField(WebDriver driver) {
        super(driver);
    }

    /** List of Options loaded by select */
    private List<Option> options = new ArrayList<Option>();

    /** This class extends Option, inserting the concept of WebElement to be
     * worked inside of SeleniumSelectField class*/
    private static class SeleniumOption extends Option {
        /** Option WebElement */
        private WebElement webElement;
    }

    private enum Type {
        VALUE, INDEX, TEXT
    };

    @Override
    public final List<Option> getOptions() {

        SeleniumOption option;
        reloadElement();
        List<WebElement> webElements = getElement().findElements(By.tagName("option"));
        for (WebElement element : webElements) {
            option = new SeleniumOption();
            option.setIndex(Integer.valueOf(element.getAttribute("index")));
            option.setValue(element.getAttribute("value"));
            option.setText(element.getText());
            option.webElement = element;
            options.add(option);
        }
        return this.options;
    }

    /**
     * {@inheritDoc} If the option text passed contains "submit::" in the string,
     * the submit value is searched, not the text inside of the option.
     */
    @Override
    public final void select(final String optionText) {
        if (optionText.contains("submit::")) {
            String value = optionText.split("::")[1];
            select(Type.VALUE, value);
        } else {
            select(Type.TEXT, optionText);
        }
    }

    @Override
    public final void select(final int optionIndex) {
        select(Type.INDEX, optionIndex);
    }

    /**
     * this private method try to search the value of the select for n seconds
     * specified by TIMEOUT static variable. The coerence if the data passed is
     * or isn't the correct value is responsability of the test developer.
     * 
     * @param type
     *            values defined by the Type private enumeration
     * @param value
     *            value to be selected
     */

    private void select(Type type, Object value) {

        assert value != null;

        reloadElement();
        this.selectByType(type, value);
    }

    private void selectByType(final Type type, final Object value) {

        final Option option = new SeleniumOption();
        switch (type) {
        case INDEX:
            option.setIndex((Integer) value);
            break;
        case VALUE:
            option.setValue((String) value);
            break;
        case TEXT:
            option.setText((String) value);
            break;
        }

        WebDriverWait wait = new WebDriverWait(getSeleniumWebDriver(), SeleniumComponent.TIMEOUT);
        ExpectedCondition<Option> resultsAreDisplayed = new ExpectedCondition<Option>() {

            public Option apply(WebDriver driver) {
                Iterator<Option> iterator = getOptions().iterator();

                while (iterator.hasNext()) {
                    Option opt = iterator.next();
                    if (isSame(option, opt)) {
                        ((SeleniumOption) opt).webElement.click();
                        return opt;
                    }
                }
                return null;
            }
        };
        wait.until(resultsAreDisplayed);
    }

    /** This method makes easy to compare between two option components. There are 2 rules
     * implemented:<br/>
     * - only class attributes not null in both classes are evaluated;<br/>
     * - all evaluable attributes must be equals.
     * @return Returns true only if the 2 rules above are true. Otherwise the return is false.
     */
    private boolean isSame(Option option1, Option option2) {

        if (option1 == null || option2 == null) {
            return false;
        }
        if (option1.equals(option2)) {
            return true;
        }

        String index1 = (option1.getIndex() == null) ? null : Integer.toString(option1.getIndex()),
                index2 = (option2.getIndex() == null) ? null : Integer.toString(option2.getIndex());

        boolean isValidIndex = validField(index1, index2);
        boolean isValidValue = validField(option1.getValue(), option2.getValue());
        boolean isValidText = validField(option1.getText(), option2.getText());

        return isValidIndex && isValidValue && isValidText;
    }

    private boolean validField(String valueA, String valueB) {

        boolean isANull, isBNull;

        isANull = (valueA == null);
        isBNull = (valueB == null);

        if (isANull && isBNull) {
            return false;
        }

        if (!isANull && !isBNull) {
            return valueA.equalsIgnoreCase(valueB);
        }

        return true;
    }

    @Override
    public final boolean isValidElementTag() {
        return "select".equalsIgnoreCase(getElement().getTagName());
    }

    @Override
    public String getBasicLocator() {
        return "select";
    }

    @Override
    public void click() {
        getElement().click();
    }
}