/*******************************************************************************
* ATE, Automation Test Engine
*
* Copyright 2014, Montreal PROT, or individual contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Montreal PROT.
*
* 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.bigtester.ate.model.page.elementfind;//NOPMD
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.bigtester.ate.GlobalUtils;
import org.bigtester.ate.annotation.ATELogLevel;
import org.bigtester.ate.annotation.TestObjectFinderLoggable;
import org.bigtester.ate.model.data.IOnTheFlyData;
import org.bigtester.ate.model.page.atewebdriver.BrowserWindow;
import org.bigtester.ate.model.page.atewebdriver.IMyWebDriver;
import org.bigtester.ate.model.page.atewebdriver.WindowFrame;
import org.bigtester.ate.model.page.atewebdriver.exception.BrowserUnexpectedException;
import org.bigtester.ate.model.page.exception.PageFrameRefreshException;
import org.eclipse.jdt.annotation.Nullable;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import com.google.common.base.Function;
// TODO: Auto-generated Javadoc
/**
* The Class AbstractElementFind defines ....
*
* @author Peidong Hu
*/
public abstract class AbstractElementFind extends AbstractTestObjectFinderImpl {
/** The find by value. */
private String findByValue;
/** The index of same elements. */
@Nullable
private IOnTheFlyData<Integer> indexOfSameElements;
/** The wait. */
@Nullable
transient protected Wait<WebDriver> wait;
/**
* Gets the finding parameters logging value.
*
* @return the finding parameters logging value
*/
public String getFindingParametersLoggingValue() {
return "findByValue = " + findByValue;
}
/**
* @return the wait
*/
public Wait<WebDriver> getWait() {
final Wait<WebDriver> retVal = wait;
if (null == retVal) {
throw new IllegalStateException("wait is not correctly populated");
} else {
return retVal;
}
}
/**
* Do find.
*
* @param myWebDriver
* the my web driver
* @param findByValue
* the find by value
* @return the web element
* @throws BrowserUnexpectedException
* @throws NoSuchElementException
*/
public abstract WebElement doFind(IMyWebDriver myWebDriver,
String findByValue) throws NoSuchElementException, BrowserUnexpectedException;
/**
* Instantiates a new abstract element find.
*
* @param findByValue
* the find by value
*/
public AbstractElementFind(String findByValue) {
super();
this.findByValue = findByValue;
}
/**
* Gets the find by value.
*
* @return the find by value
*/
public String getFindByValue() {
return findByValue;
}
/**
* Sets the find by value.
*
* @param findByValue
* the new find by value
*/
public void setFindByValue(final String findByValue) {
this.findByValue = findByValue;
}
/**
* Supports plugin = false.
*
* @param arg0
* the arg0
* @return true, if successful
*/
public boolean supports(final String arg0) {
// TODO Auto-generated method stub
return false;
}
/**
* Creates the wait.
*
* @param driver
* the driver
*/
public void createWait(WebDriver driver) {
wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
}
/**
* {@inheritDoc}
*/
@Override
public @Nullable <T> T getCapability(Class<T> type) {
if (this instanceof IElementFind) {
return (T) this; // NOPMD
} else {
return null;
}
}
/**
* Do find.
*
* @param myWebDriver
* the my web driver
* @return the web element
* @throws NoSuchElementException
* the no such element exception
* @throws BrowserUnexpectedException
*/
@TestObjectFinderLoggable (level=ATELogLevel.INFO)
public WebElement doFind(IMyWebDriver myWebDriver)
throws NoSuchElementException, BrowserUnexpectedException {
return doFind(myWebDriver, findByValue);
}
/**
* @return the indexOfSameElements
*/
public int getIndexOfSameElementsInt() {
final IOnTheFlyData<Integer> indexOfSameElements2 = indexOfSameElements;
if (null == indexOfSameElements2) {
return 0;// NOPMD
} else {
return indexOfSameElements2.getOnTheFlyData().intValue();
}
}
/**
* @return the indexOfSameElements
*/
public IOnTheFlyData<Integer> getIndexOfSameElements() {
final IOnTheFlyData<Integer> indexOfSameElements2 = indexOfSameElements;
if (null == indexOfSameElements2) {
throw GlobalUtils
.createNotInitializedException("indexOfSameElements");
} else {
return indexOfSameElements2;
}
}
/**
* @param indexOfSameElements
* the indexOfSameElements to set
*/
public void setIndexOfSameElements(
IOnTheFlyData<Integer> indexOfSameElements) {
this.indexOfSameElements = indexOfSameElements;
}
/**
* Find through frames.
*
* @param win
* the win
* @param winFrame
* the win frame
* @param wait
* the wait
* @param findByValue
* the find by value
* @return the web element
*/
@Nullable
protected WebElement findThroughFrames(BrowserWindow win,
WindowFrame winFrame, Wait<WebDriver> wait, final By findByValue) {
win.getCurrentElementFindFrameChain().add(winFrame);
try {
winFrame.obtainFrameFocus();
} catch (PageFrameRefreshException e) {
throw GlobalUtils.createNotInitializedException("web driver frame", e);
}
WebElement retValWE = null;// NOPMD
try {
retValWE = wait.until( // NOPMD
new Function<WebDriver, WebElement>() {
public @Nullable WebElement apply( // NOPMD
@Nullable WebDriver driver) {
if (null == driver) {
throw new IllegalStateException(
"webdriver is not correctly populated.");
} else {
List<WebElement> allElements = driver
.findElements(findByValue);
if (allElements.size() == 0)
throw new NoSuchElementException(
findByValue.toString());
WebElement retVal;
int intIndex = getIndexOfSameElementsInt();
if (intIndex < -1) {
retVal = allElements.get(0);
} else if (intIndex == -1) {
retVal = allElements.get(allElements.size() - 1);
} else {
retVal = allElements.get(intIndex);
}
return retVal;
// return driver.findElement(findByValue);
}
}
});
} catch (NoSuchElementException | TimeoutException error) {
List<WindowFrame> childFrames = winFrame.getChildFrames();
for (WindowFrame gChildF : childFrames) {
if (null == gChildF)
throw GlobalUtils.createInternalError("java arraylist",
error);
retValWE = findThroughFrames(win, gChildF, wait, findByValue);
if (null != retValWE) {
break;
}
}
}
if (null == retValWE) {
if (winFrame.getParentFrame() == null) {
winFrame.focusDefautContent();
} else {
winFrame.focusParentFrame();
}
}
return retValWE;
}
/**
* Find element.
*
* @param findBy
* the find by
* @param myWebDriver
* the my web driver
* @return the web element
* @throws BrowserUnexpectedException
*/
protected WebElement findElement(final By findBy, IMyWebDriver myWebDriver) throws BrowserUnexpectedException {
WebDriver webD = myWebDriver.getWebDriver();
if (null == webD) {
throw new IllegalStateException(
"web driver is not correctly populated.");
} else {
createWait(webD);
BrowserWindow winOnFocus = myWebDriver.getMultiWindowsHandler()
.getBrowserWindowOnFocus();
winOnFocus.switchToDefaultContent();
if (!winOnFocus.getLastSuccessElementFindFrameChain().isEmpty()) {
for (WindowFrame lastSuccessWFrame : winOnFocus
.getLastSuccessElementFindFrameChain()) {
try {
lastSuccessWFrame.obtainFrameFocus();
} catch (PageFrameRefreshException e) {
//throw GlobalUtils.createNotInitializedException("frame chain");
break;
}
}
}
WebElement retValWE = null;// NOPMD
try {
retValWE = getWait().until( // NOPMD
new Function<WebDriver, WebElement>() {
public @Nullable WebElement apply( // NOPMD
@Nullable WebDriver driver) {
if (null == driver) {
throw new IllegalStateException(
"webdriver is not correctly populated.");
} else {
List<WebElement> allElements = driver
.findElements(findBy);
if (allElements.size() == 0)
throw new NoSuchElementException(
findByValue);
WebElement retVal;
int intIndex = getIndexOfSameElementsInt();
if (intIndex < -1) {
retVal = allElements.get(0);
} else if (intIndex == -1) {
retVal = allElements.get(allElements
.size() - 1);
} else if (intIndex < allElements.size()){
retVal = allElements.get(intIndex);
} else {
throw new NoSuchElementException(findBy.toString());
}
return retVal;
}
}
});
} catch (NoSuchElementException | TimeoutException error) {
winOnFocus.getCurrentElementFindFrameChain().clear();
try {
myWebDriver.getMultiWindowsHandler().refreshWindowsList(myWebDriver.getWebDriverInstance(), true);
} catch (BrowserUnexpectedException e) {
myWebDriver.getMultiWindowsHandler().retryRefreshWindows(myWebDriver.getWebDriverInstance(), true);
}
for (WindowFrame winfr : winOnFocus.getVisibleFrames()) {
try {
if (null == winfr)
throw GlobalUtils.createInternalError(
"arraylist error", error);
winfr.focusDefautContent();
winOnFocus.getCurrentElementFindFrameChain().clear();
retValWE = findThroughFrames(winOnFocus, winfr,
getWait(), findBy);
if (null == retValWE)
winfr.focusDefautContent();
else {
if (!winOnFocus.getLastSuccessElementFindFrameChain().equals(
winOnFocus.getCurrentElementFindFrameChain())) {
winOnFocus.getLastSuccessElementFindFrameChain().clear();
winOnFocus.getLastSuccessElementFindFrameChain().addAll(
winOnFocus.getCurrentElementFindFrameChain());
}
break;
}
} catch (NoSuchElementException | TimeoutException error1) {
continue;
}
}
}
if (null != retValWE) {
return retValWE;
}
throw new NoSuchElementException(findBy.toString());
}
}
}