kezhenxu94
3 years ago
committed by
GitHub
44 changed files with 1861 additions and 486 deletions
@ -0,0 +1,68 @@ |
|||||||
|
/* |
||||||
|
* Licensed to Apache Software Foundation (ASF) under one or more contributor |
||||||
|
* license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright |
||||||
|
* ownership. Apache Software Foundation (ASF) licenses this file to you under |
||||||
|
* the Apache License, Version 2.0 (the "License"); you may |
||||||
|
* not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, |
||||||
|
* software distributed under the License is distributed on an |
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
* KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations |
||||||
|
* under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.apache.dolphinscheduler.e2e.cases; |
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat; |
||||||
|
import static org.awaitility.Awaitility.await; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.LoginPage; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.ProjectPage; |
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeAll; |
||||||
|
import org.junit.jupiter.api.Order; |
||||||
|
import org.junit.jupiter.api.Test; |
||||||
|
import org.openqa.selenium.remote.RemoteWebDriver; |
||||||
|
|
||||||
|
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") |
||||||
|
class ProjectE2ETest { |
||||||
|
private static final String project = "test-project-1"; |
||||||
|
|
||||||
|
private static RemoteWebDriver browser; |
||||||
|
|
||||||
|
@BeforeAll |
||||||
|
public static void setup() { |
||||||
|
new LoginPage(browser) |
||||||
|
.login("admin", "dolphinscheduler123") |
||||||
|
.goToNav(ProjectPage.class); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
@Order(1) |
||||||
|
void testCreateProject() { |
||||||
|
new ProjectPage(browser).create(project); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
@Order(30) |
||||||
|
void testDeleteProject() { |
||||||
|
final var page = new ProjectPage(browser); |
||||||
|
page.delete(project); |
||||||
|
|
||||||
|
await().untilAsserted(() -> { |
||||||
|
browser.navigate().refresh(); |
||||||
|
assertThat( |
||||||
|
page.projectList() |
||||||
|
).noneMatch( |
||||||
|
it -> it.getText().contains(project) |
||||||
|
); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,88 @@ |
|||||||
|
/* |
||||||
|
* Licensed to Apache Software Foundation (ASF) under one or more contributor |
||||||
|
* license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright |
||||||
|
* ownership. Apache Software Foundation (ASF) licenses this file to you under |
||||||
|
* the Apache License, Version 2.0 (the "License"); you may |
||||||
|
* not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, |
||||||
|
* software distributed under the License is distributed on an |
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
* KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations |
||||||
|
* under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.apache.dolphinscheduler.e2e.cases; |
||||||
|
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat; |
||||||
|
import static org.awaitility.Awaitility.await; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.LoginPage; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.security.TenantPage; |
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeAll; |
||||||
|
import org.junit.jupiter.api.Order; |
||||||
|
import org.junit.jupiter.api.Test; |
||||||
|
import org.openqa.selenium.By; |
||||||
|
import org.openqa.selenium.remote.RemoteWebDriver; |
||||||
|
|
||||||
|
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") |
||||||
|
class TenantE2ETest { |
||||||
|
private static final String tenant = System.getProperty("user.name"); |
||||||
|
|
||||||
|
private static RemoteWebDriver browser; |
||||||
|
|
||||||
|
@BeforeAll |
||||||
|
public static void setup() { |
||||||
|
new LoginPage(browser) |
||||||
|
.login("admin", "dolphinscheduler123") |
||||||
|
.goToNav(SecurityPage.class) |
||||||
|
.goToTab(TenantPage.class) |
||||||
|
; |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
@Order(10) |
||||||
|
void testCreateTenant() { |
||||||
|
new TenantPage(browser).create(tenant); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
@Order(20) |
||||||
|
void testCreateDuplicateTenant() { |
||||||
|
final var page = new TenantPage(browser); |
||||||
|
|
||||||
|
page.create(tenant); |
||||||
|
|
||||||
|
await().untilAsserted(() -> |
||||||
|
assertThat(browser.findElement(By.tagName("body")).getText()) |
||||||
|
.contains("already exists") |
||||||
|
); |
||||||
|
|
||||||
|
page.createTenantForm().buttonCancel().click(); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
@Order(30) |
||||||
|
void testDeleteTenant() { |
||||||
|
final var page = new TenantPage(browser); |
||||||
|
page.delete(tenant); |
||||||
|
|
||||||
|
await().untilAsserted(() -> { |
||||||
|
browser.navigate().refresh(); |
||||||
|
assertThat( |
||||||
|
page.tenantList() |
||||||
|
).noneMatch( |
||||||
|
it -> it.getText().contains(tenant) |
||||||
|
); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,200 @@ |
|||||||
|
/* |
||||||
|
* Licensed to Apache Software Foundation (ASF) under one or more contributor |
||||||
|
* license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright |
||||||
|
* ownership. Apache Software Foundation (ASF) licenses this file to you under |
||||||
|
* the Apache License, Version 2.0 (the "License"); you may |
||||||
|
* not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, |
||||||
|
* software distributed under the License is distributed on an |
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
* KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations |
||||||
|
* under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.apache.dolphinscheduler.e2e.cases; |
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat; |
||||||
|
import static org.awaitility.Awaitility.await; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.LoginPage; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.ProjectPage; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowDefinitionTab; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm.TaskType; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowInstanceTab; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowInstanceTab.Row; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.ShellTaskForm; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.SubWorkflowTaskForm; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.security.TenantPage; |
||||||
|
|
||||||
|
import org.junit.jupiter.api.AfterAll; |
||||||
|
import org.junit.jupiter.api.BeforeAll; |
||||||
|
import org.junit.jupiter.api.Order; |
||||||
|
import org.junit.jupiter.api.Test; |
||||||
|
import org.openqa.selenium.remote.RemoteWebDriver; |
||||||
|
|
||||||
|
@DolphinScheduler(composeFiles = "docker/basic/docker-compose.yaml") |
||||||
|
class WorkflowE2ETest { |
||||||
|
private static final String project = "test-workflow-1"; |
||||||
|
private static final String tenant = System.getProperty("user.name"); |
||||||
|
|
||||||
|
private static RemoteWebDriver browser; |
||||||
|
|
||||||
|
@BeforeAll |
||||||
|
public static void setup() { |
||||||
|
new LoginPage(browser) |
||||||
|
.login("admin", "dolphinscheduler123") |
||||||
|
.goToNav(SecurityPage.class) |
||||||
|
.goToTab(TenantPage.class) |
||||||
|
.create(tenant) |
||||||
|
.goToNav(ProjectPage.class) |
||||||
|
.create(project) |
||||||
|
; |
||||||
|
} |
||||||
|
|
||||||
|
@AfterAll |
||||||
|
public static void cleanup() { |
||||||
|
new NavBarPage(browser) |
||||||
|
.goToNav(ProjectPage.class) |
||||||
|
.goTo(project) |
||||||
|
.goToTab(WorkflowDefinitionTab.class) |
||||||
|
.cancelPublishAll() |
||||||
|
.deleteAll() |
||||||
|
; |
||||||
|
new NavBarPage(browser) |
||||||
|
.goToNav(ProjectPage.class) |
||||||
|
.delete(project) |
||||||
|
.goToNav(SecurityPage.class) |
||||||
|
.goToTab(TenantPage.class) |
||||||
|
.delete(tenant) |
||||||
|
; |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
@Order(1) |
||||||
|
void testCreateWorkflow() { |
||||||
|
final var workflow = "test-workflow-1"; |
||||||
|
|
||||||
|
final var workflowDefinitionPage = |
||||||
|
new ProjectPage(browser) |
||||||
|
.goTo(project) |
||||||
|
.goToTab(WorkflowDefinitionTab.class); |
||||||
|
|
||||||
|
workflowDefinitionPage |
||||||
|
.createWorkflow() |
||||||
|
|
||||||
|
.<ShellTaskForm> addTask(TaskType.SHELL) |
||||||
|
.script("echo ${today}\necho ${global_param}\n") |
||||||
|
.name("test-1") |
||||||
|
.addParam("today", "${system.datetime}") |
||||||
|
.submit() |
||||||
|
|
||||||
|
.submit() |
||||||
|
.name(workflow) |
||||||
|
.tenant(tenant) |
||||||
|
.addGlobalParam("global_param", "hello world") |
||||||
|
.submit() |
||||||
|
; |
||||||
|
|
||||||
|
await().untilAsserted(() -> assertThat( |
||||||
|
workflowDefinitionPage.workflowList() |
||||||
|
).anyMatch(it -> it.getText().contains(workflow))); |
||||||
|
|
||||||
|
workflowDefinitionPage.publish(workflow); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
@Order(10) |
||||||
|
void testCreateSubWorkflow() { |
||||||
|
final var workflow = "test-sub-workflow-1"; |
||||||
|
|
||||||
|
final var workflowDefinitionPage = |
||||||
|
new ProjectPage(browser) |
||||||
|
.goToNav(ProjectPage.class) |
||||||
|
.goTo(project) |
||||||
|
.goToTab(WorkflowDefinitionTab.class); |
||||||
|
|
||||||
|
workflowDefinitionPage |
||||||
|
.createWorkflow() |
||||||
|
|
||||||
|
.<SubWorkflowTaskForm> addTask(TaskType.SUB_PROCESS) |
||||||
|
.submit() |
||||||
|
|
||||||
|
.submit() |
||||||
|
.name(workflow) |
||||||
|
.tenant(tenant) |
||||||
|
.addGlobalParam("global_param", "hello world") |
||||||
|
.submit() |
||||||
|
; |
||||||
|
|
||||||
|
await().untilAsserted(() -> assertThat( |
||||||
|
workflowDefinitionPage.workflowList() |
||||||
|
).anyMatch(it -> it.getText().contains(workflow))); |
||||||
|
|
||||||
|
workflowDefinitionPage.publish(workflow); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
@Order(30) |
||||||
|
void testRunWorkflow() { |
||||||
|
final var workflow = "test-workflow-1"; |
||||||
|
|
||||||
|
final var projectPage = |
||||||
|
new ProjectPage(browser) |
||||||
|
.goToNav(ProjectPage.class) |
||||||
|
.goTo(project); |
||||||
|
|
||||||
|
projectPage |
||||||
|
.goToTab(WorkflowInstanceTab.class) |
||||||
|
.deleteAll(); |
||||||
|
|
||||||
|
projectPage |
||||||
|
.goToTab(WorkflowDefinitionTab.class) |
||||||
|
.run(workflow) |
||||||
|
.submit(); |
||||||
|
|
||||||
|
await().untilAsserted(() -> { |
||||||
|
browser.navigate().refresh(); |
||||||
|
|
||||||
|
final Row row = projectPage |
||||||
|
.goToTab(WorkflowInstanceTab.class) |
||||||
|
.instances() |
||||||
|
.iterator() |
||||||
|
.next(); |
||||||
|
|
||||||
|
assertThat(row.isSuccess()).isTrue(); |
||||||
|
assertThat(row.executionTime()).isEqualTo(1); |
||||||
|
}); |
||||||
|
|
||||||
|
// Test rerun
|
||||||
|
projectPage |
||||||
|
.goToTab(WorkflowInstanceTab.class) |
||||||
|
.instances() |
||||||
|
.stream() |
||||||
|
.filter(it -> it.rerunButton().isDisplayed()) |
||||||
|
.iterator() |
||||||
|
.next() |
||||||
|
.rerun(); |
||||||
|
|
||||||
|
await().untilAsserted(() -> { |
||||||
|
browser.navigate().refresh(); |
||||||
|
|
||||||
|
final Row row = projectPage |
||||||
|
.goToTab(WorkflowInstanceTab.class) |
||||||
|
.instances() |
||||||
|
.iterator() |
||||||
|
.next(); |
||||||
|
|
||||||
|
assertThat(row.isSuccess()).isTrue(); |
||||||
|
assertThat(row.executionTime()).isEqualTo(2); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
@ -1,98 +0,0 @@ |
|||||||
/* |
|
||||||
* Licensed to Apache Software Foundation (ASF) under one or more contributor |
|
||||||
* license agreements. See the NOTICE file distributed with |
|
||||||
* this work for additional information regarding copyright |
|
||||||
* ownership. Apache Software Foundation (ASF) licenses this file to you under |
|
||||||
* the Apache License, Version 2.0 (the "License"); you may |
|
||||||
* not use this file except in compliance with the License. |
|
||||||
* You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, |
|
||||||
* software distributed under the License is distributed on an |
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
|
||||||
* KIND, either express or implied. See the License for the |
|
||||||
* specific language governing permissions and limitations |
|
||||||
* under the License. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.apache.dolphinscheduler.e2e.cases.security; |
|
||||||
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat; |
|
||||||
import static org.awaitility.Awaitility.await; |
|
||||||
|
|
||||||
import org.apache.dolphinscheduler.e2e.core.DolphinScheduler; |
|
||||||
import org.apache.dolphinscheduler.e2e.pages.LoginPage; |
|
||||||
import org.apache.dolphinscheduler.e2e.pages.TenantPage; |
|
||||||
|
|
||||||
import org.junit.jupiter.api.Order; |
|
||||||
import org.junit.jupiter.api.Test; |
|
||||||
import org.openqa.selenium.By; |
|
||||||
import org.openqa.selenium.WebElement; |
|
||||||
import org.openqa.selenium.remote.RemoteWebDriver; |
|
||||||
|
|
||||||
@DolphinScheduler(composeFiles = "docker/tenant/docker-compose.yaml") |
|
||||||
class TenantE2ETest { |
|
||||||
private RemoteWebDriver browser; |
|
||||||
|
|
||||||
@Test |
|
||||||
@Order(1) |
|
||||||
void testLogin() { |
|
||||||
final LoginPage page = new LoginPage(browser); |
|
||||||
page.inputUsername().sendKeys("admin"); |
|
||||||
page.inputPassword().sendKeys("dolphinscheduler123"); |
|
||||||
page.buttonLogin().click(); |
|
||||||
} |
|
||||||
|
|
||||||
@Test |
|
||||||
@Order(10) |
|
||||||
void testCreateTenant() { |
|
||||||
final TenantPage page = new TenantPage(browser); |
|
||||||
final String tenant = System.getProperty("user.name"); |
|
||||||
|
|
||||||
page.buttonCreateTenant().click(); |
|
||||||
page.createTenantForm().inputTenantCode().sendKeys(tenant); |
|
||||||
page.createTenantForm().inputDescription().sendKeys("Test"); |
|
||||||
page.createTenantForm().buttonSubmit().click(); |
|
||||||
|
|
||||||
await().untilAsserted(() -> assertThat(page.tenantList()) |
|
||||||
.as("Tenant list should contain newly-created tenant") |
|
||||||
.extracting(WebElement::getText) |
|
||||||
.anyMatch(it -> it.contains(tenant))); |
|
||||||
} |
|
||||||
|
|
||||||
@Test |
|
||||||
@Order(20) |
|
||||||
void testCreateDuplicateTenant() { |
|
||||||
final String tenant = System.getProperty("user.name"); |
|
||||||
final TenantPage page = new TenantPage(browser); |
|
||||||
page.buttonCreateTenant().click(); |
|
||||||
page.createTenantForm().inputTenantCode().sendKeys(tenant); |
|
||||||
page.createTenantForm().inputDescription().sendKeys("Test"); |
|
||||||
page.createTenantForm().buttonSubmit().click(); |
|
||||||
|
|
||||||
await().untilAsserted(() -> assertThat(browser.findElementByTagName("body") |
|
||||||
.getText().contains("already exists")) |
|
||||||
.as("Should fail when creating a duplicate tenant") |
|
||||||
.isTrue()); |
|
||||||
|
|
||||||
page.createTenantForm().buttonCancel().click(); |
|
||||||
} |
|
||||||
|
|
||||||
@Test |
|
||||||
@Order(30) |
|
||||||
void testDeleteTenant() { |
|
||||||
final String tenant = System.getProperty("user.name"); |
|
||||||
final TenantPage page = new TenantPage(browser); |
|
||||||
|
|
||||||
page.tenantList() |
|
||||||
.stream() |
|
||||||
.filter(it -> it.getText().contains(tenant)) |
|
||||||
.findFirst() |
|
||||||
.ifPresent(it -> it.findElement(By.className("delete")).click()); |
|
||||||
|
|
||||||
page.buttonConfirm().click(); |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,45 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
* or more contributor license agreements. See the NOTICE file |
||||||
|
* distributed with this work for additional information |
||||||
|
* regarding copyright ownership. The ASF licenses this file |
||||||
|
* to you under the Apache License, Version 2.0 (the |
||||||
|
* "License"); you may not use this file except in compliance |
||||||
|
* with the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, |
||||||
|
* software distributed under the License is distributed on an |
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
* KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations |
||||||
|
* under the License. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.e2e.pages.common; |
||||||
|
|
||||||
|
import org.openqa.selenium.By; |
||||||
|
import org.openqa.selenium.WebDriver; |
||||||
|
import org.openqa.selenium.WebElement; |
||||||
|
import org.openqa.selenium.support.FindBy; |
||||||
|
import org.openqa.selenium.support.PageFactory; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
|
||||||
|
@Getter |
||||||
|
public final class CodeEditor { |
||||||
|
@FindBy(className = "CodeMirror") |
||||||
|
private WebElement editor; |
||||||
|
|
||||||
|
public CodeEditor(WebDriver driver) { |
||||||
|
PageFactory.initElements(driver, this); |
||||||
|
} |
||||||
|
|
||||||
|
public CodeEditor content(String content) { |
||||||
|
editor.findElement(By.className("CodeMirror-line")).click(); |
||||||
|
editor.findElement(By.tagName("textarea")).sendKeys(content); |
||||||
|
|
||||||
|
return this; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,62 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
* or more contributor license agreements. See the NOTICE file |
||||||
|
* distributed with this work for additional information |
||||||
|
* regarding copyright ownership. The ASF licenses this file |
||||||
|
* to you under the Apache License, Version 2.0 (the |
||||||
|
* "License"); you may not use this file except in compliance |
||||||
|
* with the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, |
||||||
|
* software distributed under the License is distributed on an |
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
* KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations |
||||||
|
* under the License. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.e2e.pages.common; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.ProjectPage; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.security.SecurityPage; |
||||||
|
|
||||||
|
import org.openqa.selenium.WebElement; |
||||||
|
import org.openqa.selenium.remote.RemoteWebDriver; |
||||||
|
import org.openqa.selenium.support.FindBy; |
||||||
|
import org.openqa.selenium.support.PageFactory; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
|
||||||
|
@Getter |
||||||
|
public class NavBarPage { |
||||||
|
protected final RemoteWebDriver driver; |
||||||
|
|
||||||
|
@FindBy(id = "project-tab") |
||||||
|
private WebElement projectTab; |
||||||
|
@FindBy(id = "security-tab") |
||||||
|
private WebElement securityTab; |
||||||
|
|
||||||
|
public NavBarPage(RemoteWebDriver driver) { |
||||||
|
this.driver = driver; |
||||||
|
|
||||||
|
PageFactory.initElements(driver, this); |
||||||
|
} |
||||||
|
|
||||||
|
public <T extends NavBarItem> T goToNav(Class<T> nav) { |
||||||
|
if (nav == ProjectPage.class) { |
||||||
|
projectTab().click(); |
||||||
|
return nav.cast(new ProjectPage(driver)); |
||||||
|
} |
||||||
|
if (nav == SecurityPage.class) { |
||||||
|
securityTab().click(); |
||||||
|
return nav.cast(new SecurityPage(driver)); |
||||||
|
} |
||||||
|
|
||||||
|
throw new UnsupportedOperationException("Unknown nav bar"); |
||||||
|
} |
||||||
|
|
||||||
|
public interface NavBarItem { |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,58 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
* or more contributor license agreements. See the NOTICE file |
||||||
|
* distributed with this work for additional information |
||||||
|
* regarding copyright ownership. The ASF licenses this file |
||||||
|
* to you under the Apache License, Version 2.0 (the |
||||||
|
* "License"); you may not use this file except in compliance |
||||||
|
* with the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, |
||||||
|
* software distributed under the License is distributed on an |
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
* KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations |
||||||
|
* under the License. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.e2e.pages.project; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowDefinitionTab; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowInstanceTab; |
||||||
|
|
||||||
|
import org.openqa.selenium.WebElement; |
||||||
|
import org.openqa.selenium.remote.RemoteWebDriver; |
||||||
|
import org.openqa.selenium.support.FindBy; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
|
||||||
|
@Getter |
||||||
|
public final class ProjectDetailPage extends NavBarPage { |
||||||
|
@FindBy(className = "process-definition") |
||||||
|
private WebElement menuProcessDefinition; |
||||||
|
@FindBy(className = "process-instance") |
||||||
|
private WebElement menuProcessInstances; |
||||||
|
|
||||||
|
public ProjectDetailPage(RemoteWebDriver driver) { |
||||||
|
super(driver); |
||||||
|
} |
||||||
|
|
||||||
|
public <T extends Tab> T goToTab(Class<T> tab) { |
||||||
|
if (tab == WorkflowDefinitionTab.class) { |
||||||
|
menuProcessDefinition().click(); |
||||||
|
return tab.cast(new WorkflowDefinitionTab(driver)); |
||||||
|
} |
||||||
|
if (tab == WorkflowInstanceTab.class) { |
||||||
|
menuProcessInstances().click(); |
||||||
|
return tab.cast(new WorkflowInstanceTab(driver)); |
||||||
|
} |
||||||
|
|
||||||
|
throw new UnsupportedOperationException("Unknown tab: " + tab.getName()); |
||||||
|
} |
||||||
|
|
||||||
|
public interface Tab { |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,114 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
* or more contributor license agreements. See the NOTICE file |
||||||
|
* distributed with this work for additional information |
||||||
|
* regarding copyright ownership. The ASF licenses this file |
||||||
|
* to you under the Apache License, Version 2.0 (the |
||||||
|
* "License"); you may not use this file except in compliance |
||||||
|
* with the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, |
||||||
|
* software distributed under the License is distributed on an |
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
* KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations |
||||||
|
* under the License. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.e2e.pages.project; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage.NavBarItem; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import org.openqa.selenium.By; |
||||||
|
import org.openqa.selenium.WebElement; |
||||||
|
import org.openqa.selenium.remote.RemoteWebDriver; |
||||||
|
import org.openqa.selenium.support.FindBy; |
||||||
|
import org.openqa.selenium.support.FindBys; |
||||||
|
import org.openqa.selenium.support.PageFactory; |
||||||
|
import org.openqa.selenium.support.ui.ExpectedConditions; |
||||||
|
import org.openqa.selenium.support.ui.WebDriverWait; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
|
||||||
|
@Getter |
||||||
|
public final class ProjectPage extends NavBarPage implements NavBarItem { |
||||||
|
@FindBy(id = "button-create-project") |
||||||
|
private WebElement buttonCreateProject; |
||||||
|
|
||||||
|
@FindBy(className = "rows-project") |
||||||
|
private List<WebElement> projectList; |
||||||
|
|
||||||
|
@FindBys({ |
||||||
|
@FindBy(className = "el-popconfirm"), |
||||||
|
@FindBy(className = "el-button--primary"), |
||||||
|
}) |
||||||
|
private List<WebElement> buttonConfirm; |
||||||
|
|
||||||
|
private final CreateProjectForm createProjectForm; |
||||||
|
|
||||||
|
public ProjectPage(RemoteWebDriver driver) { |
||||||
|
super(driver); |
||||||
|
|
||||||
|
this.createProjectForm = new CreateProjectForm(); |
||||||
|
|
||||||
|
PageFactory.initElements(driver, this); |
||||||
|
} |
||||||
|
|
||||||
|
public ProjectPage create(String project) { |
||||||
|
buttonCreateProject().click(); |
||||||
|
createProjectForm().inputProjectName().sendKeys(project); |
||||||
|
createProjectForm().buttonSubmit().click(); |
||||||
|
|
||||||
|
new WebDriverWait(driver(), 10) |
||||||
|
.until(ExpectedConditions.textToBePresentInElementLocated(By.className("project-name"), project)); |
||||||
|
|
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ProjectPage delete(String project) { |
||||||
|
projectList() |
||||||
|
.stream() |
||||||
|
.filter(it -> it.getText().contains(project)) |
||||||
|
.findFirst() |
||||||
|
.orElseThrow(() -> new RuntimeException("Cannot find project: " + project)) |
||||||
|
.findElement(By.className("delete")).click(); |
||||||
|
|
||||||
|
buttonConfirm() |
||||||
|
.stream() |
||||||
|
.filter(WebElement::isDisplayed) |
||||||
|
.findFirst() |
||||||
|
.orElseThrow(() -> new RuntimeException("No confirm button is displayed")) |
||||||
|
.click(); |
||||||
|
|
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public ProjectDetailPage goTo(String project) { |
||||||
|
projectList().stream() |
||||||
|
.filter(it -> it.getText().contains(project)) |
||||||
|
.map(it -> it.findElement(By.className("project-name"))) |
||||||
|
.findFirst() |
||||||
|
.orElseThrow(() -> new RuntimeException("Cannot click the project item")) |
||||||
|
.click(); |
||||||
|
|
||||||
|
return new ProjectDetailPage(driver); |
||||||
|
} |
||||||
|
|
||||||
|
@Getter |
||||||
|
public class CreateProjectForm { |
||||||
|
CreateProjectForm() { |
||||||
|
PageFactory.initElements(driver, this); |
||||||
|
} |
||||||
|
|
||||||
|
@FindBy(id = "input-project-name") |
||||||
|
private WebElement inputProjectName; |
||||||
|
|
||||||
|
@FindBy(id = "button-submit") |
||||||
|
private WebElement buttonSubmit; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,123 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
* or more contributor license agreements. See the NOTICE file |
||||||
|
* distributed with this work for additional information |
||||||
|
* regarding copyright ownership. The ASF licenses this file |
||||||
|
* to you under the Apache License, Version 2.0 (the |
||||||
|
* "License"); you may not use this file except in compliance |
||||||
|
* with the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, |
||||||
|
* software distributed under the License is distributed on an |
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
* KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations |
||||||
|
* under the License. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.e2e.pages.project.workflow; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.ProjectDetailPage; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import java.util.function.Supplier; |
||||||
|
import java.util.stream.Collectors; |
||||||
|
|
||||||
|
import org.openqa.selenium.By; |
||||||
|
import org.openqa.selenium.WebElement; |
||||||
|
import org.openqa.selenium.remote.RemoteWebDriver; |
||||||
|
import org.openqa.selenium.support.FindBy; |
||||||
|
import org.openqa.selenium.support.FindBys; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
|
||||||
|
@Getter |
||||||
|
public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDetailPage.Tab { |
||||||
|
@FindBy(id = "button-create-process") |
||||||
|
private WebElement buttonCreateProcess; |
||||||
|
@FindBy(className = "select-all") |
||||||
|
private WebElement checkBoxSelectAll; |
||||||
|
@FindBy(className = "button-delete-all") |
||||||
|
private WebElement buttonDeleteAll; |
||||||
|
@FindBys({ |
||||||
|
@FindBy(className = "el-popconfirm"), |
||||||
|
@FindBy(className = "el-button--primary"), |
||||||
|
}) |
||||||
|
private List<WebElement> buttonConfirm; |
||||||
|
@FindBy(className = "rows-workflow-definitions") |
||||||
|
private List<WebElement> workflowList; |
||||||
|
|
||||||
|
public WorkflowDefinitionTab(RemoteWebDriver driver) { |
||||||
|
super(driver); |
||||||
|
} |
||||||
|
|
||||||
|
public WorkflowForm createWorkflow() { |
||||||
|
buttonCreateProcess().click(); |
||||||
|
|
||||||
|
return new WorkflowForm(driver); |
||||||
|
} |
||||||
|
|
||||||
|
public WorkflowDefinitionTab publish(String workflow) { |
||||||
|
workflowList() |
||||||
|
.stream() |
||||||
|
.filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").equals(workflow)) |
||||||
|
.flatMap(it -> it.findElements(By.className("button-publish")).stream()) |
||||||
|
.filter(WebElement::isDisplayed) |
||||||
|
.findFirst() |
||||||
|
.orElseThrow(() -> new RuntimeException("Cannot find publish button in workflow definition")) |
||||||
|
.click(); |
||||||
|
|
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public WorkflowRunDialog run(String workflow) { |
||||||
|
workflowList() |
||||||
|
.stream() |
||||||
|
.filter(it -> it.findElement(By.className("name")).getAttribute("innerHTML").equals(workflow)) |
||||||
|
.flatMap(it -> it.findElements(By.className("button-run")).stream()) |
||||||
|
.filter(WebElement::isDisplayed) |
||||||
|
.findFirst() |
||||||
|
.orElseThrow(() -> new RuntimeException("Cannot find run button in workflow definition")) |
||||||
|
.click(); |
||||||
|
|
||||||
|
return new WorkflowRunDialog(this); |
||||||
|
} |
||||||
|
|
||||||
|
public WorkflowDefinitionTab cancelPublishAll() { |
||||||
|
final Supplier<List<WebElement>> cancelButtons = () -> |
||||||
|
workflowList() |
||||||
|
.stream() |
||||||
|
.flatMap(it -> it.findElements(By.className("button-cancel-publish")).stream()) |
||||||
|
.filter(WebElement::isDisplayed) |
||||||
|
.collect(Collectors.toList()); |
||||||
|
|
||||||
|
for (var buttons = cancelButtons.get(); |
||||||
|
!buttons.isEmpty(); |
||||||
|
buttons = cancelButtons.get()) { |
||||||
|
buttons.forEach(WebElement::click); |
||||||
|
driver().navigate().refresh(); |
||||||
|
} |
||||||
|
|
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public WorkflowDefinitionTab deleteAll() { |
||||||
|
if (workflowList().isEmpty()) { |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
checkBoxSelectAll().click(); |
||||||
|
buttonDeleteAll().click(); |
||||||
|
buttonConfirm() |
||||||
|
.stream() |
||||||
|
.filter(WebElement::isDisplayed) |
||||||
|
.findFirst() |
||||||
|
.orElseThrow(() -> new RuntimeException("No confirm button is displayed")) |
||||||
|
.click(); |
||||||
|
|
||||||
|
return this; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,85 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
* or more contributor license agreements. See the NOTICE file |
||||||
|
* distributed with this work for additional information |
||||||
|
* regarding copyright ownership. The ASF licenses this file |
||||||
|
* to you under the Apache License, Version 2.0 (the |
||||||
|
* "License"); you may not use this file except in compliance |
||||||
|
* with the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, |
||||||
|
* software distributed under the License is distributed on an |
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
* KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations |
||||||
|
* under the License. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.e2e.pages.project.workflow; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.ShellTaskForm; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.workflow.task.SubWorkflowTaskForm; |
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets; |
||||||
|
|
||||||
|
import org.openqa.selenium.By; |
||||||
|
import org.openqa.selenium.JavascriptExecutor; |
||||||
|
import org.openqa.selenium.WebDriver; |
||||||
|
import org.openqa.selenium.WebElement; |
||||||
|
import org.openqa.selenium.support.FindBy; |
||||||
|
import org.openqa.selenium.support.PageFactory; |
||||||
|
|
||||||
|
import com.google.common.io.Resources; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
import lombok.SneakyThrows; |
||||||
|
|
||||||
|
@SuppressWarnings("UnstableApiUsage") |
||||||
|
@Getter |
||||||
|
public final class WorkflowForm { |
||||||
|
private final WebDriver driver; |
||||||
|
private final WorkflowSaveDialog saveForm; |
||||||
|
|
||||||
|
@FindBy(id = "button-save") |
||||||
|
private WebElement buttonSave; |
||||||
|
|
||||||
|
public WorkflowForm(WebDriver driver) { |
||||||
|
this.driver = driver; |
||||||
|
this.saveForm = new WorkflowSaveDialog(this); |
||||||
|
|
||||||
|
PageFactory.initElements(driver, this); |
||||||
|
} |
||||||
|
|
||||||
|
@SneakyThrows |
||||||
|
@SuppressWarnings("unchecked") |
||||||
|
public <T> T addTask(TaskType type) { |
||||||
|
final var task = driver.findElement(By.className("task-item-" + type.name())); |
||||||
|
final var canvas = driver.findElement(By.className("dag-container")); |
||||||
|
|
||||||
|
final var js = (JavascriptExecutor) driver; |
||||||
|
final var dragAndDrop = String.join("\n", |
||||||
|
Resources.readLines(Resources.getResource("dragAndDrop.js"), StandardCharsets.UTF_8)); |
||||||
|
js.executeScript(dragAndDrop, task, canvas); |
||||||
|
|
||||||
|
switch (type) { |
||||||
|
case SHELL: |
||||||
|
return (T) new ShellTaskForm(this); |
||||||
|
case SUB_PROCESS: |
||||||
|
return (T) new SubWorkflowTaskForm(this); |
||||||
|
} |
||||||
|
throw new UnsupportedOperationException("Unknown task type"); |
||||||
|
} |
||||||
|
|
||||||
|
public WorkflowSaveDialog submit() { |
||||||
|
buttonSave().click(); |
||||||
|
|
||||||
|
return new WorkflowSaveDialog(this); |
||||||
|
} |
||||||
|
|
||||||
|
public enum TaskType { |
||||||
|
SHELL, |
||||||
|
SUB_PROCESS, |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,107 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
* or more contributor license agreements. See the NOTICE file |
||||||
|
* distributed with this work for additional information |
||||||
|
* regarding copyright ownership. The ASF licenses this file |
||||||
|
* to you under the Apache License, Version 2.0 (the |
||||||
|
* "License"); you may not use this file except in compliance |
||||||
|
* with the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, |
||||||
|
* software distributed under the License is distributed on an |
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
* KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations |
||||||
|
* under the License. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.e2e.pages.project.workflow; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.ProjectDetailPage; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import java.util.stream.Collectors; |
||||||
|
|
||||||
|
import org.openqa.selenium.By; |
||||||
|
import org.openqa.selenium.WebElement; |
||||||
|
import org.openqa.selenium.remote.RemoteWebDriver; |
||||||
|
import org.openqa.selenium.support.FindBy; |
||||||
|
import org.openqa.selenium.support.FindBys; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
import lombok.RequiredArgsConstructor; |
||||||
|
|
||||||
|
@Getter |
||||||
|
public final class WorkflowInstanceTab extends NavBarPage implements ProjectDetailPage.Tab { |
||||||
|
@FindBy(className = "rows-workflow-instances") |
||||||
|
private List<WebElement> instanceList; |
||||||
|
@FindBy(className = "select-all") |
||||||
|
private WebElement checkBoxSelectAll; |
||||||
|
@FindBy(className = "button-delete-all") |
||||||
|
private WebElement buttonDeleteAll; |
||||||
|
@FindBys({ |
||||||
|
@FindBy(className = "el-popconfirm"), |
||||||
|
@FindBy(className = "el-button--primary"), |
||||||
|
}) |
||||||
|
private List<WebElement> buttonConfirm; |
||||||
|
|
||||||
|
public WorkflowInstanceTab(RemoteWebDriver driver) { |
||||||
|
super(driver); |
||||||
|
} |
||||||
|
|
||||||
|
public List<Row> instances() { |
||||||
|
return instanceList() |
||||||
|
.stream() |
||||||
|
.filter(WebElement::isDisplayed) |
||||||
|
.map(Row::new) |
||||||
|
.collect(Collectors.toList()); |
||||||
|
} |
||||||
|
|
||||||
|
public WorkflowInstanceTab deleteAll() { |
||||||
|
if (instanceList().isEmpty()) { |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
checkBoxSelectAll().click(); |
||||||
|
buttonDeleteAll().click(); |
||||||
|
buttonConfirm() |
||||||
|
.stream() |
||||||
|
.filter(WebElement::isDisplayed) |
||||||
|
.findFirst() |
||||||
|
.orElseThrow(() -> new RuntimeException("No confirm button is displayed")) |
||||||
|
.click(); |
||||||
|
|
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
@RequiredArgsConstructor |
||||||
|
public static class Row { |
||||||
|
private final WebElement row; |
||||||
|
|
||||||
|
public WebElement rerunButton() { |
||||||
|
return row.findElement(By.className("button-rerun")); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isSuccess() { |
||||||
|
return !row.findElements(By.className("success")).isEmpty(); |
||||||
|
} |
||||||
|
|
||||||
|
public int executionTime() { |
||||||
|
return Integer.parseInt(row.findElement(By.className("execution-time")).getText()); |
||||||
|
} |
||||||
|
|
||||||
|
public Row rerun() { |
||||||
|
row.findElements(By.className("button-rerun")) |
||||||
|
.stream() |
||||||
|
.filter(WebElement::isDisplayed) |
||||||
|
.findFirst() |
||||||
|
.orElseThrow(() -> new RuntimeException("Cannot find rerun button")) |
||||||
|
.click(); |
||||||
|
|
||||||
|
return this; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,46 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
* or more contributor license agreements. See the NOTICE file |
||||||
|
* distributed with this work for additional information |
||||||
|
* regarding copyright ownership. The ASF licenses this file |
||||||
|
* to you under the Apache License, Version 2.0 (the |
||||||
|
* "License"); you may not use this file except in compliance |
||||||
|
* with the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, |
||||||
|
* software distributed under the License is distributed on an |
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
* KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations |
||||||
|
* under the License. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.e2e.pages.project.workflow; |
||||||
|
|
||||||
|
import org.openqa.selenium.WebElement; |
||||||
|
import org.openqa.selenium.support.FindBy; |
||||||
|
import org.openqa.selenium.support.PageFactory; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
|
||||||
|
@Getter |
||||||
|
public final class WorkflowRunDialog { |
||||||
|
private final WorkflowDefinitionTab parent; |
||||||
|
|
||||||
|
@FindBy(id = "button-submit") |
||||||
|
private WebElement buttonSubmit; |
||||||
|
|
||||||
|
public WorkflowRunDialog(WorkflowDefinitionTab parent) { |
||||||
|
this.parent = parent; |
||||||
|
|
||||||
|
PageFactory.initElements(parent().driver(), this); |
||||||
|
} |
||||||
|
|
||||||
|
public WorkflowDefinitionTab submit() { |
||||||
|
buttonSubmit().click(); |
||||||
|
|
||||||
|
return parent(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,115 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
* or more contributor license agreements. See the NOTICE file |
||||||
|
* distributed with this work for additional information |
||||||
|
* regarding copyright ownership. The ASF licenses this file |
||||||
|
* to you under the Apache License, Version 2.0 (the |
||||||
|
* "License"); you may not use this file except in compliance |
||||||
|
* with the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, |
||||||
|
* software distributed under the License is distributed on an |
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
* KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations |
||||||
|
* under the License. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.e2e.pages.project.workflow; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import java.util.stream.Stream; |
||||||
|
|
||||||
|
import org.openqa.selenium.By; |
||||||
|
import org.openqa.selenium.WebDriver; |
||||||
|
import org.openqa.selenium.WebElement; |
||||||
|
import org.openqa.selenium.support.FindBy; |
||||||
|
import org.openqa.selenium.support.FindBys; |
||||||
|
import org.openqa.selenium.support.PageFactory; |
||||||
|
import org.openqa.selenium.support.pagefactory.ByChained; |
||||||
|
import org.openqa.selenium.support.ui.ExpectedConditions; |
||||||
|
import org.openqa.selenium.support.ui.WebDriverWait; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
|
||||||
|
@Getter |
||||||
|
public final class WorkflowSaveDialog { |
||||||
|
private final WebDriver driver; |
||||||
|
private final WorkflowForm parent; |
||||||
|
|
||||||
|
@FindBy(id = "input-name") |
||||||
|
private WebElement inputName; |
||||||
|
@FindBy(id = "button-submit") |
||||||
|
private WebElement buttonSubmit; |
||||||
|
@FindBys({ |
||||||
|
@FindBy(className = "input-param-key"), |
||||||
|
@FindBy(tagName = "input"), |
||||||
|
}) |
||||||
|
private List<WebElement> inputParamKey; |
||||||
|
@FindBys({ |
||||||
|
@FindBy(className = "input-param-val"), |
||||||
|
@FindBy(tagName = "input"), |
||||||
|
}) |
||||||
|
private List<WebElement> inputParamVal; |
||||||
|
@FindBy(id = "select-tenant") |
||||||
|
private WebElement selectTenant; |
||||||
|
|
||||||
|
public WorkflowSaveDialog(WorkflowForm parent) { |
||||||
|
this.parent = parent; |
||||||
|
this.driver = parent.driver(); |
||||||
|
|
||||||
|
PageFactory.initElements(driver, this); |
||||||
|
} |
||||||
|
|
||||||
|
public WorkflowSaveDialog name(String name) { |
||||||
|
inputName().sendKeys(name); |
||||||
|
|
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public WorkflowSaveDialog tenant(String tenant) { |
||||||
|
selectTenant().click(); |
||||||
|
|
||||||
|
final var optionsLocator = By.className("option-tenants"); |
||||||
|
|
||||||
|
new WebDriverWait(driver, 10) |
||||||
|
.until(ExpectedConditions.visibilityOfElementLocated(optionsLocator)); |
||||||
|
|
||||||
|
driver().findElements(optionsLocator) |
||||||
|
.stream() |
||||||
|
.filter(it -> it.getText().contains(tenant)) |
||||||
|
.findFirst() |
||||||
|
.orElseThrow(() -> new RuntimeException("No such tenant: " + tenant)) |
||||||
|
.click() |
||||||
|
; |
||||||
|
|
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public WorkflowSaveDialog addGlobalParam(String key, String val) { |
||||||
|
assert inputParamKey().size() == inputParamVal().size(); |
||||||
|
|
||||||
|
final var len = inputParamKey().size(); |
||||||
|
|
||||||
|
final var driver = parent().driver(); |
||||||
|
Stream.concat( |
||||||
|
driver.findElements(new ByChained(By.className("user-def-params-model"), By.className("add"))).stream(), |
||||||
|
driver.findElements(new ByChained(By.className("user-def-params-model"), By.className("add-dp"))).stream()) |
||||||
|
.findFirst() |
||||||
|
.orElseThrow(() -> new RuntimeException("Cannot find button to add param")) |
||||||
|
.click(); |
||||||
|
|
||||||
|
inputParamKey().get(len).sendKeys(key); |
||||||
|
inputParamVal().get(len).sendKeys(val); |
||||||
|
|
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public WorkflowForm submit() { |
||||||
|
buttonSubmit().click(); |
||||||
|
|
||||||
|
return parent; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
* or more contributor license agreements. See the NOTICE file |
||||||
|
* distributed with this work for additional information |
||||||
|
* regarding copyright ownership. The ASF licenses this file |
||||||
|
* to you under the Apache License, Version 2.0 (the |
||||||
|
* "License"); you may not use this file except in compliance |
||||||
|
* with the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, |
||||||
|
* software distributed under the License is distributed on an |
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
* KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations |
||||||
|
* under the License. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.e2e.pages.project.workflow.task; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.e2e.pages.common.CodeEditor; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
|
||||||
|
@Getter |
||||||
|
public final class ShellTaskForm extends TaskNodeForm { |
||||||
|
private final CodeEditor codeEditor; |
||||||
|
|
||||||
|
public ShellTaskForm(WorkflowForm parent) { |
||||||
|
super(parent); |
||||||
|
|
||||||
|
this.codeEditor = new CodeEditor(parent.driver()); |
||||||
|
} |
||||||
|
|
||||||
|
public ShellTaskForm script(String script) { |
||||||
|
codeEditor().content(script); |
||||||
|
|
||||||
|
return this; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,31 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
* or more contributor license agreements. See the NOTICE file |
||||||
|
* distributed with this work for additional information |
||||||
|
* regarding copyright ownership. The ASF licenses this file |
||||||
|
* to you under the Apache License, Version 2.0 (the |
||||||
|
* "License"); you may not use this file except in compliance |
||||||
|
* with the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, |
||||||
|
* software distributed under the License is distributed on an |
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
* KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations |
||||||
|
* under the License. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.e2e.pages.project.workflow.task; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
|
||||||
|
@Getter |
||||||
|
public final class SubWorkflowTaskForm extends TaskNodeForm { |
||||||
|
public SubWorkflowTaskForm(WorkflowForm parent) { |
||||||
|
super(parent); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,93 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
* or more contributor license agreements. See the NOTICE file |
||||||
|
* distributed with this work for additional information |
||||||
|
* regarding copyright ownership. The ASF licenses this file |
||||||
|
* to you under the Apache License, Version 2.0 (the |
||||||
|
* "License"); you may not use this file except in compliance |
||||||
|
* with the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, |
||||||
|
* software distributed under the License is distributed on an |
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
* KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations |
||||||
|
* under the License. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.e2e.pages.project.workflow.task; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.e2e.pages.project.workflow.WorkflowForm; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import java.util.stream.Stream; |
||||||
|
|
||||||
|
import org.openqa.selenium.By; |
||||||
|
import org.openqa.selenium.WebElement; |
||||||
|
import org.openqa.selenium.support.FindBy; |
||||||
|
import org.openqa.selenium.support.FindBys; |
||||||
|
import org.openqa.selenium.support.PageFactory; |
||||||
|
import org.openqa.selenium.support.pagefactory.ByChained; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
|
||||||
|
@Getter |
||||||
|
public abstract class TaskNodeForm { |
||||||
|
@FindBy(id = "input-node-name") |
||||||
|
private WebElement inputNodeName; |
||||||
|
@FindBy(id = "button-submit") |
||||||
|
private WebElement buttonSubmit; |
||||||
|
@FindBys({ |
||||||
|
@FindBy(className = "input-param-key"), |
||||||
|
@FindBy(tagName = "input"), |
||||||
|
}) |
||||||
|
private List<WebElement> inputParamKey; |
||||||
|
@FindBys({ |
||||||
|
@FindBy(className = "input-param-val"), |
||||||
|
@FindBy(tagName = "input"), |
||||||
|
}) |
||||||
|
private List<WebElement> inputParamVal; |
||||||
|
|
||||||
|
private final WorkflowForm parent; |
||||||
|
|
||||||
|
TaskNodeForm(WorkflowForm parent) { |
||||||
|
this.parent = parent; |
||||||
|
|
||||||
|
final var driver = parent.driver(); |
||||||
|
|
||||||
|
PageFactory.initElements(driver, this); |
||||||
|
} |
||||||
|
|
||||||
|
public TaskNodeForm name(String name) { |
||||||
|
inputNodeName().sendKeys(name); |
||||||
|
|
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public TaskNodeForm addParam(String key, String val) { |
||||||
|
assert inputParamKey().size() == inputParamVal().size(); |
||||||
|
|
||||||
|
final var len = inputParamKey().size(); |
||||||
|
|
||||||
|
final var driver = parent().driver(); |
||||||
|
Stream.concat( |
||||||
|
driver.findElements(new ByChained(By.className("user-def-params-model"), By.className("add"))).stream(), |
||||||
|
driver.findElements(new ByChained(By.className("user-def-params-model"), By.className("add-dp"))).stream()) |
||||||
|
.findFirst() |
||||||
|
.orElseThrow(() -> new RuntimeException("Cannot find button to add param")) |
||||||
|
.click(); |
||||||
|
|
||||||
|
inputParamKey().get(len).sendKeys(key); |
||||||
|
inputParamVal().get(len).sendKeys(val); |
||||||
|
|
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public WorkflowForm submit() { |
||||||
|
buttonSubmit.click(); |
||||||
|
|
||||||
|
return parent(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,51 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
* or more contributor license agreements. See the NOTICE file |
||||||
|
* distributed with this work for additional information |
||||||
|
* regarding copyright ownership. The ASF licenses this file |
||||||
|
* to you under the Apache License, Version 2.0 (the |
||||||
|
* "License"); you may not use this file except in compliance |
||||||
|
* with the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, |
||||||
|
* software distributed under the License is distributed on an |
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
||||||
|
* KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations |
||||||
|
* under the License. |
||||||
|
* |
||||||
|
*/ |
||||||
|
package org.apache.dolphinscheduler.e2e.pages.security; |
||||||
|
|
||||||
|
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; |
||||||
|
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage.NavBarItem; |
||||||
|
|
||||||
|
import org.openqa.selenium.WebElement; |
||||||
|
import org.openqa.selenium.remote.RemoteWebDriver; |
||||||
|
import org.openqa.selenium.support.FindBy; |
||||||
|
|
||||||
|
import lombok.Getter; |
||||||
|
|
||||||
|
@Getter |
||||||
|
public class SecurityPage extends NavBarPage implements NavBarItem { |
||||||
|
@FindBy(className = "tenant-manage") |
||||||
|
private WebElement menuTenantManage; |
||||||
|
|
||||||
|
public SecurityPage(RemoteWebDriver driver) { |
||||||
|
super(driver); |
||||||
|
} |
||||||
|
|
||||||
|
public <T extends SecurityPage.Tab> T goToTab(Class<T> tab) { |
||||||
|
if (tab == TenantPage.class) { |
||||||
|
menuTenantManage().click(); |
||||||
|
return tab.cast(new TenantPage(driver)); |
||||||
|
} |
||||||
|
|
||||||
|
throw new UnsupportedOperationException("Unknown tab: " + tab.getName()); |
||||||
|
} |
||||||
|
|
||||||
|
public interface Tab { |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
|
* contributor license agreements. See the NOTICE file distributed with |
||||||
|
* this work for additional information regarding copyright ownership. |
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||||
|
* (the "License"); you may not use this file except in compliance with |
||||||
|
* the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
function createEvent(typeOfEvent) { |
||||||
|
const event = document.createEvent("CustomEvent"); |
||||||
|
event.initCustomEvent(typeOfEvent, true, true, null); |
||||||
|
event.dataTransfer = { |
||||||
|
data: {}, |
||||||
|
setData: function (key, value) { |
||||||
|
this.data[key] = value; |
||||||
|
}, |
||||||
|
getData: function (key) { |
||||||
|
return this.data[key]; |
||||||
|
} |
||||||
|
}; |
||||||
|
return event; |
||||||
|
} |
||||||
|
|
||||||
|
function dispatchEvent(element, event, transferData) { |
||||||
|
if (transferData !== undefined) { |
||||||
|
event.dataTransfer = transferData; |
||||||
|
} |
||||||
|
if (element.dispatchEvent) { |
||||||
|
element.dispatchEvent(event); |
||||||
|
} else if (element.fireEvent) { |
||||||
|
element.fireEvent("on" + event.type, event); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function simulateHTML5DragAndDrop(element, destination) { |
||||||
|
const dragStartEvent = createEvent('dragstart'); |
||||||
|
dispatchEvent(element, dragStartEvent); |
||||||
|
const dropEvent = createEvent('drop'); |
||||||
|
dispatchEvent(destination, dropEvent, dragStartEvent.dataTransfer); |
||||||
|
const dragEndEvent = createEvent('dragend'); |
||||||
|
dispatchEvent(element, dragEndEvent, dropEvent.dataTransfer); |
||||||
|
} |
||||||
|
|
||||||
|
const source = arguments[0]; |
||||||
|
const destination = arguments[1]; |
||||||
|
simulateHTML5DragAndDrop(source, destination); |
@ -1,307 +1,307 @@ |
|||||||
/* |
/* |
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||||
* contributor license agreements. See the NOTICE file distributed with |
* contributor license agreements. See the NOTICE file distributed with |
||||||
* this work for additional information regarding copyright ownership. |
* this work for additional information regarding copyright ownership. |
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||||
* (the "License"); you may not use this file except in compliance with |
* (the "License"); you may not use this file except in compliance with |
||||||
* the License. You may obtain a copy of the License at |
* the License. You may obtain a copy of the License at |
||||||
* |
* |
||||||
* http://www.apache.org/licenses/LICENSE-2.0 |
* http://www.apache.org/licenses/LICENSE-2.0 |
||||||
* |
* |
||||||
* Unless required by applicable law or agreed to in writing, software |
* Unless required by applicable law or agreed to in writing, software |
||||||
* distributed under the License is distributed on an "AS IS" BASIS, |
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
* See the License for the specific language governing permissions and |
* See the License for the specific language governing permissions and |
||||||
* limitations under the License. |
* limitations under the License. |
||||||
*/ |
*/ |
||||||
<template> |
<template> |
||||||
<div class="task-definition" v-if="!isLoading"> |
<div class="task-definition" v-if="!isLoading"> |
||||||
<m-list-construction :title="$t('Task Definition')"> |
<m-list-construction :title="$t('Task Definition')"> |
||||||
<template slot="conditions"> |
<template slot="conditions"> |
||||||
<m-conditions @on-conditions="_onConditions" :taskTypeShow="true"> |
<m-conditions @on-conditions="_onConditions" :taskTypeShow="true"> |
||||||
<template v-slot:button-group> |
<template v-slot:button-group> |
||||||
<el-button size="mini" @click="createTask"> |
<el-button size="mini" @click="createTask"> |
||||||
{{ $t("Create task") }} |
{{ $t("Create task") }} |
||||||
</el-button> |
</el-button> |
||||||
</template> |
</template> |
||||||
</m-conditions> |
</m-conditions> |
||||||
</template> |
</template> |
||||||
<template v-slot:content> |
<template v-slot:content> |
||||||
<template v-if="tasksList.length || total > 0"> |
<template v-if="tasksList.length || total > 0"> |
||||||
<m-list |
<m-list |
||||||
:tasksList="tasksList" |
:tasksList="tasksList" |
||||||
@on-update="_onUpdate" |
@on-update="_onUpdate" |
||||||
@editTask="editTask" |
@editTask="editTask" |
||||||
@viewTaskDetail="viewTaskDetail" |
@viewTaskDetail="viewTaskDetail" |
||||||
></m-list> |
></m-list> |
||||||
<div class="page-box"> |
<div class="page-box"> |
||||||
<el-pagination |
<el-pagination |
||||||
background |
background |
||||||
@current-change="_page" |
@current-change="_page" |
||||||
@size-change="_pageSize" |
@size-change="_pageSize" |
||||||
:page-size="searchParams.pageSize" |
:page-size="searchParams.pageSize" |
||||||
:current-page.sync="searchParams.pageNo" |
:current-page.sync="searchParams.pageNo" |
||||||
:page-sizes="[10, 30, 50]" |
:page-sizes="[10, 30, 50]" |
||||||
:total="total" |
:total="total" |
||||||
layout="sizes, prev, pager, next, jumper" |
layout="sizes, prev, pager, next, jumper" |
||||||
> |
> |
||||||
</el-pagination> |
</el-pagination> |
||||||
</div> |
</div> |
||||||
</template> |
</template> |
||||||
<template v-if="!tasksList.length"> |
<template v-if="!tasksList.length"> |
||||||
<m-no-data></m-no-data> |
<m-no-data></m-no-data> |
||||||
</template> |
</template> |
||||||
<m-spin :is-spin="isLoading"></m-spin> |
<m-spin :is-spin="isLoading"></m-spin> |
||||||
</template> |
</template> |
||||||
</m-list-construction> |
</m-list-construction> |
||||||
<el-drawer |
<el-drawer |
||||||
:visible.sync="taskDrawer" |
:visible.sync="taskDrawer" |
||||||
size="" |
size="" |
||||||
:with-header="false" |
:with-header="false" |
||||||
@close="closeTaskDrawer" |
@close="closeTaskDrawer" |
||||||
> |
> |
||||||
<!-- fix the bug that Element-ui(2.13.2) auto focus on the first input --> |
<!-- fix the bug that Element-ui(2.13.2) auto focus on the first input --> |
||||||
<div style="width: 0px; height: 0px; overflow: hidden"> |
<div style="width: 0px; height: 0px; overflow: hidden"> |
||||||
<el-input type="text" /> |
<el-input type="text" /> |
||||||
</div> |
</div> |
||||||
<m-form-model |
<m-form-model |
||||||
v-if="taskDrawer" |
v-if="taskDrawer" |
||||||
:nodeData="nodeData" |
:nodeData="nodeData" |
||||||
type="task-definition" |
type="task-definition" |
||||||
@changeTaskType="changeTaskType" |
@changeTaskType="changeTaskType" |
||||||
@close="closeTaskDrawer" |
@close="closeTaskDrawer" |
||||||
@addTaskInfo="saveTask" |
@addTaskInfo="saveTask" |
||||||
:taskDefinition="editingTask" |
:taskDefinition="editingTask" |
||||||
> |
> |
||||||
</m-form-model> |
</m-form-model> |
||||||
</el-drawer> |
</el-drawer> |
||||||
</div> |
</div> |
||||||
</template> |
</template> |
||||||
<script> |
<script> |
||||||
import mListConstruction from '@/module/components/listConstruction/listConstruction' |
import mListConstruction from '@/module/components/listConstruction/listConstruction' |
||||||
import mConditions from '@/module/components/conditions/conditions' |
import mConditions from '@/module/components/conditions/conditions' |
||||||
import mList from './_source/list' |
import mList from './_source/list' |
||||||
import mNoData from '@/module/components/noData/noData' |
import mNoData from '@/module/components/noData/noData' |
||||||
import mSpin from '@/module/components/spin/spin' |
import mSpin from '@/module/components/spin/spin' |
||||||
import { mapActions, mapMutations } from 'vuex' |
import { mapActions, mapMutations } from 'vuex' |
||||||
import listUrlParamHandle from '@/module/mixin/listUrlParamHandle' |
import listUrlParamHandle from '@/module/mixin/listUrlParamHandle' |
||||||
import mFormModel from '@/conf/home/pages/dag/_source/formModel/formModel.vue' |
import mFormModel from '@/conf/home/pages/dag/_source/formModel/formModel.vue' |
||||||
/** |
/** |
||||||
* tasksType |
* tasksType |
||||||
*/ |
*/ |
||||||
import { tasksType } from '@/conf/home/pages/dag/_source/config.js' |
import { tasksType } from '@/conf/home/pages/dag/_source/config.js' |
||||||
|
|
||||||
const DEFAULT_NODE_DATA = { |
const DEFAULT_NODE_DATA = { |
||||||
id: -1, |
id: -1, |
||||||
taskType: 'SHELL', |
taskType: 'SHELL', |
||||||
instanceId: -1 |
instanceId: -1 |
||||||
} |
} |
||||||
export default { |
export default { |
||||||
name: 'task-definition-index', |
name: 'task-definition-index', |
||||||
data () { |
data () { |
||||||
// tasksType |
// tasksType |
||||||
const tasksTypeList = Object.keys(tasksType) |
const tasksTypeList = Object.keys(tasksType) |
||||||
return { |
return { |
||||||
total: null, |
total: null, |
||||||
tasksList: [], |
tasksList: [], |
||||||
isLoading: true, |
isLoading: true, |
||||||
searchParams: { |
searchParams: { |
||||||
pageSize: 10, |
pageSize: 10, |
||||||
pageNo: 1, |
pageNo: 1, |
||||||
searchVal: '', |
searchVal: '', |
||||||
taskType: '', |
taskType: '', |
||||||
userId: '' |
userId: '' |
||||||
}, |
}, |
||||||
// whether the task config drawer is visible |
// whether the task config drawer is visible |
||||||
taskDrawer: false, |
taskDrawer: false, |
||||||
// nodeData |
// nodeData |
||||||
nodeData: { ...DEFAULT_NODE_DATA }, |
nodeData: { ...DEFAULT_NODE_DATA }, |
||||||
// tasksType |
// tasksType |
||||||
tasksTypeList, |
tasksTypeList, |
||||||
// editing task definition |
// editing task definition |
||||||
editingTask: null |
editingTask: null |
||||||
} |
} |
||||||
}, |
}, |
||||||
mixins: [listUrlParamHandle], |
mixins: [listUrlParamHandle], |
||||||
methods: { |
methods: { |
||||||
...mapActions('dag', [ |
...mapActions('dag', [ |
||||||
'getTaskDefinitionsList', |
'getTaskDefinitionsList', |
||||||
'genTaskCodeList', |
'genTaskCodeList', |
||||||
'saveTaskDefinition', |
'saveTaskDefinition', |
||||||
'updateTaskDefinition' |
'updateTaskDefinition' |
||||||
]), |
]), |
||||||
...mapActions('dag', [ |
...mapActions('dag', [ |
||||||
'getProcessList', |
'getProcessList', |
||||||
'getProjectList', |
'getProjectList', |
||||||
'getResourcesList', |
'getResourcesList', |
||||||
'getResourcesListJar', |
'getResourcesListJar', |
||||||
'getResourcesListJar' |
'getResourcesListJar' |
||||||
]), |
]), |
||||||
...mapMutations('dag', ['resetParams', 'setIsDetails']), |
...mapMutations('dag', ['resetParams', 'setIsDetails']), |
||||||
...mapActions('security', [ |
...mapActions('security', [ |
||||||
'getTenantList', |
'getTenantList', |
||||||
'getWorkerGroupsAll', |
'getWorkerGroupsAll', |
||||||
'getAlarmGroupsAll' |
'getAlarmGroupsAll' |
||||||
]), |
]), |
||||||
/** |
/** |
||||||
* Toggle task drawer |
* Toggle task drawer |
||||||
*/ |
*/ |
||||||
showTaskDrawer () { |
showTaskDrawer () { |
||||||
this.taskDrawer = true |
this.taskDrawer = true |
||||||
}, |
}, |
||||||
closeTaskDrawer () { |
closeTaskDrawer () { |
||||||
this.setIsDetails(false) |
this.setIsDetails(false) |
||||||
this.taskDrawer = false |
this.taskDrawer = false |
||||||
}, |
}, |
||||||
saveTask ({ item }) { |
saveTask ({ item }) { |
||||||
const isEditing = !!this.editingTask |
const isEditing = !!this.editingTask |
||||||
if (isEditing) { |
if (isEditing) { |
||||||
this.updateTaskDefinition(item) |
this.updateTaskDefinition(item) |
||||||
.then((res) => { |
.then((res) => { |
||||||
this.$message.success(res.msg) |
this.$message.success(res.msg) |
||||||
this._onUpdate() |
this._onUpdate() |
||||||
this.closeTaskDrawer() |
this.closeTaskDrawer() |
||||||
}) |
}) |
||||||
.catch((e) => { |
.catch((e) => { |
||||||
this.$message.error(e.msg || '') |
this.$message.error(e.msg || '') |
||||||
}) |
}) |
||||||
} else { |
} else { |
||||||
this.genTaskCodeList({ |
this.genTaskCodeList({ |
||||||
genNum: 1 |
genNum: 1 |
||||||
}) |
}) |
||||||
.then((res) => { |
.then((res) => { |
||||||
const [code] = res |
const [code] = res |
||||||
return code |
return code |
||||||
}) |
}) |
||||||
.then((code) => { |
.then((code) => { |
||||||
return this.saveTaskDefinition({ |
return this.saveTaskDefinition({ |
||||||
taskDefinitionJson: [ |
taskDefinitionJson: [ |
||||||
{ |
{ |
||||||
...item, |
...item, |
||||||
code |
code |
||||||
} |
} |
||||||
] |
] |
||||||
}) |
}) |
||||||
}) |
}) |
||||||
.then((res) => { |
.then((res) => { |
||||||
this.$message.success(res.msg) |
this.$message.success(res.msg) |
||||||
this._onUpdate() |
this._onUpdate() |
||||||
this.closeTaskDrawer() |
this.closeTaskDrawer() |
||||||
}) |
}) |
||||||
.catch((e) => { |
.catch((e) => { |
||||||
this.$message.error(e.msg || '') |
this.$message.error(e.msg || '') |
||||||
}) |
}) |
||||||
} |
} |
||||||
}, |
}, |
||||||
createTask () { |
createTask () { |
||||||
this.editingTask = null |
this.editingTask = null |
||||||
this.nodeData.taskType = DEFAULT_NODE_DATA.taskType |
this.nodeData.taskType = DEFAULT_NODE_DATA.taskType |
||||||
this.showTaskDrawer() |
this.showTaskDrawer() |
||||||
}, |
}, |
||||||
editTask (task) { |
editTask (task) { |
||||||
this.editingTask = task |
this.editingTask = task |
||||||
this.nodeData.id = task.code |
this.nodeData.id = task.code |
||||||
this.nodeData.taskType = task.taskType |
this.nodeData.taskType = task.taskType |
||||||
this.showTaskDrawer() |
this.showTaskDrawer() |
||||||
}, |
}, |
||||||
viewTaskDetail (task) { |
viewTaskDetail (task) { |
||||||
this.setIsDetails(true) |
this.setIsDetails(true) |
||||||
this.editTask(task) |
this.editTask(task) |
||||||
}, |
}, |
||||||
/** |
/** |
||||||
* pageNo |
* pageNo |
||||||
*/ |
*/ |
||||||
_page (val) { |
_page (val) { |
||||||
this.searchParams.pageNo = val |
this.searchParams.pageNo = val |
||||||
}, |
}, |
||||||
_pageSize (val) { |
_pageSize (val) { |
||||||
this.searchParams.pageSize = val |
this.searchParams.pageSize = val |
||||||
}, |
}, |
||||||
/** |
/** |
||||||
* conditions |
* conditions |
||||||
*/ |
*/ |
||||||
_onConditions (o) { |
_onConditions (o) { |
||||||
this.searchParams.searchVal = o.searchVal |
this.searchParams.searchVal = o.searchVal |
||||||
this.searchParams.taskType = o.taskType |
this.searchParams.taskType = o.taskType |
||||||
this.searchParams.pageNo = 1 |
this.searchParams.pageNo = 1 |
||||||
}, |
}, |
||||||
/** |
/** |
||||||
* get task definition list |
* get task definition list |
||||||
*/ |
*/ |
||||||
_getList (flag) { |
_getList (flag) { |
||||||
this.isLoading = !flag |
this.isLoading = !flag |
||||||
this.getTaskDefinitionsList(this.searchParams) |
this.getTaskDefinitionsList(this.searchParams) |
||||||
.then((res) => { |
.then((res) => { |
||||||
if (this.searchParams.pageNo > 1 && res.totalList.length === 0) { |
if (this.searchParams.pageNo > 1 && res.totalList.length === 0) { |
||||||
this.searchParams.pageNo = this.searchParams.pageNo - 1 |
this.searchParams.pageNo = this.searchParams.pageNo - 1 |
||||||
} else { |
} else { |
||||||
this.tasksList = [] |
this.tasksList = [] |
||||||
this.tasksList = res.totalList |
this.tasksList = res.totalList |
||||||
this.total = res.total |
this.total = res.total |
||||||
this.isLoading = false |
this.isLoading = false |
||||||
} |
} |
||||||
}) |
}) |
||||||
.catch((e) => { |
.catch((e) => { |
||||||
this.isLoading = false |
this.isLoading = false |
||||||
}) |
}) |
||||||
}, |
}, |
||||||
/** |
/** |
||||||
* update task dataList |
* update task dataList |
||||||
*/ |
*/ |
||||||
_onUpdate () { |
_onUpdate () { |
||||||
this._debounceGET('false') |
this._debounceGET('false') |
||||||
}, |
}, |
||||||
/** |
/** |
||||||
* change form modal task type |
* change form modal task type |
||||||
*/ |
*/ |
||||||
changeTaskType (value) { |
changeTaskType (value) { |
||||||
this.nodeData.taskType = value |
this.nodeData.taskType = value |
||||||
} |
} |
||||||
}, |
}, |
||||||
created () { |
created () { |
||||||
this.isLoading = true |
this.isLoading = true |
||||||
// Initialization parameters |
// Initialization parameters |
||||||
this.resetParams() |
this.resetParams() |
||||||
// Promise Get node needs data |
// Promise Get node needs data |
||||||
Promise.all([ |
Promise.all([ |
||||||
// get process definition |
// get process definition |
||||||
this.getProcessList(), |
this.getProcessList(), |
||||||
// get project |
// get project |
||||||
this.getProjectList(), |
this.getProjectList(), |
||||||
// get jar |
// get jar |
||||||
this.getResourcesListJar(), |
this.getResourcesListJar(), |
||||||
// get resource |
// get resource |
||||||
this.getResourcesList(), |
this.getResourcesList(), |
||||||
// get jar |
// get jar |
||||||
this.getResourcesListJar(), |
this.getResourcesListJar(), |
||||||
// get worker group list |
// get worker group list |
||||||
this.getWorkerGroupsAll(), |
this.getWorkerGroupsAll(), |
||||||
// get alarm group list |
// get alarm group list |
||||||
this.getAlarmGroupsAll(), |
this.getAlarmGroupsAll(), |
||||||
this.getTenantList() |
this.getTenantList() |
||||||
]) |
]) |
||||||
.then((data) => { |
.then((data) => { |
||||||
this.isLoading = false |
this.isLoading = false |
||||||
}) |
}) |
||||||
.catch(() => { |
.catch(() => { |
||||||
this.isLoading = false |
this.isLoading = false |
||||||
}) |
}) |
||||||
}, |
}, |
||||||
mounted () {}, |
mounted () {}, |
||||||
components: { |
components: { |
||||||
mListConstruction, |
mListConstruction, |
||||||
mConditions, |
mConditions, |
||||||
mList, |
mList, |
||||||
mNoData, |
mNoData, |
||||||
mSpin, |
mSpin, |
||||||
mFormModel |
mFormModel |
||||||
} |
} |
||||||
} |
} |
||||||
</script> |
</script> |
||||||
<style lang="scss" scoped> |
<style lang="scss" scoped> |
||||||
.task-definition { |
.task-definition { |
||||||
.taskGroupBtn { |
.taskGroupBtn { |
||||||
width: 300px; |
width: 300px; |
||||||
} |
} |
||||||
} |
} |
||||||
</style> |
</style> |
||||||
|
Loading…
Reference in new issue