diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java b/zeppelin-server/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java new file mode 100644 index 00000000000..899b8028178 --- /dev/null +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java @@ -0,0 +1,134 @@ +/* + * 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.junit.After; +import org.junit.Before; +import org.openqa.selenium.*; +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.util.LinkedList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +abstract public class AbstractZeppelinIT { + protected WebDriver driver; + + protected final static Logger LOG = LoggerFactory.getLogger(AbstractZeppelinIT.class); + protected static final long MAX_BROWSER_TIMEOUT_SEC = 30; + protected static final long MAX_PARAGRAPH_TIMEOUT_SEC = 60; + + protected void sleep(long millis, boolean logOutput) { + if (logOutput) { + LOG.info("Starting sleeping for " + (millis / 1000) + " seconds..."); + LOG.info("Caller: " + Thread.currentThread().getStackTrace()[2]); + } + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + e.printStackTrace(); + } + if (logOutput) { + LOG.info("Finished."); + } + } + + + 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[1][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[1]"); + + 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 wait = new FluentWait(driver) + .withTimeout(timeWait, TimeUnit.SECONDS) + .pollingEvery(1, TimeUnit.SECONDS) + .ignoring(NoSuchElementException.class); + + return wait.until(new Function() { + public WebElement apply(WebDriver driver) { + return driver.findElement(locator); + } + }); + } + + protected boolean endToEndTestEnabled() { + return null != System.getenv("CI"); + } + + protected void createNewNote() { + List notebookLinks = driver.findElements(By + .xpath("//div[contains(@class, \"col-md-4\")]/div/ul/li")); + List notebookTitles = new LinkedList(); + for (WebElement el : notebookLinks) { + notebookTitles.add(el.getText()); + } + + WebElement createNoteLink = driver.findElement(By.xpath("//div[contains(@class, \"col-md-4\")]/div/h5/a[contains(.,'Create new note')]")); + createNoteLink.click(); + + WebDriverWait block = new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC); + WebElement modal = block.until(ExpectedConditions.visibilityOfElementLocated(By.id("noteNameModal"))); + WebElement createNoteButton = modal.findElement(By.id("createNoteButton")); + createNoteButton.click(); + + try { + Thread.sleep(500); // wait for notebook list updated + } catch (InterruptedException e) { + } + } + + protected void deleteTestNotebook(final WebDriver driver) { + driver.findElement(By.xpath("//*[@id='main']/div//h3/span[1]/button[@tooltip='Remove the notebook']")) + .sendKeys(Keys.ENTER); + sleep(1000, true); + driver.findElement(By.xpath("//div[@class='modal-dialog'][contains(.,'delete this notebook')]" + + "//div[@class='modal-footer']//button[contains(.,'OK')]")).click(); + sleep(100, true); + } + +} diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/WebDriverManager.java b/zeppelin-server/src/test/java/org/apache/zeppelin/WebDriverManager.java index d899d571830..917896ff833 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/WebDriverManager.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/WebDriverManager.java @@ -44,7 +44,7 @@ public class WebDriverManager { private static String downLoadsDir = ""; - static WebDriver getWebDriver() { + public static WebDriver getWebDriver() { WebDriver driver = null; if (driver == null) { diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/ZeppelinIT.java b/zeppelin-server/src/test/java/org/apache/zeppelin/ZeppelinIT.java index 49c58b572cb..44769406e2a 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/ZeppelinIT.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/ZeppelinIT.java @@ -17,39 +17,20 @@ package org.apache.zeppelin; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import java.io.File; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.TimeUnit; - +import com.google.common.base.Function; import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.openqa.selenium.By; -import org.openqa.selenium.ElementNotVisibleException; -import org.openqa.selenium.Keys; -import org.openqa.selenium.NoSuchElementException; -import org.openqa.selenium.OutputType; -import org.openqa.selenium.TakesScreenshot; -import org.openqa.selenium.TimeoutException; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.chrome.ChromeDriver; -import org.openqa.selenium.firefox.FirefoxBinary; -import org.openqa.selenium.firefox.FirefoxDriver; -import org.openqa.selenium.firefox.FirefoxProfile; -import org.openqa.selenium.safari.SafariDriver; -import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.*; 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 com.google.common.base.Function; +import java.io.File; +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.assertEquals; /** * Test Zeppelin with web browser. @@ -62,11 +43,9 @@ * test -pl zeppelin-server * */ -public class ZeppelinIT { +public class ZeppelinIT extends AbstractZeppelinIT { private static final Logger LOG = LoggerFactory.getLogger(ZeppelinIT.class); - private static final long MAX_BROWSER_TIMEOUT_SEC = 30; - private static final long MAX_PARAGRAPH_TIMEOUT_SEC = 60; - private WebDriver driver; + @Before public void startUp() { @@ -85,44 +64,6 @@ public void tearDown() { driver.quit(); } - String getParagraphXPath(int paragraphNo) { - return "//div[@ng-controller=\"ParagraphCtrl\"][" + paragraphNo +"]"; - } - - boolean waitForParagraph(final int paragraphNo, final String state) { - By locator = By.xpath(getParagraphXPath(paragraphNo) - + "//div[contains(@class, 'control')]//span[1][contains(.,'" + state + "')]"); - WebElement element = pollingWait(locator, MAX_PARAGRAPH_TIMEOUT_SEC); - return element.isDisplayed(); - } - - 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) { - LOG.error("Exception in ZeppelinIT while waitForText ", e); - return false; - } - } - - public WebElement pollingWait(final By locator, final long timeWait) { - Wait wait = new FluentWait(driver) - .withTimeout(timeWait, TimeUnit.SECONDS) - .pollingEvery(1, TimeUnit.SECONDS) - .ignoring(NoSuchElementException.class); - - return wait.until(new Function() { - public WebElement apply(WebDriver driver) { - return driver.findElement(locator); - } - }); - }; - - boolean endToEndTestEnabled() { - return null != System.getenv("CI"); - } - @Test public void testAngularDisplay() throws InterruptedException{ if (!endToEndTestEnabled()) { @@ -149,7 +90,7 @@ public void testAngularDisplay() throws InterruptedException{ // check expected text waitForText("BindingTest__", By.xpath( - getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")); + getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")); /* * Bind variable @@ -163,7 +104,7 @@ public void testAngularDisplay() throws InterruptedException{ // check expected text waitForText("BindingTest_1_", By.xpath( - getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")); + getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")); /* @@ -179,17 +120,17 @@ public void testAngularDisplay() throws InterruptedException{ // check expected text waitForText("myVar=1", By.xpath( - getParagraphXPath(3) + "//div[@ng-bind=\"paragraph.result.msg\"]")); + getParagraphXPath(3) + "//div[@ng-bind=\"paragraph.result.msg\"]")); /* * Click element */ driver.findElement(By.xpath( - getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")).click(); + getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")).click(); // check expected text waitForText("BindingTest_2_", By.xpath( - getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")); + getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")); /* * Register watcher @@ -211,16 +152,16 @@ public void testAngularDisplay() throws InterruptedException{ * Click element, again and see watcher works */ driver.findElement(By.xpath( - getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")).click(); + getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")).click(); // check expected text waitForText("BindingTest_3_", By.xpath( - getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")); + getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")); waitForParagraph(3, "FINISHED"); // check expected text by watcher waitForText("myVar=3", By.xpath( - getParagraphXPath(3) + "//div[@ng-bind=\"paragraph.result.msg\"]")); + getParagraphXPath(3) + "//div[@ng-bind=\"paragraph.result.msg\"]")); /* * Unbind @@ -249,10 +190,10 @@ public void testAngularDisplay() throws InterruptedException{ driver.findElement(By.xpath("//*[@id='main']/div//h3/span[1]/button[@tooltip='Remove the notebook']")) .sendKeys(Keys.ENTER); - ZeppelinITUtils.sleep(1000, true); + sleep(1000, true); driver.findElement(By.xpath("//div[@class='modal-dialog'][contains(.,'delete this notebook')]" + "//div[@class='modal-footer']//button[contains(.,'OK')]")).click(); - ZeppelinITUtils.sleep(100, true); + sleep(100, true); System.out.println("testCreateNotebook Test executed"); } catch (ElementNotVisibleException e) { @@ -261,27 +202,4 @@ public void testAngularDisplay() throws InterruptedException{ } } - - private void createNewNote() { - List notebookLinks = driver.findElements(By - .xpath("//div[contains(@class, \"col-md-4\")]/div/ul/li")); - List notebookTitles = new LinkedList(); - for (WebElement el : notebookLinks) { - notebookTitles.add(el.getText()); - } - - WebElement createNoteLink = driver.findElement(By.xpath("//div[contains(@class, \"col-md-4\")]/div/h5/a[contains(.,'Create new note')]")); - createNoteLink.click(); - - WebDriverWait block = new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC); - WebElement modal = block.until(ExpectedConditions.visibilityOfElementLocated(By.id("noteNameModal"))); - WebElement createNoteButton = modal.findElement(By.id("createNoteButton")); - createNoteButton.click(); - - try { - Thread.sleep(500); // wait for notebook list updated - } catch (InterruptedException e) { - LOG.error("Exception in ZeppelinIT while createNewNote Thread.sleep", e); - } - } } diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java new file mode 100644 index 00000000000..41d7729191c --- /dev/null +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java @@ -0,0 +1,96 @@ +/* + * 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.integration; + + +import org.apache.zeppelin.AbstractZeppelinIT; +import org.apache.zeppelin.WebDriverManager; +import org.hamcrest.CoreMatchers; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ErrorCollector; +import org.openqa.selenium.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; + +public class ParagraphActionsIT extends AbstractZeppelinIT { + private static final Logger LOG = LoggerFactory.getLogger(ParagraphActionsIT.class); + + + @Rule + public ErrorCollector collector = new ErrorCollector(); + + @Before + public void startUp() { + if (!endToEndTestEnabled()) { + return; + } + driver = WebDriverManager.getWebDriver(); + } + + @After + public void tearDown() { + if (!endToEndTestEnabled()) { + return; + } + + driver.quit(); + } + + @Test + public void testDisableParagraphRunButton() throws InterruptedException { + if (!endToEndTestEnabled()) { + return; + } + try { + createNewNote(); + + waitForParagraph(1, "READY"); + WebElement paragraph1Editor = driver.findElement(By.xpath(getParagraphXPath(1) + "//textarea")); + paragraph1Editor.sendKeys("println" + Keys.chord(Keys.SHIFT, "9") + "\"" + + "abcd\")"); + + driver.findElement(By.xpath(getParagraphXPath(1) + "//span[@class='icon-settings']")).click(); + driver.findElement(By.xpath(getParagraphXPath(1) + "//ul/li/a[@ng-click='toggleEnableDisable()']")).click(); + collector.checkThat("The play button class was ", + driver.findElement(By.xpath(getParagraphXPath(1) + "//span[@class='icon-control-play']")).isDisplayed(), CoreMatchers.equalTo(false) + ); + + driver.findElement(By.xpath(".//*[@id='main']//button[@ng-click='runNote()']")).sendKeys(Keys.ENTER); + sleep(1000, true); + driver.findElement(By.xpath("//div[@class='modal-dialog'][contains(.,'Run all paragraphs?')]" + + "//div[@class='modal-footer']//button[contains(.,'OK')]")).click(); + sleep(2000, false); + + collector.checkThat("Paragraph status is ", + getParagraphStatus(1), CoreMatchers.equalTo("READY") + ); + + + deleteTestNotebook(driver); + + } catch (ElementNotVisibleException e) { + File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); + } + + } +} \ No newline at end of file