/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.selenium.page.graphene;
import java.io.File;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import org.jboss.arquillian.graphene.Graphene;
import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.ElementNotVisibleException;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
/**
*
* Initial date: 20.06.2014<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class OOGraphene {
private static final long poolingDuration = 50;//ms
private static final long waitTinyDuration = 15;//seconds
private static final By closeBlueBoxButtonBy = By.cssSelector("div.o_alert_info div.o_sel_info_message a.o_alert_close.o_sel_info_close i.o_icon_close");
private static final By closeModalDialogButtonBy = By.cssSelector("div.modal-dialog div.modal-header button.close");
public static void waitModalDialog(WebDriver browser) {
By modalBy = By.cssSelector("div.modal-dialog div.modal-body");
waitElement(modalBy, 5, browser);
}
public static void waitCallout(WebDriver browser) {
By calloutBy = By.cssSelector("div.popover-content div.o_callout_content");
waitElement(calloutBy, 5, browser);
}
public static void waitBusy(WebDriver browser) {
Graphene.waitModel(browser).pollingEvery(poolingDuration, TimeUnit.MILLISECONDS).until(new BusyPredicate());
}
public static void waitBusy(WebDriver browser, int timeoutInSeconds) {
Graphene.waitModel(browser).withTimeout(timeoutInSeconds, TimeUnit.SECONDS)
.pollingEvery(poolingDuration, TimeUnit.MILLISECONDS).until(new BusyPredicate());
}
public static void waitElement(By element, WebDriver browser) {
Graphene.waitModel(browser)
.pollingEvery(poolingDuration, TimeUnit.MILLISECONDS).until().element(element).is().visible();
}
/**
* Wait until the element is visible.
*
* @param element The selector for the element
* @param timeoutInSeconds The timeout in seconds
* @param browser The web driver
*/
public static void waitElement(By element, int timeoutInSeconds, WebDriver browser) {
Graphene.waitModel(browser).withTimeout(timeoutInSeconds, TimeUnit.SECONDS)
.pollingEvery(poolingDuration, TimeUnit.MILLISECONDS).until().element(element).is().visible();
}
/**
* Wait until the element is present.
*
* @param element The selector of the element
* @param timeoutInSeconds The timeout in seconds
* @param browser The web driver
*/
public static void waitElementDisappears(By element, int timeoutInSeconds, WebDriver browser) {
Graphene.waitModel(browser).withTimeout(timeoutInSeconds, TimeUnit.SECONDS)
.pollingEvery(poolingDuration, TimeUnit.MILLISECONDS).until().element(element).is().not().present();
}
/**
* Wait until the element is not visible.
*
* @param element
* @param timeoutInSeconds
* @param browser
*/
public static void waitElementUntilNotVisible(By element, int timeoutInSeconds, WebDriver browser) {
Graphene.waitModel(browser).withTimeout(timeoutInSeconds, TimeUnit.SECONDS)
.pollingEvery(poolingDuration, TimeUnit.MILLISECONDS).until().element(element).is().not().visible();
}
/**
* Wait until the element is visible.
*
* @param element The element to be visible
* @param browser The web driver
*/
public static void waitElement(WebElement element, WebDriver browser) {
Graphene.waitModel(browser)
.pollingEvery(poolingDuration, TimeUnit.MILLISECONDS).until().element(element).is().visible();
}
/**
* Wait until the element is visible.
*
* @param element The element
* @param timeoutInSeconds The timeout in seconds
* @param browser The web driver
*/
public static void waitElement(WebElement element, int timeoutInSeconds, WebDriver browser) {
Graphene.waitModel(browser).withTimeout(timeoutInSeconds, TimeUnit.SECONDS)
.pollingEvery(poolingDuration, TimeUnit.MILLISECONDS).until().element(element).is().visible();
}
/**
* Wait until the element is present.
*
* @param element The selector of the element
* @param browser The web driver
*/
public static void waitElementPresent(By element, WebDriver browser) {
Graphene.waitModel(browser)
.pollingEvery(poolingDuration, TimeUnit.MILLISECONDS).until().element(element).is().present();
}
/**
* Wait until the element is present.
*
* @param element The selector of the element
* @param timeoutInSeconds The timeout in seconds
* @param browser The web driver
*/
public static void waitElementPresent(By element, int timeoutInSeconds, WebDriver browser) {
Graphene.waitModel(browser).withTimeout(timeoutInSeconds, TimeUnit.SECONDS)
.pollingEvery(poolingDuration, TimeUnit.MILLISECONDS).until().element(element).is().present();
}
/**
* The method is very, very experimental and not reliable. Only for research purpose.
*
* @param by
* @param browser
*/
public static void waitElementInViewport(By by, WebDriver browser) {
Graphene.waitModel(browser).withTimeout(5, TimeUnit.SECONDS)
.pollingEvery(poolingDuration, TimeUnit.MILLISECONDS)
.until(new InViewportPredicate(by));
}
public static void waitGui(WebDriver browser) {
Graphene.waitGui(browser);
}
public static WebElement moveTo(WebElement element, WebDriver browser) {
Actions actions = new Actions(browser);
actions.moveToElement(element).perform();
return element;
}
// top.tinymce.get('o_fi1000000416').setContent('<p>Hacked</p>');
// <div id="o_fi1000000416_diw" class="o_richtext_mce"> <iframe id="o_fi1000000416_ifr">
public static final void tinymce(String content, WebDriver browser) {
Graphene.waitModel(browser).withTimeout(waitTinyDuration, TimeUnit.SECONDS)
.pollingEvery(poolingDuration, TimeUnit.MILLISECONDS)
.until(new TinyMCELoadedPredicate());
((JavascriptExecutor)browser).executeScript("top.tinymce.activeEditor.setContent('" + content + "')");
}
public static final void tinymce(String content, String containerCssSelector, WebDriver browser) {
By tinyIdBy = By.cssSelector(containerCssSelector + " div.o_richtext_mce");
waitElement(tinyIdBy, 5, browser);
WebElement tinyIdEl = browser.findElement(tinyIdBy);
String tinyId = tinyIdEl.getAttribute("id").replace("_diw", "");
Graphene.waitModel(browser).withTimeout(waitTinyDuration, TimeUnit.SECONDS)
.pollingEvery(poolingDuration, TimeUnit.MILLISECONDS)
.until(new TinyMCELoadedByIdPredicate(tinyId));
((JavascriptExecutor)browser).executeScript("top.tinymce.editors['" + tinyId + "'].setContent('" + content + "')");
}
/**
* Make sure that the checkbox is in the correct state.
* @param checkboxEl
* @param val
*/
public static final void check(WebElement checkboxEl, Boolean val) {
if(val == null) return;
String checked = checkboxEl.getAttribute("checked");
if(Boolean.TRUE.equals(val)) {
if(checked == null) {
checkboxEl.click();
}
} else {
if(checked != null) {
checkboxEl.click();
}
}
}
public static final void textarea(WebElement textareaEl, String content, WebDriver browser) {
String id = textareaEl.getAttribute("id");
((JavascriptExecutor)browser).executeScript("document.getElementById('" + id + "').value = '" + content + "'");
}
public static final void date(Date date, String seleniumCssClass, WebDriver browser) {
Locale locale = getLocale(browser);
String dateText = DateFormat.getDateInstance(DateFormat.SHORT, locale).format(date);
By dateBy = By.cssSelector("div." + seleniumCssClass + " input.o_date_day");
browser.findElement(dateBy).sendKeys(dateText);
}
public static final void datetime(Date date, String seleniumCssClass, WebDriver browser) {
Locale locale = getLocale(browser);
String dateText = DateFormat.getDateInstance(DateFormat.SHORT, locale).format(date);
By dateBy = By.cssSelector("div." + seleniumCssClass + " input.o_date_day");
browser.findElement(dateBy).sendKeys(dateText);
By timeBy = By.cssSelector("div." + seleniumCssClass + " input.o_date_ms");
List<WebElement> timeEls = browser.findElements(timeBy);
Assert.assertNotNull(timeEls);
Assert.assertEquals(2, timeEls.size());
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
timeEls.get(0).click();
timeEls.get(0).clear();
timeEls.get(0).sendKeys(Integer.toString(hour));
timeEls.get(1).clear();
timeEls.get(1).sendKeys(Integer.toString(minute));
}
public static final Locale getLocale(WebDriver browser) {
String cssLanguage = browser.findElement(By.id("o_body")).getAttribute("class");
if(cssLanguage.contains("o_lang_de")) {
return Locale.GERMAN;
}
return Locale.ENGLISH;
}
/**
* Wait the end of the transition of the user's tools bar.
* @param browser
*/
public static final void waitingTransition(WebDriver browser) {
Graphene.waitModel(browser).pollingEvery(poolingDuration, TimeUnit.MILLISECONDS).until(new TransitionPredicate());
waitingALittleBit();
}
/**
* Wait 100ms
*/
public static final void waitingALittleBit() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* Wait 0.5 second
*/
public static final void waitingALittleLonger() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static final void uploadFile(By inputBy, File file, WebDriver browser) {
WebElement input = browser.findElement(inputBy);
input.sendKeys(file.getAbsolutePath());
}
public static final void waitScrollTop(WebDriver browser) {
try {
Graphene.waitModel(browser).ignoring(TimeoutException.class).pollingEvery(poolingDuration, TimeUnit.MILLISECONDS)
.until(new ScrollToPredicate());
waitingALittleBit();
} catch (Exception e) {
//e.printStackTrace();
}
}
public static final void waitAndCloseBlueMessageWindow(WebDriver browser) {
try {
Graphene.waitModel(browser).withTimeout(5, TimeUnit.SECONDS)
.pollingEvery(poolingDuration, TimeUnit.MILLISECONDS).until().element(closeBlueBoxButtonBy).is().visible();
} catch (Exception e) {
//e.printStackTrace();
}
closeBlueMessageWindow(browser);
}
public static final void closeBlueMessageWindow(WebDriver browser) {
List<WebElement> closeButtons = browser.findElements(closeBlueBoxButtonBy);
for(WebElement closeButton:closeButtons) {
if(closeButton.isDisplayed()) {
try {
clickCloseButton(browser, closeButton);
} catch (TimeoutException e) {
try {
clickCloseButton(browser, closeButton);
} catch(Exception e2) {
//e.printStackTrace();
}
} catch(ElementNotVisibleException e1) {
try {
waitingALittleLonger();
clickCloseButton(browser, closeButton);
} catch(Exception e2) {
//e2.printStackTrace();
}
}
}
}
}
private static final void clickCloseButton(WebDriver browser, WebElement closeButton) {
closeButton.click();
Graphene.waitModel(browser)
.withTimeout(1000, TimeUnit.MILLISECONDS)
.pollingEvery(poolingDuration, TimeUnit.MILLISECONDS)
.until(new CloseAlertInfoPredicate());
}
public static final void closeModalDialogWindow(WebDriver browser) {
List<WebElement> closeButtons = browser.findElements(closeModalDialogButtonBy);
for(WebElement closeButton:closeButtons) {
if(closeButton.isDisplayed()) {
try {
clickModalDialogCloseButton(browser, closeButton);
} catch (TimeoutException e) {
try {
clickModalDialogCloseButton(browser, closeButton);
} catch(Exception e2) {
//
}
}
}
}
}
private static final void clickModalDialogCloseButton(WebDriver browser, WebElement closeButton) {
try {
closeButton.click();
By dialogBy = By.cssSelector("div.modal-dialog");
OOGraphene.waitElementDisappears(dialogBy, 2, browser);
} catch (ElementNotVisibleException e) {
//e.printStackTrace();
}
}
public static final void closeOffCanvas(WebDriver browser) {
By closeBy = By.cssSelector("a.o_offcanvas_close");
WebElement closeButton = browser.findElement(closeBy);
if(closeButton.isDisplayed()) {
//timing issue if the close button is disappearing
waitNavBarTransition(browser);
if(closeButton.isDisplayed()) {
try {
closeButton.click();
waitNavBarTransition(browser);
} catch (Exception e) {
//e.printStackTrace();
}
}
}
}
public static final void waitNavBarTransition(WebDriver browser) {
try {
Graphene.waitModel(browser).pollingEvery(poolingDuration, TimeUnit.MILLISECONDS)
.until(new NavBarTransitionPredicate());
waitingALittleBit();
} catch (Exception e) {
//e.printStackTrace();
}
}
}