This is an automated email from the ASF dual-hosted git repository.
liuxiaochun pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/incubator-dolphinscheduler.git
The following commit(s) were added to refs/heads/dev by this push:
new 1cadb1a Add e2e automated testing (#2005)
1cadb1a is described below
commit 1cadb1a2511174f59c28ebffb6223989865c3c19
Author: xingchun-chen <[email protected]>
AuthorDate: Wed Feb 26 11:08:55 2020 +0800
Add e2e automated testing (#2005)
* add ui-test
* add e2e license and notice
* e2e delete dolphinscheduler parent project dependency
* pom.xml delete e2e dependency
Co-authored-by: chenxingchun
<[email protected]>
---
dolphinscheduler-dist/pom.xml | 2 -
e2e/pom.xml | 137 ++++++++
.../dolphinscheduler/constant/TestConstant.java | 37 +++
.../dolphinscheduler/util/PropertiesReader.java | 49 +++
.../apache/dolphinscheduler/util/RedisUtil.java | 204 ++++++++++++
.../apache/dolphinscheduler/base/BaseDriver.java | 133 ++++++++
.../org/apache/dolphinscheduler/base/BaseTest.java | 107 +++++++
.../dolphinscheduler/common/BrowserCommon.java | 353 +++++++++++++++++++++
.../apache/dolphinscheduler/common/PageCommon.java | 50 +++
.../apache/dolphinscheduler/data/LoginData.java | 43 +++
.../data/project/CreatProjectData.java | 26 ++
.../data/project/CreatWorkflowData.java | 36 +++
.../data/security/TenantManageData.java | 55 ++++
.../data/security/UserManageData.java | 34 ++
.../dolphinscheduler/locator/LoginLocator.java | 33 ++
.../locator/project/CreateProjectLocator.java | 36 +++
.../locator/project/CreateWorkflowLocator.java | 97 ++++++
.../locator/security/TenantManageLocator.java | 33 ++
.../locator/security/UserManageLocator.java | 45 +++
.../apache/dolphinscheduler/page/LoginPage.java | 65 ++++
.../page/project/CreateProjectPage.java | 58 ++++
.../page/project/CreateWorkflowPage.java | 108 +++++++
.../page/security/TenantManagePage.java | 69 ++++
.../page/security/UserManagePage.java | 67 ++++
.../dolphinscheduler/testcase/LoginTest.java | 37 +++
.../testcase/project/CreateProjectTest.java | 36 +++
.../testcase/project/CreateWorkflowTest.java | 34 ++
.../testcase/security/TenantManageTest.java | 34 ++
.../testcase/security/UserManageTest.java | 34 ++
e2e/src/test/resources/config/config.properties | 58 ++++
e2e/suite.xml | 18 ++
e2e/testng.xml | 22 ++
pom.xml | 1 -
33 files changed, 2148 insertions(+), 3 deletions(-)
diff --git a/dolphinscheduler-dist/pom.xml b/dolphinscheduler-dist/pom.xml
index b43daff..80ddfec 100644
--- a/dolphinscheduler-dist/pom.xml
+++ b/dolphinscheduler-dist/pom.xml
@@ -41,7 +41,6 @@
<groupId>org.apache.dolphinscheduler</groupId>
<artifactId>dolphinscheduler-api</artifactId>
</dependency>
-
</dependencies>
<profiles>
@@ -97,7 +96,6 @@
</execution>
</executions>
</plugin>
-
</plugins>
</build>
</profile>
diff --git a/e2e/pom.xml b/e2e/pom.xml
new file mode 100644
index 0000000..ac9cea9
--- /dev/null
+++ b/e2e/pom.xml
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.dolphinscheduler-e2e</groupId>
+ <artifactId>dolphinscheduler-e2e</artifactId>
+ <version>1.0.0</version>
+
+ <properties>
+ <testng.version>6.14.3</testng.version>
+ <selenium.version>3.141.59</selenium.version>
+ <guava.version>22.0</guava.version>
+ <commons-io.version>2.6</commons-io.version>
+ <reportng.version>1.1.4</reportng.version>
+ <commons-pool2.version>2.8.0</commons-pool2.version>
+ <inject.version>4.2.1</inject.version>
+ <xml.file>testng.xml</xml.file>
+ </properties>
+
+ <dependencies>
+ <!-- selenium -->
+ <dependency>
+ <groupId>org.seleniumhq.selenium</groupId>
+ <artifactId>selenium-java</artifactId>
+ <version>${selenium.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>${guava.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.inject</groupId>
+ <artifactId>guice</artifactId>
+ <version>${inject.version}</version>
+ </dependency>
+ <!-- testng -->
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <version>${testng.version}</version>
+ </dependency>
+ <!-- Depends on reportNg, associated with testNg-->
+ <dependency>
+ <groupId>org.uncommons</groupId>
+ <artifactId>reportng</artifactId>
+ <version>${reportng.version}</version>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>${commons-io.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.servicemix.bundles</groupId>
+ <artifactId>org.apache.servicemix.bundles.jedis</artifactId>
+ <version>2.6.0_2-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-pool2</artifactId>
+ <version>${commons-pool2.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.8.0</version>
+ <configuration>
+ <source>1.8</source>
+ <target>1.8</target>
+ <encoding>UTF-8</encoding>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.20.1</version>
+ <configuration>
+ <suiteXmlFiles>
+ <suiteXmlFile>${xml.file}</suiteXmlFile>
+ </suiteXmlFiles>
+ <argLine>-Dfile.encoding=UTF-8</argLine>
+ <properties>
+ <property>
+ <name>usedefaultlisteners</name>
+ <!--Set listen false, Do not use the default
report testng, use reportng-->
+ <value>false</value>
+ </property>
+ <property>
+ <name>listener</name>
+
<value>org.uncommons.reportng.HTMLReporter,org.uncommons.reportng.JUnitXMLReporter</value>
+ </property>
+ </properties>
+ <!--<workingDirectory>target/</workingDirectory>-->
+ <!--<forkMode>always</forkMode>-->
+ </configuration>
+ </plugin>
+
+
+ <!--<plugin>-->
+ <!--<groupId>org.apache.maven.plugins</groupId>-->
+ <!--<artifactId>maven-surefire-plugin</artifactId>-->
+ <!--<version>2.5</version>-->
+ <!--<configuration>-->
+ <!--<properties>-->
+ <!--<property>-->
+ <!--<name>usedefaultlisteners</name>-->
+ <!--<!–Set listen false, Do not use the
default report testng, use reportng–>-->
+ <!--<value>false</value>-->
+ <!--</property>-->
+ <!--<property>-->
+ <!--<name>listener</name>-->
+
<!--<value>org.uncommons.reportng.HTMLReporter,org.uncommons.reportng.JUnitXMLReporter</value>-->
+ <!--</property>-->
+ <!--</properties>-->
+ <!--<workingDirectory>target/</workingDirectory>-->
+ <!--<forkMode>always</forkMode>-->
+ <!--</configuration>-->
+ <!--</plugin>-->
+ </plugins>
+ </build>
+</project>
\ No newline at end of file
diff --git
a/e2e/src/main/java/org/apache/dolphinscheduler/constant/TestConstant.java
b/e2e/src/main/java/org/apache/dolphinscheduler/constant/TestConstant.java
new file mode 100644
index 0000000..8a3b8eb
--- /dev/null
+++ b/e2e/src/main/java/org/apache/dolphinscheduler/constant/TestConstant.java
@@ -0,0 +1,37 @@
+/*
+ * 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.constant;
+
+public class TestConstant {
+ /**
+ * 1000
+ */
+ public static final int ONE_THOUSANG = 1000;
+
+
+
+ /**
+ * 3000
+ */
+ public static final int THREE_THOUSANG = 3000;
+
+ /**
+ * 10000
+ */
+ public static final int TEN_THOUSANG = 10000;
+
+}
diff --git
a/e2e/src/main/java/org/apache/dolphinscheduler/util/PropertiesReader.java
b/e2e/src/main/java/org/apache/dolphinscheduler/util/PropertiesReader.java
new file mode 100644
index 0000000..cbf7d07
--- /dev/null
+++ b/e2e/src/main/java/org/apache/dolphinscheduler/util/PropertiesReader.java
@@ -0,0 +1,49 @@
+/*
+ * 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.util;
+
+import java.io.*;
+import java.util.Properties;
+
+/**
+ * read properties
+ */
+public class PropertiesReader {
+ private static Properties properties = new Properties();
+
+ /**
+ * @param propertiesPath properties path
+ * @return Properties
+ * @throws IOException IOException
+ */
+ public static Properties readProperties(String propertiesPath) throws
IOException {
+ System.out.println("read properties ");
+ InputStream inputStream = new FileInputStream(propertiesPath);
+ InputStreamReader inputStreamReader = new
InputStreamReader(inputStream, "UTF-8");
+ BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
+ properties.load(bufferedReader);
+ return properties;
+ }
+
+ /***
+ * @param key key
+ * @return value
+ */
+ public static String getKey(String key) {
+ return properties.getProperty(key);
+ }
+}
diff --git a/e2e/src/main/java/org/apache/dolphinscheduler/util/RedisUtil.java
b/e2e/src/main/java/org/apache/dolphinscheduler/util/RedisUtil.java
new file mode 100644
index 0000000..7f9340f
--- /dev/null
+++ b/e2e/src/main/java/org/apache/dolphinscheduler/util/RedisUtil.java
@@ -0,0 +1,204 @@
+/*
+ * 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.util;
+
+import org.apache.dolphinscheduler.constant.TestConstant;
+import redis.clients.jedis.Jedis;
+import redis.clients.jedis.JedisPool;
+import redis.clients.jedis.JedisPoolConfig;
+
+/**
+ * redis util
+ */
+public class RedisUtil {
+ /**
+ * redis ip
+ */
+ private static String redisIp;
+
+ /**
+ * redis port
+ */
+ private static int redisPort;
+
+ /**
+ * redis password
+ */
+ private static String redisPwd;
+
+ /**
+ * redis pool config
+ */
+ private static JedisPoolConfig jedisPoolConfig;
+
+ /**
+ * redis pool
+ */
+ private static JedisPool jedisPool;
+
+ /**
+ * jedis connection
+ */
+ private Jedis jedis;
+
+ /**
+ * jedis expire time
+ */
+ private int jedisExpireTime;
+
+ /**
+ * jedis max total
+ */
+ private static int jedisPoolMaxTotal;
+
+ /**
+ * jedis max idle
+ */
+ private static int jedisPoolMaxIdle;
+
+ /**
+ * jedis max wait time
+ */
+ private static int jedisPoolMaxWaitMillis;
+
+ /**
+ * Whether to perform a valid check when calling the borrowObject method
+ */
+ private static boolean jedisPoolTestOnBorrow;
+
+ /**
+ * Whether to perform a valid check when calling the returnObject method
+ */
+ private static boolean jedisPoolTestOnReturn;
+
+ /**
+ * storage local thread
+ */
+ public static ThreadLocal<Jedis> threadLocal = new ThreadLocal<>();
+
+ /*
+ * redis init
+ */
+ static {
+ // redis properties
+ redisIp = PropertiesReader.getKey("redis.ip");
+ redisPort = Integer.valueOf(PropertiesReader.getKey("redis.port"));
+ redisPwd = PropertiesReader.getKey("redis.pwd");
+ //redis pool properties
+ jedisPoolMaxTotal =
Integer.valueOf(PropertiesReader.getKey("jedis.pool.maxTotal"));
+ jedisPoolMaxIdle =
Integer.valueOf(PropertiesReader.getKey("jedis.pool.maxIdle"));
+ jedisPoolMaxWaitMillis =
Integer.valueOf(PropertiesReader.getKey("jedis.pool.maxWaitMillis"));
+ jedisPoolTestOnBorrow =
Boolean.valueOf(PropertiesReader.getKey("jedis.pool.testOnBorrow"));
+ jedisPoolTestOnReturn =
Boolean.valueOf(PropertiesReader.getKey("jedis.pool.testOnReturn"));
+ // redis pool start properties
+ jedisPoolConfig = new JedisPoolConfig();
+ jedisPoolConfig.setMaxTotal(jedisPoolMaxTotal);
+ jedisPoolConfig.setMaxIdle(jedisPoolMaxIdle);
+ jedisPoolConfig.setMaxWaitMillis(jedisPoolMaxWaitMillis);
+ jedisPoolConfig.setTestOnBorrow(jedisPoolTestOnBorrow);
+ jedisPoolConfig.setTestOnReturn(jedisPoolTestOnReturn);
+ // connect redis
+ try {
+ System.out.println("redis init");
+ if (redisPwd.isEmpty())
+ jedisPool = new JedisPool(jedisPoolConfig, redisIp, redisPort,
TestConstant.THREE_THOUSANG);
+ else {
+ jedisPool = new JedisPool(jedisPoolConfig, redisIp, redisPort,
TestConstant.TEN_THOUSANG, redisPwd);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println("redis connect fail");
+ }
+ }
+
+ /**
+ * get redis pool
+ *
+ * @return redis pool
+ */
+ public static JedisPool getJedisPool() {
+ return jedisPool;
+ }
+
+ /**
+ * get jedis connection
+ *
+ * @return jedis connection
+ */
+ public Jedis getNewJedis() {
+ Jedis newJedis = null;
+ try {
+ newJedis = jedisPool.getResource();
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println("redis connection fail");
+ }
+ System.out.println("redis connection success");
+ return newJedis;
+ }
+
+ /**
+ * get jedis connection
+ *
+ * @return jedis connection
+ */
+ public Jedis getJedis() {
+ return jedis;
+ }
+
+ public void setJedisAndExpire(Jedis jedis) {
+ this.jedis = jedis;
+ threadLocal.set(jedis);
+ // jedis expire time(s)
+ jedisExpireTime =
Integer.valueOf(PropertiesReader.getKey("jedis.expireTime"));
+ System.out.println("redisUtil sets up a redis connection");
+ }
+
+ /**
+ * set key
+ *
+ * @param key key
+ * @param value value
+ *
+ */
+
+ public void setKey(String key, String value) {
+ jedis.set(key, value);
+ // set expire time 1h
+ jedis.expire(key, jedisExpireTime);
+ }
+
+ /**
+ * get key
+ *
+ * @param key key
+ * @return value
+ */
+ public String getKey(String key) {
+ return jedis.get(key);
+ }
+
+ /**
+ * Return jedis connection
+ */
+ public void returnJedis() {
+ if (jedis != null) {
+ jedis.close();
+ }
+ System.out.println("jedis has been returned");
+ }
+}
diff --git a/e2e/src/test/java/org/apache/dolphinscheduler/base/BaseDriver.java
b/e2e/src/test/java/org/apache/dolphinscheduler/base/BaseDriver.java
new file mode 100644
index 0000000..c1397b6
--- /dev/null
+++ b/e2e/src/test/java/org/apache/dolphinscheduler/base/BaseDriver.java
@@ -0,0 +1,133 @@
+/*
+ * 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.base;
+
+
+import org.apache.dolphinscheduler.constant.TestConstant;
+import org.apache.dolphinscheduler.util.PropertiesReader;
+import org.openqa.selenium.JavascriptExecutor;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.chrome.ChromeDriver;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * base driver class
+ */
+public class BaseDriver {
+ /**
+ * driver
+ */
+ private WebDriver driver;
+
+ /**
+ * chrome driver path
+ */
+ private String chromeDriverPath;
+
+
+ /**
+ * implicitly wait time(s)
+ */
+ private long implicitlyWait;
+
+ /**
+ * page load timeout(s)
+ */
+ private long pageLoadTimeout;
+
+ /**
+ * script Timeout(s)
+ */
+ private long setScriptTimeout;
+
+
+ /**
+ * Local thread storage is used to store the driver
+ */
+ public static ThreadLocal<WebDriver> threadLocal = new ThreadLocal<>();
+
+ /**
+ *Initialization parameters
+ */
+ public BaseDriver() throws IOException {
+ /* driver test class path */
+ chromeDriverPath = PropertiesReader.getKey("driver.chromeDriver");
+
+ /* wait time */
+ implicitlyWait =
Long.valueOf(PropertiesReader.getKey("driver.timeouts.implicitlyWait"));
+ pageLoadTimeout =
Long.valueOf(PropertiesReader.getKey("driver.timeouts.pageLoadTimeout"));
+ setScriptTimeout =
Long.valueOf(PropertiesReader.getKey("driver.timeouts.setScriptTimeout"));
+ }
+
+
+ /**
+ * start chrome browser
+ */
+ public void startBrowser() throws Exception {
+ // set chrome driver
+ System.setProperty("webdriver.chrome.driver", chromeDriverPath);
+ driver = new ChromeDriver();
+
+ /* driver setting wait time */
+ // implicitly wait time
+ driver.manage().timeouts().implicitlyWait(implicitlyWait,
TimeUnit.SECONDS);
+ // page load timeout
+ driver.manage().timeouts().pageLoadTimeout(pageLoadTimeout,
TimeUnit.SECONDS);
+ // script timeout
+ driver.manage().timeouts().setScriptTimeout(setScriptTimeout,
TimeUnit.SECONDS);
+
+ // window maximize
+ driver.manage().window().maximize();
+
+ // set threadLocal
+ threadLocal.set(driver);
+ }
+
+ /**
+ * get webDriver
+ *
+ * @return driver
+ */
+ public WebDriver getDriver() {
+ return driver;
+ }
+
+ /**
+ * set webDriver
+ *
+ * @param driver driver
+ */
+ public void setDriver(WebDriver driver) {
+ this.driver = driver;
+ // Thread local storage
+ threadLocal.set(driver);
+ }
+
+ /**
+ * close browser
+ */
+ public void closeBrowser() throws InterruptedException {
+ // JS Show a pop-up box to indicate the end of the test
+ Thread.sleep(TestConstant.ONE_THOUSANG);
+ ((JavascriptExecutor) driver).executeScript("alert('Test completed,
browser closes after 3s')");
+ Thread.sleep(TestConstant.THREE_THOUSANG);
+ if (driver != null) {
+ driver.quit();
+ }
+ }
+}
diff --git a/e2e/src/test/java/org/apache/dolphinscheduler/base/BaseTest.java
b/e2e/src/test/java/org/apache/dolphinscheduler/base/BaseTest.java
new file mode 100644
index 0000000..c12c19f
--- /dev/null
+++ b/e2e/src/test/java/org/apache/dolphinscheduler/base/BaseTest.java
@@ -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.base;
+
+
+import org.apache.dolphinscheduler.page.LoginPage;
+import org.apache.dolphinscheduler.util.PropertiesReader;
+import org.openqa.selenium.WebDriver;
+import org.testng.annotations.*;
+
+import java.io.IOException;
+import java.util.Properties;
+
+/**
+ * base test class
+ */
+public class BaseTest {
+ /**
+ * properties
+ */
+ private static Properties properties;
+
+
+ /**
+ * baseDriver
+ */
+ private BaseDriver baseDriver;
+
+ /**
+ * driver
+ */
+ public WebDriver driver;
+
+ /**
+ * Executed before executing a test suite
+ * Read the test configuration file
+ *
+ * @param propertiesPath properties path
+ * @throws IOException IOException
+ */
+ @BeforeSuite(alwaysRun = true)
+ @Parameters({"propertiesPath"})
+ public void
beforeSuite(@Optional("src/test/resources/config/config.properties") String
propertiesPath) throws IOException {
+ // read properties
+ properties = PropertiesReader.readProperties(propertiesPath);
+ }
+
+ /**
+ * Executed before executing a testcase
+ */
+ @BeforeTest(alwaysRun = true)
+ public void beforeTest() throws Exception {
+ //base driver
+ baseDriver = new BaseDriver();
+ baseDriver.startBrowser();
+ driver = baseDriver.getDriver();
+ }
+
+ /**
+ * Executed before executing a class method in a test case
+ */
+ @BeforeClass(alwaysRun = true)
+ public void setUp() throws IOException, InterruptedException {
+ LoginPage loginPage = new LoginPage(driver);
+ loginPage.jumpPage();
+ loginPage.login();
+ }
+
+
+ /**
+ * Execute after executing a class method in a test case
+ */
+ @AfterClass(alwaysRun = true)
+ public void afterClass() {
+ // logout
+ }
+
+ /**
+ * Execute after executing a testcase
+ */
+ @AfterTest(alwaysRun = true)
+ public void afterTest() throws InterruptedException {
+ // close browser
+ baseDriver.closeBrowser();
+ }
+
+ /**
+ * Execute after executing a testsuite
+ */
+ @AfterSuite(alwaysRun = true)
+ public void afterSuite() {
+ }
+}
\ No newline at end of file
diff --git
a/e2e/src/test/java/org/apache/dolphinscheduler/common/BrowserCommon.java
b/e2e/src/test/java/org/apache/dolphinscheduler/common/BrowserCommon.java
new file mode 100644
index 0000000..fb16162
--- /dev/null
+++ b/e2e/src/test/java/org/apache/dolphinscheduler/common/BrowserCommon.java
@@ -0,0 +1,353 @@
+/*
+ * 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.common;
+
+import org.apache.dolphinscheduler.util.PropertiesReader;
+import org.apache.dolphinscheduler.util.RedisUtil;
+import org.openqa.selenium.*;
+import org.openqa.selenium.interactions.Actions;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import org.openqa.selenium.support.ui.WebDriverWait;
+import redis.clients.jedis.Jedis;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Encapsulate the most basic operations on the interface in the browser
+ */
+public class BrowserCommon {
+ /**
+ * driver
+ */
+ protected WebDriver driver;
+
+ /**
+ * actions
+ */
+ protected Actions actions;
+
+ /**
+ * Javascript
+ */
+ protected JavascriptExecutor je;
+
+ /**
+ * Show wait
+ */
+ protected WebDriverWait wait;
+
+ /**
+ * Jedis
+ */
+ protected Jedis jedis;
+
+ /**
+ * redis util
+ */
+ protected RedisUtil redisUtil;
+
+ /**
+ * @param driver driver
+ */
+ public BrowserCommon(WebDriver driver) {
+ this.driver = driver;
+ this.actions = new Actions(driver);
+ this.je = ((JavascriptExecutor) driver);
+ // show wait timeout
+ long timeout =
Long.valueOf(PropertiesReader.getKey("driver.timeouts.webDriverWait"));
+ wait = new WebDriverWait(driver, timeout);
+ }
+
+ /**
+ * @param driver driver
+ * @param jedis jedis
+ */
+ public BrowserCommon(WebDriver driver, Jedis jedis) {
+ this.driver = driver;
+ this.actions = new Actions(driver);
+ this.je = ((JavascriptExecutor) driver);
+ // show wait timeout
+ long timeout =
Long.valueOf(PropertiesReader.getKey("driver.timeouts.webDriverWait"));
+ wait = new WebDriverWait(driver, timeout);
+ this.jedis = jedis;
+ }
+
+ /**
+ * @param driver driver
+ * @param redisUtil redisUtil
+ */
+ public BrowserCommon(WebDriver driver, RedisUtil redisUtil) {
+ this.driver = driver;
+ this.actions = new Actions(driver);
+ this.je = ((JavascriptExecutor) driver);
+ // show wait timeout
+ long timeout =
Long.valueOf(PropertiesReader.getKey("driver.timeouts.webDriverWait"));
+ wait = new WebDriverWait(driver, timeout);
+// this.redisUtil = redisUtil;
+// this.jedis = redisUtil.getJedis();
+ }
+
+
+ /**
+ * Get WebElement element object through element positioning
+ *
+ * @param locator By
+ * @return WebElement
+ */
+
+ public WebElement locateElement(By locator) {
+ return
wait.until(ExpectedConditions.presenceOfElementLocated(locator));
+ }
+
+ /**
+ * Click button element
+ * @param locator By
+ * @return clickButton
+ */
+ public WebElement clickButton(By locator) {
+ WebElement buttonElement = locateElement(locator);
+ wait.until(ExpectedConditions.elementToBeClickable(locator));
+ ExpectedConditions.elementToBeClickable(locator);
+ buttonElement.click();
+ return buttonElement;
+ }
+
+ /**
+ * Click element
+ *
+ * @param locator By
+ * @return inputElement
+ */
+ public WebElement clickElement(By locator) {
+ WebElement clickElement = locateElement(locator);
+ clickElement.click();
+ return clickElement;
+ }
+
+ /**
+ * input element
+ *
+ * @param locator By
+ * @param content Input content
+ * @return inputElement
+ */
+ public WebElement sendInput(By locator, String content) {
+ WebElement inputElement = locateElement(locator);
+ inputElement.clear();
+ inputElement.sendKeys(content);
+ return inputElement;
+ }
+ /**
+ * clear element
+ *
+ * @param locator By
+ */
+ public void clearInput(By locator) {
+ WebElement clearElement = locateElement(locator);
+ clearElement.click();
+ clearElement.clear();
+ clearElement.sendKeys(Keys.chord(Keys.CONTROL, "a"));
+ clearElement.sendKeys(Keys.DELETE);
+ }
+
+
+ /**
+ * move to element
+ *
+ * @param locator BY
+ * @return actions
+ */
+ public Actions moveToElement(By locator) {
+ return actions.moveToElement(locateElement(locator));
+ }
+
+ /**
+ * mouse drag element
+ *
+ * @param source_locator BY
+ * @param target_locator BY
+ * @param X X-axis
+ * @param Y Y-axis
+ */
+ public void dragAndDropBy(By source_locator, By target_locator, int X, int
Y) {
+ WebElement sourcetElement = locateElement(source_locator);
+ WebElement targetElement = locateElement(target_locator);
+ actions.dragAndDrop(sourcetElement,
targetElement).moveToElement(targetElement, X, Y).perform();
+ actions.release();
+ }
+
+
+ /**
+ * jump page
+ *
+ * @param url url
+ */
+ public void jumpPage(String url) {
+ driver.get(url);
+ }
+
+
+ /**
+ * Find the next handle, recommended for two windows
+ *
+ * @return driver
+ */
+ public WebDriver switchNextHandle() {
+ // Current window handle
+ String currentHandle = driver.getWindowHandle();
+ // All window handle
+ Set<String> allHandles = driver.getWindowHandles();
+ // Finding the next handle
+ for (String handle : allHandles) {
+ if (!handle.equals(currentHandle)) {
+ return driver.switchTo().window(handle);
+ }
+ }
+ return driver;
+ }
+
+ /**
+ * Multi-window switch handle, according to the handle number passed in
+ *
+ * @param num Number starts from 1
+ * @return driver
+ */
+ public WebDriver switchHandle(int num) {
+ // current handle
+ String currentHandle = driver.getWindowHandle();
+ // all handle
+ Set<String> allHandlesSet = driver.getWindowHandles();
+ List<String> allHandlesList = new ArrayList<>(allHandlesSet);
+ // switch handle
+ return driver.switchTo().window(allHandlesList.get(num - 1));
+ }
+
+ /**
+ * Switch frame structure
+ *
+ * @param locator frame
+ * @return driver
+ */
+ public WebDriver switchFrame(By locator) {
+ return driver.switchTo().frame(locateElement(locator));
+ }
+
+ /**
+ * Switch parent frame structure
+ *
+ * @return driver
+ */
+ public WebDriver switchParentFrame() {
+ return driver.switchTo().parentFrame();
+ }
+
+ /**
+ * Switch out of frame structure
+ *
+ * @return driver
+ */
+ public WebDriver switchOutOfFrame() {
+ return driver.switchTo().defaultContent();
+ }
+
+
+ /**
+ * execute JS Script
+ *
+ * @param script JS script
+ */
+ public void executeScript(String script) {
+ je.executeScript(script);
+ }
+
+ /**
+ * execute JS Script
+ *
+ * @param script JS script
+ * @param args Object element array
+ */
+ public void executeScript(String script, Object... args) {
+ je.executeScript(script, args);
+ }
+
+ /**
+ * Page slide to top
+ */
+ public void scrollToTop() {
+ executeScript("window.scrollTo(0, 0)");
+ }
+
+ /**
+ * Page slides to the bottom
+ */
+ public void scrollToBottom() {
+ executeScript("window.scrollTo(0, document.body.scrollHeight)");
+ }
+
+ /**
+ * Page swipe makes the top of the element align with the top of the page
+ *
+ * @param by Elements that need to be aligned with the top of the page
+ */
+ public void scrollElementTopToTop(By by) {
+ executeScript("arguments[0].scrollIntoView(true);",
driver.findElement(by));
+ }
+
+ /**
+ * Page sliding makes the bottom of the element aligned with the bottom of
the page
+ *
+ * @param by Elements that need to be aligned with the bottom of the page
+ */
+ public void scrollElementBottomToBottom(By by) {
+ executeScript("arguments[0].scrollIntoView(false);",
driver.findElement(by));
+ }
+
+
+ /**
+ * Determine if the current page title is the specified title
+ *
+ * @param title title
+ * @return boolean
+ */
+
+ public boolean ifTitleIs(String title) {
+ return wait.until(ExpectedConditions.titleIs(title));
+ }
+
+ /**
+ * Determines whether the current page title contains the specified text
+ *
+ * @param text text
+ * @return boolean
+ */
+ public boolean ifTitleContains(String text) {
+ return wait.until(ExpectedConditions.titleContains(text));
+ }
+
+ /**
+ * Determines whether the text value of an element on the current page is
the specified text
+ *
+ * @param locator By
+ * @param text text
+ * @return boolean
+ */
+ public boolean ifTextExists(By locator, String text) {
+ return
wait.until(ExpectedConditions.textToBePresentInElementLocated(locator, text));
+ }
+}
diff --git
a/e2e/src/test/java/org/apache/dolphinscheduler/common/PageCommon.java
b/e2e/src/test/java/org/apache/dolphinscheduler/common/PageCommon.java
new file mode 100644
index 0000000..72dc03a
--- /dev/null
+++ b/e2e/src/test/java/org/apache/dolphinscheduler/common/PageCommon.java
@@ -0,0 +1,50 @@
+/*
+ * 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.common;
+
+import org.apache.dolphinscheduler.util.RedisUtil;
+import org.openqa.selenium.WebDriver;
+import redis.clients.jedis.Jedis;
+
+
+/**
+ * Encapsulate the operation methods that can be used for each module page
+ */
+public class PageCommon extends BrowserCommon {
+ /**
+ * @param driver driver
+ */
+ public PageCommon(WebDriver driver) {
+ super(driver);
+ }
+
+ /**
+ * @param driver driver
+ * @param jedis jedis
+ */
+ public PageCommon(WebDriver driver, Jedis jedis) {
+ super(driver, jedis);
+ }
+
+ /**
+ * @param driver driver
+ * @param redisUtil redisUtil
+ */
+ public PageCommon(WebDriver driver, RedisUtil redisUtil) {
+ super(driver, redisUtil);
+ }
+}
diff --git a/e2e/src/test/java/org/apache/dolphinscheduler/data/LoginData.java
b/e2e/src/test/java/org/apache/dolphinscheduler/data/LoginData.java
new file mode 100644
index 0000000..e56df5a
--- /dev/null
+++ b/e2e/src/test/java/org/apache/dolphinscheduler/data/LoginData.java
@@ -0,0 +1,43 @@
+/*
+ * 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.data;
+
+import org.apache.dolphinscheduler.util.PropertiesReader;
+
+/**
+ * Landing page object: data
+ */
+
+public class LoginData {
+ /**
+ * Login URL
+ */
+ public static final String URL = PropertiesReader.getKey("LOGIN_URL");
+
+
+ /**
+ * Login username
+ */
+ public static final String USER = PropertiesReader.getKey("USER_NAME");
+
+ /**
+ * Login password
+ */
+ public static final String PASSWORD = PropertiesReader.getKey("PASSWORD");
+
+ public static final String TENANT = "租户管理 - DolphinScheduler";
+}
diff --git
a/e2e/src/test/java/org/apache/dolphinscheduler/data/project/CreatProjectData.java
b/e2e/src/test/java/org/apache/dolphinscheduler/data/project/CreatProjectData.java
new file mode 100644
index 0000000..8f6c9c8
--- /dev/null
+++
b/e2e/src/test/java/org/apache/dolphinscheduler/data/project/CreatProjectData.java
@@ -0,0 +1,26 @@
+/*
+ * 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.data.project;
+
+public class CreatProjectData {
+ // create project name
+ public static final String PROJECT_NAME = "selenium_project";
+ // create project description
+ public static final String DESCRIPTION = "test create project description";
+ // project page title
+ public static final String PROJECT_TITLE = "项目 - DolphinScheduler";
+}
diff --git
a/e2e/src/test/java/org/apache/dolphinscheduler/data/project/CreatWorkflowData.java
b/e2e/src/test/java/org/apache/dolphinscheduler/data/project/CreatWorkflowData.java
new file mode 100644
index 0000000..1e45d47
--- /dev/null
+++
b/e2e/src/test/java/org/apache/dolphinscheduler/data/project/CreatWorkflowData.java
@@ -0,0 +1,36 @@
+/*
+ * 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.data.project;
+
+public class CreatWorkflowData {
+ //input shell task name
+ public static final String SHELL_TASK_NAME = "shell task description test";
+
+ //input shell task description
+ public static final String SHELL_TASK_DESCRIPTION = "shell task
description test";
+
+ //input timeout
+ public static final String INPUT_TIMEOUT = "60";
+
+ //input shell script
+ public static final String SHELL_SCRIPT = "echo 1111111";
+
+ public static final String WORKFLOW_TITLE = "创建流程定义 - DolphinScheduler";
+
+
+
+}
diff --git
a/e2e/src/test/java/org/apache/dolphinscheduler/data/security/TenantManageData.java
b/e2e/src/test/java/org/apache/dolphinscheduler/data/security/TenantManageData.java
new file mode 100644
index 0000000..b791c07
--- /dev/null
+++
b/e2e/src/test/java/org/apache/dolphinscheduler/data/security/TenantManageData.java
@@ -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.
+ */
+
+/**
+ * Tenant page object: data
+ */
+package org.apache.dolphinscheduler.data.security;
+
+import org.apache.dolphinscheduler.data.LoginData;
+
+public class TenantManageData {
+ /**
+ * Tenant URL
+ */
+ public static final String TENANAT_URL = LoginData.URL +
"/ui/#/security/tenant";
+
+ /**
+ * Tenant Code
+ */
+ public static final String TENANAT_CODE = "dolphinscheduler_tenant_code2";
+
+ /**
+ * Tenant Name
+ */
+ public static final String TENANAT_NAME = "dolphinscheduler_tenant_Name";
+
+ /**
+ * Queue
+ */
+ public static final String QUEUE = "default";
+
+ /**
+ * Description
+ */
+ public static final String DESCRIPTION = "creat tenant test";
+
+ public static final String TENANAT_MANAGE = "租户管理 - DolphinScheduler";
+
+
+
+}
diff --git
a/e2e/src/test/java/org/apache/dolphinscheduler/data/security/UserManageData.java
b/e2e/src/test/java/org/apache/dolphinscheduler/data/security/UserManageData.java
new file mode 100644
index 0000000..03c985f
--- /dev/null
+++
b/e2e/src/test/java/org/apache/dolphinscheduler/data/security/UserManageData.java
@@ -0,0 +1,34 @@
+/*
+ * 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.data.security;
+
+import org.apache.dolphinscheduler.data.LoginData;
+
+public class UserManageData {
+ public static final String USER_URL = LoginData.URL +
"/ui/#/security/users";
+
+ public static final String USERNAME = "selenium111";
+
+ public static final String PASSWORD = "123456qwe";
+
+ public static final String EMAIL = "[email protected]";
+
+ public static final String PHONE = "15811112222";
+
+ public static final String USER_MANAGE = "用户管理 - DolphinScheduler";
+
+}
diff --git
a/e2e/src/test/java/org/apache/dolphinscheduler/locator/LoginLocator.java
b/e2e/src/test/java/org/apache/dolphinscheduler/locator/LoginLocator.java
new file mode 100644
index 0000000..32a82bb
--- /dev/null
+++ b/e2e/src/test/java/org/apache/dolphinscheduler/locator/LoginLocator.java
@@ -0,0 +1,33 @@
+/*
+ * 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.locator;
+
+import org.openqa.selenium.By;
+
+/**
+ * Page object: element positioning
+ */
+
+public class LoginLocator {
+ public static final By LOGIN_INPUT_USER =
By.xpath("//input[@class='input-element suffix']");
+
+ public static final By LOGIN_INPUT_PASSWORD =
By.xpath("//input[@class='input-element suffix']");
+
+ public static final By LOGIN_BUTTON = By.xpath("//button");
+
+ public static final By LOGIN_BUTTON_MOVE = By.xpath("//button[contains(.,'
Loading...')]");
+}
diff --git
a/e2e/src/test/java/org/apache/dolphinscheduler/locator/project/CreateProjectLocator.java
b/e2e/src/test/java/org/apache/dolphinscheduler/locator/project/CreateProjectLocator.java
new file mode 100644
index 0000000..d2c0d84
--- /dev/null
+++
b/e2e/src/test/java/org/apache/dolphinscheduler/locator/project/CreateProjectLocator.java
@@ -0,0 +1,36 @@
+/*
+ * 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.locator.project;
+
+import org.openqa.selenium.By;
+
+public class CreateProjectLocator {
+ //click project manage
+ public static final By PROJECT_MANAGE = By.xpath("//div[2]/div/a/span");
+
+ //click create project button
+ public static final By CREATE_PROJECT_BUTTON = By.xpath("//button/span");
+
+ //input project name
+ public static final By PROJECT_NAME =
By.xpath("//div[2]/div/div/div[2]/div/input");
+
+ //input project description
+ public static final By PROJECT_DESCRIPTION = By.xpath("//textarea");
+
+ //submit button
+ public static final By SUBMIT_BUTTON = By.xpath("//div[3]/button[2]/span");
+}
diff --git
a/e2e/src/test/java/org/apache/dolphinscheduler/locator/project/CreateWorkflowLocator.java
b/e2e/src/test/java/org/apache/dolphinscheduler/locator/project/CreateWorkflowLocator.java
new file mode 100644
index 0000000..3bea648
--- /dev/null
+++
b/e2e/src/test/java/org/apache/dolphinscheduler/locator/project/CreateWorkflowLocator.java
@@ -0,0 +1,97 @@
+/*
+ * 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.locator.project;
+
+import org.openqa.selenium.By;
+
+public class CreateWorkflowLocator {
+ // click project manage
+ public static final By CLICK_PROJECT_MANAGE =
By.xpath("//div[2]/div/a/span");
+
+ // click project name
+ public static final By CLICK_PROJECT_NAME = By.xpath("//span/a");
+
+ // click workflow define
+ public static final By CLICK_WORKFLOW_DEFINE = By.xpath("//li/span");
+
+ // click create workflow button
+ public static final By CLICK_CREATE_WORKFLOW_BUTTON =
By.xpath("//button/span");
+
+ //mouse down at shell
+ public static final By MOUSE_DOWN_AT_SHELL =
By.xpath("//*[@id='SHELL']/div/div");
+
+ //mouse down at spark
+ public static final By MOUSE_DOWN_AT_SPARK = By.xpath("//div[5]/div/div");
+
+ //mouse move at DAG
+ public static final By MOUSE_MOVE_SHELL_AT_DAG =
By.xpath("//div[2]/div/div[2]/div[2]/div/div");
+
+// //click shell task
+// public static final By CLICK_SHELL_TASK =
By.xpath("//div[2]/div/div[2]/div[2]/div/div");
+
+ //input shell task _name
+ public static final By INPUT_SHELL_TASK_NAME = By.xpath("//input");
+
+ //click stop run type
+ public static final By CLICK_STOP_RUN_TYPE =
By.xpath("//label[2]/span/input");
+
+ //click normal run type
+ public static final By CLICK_NORMAL_RUN_TYPE = By.xpath("//span/input");
+
+ //input shell task description
+ public static final By INPUT_SHELL_TASK_DESCRIPTION =
By.xpath("//label/div/textarea");
+
+ //click task priority
+ public static final By CLICK_TASK_PRIORITY =
By.xpath("//span/div/div/div/div/div");
+
+ //select task priority
+ public static final By SELECT_TASK_PRIORITY = By.xpath("//li[2]/li/span");
+
+ //click work group
+ public static final By CLICK_WORK_GROUP = By.xpath("//div/div/input");
+
+ //select work group
+ public static final By SELECT_WORK_GROUP =
By.xpath("//div[4]/div[2]/div/div[1]/div/input");
+
+ //select number of failed retries
+ public static final By SELECT_FAIL_RETRIES_NUMBER =
By.xpath("//div[5]/div[2]/div[1]/div[1]/div/input");
+
+ //select failed retry interval
+ public static final By SELECT_FAIL_RETRIES_INTERVAL =
By.xpath("//div[5]/div[2]/div[2]/div[1]/div/input");
+
+ //click timeout alarm
+ public static final By CLICK_TIMEOUT_ALARM =
By.xpath("//label/div/span/span");
+
+ //select timeout fail
+ public static final By SELECT_TIMEOUT_FAIL =
By.xpath("//div/div/label[2]/span/input");
+
+ //cancel timeout alarm
+ public static final By CANCEL_TIMEOUT_ALARM =
By.xpath("//div/div/label/span/input");
+
+ //select timeout alarm
+ public static final By SELECT_TIMEOUT_ALARM =
By.xpath("//div/div/label/span/input");
+
+ //input timeout
+ public static final By SELECT_TIMEOUT =
By.xpath("//div[3]/div[2]/label/div/input");
+
+ //input script
+ public static final By INPUT_SCRIPT =
By.xpath("//div[2]/div/div/div/div/div/textarea");
+
+
+
+}
diff --git
a/e2e/src/test/java/org/apache/dolphinscheduler/locator/security/TenantManageLocator.java
b/e2e/src/test/java/org/apache/dolphinscheduler/locator/security/TenantManageLocator.java
new file mode 100644
index 0000000..7d9c8a5
--- /dev/null
+++
b/e2e/src/test/java/org/apache/dolphinscheduler/locator/security/TenantManageLocator.java
@@ -0,0 +1,33 @@
+/*
+ * 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.locator.security;
+
+import org.openqa.selenium.By;
+
+public class TenantManageLocator{
+ public static final By CREATE_TENANT_BUTTON =
By.xpath("//button[@class='ans-btn ans-btn-ghost ans-btn-small']");
+
+ public static final By TENANT_INPUT_CODE =
By.xpath("//div[2]/div/div/div[2]/div/input");
+
+ public static final By TENANT_INPUT_NAME =
By.xpath("//div[2]/div[2]/div/input");
+
+ public static final By QUEUE = By.xpath("//textarea");
+
+ public static final By DESCRIPTION = By.xpath("//textarea");
+
+ public static final By SUBMIT_BUTTON = By.xpath("//div[3]/button[2]/span");
+}
diff --git
a/e2e/src/test/java/org/apache/dolphinscheduler/locator/security/UserManageLocator.java
b/e2e/src/test/java/org/apache/dolphinscheduler/locator/security/UserManageLocator.java
new file mode 100644
index 0000000..0d84692
--- /dev/null
+++
b/e2e/src/test/java/org/apache/dolphinscheduler/locator/security/UserManageLocator.java
@@ -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.locator.security;
+
+import org.openqa.selenium.By;
+
+public class UserManageLocator {
+
+ public static final By CLICK_USER_MANAGE =
By.xpath("//div[3]/div/a/div/a/span");
+
+ public static final By CLICK_CREATE_USER_BUTTON =
By.xpath("//span[contains(.,'创建用户')]");
+
+ public static final By INPUT_USERNAME =
By.xpath("//div[2]/div/div/div[2]/div/input");
+
+ public static final By INPUT_PASSWORD =
By.xpath("//div[2]/div[2]/div/input");
+
+ public static final By CLICK_TENANT =
By.xpath("//div[3]/div[2]/div/div/div/input");
+
+ public static final By SELECT_TENANT =
By.xpath("//div[3]/div[2]/div/div[2]/div/div/div/ul/li/span");
+
+ public static final By CLICK_QUEUE =
By.xpath("//div[4]/div[2]/div/div/div/input");
+
+ public static final By SELECT_QUEUE =
By.xpath("//div[4]/div[2]/div/div[2]/div/div/div/ul/li/span");
+
+ public static final By TENANT_INPUT_EMAIL =
By.xpath("//div[5]/div[2]/div/input");
+
+ public static final By TENANT_INPUT_PHONE =
By.xpath("//div[6]/div[2]/div/input");
+
+ public static final By SUBMIT = By.xpath("//div[3]/button[2]/span");
+
+}
diff --git a/e2e/src/test/java/org/apache/dolphinscheduler/page/LoginPage.java
b/e2e/src/test/java/org/apache/dolphinscheduler/page/LoginPage.java
new file mode 100644
index 0000000..cd6b318
--- /dev/null
+++ b/e2e/src/test/java/org/apache/dolphinscheduler/page/LoginPage.java
@@ -0,0 +1,65 @@
+/*
+ * 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.page;
+
+import org.apache.dolphinscheduler.common.PageCommon;
+import org.apache.dolphinscheduler.constant.TestConstant;
+import org.apache.dolphinscheduler.data.LoginData;
+import org.apache.dolphinscheduler.locator.LoginLocator;
+import org.apache.dolphinscheduler.util.RedisUtil;
+import org.openqa.selenium.WebDriver;
+
+
+
+public class LoginPage extends PageCommon {
+ /**
+ * Unique constructor
+ * @param driver driver
+ */
+ public LoginPage(WebDriver driver) {
+ super(driver);
+ }
+
+
+ /**
+ * jump page
+ */
+ public void jumpPage() {
+ System.out.println("jump login page");
+ super.jumpPage(LoginData.URL);
+ }
+
+ /**
+ * login
+ *
+ * @return Whether to enter the specified page after searching
+ */
+ public boolean login() throws InterruptedException {
+ System.out.println("LoginPage");
+ // login data
+ sendInput(LoginLocator.LOGIN_INPUT_USER, LoginData.USER);
+ sendInput(LoginLocator.LOGIN_INPUT_PASSWORD, LoginData.PASSWORD);
+
+ // click login button
+ clickButton(LoginLocator.LOGIN_BUTTON);
+
+ moveToElement(LoginLocator.LOGIN_BUTTON_MOVE);
+
+ // Whether to enter the specified page after login
+ return ifTitleContains(LoginData.TENANT);
+ }
+}
diff --git
a/e2e/src/test/java/org/apache/dolphinscheduler/page/project/CreateProjectPage.java
b/e2e/src/test/java/org/apache/dolphinscheduler/page/project/CreateProjectPage.java
new file mode 100644
index 0000000..7961715
--- /dev/null
+++
b/e2e/src/test/java/org/apache/dolphinscheduler/page/project/CreateProjectPage.java
@@ -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.page.project;
+
+import org.apache.dolphinscheduler.common.PageCommon;
+import org.apache.dolphinscheduler.constant.TestConstant;
+import org.apache.dolphinscheduler.data.project.CreatProjectData;
+import org.apache.dolphinscheduler.locator.project.CreateProjectLocator;
+import org.openqa.selenium.WebDriver;
+
+public class CreateProjectPage extends PageCommon {
+ public CreateProjectPage(WebDriver driver) {
+ super(driver);
+ }
+ /**
+ * jump page
+ */
+ public void jumpPage() throws InterruptedException {
+ Thread.sleep(TestConstant.ONE_THOUSANG);
+ clickElement(CreateProjectLocator.PROJECT_MANAGE);
+ }
+
+ /**
+ * creatTenant
+ *
+ * @return Whether to enter the specified page after creat tenant
+ */
+ public boolean createProject() throws InterruptedException {
+ Thread.sleep(TestConstant.ONE_THOUSANG);
+ //click create project
+ clickElement(CreateProjectLocator.CREATE_PROJECT_BUTTON);
+ Thread.sleep(TestConstant.ONE_THOUSANG);
+
+ // input create project data
+ sendInput(CreateProjectLocator.PROJECT_NAME,
CreatProjectData.PROJECT_NAME);
+ sendInput(CreateProjectLocator.PROJECT_DESCRIPTION,
CreatProjectData.DESCRIPTION);
+
+ // click submit button
+ clickButton(CreateProjectLocator.SUBMIT_BUTTON);
+
+ // Whether to enter the specified page after submit
+ return ifTitleContains(CreatProjectData.PROJECT_TITLE);
+ }
+}
diff --git
a/e2e/src/test/java/org/apache/dolphinscheduler/page/project/CreateWorkflowPage.java
b/e2e/src/test/java/org/apache/dolphinscheduler/page/project/CreateWorkflowPage.java
new file mode 100644
index 0000000..827198b
--- /dev/null
+++
b/e2e/src/test/java/org/apache/dolphinscheduler/page/project/CreateWorkflowPage.java
@@ -0,0 +1,108 @@
+/*
+ * 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.page.project;
+
+import org.apache.dolphinscheduler.common.PageCommon;
+import org.apache.dolphinscheduler.constant.TestConstant;
+import org.apache.dolphinscheduler.data.project.CreatWorkflowData;
+import org.apache.dolphinscheduler.locator.project.CreateProjectLocator;
+import org.apache.dolphinscheduler.locator.project.CreateWorkflowLocator;
+import org.openqa.selenium.WebDriver;
+
+public class CreateWorkflowPage extends PageCommon {
+ public CreateWorkflowPage(WebDriver driver) {
+ super(driver);
+ }
+ /**
+ * jump page
+ */
+ public boolean CreateWorkflow() throws InterruptedException {
+ Thread.sleep(TestConstant.ONE_THOUSANG);
+ // click project manage
+ clickElement(CreateProjectLocator.PROJECT_MANAGE);
+ Thread.sleep(TestConstant.ONE_THOUSANG);
+
+ // click project name
+ clickElement(CreateWorkflowLocator.CLICK_PROJECT_NAME);
+ Thread.sleep(TestConstant.ONE_THOUSANG);
+
+ // click workflow define
+ clickElement(CreateWorkflowLocator.CLICK_WORKFLOW_DEFINE);
+
+ // click create workflow button
+ clickElement(CreateWorkflowLocator.CLICK_CREATE_WORKFLOW_BUTTON);
+
+ //drag shell_task
+
dragAndDropBy(CreateWorkflowLocator.MOUSE_DOWN_AT_SHELL,CreateWorkflowLocator.MOUSE_MOVE_SHELL_AT_DAG,
3 ,6);
+
+ //input shell task _name
+ sendInput(CreateWorkflowLocator.INPUT_SHELL_TASK_NAME ,
CreatWorkflowData.SHELL_TASK_NAME);
+
+ //click stop run type
+ clickElement(CreateWorkflowLocator.CLICK_STOP_RUN_TYPE);
+
+
+ //click normal run type
+ clickElement(CreateWorkflowLocator.CLICK_NORMAL_RUN_TYPE);
+
+
+ //input shell task description
+ sendInput(CreateWorkflowLocator.INPUT_SHELL_TASK_DESCRIPTION ,
CreatWorkflowData.SHELL_TASK_DESCRIPTION);
+
+ //select task priority
+ clickElement(CreateWorkflowLocator.CLICK_TASK_PRIORITY);
+ clickElement(CreateWorkflowLocator.SELECT_TASK_PRIORITY);
+
+ //select work group
+ clickElement(CreateWorkflowLocator.CLICK_WORK_GROUP);
+ clickElement(CreateWorkflowLocator.SELECT_WORK_GROUP);
+
+ //select number of failed retries
+ clickElement(CreateWorkflowLocator.SELECT_FAIL_RETRIES_NUMBER);
+
+ //select failed retry interval
+ clickElement(CreateWorkflowLocator.SELECT_FAIL_RETRIES_INTERVAL);
+
+
+ //click timeout alarm
+ clickElement(CreateWorkflowLocator.CLICK_TIMEOUT_ALARM);
+
+
+ //select timeout fail
+ clickElement(CreateWorkflowLocator.SELECT_TIMEOUT_FAIL);
+
+
+ //cancel timeout alarm
+ clickElement(CreateWorkflowLocator.CANCEL_TIMEOUT_ALARM);
+
+
+ //select timeout alarm
+ clickElement(CreateWorkflowLocator.SELECT_TIMEOUT_ALARM);
+
+ //clear input
+ clearInput(CreateWorkflowLocator.SELECT_TIMEOUT);
+ Thread.sleep(TestConstant.ONE_THOUSANG);
+
+ //input timeout
+
sendInput(CreateWorkflowLocator.SELECT_TIMEOUT,CreatWorkflowData.INPUT_TIMEOUT);
+
+ //input script
+ sendInput(CreateWorkflowLocator.INPUT_SCRIPT,
CreatWorkflowData.SHELL_SCRIPT);
+
+ return ifTitleContains(CreatWorkflowData.WORKFLOW_TITLE);
+ }
+}
diff --git
a/e2e/src/test/java/org/apache/dolphinscheduler/page/security/TenantManagePage.java
b/e2e/src/test/java/org/apache/dolphinscheduler/page/security/TenantManagePage.java
new file mode 100644
index 0000000..4c88f65
--- /dev/null
+++
b/e2e/src/test/java/org/apache/dolphinscheduler/page/security/TenantManagePage.java
@@ -0,0 +1,69 @@
+/*
+ * 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.page.security;
+
+import org.apache.dolphinscheduler.common.PageCommon;
+import org.apache.dolphinscheduler.constant.TestConstant;
+import org.apache.dolphinscheduler.data.LoginData;
+import org.apache.dolphinscheduler.data.security.TenantManageData;
+import org.apache.dolphinscheduler.locator.LoginLocator;
+import org.apache.dolphinscheduler.locator.security.TenantManageLocator;
+import org.apache.dolphinscheduler.util.RedisUtil;
+import org.openqa.selenium.WebDriver;
+
+public class TenantManagePage extends PageCommon {
+ /**
+ * Unique constructor
+ * @param driver driver
+ */
+ public TenantManagePage(WebDriver driver) {
+ super(driver);
+ }
+
+
+ /**
+ * jump page
+ */
+ public void jumpPage() {
+ System.out.println("jump tenant page");
+ super.jumpPage(TenantManageData.TENANAT_URL);
+ }
+
+ /**
+ * createTenant
+ *
+ * @return Whether to enter the specified page after creat tenant
+ */
+ public boolean createTenant() throws InterruptedException {
+ Thread.sleep(TestConstant.ONE_THOUSANG);
+
+ //create tenant
+ clickButton(TenantManageLocator.CREATE_TENANT_BUTTON);
+
+ // tenant data
+ sendInput(TenantManageLocator.TENANT_INPUT_CODE,
TenantManageData.TENANAT_CODE);
+ sendInput(TenantManageLocator.TENANT_INPUT_NAME,
TenantManageData.TENANAT_NAME);
+ sendInput(TenantManageLocator.QUEUE, TenantManageData.QUEUE);
+ sendInput(TenantManageLocator.DESCRIPTION,
TenantManageData.DESCRIPTION);
+
+ // click button
+ clickButton(TenantManageLocator.SUBMIT_BUTTON);
+
+ // Whether to enter the specified page after submit
+ return ifTitleContains(TenantManageData.TENANAT_MANAGE);
+ }
+}
diff --git
a/e2e/src/test/java/org/apache/dolphinscheduler/page/security/UserManagePage.java
b/e2e/src/test/java/org/apache/dolphinscheduler/page/security/UserManagePage.java
new file mode 100644
index 0000000..3e2be2d
--- /dev/null
+++
b/e2e/src/test/java/org/apache/dolphinscheduler/page/security/UserManagePage.java
@@ -0,0 +1,67 @@
+/*
+ * 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.page.security;
+
+import org.apache.dolphinscheduler.common.PageCommon;
+import org.apache.dolphinscheduler.constant.TestConstant;
+import org.apache.dolphinscheduler.data.security.UserManageData;
+import org.apache.dolphinscheduler.locator.security.UserManageLocator;
+import org.openqa.selenium.WebDriver;
+
+public class UserManagePage extends PageCommon {
+ public UserManagePage(WebDriver driver) {
+ super(driver);
+ }
+ /**
+ * jump page
+ */
+ public void jumpPage() {
+ System.out.println("jump tenant page");
+ super.jumpPage(UserManageData.USER_URL);
+ }
+
+ /**
+ * creatTenant
+ *
+ * @return Whether to enter the specified page after creat tenant
+ */
+ public boolean createUser() throws InterruptedException {
+ Thread.sleep(TestConstant.ONE_THOUSANG);
+ // click user manage
+ clickElement(UserManageLocator.CLICK_USER_MANAGE);
+ Thread.sleep(TestConstant.ONE_THOUSANG);
+
+ // click create user button
+ clickButton(UserManageLocator.CLICK_CREATE_USER_BUTTON);
+
+ // input user data
+ sendInput(UserManageLocator.INPUT_USERNAME, UserManageData.USERNAME);
+ sendInput(UserManageLocator.INPUT_PASSWORD, UserManageData.PASSWORD);
+ clickButton(UserManageLocator.CLICK_TENANT);
+ clickButton(UserManageLocator.SELECT_TENANT);
+ clickButton(UserManageLocator.CLICK_QUEUE);
+ clickButton(UserManageLocator.SELECT_QUEUE);
+ sendInput(UserManageLocator.TENANT_INPUT_EMAIL, UserManageData.EMAIL);
+ sendInput(UserManageLocator.TENANT_INPUT_PHONE, UserManageData.PHONE);
+
+ // click button
+ clickButton(UserManageLocator.SUBMIT);
+
+ // Whether to enter the specified page after submit
+ return ifTitleContains(UserManageData.USER_MANAGE);
+ }
+}
diff --git
a/e2e/src/test/java/org/apache/dolphinscheduler/testcase/LoginTest.java
b/e2e/src/test/java/org/apache/dolphinscheduler/testcase/LoginTest.java
new file mode 100644
index 0000000..bd3c31d
--- /dev/null
+++ b/e2e/src/test/java/org/apache/dolphinscheduler/testcase/LoginTest.java
@@ -0,0 +1,37 @@
+/*
+ * 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.testcase;
+
+import org.apache.dolphinscheduler.base.BaseTest;
+import org.apache.dolphinscheduler.page.LoginPage;
+import org.testng.annotations.Test;
+
+
+public class LoginTest extends BaseTest {
+ private LoginPage loginPage;
+ @Test(description = "LoginTest", priority = 1)
+ public void testLogin() throws InterruptedException {
+ // init login page
+ loginPage = new LoginPage(driver);
+
+ // enter login page
+ loginPage.jumpPage();
+
+ //assert login page
+ assert loginPage.login();
+ }
+}
diff --git
a/e2e/src/test/java/org/apache/dolphinscheduler/testcase/project/CreateProjectTest.java
b/e2e/src/test/java/org/apache/dolphinscheduler/testcase/project/CreateProjectTest.java
new file mode 100644
index 0000000..66af105
--- /dev/null
+++
b/e2e/src/test/java/org/apache/dolphinscheduler/testcase/project/CreateProjectTest.java
@@ -0,0 +1,36 @@
+/*
+ * 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.testcase.project;
+
+import org.apache.dolphinscheduler.base.BaseTest;
+import org.apache.dolphinscheduler.page.project.CreateProjectPage;
+import org.testng.annotations.Test;
+
+public class CreateProjectTest extends BaseTest {
+ private CreateProjectPage createProjectPage;
+
+ @Test(description = "TenantTest", priority = 1)
+ public void testUserManage() throws InterruptedException {
+ createProjectPage = new CreateProjectPage(driver);
+ // enter user manage page
+ createProjectPage.jumpPage();
+ //assert user manage page
+ assert createProjectPage.createProject();
+ }
+
+}
+
diff --git
a/e2e/src/test/java/org/apache/dolphinscheduler/testcase/project/CreateWorkflowTest.java
b/e2e/src/test/java/org/apache/dolphinscheduler/testcase/project/CreateWorkflowTest.java
new file mode 100644
index 0000000..ac1bfec
--- /dev/null
+++
b/e2e/src/test/java/org/apache/dolphinscheduler/testcase/project/CreateWorkflowTest.java
@@ -0,0 +1,34 @@
+/*
+ * 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.testcase.project;
+
+import org.apache.dolphinscheduler.base.BaseTest;
+import org.apache.dolphinscheduler.page.project.CreateWorkflowPage;
+import org.testng.annotations.Test;
+
+public class CreateWorkflowTest extends BaseTest {
+ private CreateWorkflowPage createWorkflowPage;
+
+ @Test(description = "CreateWorkflowTest", priority = 1)
+ public void CreateWorkflowTest() throws InterruptedException {
+ createWorkflowPage = new CreateWorkflowPage(driver);
+ // enter user manage page
+// createWorkflowPage.jumpPage();
+ //assert user manage page
+ assert createWorkflowPage.CreateWorkflow();
+ }
+}
diff --git
a/e2e/src/test/java/org/apache/dolphinscheduler/testcase/security/TenantManageTest.java
b/e2e/src/test/java/org/apache/dolphinscheduler/testcase/security/TenantManageTest.java
new file mode 100644
index 0000000..7124b4e
--- /dev/null
+++
b/e2e/src/test/java/org/apache/dolphinscheduler/testcase/security/TenantManageTest.java
@@ -0,0 +1,34 @@
+/*
+ * 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.testcase.security;
+
+import org.apache.dolphinscheduler.base.BaseTest;
+import org.apache.dolphinscheduler.page.security.TenantManagePage;
+import org.testng.annotations.Test;
+
+public class TenantManageTest extends BaseTest {
+ private TenantManagePage tenantManagePage;
+
+ @Test(description = "TenantTest", priority = 1)
+ public void testTenantManage() throws InterruptedException {
+ tenantManagePage = new TenantManagePage(driver);
+ // enter tenant manage page
+ tenantManagePage.jumpPage();
+ //assert tenant manage page
+ assert tenantManagePage.createTenant();
+ }
+}
diff --git
a/e2e/src/test/java/org/apache/dolphinscheduler/testcase/security/UserManageTest.java
b/e2e/src/test/java/org/apache/dolphinscheduler/testcase/security/UserManageTest.java
new file mode 100644
index 0000000..834ebdb
--- /dev/null
+++
b/e2e/src/test/java/org/apache/dolphinscheduler/testcase/security/UserManageTest.java
@@ -0,0 +1,34 @@
+/*
+ * 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.testcase.security;
+
+import org.apache.dolphinscheduler.base.BaseTest;
+import org.apache.dolphinscheduler.page.security.UserManagePage;
+import org.testng.annotations.Test;
+
+public class UserManageTest extends BaseTest {
+ private UserManagePage userManagePage;
+
+ @Test(description = "TenantTest", priority = 1)
+ public void testUserManage() throws InterruptedException {
+ userManagePage = new UserManagePage(driver);
+ // enter user manage page
+ userManagePage.jumpPage();
+ //assert user manage page
+ assert userManagePage.createUser();
+ }
+}
diff --git a/e2e/src/test/resources/config/config.properties
b/e2e/src/test/resources/config/config.properties
new file mode 100644
index 0000000..e3ee61c
--- /dev/null
+++ b/e2e/src/test/resources/config/config.properties
@@ -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.
+#
+
+############### project ##############
+# login url
+LOGIN_URL=http://ark1:12345/dolphinscheduler
+#login username
+USER_NAME=admin
+#login password
+PASSWORD=123456
+
+############### web driver ##############
+# driver path
+driver.chromeDriver=/Users/chenxingchun/Documents/easyscheduler/selenium/chromeDriver
+# implicitly wait(s)
+driver.timeouts.implicitlyWait=10
+# show wait(s)
+driver.timeouts.webDriverWait=10
+# page load timeout(s)
+driver.timeouts.pageLoadTimeout=10
+# JS wait timeouts(s)
+driver.timeouts.setScriptTimeout=10
+
+
+############### redis ##############
+# redis ip
+redis.ip=127.0.0.1
+# redis port
+redis.port=6379
+# redis password
+redis.pwd=
+############### redis pool ##############
+# jedis expireTime(s)
+jedis.expireTime=3600
+# jedis maxTotal
+jedis.pool.maxTotal=3000
+# jedis maxIdle
+jedis.pool.maxIdle=1000
+# jedis maxWaitMillis
+jedis.pool.maxWaitMillis=10000
+# jedis Whether to perform a valid check when calling the borrowObject method
+jedis.pool.testOnBorrow=true
+# jedis Whether to perform a valid check when calling the returnObject method
+jedis.pool.testOnReturn=true
\ No newline at end of file
diff --git a/e2e/suite.xml b/e2e/suite.xml
new file mode 100644
index 0000000..d9d7ae6
--- /dev/null
+++ b/e2e/suite.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
+<suite name="e2e Test Suite" parallel="tests" thread-count="2">
+ <!-- create tenant -->
+ <test name="create-tenant" preserve-order="true">
+ <classes>
+ <class
name="org.apache.dolphinscheduler.testcase.security.TenantManageTest">
+ </class>
+ </classes>
+ </test>
+ <!-- create user -->
+ <test name="create-user" preserve-order="true">
+ <classes>
+ <class
name="org.apache.dolphinscheduler.testcase.security.UserManageTest">
+ </class>
+ </classes>
+ </test>
+</suite>
\ No newline at end of file
diff --git a/e2e/testng.xml b/e2e/testng.xml
new file mode 100644
index 0000000..60d2541
--- /dev/null
+++ b/e2e/testng.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
+<suite name="dolphinscheduler_e2e" parallel="false">
+ <test name="dolphinscheduler_test">
+ <!--<packages>-->
+ <!--<!–<package
name="org.apache.dolphinscheduler.testcase.security.TenantManageTest"/>–>-->
+ <!--<package
name="org.apache.dolphinscheduler.testcase.security.*"/>-->
+ <!--</packages>-->
+ <!--<classes>-->
+ <!--<class
name="org.apache.dolphinscheduler.testcase.security.UserManageTest"></class>-->
+ <!--</classes>-->
+ </test>
+
+ <!--<suite-files>-->
+ <!--<suite-file path="suite.xml"/>-->
+ <!--</suite-files>-->
+
+ <listeners>
+ <listener class-name="org.uncommons.reportng.HTMLReporter" />
+ <listener class-name="org.uncommons.reportng.JUnitXMLReporter" />
+ </listeners>
+</suite>
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index ee2d808..076b856 100644
--- a/pom.xml
+++ b/pom.xml
@@ -242,7 +242,6 @@
<artifactId>dolphinscheduler-alert</artifactId>
<version>${project.version}</version>
</dependency>
-
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>