This is an automated email from the ASF dual-hosted git repository. prabhjyotsingh pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/zeppelin.git
The following commit(s) were added to refs/heads/master by this push: new b80dce5 [ZEPPELIN-5075] Bump up firefox version b80dce5 is described below commit b80dce567b6a06e8f6daf79d581a1843d81248f7 Author: Prabhjyot Singh <prabhjyotsi...@gmail.com> AuthorDate: Mon Oct 19 00:18:57 2020 +0530 [ZEPPELIN-5075] Bump up firefox version ### What is this PR for? The firefox version (31) is currently too old and if selenium test cases fail it becomes difficult to repro the issue. ### What type of PR is it? [Improvement] ### What is the Jira issue? * https://issues.apache.org/jira/browse/ZEPPELIN-5075 ### How should this be tested? * CI should be green * Travis link: https://travis-ci.com/github/prabhjyotsingh/zeppelin/builds/187051708 * Travis link: (latest) https://travis-ci.com/github/prabhjyotsingh/zeppelin/builds/190831750 ### Questions: * Does the licenses files need update? * Is there breaking changes for older versions? * Does this needs documentation? Author: Prabhjyot Singh <prabhjyotsi...@gmail.com> Author: Prabhjyot Singh <prabhjyot.si...@cloudera.com> Closes #3928 from prabhjyotsingh/ZEPPELIN-5075 and squashes the following commits: 84aa125ca [Prabhjyot Singh] ensure code editor is visible, if not force it to. bce7fd8d7 [Prabhjyot Singh] upgrade firfox to 81 reduce FF logs 80ab432d4 [Prabhjyot Singh] Merge remote-tracking branch 'apache-github/master' into ZEPPELIN-5075 e64916617 [Prabhjyot Singh] add condition for running with display 99 d1f78fa7f [Prabhjyot Singh] retry click 4cc2a693c [Prabhjyot Singh] ensure element is always clicked, reducing chances for flaky tests 09fb985ea [Prabhjyot Singh] fix testShowDescriptionOnInterpreterCreate, testAngularDisplay 5dd89f660 [Prabhjyot Singh] fix travis 5c30a22fd [Prabhjyot Singh] fix unused imports 2a7ca66a8 [Prabhjyot Singh] ZEPPELIN-5075: bump up selenium and firefox Change-Id: I8ed18d10f450c916528b98b9aff1759707cdce7e --- .travis.yml | 2 +- zeppelin-integration/pom.xml | 6 +- .../org/apache/zeppelin/AbstractZeppelinIT.java | 57 ++++++++++---- .../java/org/apache/zeppelin/WebDriverManager.java | 89 +++++++++++----------- .../apache/zeppelin/integration/InterpreterIT.java | 13 ++-- .../integration/InterpreterModeActionsIT.java | 6 +- .../zeppelin/integration/ParagraphActionsIT.java | 9 +-- .../apache/zeppelin/integration/ZeppelinIT.java | 28 +++---- 8 files changed, 120 insertions(+), 90 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0672b2f..0966058 100644 --- a/.travis.yml +++ b/.travis.yml @@ -169,7 +169,7 @@ jobs: jdk: "openjdk8" dist: xenial addons: - firefox: "31.0" + firefox: "81.0" before_install: - export PYTHON=2 - export R=true diff --git a/zeppelin-integration/pom.xml b/zeppelin-integration/pom.xml index 7beb821..8084a7d 100644 --- a/zeppelin-integration/pom.xml +++ b/zeppelin-integration/pom.xml @@ -42,7 +42,7 @@ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!--test library versions--> - <selenium.java.version>3.8.1</selenium.java.version> + <selenium.java.version>3.141.59</selenium.java.version> <commons.lang3.version>3.7</commons.lang3.version> <!--plugin library versions--> @@ -69,6 +69,10 @@ <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </exclusion> + <exclusion> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </exclusion> </exclusions> <scope>test</scope> </dependency> diff --git a/zeppelin-integration/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java b/zeppelin-integration/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java index 3a8bf58..5d280eb 100644 --- a/zeppelin-integration/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java +++ b/zeppelin-integration/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java @@ -19,12 +19,23 @@ package org.apache.zeppelin; import com.google.common.base.Function; +import java.io.File; +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.concurrent.TimeUnit; 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.By; +import org.openqa.selenium.ElementClickInterceptedException; +import org.openqa.selenium.JavascriptExecutor; +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.interactions.Actions; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.FluentWait; import org.openqa.selenium.support.ui.Wait; @@ -32,11 +43,8 @@ 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); @@ -46,7 +54,19 @@ abstract public class AbstractZeppelinIT { protected static final long MAX_PARAGRAPH_TIMEOUT_SEC = 120; protected void setTextOfParagraph(int paragraphNo, String text) { - String editorId = driver.findElement(By.xpath(getParagraphXPath(paragraphNo) + "//div[contains(@class, 'editor')]")).getAttribute("id"); + String paragraphXpath = getParagraphXPath(paragraphNo); + + try { + driver.manage().timeouts().implicitlyWait(100, TimeUnit.MILLISECONDS); + // make sure ace code is visible, if not click on show editor icon to make it visible + driver.findElement(By.xpath(paragraphXpath + "//span[@class='icon-size-fullscreen']")).click(); + } catch (NoSuchElementException e) { + // ignore + } finally { + driver.manage().timeouts().implicitlyWait(AbstractZeppelinIT.MAX_BROWSER_TIMEOUT_SEC, TimeUnit.SECONDS); + } + String editorId = pollingWait(By.xpath(paragraphXpath + "//div[contains(@class, 'editor')]"), + MIN_IMPLICIT_WAIT).getAttribute("id"); if (driver instanceof JavascriptExecutor) { ((JavascriptExecutor) driver).executeScript("ace.edit('" + editorId + "'). setValue('" + text + "')"); } else { @@ -56,8 +76,7 @@ abstract public class AbstractZeppelinIT { protected void runParagraph(int paragraphNo) { By by = By.xpath(getParagraphXPath(paragraphNo) + "//span[@class='icon-control-play']"); - pollingWait(by, 5); - driver.findElement(by).click(); + clickAndWait(by); } @@ -94,8 +113,8 @@ abstract public class AbstractZeppelinIT { protected WebElement pollingWait(final By locator, final long timeWait) { Wait<WebDriver> wait = new FluentWait<>(driver) - .withTimeout(timeWait, TimeUnit.SECONDS) - .pollingEvery(1, TimeUnit.SECONDS) + .withTimeout(Duration.of(timeWait, ChronoUnit.SECONDS)) + .pollingEvery(Duration.of(1, ChronoUnit.SECONDS)) .ignoring(NoSuchElementException.class); return wait.until(new Function<WebDriver, WebElement>() { @@ -136,8 +155,16 @@ abstract public class AbstractZeppelinIT { } protected void clickAndWait(final By locator) { - pollingWait(locator, MAX_IMPLICIT_WAIT).click(); - ZeppelinITUtils.sleep(1000, false); + WebElement element = pollingWait(locator, MAX_IMPLICIT_WAIT); + try { + element.click(); + ZeppelinITUtils.sleep(1000, false); + } catch (ElementClickInterceptedException e) { + // if the previous click did not happened mean the element is behind another clickable element + Actions action = new Actions(driver); + action.moveToElement(element).click().build().perform(); + ZeppelinITUtils.sleep(1500, false); + } } protected void handleException(String message, Exception e) throws Exception { diff --git a/zeppelin-integration/src/test/java/org/apache/zeppelin/WebDriverManager.java b/zeppelin-integration/src/test/java/org/apache/zeppelin/WebDriverManager.java index 768113f..ac5e4c8 100644 --- a/zeppelin-integration/src/test/java/org/apache/zeppelin/WebDriverManager.java +++ b/zeppelin-integration/src/test/java/org/apache/zeppelin/WebDriverManager.java @@ -19,6 +19,7 @@ package org.apache.zeppelin; import static org.junit.Assert.fail; +import com.google.common.collect.ImmutableMap; import java.io.File; import java.io.IOException; import java.net.URL; @@ -29,9 +30,7 @@ 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.FirefoxDriver.SystemProperty; import org.openqa.selenium.firefox.FirefoxOptions; import org.openqa.selenium.firefox.FirefoxProfile; import org.openqa.selenium.firefox.GeckoDriverService; @@ -50,52 +49,56 @@ public class WebDriverManager { private static String downLoadsDir = ""; - private static String GECKODRIVER_VERSION = "0.19.1"; + private static String GECKODRIVER_VERSION = "0.27.0"; public 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 + "/firefox/"; - - downloadGeekoDriver(firefoxVersion, tempPath); - - 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); - - System.setProperty(GeckoDriverService.GECKO_DRIVER_EXE_PROPERTY, tempPath + "geckodriver"); - System.setProperty(SystemProperty.DRIVER_USE_MARIONETTE, "false"); - - FirefoxOptions firefoxOptions = new FirefoxOptions(); - firefoxOptions.setBinary(ffox); - firefoxOptions.setProfile(profile); - driver = new FirefoxDriver(firefoxOptions); - } catch (Exception e) { - LOG.error("Exception in WebDriverManager while FireFox Driver ", e); + try { + int firefoxVersion = WebDriverManager.getFirefoxVersion(); + LOG.info("Firefox version " + firefoxVersion + " detected"); + + downLoadsDir = FileUtils.getTempDirectory().toString(); + + String tempPath = downLoadsDir + "/firefox/"; + + downloadGeekoDriver(firefoxVersion, tempPath); + + 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); + + FirefoxOptions firefoxOptions = new FirefoxOptions(); + firefoxOptions.setProfile(profile); + + ImmutableMap<String, String> displayImmutable = ImmutableMap.<String, String>builder().build(); + if ("true".equals(System.getenv("TRAVIS"))) { + // Run with DISPLAY 99 for TRAVIS or other build machine + displayImmutable = ImmutableMap.of("DISPLAY", ":99"); } + + System.setProperty(FirefoxDriver.SystemProperty.BROWSER_LOGFILE, "/dev/null"); + System.setProperty(FirefoxDriver.SystemProperty.DRIVER_USE_MARIONETTE,"true"); + + driver = new FirefoxDriver( + new GeckoDriverService.Builder() + .usingDriverExecutable(new File(tempPath + "geckodriver")) + .withEnvironment(displayImmutable) + .build(), firefoxOptions); + + } catch (Exception e) { + LOG.error("Exception in WebDriverManager while FireFox Driver ", e); } if (driver == null) { diff --git a/zeppelin-integration/src/test/java/org/apache/zeppelin/integration/InterpreterIT.java b/zeppelin-integration/src/test/java/org/apache/zeppelin/integration/InterpreterIT.java index bdf7811..a7257a0 100644 --- a/zeppelin-integration/src/test/java/org/apache/zeppelin/integration/InterpreterIT.java +++ b/zeppelin-integration/src/test/java/org/apache/zeppelin/integration/InterpreterIT.java @@ -51,13 +51,14 @@ public class InterpreterIT extends AbstractZeppelinIT { public void testShowDescriptionOnInterpreterCreate() throws Exception { try { // navigate to interpreter page - WebElement settingButton = driver.findElement(By.xpath("//button[@class='nav-btn dropdown-toggle ng-scope']")); - settingButton.click(); - WebElement interpreterLink = driver.findElement(By.xpath("//a[@href='#/interpreter']")); - interpreterLink.click(); + // setting button + clickAndWait(By.xpath("//button[@class='nav-btn dropdown-toggle ng-scope']")); - WebElement createButton = driver.findElement(By.xpath("//button[contains(., 'Create')]")); - createButton.click(); + // interpreter link + clickAndWait(By.xpath("//a[@href='#/interpreter']")); + + // create button + clickAndWait(By.xpath("//button[contains(., 'Create')]")); Select select = new Select(driver.findElement(By.xpath("//select[@ng-change='newInterpreterGroupChange()']"))); select.selectByVisibleText("spark"); diff --git a/zeppelin-integration/src/test/java/org/apache/zeppelin/integration/InterpreterModeActionsIT.java b/zeppelin-integration/src/test/java/org/apache/zeppelin/integration/InterpreterModeActionsIT.java index 200a4b2..1b2f727 100644 --- a/zeppelin-integration/src/test/java/org/apache/zeppelin/integration/InterpreterModeActionsIT.java +++ b/zeppelin-integration/src/test/java/org/apache/zeppelin/integration/InterpreterModeActionsIT.java @@ -475,8 +475,7 @@ public class InterpreterModeActionsIT extends AbstractZeppelinIT { element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) .until(ExpectedConditions.visibilityOfElementLocated(locator)); if (element.isDisplayed()) { - pollingWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user2noteId + "')]"), - MAX_BROWSER_TIMEOUT_SEC).click(); + clickAndWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user2noteId + "')]")); } clickAndWait(By.xpath("//*[@id='actionbar']//span[contains(@uib-tooltip, 'Interpreter binding')]")); clickAndWait(By.xpath("//div[@data-ng-repeat='item in interpreterBindings' and contains(., 'python')]//a")); @@ -754,8 +753,7 @@ public class InterpreterModeActionsIT extends AbstractZeppelinIT { element = (new WebDriverWait(driver, MAX_BROWSER_TIMEOUT_SEC)) .until(ExpectedConditions.visibilityOfElementLocated(locator)); if (element.isDisplayed()) { - pollingWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user2noteId + "')]"), - MAX_BROWSER_TIMEOUT_SEC).click(); + clickAndWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user2noteId + "')]")); } clickAndWait(By.xpath("//*[@id='actionbar']//span[contains(@uib-tooltip, 'Interpreter binding')]")); clickAndWait(By.xpath("//div[@data-ng-repeat='item in interpreterBindings' and contains(., 'python')]//a")); diff --git a/zeppelin-integration/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java b/zeppelin-integration/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java index b7e6cd2..a076908 100644 --- a/zeppelin-integration/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java +++ b/zeppelin-integration/src/test/java/org/apache/zeppelin/integration/ParagraphActionsIT.java @@ -57,7 +57,7 @@ public class ParagraphActionsIT extends AbstractZeppelinIT { public void testCreateNewButton() throws Exception { try { createNewNote(); - Actions action = new Actions(driver); + waitForParagraph(1, "READY"); Integer oldNosOfParas = driver.findElements(By.xpath("//div[@ng-controller=\"ParagraphCtrl\"]")).size(); collector.checkThat("Before Insert New : the number of paragraph ", @@ -80,9 +80,7 @@ public class ParagraphActionsIT extends AbstractZeppelinIT { setTextOfParagraph(1, " original paragraph "); - WebElement newPara = driver.findElement(By.xpath(getParagraphXPath(1) + "//div[contains(@class,'new-paragraph')][1]")); - action.moveToElement(newPara).click().build().perform(); - ZeppelinITUtils.sleep(1000, false); + clickAndWait(By.xpath(getParagraphXPath(1) + "//div[contains(@class,'new-paragraph')][1]")); waitForParagraph(1, "READY"); collector.checkThat("Paragraph is created above", @@ -90,8 +88,7 @@ public class ParagraphActionsIT extends AbstractZeppelinIT { CoreMatchers.equalTo(StringUtils.EMPTY)); setTextOfParagraph(1, " this is above "); - newPara = driver.findElement(By.xpath(getParagraphXPath(2) + "//div[contains(@class,'new-paragraph')][2]")); - action.moveToElement(newPara).click().build().perform(); + clickAndWait(By.xpath(getParagraphXPath(2) + "//div[contains(@class,'new-paragraph')][2]")); waitForParagraph(3, "READY"); diff --git a/zeppelin-integration/src/test/java/org/apache/zeppelin/integration/ZeppelinIT.java b/zeppelin-integration/src/test/java/org/apache/zeppelin/integration/ZeppelinIT.java index 9315056..21af0eb 100644 --- a/zeppelin-integration/src/test/java/org/apache/zeppelin/integration/ZeppelinIT.java +++ b/zeppelin-integration/src/test/java/org/apache/zeppelin/integration/ZeppelinIT.java @@ -17,6 +17,10 @@ package org.apache.zeppelin.integration; +import static org.apache.commons.lang3.StringUtils.isNotBlank; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import org.apache.zeppelin.AbstractZeppelinIT; import org.apache.zeppelin.WebDriverManager; import org.apache.zeppelin.ZeppelinITUtils; @@ -34,10 +38,6 @@ import org.openqa.selenium.WebElement; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static org.apache.commons.lang3.StringUtils.isNotBlank; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - /** * Test Zeppelin with web browser. * @@ -114,8 +114,8 @@ public class ZeppelinIT extends AbstractZeppelinIT { /* * Click element */ - driver.findElement(By.xpath( - getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")).click(); + clickAndWait(By.xpath( + getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")); // check expected text waitForText("BindingTest_2_", By.xpath( @@ -135,8 +135,8 @@ public class ZeppelinIT extends AbstractZeppelinIT { /* * Click element, again and see watcher works */ - driver.findElement(By.xpath( - getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")).click(); + clickAndWait(By.xpath( + getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")); // check expected text waitForText("BindingTest_3_", By.xpath( @@ -151,8 +151,8 @@ public class ZeppelinIT extends AbstractZeppelinIT { /* * Click element, again and see watcher still works */ - driver.findElement(By.xpath( - getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")).click(); + clickAndWait(By.xpath( + getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")); // check expected text waitForText("BindingTest_4_", By.xpath( getParagraphXPath(1) + "//div[@id=\"angularTestButton\"]")); @@ -187,8 +187,8 @@ public class ZeppelinIT extends AbstractZeppelinIT { driver.findElement(By.xpath(".//*[@id='main']//button[@ng-click='moveNoteToTrash(note.id)']")) .sendKeys(Keys.ENTER); ZeppelinITUtils.sleep(1000, false); - driver.findElement(By.xpath("//div[@class='modal-dialog'][contains(.,'This note will be moved to trash')]" + - "//div[@class='modal-footer']//button[contains(.,'OK')]")).click(); + clickAndWait(By.xpath("//div[@class='modal-dialog'][contains(.,'This note will be moved to trash')]" + + "//div[@class='modal-footer']//button[contains(.,'OK')]")); ZeppelinITUtils.sleep(100, false); LOG.info("testCreateNotebook Test executed"); @@ -304,8 +304,8 @@ public class ZeppelinIT extends AbstractZeppelinIT { setTextOfParagraph(2, "%sh echo NEW_VALUE"); // Click on 1 paragraph to trigger z.runParagraph() function - driver.findElement(By.xpath( - getParagraphXPath(1) + "//div[@id=\"angularRunParagraph\"]")).click(); + + clickAndWait(By.xpath(getParagraphXPath(1) + "//div[@id=\"angularRunParagraph\"]")); waitForParagraph(2, "FINISHED");