Repository: incubator-zeppelin
Updated Branches:
  refs/heads/master 8dd7f4938 -> ad7a6c082


Add firebug and firepath for debugging

Hi,

I've refactored some of the selenium related test case, and added firebug and 
firepath for debugging so that if CI is failing on travis it can be debugged on 
local.

Also I feel that we should delete notebook once selenium test case is finished.

Author: Prabhjyot Singh <[email protected]>

Closes #490 from prabhjyotsingh/addFirebug and squashes the following commits:

1cc00e0 [Prabhjyot Singh] Merge remote-tracking branch 'remote/master' into 
addFirebug
6af0aa6 [Prabhjyot Singh] resolving merge issue
28f5087 [Prabhjyot Singh] Fixing CI failure
31e330c [Prabhjyot Singh] remove firebug binaries
3e8613e [Prabhjyot Singh] Download firebug binaries insted of keeping it in 
resource
4e0e33c [Prabhjyot Singh] refactor add firebug and firepath for debugging 
delete notebook once test is finished


Project: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/commit/ad7a6c08
Tree: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/tree/ad7a6c08
Diff: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/diff/ad7a6c08

Branch: refs/heads/master
Commit: ad7a6c0821840d32c8ddc87c9835c8b0cf1d33e1
Parents: 8dd7f49
Author: Prabhjyot Singh <[email protected]>
Authored: Fri Dec 18 12:35:48 2015 +0530
Committer: Lee moon soo <[email protected]>
Committed: Thu Dec 24 13:56:31 2015 +0900

----------------------------------------------------------------------
 .../org/apache/zeppelin/CommandExecutor.java    |  74 +++++
 .../java/org/apache/zeppelin/ProcessData.java   | 248 +++++++++++++++
 .../org/apache/zeppelin/WebDriverManager.java   | 185 +++++++++++
 .../java/org/apache/zeppelin/ZeppelinIT.java    | 305 ++++++++-----------
 .../org/apache/zeppelin/ZeppelinITUtils.java    |  42 +++
 5 files changed, 676 insertions(+), 178 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/ad7a6c08/zeppelin-server/src/test/java/org/apache/zeppelin/CommandExecutor.java
----------------------------------------------------------------------
diff --git 
a/zeppelin-server/src/test/java/org/apache/zeppelin/CommandExecutor.java 
b/zeppelin-server/src/test/java/org/apache/zeppelin/CommandExecutor.java
new file mode 100644
index 0000000..fd8a66f
--- /dev/null
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/CommandExecutor.java
@@ -0,0 +1,74 @@
+/*
+ * 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 org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class CommandExecutor {
+
+  public final static Logger LOG = 
LoggerFactory.getLogger(CommandExecutor.class);
+
+  public enum IGNORE_ERRORS {
+    TRUE,
+    FALSE
+  }
+
+  public static int NORMAL_EXIT = 0;
+
+  private static IGNORE_ERRORS DEFAULT_BEHAVIOUR_ON_ERRORS = 
IGNORE_ERRORS.TRUE;
+
+  public static Object executeCommandLocalHost(String[] command, boolean 
printToConsole, ProcessData.Types_Of_Data type, IGNORE_ERRORS ignore_errors) {
+    List<String> subCommandsAsList = new 
ArrayList<String>(Arrays.asList(command));
+    String mergedCommand = StringUtils.join(subCommandsAsList, " ");
+
+    LOG.info("Sending command \"" + mergedCommand + "\" to localhost");
+
+    ProcessBuilder processBuilder = new ProcessBuilder(command);
+    Process process = null;
+    try {
+      process = processBuilder.start();
+    } catch (IOException e) {
+      throw new RuntimeException(e);
+    }
+
+    ProcessData data_of_process = new ProcessData(process, printToConsole);
+    Object output_of_process = data_of_process.getData(type);
+    int exit_code = data_of_process.getExitCodeValue();
+
+    if (!printToConsole)
+      LOG.trace(output_of_process.toString());
+    else
+      LOG.debug(output_of_process.toString());
+    if (ignore_errors == IGNORE_ERRORS.FALSE && exit_code != NORMAL_EXIT) {
+      LOG.error(String.format("*********************Command '%s' failed with 
exitcode %s *********************", mergedCommand, exit_code));
+    }
+    return output_of_process;
+  }
+
+  public static Object executeCommandLocalHost(String command, boolean 
printToConsole, ProcessData.Types_Of_Data type) {
+    return executeCommandLocalHost(new String[]{"bash", "-c", command}, 
printToConsole, type, DEFAULT_BEHAVIOUR_ON_ERRORS);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/ad7a6c08/zeppelin-server/src/test/java/org/apache/zeppelin/ProcessData.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/ProcessData.java 
b/zeppelin-server/src/test/java/org/apache/zeppelin/ProcessData.java
new file mode 100644
index 0000000..d1e0d5c
--- /dev/null
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/ProcessData.java
@@ -0,0 +1,248 @@
+/*
+ * 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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+import java.util.concurrent.TimeUnit;
+
+public class ProcessData {
+  public enum Types_Of_Data {
+    OUTPUT,
+    ERROR,
+    EXIT_CODE,
+    STREAMS_MERGED,
+    PROCESS_DATA_OBJECT
+  }
+
+  public final static Logger LOG = LoggerFactory.getLogger(ProcessData.class);
+
+  private Process checked_process;
+  private boolean printToConsole = false;
+  private boolean removeRedundantOutput = true;
+
+  public ProcessData(Process connected_process, boolean printToConsole, int 
silenceTimeout, TimeUnit timeUnit) {
+    this.checked_process = connected_process;
+    this.printToConsole = printToConsole;
+    this.silenceTimeout = TimeUnit.MILLISECONDS.convert(silenceTimeout, 
timeUnit);
+  }
+
+  public ProcessData(Process connected_process, boolean printToConsole, int 
silenceTimeoutSec) {
+    this.checked_process = connected_process;
+    this.printToConsole = printToConsole;
+    this.silenceTimeout = TimeUnit.MILLISECONDS.convert(silenceTimeoutSec, 
TimeUnit.SECONDS);
+  }
+
+  public ProcessData(Process connected_process, boolean printToConsole) {
+    this.checked_process = connected_process;
+    this.printToConsole = printToConsole;
+  }
+
+  public ProcessData(Process connected_process) {
+    this.checked_process = connected_process;
+    this.printToConsole = true;
+  }
+
+
+  boolean returnCodeRetrieved = false;
+
+  private String outPutStream = null;
+  private String errorStream = null;
+  private int returnCode;
+  private long silenceTimeout = 10 * 60 * 1000;
+  private final long unconditionalExitDelayMinutes = 30;
+
+  public static boolean isRunning(Process process) {
+    try {
+      process.exitValue();
+      return false;
+    } catch (IllegalThreadStateException e) {
+      return true;
+    }
+  }
+
+  public Object getData(Types_Of_Data type) {
+    //TODO get rid of Pseudo-terminal will not be allocated because stdin is 
not a terminal.
+    switch (type) {
+      case OUTPUT: {
+        return this.getOutPutStream();
+      }
+      case ERROR: {
+        return this.getErrorStream();
+      }
+      case EXIT_CODE: {
+        return this.getExitCodeValue();
+      }
+      case STREAMS_MERGED: {
+        return this.getOutPutStream() + "\n" + this.getErrorStream();
+      }
+      case PROCESS_DATA_OBJECT: {
+        this.getErrorStream();
+        return this;
+      }
+      default: {
+        throw new IllegalArgumentException("Data Type " + type + " not 
supported yet!");
+      }
+    }
+  }
+
+  public int getExitCodeValue() {
+    try {
+      if (!returnCodeRetrieved) {
+        this.checked_process.waitFor();
+        this.returnCode = this.checked_process.exitValue();
+        this.returnCodeRetrieved = true;
+        this.checked_process.destroy();
+      }
+    } catch (Exception inter) {
+      throw new RuntimeException("Couldn't finish waiting for process " + 
this.checked_process + " termination", inter);
+    }
+    return this.returnCode;
+  }
+
+  public String getOutPutStream() {
+    if (this.outPutStream == null) {
+      try {
+        buildOutputAndErrorStreamData();
+      } catch (Exception e) {
+        throw new RuntimeException("Couldn't retrieve Output Stream data from 
process: " + this.checked_process.toString(), e);
+
+      }
+    }
+    this.outPutStream = this.outPutStream.replace("Pseudo-terminal will not be 
allocated because stdin is not a terminal.", "");
+    this.errorStream = this.errorStream.replace("Pseudo-terminal will not be 
allocated because stdin is not a terminal.", "");
+    return this.outPutStream;
+  }
+
+  public String getErrorStream() {
+    if (this.errorStream == null) {
+      try {
+        buildOutputAndErrorStreamData();
+      } catch (Exception e) {
+        throw new RuntimeException("Couldn't retrieve Error Stream data from 
process: " + this.checked_process.toString(), e);
+
+      }
+    }
+    this.outPutStream = this.outPutStream.replace("Pseudo-terminal will not be 
allocated because stdin is not a terminal.", "");
+    this.errorStream = this.errorStream.replace("Pseudo-terminal will not be 
allocated because stdin is not a terminal.", "");
+    return this.errorStream;
+  }
+
+  public String toString() {
+    StringBuilder result = new StringBuilder();
+    result.append(String.format("[OUTPUT STREAM]\n%s\n", this.outPutStream));
+    result.append(String.format("[ERROR STREAM]\n%s\n", this.errorStream));
+    result.append(String.format("[EXIT CODE]\n%d", this.returnCode));
+    return result.toString();
+  }
+
+  private void buildOutputAndErrorStreamData() throws IOException {
+    StringBuilder sbInStream = new StringBuilder();
+    StringBuilder sbErrorStream = new StringBuilder();
+
+    try {
+      InputStream in = this.checked_process.getInputStream();
+      InputStream inErrors = this.checked_process.getErrorStream();
+      BufferedReader inReader = new BufferedReader(new InputStreamReader(in));
+      BufferedReader inReaderErrors = new BufferedReader(new 
InputStreamReader(inErrors));
+      LOG.trace("Started retrieving data from streams of attached process: " + 
this.checked_process);
+
+      long lastStreamDataTime = System.currentTimeMillis();   //Store start 
time to be able to finish method if command hangs
+      long unconditionalExitTime = System.currentTimeMillis() + 
TimeUnit.MILLISECONDS.convert(unconditionalExitDelayMinutes, TimeUnit.MINUTES); 
// Stop after 'unconditionalExitDelayMinutes' even if process is alive and 
sending output
+      final int BUFFER_LEN = 300;
+      char charBuffer[] = new char[BUFFER_LEN];     //Use char buffer to read 
output, size can be tuned.
+      boolean outputProduced = true;                //Flag to check if 
previous iteration produced any output
+      while (isRunning(this.checked_process) || outputProduced) {   //Continue 
if process is alive or some output was produced on previous iteration and there 
may be still some data to read.
+        outputProduced = false;
+        ZeppelinITUtils.sleep(100, false);                                  
//Some local commands can exit fast, but immediate stream reading will give no 
output and after iteration, 'while' condition will be false so we will not read 
out any output while it is still there, just need to wait for some time for it 
to appear in streams.
+
+        StringBuilder tempSB = new StringBuilder();
+        while (inReader.ready()) {
+          tempSB.setLength(0);                                // clean 
temporary StringBuilder
+          int readCount = inReader.read(charBuffer, 0, BUFFER_LEN); //read up 
to 'BUFFER_LEN' chars to buffer
+          if (readCount < 1) {                                     // if 
nothing read or error occurred
+            break;
+          }
+          tempSB.append(charBuffer, 0, readCount);
+
+          sbInStream.append(tempSB);
+          if (tempSB.length() > 0) {
+            outputProduced = true;                                //set flag 
to know that we read something and there may be moire data, even if process 
already exited
+          }
+
+          lastStreamDataTime = System.currentTimeMillis();        //remember 
last time data was read from streams to be sure we are not looping infinitely
+        }
+
+        tempSB = new StringBuilder();                               //Same, 
but for error stream
+        while (inReaderErrors.ready()) {
+          tempSB.setLength(0);
+          int readCount = inReaderErrors.read(charBuffer, 0, BUFFER_LEN);
+          if (readCount < 1) {
+            break;
+          }
+          tempSB.append(charBuffer, 0, readCount);
+          sbErrorStream.append(tempSB);
+          if (tempSB.length() > 0) {
+            outputProduced = true;
+            String temp = new String(tempSB);
+            temp = temp.replaceAll("Pseudo-terminal will not be allocated 
because stdin is not a terminal.", "");
+            //TODO : error stream output need to be improved, because it 
outputs downloading information.
+            if (printToConsole) {
+              if (!temp.trim().equals("")) {
+                if (temp.toLowerCase().contains("error") || 
temp.toLowerCase().contains("failed")) {
+                  LOG.warn(temp.trim());
+                } else {
+                  LOG.debug(temp.trim());
+                }
+              }
+            }
+          }
+          lastStreamDataTime = System.currentTimeMillis();
+        }
+
+
+        if ((System.currentTimeMillis() - lastStreamDataTime > silenceTimeout) 
||     //Exit if silenceTimeout ms has passed from last stream read. Means 
process is alive but not sending any data.
+            (System.currentTimeMillis() > unconditionalExitTime)) {            
        //Exit unconditionally - guards against alive process continuously 
sending data.
+          LOG.info("Conditions: " + (System.currentTimeMillis() - 
lastStreamDataTime > silenceTimeout) + " " +
+              (System.currentTimeMillis() > unconditionalExitTime));
+          this.checked_process.destroy();
+          try {
+            if ((System.currentTimeMillis() > unconditionalExitTime))
+              LOG.error("!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Unconditional 
exit occured@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@!\nsome process hag up for more 
than " + unconditionalExitDelayMinutes + " minutes.");
+            LOG.error("!##################################!");
+            StringWriter sw = new StringWriter();
+            new Exception("Exited from buildOutputAndErrorStreamData by 
timeout").printStackTrace(new PrintWriter(sw)); //Get stack trace
+            String exceptionAsString = sw.toString();
+            LOG.error(exceptionAsString);
+          } catch (Exception ignore) {
+          }
+          break;
+        }
+      }
+
+      in.close();
+      inErrors.close();
+    } finally {
+      this.outPutStream = sbInStream.toString();
+      this.errorStream = sbErrorStream.toString();
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/ad7a6c08/zeppelin-server/src/test/java/org/apache/zeppelin/WebDriverManager.java
----------------------------------------------------------------------
diff --git 
a/zeppelin-server/src/test/java/org/apache/zeppelin/WebDriverManager.java 
b/zeppelin-server/src/test/java/org/apache/zeppelin/WebDriverManager.java
new file mode 100644
index 0000000..5b0b199
--- /dev/null
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/WebDriverManager.java
@@ -0,0 +1,185 @@
+/*
+ * 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 org.apache.commons.io.FileUtils;
+import org.openqa.selenium.By;
+import org.openqa.selenium.TimeoutException;
+import org.openqa.selenium.WebDriver;
+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.ExpectedCondition;
+import org.openqa.selenium.support.ui.WebDriverWait;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+
+import static org.junit.Assert.fail;
+
+
+public class WebDriverManager {
+
+  public final static Logger LOG = 
LoggerFactory.getLogger(WebDriverManager.class);
+
+  private static String downLoadsDir = "";
+
+  static WebDriver getWebDriver() {
+    WebDriver driver = null;
+
+    if (driver == null) {
+      try {
+        FirefoxBinary ffox = new FirefoxBinary();
+        if ("true".equals(System.getenv("TRAVIS"))) {
+          ffox.setEnvironmentProperty("DISPLAY", ":99"); // xvfb is supposed to
+          // run with DISPLAY 99
+        }
+        int firefoxVersion = WebDriverManager.getFirefoxVersion();
+        LOG.info("Firefox version " + firefoxVersion + " detected");
+
+        downLoadsDir = FileUtils.getTempDirectory().toString();
+
+        String tempPath = downLoadsDir + "/firebug/";
+
+        downloadFireBug(firefoxVersion, tempPath);
+
+        final String firebugPath = tempPath + "firebug.xpi";
+        final String firepathPath = tempPath + "firepath.xpi";
+
+        FirefoxProfile profile = new FirefoxProfile();
+        profile.setPreference("browser.download.folderList", 2);
+        profile.setPreference("browser.download.dir", downLoadsDir);
+        profile.setPreference("browser.helperApps.alwaysAsk.force", false);
+        profile.setPreference("browser.download.manager.showWhenStarting", 
false);
+        profile.setPreference("browser.download.manager.showAlertOnComplete", 
false);
+        profile.setPreference("browser.download.manager.closeWhenDone", true);
+        profile.setPreference("app.update.auto", false);
+        profile.setPreference("app.update.enabled", false);
+        profile.setPreference("dom.max_script_run_time", 0);
+        profile.setPreference("dom.max_chrome_script_run_time", 0);
+        profile.setPreference("browser.helperApps.neverAsk.saveToDisk", 
"application/x-ustar,application/octet-stream,application/zip,text/csv,text/plain");
+        profile.setPreference("network.proxy.type", 0);
+
+        profile.addExtension(new File(firebugPath));
+        profile.addExtension(new File(firepathPath));
+
+        driver = new FirefoxDriver(ffox, profile);
+      } catch (Exception e) {
+      }
+    }
+
+    if (driver == null) {
+      try {
+        driver = new ChromeDriver();
+      } catch (Exception e) {
+      }
+    }
+
+    if (driver == null) {
+      try {
+        driver = new SafariDriver();
+      } catch (Exception e) {
+      }
+    }
+
+    String url;
+    if (System.getProperty("url") != null) {
+      url = System.getProperty("url");
+    } else {
+      url = "http://localhost:8080";;
+    }
+
+    long start = System.currentTimeMillis();
+    boolean loaded = false;
+    driver.get(url);
+
+    while (System.currentTimeMillis() - start < 60 * 1000) {
+      // wait for page load
+      try {
+        (new WebDriverWait(driver, 5)).until(new ExpectedCondition<Boolean>() {
+          @Override
+          public Boolean apply(WebDriver d) {
+            return d.findElement(By.partialLinkText("Create new note"))
+                .isDisplayed();
+          }
+        });
+        loaded = true;
+        break;
+      } catch (TimeoutException e) {
+        driver.navigate().to(url);
+      }
+    }
+
+    if (loaded == false) {
+      fail();
+    }
+
+    return driver;
+  }
+
+  private static void downloadFireBug(int firefoxVersion, String tempPath) {
+    String firebugUrlString = null;
+    if (firefoxVersion < 23)
+      firebugUrlString = 
"http://getfirebug.com/releases/firebug/1.11/firebug-1.11.4.xpi";;
+    else if (firefoxVersion >= 23 && firefoxVersion < 30)
+      firebugUrlString = 
"http://getfirebug.com/releases/firebug/1.12/firebug-1.12.8.xpi";;
+    else if (firefoxVersion >= 30)
+      firebugUrlString = 
"http://getfirebug.com/releases/firebug/2.0/firebug-2.0.7.xpi";;
+
+
+    LOG.info("firebug version: " + firefoxVersion + ", will be downloaded to " 
+ tempPath);
+    try {
+      File firebugFile = new File(tempPath + "firebug.xpi");
+      URL firebugUrl = new URL(firebugUrlString);
+      if (!firebugFile.exists()) {
+        FileUtils.copyURLToFile(firebugUrl, firebugFile);
+      }
+
+
+      File firepathFile = new File(tempPath + "firepath.xpi");
+      URL firepathUrl = new 
URL("https://addons.cdn.mozilla.net/user-media/addons/11900/firepath-0.9.7.1-fx.xpi";);
+      if (!firepathFile.exists()) {
+        FileUtils.copyURLToFile(firepathUrl, firepathFile);
+      }
+
+    } catch (IOException e) {
+      LOG.error("Download of firebug version: " + firefoxVersion + ", falied 
in path " + tempPath);
+      LOG.error(e.toString());
+    }
+    LOG.info("Download of firebug version: " + firefoxVersion + ", 
successful");
+  }
+
+  public static int getFirefoxVersion() {
+    try {
+      String firefoxVersionCmd = "firefox -v";
+      if (System.getProperty("os.name").startsWith("Mac OS")) {
+        firefoxVersionCmd = "/Applications/Firefox.app/Contents/MacOS/" + 
firefoxVersionCmd;
+      }
+      String versionString = (String) 
CommandExecutor.executeCommandLocalHost(firefoxVersionCmd, false, 
ProcessData.Types_Of_Data.OUTPUT);
+      return Integer.valueOf(versionString.replaceAll("Mozilla Firefox", 
"").trim().substring(0, 2));
+    } catch (Exception e) {
+      e.printStackTrace();
+      return -1;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/ad7a6c08/zeppelin-server/src/test/java/org/apache/zeppelin/ZeppelinIT.java
----------------------------------------------------------------------
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 2a32c9c..6b464dd 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/ZeppelinIT.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/ZeppelinIT.java
@@ -68,70 +68,12 @@ public class ZeppelinIT {
   private static final long MAX_PARAGRAPH_TIMEOUT_SEC = 60;
   private WebDriver driver;
 
-  private void setWebDriver() {
-
-    if (driver == null) {
-      try {
-        FirefoxBinary ffox = new FirefoxBinary();
-        if ("true".equals(System.getenv("TRAVIS"))) {
-          ffox.setEnvironmentProperty("DISPLAY", ":99"); // xvfb is supposed to
-                                                         // run with DISPLAY 99
-        }
-        FirefoxProfile profile = new FirefoxProfile();
-        driver = new FirefoxDriver(ffox, profile);
-      } catch (Exception e) {
-        LOG.error("Starting Firefox failed",e);
-      }
-    }
-
-    if (driver == null) {
-      try {
-        driver = new ChromeDriver();
-      } catch (Exception e) {
-        LOG.error("Starting Chrome failed",e);
-      }
-    }
-
-    if (driver == null) {
-      try {
-        driver = new SafariDriver();
-      } catch (Exception e) {
-        LOG.error("Starting Safari failed",e);
-      }
-    }
-
-    String url;
-    if (System.getProperty("url") != null) {
-      url = System.getProperty("url");
-    } else {
-      url = "http://localhost:8080";;
-    }
-
-    long start = System.currentTimeMillis();
-    boolean loaded = false;
-    driver.get(url);
-
-    while (System.currentTimeMillis() - start < 60 * 1000) {
-      try { // wait for page load
-        WebElement element = pollingWait(By.partialLinkText("Create new 
note"), MAX_BROWSER_TIMEOUT_SEC);
-        loaded = element.isDisplayed();
-        break;
-      } catch (TimeoutException e) {
-        driver.navigate().to(url);
-      }
-    }
-
-    if (loaded == false) {
-      fail();
-    }
-  }
-
   @Before
   public void startUp() {
     if (!endToEndTestEnabled()) {
       return;
     }
-    setWebDriver();
+    driver = WebDriverManager.getWebDriver();
   }
 
   @After
@@ -186,125 +128,132 @@ public class ZeppelinIT {
       return;
     }
     try {
-    createNewNote();
-
-    // wait for first paragraph's " READY " status text
-    waitForParagraph(1, "READY");
-
-    /*
-     * print angular template
-     * %angular <div id='angularTestButton' 
ng-click='myVar=myVar+1'>BindingTest_{{myVar}}_</div>
-     */
-    WebElement paragraph1Editor = 
driver.findElement(By.xpath(getParagraphXPath(1) + "//textarea"));
-    paragraph1Editor.sendKeys("println" + Keys.chord(Keys.SHIFT, "9") + "\""
-                + Keys.chord(Keys.SHIFT, "5")
-                + "angular <div id='angularTestButton' "
-                + "ng" + Keys.chord(Keys.SUBTRACT) + "click='myVar=myVar+1'>"
-                + "BindingTest_{{myVar}}_</div>\")");
-    paragraph1Editor.sendKeys(Keys.chord(Keys.SHIFT, Keys.ENTER));
-    waitForParagraph(1, "FINISHED");
-
-    // check expected text
-    waitForText("BindingTest__", By.xpath(
-        getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]"));
-
-    /*
-     * Bind variable
-     * 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));
-    waitForParagraph(2, "FINISHED");
-
-    // check expected text
-    waitForText("BindingTest_1_", By.xpath(
-        getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]"));
-
-
-    /*
-     * 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));
-    waitForParagraph(3, "FINISHED");
-
-    // check expected text
-    waitForText("myVar=1", By.xpath(
-        getParagraphXPath(3) + "//div[@ng-bind=\"paragraph.result.msg\"]"));
-
-    /*
-     * Click element
-     */
-    driver.findElement(By.xpath(
-        getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")).click();
-
-    // check expected text
-    waitForText("BindingTest_2_", By.xpath(
-        getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]"));
-
-    /*
-     * Register watcher
-     * z.angularWatch("myVar", (before:Object, after:Object, 
context:org.apache.zeppelin.interpreter.InterpreterContext) => {
-     *   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));
-    waitForParagraph(4, "FINISHED");
-
-
-    /*
-     * Click element, again and see watcher works
-     */
-    driver.findElement(By.xpath(
-        getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")).click();
-
-    // check expected text
-    waitForText("BindingTest_3_", By.xpath(
-        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\"]"));
-
-    /*
-     * 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));
-    waitForParagraph(5, "FINISHED");
-
-    // check expected text
-    waitForText("BindingTest__",
-        By.xpath(getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]"));
-
-    /*
-     * Bind again and see rebind works.
-     */
-    paragraph2Editor = driver.findElement(By.xpath(getParagraphXPath(2) + 
"//textarea"));
-    paragraph2Editor.sendKeys(Keys.chord(Keys.SHIFT, Keys.ENTER));
-    waitForParagraph(2, "FINISHED");
-
-    // check expected text
-    waitForText("BindingTest_1_",
-        By.xpath(getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]"));
-
-    System.out.println("testCreateNotebook Test executed");
+      createNewNote();
+
+      // wait for first paragraph's " READY " status text
+      waitForParagraph(1, "READY");
+
+      /*
+       * print angular template
+       * %angular <div id='angularTestButton' 
ng-click='myVar=myVar+1'>BindingTest_{{myVar}}_</div>
+       */
+      WebElement paragraph1Editor = 
driver.findElement(By.xpath(getParagraphXPath(1) + "//textarea"));
+      paragraph1Editor.sendKeys("println" + Keys.chord(Keys.SHIFT, "9") + "\""
+                  + Keys.chord(Keys.SHIFT, "5")
+                  + "angular <div id='angularTestButton' "
+                  + "ng" + Keys.chord(Keys.SUBTRACT) + "click='myVar=myVar+1'>"
+                  + "BindingTest_{{myVar}}_</div>\")");
+      paragraph1Editor.sendKeys(Keys.chord(Keys.SHIFT, Keys.ENTER));
+      waitForParagraph(1, "FINISHED");
+
+      // check expected text
+      waitForText("BindingTest__", By.xpath(
+          getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]"));
+
+      /*
+       * Bind variable
+       * 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));
+      waitForParagraph(2, "FINISHED");
+
+      // check expected text
+      waitForText("BindingTest_1_", By.xpath(
+          getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]"));
+
+
+      /*
+       * 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));
+      waitForParagraph(3, "FINISHED");
+
+      // check expected text
+      waitForText("myVar=1", By.xpath(
+          getParagraphXPath(3) + "//div[@ng-bind=\"paragraph.result.msg\"]"));
+
+      /*
+       * Click element
+       */
+      driver.findElement(By.xpath(
+          getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")).click();
+
+      // check expected text
+      waitForText("BindingTest_2_", By.xpath(
+          getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]"));
+
+      /*
+       * Register watcher
+       * z.angularWatch("myVar", (before:Object, after:Object, 
context:org.apache.zeppelin.interpreter.InterpreterContext) => {
+       *   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));
+      waitForParagraph(4, "FINISHED");
+
+
+      /*
+       * Click element, again and see watcher works
+       */
+      driver.findElement(By.xpath(
+          getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")).click();
+
+      // check expected text
+      waitForText("BindingTest_3_", By.xpath(
+          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\"]"));
+
+      /*
+       * 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));
+      waitForParagraph(5, "FINISHED");
+
+      // check expected text
+      waitForText("BindingTest__",
+          By.xpath(getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]"));
+
+      /*
+       * Bind again and see rebind works.
+       */
+      paragraph2Editor = driver.findElement(By.xpath(getParagraphXPath(2) + 
"//textarea"));
+      paragraph2Editor.sendKeys(Keys.chord(Keys.SHIFT, Keys.ENTER));
+      waitForParagraph(2, "FINISHED");
+
+      // check expected text
+      waitForText("BindingTest_1_",
+          By.xpath(getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]"));
+
+      
driver.findElement(By.xpath("//*[@id='main']/div//h3/span[1]/button[@tooltip='Remove
 the notebook']"))
+          .sendKeys(Keys.ENTER);
+      ZeppelinITUtils.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);
+
+      System.out.println("testCreateNotebook Test executed");
     } catch (ElementNotVisibleException e) {
       File scrFile = 
((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
 

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/ad7a6c08/zeppelin-server/src/test/java/org/apache/zeppelin/ZeppelinITUtils.java
----------------------------------------------------------------------
diff --git 
a/zeppelin-server/src/test/java/org/apache/zeppelin/ZeppelinITUtils.java 
b/zeppelin-server/src/test/java/org/apache/zeppelin/ZeppelinITUtils.java
new file mode 100644
index 0000000..2fa6806
--- /dev/null
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/ZeppelinITUtils.java
@@ -0,0 +1,42 @@
+/*
+ * 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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ZeppelinITUtils {
+
+  public final static Logger LOG = 
LoggerFactory.getLogger(ZeppelinITUtils.class);
+
+  public static 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.");
+    }
+  }
+}


Reply via email to