diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java b/zeppelin-server/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java index 7b3f3a7220e..a86d08b212a 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java @@ -41,6 +41,7 @@ abstract public class AbstractZeppelinIT { protected 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; @@ -59,6 +60,19 @@ protected void sleep(long millis, boolean logOutput) { } } + 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 + "]"; @@ -135,40 +149,6 @@ protected void deleteTestNotebook(final WebDriver driver) { sleep(100, true); } - public enum HelperKeys implements CharSequence { - OPEN_PARENTHESIS(Keys.chord(Keys.SHIFT, "9")), - EXCLAMATION(Keys.chord(Keys.SHIFT, "1")), - PERCENTAGE(Keys.chord(Keys.SHIFT, "5")), - SHIFT_ENTER(Keys.chord(SHIFT, ENTER)); - - private final CharSequence keyCode; - - HelperKeys(CharSequence keyCode) { - this.keyCode = keyCode; - } - - public char charAt(int index) { - return index == 0 ? keyCode.charAt(index) : '\ue000'; - } - - public int length() { - return 1; - } - - public CharSequence subSequence(int start, int end) { - if (start == 0 && end == 1) { - return String.valueOf(this.keyCode); - } else { - throw new IndexOutOfBoundsException(); - } - } - - public String toString() { - return String.valueOf(this.keyCode); - } - - } - protected void handleException(String message, Exception e) throws Exception { LOG.error(message, e); File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); 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 2a1f58b8f4e..4f0f3944e06 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/WebDriverManager.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/WebDriverManager.java @@ -34,6 +34,7 @@ import java.io.File; import java.io.IOException; import java.net.URL; +import java.util.concurrent.TimeUnit; import static org.junit.Assert.fail; @@ -114,6 +115,8 @@ public static WebDriver getWebDriver() { long start = System.currentTimeMillis(); boolean loaded = false; + driver.manage().timeouts().implicitlyWait(AbstractZeppelinIT.MAX_IMPLICIT_WAIT, + TimeUnit.SECONDS); driver.get(url); while (System.currentTimeMillis() - start < 60 * 1000) { 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 index 544004c708d..57a99913b3e 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java @@ -87,8 +87,7 @@ public void testCreateNewButton() throws Exception { "//div[@class='modal-footer']//button[contains(.,'OK')]")).click(); ZeppelinITUtils.sleep(1000, false); - WebElement oldParagraphEditor = driver.findElement(By.xpath(getParagraphXPath(1) + "//textarea")); - oldParagraphEditor.sendKeys(" original paragraph "); + setTextOfParagraph(1, " original paragraph "); WebElement newPara = driver.findElement(By.xpath(getParagraphXPath(1) + "//div[contains(@class,'new-paragraph')][1]")); action.moveToElement(newPara).click().build().perform(); @@ -98,8 +97,7 @@ public void testCreateNewButton() throws Exception { collector.checkThat("Paragraph is created above", driver.findElement(By.xpath(getParagraphXPath(1) + "//div[contains(@class, 'editor')]")).getText(), CoreMatchers.equalTo("")); - WebElement aboveParagraphEditor = driver.findElement(By.xpath(getParagraphXPath(1) + "//textarea")); - aboveParagraphEditor.sendKeys(" this is above "); + setTextOfParagraph(1, " this is above "); newPara = driver.findElement(By.xpath(getParagraphXPath(2) + "//div[contains(@class,'new-paragraph')][2]")); action.moveToElement(newPara).click().build().perform(); @@ -109,8 +107,7 @@ public void testCreateNewButton() throws Exception { collector.checkThat("Paragraph is created below", driver.findElement(By.xpath(getParagraphXPath(3) + "//div[contains(@class, 'editor')]")).getText(), CoreMatchers.equalTo("")); - WebElement belowParagraphEditor = driver.findElement(By.xpath(getParagraphXPath(3) + "//textarea")); - belowParagraphEditor.sendKeys(" this is below "); + setTextOfParagraph(3, " this is below "); collector.checkThat("The output field of paragraph1 contains", driver.findElement(By.xpath(getParagraphXPath(1) + "//div[contains(@class, 'editor')]")).getText(), @@ -163,7 +160,7 @@ public void testRemoveButton() throws Exception { deleteTestNotebook(driver); } catch (Exception e) { - handleException("Exception in ParagraphActionsIT while testMoveUpAndDown ", e); + handleException("Exception in ParagraphActionsIT while testRemoveButton ", e); } } @@ -176,16 +173,14 @@ public void testMoveUpAndDown() throws Exception { createNewNote(); waitForParagraph(1, "READY"); - WebElement paragraph1Editor = driver.findElement(By.xpath(getParagraphXPath(1) + "//textarea")); - paragraph1Editor.sendKeys("1"); + setTextOfParagraph(1, "1"); driver.findElement(By.xpath(getParagraphXPath(1) + "//span[@class='icon-settings']")).click(); driver.findElement(By.xpath(getParagraphXPath(1) + "//ul/li/a[@ng-click='insertNew()']")).click(); waitForParagraph(2, "READY"); - WebElement paragraph2Editor = driver.findElement(By.xpath(getParagraphXPath(2) + "//textarea")); - paragraph2Editor.sendKeys("2"); + setTextOfParagraph(2, "2"); collector.checkThat("The paragraph1 value contains", @@ -236,9 +231,7 @@ public void testDisableParagraphRunButton() throws Exception { createNewNote(); waitForParagraph(1, "READY"); - WebElement paragraph1Editor = driver.findElement(By.xpath(getParagraphXPath(1) + "//textarea")); - paragraph1Editor.sendKeys("println" + Keys.chord(Keys.SHIFT, "9") + "\"" - + "abcd\")"); + setTextOfParagraph(1, "println (\"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(); @@ -275,9 +268,7 @@ public void testClearOutputButton() throws Exception { waitForParagraph(1, "READY"); String xpathToOutputField=getParagraphXPath(1) + "//div[contains(@ng-if,'getResultType()')]"; - WebElement paragraph1Editor = driver.findElement(By.xpath(getParagraphXPath(1) + "//textarea")); - paragraph1Editor.sendKeys("println" + Keys.chord(Keys.SHIFT, "9") + "\"" - + "abcd\")"); + setTextOfParagraph(1, "println (\"abcd\")"); collector.checkThat("Before Run Output field contains ", driver.findElement(By.xpath(xpathToOutputField)).getText(), CoreMatchers.equalTo("")); diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/integration/SparkParagraphIT.java b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/SparkParagraphIT.java index e9f2bf8baec..eb09539be5e 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/integration/SparkParagraphIT.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/SparkParagraphIT.java @@ -32,9 +32,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static org.apache.zeppelin.AbstractZeppelinIT.HelperKeys.*; -import static org.openqa.selenium.Keys.*; - public class SparkParagraphIT extends AbstractZeppelinIT { private static final Logger LOG = LoggerFactory.getLogger(SparkParagraphIT.class); @@ -67,17 +64,10 @@ public void testSpark() throws Exception { return; } try { - WebElement paragraph1Editor = driver.findElement(By.xpath(getParagraphXPath(1) + "//textarea")); - paragraph1Editor.sendKeys("sc.version"); - paragraph1Editor.sendKeys(SHIFT_ENTER); + setTextOfParagraph(1, "sc.version"); + runParagraph(1); waitForParagraph(1, "FINISHED"); - WebElement paragraph1Result = driver.findElement(By.xpath( - getParagraphXPath(1) + "//div[@class=\"tableDisplay\"]")); - Float sparkVersion = Float.parseFloat(paragraph1Result.getText().split("= ")[1].substring(0, 3)); - - WebElement paragraph2Editor = driver.findElement(By.xpath(getParagraphXPath(2) + "//textarea")); - /* equivalent of @@ -90,50 +80,15 @@ case class Bank(age: Integer, job: String, marital: String, education: String, b val bank = bankText.map(s => s.split(";")).filter(s => s(0) != "\"age\"").map(s => Bank(s(0).toInt,s(1).replaceAll("\"", ""),s(2).replaceAll("\"", ""),s(3).replaceAll("\"", ""),s(5).replaceAll("\"", "").toInt)).toDF() bank.registerTempTable("bank") */ - paragraph2Editor.sendKeys("import org.apache.commons.io.IOUtils" + - ENTER + - - "import java.net.URL" + - ENTER + - - "import java.nio.charset.Charset" + - ENTER + - - "val bankText = sc.parallelize" + OPEN_PARENTHESIS + - "IOUtils.toString" + OPEN_PARENTHESIS + "new URL" + OPEN_PARENTHESIS - + "\"https://s3.amazonaws.com/apache" + SUBTRACT + "zeppelin/tutorial/bank/bank." + - "csv\"),Charset.forName" + OPEN_PARENTHESIS + "\"utf8\"))" + - ".split" + OPEN_PARENTHESIS + "\"\\n\"))" + - ENTER + - - "case class Bank" + OPEN_PARENTHESIS + - "age: Integer, job: String, marital: String, education: String, balance: Integer)" + - ENTER + - ENTER + - - "val bank = bankText.map" + OPEN_PARENTHESIS + "s => s.split" + - OPEN_PARENTHESIS + "\";\")).filter" + OPEN_PARENTHESIS + - "s => s" + OPEN_PARENTHESIS + "0) " + EXCLAMATION + - "= \"\\\"age\\\"\").map" + OPEN_PARENTHESIS + - "s => Bank" + OPEN_PARENTHESIS + "s" + OPEN_PARENTHESIS + - "0).toInt,s" + OPEN_PARENTHESIS + "1).replaceAll" + - OPEN_PARENTHESIS + "\"\\\"\", \"\")," + - "s" + OPEN_PARENTHESIS + "2).replaceAll" + - OPEN_PARENTHESIS + "\"\\\"\", \"\")," + - "s" + OPEN_PARENTHESIS + "3).replaceAll" + - OPEN_PARENTHESIS + "\"\\\"\", \"\")," + - "s" + OPEN_PARENTHESIS + "5).replaceAll" + - OPEN_PARENTHESIS + "\"\\\"\", \"\").toInt" + ")" + - ")" + (sparkVersion < 1.3f ? "" : ".toDF" + OPEN_PARENTHESIS + ")") + - ENTER + - - "bank.registerTempTable" + OPEN_PARENTHESIS + "\"bank\")" - ); - paragraph2Editor.sendKeys("" + END + BACK_SPACE + BACK_SPACE + - BACK_SPACE + BACK_SPACE + BACK_SPACE + BACK_SPACE + - BACK_SPACE + BACK_SPACE + BACK_SPACE + BACK_SPACE + BACK_SPACE); - - paragraph2Editor.sendKeys(SHIFT_ENTER); + setTextOfParagraph(2, "import org.apache.commons.io.IOUtils\\n" + + "import java.net.URL\\n" + + "import java.nio.charset.Charset\\n" + + "val bankText = sc.parallelize(IOUtils.toString(new URL(\"https://s3.amazonaws.com/apache-zeppelin/tutorial/bank/bank.csv\"),Charset.forName(\"utf8\")).split(\"\\\\n\"))\\n" + + "case class Bank(age: Integer, job: String, marital: String, education: String, balance: Integer)\\n" + + "\\n" + + "val bank = bankText.map(s => s.split(\";\")).filter(s => s(0) != \"\\\\\"age\\\\\"\").map(s => Bank(s(0).toInt,s(1).replaceAll(\"\\\\\"\", \"\"),s(2).replaceAll(\"\\\\\"\", \"\"),s(3).replaceAll(\"\\\\\"\", \"\"),s(5).replaceAll(\"\\\\\"\", \"\").toInt)).toDF()\\n" + + "bank.registerTempTable(\"bank\")"); + runParagraph(2); try { waitForParagraph(2, "FINISHED"); @@ -164,14 +119,11 @@ public void testPySpark() throws Exception { return; } try { - WebElement paragraph1Editor = driver.findElement(By.xpath(getParagraphXPath(1) + "//textarea")); - - paragraph1Editor.sendKeys(PERCENTAGE + "pyspark" + ENTER + - "for x in range" + OPEN_PARENTHESIS + "0, 3):" + ENTER + - " print \"test loop " + PERCENTAGE + "d\" " + - PERCENTAGE + " " + OPEN_PARENTHESIS + "x)" + ENTER); + setTextOfParagraph(1, "%pyspark\\n" + + "for x in range(0, 3):\\n" + + " print \"test loop %d\" % (x)"); - paragraph1Editor.sendKeys(SHIFT_ENTER); + runParagraph(1); try { waitForParagraph(1, "FINISHED"); @@ -199,12 +151,9 @@ public void testSqlSpark() throws Exception { return; } try { - WebElement paragraph1Editor = driver.findElement(By.xpath(getParagraphXPath(1) + "//textarea")); - - paragraph1Editor.sendKeys(PERCENTAGE + "sql" + ENTER + + setTextOfParagraph(1,"%sql\\n" + "select * from bank limit 1"); - - paragraph1Editor.sendKeys(SHIFT_ENTER); + runParagraph(1); try { waitForParagraph(1, "FINISHED"); diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ZeppelinIT.java b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ZeppelinIT.java index caf24168bc1..d7f3b4949f2 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ZeppelinIT.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/integration/ZeppelinIT.java @@ -17,21 +17,21 @@ package org.apache.zeppelin.integration; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.io.FileUtils; 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.openqa.selenium.*; +import org.junit.rules.ErrorCollector; +import org.openqa.selenium.By; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.File; - import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; /** * Test Zeppelin with web browser. @@ -47,6 +47,8 @@ public class ZeppelinIT extends AbstractZeppelinIT { private static final Logger LOG = LoggerFactory.getLogger(ZeppelinIT.class); + @Rule + public ErrorCollector collector = new ErrorCollector(); @Before public void startUp() { @@ -80,13 +82,8 @@ public void testAngularDisplay() throws Exception { * print angular template * %angular
BindingTest_{{myVar}}_
*/ - WebElement paragraph1Editor = driver.findElement(By.xpath(getParagraphXPath(1) + "//textarea")); - paragraph1Editor.sendKeys("println" + Keys.chord(Keys.SHIFT, "9") + "\"" - + Keys.chord(Keys.SHIFT, "5") - + "angular
" - + "BindingTest_{{myVar}}_
\")"); - paragraph1Editor.sendKeys(Keys.chord(Keys.SHIFT, Keys.ENTER)); + setTextOfParagraph(1, "println(\"%angular
BindingTest_{{myVar}}_
\")"); + runParagraph(1); waitForParagraph(1, "FINISHED"); // check expected text @@ -98,9 +95,8 @@ public void testAngularDisplay() throws Exception { * z.angularBind("myVar", 1) */ assertEquals(1, driver.findElements(By.xpath(getParagraphXPath(2) + "//textarea")).size()); - WebElement paragraph2Editor = driver.findElement(By.xpath(getParagraphXPath(2) + "//textarea")); - paragraph2Editor.sendKeys("z.angularBind" + Keys.chord(Keys.SHIFT, "9") + "\"myVar\", 1)"); - paragraph2Editor.sendKeys(Keys.chord(Keys.SHIFT, Keys.ENTER)); + setTextOfParagraph(2, "z.angularBind(\"myVar\", 1)"); + runParagraph(2); waitForParagraph(2, "FINISHED"); // check expected text @@ -112,11 +108,8 @@ public void testAngularDisplay() throws Exception { * print variable * print("myVar="+z.angular("myVar")) */ - WebElement paragraph3Editor = driver.findElement(By.xpath(getParagraphXPath(3) + "//textarea")); - paragraph3Editor.sendKeys( - "print" + Keys.chord(Keys.SHIFT, "9") + "\"myVar=\"" + Keys.chord(Keys.ADD) - + "z.angular" + Keys.chord(Keys.SHIFT, "9") + "\"myVar\"))"); - paragraph3Editor.sendKeys(Keys.chord(Keys.SHIFT, Keys.ENTER)); + setTextOfParagraph(3, "print(\"myVar=\"+z.angular(\"myVar\"))"); + runParagraph(3); waitForParagraph(3, "FINISHED"); // check expected text @@ -139,13 +132,8 @@ public void testAngularDisplay() throws Exception { * z.run(2, context) * } */ - WebElement paragraph4Editor = driver.findElement(By.xpath(getParagraphXPath(4) + "//textarea")); - paragraph4Editor.sendKeys( - "z.angularWatch" + Keys.chord(Keys.SHIFT, "9") + "\"myVar\", " - + Keys.chord(Keys.SHIFT, "9") - + "before:Object, after:Object, context:org.apache.zeppelin.interpreter.InterpreterContext)" - + Keys.EQUALS + ">{ z.run" +Keys.chord(Keys.SHIFT, "9") + "2, context)}"); - paragraph4Editor.sendKeys(Keys.chord(Keys.SHIFT, Keys.ENTER)); + setTextOfParagraph(4, "z.angularWatch(\"myVar\", (before:Object, after:Object, context:org.apache.zeppelin.interpreter.InterpreterContext)=>{ z.run(2, context)})"); + runParagraph(4); waitForParagraph(4, "FINISHED"); @@ -168,10 +156,8 @@ public void testAngularDisplay() throws Exception { * Unbind * z.angularUnbind("myVar") */ - WebElement paragraph5Editor = driver.findElement(By.xpath(getParagraphXPath(5) + "//textarea")); - paragraph5Editor.sendKeys( - "z.angularUnbind" + Keys.chord(Keys.SHIFT, "9") + "\"myVar\")"); - paragraph5Editor.sendKeys(Keys.chord(Keys.SHIFT, Keys.ENTER)); + setTextOfParagraph(5, "z.angularUnbind(\"myVar\")"); + runParagraph(5); waitForParagraph(5, "FINISHED"); // check expected text @@ -181,8 +167,7 @@ public void testAngularDisplay() throws Exception { /* * Bind again and see rebind works. */ - paragraph2Editor = driver.findElement(By.xpath(getParagraphXPath(2) + "//textarea")); - paragraph2Editor.sendKeys(Keys.chord(Keys.SHIFT, Keys.ENTER)); + runParagraph(2); waitForParagraph(2, "FINISHED"); // check expected text @@ -228,15 +213,19 @@ public void testSparkInterpreterDependencyLoading() throws Exception { // wait for first paragraph's " READY " status text waitForParagraph(1, "READY"); - WebElement paragraph1Editor = driver.findElement(By.xpath(getParagraphXPath(1) + "//textarea")); - - paragraph1Editor.sendKeys("import org.apache.commons.csv.CSVFormat"); - paragraph1Editor.sendKeys(Keys.chord(Keys.SHIFT, Keys.ENTER)); + setTextOfParagraph(1, "import org.apache.commons.csv.CSVFormat"); + runParagraph(1); waitForParagraph(1, "FINISHED"); // check expected text - assertTrue(waitForText("import org.apache.commons.csv.CSVFormat", - By.xpath(getParagraphXPath(1) + "//div[starts-with(@id, 'p') and contains(@id, 'text')]/div"))); + WebElement paragraph1Result = driver.findElement(By.xpath( + getParagraphXPath(1) + "//div[@class=\"tableDisplay\"]")); + + collector.checkThat("Paragraph from ZeppelinIT of testSparkInterpreterDependencyLoading result: ", + paragraph1Result.getText().toString(), CoreMatchers.containsString( + "import org.apache.commons.csv.CSVFormat" + ) + ); //delete created notebook for cleanup. deleteTestNotebook(driver);