/**
* Constellio
* Copyright (C) 2010 DocuLibre inc.
*
* This program is free software: you can redistribute it and/or modifyTo
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.constellio.sdk.tests.selenium.adapters.base;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.Point;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import com.constellio.sdk.tests.selenium.conditions.ConditionWithTimeout;
@SuppressWarnings({ "rawtypes", "unchecked" })
public abstract class WebElementAdapter<WE extends WebElement, WD extends WebDriverAdapter<WE>> implements WebElement {
private WebElementFinder<WebElement> adaptedElementFinder;
private WD webDriver;
public WebElementAdapter(WD driver, final By by) {
super();
this.webDriver = driver;
this.adaptedElementFinder = new WebElementFinder<WebElement>() {
@Override
public WebElement get() {
webDriver.ensureNoApplicationException();
return WebElementAdapter.this.webDriver.findElement(by);
}
@Override
public String getOperationDescription() {
return "webDriver.find(" + by.toString() + ")";
}
};
this.adaptedElementFinder.getUsingCache();
}
protected WebElementAdapter(WD webDriver, WebElementFinder<WebElement> webElementFinder) {
this.webDriver = webDriver;
this.adaptedElementFinder = webElementFinder;
this.adaptedElementFinder.getUsingCache();
}
public WebElementAdapter(final WebElementAdapter<?, WD> webElement, final By by) {
super();
this.webDriver = webElement.webDriver;
this.adaptedElementFinder = new WebElementFinder<WebElement>() {
@Override
public WebElement get() {
webDriver.ensureNoApplicationException();
return webElement.findElement(by);
}
@Override
public String getOperationDescription() {
return webElement.toString() + ".find(" + by.toString() + ")";
}
};
this.adaptedElementFinder.getUsingCache();
}
public WebElementAdapter(WebElementAdapter<WE, WD> webElement) {
super();
this.webDriver = webElement.webDriver;
this.adaptedElementFinder = webElement.adaptedElementFinder;
}
protected abstract WE adapt(WebElementFinder<WebElement> adapted, WD webDriver);
public void changeValueTo(String newValue) {
clear();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
click();
sendKeysWithoutOnchangeEvent(newValue);
}
@Override
public void clear() {
getAdaptedElement().clear();
}
@Override
public void click() {
scrollIntoView();
getAdaptedElement().click();
}
public void rightClick() {
WebElement webElement = getAdaptedSeleniumElement();
Actions oAction = new Actions(webDriver.getAdaptedDriver());
oAction.moveToElement(webElement);
oAction.contextClick(webElement).build().perform();
}
@Deprecated
public void clickUsingJavascript() {
try {
scrollIntoView();
webDriver.executeScript("arguments[0].scrollIntoView();arguments[0].click();", getAdaptedSeleniumElement());
} catch (Exception e) {
getAdaptedSeleniumElement().click();
}
}
public void clickAndWaitForElementRefresh(final WebElementAdapter<WE, WD> element) {
clickAndWaitForElementRefresh(element, 10000);
}
public void clickAndWaitForElementRefresh(final WebElementAdapter<WE, WD> element, long timeoutInMS) {
scrollIntoView();
final long initialVersion = element.getVersion();
getAdaptedElement().click();
new ConditionWithTimeout() {
@Override
protected boolean evaluate() {
return element.getVersion() > initialVersion;
}
}.waitForTrue(timeoutInMS);
}
public List<WE> findAdaptElements(final By by) {
List<WE> adapters = new ArrayList<WE>();
int size = getAdaptedElement().findElements(by).size();
for (int i = 0; i < size; i++) {
adapters.add(findElementAtIndex(by, i));
}
return Collections.unmodifiableList(adapters);
}
public WE find(String className) {
return findElement(By.className(className));
}
@Override
public WE findElement(final By by) {
WebElementFinder<WebElement> factory = new WebElementFinder<WebElement>() {
@Override
public WebElement get() {
webDriver.ensureNoApplicationException();
return getAdaptedElement().findElement(by);
}
@Override
public String getOperationDescription() {
return getAdaptedElement().toString() + ".find(" + by.toString() + ")";
}
};
factory.getUsingCache();
return adapt(factory, webDriver);
}
public WE findElementAtIndex(final By by, final int index) {
WebElementFinder<WebElement> factory = new WebElementFinder<WebElement>() {
@Override
public WebElement get() {
webDriver.ensureNoApplicationException();
return getAdaptedElement().findElements(by).get(index);
}
@Override
public String getOperationDescription() {
return WebElementAdapter.this.toString() + ".findElements(" + by.toString() + ")";
}
};
factory.getUsingCache();
return adapt(factory, webDriver);
}
@Override
public List<WebElement> findElements(By by) {
return (List<WebElement>) findAdaptElements(by);
}
public WebElement getAdaptedElement() {
WebElement adapted = adaptedElementFinder.getUsingCache();
return adapted;
}
public WebElement getAdaptedSeleniumElement() {
WebElement adapted = adaptedElementFinder.getUsingCache();
if (adapted instanceof WebElementAdapter) {
return ((WebElementAdapter) adapted).getAdaptedSeleniumElement();
} else {
return adapted;
}
}
public List<WE> getChildren() {
return findAdaptElements(By.xpath("*"));
}
public String getClassNames() {
return getAttribute("class");
}
@Override
public String getAttribute(String name) {
return getAdaptedElement().getAttribute(name);
}
@Override
public String getCssValue(String propertyName) {
return getAdaptedElement().getCssValue(propertyName);
}
@Override
public Point getLocation() {
return getAdaptedElement().getLocation();
}
@Override
public Dimension getSize() {
return getAdaptedElement().getSize();
}
@Override
public String getTagName() {
return getAdaptedElement().getTagName();
}
@Override
public String getText() {
scrollIntoView();
return getAdaptedElement().getText();
}
public long getVersion() {
return adaptedElementFinder.getVersion();
}
@Override
public boolean isDisplayed() {
return getAdaptedElement().isDisplayed();
}
@Override
public boolean isEnabled() {
return getAdaptedElement().isEnabled();
}
@Override
public boolean isSelected() {
return getAdaptedElement().isSelected();
}
/**
* Use sendKeysWithoutOnchangeEvent instead
*/
@Override
public void sendKeys(CharSequence... keysToSend) {
sendKeysWithoutOnchangeEvent(keysToSend);
}
public void sendKeysWithoutOnchangeEvent(CharSequence... keysToSend) {
getAdaptedElement().sendKeys(keysToSend);
}
@Override
public void submit() {
getAdaptedElement().submit();
}
@Override
public String toString() {
return "anElement";
}
public void waitForRemoval() {
waitForRemoval(10000);
}
public void waitForRemoval(long timeout) {
new ConditionWithTimeout() {
@Override
protected boolean evaluate() {
try {
getLocation();
return false;
} catch (Exception e) {
return true;
}
}
}.waitForTrue(timeout);
}
public void waitUntilElementExist(By by) {
waitUntilElementExist(by, 10000);
}
public void waitUntilElementExist(final By by, long timeout) {
new ConditionWithTimeout() {
@Override
protected boolean evaluate() {
return findElement(by) != null;
}
}.waitForTrue(timeout);
}
public void waitUntilElementRemoved(By by) {
waitUntilElementRemoved(by, 10000);
}
public void waitUntilElementRemoved(final By by, long timeout) {
new ConditionWithTimeout() {
@Override
protected boolean evaluate() {
try {
findElement(by).getLocation();
return false;
} catch (Exception e) {
return true;
}
}
}.waitForTrue(timeout);
}
public WD getWebDriver() {
return webDriver;
}
public WebElementFinder<WebElement> getAdaptedElementFinder() {
return adaptedElementFinder;
}
public void scrollIntoView() {
//Actions actions = new Actions(webDriver.getAdaptedDriver());
//actions.moveToElement(this.getAdaptedSeleniumElement());
// actions.click();
//actions.perform();
webDriver.scrollIntoView(this);
}
}