Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions .github/workflows/frontend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,29 +149,11 @@ jobs:
defaults:
run:
shell: bash -l {0}
env:
ZEPPELIN_SELENIUM_BROWSER: "edge"
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Tune Runner VM
uses: ./.github/actions/tune-runner-vm
- name: Install Microsoft Edge
run: |
curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | sudo gpg --dearmor -o /usr/share/keyrings/microsoft-edge.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/microsoft-edge.gpg] https://packages.microsoft.com/repos/edge stable main" | sudo tee /etc/apt/sources.list.d/microsoft-edge.list
sudo apt-get update
sudo apt-get install -y microsoft-edge-stable
- name: Install msedgedriver
run: |
EDGE_VERSION=$(microsoft-edge --version | awk '{print $3}')
wget -q "https://msedgedriver.microsoft.com/${EDGE_VERSION}/edgedriver_linux64.zip" -O edgedriver.zip
unzip -q edgedriver.zip
sudo mv msedgedriver /usr/local/bin/
sudo chmod +x /usr/local/bin/msedgedriver
rm edgedriver.zip
- name: Print Edge version
run: msedgedriver --version
- name: Set up JDK 11
uses: actions/setup-java@v4
with:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@
package org.apache.zeppelin;


import com.google.common.base.Function;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.By;
Expand All @@ -38,8 +36,6 @@
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;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -55,15 +51,13 @@ abstract public class AbstractZeppelinIT {
protected static final long MAX_PARAGRAPH_TIMEOUT_SEC = 120;

protected void authenticationUser(String userName, String password) {
pollingWait(
clickableWait(
By.xpath("//div[contains(@class, 'navbar-collapse')]//li//button[contains(.,'Login')]"),
MAX_BROWSER_TIMEOUT_SEC).click();

ZeppelinITUtils.sleep(1000, false);

pollingWait(By.xpath("//*[@id='userName']"), MAX_BROWSER_TIMEOUT_SEC).sendKeys(userName);
pollingWait(By.xpath("//*[@id='password']"), MAX_BROWSER_TIMEOUT_SEC).sendKeys(password);
pollingWait(
visibilityWait(By.xpath("//*[@id='userName']"), MAX_BROWSER_TIMEOUT_SEC).sendKeys(userName);
visibilityWait(By.xpath("//*[@id='password']"), MAX_BROWSER_TIMEOUT_SEC).sendKeys(password);
clickableWait(
By.xpath("//*[@id='loginModalContent']//button[contains(.,'Login')]"),
MAX_BROWSER_TIMEOUT_SEC).click();

Expand Down Expand Up @@ -132,7 +126,7 @@ protected static String getNoteFormsXPath() {
protected boolean waitForParagraph(final int paragraphNo, final String state) {
By locator = By.xpath(getParagraphXPath(paragraphNo)
+ "//div[contains(@class, 'control')]//span[2][contains(.,'" + state + "')]");
WebElement element = pollingWait(locator, MAX_PARAGRAPH_TIMEOUT_SEC);
WebElement element = visibilityWait(locator, MAX_PARAGRAPH_TIMEOUT_SEC);
return element.isDisplayed();
}

Expand All @@ -145,20 +139,29 @@ protected String getParagraphStatus(final int paragraphNo) {

protected boolean waitForText(final String txt, final By locator) {
try {
WebElement element = pollingWait(locator, MAX_BROWSER_TIMEOUT_SEC);
WebElement element = visibilityWait(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<WebDriver> wait = new FluentWait<>(manager.getWebDriver())
.withTimeout(Duration.of(timeWait, ChronoUnit.SECONDS))
.pollingEvery(Duration.of(1, ChronoUnit.SECONDS))
.ignoring(NoSuchElementException.class);
WebDriverWait wait = new WebDriverWait(manager.getWebDriver(),
Duration.ofSeconds(timeWait));
return wait.until(ExpectedConditions.presenceOfElementLocated(locator));
}

protected WebElement visibilityWait(final By locator, final long timeWait) {
WebDriverWait wait = new WebDriverWait(manager.getWebDriver(),
Duration.ofSeconds(timeWait));
return wait.until(ExpectedConditions.visibilityOfElementLocated(locator));
}

return wait.until((Function<WebDriver, WebElement>) driver -> driver.findElement(locator));
protected WebElement clickableWait(final By locator, final long timeWait) {
WebDriverWait wait = new WebDriverWait(manager.getWebDriver(),
Duration.ofSeconds(timeWait));
return wait.until(ExpectedConditions.elementToBeClickable(locator));
}

protected void createNewNote() {
Expand Down Expand Up @@ -193,7 +196,7 @@ protected void deleteTrashNotebook(final WebDriver driver) {
}

protected void clickAndWait(final By locator) {
WebElement element = pollingWait(locator, MAX_IMPLICIT_WAIT);
WebElement element = clickableWait(locator, MAX_IMPLICIT_WAIT);
try {
element.click();
ZeppelinITUtils.sleep(1000, false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

import org.apache.commons.lang3.SystemUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
Expand Down Expand Up @@ -84,6 +85,12 @@ private WebDriver constructWebDriver(int port) {
Supplier<WebDriver> chromeDriverSupplier = () -> {
try {
ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-search-engine-choice-screen");
options.setExperimentalOption("prefs", Map.of(
"credentials_enable_service", false,
"profile.password_manager_enabled", false,
"profile.password_manager_leak_detection", false
));
return new ChromeDriver(options);
} catch (Exception e) {
LOG.error("Exception in WebDriverManager while ChromeDriver ", e);
Expand Down Expand Up @@ -169,7 +176,8 @@ public Boolean apply(WebDriver d) {
assertTrue(loaded);

try {
driver.manage().window().maximize();
// Manually setting fixed window size since `maximize()` crashes for Chrome/Edge driver on linux with xvfb.
driver.manage().window().setSize(new Dimension(1920, 1080));
} catch (Exception e) {
LOG.warn("Failed to maximize browser window. Consider using setSize() instead.", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,37 +109,37 @@ void testAnyOfRolesUser() throws Exception {
try {
authenticationUser("admin", "password1");

pollingWait(By.xpath("//div/button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"),
clickableWait(By.xpath("//div/button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"),
MAX_BROWSER_TIMEOUT_SEC).click();
clickAndWait(By.xpath("//li/a[contains(@href, '#/interpreter')]"));

assertTrue(pollingWait(By.xpath(
assertTrue(visibilityWait(By.xpath(
"//div[@id='main']/div/div[2]"),
MIN_IMPLICIT_WAIT).isDisplayed(), "Check is user has permission to view this page");

logoutUser("admin");

authenticationUser("finance1", "finance1");

pollingWait(By.xpath("//div/button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"),
clickableWait(By.xpath("//div/button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"),
MAX_BROWSER_TIMEOUT_SEC).click();
clickAndWait(By.xpath("//li/a[contains(@href, '#/interpreter')]"));

assertTrue(
pollingWait(By.xpath("//div[@id='main']/div/div[2]"), MIN_IMPLICIT_WAIT).isDisplayed(),
visibilityWait(By.xpath("//div[@id='main']/div/div[2]"), MIN_IMPLICIT_WAIT).isDisplayed(),
"Check is user has permission to view this page");

logoutUser("finance1");

authenticationUser("hr1", "hr1");

pollingWait(By.xpath("//div/button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"),
clickableWait(By.xpath("//div/button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"),
MAX_BROWSER_TIMEOUT_SEC).click();
clickAndWait(By.xpath("//li/a[contains(@href, '#/interpreter')]"));

try {
assertTrue(
pollingWait(By.xpath("//li[contains(@class, 'ng-toast__message')]//span/span"),
visibilityWait(By.xpath("//li[contains(@class, 'ng-toast__message')]//span/span"),
MIN_IMPLICIT_WAIT).isDisplayed(),
"Check is user has permission to view this page");
} catch (TimeoutException e) {
Expand All @@ -161,27 +161,27 @@ void testGroupPermission() throws Exception {
String noteId = manager.getWebDriver().getCurrentUrl()
.substring(manager.getWebDriver().getCurrentUrl().lastIndexOf("/") + 1);

pollingWait(By.xpath("//span[@uib-tooltip='Note permissions']"),
clickableWait(By.xpath("//span[@uib-tooltip='Note permissions']"),
MAX_BROWSER_TIMEOUT_SEC).click();
pollingWait(By.xpath(".//*[@id='selectOwners']/following::span//input"),
visibilityWait(By.xpath(".//*[@id='selectOwners']/following::span//input"),
MAX_BROWSER_TIMEOUT_SEC).sendKeys("finance ");
pollingWait(By.xpath(".//*[@id='selectReaders']/following::span//input"),
visibilityWait(By.xpath(".//*[@id='selectReaders']/following::span//input"),
MAX_BROWSER_TIMEOUT_SEC).sendKeys("finance ");
pollingWait(By.xpath(".//*[@id='selectRunners']/following::span//input"),
visibilityWait(By.xpath(".//*[@id='selectRunners']/following::span//input"),
MAX_BROWSER_TIMEOUT_SEC).sendKeys("finance ");
pollingWait(By.xpath(".//*[@id='selectWriters']/following::span//input"),
visibilityWait(By.xpath(".//*[@id='selectWriters']/following::span//input"),
MAX_BROWSER_TIMEOUT_SEC).sendKeys("finance ");
pollingWait(By.xpath("//button[@ng-click='savePermissions()']"), MAX_BROWSER_TIMEOUT_SEC)
visibilityWait(By.xpath("//button[@ng-click='savePermissions()']"), MAX_BROWSER_TIMEOUT_SEC)
.sendKeys(Keys.ENTER);

pollingWait(By.xpath("//div[@class='modal-dialog'][contains(.,'Permissions Saved ')]" +
clickableWait(By.xpath("//div[@class='modal-dialog'][contains(.,'Permissions Saved ')]" +
"//div[@class='modal-footer']//button[contains(.,'OK')]"),
MAX_BROWSER_TIMEOUT_SEC).click();
logoutUser("finance1");

authenticationUser("hr1", "hr1");
try {
WebElement element = pollingWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + noteId + "')]"),
WebElement element = visibilityWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + noteId + "')]"),
MAX_BROWSER_TIMEOUT_SEC);
assertFalse(element.isDisplayed(), "Check is user has permission to view this note link");
} catch (Exception e) {
Expand All @@ -202,7 +202,7 @@ void testGroupPermission() throws Exception {

authenticationUser("finance2", "finance2");
try {
WebElement element = pollingWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + noteId + "')]"),
WebElement element = visibilityWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + noteId + "')]"),
MAX_BROWSER_TIMEOUT_SEC);
assertTrue(element.isDisplayed(), "Check is user has permission to view this note link");
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,10 @@ void testGloballyAction() throws Exception {
try {
//step 1: (admin) login, set 'globally in shared' mode of python interpreter, logout
authenticationUser("admin", "password1");
pollingWait(By.xpath("//div/button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"),
clickableWait(By.xpath("//div/button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"),
MAX_BROWSER_TIMEOUT_SEC).click();
clickAndWait(By.xpath("//li/a[contains(@href, '#/interpreter')]"));
pollingWait(By.xpath("//input[contains(@ng-model, 'searchInterpreter')]"),
visibilityWait(By.xpath("//input[contains(@ng-model, 'searchInterpreter')]"),
MAX_BROWSER_TIMEOUT_SEC).sendKeys("python");
ZeppelinITUtils.sleep(500, false);
clickAndWait(By.xpath("//div[contains(@id, 'python')]//button[contains(@ng-click, 'valueform.$show();\n" +
Expand Down Expand Up @@ -206,7 +206,7 @@ void testGloballyAction() throws Exception {
(new WebDriverWait(manager.getWebDriver(), Duration.ofSeconds(MAX_BROWSER_TIMEOUT_SEC)))
.until(ExpectedConditions.visibilityOfElementLocated(locator));
if (element.isDisplayed()) {
pollingWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user1noteId + "')]"),
clickableWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user1noteId + "')]"),
MAX_BROWSER_TIMEOUT_SEC).click();
}
waitForParagraph(2, "FINISHED");
Expand Down Expand Up @@ -265,11 +265,11 @@ void testPerUserScopedAction() throws Exception {
try {
//step 1: (admin) login, set 'Per user in scoped' mode of python interpreter, logout
authenticationUser("admin", "password1");
pollingWait(By.xpath("//div/button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"),
clickableWait(By.xpath("//div/button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"),
MAX_BROWSER_TIMEOUT_SEC).click();

clickAndWait(By.xpath("//li/a[contains(@href, '#/interpreter')]"));
pollingWait(By.xpath("//input[contains(@ng-model, 'searchInterpreter')]"),
visibilityWait(By.xpath("//input[contains(@ng-model, 'searchInterpreter')]"),
MAX_BROWSER_TIMEOUT_SEC).sendKeys("python");
ZeppelinITUtils.sleep(500, false);

Expand Down Expand Up @@ -370,7 +370,7 @@ void testPerUserScopedAction() throws Exception {
(new WebDriverWait(manager.getWebDriver(), Duration.ofSeconds(MAX_BROWSER_TIMEOUT_SEC)))
.until(ExpectedConditions.visibilityOfElementLocated(locator));
if (element.isDisplayed()) {
pollingWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user1noteId + "')]"),
clickableWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user1noteId + "')]"),
MAX_BROWSER_TIMEOUT_SEC).click();
}
runParagraph(2);
Expand Down Expand Up @@ -467,7 +467,7 @@ void testPerUserScopedAction() throws Exception {
(new WebDriverWait(manager.getWebDriver(), Duration.ofSeconds(MAX_BROWSER_TIMEOUT_SEC)))
.until(ExpectedConditions.visibilityOfElementLocated(locator));
if (element.isDisplayed()) {
pollingWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user1noteId + "')]"),
clickableWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user1noteId + "')]"),
MAX_BROWSER_TIMEOUT_SEC).click();
}
waitForParagraph(1, "FINISHED");
Expand All @@ -486,7 +486,7 @@ void testPerUserScopedAction() throws Exception {
(new WebDriverWait(manager.getWebDriver(), Duration.ofSeconds(MAX_BROWSER_TIMEOUT_SEC)))
.until(ExpectedConditions.visibilityOfElementLocated(locator));
if (element.isDisplayed()) {
pollingWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user2noteId + "')]"),
clickableWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user2noteId + "')]"),
MAX_BROWSER_TIMEOUT_SEC).click();
}
runParagraph(1);
Expand All @@ -510,11 +510,11 @@ void testPerUserScopedAction() throws Exception {
//System: Check if the number of python interpreter process is 0
//System: Check if the number of python process is 0
authenticationUser("admin", "password1");
pollingWait(By.xpath("//div/button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"),
clickableWait(By.xpath("//div/button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"),
MAX_BROWSER_TIMEOUT_SEC).click();

clickAndWait(By.xpath("//li/a[contains(@href, '#/interpreter')]"));
pollingWait(By.xpath("//input[contains(@ng-model, 'searchInterpreter')]"),
visibilityWait(By.xpath("//input[contains(@ng-model, 'searchInterpreter')]"),
MAX_BROWSER_TIMEOUT_SEC).sendKeys("python");
ZeppelinITUtils.sleep(500, false);

Expand Down Expand Up @@ -553,10 +553,10 @@ void testPerUserIsolatedAction() throws Exception {
try {
//step 1: (admin) login, set 'Per user in isolated' mode of python interpreter, logout
authenticationUser("admin", "password1");
pollingWait(By.xpath("//div/button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"),
clickableWait(By.xpath("//div/button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"),
MAX_BROWSER_TIMEOUT_SEC).click();
clickAndWait(By.xpath("//li/a[contains(@href, '#/interpreter')]"));
pollingWait(By.xpath("//input[contains(@ng-model, 'searchInterpreter')]"),
visibilityWait(By.xpath("//input[contains(@ng-model, 'searchInterpreter')]"),
MAX_BROWSER_TIMEOUT_SEC).sendKeys("python");
ZeppelinITUtils.sleep(500, false);
clickAndWait(By.xpath("//div[contains(@id, 'python')]//button[contains(@ng-click, 'valueform.$show();\n" +
Expand Down Expand Up @@ -653,7 +653,7 @@ void testPerUserIsolatedAction() throws Exception {
(new WebDriverWait(manager.getWebDriver(), Duration.ofSeconds(MAX_BROWSER_TIMEOUT_SEC)))
.until(ExpectedConditions.visibilityOfElementLocated(locator));
if (element.isDisplayed()) {
pollingWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user1noteId + "')]"),
clickableWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user1noteId + "')]"),
MAX_BROWSER_TIMEOUT_SEC).click();
}
runParagraph(2);
Expand Down Expand Up @@ -752,7 +752,7 @@ void testPerUserIsolatedAction() throws Exception {
(new WebDriverWait(manager.getWebDriver(), Duration.ofSeconds(MAX_BROWSER_TIMEOUT_SEC)))
.until(ExpectedConditions.visibilityOfElementLocated(locator));
if (element.isDisplayed()) {
pollingWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user1noteId + "')]"),
clickableWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user1noteId + "')]"),
MAX_BROWSER_TIMEOUT_SEC).click();
}
waitForParagraph(1, "FINISHED");
Expand All @@ -771,7 +771,7 @@ void testPerUserIsolatedAction() throws Exception {
(new WebDriverWait(manager.getWebDriver(), Duration.ofSeconds(MAX_BROWSER_TIMEOUT_SEC)))
.until(ExpectedConditions.visibilityOfElementLocated(locator));
if (element.isDisplayed()) {
pollingWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user2noteId + "')]"),
clickableWait(By.xpath("//*[@id='notebook-names']//a[contains(@href, '" + user2noteId + "')]"),
MAX_BROWSER_TIMEOUT_SEC).click();
}
runParagraph(1);
Expand All @@ -795,11 +795,11 @@ void testPerUserIsolatedAction() throws Exception {
//System: Check if the number of python interpreter process is 0
//System: Check if the number of python process is 0
authenticationUser("admin", "password1");
pollingWait(By.xpath("//div/button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"),
clickableWait(By.xpath("//div/button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"),
MAX_BROWSER_TIMEOUT_SEC).click();

clickAndWait(By.xpath("//li/a[contains(@href, '#/interpreter')]"));
pollingWait(By.xpath("//input[contains(@ng-model, 'searchInterpreter')]"),
visibilityWait(By.xpath("//input[contains(@ng-model, 'searchInterpreter')]"),
MAX_BROWSER_TIMEOUT_SEC).sendKeys("python");
ZeppelinITUtils.sleep(500, false);

Expand Down
Loading
Loading