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 6d2746eeab9..1c5e8be00ce 100644 --- a/zeppelin-integration/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java +++ b/zeppelin-integration/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java @@ -61,21 +61,38 @@ protected void authenticationUser(String userName, String password) { By.xpath("//*[@id='loginModalContent']//button[contains(.,'Login')]"), MAX_BROWSER_TIMEOUT_SEC).click(); - ZeppelinITUtils.sleep(1000, false); + // Wait for the logged-in navbar user dropdown to appear (indicates login completed + // and Angular digest cycle has updated the DOM), then dismiss any leftover modal overlay + visibilityWait( + By.xpath("//div[contains(@class, 'navbar-collapse')]//li//button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"), + MAX_BROWSER_TIMEOUT_SEC); + try { + ((JavascriptExecutor) manager.getWebDriver()).executeScript( + "$('.modal-backdrop').remove(); $('#loginModal').modal('hide');"); + } catch (Exception e) { + // ignore if jQuery/Bootstrap not ready + } + ZeppelinITUtils.sleep(500, false); } protected void logoutUser(String userName) throws URISyntaxException { ZeppelinITUtils.sleep(500, false); - manager.getWebDriver().findElement( - By.xpath("//div[contains(@class, 'navbar-collapse')]//li[contains(.,'" + userName + "')]")).click(); + clickableWait( + By.xpath("//div[contains(@class, 'navbar-collapse')]//li[contains(.,'" + userName + "')]"), + MAX_BROWSER_TIMEOUT_SEC).click(); ZeppelinITUtils.sleep(500, false); - manager.getWebDriver().findElement( - By.xpath("//div[contains(@class, 'navbar-collapse')]//li[contains(.,'" + userName + "')]//a[@ng-click='navbar.logout()']")).click(); + clickableWait( + By.xpath("//div[contains(@class, 'navbar-collapse')]//li[contains(.,'" + userName + "')]//a[@ng-click='navbar.logout()']"), + MAX_BROWSER_TIMEOUT_SEC).click(); ZeppelinITUtils.sleep(2000, false); - if (manager.getWebDriver().findElement( - By.xpath("//*[@id='loginModal']//div[contains(@class, 'modal-header')]/button")).isDisplayed()) { - manager.getWebDriver().findElement( - By.xpath("//*[@id='loginModal']//div[contains(@class, 'modal-header')]/button")).click(); + try { + WebElement closeButton = manager.getWebDriver().findElement( + By.xpath("//*[@id='loginModal']//div[contains(@class, 'modal-header')]/button")); + if (closeButton.isDisplayed()) { + closeButton.click(); + } + } catch (NoSuchElementException e) { + // login modal close button not found, which is fine } manager.getWebDriver().get(new URI(manager.getWebDriver().getCurrentUrl()).resolve("/classic/#/").toString()); ZeppelinITUtils.sleep(500, false); 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 003f7cc5376..745cfd284bf 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 @@ -33,11 +33,15 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import java.time.Duration; import org.openqa.selenium.By; +import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.Keys; import org.openqa.selenium.StaleElementReferenceException; import org.openqa.selenium.TimeoutException; import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -326,16 +330,31 @@ void testAngularRunParagraph() throws Exception { "%angular