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); |
Loading…
Reference in new issue