Browse Source

[Feature-8823][E2E] Restore resource center e2e test cases in ui-next (#8840)

3.0.0/version-upgrade
xiangzihao 3 years ago committed by GitHub
parent
commit
49b1a073dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      .github/workflows/e2e.yml
  2. 108
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/FileManageE2ETest.java
  3. 51
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/FunctionManageE2ETest.java
  4. 38
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UdfManageE2ETest.java
  5. 42
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UserE2ETest.java
  6. 17
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/CodeEditor.java
  7. 120
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/FileManagePage.java
  8. 84
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/FunctionManagePage.java
  9. 18
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/ResourcePage.java
  10. 63
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/UdfManagePage.java
  11. 15
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/UserPage.java
  12. 6
      dolphinscheduler-ui-next/src/views/resource/file/create/index.tsx
  13. 2
      dolphinscheduler-ui-next/src/views/resource/file/edit/index.tsx
  14. 4
      dolphinscheduler-ui-next/src/views/resource/file/folder/index.tsx
  15. 7
      dolphinscheduler-ui-next/src/views/resource/file/index.tsx
  16. 4
      dolphinscheduler-ui-next/src/views/resource/file/rename/index.tsx
  17. 5
      dolphinscheduler-ui-next/src/views/resource/file/table/table-action.tsx
  18. 5
      dolphinscheduler-ui-next/src/views/resource/file/upload/index.tsx
  19. 8
      dolphinscheduler-ui-next/src/views/resource/udf/function/components/function-modal.tsx
  20. 3
      dolphinscheduler-ui-next/src/views/resource/udf/function/index.tsx
  21. 4
      dolphinscheduler-ui-next/src/views/resource/udf/function/use-table.ts
  22. 4
      dolphinscheduler-ui-next/src/views/resource/udf/resource/components/folder-modal.tsx
  23. 5
      dolphinscheduler-ui-next/src/views/resource/udf/resource/components/upload-modal.tsx
  24. 5
      dolphinscheduler-ui-next/src/views/resource/udf/resource/index.tsx
  25. 5
      dolphinscheduler-ui-next/src/views/resource/udf/resource/use-table.ts
  26. 4
      dolphinscheduler-ui-next/src/views/security/user-manage/use-columns.ts

12
.github/workflows/e2e.yml

@ -87,12 +87,12 @@ jobs:
# class: org.apache.dolphinscheduler.e2e.cases.WorkflowE2ETest # class: org.apache.dolphinscheduler.e2e.cases.WorkflowE2ETest
# - name: WorkflowForSwitch # - name: WorkflowForSwitch
# class: org.apache.dolphinscheduler.e2e.cases.WorkflowSwitchE2ETest # class: org.apache.dolphinscheduler.e2e.cases.WorkflowSwitchE2ETest
# - name: FileManage - name: FileManage
# class: org.apache.dolphinscheduler.e2e.cases.FileManageE2ETest class: org.apache.dolphinscheduler.e2e.cases.FileManageE2ETest
# - name: UdfManage - name: UdfManage
# class: org.apache.dolphinscheduler.e2e.cases.UdfManageE2ETest class: org.apache.dolphinscheduler.e2e.cases.UdfManageE2ETest
# - name: FunctionManage - name: FunctionManage
# class: org.apache.dolphinscheduler.e2e.cases.FunctionManageE2ETest class: org.apache.dolphinscheduler.e2e.cases.FunctionManageE2ETest
# - name: MysqlDataSource # - name: MysqlDataSource
# class: org.apache.dolphinscheduler.e2e.cases.MysqlDataSourceE2ETest # class: org.apache.dolphinscheduler.e2e.cases.MysqlDataSourceE2ETest
# - name: ClickhouseDataSource # - name: ClickhouseDataSource

108
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/FileManageE2ETest.java

@ -84,20 +84,26 @@ public class FileManageE2ETest {
@BeforeAll @BeforeAll
public static void setup() { public static void setup() {
// TenantPage tenantPage = new LoginPage(browser) TenantPage tenantPage = new LoginPage(browser)
// .login(user, password) .login(user, password)
// .create(tenant); .goToNav(SecurityPage.class)
// .goToTab(TenantPage.class)
// await().untilAsserted(() -> assertThat(tenantPage.tenantList()) .create(tenant);
// .as("Tenant list should contain newly-created tenant")
// .extracting(WebElement::getText) await().untilAsserted(() -> assertThat(tenantPage.tenantList())
// .anyMatch(it -> it.contains(tenant))); .as("Tenant list should contain newly-created tenant")
// .extracting(WebElement::getText)
// tenantPage.goToNav(SecurityPage.class) .anyMatch(it -> it.contains(tenant)));
// .goToTab(UserPage.class)
// .update(user, user, password, email, phone) UserPage userPage = tenantPage.goToNav(SecurityPage.class)
// .goToNav(ResourcePage.class) .goToTab(UserPage.class);
// .goToTab(FileManagePage.class);
new WebDriverWait(userPage.driver(), 20).until(ExpectedConditions.visibilityOfElementLocated(
new By.ByClassName("name")));
userPage.update(user, user, password, email, phone, tenant)
.goToNav(ResourcePage.class)
.goToTab(FileManagePage.class);
} }
@AfterAll @AfterAll
@ -137,39 +143,39 @@ public class FileManageE2ETest {
.anyMatch(it -> it.contains(testDirectoryName))); .anyMatch(it -> it.contains(testDirectoryName)));
} }
@Test // @Test
@Order(20) // @Order(20)
void testCreateDuplicateDirectory() { // void testCreateDuplicateDirectory() {
final FileManagePage page = new FileManagePage(browser); // final FileManagePage page = new FileManagePage(browser);
//
page.createDirectory(testDirectoryName, "test_desc"); // page.createDirectory(testDirectoryName, "test_desc");
//
await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText()) // await().untilAsserted(() -> assertThat(browser.findElement(By.tagName("body")).getText())
.contains("resource already exists") // .contains("resource already exists")
); // );
//
page.createDirectoryBox().buttonCancel().click(); // page.createDirectoryBox().buttonCancel().click();
} // }
@Test
@Order(21)
void testCreateSubDirectory() {
final FileManagePage page = new FileManagePage(browser);
page.createSubDirectory(testDirectoryName, testSubDirectoryName, "test_desc");
await().untilAsserted(() -> assertThat(page.fileList()) // @Test
.as("File list should contain newly-created file") // @Order(21)
.extracting(WebElement::getText) // void testCreateSubDirectory() {
.anyMatch(it -> it.contains(testSubDirectoryName))); // final FileManagePage page = new FileManagePage(browser);
} //
// page.createSubDirectory(testDirectoryName, testSubDirectoryName, "test_desc");
//
// await().untilAsserted(() -> assertThat(page.fileList())
// .as("File list should contain newly-created file")
// .extracting(WebElement::getText)
// .anyMatch(it -> it.contains(testSubDirectoryName)));
// }
@Test @Test
@Order(22) @Order(22)
void testRenameDirectory() { void testRenameDirectory() {
final FileManagePage page = new FileManagePage(browser); final FileManagePage page = new FileManagePage(browser);
page.rename(testSubDirectoryName, testRenameDirectoryName); page.rename(testDirectoryName, testRenameDirectoryName);
await().untilAsserted(() -> { await().untilAsserted(() -> {
browser.navigate().refresh(); browser.navigate().refresh();
@ -188,7 +194,7 @@ public class FileManageE2ETest {
page.goToNav(ResourcePage.class) page.goToNav(ResourcePage.class)
.goToTab(FileManagePage.class) .goToTab(FileManagePage.class)
.delete(testDirectoryName); .delete(testRenameDirectoryName);
await().untilAsserted(() -> { await().untilAsserted(() -> {
browser.navigate().refresh(); browser.navigate().refresh();
@ -196,7 +202,7 @@ public class FileManageE2ETest {
assertThat( assertThat(
page.fileList() page.fileList()
).noneMatch( ).noneMatch(
it -> it.getText().contains(testDirectoryName) it -> it.getText().contains(testRenameDirectoryName)
); );
}); });
} }
@ -264,26 +270,10 @@ public class FileManageE2ETest {
}); });
} }
@Test
@Order(60)
void testUploadOver1GBFile() throws IOException {
final FileManagePage page = new FileManagePage(browser);
RandomAccessFile file = new RandomAccessFile(testOver1GBFilePath.toFile(), "rw");
file.setLength((long) (1.5 * 1024 * 1024 * 1024));
page.uploadFile(testOver1GBFilePath.toFile().getAbsolutePath());
await().untilAsserted(() ->
assertThat(browser.findElement(By.tagName("body")).getText())
.contains("Upload File size cannot exceed 1g")
);
}
@Test @Test
@Order(65) @Order(65)
void testUploadUnder1GBFile() throws IOException { void testUploadUnder1GBFile() throws IOException {
final FileManagePage page = new FileManagePage(browser); FileManagePage page = new FileManagePage(browser);
browser.navigate().refresh(); browser.navigate().refresh();

51
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/FunctionManageE2ETest.java

@ -83,28 +83,32 @@ public class FunctionManageE2ETest {
@BeforeAll @BeforeAll
@SneakyThrows @SneakyThrows
public static void setup() { public static void setup() {
// TenantPage tenantPage = new LoginPage(browser) TenantPage tenantPage = new LoginPage(browser)
// .login(user, password) .login(user, password)
// .create(tenant); .goToNav(SecurityPage.class)
// .goToTab(TenantPage.class)
// await().untilAsserted(() -> assertThat(tenantPage.tenantList()) .create(tenant);
// .as("Tenant list should contain newly-created tenant")
// .extracting(WebElement::getText) await().untilAsserted(() -> assertThat(tenantPage.tenantList())
// .anyMatch(it -> it.contains(tenant))); .as("Tenant list should contain newly-created tenant")
// .extracting(WebElement::getText)
// downloadFile("https://repo1.maven.org/maven2/org/apache/hive/hive-jdbc/3.1.2/hive-jdbc-3.1.2.jar", testUploadUdfFilePath.toFile().getAbsolutePath()); .anyMatch(it -> it.contains(tenant)));
//
// UdfManagePage udfManagePage = tenantPage.goToNav(SecurityPage.class) downloadFile("https://repo1.maven.org/maven2/org/apache/hive/hive-jdbc/3.1.2/hive-jdbc-3.1.2.jar", testUploadUdfFilePath.toFile().getAbsolutePath());
// .goToTab(UserPage.class)
// .update(user, user, password, email, phone) UserPage userPage = tenantPage.goToNav(SecurityPage.class)
// .goToNav(ResourcePage.class) .goToTab(UserPage.class);
// .goToTab(UdfManagePage.class)
// .uploadFile(testUploadUdfFilePath.toFile().getAbsolutePath()); new WebDriverWait(userPage.driver(), 20).until(ExpectedConditions.visibilityOfElementLocated(
// new By.ByClassName("name")));
// new WebDriverWait(browser, 10).until(ExpectedConditions.invisibilityOfElementLocated(By.id("fileUpdateDialog")));
// UdfManagePage udfManagePage = userPage.update(user, user, password, email, phone, tenant)
// udfManagePage.goToNav(ResourcePage.class) .goToNav(ResourcePage.class)
// .goToTab(FunctionManagePage.class); .goToTab(UdfManagePage.class)
.uploadFile(testUploadUdfFilePath.toFile().getAbsolutePath());
udfManagePage.goToNav(ResourcePage.class)
.goToTab(FunctionManagePage.class);
} }
@AfterAll @AfterAll
@ -141,9 +145,6 @@ public class FunctionManageE2ETest {
void testCreateUdfFunction() { void testCreateUdfFunction() {
FunctionManagePage page = new FunctionManagePage(browser); FunctionManagePage page = new FunctionManagePage(browser);
new WebDriverWait(page.driver(), 10)
.until(ExpectedConditions.elementToBeClickable(By.id("btnCreateUdfFunction")));
page.createUdfFunction(testUdfFunctionName, testClassName, testUploadUdfFileName, testDescription); page.createUdfFunction(testUdfFunctionName, testClassName, testUploadUdfFileName, testDescription);
await().untilAsserted(() -> assertThat(page.functionList()) await().untilAsserted(() -> assertThat(page.functionList())

38
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UdfManageE2ETest.java

@ -80,20 +80,26 @@ public class UdfManageE2ETest {
@BeforeAll @BeforeAll
public static void setup() { public static void setup() {
// TenantPage tenantPage = new LoginPage(browser) TenantPage tenantPage = new LoginPage(browser)
// .login(user, password) .login(user, password)
// .create(tenant); .goToNav(SecurityPage.class)
// .goToTab(TenantPage.class)
// await().untilAsserted(() -> assertThat(tenantPage.tenantList()) .create(tenant);
// .as("Tenant list should contain newly-created tenant")
// .extracting(WebElement::getText) await().untilAsserted(() -> assertThat(tenantPage.tenantList())
// .anyMatch(it -> it.contains(tenant))); .as("Tenant list should contain newly-created tenant")
// .extracting(WebElement::getText)
// tenantPage.goToNav(SecurityPage.class) .anyMatch(it -> it.contains(tenant)));
// .goToTab(UserPage.class)
// .update(user, user, password, email, phone) UserPage userPage = tenantPage.goToNav(SecurityPage.class)
// .goToNav(ResourcePage.class) .goToTab(UserPage.class);
// .goToTab(UdfManagePage.class);
new WebDriverWait(userPage.driver(), 20).until(ExpectedConditions.visibilityOfElementLocated(
new By.ByClassName("name")));
userPage.update(user, user, password, email, phone, tenant)
.goToNav(ResourcePage.class)
.goToTab(UdfManagePage.class);
} }
@AfterAll @AfterAll
@ -113,7 +119,7 @@ public class UdfManageE2ETest {
final UdfManagePage page = new UdfManagePage(browser); final UdfManagePage page = new UdfManagePage(browser);
new WebDriverWait(page.driver(), 10) new WebDriverWait(page.driver(), 10)
.until(ExpectedConditions.urlContains("/#/resource/udf")); .until(ExpectedConditions.urlContains("/resource-manage"));
page.createDirectory(testDirectoryName, "test_desc"); page.createDirectory(testDirectoryName, "test_desc");
@ -168,8 +174,6 @@ public class UdfManageE2ETest {
page.uploadFile(testUploadUdfFilePath.toFile().getAbsolutePath()); page.uploadFile(testUploadUdfFilePath.toFile().getAbsolutePath());
new WebDriverWait(browser, 10).until(ExpectedConditions.invisibilityOfElementLocated(By.id("fileUpdateDialog")));
await().untilAsserted(() -> { await().untilAsserted(() -> {
assertThat(page.udfList()) assertThat(page.udfList())
.as("File list should contain newly-created file") .as("File list should contain newly-created file")

42
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/UserE2ETest.java

@ -37,6 +37,8 @@ import org.junit.jupiter.api.Test;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") @DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml")
class UserE2ETest { class UserE2ETest {
@ -115,7 +117,12 @@ class UserE2ETest {
void testEditUser() { void testEditUser() {
UserPage page = new UserPage(browser); UserPage page = new UserPage(browser);
page.update(user, editUser, editPassword, editEmail, editPhone); new WebDriverWait(browser, 20).until(ExpectedConditions.visibilityOfElementLocated(
new By.ByClassName("name")));
browser.navigate().refresh();
page.update(user, editUser, editPassword, editEmail, editPhone, tenant);
await().untilAsserted(() -> { await().untilAsserted(() -> {
browser.navigate().refresh(); browser.navigate().refresh();
@ -125,23 +132,22 @@ class UserE2ETest {
.anyMatch(it -> it.contains(editUser)); .anyMatch(it -> it.contains(editUser));
}); });
} }
@Test
@Order(40)
void testDeleteUser() {
final UserPage page = new UserPage(browser);
page.delete(editUser);
// @Test await().untilAsserted(() -> {
// @Order(40) browser.navigate().refresh();
// void testDeleteUser() {
// final UserPage page = new UserPage(browser); assertThat(
// page.userList()
// page.delete(editUser); ).noneMatch(
// it -> it.getText().contains(user) || it.getText().contains(editUser)
// await().untilAsserted(() -> { );
// browser.navigate().refresh(); });
// }
// assertThat(
// page.userList()
// ).noneMatch(
// it -> it.getText().contains(user) || it.getText().contains(editUser)
// );
// });
// }
} }

17
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/common/CodeEditor.java

@ -22,23 +22,34 @@ package org.apache.dolphinscheduler.e2e.pages.common;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import lombok.Getter; import lombok.Getter;
@Getter @Getter
public final class CodeEditor { public final class CodeEditor {
@FindBy(className = "CodeMirror") @FindBys({
@FindBy(className = "monaco-editor"),
@FindBy(className = "view-line"),
})
private WebElement editor; private WebElement editor;
private WebDriver driver;
public CodeEditor(WebDriver driver) { public CodeEditor(WebDriver driver) {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
this.driver = driver;
} }
public CodeEditor content(String content) { public CodeEditor content(String content) {
editor.findElement(By.className("CodeMirror-line")).click(); editor.click();
editor.findElement(By.tagName("textarea")).sendKeys(content);
Actions actions = new Actions(this.driver);
actions.moveToElement(editor).sendKeys(content).perform();
return this; return this;
} }

120
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/FileManagePage.java

@ -26,12 +26,16 @@ import org.apache.dolphinscheduler.e2e.pages.common.CodeEditor;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.LocalFileDetector; import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.FindBys;
import org.openqa.selenium.support.PageFactory; import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
@ -39,45 +43,46 @@ import java.util.List;
@Getter @Getter
public class FileManagePage extends NavBarPage implements ResourcePage.Tab { public class FileManagePage extends NavBarPage implements ResourcePage.Tab {
@FindBy(id = "btnCreateDirectory") @FindBy(className = "btn-create-directory")
private WebElement buttonCreateDirectory; private WebElement buttonCreateDirectory;
@FindBy(id = "btnCreateFile") @FindBy(className = "btn-create-file")
private WebElement buttonCreateFile; private WebElement buttonCreateFile;
@FindBy(id = "btnUploadFile") @FindBy(className = "btn-upload-file")
private WebElement buttonUploadFile; private WebElement buttonUploadFile;
private final CreateDirectoryBox createDirectoryBox; private final CreateDirectoryBox createDirectoryBox;
private final RenameDirectoryBox renameDirectoryBox; private final RenameBox renameBox;
private final CreateFileBox createFileBox; private final CreateFileBox createFileBox;
private final UploadFileBox uploadFileBox; private final UploadFileBox uploadFileBox;
private final EditFileBox editFileBox;
@FindBy(className = "items") @FindBy(className = "items")
private List<WebElement> fileList; private List<WebElement> fileList;
@FindBy(id = "delete")
private WebElement buttonDelete;
@FindBys({ @FindBys({
@FindBy(className = "el-popconfirm"), @FindBy(className = "n-popconfirm__action"),
@FindBy(className = "el-button--primary"), @FindBy(className = "n-button--primary-type"),
}) })
private List<WebElement> buttonConfirm; private WebElement buttonConfirm;
public FileManagePage(RemoteWebDriver driver) { public FileManagePage(RemoteWebDriver driver) {
super(driver); super(driver);
createDirectoryBox = new CreateDirectoryBox(); createDirectoryBox = new CreateDirectoryBox();
renameDirectoryBox = new RenameDirectoryBox(); renameBox = new RenameBox();
createFileBox = new CreateFileBox(); createFileBox = new CreateFileBox();
uploadFileBox = new UploadFileBox(); uploadFileBox = new UploadFileBox();
editFileBox = new EditFileBox();
} }
public FileManagePage createDirectory(String name, String description) { public FileManagePage createDirectory(String name, String description) {
@ -104,15 +109,16 @@ public class FileManagePage extends NavBarPage implements ResourcePage.Tab {
fileList() fileList()
.stream() .stream()
.filter(it -> it.getText().contains(currentName)) .filter(it -> it.getText().contains(currentName))
.flatMap(it -> it.findElements(By.id("btnRename")).stream()) .flatMap(it -> it.findElements(By.className("btn-rename")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("No rename button in file manage list")) .orElseThrow(() -> new RuntimeException("No rename button in file manage list"))
.click(); .click();
renameDirectoryBox().inputName().clear(); renameBox().inputName().sendKeys(Keys.CONTROL + "a");
renameDirectoryBox().inputName().sendKeys(AfterName); renameBox().inputName().sendKeys(Keys.BACK_SPACE);
renameDirectoryBox().buttonSubmit().click(); renameBox().inputName().sendKeys(AfterName);
renameBox().buttonSubmit().click();
return this; return this;
} }
@ -139,18 +145,13 @@ public class FileManagePage extends NavBarPage implements ResourcePage.Tab {
fileList() fileList()
.stream() .stream()
.filter(it -> it.getText().contains(name)) .filter(it -> it.getText().contains(name))
.flatMap(it -> it.findElements(By.id("delete")).stream()) .flatMap(it -> it.findElements(By.className("btn-delete")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("No delete button in file manage list")) .orElseThrow(() -> new RuntimeException("No delete button in file manage list"))
.click(); .click();
buttonConfirm() ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
.stream()
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No confirm button when deleting"))
.click();
return this; return this;
} }
@ -169,14 +170,16 @@ public class FileManagePage extends NavBarPage implements ResourcePage.Tab {
fileList() fileList()
.stream() .stream()
.filter(it -> it.getText().contains(fileName)) .filter(it -> it.getText().contains(fileName))
.flatMap(it -> it.findElements(By.id("btnEdit")).stream()) .flatMap(it -> it.findElements(By.className("btn-edit")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("No edit button in file manage list")) .orElseThrow(() -> new RuntimeException("No edit button in file manage list"))
.click(); .click();
createFileBox().codeEditor().content(scripts); new WebDriverWait(driver, 5).until(ExpectedConditions.urlContains("/edit"));
createFileBox().buttonSubmit().click();
editFileBox().codeEditor().content(scripts);
editFileBox().buttonSubmit().click();
return this; return this;
} }
@ -196,7 +199,7 @@ public class FileManagePage extends NavBarPage implements ResourcePage.Tab {
fileList() fileList()
.stream() .stream()
.filter(it -> it.getText().contains(fileName)) .filter(it -> it.getText().contains(fileName))
.flatMap(it -> it.findElements(By.id("btnDownload")).stream()) .flatMap(it -> it.findElements(By.className("btn-download")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("No download button in file manage list")) .orElseThrow(() -> new RuntimeException("No download button in file manage list"))
@ -211,35 +214,47 @@ public class FileManagePage extends NavBarPage implements ResourcePage.Tab {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBy(id = "inputDirectoryName") @FindBys({
@FindBy(className = "input-directory-name"),
@FindBy(tagName = "input"),
})
private WebElement inputDirectoryName; private WebElement inputDirectoryName;
@FindBy(id = "inputDescription") @FindBys({
@FindBy(className = "input-description"),
@FindBy(tagName = "textarea"),
})
private WebElement inputDescription; private WebElement inputDescription;
@FindBy(id = "btnSubmit") @FindBy(className = "btn-submit")
private WebElement buttonSubmit; private WebElement buttonSubmit;
@FindBy(id = "btnCancel") @FindBy(className = "btn-cancel")
private WebElement buttonCancel; private WebElement buttonCancel;
} }
@Getter @Getter
public class RenameDirectoryBox { public class RenameBox {
RenameDirectoryBox() { RenameBox() {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBy(id = "inputName") @FindBys({
@FindBy(className = "input-name"),
@FindBy(tagName = "input"),
})
private WebElement inputName; private WebElement inputName;
@FindBy(id = "inputDescription") @FindBys({
@FindBy(className = "input-description"),
@FindBy(tagName = "textarea"),
})
private WebElement inputDescription; private WebElement inputDescription;
@FindBy(id = "btnSubmit") @FindBy(className = "btn-submit")
private WebElement buttonSubmit; private WebElement buttonSubmit;
@FindBy(id = "btnCancel") @FindBy(className = "btn-cancel")
private WebElement buttonCancel; private WebElement buttonCancel;
} }
@ -249,15 +264,33 @@ public class FileManagePage extends NavBarPage implements ResourcePage.Tab {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBy(id = "inputFileName") @FindBys({
@FindBy(className = "input-file-name"),
@FindBy(tagName = "input"),
})
private WebElement inputFileName; private WebElement inputFileName;
private final CodeEditor codeEditor = new CodeEditor(driver); private final CodeEditor codeEditor = new CodeEditor(driver);
@FindBy(id = "btnSubmit") @FindBy(className = "btn-submit")
private WebElement buttonSubmit;
@FindBy(className = "btn-cancel")
private WebElement buttonCancel;
}
@Getter
public class EditFileBox {
EditFileBox() {
PageFactory.initElements(driver, this);
}
CodeEditor codeEditor = new CodeEditor(driver);
@FindBy(className = "btn-submit")
private WebElement buttonSubmit; private WebElement buttonSubmit;
@FindBy(id = "btnCancel") @FindBy(className = "btn-cancel")
private WebElement buttonCancel; private WebElement buttonCancel;
} }
@ -267,13 +300,16 @@ public class FileManagePage extends NavBarPage implements ResourcePage.Tab {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBy(id = "btnUpload") @FindBys({
@FindBy(className = "btn-upload"),
@FindBy(tagName = "input"),
})
private WebElement buttonUpload; private WebElement buttonUpload;
@FindBy(id = "btnSubmit") @FindBy(className = "btn-submit")
private WebElement buttonSubmit; private WebElement buttonSubmit;
@FindBy(id = "btnCancel") @FindBy(className = "btn-cancel")
private WebElement buttonCancel; private WebElement buttonCancel;
} }
} }

84
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/FunctionManagePage.java

@ -27,6 +27,8 @@ import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import java.util.List; import java.util.List;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.FindBy;
@ -37,17 +39,17 @@ import org.openqa.selenium.support.ui.WebDriverWait;
@Getter @Getter
public class FunctionManagePage extends NavBarPage implements ResourcePage.Tab { public class FunctionManagePage extends NavBarPage implements ResourcePage.Tab {
@FindBy(id = "btnCreateUdfFunction") @FindBy(className = "btn-create-udf-function")
private WebElement buttonCreateUdfFunction; private WebElement buttonCreateUdfFunction;
@FindBy(className = "udf-function-items") @FindBy(className = "items")
private List<WebElement> functionList; private List<WebElement> functionList;
@FindBys({ @FindBys({
@FindBy(className = "el-popconfirm"), @FindBy(className = "n-popconfirm__action"),
@FindBy(className = "el-button--primary"), @FindBy(className = "n-button--primary-type"),
}) })
private List<WebElement> buttonConfirm; private WebElement buttonConfirm;
private final CreateUdfFunctionBox createUdfFunctionBox; private final CreateUdfFunctionBox createUdfFunctionBox;
@ -64,6 +66,8 @@ public class FunctionManagePage extends NavBarPage implements ResourcePage.Tab {
public FunctionManagePage createUdfFunction(String udfFunctionName, String className, String udfResourceName, String description) { public FunctionManagePage createUdfFunction(String udfFunctionName, String className, String udfResourceName, String description) {
buttonCreateUdfFunction().click(); buttonCreateUdfFunction().click();
createUdfFunctionBox().radioFunctionType().click();
createUdfFunctionBox().inputFunctionName().sendKeys(udfFunctionName); createUdfFunctionBox().inputFunctionName().sendKeys(udfFunctionName);
createUdfFunctionBox().inputClassName().sendKeys(className); createUdfFunctionBox().inputClassName().sendKeys(className);
@ -74,7 +78,7 @@ public class FunctionManagePage extends NavBarPage implements ResourcePage.Tab {
createUdfFunctionBox().selectUdfResource() createUdfFunctionBox().selectUdfResource()
.stream() .stream()
.filter(it -> it.getText().contains(udfResourceName)) .filter(it -> it.getAttribute("innerHTML").contains(udfResourceName))
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException(String.format("No %s in udf resource list", udfResourceName))) .orElseThrow(() -> new RuntimeException(String.format("No %s in udf resource list", udfResourceName)))
.click(); .click();
@ -88,16 +92,14 @@ public class FunctionManagePage extends NavBarPage implements ResourcePage.Tab {
functionList() functionList()
.stream() .stream()
.filter(it -> it.getText().contains(currentName)) .filter(it -> it.getText().contains(currentName))
.flatMap(it -> it.findElements(By.id("btnRename")).stream()) .flatMap(it -> it.findElements(By.className("btn-edit")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("No rename button in function manage list")) .orElseThrow(() -> new RuntimeException("No rename button in function manage list"))
.click(); .click();
new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.id("createUdfDialog"))); renameUdfFunctionBox().inputFunctionName().sendKeys(Keys.CONTROL + "a");
renameUdfFunctionBox().inputFunctionName().sendKeys(Keys.BACK_SPACE);
renameUdfFunctionBox().inputFunctionName().clear();
renameUdfFunctionBox().inputFunctionName().sendKeys(afterName); renameUdfFunctionBox().inputFunctionName().sendKeys(afterName);
renameUdfFunctionBox.buttonSubmit().click(); renameUdfFunctionBox.buttonSubmit().click();
@ -109,18 +111,13 @@ public class FunctionManagePage extends NavBarPage implements ResourcePage.Tab {
functionList() functionList()
.stream() .stream()
.filter(it -> it.getText().contains(udfFunctionName)) .filter(it -> it.getText().contains(udfFunctionName))
.flatMap(it -> it.findElements(By.id("btnDelete")).stream()) .flatMap(it -> it.findElements(By.className("btn-delete")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("No delete button in udf resource list")) .orElseThrow(() -> new RuntimeException("No delete button in udf resource list"))
.click(); .click();
buttonConfirm() ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
.stream()
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No confirm button when deleting in udf resource page"))
.click();
return this; return this;
} }
@ -131,25 +128,43 @@ public class FunctionManagePage extends NavBarPage implements ResourcePage.Tab {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBy(id = "inputFunctionName") @FindBys({
@FindBy(className = "radio-function-type"),
@FindBy(tagName = "input"),
})
private WebElement radioFunctionType;
@FindBys({
@FindBy(className = "input-function-name"),
@FindBy(tagName = "input"),
})
private WebElement inputFunctionName; private WebElement inputFunctionName;
@FindBy(id = "inputClassName") @FindBys({
@FindBy(className = "input-class-name"),
@FindBy(tagName = "input"),
})
private WebElement inputClassName; private WebElement inputClassName;
@FindBy(id = "btnUdfResourceDropDown") @FindBys({
@FindBy(className = "btn-udf-resource-dropdown"),
@FindBy(className = "n-base-selection"),
})
private WebElement buttonUdfResourceDropDown; private WebElement buttonUdfResourceDropDown;
@FindBy(className = "vue-treeselect__menu") @FindBy(className = "n-tree-node-content__text")
private List<WebElement> selectUdfResource; private List<WebElement> selectUdfResource;
@FindBy(id = "inputDescription") @FindBys({
@FindBy(className = "input-description"),
@FindBy(tagName = "textarea"),
})
private WebElement inputDescription; private WebElement inputDescription;
@FindBy(id = "btnSubmit") @FindBy(className = "btn-submit")
private WebElement buttonSubmit; private WebElement buttonSubmit;
@FindBy(id = "btnCancel") @FindBy(className = "btn-cancel")
private WebElement buttonCancel; private WebElement buttonCancel;
} }
@ -159,19 +174,28 @@ public class FunctionManagePage extends NavBarPage implements ResourcePage.Tab {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBy(id = "inputFunctionName") @FindBys({
@FindBy(className = "input-function-name"),
@FindBy(tagName = "input"),
})
private WebElement inputFunctionName; private WebElement inputFunctionName;
@FindBy(id = "inputClassName") @FindBys({
@FindBy(className = "input-class-name"),
@FindBy(tagName = "input"),
})
private WebElement inputClassName; private WebElement inputClassName;
@FindBy(id = "inputDescription") @FindBys({
@FindBy(className = "input-description"),
@FindBy(tagName = "textarea"),
})
private WebElement inputDescription; private WebElement inputDescription;
@FindBy(id = "btnSubmit") @FindBy(className = "btn-submit")
private WebElement buttonSubmit; private WebElement buttonSubmit;
@FindBy(id = "btnCancel") @FindBy(className = "btn-cancel")
private WebElement buttonCancel; private WebElement buttonCancel;
} }
} }

18
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/ResourcePage.java

@ -32,13 +32,13 @@ import org.openqa.selenium.support.ui.WebDriverWait;
@Getter @Getter
public class ResourcePage extends NavBarPage implements NavBarPage.NavBarItem { public class ResourcePage extends NavBarPage implements NavBarPage.NavBarItem {
@FindBy(className = "tab-file-manage") @FindBy(css = ".tab-vertical > .n-menu-item:nth-child(1) > .n-menu-item-content")
private WebElement fileManageTab; private WebElement fileManageTab;
@FindBy(className = "tab-udf-resource-manage") @FindBy(css = ".tab-vertical .n-submenu:nth-of-type(2) .n-menu-item:nth-of-type(1) > .n-menu-item-content")
private WebElement udfManageTab; private WebElement udfManageTab;
@FindBy(className = "tab-function-resource-manage") @FindBy(css = ".tab-vertical .n-submenu:nth-of-type(2) .n-menu-item:nth-of-type(2) > .n-menu-item-content")
private WebElement functionManageTab; private WebElement functionManageTab;
public ResourcePage(RemoteWebDriver driver) { public ResourcePage(RemoteWebDriver driver) {
@ -47,20 +47,20 @@ public class ResourcePage extends NavBarPage implements NavBarPage.NavBarItem {
public <T extends ResourcePage.Tab> T goToTab(Class<T> tab) { public <T extends ResourcePage.Tab> T goToTab(Class<T> tab) {
if (tab == FileManagePage.class) { if (tab == FileManagePage.class) {
WebElement fileManageTabElement = new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(fileManageTab)); new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(fileManageTab));
fileManageTabElement.click(); fileManageTab.click();
return tab.cast(new FileManagePage(driver)); return tab.cast(new FileManagePage(driver));
} }
if (tab == UdfManagePage.class) { if (tab == UdfManagePage.class) {
WebElement udfManageTabElement = new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(udfManageTab)); new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(udfManageTab));
udfManageTabElement.click(); udfManageTab.click();
return tab.cast(new UdfManagePage(driver)); return tab.cast(new UdfManagePage(driver));
} }
if (tab == FunctionManagePage.class) { if (tab == FunctionManagePage.class) {
WebElement functionManageTabElement = new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(functionManageTab)); new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(functionManageTab));
functionManageTabElement.click(); functionManageTab.click();
return tab.cast(new FunctionManagePage(driver)); return tab.cast(new FunctionManagePage(driver));
} }

63
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/resource/UdfManagePage.java

@ -27,6 +27,7 @@ import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import java.util.List; import java.util.List;
import org.openqa.selenium.By; import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement; import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.LocalFileDetector; import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver; import org.openqa.selenium.remote.RemoteWebDriver;
@ -36,20 +37,20 @@ import org.openqa.selenium.support.PageFactory;
@Getter @Getter
public class UdfManagePage extends NavBarPage implements ResourcePage.Tab { public class UdfManagePage extends NavBarPage implements ResourcePage.Tab {
@FindBy(id = "btnCreateDirectory") @FindBy(className = "btn-create-directory")
private WebElement buttonCreateDirectory; private WebElement buttonCreateDirectory;
@FindBy(id = "btnUploadUdf") @FindBy(className = "btn-upload-udf")
private WebElement buttonUploadUdf; private WebElement buttonUploadUdf;
@FindBy(className = "udf-items") @FindBy(className = "items")
private List<WebElement> udfList; private List<WebElement> udfList;
@FindBys({ @FindBys({
@FindBy(className = "el-popconfirm"), @FindBy(className = "n-popconfirm__action"),
@FindBy(className = "el-button--primary"), @FindBy(className = "n-button--primary-type"),
}) })
private List<WebElement> buttonConfirm; private WebElement buttonConfirm;
private final UploadFileBox uploadFileBox; private final UploadFileBox uploadFileBox;
@ -92,7 +93,7 @@ public class UdfManagePage extends NavBarPage implements ResourcePage.Tab {
udfList() udfList()
.stream() .stream()
.filter(it -> it.getText().contains(fileName)) .filter(it -> it.getText().contains(fileName))
.flatMap(it -> it.findElements(By.id("btnDownload")).stream()) .flatMap(it -> it.findElements(By.className("btn-download")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("No download button in udf manage list")) .orElseThrow(() -> new RuntimeException("No download button in udf manage list"))
@ -105,7 +106,7 @@ public class UdfManagePage extends NavBarPage implements ResourcePage.Tab {
udfList() udfList()
.stream() .stream()
.filter(it -> it.getText().contains(currentName)) .filter(it -> it.getText().contains(currentName))
.flatMap(it -> it.findElements(By.id("btnRename")).stream()) .flatMap(it -> it.findElements(By.className("btn-edit")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("No rename button in udf manage list")) .orElseThrow(() -> new RuntimeException("No rename button in udf manage list"))
@ -122,18 +123,13 @@ public class UdfManagePage extends NavBarPage implements ResourcePage.Tab {
udfList() udfList()
.stream() .stream()
.filter(it -> it.getText().contains(name)) .filter(it -> it.getText().contains(name))
.flatMap(it -> it.findElements(By.id("btnDelete")).stream()) .flatMap(it -> it.findElements(By.className("btn-delete")).stream())
.filter(WebElement::isDisplayed) .filter(WebElement::isDisplayed)
.findFirst() .findFirst()
.orElseThrow(() -> new RuntimeException("No delete button in udf manage list")) .orElseThrow(() -> new RuntimeException("No delete button in udf manage list"))
.click(); .click();
buttonConfirm() ((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
.stream()
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("No confirm button when deleting"))
.click();
return this; return this;
} }
@ -144,16 +140,22 @@ public class UdfManagePage extends NavBarPage implements ResourcePage.Tab {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBy(id = "inputName") @FindBys({
@FindBy(className = "input-directory-name"),
@FindBy(tagName = "input"),
})
private WebElement inputName; private WebElement inputName;
@FindBy(id = "inputDescription") @FindBys({
@FindBy(className = "input-description"),
@FindBy(tagName = "textarea"),
})
private WebElement inputDescription; private WebElement inputDescription;
@FindBy(id = "btnSubmit") @FindBy(className = "btn-submit")
private WebElement buttonSubmit; private WebElement buttonSubmit;
@FindBy(id = "btnCancel") @FindBy(className = "btn-cancel")
private WebElement buttonCancel; private WebElement buttonCancel;
} }
@ -163,13 +165,16 @@ public class UdfManagePage extends NavBarPage implements ResourcePage.Tab {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBy(id = "btnUpload") @FindBys({
@FindBy(className = "btn-upload"),
@FindBy(tagName = "input"),
})
private WebElement buttonUpload; private WebElement buttonUpload;
@FindBy(id = "btnSubmit") @FindBy(className = "btn-submit")
private WebElement buttonSubmit; private WebElement buttonSubmit;
@FindBy(id = "btnCancel") @FindBy(className = "btn-cancel")
private WebElement buttonCancel; private WebElement buttonCancel;
} }
@ -179,16 +184,22 @@ public class UdfManagePage extends NavBarPage implements ResourcePage.Tab {
PageFactory.initElements(driver, this); PageFactory.initElements(driver, this);
} }
@FindBy(id = "inputDirectoryName") @FindBys({
@FindBy(className = "input-directory-name"),
@FindBy(tagName = "input"),
})
private WebElement inputDirectoryName; private WebElement inputDirectoryName;
@FindBy(id = "inputDescription") @FindBys({
@FindBy(className = "input-description"),
@FindBy(tagName = "textarea"),
})
private WebElement inputDescription; private WebElement inputDescription;
@FindBy(id = "btnSubmit") @FindBy(className = "btn-submit")
private WebElement buttonSubmit; private WebElement buttonSubmit;
@FindBy(id = "btnCancel") @FindBy(className = "btn-cancel")
private WebElement buttonCancel; private WebElement buttonCancel;
} }
} }

15
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/security/UserPage.java

@ -83,7 +83,8 @@ public final class UserPage extends NavBarPage implements SecurityPage.Tab {
return this; return this;
} }
public UserPage update(String user, String editUser, String editPassword, String editEmail, String editPhone) { public UserPage update(String user, String editUser, String editPassword, String editEmail, String editPhone,
String tenant) {
userList().stream() userList().stream()
.filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(user)) .filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").contains(user))
.flatMap(it -> it.findElements(By.className("edit")).stream()) .flatMap(it -> it.findElements(By.className("edit")).stream())
@ -98,6 +99,18 @@ public final class UserPage extends NavBarPage implements SecurityPage.Tab {
editUserForm().inputUserPassword().sendKeys(editPassword); editUserForm().inputUserPassword().sendKeys(editPassword);
createUserForm().btnSelectTenantDropdown().click();
new WebDriverWait(driver, 5).until(ExpectedConditions.visibilityOfElementLocated(new By.ByClassName(
"n-base-select-option__content")));
createUserForm().selectTenant()
.stream()
.filter(it -> it.getText().contains(tenant))
.findFirst()
.orElseThrow(() -> new RuntimeException(String.format("No %s in tenant dropdown list", tenant)))
.click();
editUserForm().inputEmail().sendKeys(Keys.CONTROL+"a"); editUserForm().inputEmail().sendKeys(Keys.CONTROL+"a");
editUserForm().inputEmail().sendKeys(Keys.BACK_SPACE); editUserForm().inputEmail().sendKeys(Keys.BACK_SPACE);
editUserForm().inputEmail().sendKeys(editEmail); editUserForm().inputEmail().sendKeys(editEmail);

6
dolphinscheduler-ui-next/src/views/resource/file/create/index.tsx

@ -77,6 +77,7 @@ export default defineComponent({
v-model={[this.fileForm.fileName, 'value']} v-model={[this.fileForm.fileName, 'value']}
placeholder={t('resource.file.enter_name_tips')} placeholder={t('resource.file.enter_name_tips')}
style={{ width: '300px' }} style={{ width: '300px' }}
class='input-file-name'
/> />
</NFormItem> </NFormItem>
<NFormItem label={t('resource.file.file_format')} path='suffix'> <NFormItem label={t('resource.file.file_format')} path='suffix'>
@ -85,6 +86,7 @@ export default defineComponent({
v-model={[this.fileForm.suffix, 'value']} v-model={[this.fileForm.suffix, 'value']}
options={this.fileSuffixOptions} options={this.fileSuffixOptions}
style={{ width: '100px' }} style={{ width: '100px' }}
class='select-file-format'
/> />
</NFormItem> </NFormItem>
<NFormItem label={t('resource.file.description')} path='description'> <NFormItem label={t('resource.file.description')} path='description'>
@ -93,6 +95,7 @@ export default defineComponent({
v-model={[this.fileForm.description, 'value']} v-model={[this.fileForm.description, 'value']}
placeholder={t('resource.file.enter_description_tips')} placeholder={t('resource.file.enter_description_tips')}
style={{ width: '430px' }} style={{ width: '430px' }}
class='input-description'
/> />
</NFormItem> </NFormItem>
<NFormItem label={t('resource.file.file_content')} path='content'> <NFormItem label={t('resource.file.file_content')} path='content'>
@ -106,7 +109,7 @@ export default defineComponent({
</NFormItem> </NFormItem>
<div class={styles['file-edit-content']}> <div class={styles['file-edit-content']}>
<div class={styles.submit}> <div class={styles.submit}>
<NButton type='info' size='small' round onClick={this.handleFile}> <NButton type='info' size='small' round onClick={this.handleFile} class='btn-submit'>
{t('resource.file.save')} {t('resource.file.save')}
</NButton> </NButton>
<NButton <NButton
@ -115,6 +118,7 @@ export default defineComponent({
text text
style={{ marginLeft: '15px' }} style={{ marginLeft: '15px' }}
onClick={this.handleReturn} onClick={this.handleReturn}
class='btn-cancel'
> >
{t('resource.file.return')} {t('resource.file.return')}
</NButton> </NButton>

2
dolphinscheduler-ui-next/src/views/resource/file/edit/index.tsx

@ -89,6 +89,7 @@ export default defineComponent({
text text
style={{ marginRight: '15px' }} style={{ marginRight: '15px' }}
onClick={this.handleReturn} onClick={this.handleReturn}
class='btn-cancel'
> >
{t('resource.file.return')} {t('resource.file.return')}
</NButton> </NButton>
@ -97,6 +98,7 @@ export default defineComponent({
size='small' size='small'
round round
onClick={() => this.handleFileContent()} onClick={() => this.handleFileContent()}
class='btn-submit'
> >
{t('resource.file.save')} {t('resource.file.save')}
</NButton> </NButton>

4
dolphinscheduler-ui-next/src/views/resource/file/folder/index.tsx

@ -59,6 +59,8 @@ export default defineComponent({
title={t('resource.file.create_folder')} title={t('resource.file.create_folder')}
onCancel={this.hideModal} onCancel={this.hideModal}
onConfirm={this.handleFolder} onConfirm={this.handleFolder}
confirmClassName='btn-submit'
cancelClassName='btn-cancel'
> >
<NForm <NForm
rules={this.rules} rules={this.rules}
@ -70,6 +72,7 @@ export default defineComponent({
<NInput <NInput
v-model={[this.folderForm.name, 'value']} v-model={[this.folderForm.name, 'value']}
placeholder={t('resource.file.enter_name_tips')} placeholder={t('resource.file.enter_name_tips')}
class='input-directory-name'
/> />
</NFormItem> </NFormItem>
<NFormItem label={t('resource.file.description')} path='description'> <NFormItem label={t('resource.file.description')} path='description'>
@ -77,6 +80,7 @@ export default defineComponent({
type='textarea' type='textarea'
v-model={[this.folderForm.description, 'value']} v-model={[this.folderForm.description, 'value']}
placeholder={t('resource.file.enter_description_tips')} placeholder={t('resource.file.enter_description_tips')}
class='input-description'
/> />
</NFormItem> </NFormItem>
</NForm> </NForm>

7
dolphinscheduler-ui-next/src/views/resource/file/index.tsx

@ -188,13 +188,13 @@ export default defineComponent({
<div class={styles['conditions-model']}> <div class={styles['conditions-model']}>
<NSpace> <NSpace>
<NButtonGroup> <NButtonGroup>
<NButton onClick={handleCreateFolder}> <NButton onClick={handleCreateFolder} class="btn-create-directory">
{t('resource.file.create_folder')} {t('resource.file.create_folder')}
</NButton> </NButton>
<NButton onClick={handleCreateFile}> <NButton onClick={handleCreateFile} class="btn-create-file">
{t('resource.file.create_file')} {t('resource.file.create_file')}
</NButton> </NButton>
<NButton onClick={handleUploadFile}> <NButton onClick={handleUploadFile} class="btn-upload-file">
{t('resource.file.upload_files')} {t('resource.file.upload_files')}
</NButton> </NButton>
</NButtonGroup> </NButtonGroup>
@ -226,6 +226,7 @@ export default defineComponent({
striped striped
size={'small'} size={'small'}
class={styles['table-box']} class={styles['table-box']}
row-class-name='items'
/> />
<div class={styles.pagination}> <div class={styles.pagination}>
<NPagination <NPagination

4
dolphinscheduler-ui-next/src/views/resource/file/rename/index.tsx

@ -75,6 +75,8 @@ export default defineComponent({
title={t('resource.file.rename')} title={t('resource.file.rename')}
onCancel={this.hideModal} onCancel={this.hideModal}
onConfirm={this.handleFile} onConfirm={this.handleFile}
confirmClassName='btn-submit'
cancelClassName='btn-cancel'
> >
<NForm <NForm
rules={this.rules} rules={this.rules}
@ -86,6 +88,7 @@ export default defineComponent({
<NInput <NInput
v-model={[this.renameForm.name, 'value']} v-model={[this.renameForm.name, 'value']}
placeholder={t('resource.file.enter_name_tips')} placeholder={t('resource.file.enter_name_tips')}
class='input-name'
/> />
</NFormItem> </NFormItem>
<NFormItem label={t('resource.file.description')} path='description'> <NFormItem label={t('resource.file.description')} path='description'>
@ -93,6 +96,7 @@ export default defineComponent({
type='textarea' type='textarea'
v-model={[this.renameForm.description, 'value']} v-model={[this.renameForm.description, 'value']}
placeholder={t('resource.file.enter_description_tips')} placeholder={t('resource.file.enter_description_tips')}
class='input-description'
/> />
</NFormItem> </NFormItem>
</NForm> </NForm>

5
dolphinscheduler-ui-next/src/views/resource/file/table/table-action.tsx

@ -102,6 +102,7 @@ export default defineComponent({
}} }}
style={{ marginRight: '-5px' }} style={{ marginRight: '-5px' }}
circle circle
class='btn-edit'
> >
<NIcon> <NIcon>
<FormOutlined /> <FormOutlined />
@ -126,6 +127,7 @@ export default defineComponent({
} }
style={{ marginRight: '-5px' }} style={{ marginRight: '-5px' }}
circle circle
class="btn-rename"
> >
<NIcon> <NIcon>
<EditOutlined /> <EditOutlined />
@ -146,6 +148,7 @@ export default defineComponent({
circle circle
style={{ marginRight: '-5px' }} style={{ marginRight: '-5px' }}
onClick={() => downloadResource(this.row.id)} onClick={() => downloadResource(this.row.id)}
class='btn-download'
> >
<NIcon> <NIcon>
<DownloadOutlined /> <DownloadOutlined />
@ -158,7 +161,7 @@ export default defineComponent({
{{ {{
default: () => t('resource.file.delete'), default: () => t('resource.file.delete'),
trigger: () => ( trigger: () => (
<NButton size='tiny' type='error' circle> <NButton size='tiny' type='error' circle class='btn-delete'>
<NPopconfirm <NPopconfirm
positive-text={t('resource.file.confirm')} positive-text={t('resource.file.confirm')}
negative-text={t('resource.file.cancel')} negative-text={t('resource.file.cancel')}

5
dolphinscheduler-ui-next/src/views/resource/file/upload/index.tsx

@ -65,6 +65,8 @@ export default defineComponent({
title={t('resource.file.upload_files')} title={t('resource.file.upload_files')}
onCancel={this.hideModal} onCancel={this.hideModal}
onConfirm={this.handleFile} onConfirm={this.handleFile}
confirmClassName='btn-submit'
cancelClassName='btn-cancel'
> >
<NForm <NForm
rules={this.rules} rules={this.rules}
@ -76,6 +78,7 @@ export default defineComponent({
<NInput <NInput
v-model={[this.uploadForm.name, 'value']} v-model={[this.uploadForm.name, 'value']}
placeholder={t('resource.file.enter_name_tips')} placeholder={t('resource.file.enter_name_tips')}
class='input-file-name'
/> />
</NFormItem> </NFormItem>
<NFormItem label={t('resource.file.description')} path='description'> <NFormItem label={t('resource.file.description')} path='description'>
@ -83,12 +86,14 @@ export default defineComponent({
type='textarea' type='textarea'
v-model={[this.uploadForm.description, 'value']} v-model={[this.uploadForm.description, 'value']}
placeholder={t('resource.file.enter_description_tips')} placeholder={t('resource.file.enter_description_tips')}
class='input-description'
/> />
</NFormItem> </NFormItem>
<NFormItem label={t('resource.file.upload_files')} path='file'> <NFormItem label={t('resource.file.upload_files')} path='file'>
<NUpload <NUpload
v-model={[this.uploadForm.file, 'value']} v-model={[this.uploadForm.file, 'value']}
customRequest={this.customRequest} customRequest={this.customRequest}
class='btn-upload'
> >
<NButton>{t('resource.file.upload_files')}</NButton> <NButton>{t('resource.file.upload_files')}</NButton>
</NUpload> </NUpload>

8
dolphinscheduler-ui-next/src/views/resource/udf/function/components/function-modal.tsx

@ -124,6 +124,8 @@ export default defineComponent({
} }
onCancel={this.hideModal} onCancel={this.hideModal}
onConfirm={this.row.id ? this.handleRename : this.handleCreate} onConfirm={this.row.id ? this.handleRename : this.handleCreate}
confirmClassName='btn-submit'
cancelClassName='btn-cancel'
> >
<NForm <NForm
rules={this.rules} rules={this.rules}
@ -135,6 +137,7 @@ export default defineComponent({
<NRadioGroup <NRadioGroup
v-model={[this.functionForm.type, 'value']} v-model={[this.functionForm.type, 'value']}
name='type' name='type'
class='radio-function-type'
> >
<NRadio value='HIVE'>HIVE UDF</NRadio> <NRadio value='HIVE'>HIVE UDF</NRadio>
</NRadioGroup> </NRadioGroup>
@ -146,6 +149,7 @@ export default defineComponent({
<NInput <NInput
v-model={[this.functionForm.funcName, 'value']} v-model={[this.functionForm.funcName, 'value']}
placeholder={t('resource.function.enter_udf_unction_name_tips')} placeholder={t('resource.function.enter_udf_unction_name_tips')}
class='input-function-name'
/> />
</NFormItem> </NFormItem>
<NFormItem <NFormItem
@ -155,6 +159,7 @@ export default defineComponent({
<NInput <NInput
v-model={[this.functionForm.className, 'value']} v-model={[this.functionForm.className, 'value']}
placeholder={t('resource.function.enter_package_name_tips')} placeholder={t('resource.function.enter_package_name_tips')}
class='input-class-name'
/> />
</NFormItem> </NFormItem>
<NFormItem <NFormItem
@ -173,6 +178,7 @@ export default defineComponent({
defaultValue={this.functionForm.resourceId} defaultValue={this.functionForm.resourceId}
disabled={this.uploadShow} disabled={this.uploadShow}
showPath={false} showPath={false}
class='btn-udf-resource-dropdown'
></NTreeSelect> ></NTreeSelect>
<NButton <NButton
type='primary' type='primary'
@ -244,6 +250,7 @@ export default defineComponent({
type='textarea' type='textarea'
v-model={[this.uploadForm.description, 'value']} v-model={[this.uploadForm.description, 'value']}
placeholder={t('resource.function.enter_description_tips')} placeholder={t('resource.function.enter_description_tips')}
class='input-description'
/> />
</NFormItem> </NFormItem>
<NFormItem label=' '> <NFormItem label=' '>
@ -260,6 +267,7 @@ export default defineComponent({
type='textarea' type='textarea'
v-model={[this.functionForm.description, 'value']} v-model={[this.functionForm.description, 'value']}
placeholder={t('resource.function.enter_instructions_tips')} placeholder={t('resource.function.enter_instructions_tips')}
class='input-description'
/> />
</NFormItem> </NFormItem>
</NForm> </NForm>

3
dolphinscheduler-ui-next/src/views/resource/udf/function/index.tsx

@ -94,7 +94,7 @@ export default defineComponent({
<Card class={styles.card}> <Card class={styles.card}>
<div class={styles.header}> <div class={styles.header}>
<NSpace> <NSpace>
<NButton type='primary' onClick={this.handleCreateFolder}> <NButton type='primary' onClick={this.handleCreateFolder} class='btn-create-udf-function'>
{t('resource.function.create_udf_function')} {t('resource.function.create_udf_function')}
</NButton> </NButton>
</NSpace> </NSpace>
@ -124,6 +124,7 @@ export default defineComponent({
striped striped
size={'small'} size={'small'}
class={styles.table} class={styles.table}
row-class-name='items'
/> />
<div class={styles.pagination}> <div class={styles.pagination}>
<NPagination <NPagination

4
dolphinscheduler-ui-next/src/views/resource/udf/function/use-table.ts

@ -94,6 +94,7 @@ export function useTable() {
circle: true, circle: true,
type: 'info', type: 'info',
size: 'tiny', size: 'tiny',
class: 'btn-edit',
onClick: () => { onClick: () => {
handleEdit(row) handleEdit(row)
} }
@ -124,7 +125,8 @@ export function useTable() {
{ {
circle: true, circle: true,
type: 'error', type: 'error',
size: 'tiny' size: 'tiny',
class: 'btn-delete'
}, },
{ {
icon: () => h(DeleteOutlined) icon: () => h(DeleteOutlined)

4
dolphinscheduler-ui-next/src/views/resource/udf/resource/components/folder-modal.tsx

@ -79,6 +79,8 @@ export default defineComponent({
title={t('resource.udf.create_folder')} title={t('resource.udf.create_folder')}
onCancel={this.hideModal} onCancel={this.hideModal}
onConfirm={this.row.id ? this.handleRename : this.handleCreate} onConfirm={this.row.id ? this.handleRename : this.handleCreate}
confirmClassName='btn-submit'
cancelClassName='btn-cancel'
> >
<NForm <NForm
rules={this.rules} rules={this.rules}
@ -90,6 +92,7 @@ export default defineComponent({
<NInput <NInput
v-model={[this.folderForm.name, 'value']} v-model={[this.folderForm.name, 'value']}
placeholder={t('resource.udf.enter_name_tips')} placeholder={t('resource.udf.enter_name_tips')}
class='input-directory-name'
/> />
</NFormItem> </NFormItem>
<NFormItem label={t('resource.udf.description')} path='description'> <NFormItem label={t('resource.udf.description')} path='description'>
@ -97,6 +100,7 @@ export default defineComponent({
type='textarea' type='textarea'
v-model={[this.folderForm.description, 'value']} v-model={[this.folderForm.description, 'value']}
placeholder={t('resource.udf.enter_description_tips')} placeholder={t('resource.udf.enter_description_tips')}
class='input-description'
/> />
</NFormItem> </NFormItem>
</NForm> </NForm>

5
dolphinscheduler-ui-next/src/views/resource/udf/resource/components/upload-modal.tsx

@ -66,6 +66,8 @@ export default defineComponent({
title={t('resource.udf.file_upload')} title={t('resource.udf.file_upload')}
onCancel={this.hideModal} onCancel={this.hideModal}
onConfirm={this.handleFolder} onConfirm={this.handleFolder}
confirmClassName='btn-submit'
cancelClassName='btn-cancel'
> >
<NForm <NForm
rules={this.rules} rules={this.rules}
@ -77,6 +79,7 @@ export default defineComponent({
<NInput <NInput
v-model={[this.uploadForm.name, 'value']} v-model={[this.uploadForm.name, 'value']}
placeholder={t('resource.udf.enter_name_tips')} placeholder={t('resource.udf.enter_name_tips')}
class='input-file-name'
/> />
</NFormItem> </NFormItem>
<NFormItem label={t('resource.udf.description')} path='description'> <NFormItem label={t('resource.udf.description')} path='description'>
@ -84,12 +87,14 @@ export default defineComponent({
type='textarea' type='textarea'
v-model={[this.uploadForm.description, 'value']} v-model={[this.uploadForm.description, 'value']}
placeholder={t('resource.udf.enter_description_tips')} placeholder={t('resource.udf.enter_description_tips')}
class='input-description'
/> />
</NFormItem> </NFormItem>
<NFormItem label={t('resource.udf.upload_files')} path='file'> <NFormItem label={t('resource.udf.upload_files')} path='file'>
<NUpload <NUpload
v-model={[this.uploadForm.file, 'value']} v-model={[this.uploadForm.file, 'value']}
customRequest={this.customRequest} customRequest={this.customRequest}
class='btn-upload'
> >
<NButton> <NButton>
{t('resource.udf.upload')} {t('resource.udf.upload')}

5
dolphinscheduler-ui-next/src/views/resource/udf/resource/index.tsx

@ -115,10 +115,10 @@ export default defineComponent({
<Card class={styles.card}> <Card class={styles.card}>
<div class={styles.header}> <div class={styles.header}>
<NSpace> <NSpace>
<NButton type='primary' onClick={this.handleCreateFolder}> <NButton type='primary' onClick={this.handleCreateFolder} class='btn-create-directory'>
{t('resource.udf.create_folder')} {t('resource.udf.create_folder')}
</NButton> </NButton>
<NButton strong secondary onClick={this.handleUploadFile}> <NButton strong secondary onClick={this.handleUploadFile} class='btn-upload-udf'>
{t('resource.udf.upload_udf_resources')} {t('resource.udf.upload_udf_resources')}
</NButton> </NButton>
</NSpace> </NSpace>
@ -151,6 +151,7 @@ export default defineComponent({
striped striped
size={'small'} size={'small'}
class={styles.table} class={styles.table}
row-class-name='items'
/> />
<div class={styles.pagination}> <div class={styles.pagination}>
<NPagination <NPagination

5
dolphinscheduler-ui-next/src/views/resource/udf/resource/use-table.ts

@ -131,6 +131,7 @@ export function useTable() {
circle: true, circle: true,
type: 'info', type: 'info',
size: 'tiny', size: 'tiny',
class: 'btn-edit',
onClick: () => { onClick: () => {
handleEdit(row) handleEdit(row)
} }
@ -154,6 +155,7 @@ export function useTable() {
circle: true, circle: true,
type: 'info', type: 'info',
size: 'tiny', size: 'tiny',
class: 'btn-download',
disabled: row?.directory ? true : false, disabled: row?.directory ? true : false,
onClick: () => downloadResource(row.id) onClick: () => downloadResource(row.id)
}, },
@ -184,7 +186,8 @@ export function useTable() {
tag: 'div', tag: 'div',
circle: true, circle: true,
type: 'error', type: 'error',
size: 'tiny' size: 'tiny',
class: 'btn-delete',
}, },
{ {
icon: () => h(DeleteOutlined) icon: () => h(DeleteOutlined)

4
dolphinscheduler-ui-next/src/views/security/user-manage/use-columns.ts

@ -43,7 +43,8 @@ export function useColumns(onCallback: Function) {
}, },
{ {
title: t('security.user.username'), title: t('security.user.username'),
key: 'userName' key: 'userName',
className: 'name'
}, },
{ {
title: t('security.user.user_type'), title: t('security.user.user_type'),
@ -157,6 +158,7 @@ export function useColumns(onCallback: Function) {
circle: true, circle: true,
type: 'info', type: 'info',
size: 'small', size: 'small',
class: 'edit',
onClick: () => void onCallback({ rowData }, 'edit') onClick: () => void onCallback({ rowData }, 'edit')
}, },
() => h(NIcon, null, () => h(EditOutlined)) () => h(NIcon, null, () => h(EditOutlined))

Loading…
Cancel
Save