/*
* 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 org.apache.zeppelin;
import com.google.common.base.Function;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.Date;
import java.util.concurrent.TimeUnit;
abstract public class AbstractZeppelinIT {
protected static WebDriver driver;
protected final static Logger LOG = LoggerFactory.getLogger(AbstractZeppelinIT.class);
protected static final long MAX_IMPLICIT_WAIT = 30;
protected static final long MAX_BROWSER_TIMEOUT_SEC = 30;
protected static final long MAX_PARAGRAPH_TIMEOUT_SEC = 60;
protected void setTextOfParagraph(int paragraphNo, String text) {
String editorId = driver.findElement(By.xpath(getParagraphXPath(paragraphNo) + "//div[contains(@class, 'editor')]")).getAttribute("id");
if (driver instanceof JavascriptExecutor) {
((JavascriptExecutor) driver).executeScript("ace.edit('" + editorId + "'). setValue('" + text + "')");
} else {
throw new IllegalStateException("This driver does not support JavaScript!");
}
}
protected void runParagraph(int paragraphNo) {
driver.findElement(By.xpath(getParagraphXPath(paragraphNo) + "//span[@class='icon-control-play']")).click();
}
protected String getParagraphXPath(int paragraphNo) {
return "(//div[@ng-controller=\"ParagraphCtrl\"])[" + paragraphNo + "]";
}
protected boolean waitForParagraph(final int paragraphNo, final String state) {
By locator = By.xpath(getParagraphXPath(paragraphNo)
+ "//div[contains(@class, 'control')]//span[2][contains(.,'" + state + "')]");
WebElement element = pollingWait(locator, MAX_PARAGRAPH_TIMEOUT_SEC);
return element.isDisplayed();
}
protected String getParagraphStatus(final int paragraphNo) {
By locator = By.xpath(getParagraphXPath(paragraphNo)
+ "//div[contains(@class, 'control')]/span[2]");
return driver.findElement(locator).getText();
}
protected boolean waitForText(final String txt, final By locator) {
try {
WebElement element = pollingWait(locator, MAX_BROWSER_TIMEOUT_SEC);
return txt.equals(element.getText());
} catch (TimeoutException e) {
return false;
}
}
protected WebElement pollingWait(final By locator, final long timeWait) {
Wait<WebDriver> wait = new FluentWait<>(driver)
.withTimeout(timeWait, TimeUnit.SECONDS)
.pollingEvery(1, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
return wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
});
}
protected static boolean endToEndTestEnabled() {
return null != System.getenv("TEST_SELENIUM");
}
protected void createNewNote() {
clickAndWait(By.xpath("//div[contains(@class, \"col-md-4\")]/div/h5/a[contains(.,'Create new" +
" note')]"));
WebDriverWait block = new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC);
block.until(ExpectedConditions.visibilityOfElementLocated(By.id("noteNameModal")));
clickAndWait(By.id("createNoteButton"));
block.until(ExpectedConditions.invisibilityOfElementLocated(By.className("pull-right")));
}
protected void deleteTestNotebook(final WebDriver driver) {
WebDriverWait block = new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC);
driver.findElement(By.xpath(".//*[@id='main']//button[@ng-click='moveNoteToTrash(note.id)']"))
.sendKeys(Keys.ENTER);
block.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(".//*[@id='main']//button[@ng-click='moveNoteToTrash(note.id)']")));
driver.findElement(By.xpath("//div[@class='modal-dialog'][contains(.,'This note will be moved to trash')]" +
"//div[@class='modal-footer']//button[contains(.,'OK')]")).click();
ZeppelinITUtils.sleep(100, true);
}
protected void clickAndWait(final By locator) {
pollingWait(locator, MAX_IMPLICIT_WAIT).click();
ZeppelinITUtils.sleep(1000, true);
}
protected void handleException(String message, Exception e) throws Exception {
LOG.error(message, e);
LogEntries logEntries = driver.manage().logs().get(LogType.BROWSER);
for (LogEntry entry : logEntries) {
LOG.error(new Date(entry.getTimestamp()) + " " + entry.getLevel() + " " + entry.getMessage());
}
File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
LOG.error("ScreenShot::\ndata:image/png;base64," + new String(Base64.encodeBase64(FileUtils.readFileToByteArray(scrFile))));
throw e;
}
}