org.suren.autotest.web.framework.selenium.action.SeleniumClick.java Source code

Java tutorial

Introduction

Here is the source code for org.suren.autotest.web.framework.selenium.action.SeleniumClick.java

Source

/*
 * Copyright 2002-2007 the original author or authors.
 *
 * Licensed 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 org.suren.autotest.web.framework.selenium.action;

import java.awt.AWTException;
import java.awt.Robot;
import java.util.Iterator;
import java.util.Set;

import org.openqa.selenium.Dimension;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Point;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.suren.autotest.web.framework.core.ElementSearchStrategy;
import org.suren.autotest.web.framework.core.action.ClickAble;
import org.suren.autotest.web.framework.core.ui.AbstractElement;
import org.suren.autotest.web.framework.core.ui.Element;
import org.suren.autotest.web.framework.core.ui.FileUpload;
import org.suren.autotest.web.framework.selenium.SeleniumEngine;
import org.suren.autotest.web.framework.selenium.strategy.SearchStrategyUtils;

/**
 * Selenium???
 * 
 * @author suren
 * @since jdk1.6 2016629
 */
@Component
public class SeleniumClick implements ClickAble {
    private static final Logger logger = LoggerFactory.getLogger(SeleniumClick.class);

    /** ?? */
    private int maxRetry = 3;

    private static final String ERR_TIMES = "CLICK_ERR_TIMES";

    @Autowired
    private SeleniumEngine engine;
    @Autowired
    private SearchStrategyUtils searchStrategyUtils;

    @Override
    public void click(Element ele) {
        int errorTimes = 0;

        if (ele instanceof AbstractElement) {
            Object errObj = ((AbstractElement) ele).getData(ERR_TIMES);
            if (errObj instanceof Integer) {
                errorTimes = (Integer) errObj;
                if (errorTimes >= maxRetry) {
                    return;
                }
            }
        }

        if (errorTimes > 0) {
            logger.warn(String.format("Click operation retry times [%s].", errorTimes));
        }

        ElementSearchStrategy<WebElement> searchStrategy = searchStrategyUtils.findStrategy(WebElement.class, ele);
        WebElement webEle = searchStrategy.search(ele);
        if (webEle == null) {
            throw new RuntimeException(
                    String.format("Element [%s] can not found " + "by strategy [%s]!", ele, searchStrategy));
        }

        try {
            //??
            if (!(ele instanceof FileUpload) && !(engine.getDriver() instanceof RemoteWebDriver)) {
                Dimension size = webEle.getSize();
                Point loc = webEle.getLocation();
                int toolbarHeight = engine.getToolbarHeight();
                int x = size.getWidth() / 2 + loc.getX();
                int y = size.getHeight() / 2 + loc.getY() + toolbarHeight;

                new Robot().mouseMove(x, y);
            }

            webEle.click();

            //a??target????window?
            String tagName = webEle.getTagName();
            String targetAttr = webEle.getAttribute("target");
            if ("a".equals(tagName) && "_blank".equals(targetAttr)) {
                WebDriver driver = engine.getDriver();
                Set<String> handlers = driver.getWindowHandles();
                Iterator<String> it = handlers.iterator();
                while (it.hasNext()) {
                    String name = it.next();

                    driver.switchTo().window(name);
                }
            }
        } catch (WebDriverException e) {
            logger.error(String.format("[%s]??", webEle), e);
            if (ele instanceof AbstractElement) {
                ((AbstractElement) ele).putData(ERR_TIMES, ++errorTimes);
            }

            //?????
            if (e.getMessage().contains("is not clickable at point")) {
                logger.info("Will retry click operation, after element move.");

                new Actions(engine.getDriver()).moveToElement(webEle, -50, -50).perform();

                WebDriverWait wait = new WebDriverWait(engine.getDriver(), 30);
                ((JavascriptExecutor) engine.getDriver()).executeScript("arguments[0].scrollIntoView();", webEle,
                        -50, -50);
                wait.until(ExpectedConditions.visibilityOf(webEle));

                click(ele);
            }
        } catch (AWTException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void dbClick(Element ele) {
        Actions actions = new Actions(engine.getDriver());
        actions.doubleClick(searchStrategyUtils.findStrategy(WebElement.class, ele).search(ele));
    }

    @Override
    public boolean isEnabled(Element element) {
        return searchStrategyUtils.findStrategy(WebElement.class, element).search(element).isEnabled();
    }

    @Override
    public boolean isHidden(Element element) {
        return !searchStrategyUtils.findStrategy(WebElement.class, element).search(element).isDisplayed();
    }

    /**
     * @return ??
     */
    public int getMaxRetry() {
        return maxRetry;
    }

    /**
     * @param maxRetry ??3
     */
    public void setMaxRetry(int maxRetry) {
        this.maxRetry = maxRetry;
    }

}