Browse Source

Merge pull request #15 from apache/dev

update code
pull/3/MERGE
BoYiZhang 4 years ago committed by GitHub
parent
commit
5ea402252a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 31
      docker/build/Dockerfile
  2. 71
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/TaskParametersUtils.java
  3. 1
      dolphinscheduler-dist/release-docs/LICENSE
  4. 19
      dolphinscheduler-dist/release-docs/licenses/ui-licenses/LICENSE-dagre
  5. 10
      dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/worker/task/TaskManager.java
  6. 19
      dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/worker/task/TaskManagerTest.java
  7. 1
      dolphinscheduler-ui/package.json
  8. 212
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/dag.js
  9. 19
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/list.vue
  10. 11
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/instance/pages/list/_source/list.vue
  11. 2
      dolphinscheduler-ui/src/js/conf/home/pages/user/pages/password/_source/info.vue
  12. 10
      e2e/pom.xml
  13. 45
      e2e/src/main/java/org/apache/dolphinscheduler/util/YmlReader.java
  14. 1
      e2e/src/test/java/org/apache/dolphinscheduler/base/BaseDriver.java
  15. 3
      e2e/src/test/java/org/apache/dolphinscheduler/data/LoginData.java
  16. 12
      e2e/src/test/java/org/apache/dolphinscheduler/data/project/ProcessInstanceData.java
  17. 16
      e2e/src/test/java/org/apache/dolphinscheduler/data/project/ProjectData.java
  18. 19
      e2e/src/test/java/org/apache/dolphinscheduler/data/project/RunWorkflowData.java
  19. 25
      e2e/src/test/java/org/apache/dolphinscheduler/data/project/TimingData.java
  20. 76
      e2e/src/test/java/org/apache/dolphinscheduler/data/project/WorkflowDefineData.java
  21. 18
      e2e/src/test/java/org/apache/dolphinscheduler/data/security/AlertManageData.java
  22. 31
      e2e/src/test/java/org/apache/dolphinscheduler/data/security/QueueManageData.java
  23. 30
      e2e/src/test/java/org/apache/dolphinscheduler/data/security/TenantManageData.java
  24. 15
      e2e/src/test/java/org/apache/dolphinscheduler/data/security/TokenManageData.java
  25. 29
      e2e/src/test/java/org/apache/dolphinscheduler/data/security/UserManageData.java
  26. 2
      e2e/src/test/java/org/apache/dolphinscheduler/locator/project/WorkflowDefineLocator.java
  27. 6
      e2e/src/test/java/org/apache/dolphinscheduler/locator/security/TokenManageLocator.java
  28. 2
      e2e/src/test/java/org/apache/dolphinscheduler/locator/security/UserManageLocator.java
  29. 8
      e2e/src/test/java/org/apache/dolphinscheduler/page/LoginPage.java
  30. 4
      e2e/src/test/java/org/apache/dolphinscheduler/page/project/ProcessInstancePage.java
  31. 15
      e2e/src/test/java/org/apache/dolphinscheduler/page/project/ProjectPage.java
  32. 11
      e2e/src/test/java/org/apache/dolphinscheduler/page/project/RunWorkflowPage.java
  33. 31
      e2e/src/test/java/org/apache/dolphinscheduler/page/project/TimingPage.java
  34. 57
      e2e/src/test/java/org/apache/dolphinscheduler/page/project/WorkflowDefinePage.java
  35. 14
      e2e/src/test/java/org/apache/dolphinscheduler/page/security/AlertManagePage.java
  36. 18
      e2e/src/test/java/org/apache/dolphinscheduler/page/security/QueueManagePage.java
  37. 16
      e2e/src/test/java/org/apache/dolphinscheduler/page/security/TenantManagePage.java
  38. 14
      e2e/src/test/java/org/apache/dolphinscheduler/page/security/TokenManagePage.java
  39. 33
      e2e/src/test/java/org/apache/dolphinscheduler/page/security/UserManagePage.java
  40. 55
      e2e/src/test/resources/testData/security_zh_cn.yml
  41. 63
      e2e/src/test/resources/testData/workflow_zh_cn.yml
  42. 2
      e2e/testng.xml

31
docker/build/Dockerfile

@ -27,13 +27,13 @@ ENV DEBIAN_FRONTEND noninteractive
#If install slowly, you can replcae alpine's mirror with aliyun's mirror, Example:
#RUN sed -i "s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g" /etc/apk/repositories
RUN apk update && \
apk --update add --no-cache dos2unix shadow bash openrc python2 python3 sudo vim wget iputils net-tools openssh-server py-pip tini && \
apk add --update procps && \
apk add --update --no-cache dos2unix shadow bash openrc python2 python3 sudo vim wget iputils net-tools openssh-server py-pip tini && \
apk add --update --no-cache procps && \
openrc boot && \
pip install kazoo
#2. install jdk
RUN apk add openjdk8
RUN apk add --update --no-cache openjdk8
ENV JAVA_HOME /usr/lib/jvm/java-1.8-openjdk
ENV PATH $JAVA_HOME/bin:$PATH
@ -43,19 +43,20 @@ RUN mv /opt/apache-dolphinscheduler-incubating-${VERSION}-dolphinscheduler-bin/
ENV DOLPHINSCHEDULER_HOME /opt/dolphinscheduler
#4. install database, if use mysql as your backend database, the `mysql-client` package should be installed
RUN apk add postgresql postgresql-contrib
RUN apk add --update --no-cache postgresql postgresql-contrib
#5. modify nginx
RUN echo "daemon off;" >> /etc/nginx/nginx.conf && \
rm -rf /etc/nginx/conf.d/*
ADD ./conf/nginx/dolphinscheduler.conf /etc/nginx/conf.d
COPY ./conf/nginx/dolphinscheduler.conf /etc/nginx/conf.d
#6. add configuration and modify permissions and set soft links
ADD ./checkpoint.sh /root/checkpoint.sh
ADD ./startup-init-conf.sh /root/startup-init-conf.sh
ADD ./startup.sh /root/startup.sh
ADD ./conf/dolphinscheduler/*.tpl /opt/dolphinscheduler/conf/
ADD ./conf/dolphinscheduler/logback/* /opt/dolphinscheduler/conf/
ADD conf/dolphinscheduler/env/dolphinscheduler_env.sh /opt/dolphinscheduler/conf/env/
COPY ./checkpoint.sh /root/checkpoint.sh
COPY ./startup-init-conf.sh /root/startup-init-conf.sh
COPY ./startup.sh /root/startup.sh
COPY ./conf/dolphinscheduler/*.tpl /opt/dolphinscheduler/conf/
COPY ./conf/dolphinscheduler/logback/* /opt/dolphinscheduler/conf/
COPY conf/dolphinscheduler/env/dolphinscheduler_env.sh /opt/dolphinscheduler/conf/env/
RUN chmod +x /root/checkpoint.sh && \
chmod +x /root/startup-init-conf.sh && \
chmod +x /root/startup.sh && \
@ -70,12 +71,12 @@ RUN chmod +x /root/checkpoint.sh && \
dos2unix /opt/dolphinscheduler/bin/*.sh && \
rm -rf /bin/sh && \
ln -s /bin/bash /bin/sh && \
mkdir -p /tmp/xls
#7. remove apk index cache and disable coredup for sudo
RUN rm -rf /var/cache/apk/* && \
mkdir -p /tmp/xls && \
#7. remove apk index cache and disable coredup for sudo
rm -rf /var/cache/apk/* && \
echo "Set disable_coredump false" >> /etc/sudo.conf
#8. expose port
EXPOSE 2181 2888 3888 5432 5678 1234 12345 50051 8888

71
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/TaskParametersUtils.java

@ -55,41 +55,42 @@ public class TaskParametersUtils {
* @return task parameters
*/
public static AbstractParameters getParameters(String taskType, String parameter) {
try {
switch (EnumUtils.getEnum(TaskType.class, taskType)) {
case SUB_PROCESS:
return JSONUtils.parseObject(parameter, SubProcessParameters.class);
case SHELL:
case WATERDROP:
return JSONUtils.parseObject(parameter, ShellParameters.class);
case PROCEDURE:
return JSONUtils.parseObject(parameter, ProcedureParameters.class);
case SQL:
return JSONUtils.parseObject(parameter, SqlParameters.class);
case MR:
return JSONUtils.parseObject(parameter, MapreduceParameters.class);
case SPARK:
return JSONUtils.parseObject(parameter, SparkParameters.class);
case PYTHON:
return JSONUtils.parseObject(parameter, PythonParameters.class);
case DEPENDENT:
return JSONUtils.parseObject(parameter, DependentParameters.class);
case FLINK:
return JSONUtils.parseObject(parameter, FlinkParameters.class);
case HTTP:
return JSONUtils.parseObject(parameter, HttpParameters.class);
case DATAX:
return JSONUtils.parseObject(parameter, DataxParameters.class);
case CONDITIONS:
return JSONUtils.parseObject(parameter, ConditionsParameters.class);
case SQOOP:
return JSONUtils.parseObject(parameter, SqoopParameters.class);
default:
return null;
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
TaskType anEnum = EnumUtils.getEnum(TaskType.class, taskType);
if (anEnum == null) {
logger.error("not support task type: {}", taskType);
return null;
}
return null;
switch (anEnum) {
case SUB_PROCESS:
return JSONUtils.parseObject(parameter, SubProcessParameters.class);
case SHELL:
case WATERDROP:
return JSONUtils.parseObject(parameter, ShellParameters.class);
case PROCEDURE:
return JSONUtils.parseObject(parameter, ProcedureParameters.class);
case SQL:
return JSONUtils.parseObject(parameter, SqlParameters.class);
case MR:
return JSONUtils.parseObject(parameter, MapreduceParameters.class);
case SPARK:
return JSONUtils.parseObject(parameter, SparkParameters.class);
case PYTHON:
return JSONUtils.parseObject(parameter, PythonParameters.class);
case DEPENDENT:
return JSONUtils.parseObject(parameter, DependentParameters.class);
case FLINK:
return JSONUtils.parseObject(parameter, FlinkParameters.class);
case HTTP:
return JSONUtils.parseObject(parameter, HttpParameters.class);
case DATAX:
return JSONUtils.parseObject(parameter, DataxParameters.class);
case CONDITIONS:
return JSONUtils.parseObject(parameter, ConditionsParameters.class);
case SQOOP:
return JSONUtils.parseObject(parameter, SqoopParameters.class);
default:
return null;
}
}
}

1
dolphinscheduler-dist/release-docs/LICENSE vendored

@ -502,6 +502,7 @@ MIT licenses
vue-router 2.7.0: https://github.com/vuejs/vue-router MIT
vuex 3.0.0: https://github.com/vuejs/vuex MIT
vuex-router-sync 4.1.2: https://github.com/vuejs/vuex-router-sync MIT
dagre 0.8.5: https://github.com/dagrejs/dagre MIT
========================================
Apache 2.0 licenses

19
dolphinscheduler-dist/release-docs/licenses/ui-licenses/LICENSE-dagre vendored

@ -0,0 +1,19 @@
Copyright (c) 2012-2014 Chris Pettitt
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

10
dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/worker/task/TaskManager.java

@ -30,7 +30,6 @@ import org.apache.dolphinscheduler.server.worker.task.shell.ShellTask;
import org.apache.dolphinscheduler.server.worker.task.spark.SparkTask;
import org.apache.dolphinscheduler.server.worker.task.sql.SqlTask;
import org.apache.dolphinscheduler.server.worker.task.sqoop.SqoopTask;
import org.slf4j.Logger;
/**
@ -46,7 +45,12 @@ public class TaskManager {
* @throws IllegalArgumentException illegal argument exception
*/
public static AbstractTask newTask(TaskExecutionContext taskExecutionContext, Logger logger) throws IllegalArgumentException {
switch (EnumUtils.getEnum(TaskType.class,taskExecutionContext.getTaskType())) {
TaskType anEnum = EnumUtils.getEnum(TaskType.class, taskExecutionContext.getTaskType());
if (anEnum == null) {
logger.error("not support task type: {}", taskExecutionContext.getTaskType());
throw new IllegalArgumentException("not support task type");
}
switch (anEnum) {
case SHELL:
case WATERDROP:
return new ShellTask(taskExecutionContext, logger);
@ -69,7 +73,7 @@ public class TaskManager {
case SQOOP:
return new SqoopTask(taskExecutionContext, logger);
default:
logger.error("unsupport task type: {}", taskExecutionContext.getTaskType());
logger.error("not support task type: {}", taskExecutionContext.getTaskType());
throw new IllegalArgumentException("not support task type");
}
}

19
dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/worker/task/TaskManagerTest.java

@ -38,6 +38,8 @@ import org.slf4j.LoggerFactory;
@PrepareForTest({SpringApplicationContext.class})
public class TaskManagerTest {
private static Logger logger = LoggerFactory.getLogger(TaskManagerTest.class);
private TaskExecutionContext taskExecutionContext;
private Logger taskLogger;
@ -95,9 +97,18 @@ public class TaskManagerTest {
Assert.assertNotNull(TaskManager.newTask(taskExecutionContext,taskLogger));
taskExecutionContext.setTaskType("SQOOP");
Assert.assertNotNull(TaskManager.newTask(taskExecutionContext,taskLogger));
//taskExecutionContext.setTaskType(null);
//Assert.assertNull(TaskManager.newTask(taskExecutionContext,taskLogger));
//taskExecutionContext.setTaskType("XXX");
//Assert.assertNotNull(TaskManager.newTask(taskExecutionContext,taskLogger));
}
@Test(expected = IllegalArgumentException.class)
public void testNewTaskIsNull() {
taskExecutionContext.setTaskType(null);
TaskManager.newTask(taskExecutionContext,taskLogger);
}
@Test(expected = IllegalArgumentException.class)
public void testNewTaskIsNotExists() {
taskExecutionContext.setTaskType("XXX");
TaskManager.newTask(taskExecutionContext,taskLogger);
}
}

1
dolphinscheduler-ui/package.json

@ -20,6 +20,7 @@
"clipboard": "^2.0.1",
"codemirror": "^5.43.0",
"d3": "^3.5.17",
"dagre": "^0.8.5",
"dayjs": "^1.7.8",
"echarts": "4.1.0",
"html2canvas": "^0.5.0-beta4",

212
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/dag.js

@ -22,6 +22,7 @@ import { jsPlumb } from 'jsplumb'
import JSP from './plugIn/jsPlumbHandle'
import DownChart from './plugIn/downChart'
import store from '@/conf/home/store'
import dagre from "dagre"
/**
* Prototype method
@ -115,202 +116,38 @@ Dag.prototype.toolbarEvent = function ({ item, code, is }) {
*/
Dag.prototype.backfill = function (arg) {
if (arg) {
let locationsValue = store.state.dag.locations
const locationsValue1 = store.state.dag.locations
const locationsValue2 = store.state.dag.locations
const arr = []
for (const i in locationsValue1) {
const objs = {}
objs.id = i
arr.push(Object.assign(objs, locationsValue1[i])) // Attributes
}
const tmp = []
for (const i in locationsValue2) {
if (locationsValue2[i].targetarr !== '' && locationsValue2[i].targetarr.split(',').length > 1) {
tmp.push(locationsValue2[i])
}
}
const copy = function (array) {
const newArray = []
for (const item of array) {
newArray.push(item)
}
return newArray
}
const newArr = copy(arr)
const getNewArr = function () {
for (let i = 0; i < newArr.length; i++) {
if (newArr[i].targetarr !== '' && newArr[i].targetarr.split(',').length > 1) {
newArr[i].targetarr = newArr[i].targetarr.split(',').shift()
}
}
return newArr
}
getNewArr()
/**
* @description Transform flat data into a tree structure
* @param {Array} arr Flat data
* @param {String} pidStr targetarr key name
* @param {String} idStr id key name
* @param {String} childrenStr children key name
*/
const fommat = function ({ arrayList, pidStr = 'targetarr', idStr = 'id', childrenStr = 'children' }) {
const listOjb = {} // Used to store objects of the form {key: obj}
const treeList = [] // An array to store the final tree structure data
// Transform the data into {key: obj} format, which is convenient for the following data processing
for (let i = 0; i < arrayList.length; i++) {
listOjb[arrayList[i][idStr]] = arrayList[i]
}
// Format data based on pid
for (let j = 0; j < arrayList.length; j++) {
// Determine if the parent exists
// let haveParent = arrayList[j].targetarr.split(',').length>1?listOjb[arrayList[j].targetarr.split(',')[0]]:listOjb[arrayList[j][pidStr]]
const haveParent = listOjb[arrayList[j][pidStr]]
if (haveParent) {
// If there is no parent children field, create a children field
!haveParent[childrenStr] && (haveParent[childrenStr] = [])
// Insert child in parent
haveParent[childrenStr].push(arrayList[j])
} else {
// If there is no parent, insert directly into the outermost layer
treeList.push(arrayList[j])
}
}
return treeList
}
const datas = fommat({ arrayList: newArr, pidStr: 'targetarr' })
// Count the number of leaf nodes
const getLeafCountTree = function (json) {
if (!json.children) {
json.colspan = 1
return 1
} else {
let leafCount = 0
for (let i = 0; i < json.children.length; i++) {
leafCount = leafCount + getLeafCountTree(json.children[i])
}
json.colspan = leafCount
return leafCount
}
}
// Number of tree node levels
const countTree = getLeafCountTree(datas[0])
const getMaxFloor = function (treeData) {
let max = 0
function each (data, floor) {
data.forEach(e => {
e.floor = floor
e.x = floor * 170
if (floor > max) {
max = floor
}
if (e.children) {
each(e.children, floor + 1)
}
})
}
each(treeData, 1)
return max
}
getMaxFloor(datas)
// The last child of each node
let lastchildren = []
const forxh = function (list) {
for (let i = 0; i < list.length; i++) {
const chlist = list[i]
if (chlist.children) {
forxh(chlist.children)
} else {
lastchildren.push(chlist)
}
}
}
forxh(datas)
// Get all parent nodes above the leaf node
const treeFindPath = function (tree, func, path, n) {
if (!tree) return []
for (const data of tree) {
path.push(data.name)
if (func(data)) return path
if (data.children) {
const findChildren = treeFindPath(data.children, func, path, n)
if (findChildren.length) return findChildren
}
path.pop()
}
return []
}
const toLine = function (data) {
return data.reduce((arrData, { id, name, targetarr, x, y, children = [] }) =>
arrData.concat([{ id, name, targetarr, x, y }], toLine(children)), [])
}
const listarr = toLine(datas)
const listarrs = toLine(datas)
const dataObject = {}
for (let i = 0; i < listarrs.length; i++) {
delete (listarrs[i].id)
}
const marginX = 100
const g = new dagre.graphlib.Graph()
g.setGraph({})
g.setDefaultEdgeLabel(function () { return {} })
for (let a = 0; a < listarr.length; a++) {
dataObject[listarr[a].id] = listarrs[a]
for (const i in store.state.dag.locations) {
const location = store.state.dag.locations[i]
g.setNode(i, { label: i, width: Math.min(location.name.length * 7, 170), height: 150 })
}
// Comparison function
const createComparisonFunction = function (propertyName) {
return function (object1, object2) {
const value1 = object1[propertyName]
const value2 = object2[propertyName]
if (value1 < value2) {
return -1
} else if (value1 > value2) {
return 1
} else {
return 0
}
}
for (const i in store.state.dag.connects) {
const connect = store.state.dag.connects[i]
g.setEdge(connect['endPointSourceId'], connect['endPointTargetId'])
}
dagre.layout(g)
lastchildren = lastchildren.sort(createComparisonFunction('x'))
// Coordinate value of each leaf node
for (let a = 0; a < lastchildren.length; a++) {
dataObject[lastchildren[a].id].y = (a + 1) * 120
}
for (let i = 0; i < lastchildren.length; i++) {
const node = treeFindPath(datas, data => data.targetarr === lastchildren[i].targetarr, [], i + 1)
for (let j = 0; j < node.length; j++) {
for (let k = 0; k < listarrs.length; k++) {
if (node[j] === listarrs[k].name) {
listarrs[k].y = (i + 1) * 120
}
}
}
}
for (let i = 0; i < tmp.length; i++) {
for (const objs in dataObject) {
if (tmp[i].name === dataObject[objs].name) {
dataObject[objs].targetarr = tmp[i].targetarr
}
}
}
for (let a = 0; a < lastchildren.length; a++) {
dataObject[lastchildren[a].id].y = (a + 1) * 120
}
if (countTree > 1) {
dataObject[Object.keys(locationsValue1)[0]].y = (countTree / 2) * 120 + 50
}
locationsValue = dataObject
const self = this
const dataObject = {}
g.nodes().forEach(function (v) {
const node = g.node(v)
const obj = {}
obj.name = node.label
obj.x = node.x + marginX
obj.y = node.y
dataObject[node.label] = obj
})
jsPlumb.ready(() => {
JSP.init({
dag: this.dag,
instance: this.instance,
options: {
onRemoveNodes ($id) {
self.dag.removeEventModelById($id)
this.dag.removeEventModelById($id)
}
}
})
@ -319,20 +156,19 @@ Dag.prototype.backfill = function (arg) {
// connects
connects: _.cloneDeep(store.state.dag.connects),
// Node location information
locations: _.cloneDeep(locationsValue),
locations: _.cloneDeep(dataObject),
// Node data
largeJson: _.cloneDeep(store.state.dag.tasks)
})
})
} else {
const self = this
jsPlumb.ready(() => {
JSP.init({
dag: this.dag,
instance: this.instance,
options: {
onRemoveNodes ($id) {
self.dag.removeEventModelById($id)
this.dag.removeEventModelById($id)
}
}
})

19
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/list.vue

@ -124,7 +124,6 @@
</table>
</div>
<x-poptip
v-show="strSelectIds !== ''"
ref="poptipDeleteAll"
placement="bottom-start"
width="90">
@ -134,14 +133,12 @@
<x-button type="primary" size="xsmall" shape="circle" @click="_delete({},-1)">{{$t('Confirm')}}</x-button>
</div>
<template slot="reference">
<x-button size="xsmall" style="position: absolute; bottom: -48px; left: 22px;" >{{$t('Delete')}}</x-button>
<x-button size="xsmall" :disabled="!strSelectIds" style="position: absolute; bottom: -48px; left: 22px;" >{{$t('Delete')}}</x-button>
</template>
</x-poptip>
<template v-if="strSelectIds !== ''">
<x-button size="xsmall" style="position: absolute; bottom: -48px; left: 80px;" @click="_batchExport(item)" >{{$t('Export')}}</x-button>
<x-button size="xsmall" style="position: absolute; bottom: -48px; left: 140px;" @click="_batchCopy(item)" >{{$t('Batch copy')}}</x-button>
<x-button size="xsmall" style="position: absolute; bottom: -48px; left: 225px;" @click="_batchMove(item)" >{{$t('Batch move')}}</x-button>
</template>
<x-button size="xsmall" :disabled="!strSelectIds" style="position: absolute; bottom: -48px; left: 80px;" @click="_batchExport(item)" >{{$t('Export')}}</x-button>
<x-button size="xsmall" :disabled="!strSelectIds" style="position: absolute; bottom: -48px; left: 140px;" @click="_batchCopy(item)" >{{$t('Batch copy')}}</x-button>
<x-button size="xsmall" :disabled="!strSelectIds" style="position: absolute; bottom: -48px; left: 225px;" @click="_batchMove(item)" >{{$t('Batch move')}}</x-button>
</div>
</template>
@ -268,6 +265,12 @@
* Close the delete layer
*/
_closeDelete (i) {
// close batch
if (i < 0) {
this.$refs['poptipDeleteAll'].doClose()
return
}
// close one
this.$refs[`poptip-delete-${i}`][0].doClose()
},
/**
@ -596,8 +599,10 @@
}).then(res => {
this._onUpdate()
this.checkAll = false
this.strSelectIds = ''
this.$message.success(res.msg)
}).catch(e => {
this.strSelectIds = ''
this.checkAll = false
this.$message.error(e.msg || '')
})

11
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/instance/pages/list/_source/list.vue

@ -288,7 +288,6 @@
</table>
</div>
<x-poptip
v-show="strDelete !== ''"
ref="poptipDeleteAll"
placement="bottom-start"
width="90">
@ -298,7 +297,7 @@
<x-button type="primary" size="xsmall" shape="circle" @click="_delete({},-1)">{{$t('Confirm')}}</x-button>
</div>
<template slot="reference">
<x-button size="xsmall" style="position: absolute; bottom: -48px; left: 22px;" >{{$t('Delete')}}</x-button>
<x-button size="xsmall" :disabled="!strDelete" style="position: absolute; bottom: -48px; left: 22px;" >{{$t('Delete')}}</x-button>
</template>
</x-poptip>
</div>
@ -344,6 +343,12 @@
* Close the delete layer
*/
_closeDelete (i) {
// close batch
if (i < 0) {
this.$refs['poptipDeleteAll'].doClose()
return
}
// close one
this.$refs[`poptip-delete-${i}`][0].doClose()
},
/**
@ -539,9 +544,11 @@
}).then(res => {
this._onUpdate()
this.checkAll = false
this.strDelete = ''
this.$message.success(res.msg)
}).catch(e => {
this.checkAll = false
this.strDelete = ''
this.$message.error(e.msg || '')
})
}

2
dolphinscheduler-ui/src/js/conf/home/pages/user/pages/password/_source/info.vue

@ -86,7 +86,7 @@
tenantId: this.userInfo.tenantId,
email: this.userInfo.email,
phone: this.userInfo.phone,
state: this.userinfo.state
state: this.userInfo.state
}
this.spinnerLoading = true
this.updateUser(param).then(res => {

10
e2e/pom.xml

@ -87,6 +87,16 @@
<artifactId>commons-pool2</artifactId>
<version>${commons-pool2.version}</version>
</dependency>
<dependency>
<groupId>org.jyaml</groupId>
<artifactId>jyaml</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
</dependencies>
<build>

45
e2e/src/main/java/org/apache/dolphinscheduler/util/YmlReader.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.util;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import org.ho.yaml.Yaml;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
/**
* read yml file
*/
public class YmlReader {
public static HashMap<String,HashMap<String, String>> map;
public String getDataYml(String filePath, String key1, String key2) {
Yaml yaml = new Yaml();
Resource resource = new DefaultResourceLoader().getResource("classpath:" + filePath + ".yml");
try {
InputStream inputStream = resource.getInputStream();
map = yaml.loadType(inputStream, HashMap.class);
} catch (IOException e) {
e.printStackTrace();
}
String data = map.get(key1).get(key2);
return data;
}
}

1
e2e/src/test/java/org/apache/dolphinscheduler/base/BaseDriver.java

@ -23,7 +23,6 @@ import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

3
e2e/src/test/java/org/apache/dolphinscheduler/data/LoginData.java

@ -28,7 +28,6 @@ public class LoginData {
*/
public static final String URL = PropertiesReader.getKey("LOGIN_URL");
/**
* Login username
*/
@ -38,6 +37,4 @@ public class LoginData {
* Login password
*/
public static final String PASSWORD = PropertiesReader.getKey("PASSWORD");
public static final String TENANT = "租户管理 - DolphinScheduler";
}

12
e2e/src/test/java/org/apache/dolphinscheduler/data/project/ProcessInstanceData.java

@ -16,10 +16,12 @@
*/
package org.apache.dolphinscheduler.data.project;
public class ProcessInstanceData {
//Process Instance page title
public static final String PROCESS_INSTANCE_TITLE = "工作流实例 - DolphinScheduler";
public static final String RERUN_TYPE= "重跑";
import org.apache.dolphinscheduler.util.YmlReader;
public class ProcessInstanceData {
public String getProcessInstanceData(String param) {
YmlReader ymlReader = new YmlReader();
String processInstanceData = ymlReader.getDataYml("testData/workflow_zh_cn", "processInstance", param);
return processInstanceData;
}
}

16
e2e/src/test/java/org/apache/dolphinscheduler/data/project/ProjectData.java

@ -16,14 +16,12 @@
*/
package org.apache.dolphinscheduler.data.project;
public class ProjectData {
public static final String CREATE_PROJECT_BUTTON = "创建项目";
import org.apache.dolphinscheduler.util.YmlReader;
// create project name
public static final String PROJECT_NAME = "selenium_project_1";
// create project description
public static final String DESCRIPTION = "test create project description";
// project page title
public static final String PROJECT_TITLE = "项目 - DolphinScheduler";
public class ProjectData {
public String getProjectData(String param) {
YmlReader ymlReader = new YmlReader();
String projectData = ymlReader.getDataYml("testData/workflow_zh_cn", "projectManage", param);
return projectData;
}
}

19
e2e/src/test/java/org/apache/dolphinscheduler/data/project/RunWorkflowData.java

@ -16,17 +16,12 @@
*/
package org.apache.dolphinscheduler.data.project;
public class RunWorkflowData {
/**
* run workflow data
*/
//input shell task name
public static final String RECIPIENT = "123456789@qq.com";
//input shell task description
public static final String Cc = "qwe12312sds@qq.com";
public static final String RUN_WORKFLOW_TITLE = "工作流定义 - DolphinScheduler";
import org.apache.dolphinscheduler.util.YmlReader;
public class RunWorkflowData {
public String getRunWorkflowData(String param) {
YmlReader ymlReader = new YmlReader();
String runWorkflowData = ymlReader.getDataYml("testData/workflow_zh_cn", "runWorkflow", param);
return runWorkflowData;
}
}

25
e2e/src/test/java/org/apache/dolphinscheduler/data/project/TimingData.java

@ -16,23 +16,12 @@
*/
package org.apache.dolphinscheduler.data.project;
public class TimingData {
/**
* timing data
*/
//input shell task name
public static final String RECIPIENT = "test123456@qq.com";
//input shell task description
public static final String Cc = "test.123qwe@qq.com";
public static final String EDIT_RECIPIENT = "test.edit123456@qq.com";
public static final String EDIT_Cc = "test.edit123qwe@qq.com";
import org.apache.dolphinscheduler.util.YmlReader;
public static final String TIMING_OFFLINE_STATE = "下线";
public static final String TIMING_ONLINE_STATE = "上线";
public static final String TIMING_TITLE = "定时任务列表 - DolphinScheduler";
public class TimingData {
public String getTimingData(String param) {
YmlReader ymlReader = new YmlReader();
String timingData = ymlReader.getDataYml("testData/workflow_zh_cn", "timing", param);
return timingData;
}
}

76
e2e/src/test/java/org/apache/dolphinscheduler/data/project/WorkflowDefineData.java

@ -16,74 +16,12 @@
*/
package org.apache.dolphinscheduler.data.project;
public class WorkflowDefineData {
/**
* create workflow data
*/
public static final String workflow_define = "工作流定义";
//input shell task name
public static final String SHELL_TASK_NAME = "shell_task_selenium_1";
//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";
//input custom parameters
public static final String INPUT_CUSTOM_PARAMETERS = "selenium_parameter";
//input custom parameters value
public static final String INPUT_CUSTOM_PARAMETERS_VALUE = "selenium_parameter_123";
//input add custom parameters
public static final String INPUT_ADD_CUSTOM_PARAMETERS = "selenium_parameter_delete";
//input add custom parameters value
public static final String INPUT_ADD_CUSTOM_PARAMETERS_VALUE = "selenium_parameter_delete_456";
//workflow define title
public static final String WORKFLOW_TITLE = "工作流定义 - DolphinScheduler";
//create workflow title
public static final String CREATE_WORKFLOW_TITLE = "创建流程定义 - DolphinScheduler";
/**
* save workflow data
*/
//input workflow name
public static final String INPUT_WORKFLOW_NAME = "selenium_shell_1";
//input workflow description
public static final String INPUT_WORKFLOW_DESCRIPTION = "test selenium_shell_1 description";
//input workflow timeout
public static final String INPUT_WORKFLOW_TIMEOUT = "30";
//input workflow global parameters
public static final String INPUT_WORKFLOW_GLOBAL_PARAMETERS = "selenium_global_parameters_1";
//input workflow global parameters value
public static final String INPUT_WORKFLOW_GLOBAL_PARAMETERS_VALUES = "selenium_global_parameters_value_1";
//input to add workflow global parameters
public static final String INPUT_ADD_WORKFLOW_GLOBAL_PARAMETERS = "selenium_global_parameters_2";
//input to add workflow global parameters value
public static final String INPUT_ADD_WORKFLOW_GLOBAL_PARAMETERS_VALUES = "selenium_global_parameters_value_2";
/**
* workflowDefine list
*/
public static final String WORKFLOW_ONLINE_STATE = "上线";
public static final String WORKFLOW_OFFLINE_STATE = "下线";
import org.apache.dolphinscheduler.util.YmlReader;
public class WorkflowDefineData {
public String getWorkflowDefineData(String param) {
YmlReader ymlReader = new YmlReader();
String workflowDefineData = ymlReader.getDataYml("testData/workflow_zh_cn", "workflowDefine", param);
return workflowDefineData;
}
}

18
e2e/src/test/java/org/apache/dolphinscheduler/data/security/AlertManageData.java

@ -16,17 +16,13 @@
*/
package org.apache.dolphinscheduler.data.security;
public class AlertManageData {
//Alert Name
public static final String ALERT_NAME = "selenium_alert_Name";
public static final String CREATE_ALERT = "创建告警组";
// Alert Type
public static final String ALERT_TYPE = "邮件";
import org.apache.dolphinscheduler.util.YmlReader;
//Alert Description
public static final String DESCRIPTION = "create alert test";
public static final String ALERT_MANAGE = "告警组管理 - DolphinScheduler";
public class AlertManageData {
public String getAlertData(String param) {
YmlReader ymlReader = new YmlReader();
String alertData = ymlReader.getDataYml("testData/security_zh_cn", "alertManage", param);
return alertData;
}
}

31
e2e/src/test/java/org/apache/dolphinscheduler/data/security/QueueManageData.java

@ -16,29 +16,12 @@
*/
package org.apache.dolphinscheduler.data.security;
public class QueueManageData {
/**
* Create Queue Name
*/
public static final String QUEUE_NAME = "selenium_queue_name";
public static final String CREATE_QUEUE = "创建队列";
/**
* Create Queue Value
*/
public static final String QUEUE_VALUE = "selenium_queue_value";
/**
* Edit Queue Name
*/
public static final String EDIT_QUEUE_NAME = "selenium_queue_value_edit";
/**
* Edit Queue Value
*/
public static final String EDIT_QUEUE_VALUE = "selenium_queue_value_edit";
public static final String QUEUE_MANAGE = "队列管理 - DolphinScheduler";
import org.apache.dolphinscheduler.util.YmlReader;
public class QueueManageData {
public String getQueueData(String param) {
YmlReader ymlReader = new YmlReader();
String queueData = ymlReader.getDataYml("testData/security_zh_cn", "queueManage", param);
return queueData;
}
}

30
e2e/src/test/java/org/apache/dolphinscheduler/data/security/TenantManageData.java

@ -20,30 +20,12 @@
*/
package org.apache.dolphinscheduler.data.security;
import org.apache.dolphinscheduler.util.YmlReader;
public class TenantManageData {
/**
* Tenant Code
*/
public static final String TENANT_CODE = "selenium_tenant_code_1";
/**
* Tenant Name
*/
public static final String TENANT_NAME = "selenium_tenant_Name";
/**
* Queue
*/
public static final String QUEUE = "default";
/**
* Description
*/
public static final String DESCRIPTION = "create tenant test";
public static final String TENANT_MANAGE = "租户管理 - DolphinScheduler";
public String getTenantData(String param) {
YmlReader ymlReader = new YmlReader();
String tenantData = ymlReader.getDataYml("testData/security_zh_cn", "tenantManage", param);
return tenantData;
}
}

15
e2e/src/test/java/org/apache/dolphinscheduler/data/security/TokenManageData.java

@ -16,13 +16,12 @@
*/
package org.apache.dolphinscheduler.data.security;
public class TokenManageData {
public static final String TOKEN_MANAGE = "令牌管理 - DolphinScheduler";
public static final String CREATE_TOKEN = "创建令牌";
public static final String DATE = "2038-06-10 00:00:00";
public static final String NAME = "admin";
import org.apache.dolphinscheduler.util.YmlReader;
public class TokenManageData {
public String getTokenData(String param) {
YmlReader ymlReader = new YmlReader();
String tokenData = ymlReader.getDataYml("testData/security_zh_cn", "tokenManage", param);
return tokenData;
}
}

29
e2e/src/test/java/org/apache/dolphinscheduler/data/security/UserManageData.java

@ -16,29 +16,12 @@
*/
package org.apache.dolphinscheduler.data.security;
import org.apache.dolphinscheduler.util.YmlReader;
public class UserManageData {
/**
* create user
*/
public static final String USERNAME = "selenium_user_1";
public static final String PASSWORD = "123456qwe";
public static final String EMAIL = "123456789@qq.com";
public static final String PHONE = "15811112222";
public static final String USER_MANAGE = "用户管理 - DolphinScheduler";
public static final String CREATE_USER_BUTTON = "创建用户";
/**
* edit user
*/
public static final String EDIT_USERNAME = "selenium_user_edit";
public static final String EDIT_PASSWORD = "123456qwe";
public static final String EDIT_EMAIL = "123456_edit@qq.com";
public static final String EDIT_PHONE = "15800001111";
public String getUserData(String param) {
YmlReader ymlReader = new YmlReader();
String userData = ymlReader.getDataYml("testData/security_zh_cn", "userManage", param);
return userData;
}
}

2
e2e/src/test/java/org/apache/dolphinscheduler/locator/project/WorkflowDefineLocator.java

@ -179,6 +179,8 @@ public class WorkflowDefineLocator {
//scroll to element bottom
public static final By SCROLL_BOTTOM = By.xpath("//span/a/em");
public static final By WORKFLOW_NAME = By.xpath("//table/tr[2]/td[3]/span/a");
/**
* online workflow
*/

6
e2e/src/test/java/org/apache/dolphinscheduler/locator/security/TokenManageLocator.java

@ -24,18 +24,18 @@ public class TokenManageLocator {
public static final By CLICK_CREATE_TOKEN = By.xpath("//div[2]/div/div[2]/div[2]/div/div[1]/button/span");
public static final By CREATE_TOKEN_POPUP = By.xpath("//div[5]/div/div[2]/div/div[1]/span");
public static final By SELECT_USER = By.xpath("//div[2]/div[2]/div/div/div/span/i");
public static final By CLICK_GENERATE_TOKEN_BUTTON = By.xpath("//div[3]/div[2]/button/span");
public static final By CLICK_SUBMIT_BUTTON = By.xpath("//div[3]/button[2]/span");
public static final By EDIT_TOKEN_BUTTON = By.xpath("//table/tr[2]/td[7]/button");
//edit token
public static final By TOKEN = By.xpath("//table/tr[2]/td[1]/span");
public static final By EDIT_TOKEN_BUTTON = By.xpath("//table/tr[2]/td[7]/button");
public static final By CLICK_EDIT_BUTTON = By.xpath("//div[3]/div[1]/div/table/tr[2]/td[7]/button/i");
//delete token
public static final By CLICK_DELETE_BUTTON = By.xpath("//div[3]/div[1]/div/table/tr[2]/td[7]/span/button");

2
e2e/src/test/java/org/apache/dolphinscheduler/locator/security/UserManageLocator.java

@ -49,6 +49,8 @@ public class UserManageLocator {
public static final By SUBMIT = By.xpath("//div[3]/button[2]/span");
public static final By USERNAME = By.xpath("//table/tr[2]/td[2]/span");
/**
* edit user
*/

8
e2e/src/test/java/org/apache/dolphinscheduler/page/LoginPage.java

@ -18,13 +18,14 @@ package org.apache.dolphinscheduler.page;
import org.apache.dolphinscheduler.common.PageCommon;
import org.apache.dolphinscheduler.data.LoginData;
import org.apache.dolphinscheduler.data.security.TenantManageData;
import org.apache.dolphinscheduler.locator.LoginLocator;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
public class LoginPage extends PageCommon {
TenantManageData tenantManageData = new TenantManageData();
/**
* Unique constructor
* @param driver driver
@ -33,7 +34,6 @@ public class LoginPage extends PageCommon {
super(driver);
}
/**
* jump page
*/
@ -65,6 +65,6 @@ public class LoginPage extends PageCommon {
moveToElement(LoginLocator.LOGIN_BUTTON_MOVE);
// Whether to enter the specified page after login
return ifTitleContains(LoginData.TENANT);
return ifTitleContains(tenantManageData.getTenantData("tenantTitle"));
}
}

4
e2e/src/test/java/org/apache/dolphinscheduler/page/project/ProcessInstancePage.java

@ -23,6 +23,8 @@ import org.apache.dolphinscheduler.data.project.ProcessInstanceData;
public class ProcessInstancePage extends PageCommon {
ProcessInstanceData processInstanceData = new ProcessInstanceData();
public ProcessInstancePage(WebDriver driver) {
super(driver);
}
@ -36,7 +38,7 @@ public class ProcessInstancePage extends PageCommon {
clickTopElement(ProcessInstanceLocator.CLICK_PROCESS_INSTANCE_NAME);
locateElement(ProcessInstanceLocator.PROCESS_INSTANCE_SUCCESS_STATE);
clickTopElement(ProcessInstanceLocator.CLICK_RERUN_BUTTON);
return ifTitleContains(ProcessInstanceData.PROCESS_INSTANCE_TITLE);
return ifTitleContains(processInstanceData.getProcessInstanceData("processInstanceTitle"));
}
}

15
e2e/src/test/java/org/apache/dolphinscheduler/page/project/ProjectPage.java

@ -17,12 +17,13 @@
package org.apache.dolphinscheduler.page.project;
import org.apache.dolphinscheduler.common.PageCommon;
import org.apache.dolphinscheduler.constant.TestConstant;
import org.apache.dolphinscheduler.data.project.ProjectData;
import org.apache.dolphinscheduler.locator.project.ProjectLocator;
import org.openqa.selenium.WebDriver;
public class ProjectPage extends PageCommon {
ProjectData projectData = new ProjectData();
public ProjectPage(WebDriver driver) {
super(driver);
}
@ -32,7 +33,7 @@ public class ProjectPage extends PageCommon {
*/
public boolean jumpProjectManagePage() throws InterruptedException {
clickTopElement(ProjectLocator.PROJECT_MANAGE);
return ifTitleContains(ProjectData.PROJECT_TITLE);
return ifTitleContains(projectData.getProjectData("projectTitle"));
}
/**
@ -41,18 +42,18 @@ public class ProjectPage extends PageCommon {
* @return Whether to enter the specified page after create project
*/
public boolean createProject() throws InterruptedException {
ifTextExists(ProjectLocator.CREATE_PROJECT_BUTTON,ProjectData.CREATE_PROJECT_BUTTON);
ifTextExists(ProjectLocator.CREATE_PROJECT_BUTTON, projectData.getProjectData("createProjectButton"));
clickElement(ProjectLocator.CREATE_PROJECT_BUTTON);
// input create project data
sendInput(ProjectLocator.PROJECT_NAME, ProjectData.PROJECT_NAME);
sendInput(ProjectLocator.PROJECT_DESCRIPTION, ProjectData.DESCRIPTION);
sendInput(ProjectLocator.PROJECT_NAME, projectData.getProjectData("projectName"));
sendInput(ProjectLocator.PROJECT_DESCRIPTION, projectData.getProjectData("description"));
// click submit button
clickButton(ProjectLocator.SUBMIT_BUTTON);
// Whether to enter the specified page after submit
return ifTextExists(ProjectLocator.LIST_PROJECT_NAME,ProjectData.PROJECT_NAME);
return ifTextExists(ProjectLocator.LIST_PROJECT_NAME, projectData.getProjectData("projectName"));
}
/**
@ -68,6 +69,6 @@ public class ProjectPage extends PageCommon {
clickElement(ProjectLocator.CONFIRM_DELETE_PROJECT_BUTTON);
// Whether to enter the specified page after submit
return ifTitleContains(ProjectData.PROJECT_TITLE);
return ifTitleContains(projectData.getProjectData("projectTitle"));
}
}

11
e2e/src/test/java/org/apache/dolphinscheduler/page/project/RunWorkflowPage.java

@ -24,13 +24,16 @@ import org.apache.dolphinscheduler.locator.project.WorkflowDefineLocator;
import org.openqa.selenium.WebDriver;
public class RunWorkflowPage extends PageCommon {
RunWorkflowData runWorkflowData = new RunWorkflowData();
WorkflowDefineData workflowDefineData = new WorkflowDefineData();
public RunWorkflowPage(WebDriver driver) {
super(driver);
}
public boolean runWorkflow() throws InterruptedException {
// Determine whether the workflow status is online
ifTextExists(WorkflowDefineLocator.WORKFLOW_STATE, WorkflowDefineData.WORKFLOW_ONLINE_STATE);
ifTextExists(WorkflowDefineLocator.WORKFLOW_STATE, runWorkflowData.getRunWorkflowData("online"));
// click run workflow button
System.out.println("Click run workflow button");
@ -46,10 +49,10 @@ public class RunWorkflowPage extends PageCommon {
clickElement(RunWorkflowLocator.SELECT_WORKER_GROUP);
clickElement(RunWorkflowLocator.CLICK_NOTICE_GROUP);
clickElement(RunWorkflowLocator.SELECT_NOTICE_GROUP);
sendInput(RunWorkflowLocator.INPUT_RECIPIENT, RunWorkflowData.RECIPIENT);
sendInput(RunWorkflowLocator.INPUT_Cc,RunWorkflowData.Cc);
sendInput(RunWorkflowLocator.INPUT_RECIPIENT, runWorkflowData.getRunWorkflowData("recipient"));
sendInput(RunWorkflowLocator.INPUT_Cc, runWorkflowData.getRunWorkflowData("Cc"));
clickButton(RunWorkflowLocator.CLICK_RUNNING_BUTTON);
return ifTitleContains(RunWorkflowData.RUN_WORKFLOW_TITLE);
return ifTitleContains(workflowDefineData.getWorkflowDefineData("workflowDefineTitle"));
}
}

31
e2e/src/test/java/org/apache/dolphinscheduler/page/project/TimingPage.java

@ -18,23 +18,24 @@ package org.apache.dolphinscheduler.page.project;
import org.apache.dolphinscheduler.common.PageCommon;
import org.apache.dolphinscheduler.data.project.TimingData;
import org.apache.dolphinscheduler.data.project.WorkflowDefineData;
import org.apache.dolphinscheduler.locator.project.TimingLocator;
import org.apache.dolphinscheduler.locator.project.WorkflowDefineLocator;
import org.openqa.selenium.WebDriver;
public class TimingPage extends PageCommon {
TimingData timingData = new TimingData();
public TimingPage(WebDriver driver) {
super(driver);
}
/**
* create timing
*/
public boolean createTiming() throws InterruptedException {
flushPage();
// Determine whether the workflow status is online
ifTextExists(WorkflowDefineLocator.WORKFLOW_STATE, WorkflowDefineData.WORKFLOW_ONLINE_STATE);
ifTextExists(WorkflowDefineLocator.WORKFLOW_STATE, timingData.getTimingData("online"));
// click timing button
System.out.println("Click timing button");
@ -52,11 +53,11 @@ public class TimingPage extends PageCommon {
clickElement(TimingLocator.SELECT_WORKER_GROUP);
clickElement(TimingLocator.CLICK_NOTICE_GROUP);
clickElement(TimingLocator.SELECT_NOTICE_GROUP);
sendInput(TimingLocator.INPUT_RECIPIENT, TimingData.RECIPIENT);
sendInput(TimingLocator.INPUT_Cc,TimingData.Cc);
sendInput(TimingLocator.INPUT_RECIPIENT, timingData.getTimingData("recipient"));
sendInput(TimingLocator.INPUT_Cc, timingData.getTimingData("Cc"));
clickButton(TimingLocator.CLICK_CREATE_BUTTON);
return ifTextExists(TimingLocator.TIMING_STATE, TimingData.TIMING_OFFLINE_STATE);
return ifTextExists(TimingLocator.TIMING_STATE, timingData.getTimingData("offline"));
}
/**
@ -68,7 +69,7 @@ public class TimingPage extends PageCommon {
clickButton(TimingLocator.CLICK_TIMING_MANAGEMENT_BUTTON);
// Determine whether the workflow name exists
ifTextExists(TimingLocator.WORKFLOW_NAME, WorkflowDefineData.INPUT_WORKFLOW_NAME);
ifTextExists(TimingLocator.WORKFLOW_NAME, timingData.getTimingData("offline"));
System.out.println("Click edit timing button");
clickButton(TimingLocator.CLICK_EDIT_TIMING_BUTTON);
@ -85,11 +86,11 @@ public class TimingPage extends PageCommon {
clickElement(TimingLocator.SELECT_WORKER_GROUP);
clickElement(TimingLocator.CLICK_NOTICE_GROUP);
clickElement(TimingLocator.SELECT_NOTICE_GROUP);
sendInput(TimingLocator.INPUT_RECIPIENT, TimingData.EDIT_RECIPIENT);
sendInput(TimingLocator.INPUT_Cc,TimingData.EDIT_Cc);
sendInput(TimingLocator.INPUT_RECIPIENT, timingData.getTimingData("editRecipient"));
sendInput(TimingLocator.INPUT_Cc, timingData.getTimingData("editCc"));
clickButton(TimingLocator.CLICK_CREATE_BUTTON);
return ifTitleContains(TimingData.TIMING_TITLE );
return ifTitleContains(timingData.getTimingData("timingTitle"));
}
@ -99,13 +100,13 @@ public class TimingPage extends PageCommon {
public boolean onlineTiming() throws InterruptedException {
flushPage();
// Determine whether the timing is offline
ifTextExists(TimingLocator.TIMING_MANAGEMENT_TIMING_STATE, TimingData.TIMING_OFFLINE_STATE);
ifTextExists(TimingLocator.TIMING_MANAGEMENT_TIMING_STATE, timingData.getTimingData("offline"));
// click online timing button
System.out.println("Click online timing button");
clickElement(TimingLocator.CLICK_ONLINE_TIMING_BUTTON);
return ifTextExists(TimingLocator.TIMING_MANAGEMENT_TIMING_STATE, TimingData.TIMING_ONLINE_STATE);
return ifTextExists(TimingLocator.TIMING_MANAGEMENT_TIMING_STATE, timingData.getTimingData("online"));
}
@ -115,13 +116,13 @@ public class TimingPage extends PageCommon {
public boolean offlineTiming() throws InterruptedException {
flushPage();
// Determine whether the timing is online
ifTextExists(TimingLocator.TIMING_MANAGEMENT_TIMING_STATE, TimingData.TIMING_ONLINE_STATE);
ifTextExists(TimingLocator.TIMING_MANAGEMENT_TIMING_STATE, timingData.getTimingData("online"));
// click offline timing button
System.out.println("Click offline timing button");
clickElement(TimingLocator.CLICK_OFFLINE_TIMING_BUTTON);
return ifTextExists(TimingLocator.TIMING_MANAGEMENT_TIMING_STATE, TimingData.TIMING_OFFLINE_STATE);
return ifTextExists(TimingLocator.TIMING_MANAGEMENT_TIMING_STATE, timingData.getTimingData("offline"));
}
@ -131,7 +132,7 @@ public class TimingPage extends PageCommon {
*/
public boolean deleteTiming() throws InterruptedException {
// Determine whether the timing is offline
ifTextExists(TimingLocator.TIMING_MANAGEMENT_TIMING_STATE, TimingData.TIMING_OFFLINE_STATE);
ifTextExists(TimingLocator.TIMING_MANAGEMENT_TIMING_STATE, timingData.getTimingData("offline"));
// click offline timing button
System.out.println("Click delete timing button");

57
e2e/src/test/java/org/apache/dolphinscheduler/page/project/WorkflowDefinePage.java

@ -17,7 +17,6 @@
package org.apache.dolphinscheduler.page.project;
import org.apache.dolphinscheduler.common.PageCommon;
import org.apache.dolphinscheduler.constant.TestConstant;
import org.apache.dolphinscheduler.data.project.ProjectData;
import org.apache.dolphinscheduler.data.project.WorkflowDefineData;
import org.apache.dolphinscheduler.locator.project.ProjectLocator;
@ -25,6 +24,9 @@ import org.apache.dolphinscheduler.locator.project.WorkflowDefineLocator;
import org.openqa.selenium.WebDriver;
public class WorkflowDefinePage extends PageCommon {
WorkflowDefineData workflowDefineData = new WorkflowDefineData();
ProjectData projectData = new ProjectData();
public WorkflowDefinePage(WebDriver driver) {
super(driver);
}
@ -34,18 +36,18 @@ public class WorkflowDefinePage extends PageCommon {
*/
public boolean jumpWorkflowPage() throws InterruptedException {
ifTextExists(ProjectLocator.LIST_PROJECT_NAME, ProjectData.PROJECT_NAME);
ifTextExists(ProjectLocator.LIST_PROJECT_NAME, projectData.getProjectData("projectName"));
// click project name
clickElement(WorkflowDefineLocator.CLICK_PROJECT_NAME);
ifTextExists(WorkflowDefineLocator.CLICK_WORKFLOW_DEFINE,WorkflowDefineData.workflow_define);
ifTextExists(WorkflowDefineLocator.CLICK_WORKFLOW_DEFINE,workflowDefineData.getWorkflowDefineData("workflowDefine"));
System.out.println("Click on workflow define to jump to workflow define page");
// click workflow define
clickElement(WorkflowDefineLocator.CLICK_WORKFLOW_DEFINE);
return ifTitleContains(WorkflowDefineData.WORKFLOW_TITLE);
return ifTitleContains(workflowDefineData.getWorkflowDefineData("workflowDefineTitle"));
}
public boolean createWorkflow() throws InterruptedException {
@ -58,8 +60,7 @@ public class WorkflowDefinePage extends PageCommon {
dragAndDrop(WorkflowDefineLocator.MOUSE_DOWN_AT_SHELL, WorkflowDefineLocator.MOUSE_MOVE_SHELL_AT_DAG);
//input shell task _name
sendInput(WorkflowDefineLocator.INPUT_SHELL_TASK_NAME , WorkflowDefineData.SHELL_TASK_NAME);
sendInput(WorkflowDefineLocator.INPUT_SHELL_TASK_NAME, workflowDefineData.getWorkflowDefineData("shellTaskName"));
//click stop run type
clickElement(WorkflowDefineLocator.CLICK_STOP_RUN_TYPE);
@ -67,7 +68,7 @@ public class WorkflowDefinePage extends PageCommon {
clickElement(WorkflowDefineLocator.CLICK_NORMAL_RUN_TYPE);
//input shell task description
sendInput(WorkflowDefineLocator.INPUT_SHELL_TASK_DESCRIPTION , WorkflowDefineData.SHELL_TASK_DESCRIPTION);
sendInput(WorkflowDefineLocator.INPUT_SHELL_TASK_DESCRIPTION, workflowDefineData.getWorkflowDefineData("shellTaskDescription"));
//select task priority
clickElement(WorkflowDefineLocator.CLICK_TASK_PRIORITY);
@ -100,20 +101,20 @@ public class WorkflowDefinePage extends PageCommon {
clearInput(WorkflowDefineLocator.SELECT_TIMEOUT);
//input timeout
sendInput(WorkflowDefineLocator.SELECT_TIMEOUT, WorkflowDefineData.INPUT_TIMEOUT);
sendInput(WorkflowDefineLocator.SELECT_TIMEOUT, workflowDefineData.getWorkflowDefineData("taskTimeout"));
//click codeMirror and input script
inputCodeMirror(WorkflowDefineLocator.CLICK_CODE_MIRROR, WorkflowDefineLocator.INPUT_SCRIPT, WorkflowDefineData.SHELL_SCRIPT);
inputCodeMirror(WorkflowDefineLocator.CLICK_CODE_MIRROR, WorkflowDefineLocator.INPUT_SCRIPT, workflowDefineData.getWorkflowDefineData("shellScript"));
scrollToElementBottom(WorkflowDefineLocator.SCROLL_BOTTOM);
//click custom parameters
clickElement(WorkflowDefineLocator.CLICK_CUSTOM_PARAMETERS);
//input custom parameters
sendInput(WorkflowDefineLocator.INPUT_CUSTOM_PARAMETERS, WorkflowDefineData.INPUT_CUSTOM_PARAMETERS);
sendInput(WorkflowDefineLocator.INPUT_CUSTOM_PARAMETERS, workflowDefineData.getWorkflowDefineData("customParameter1"));
//input custom parameters value
sendInput(WorkflowDefineLocator.INPUT_CUSTOM_PARAMETERS_VALUE, WorkflowDefineData.INPUT_CUSTOM_PARAMETERS_VALUE);
sendInput(WorkflowDefineLocator.INPUT_CUSTOM_PARAMETERS_VALUE, workflowDefineData.getWorkflowDefineData("customParameterValue1"));
//click add custom parameters
clickElement(WorkflowDefineLocator.CLICK_ADD_CUSTOM_PARAMETERS);
@ -121,10 +122,10 @@ public class WorkflowDefinePage extends PageCommon {
scrollToElementBottom(WorkflowDefineLocator.SCROLL_BOTTOM);
//input add custom parameters
sendInput(WorkflowDefineLocator.INPUT_ADD_CUSTOM_PARAMETERS, WorkflowDefineData.INPUT_ADD_CUSTOM_PARAMETERS);
sendInput(WorkflowDefineLocator.INPUT_ADD_CUSTOM_PARAMETERS, workflowDefineData.getWorkflowDefineData("customParameter2"));
//input add custom parameters value
sendInput(WorkflowDefineLocator.INPUT_ADD_CUSTOM_PARAMETERS_VALUE, WorkflowDefineData.INPUT_ADD_CUSTOM_PARAMETERS_VALUE);
sendInput(WorkflowDefineLocator.INPUT_ADD_CUSTOM_PARAMETERS_VALUE, workflowDefineData.getWorkflowDefineData("customParameterValue2"));
//click delete custom parameters
clickElement(WorkflowDefineLocator.CLICK_DELETE_CUSTOM_PARAMETERS);
@ -140,7 +141,7 @@ public class WorkflowDefinePage extends PageCommon {
clickButton(WorkflowDefineLocator.COPY_TASK);
clickButton(WorkflowDefineLocator.CLICK_LINE);
mouseMovePosition(WorkflowDefineLocator.LINE_SOURCES_TASK,WorkflowDefineLocator.LINE_TARGET_TASK);
return ifTitleContains(WorkflowDefineData.CREATE_WORKFLOW_TITLE);
return ifTitleContains(workflowDefineData.getWorkflowDefineData("createWorkflowTitle"));
}
/**
@ -153,10 +154,10 @@ public class WorkflowDefinePage extends PageCommon {
clickElement(WorkflowDefineLocator.CLICK_SAVE_WORKFLOW_BUTTON);
//input workflow name
sendInput(WorkflowDefineLocator.INPUT_WORKFLOW_NAME, WorkflowDefineData.INPUT_WORKFLOW_NAME);
sendInput(WorkflowDefineLocator.INPUT_WORKFLOW_NAME, workflowDefineData.getWorkflowDefineData("workflowName"));
//input workflow description
sendInput(WorkflowDefineLocator.INPUT_WORKFLOW_DESCRIPTION, WorkflowDefineData.INPUT_WORKFLOW_DESCRIPTION);
sendInput(WorkflowDefineLocator.INPUT_WORKFLOW_DESCRIPTION, workflowDefineData.getWorkflowDefineData("workflowDescription"));
//select tenant
clickElement(WorkflowDefineLocator.CLICK_TENANT);
@ -167,25 +168,25 @@ public class WorkflowDefinePage extends PageCommon {
clearInput(WorkflowDefineLocator.INPUT_WORKFLOW_TIMEOUT);
//input workflow timeout
sendInput(WorkflowDefineLocator.INPUT_WORKFLOW_TIMEOUT, WorkflowDefineData.INPUT_WORKFLOW_TIMEOUT);
sendInput(WorkflowDefineLocator.INPUT_WORKFLOW_TIMEOUT, workflowDefineData.getWorkflowDefineData("workflowTimeout"));
//click workflow global parameters
clickElement(WorkflowDefineLocator.CLICK_WORKFLOW_GLOBAL_PARAMETERS);
//input workflow global parameters
sendInput(WorkflowDefineLocator.INPUT_WORKFLOW_GLOBAL_PARAMETERS, WorkflowDefineData.INPUT_WORKFLOW_GLOBAL_PARAMETERS);
sendInput(WorkflowDefineLocator.INPUT_WORKFLOW_GLOBAL_PARAMETERS, workflowDefineData.getWorkflowDefineData("globalParameter1"));
//input workflow global parameters value
sendInput(WorkflowDefineLocator.INPUT_WORKFLOW_GLOBAL_PARAMETERS_VALUES, WorkflowDefineData.INPUT_WORKFLOW_GLOBAL_PARAMETERS_VALUES);
sendInput(WorkflowDefineLocator.INPUT_WORKFLOW_GLOBAL_PARAMETERS_VALUES, workflowDefineData.getWorkflowDefineData("globalParameterValue1"));
//click to add workflow global parameters
clickElement(WorkflowDefineLocator.CLICK_ADD_WORKFLOW_GLOBAL_PARAMETERS);
//input to add workflow global parameters
sendInput(WorkflowDefineLocator.INPUT_ADD_WORKFLOW_GLOBAL_PARAMETERS, WorkflowDefineData.INPUT_ADD_WORKFLOW_GLOBAL_PARAMETERS);
sendInput(WorkflowDefineLocator.INPUT_ADD_WORKFLOW_GLOBAL_PARAMETERS, workflowDefineData.getWorkflowDefineData("globalParameter2"));
//input to add workflow global parameters value
sendInput(WorkflowDefineLocator.INPUT_ADD_WORKFLOW_GLOBAL_PARAMETERS_VALUES, WorkflowDefineData.INPUT_ADD_WORKFLOW_GLOBAL_PARAMETERS_VALUES);
sendInput(WorkflowDefineLocator.INPUT_ADD_WORKFLOW_GLOBAL_PARAMETERS_VALUES, workflowDefineData.getWorkflowDefineData("globalParameterValue2"));
//delete workflow global parameters value
clickElement(WorkflowDefineLocator.CLICK_DELETE_WORKFLOW_GLOBAL_PARAMETERS);
@ -194,33 +195,33 @@ public class WorkflowDefinePage extends PageCommon {
System.out.println("submit workflow");
clickButton(WorkflowDefineLocator.CLICK_ADD_BUTTON);
return ifTitleContains(WorkflowDefineData.CREATE_WORKFLOW_TITLE);
return ifTitleContains(workflowDefineData.getWorkflowDefineData("createWorkflowTitle"));
}
public boolean onlineWorkflow() throws InterruptedException {
clickElement(WorkflowDefineLocator.CLICK_WORKFLOW_DEFINE);
// Determine whether the workflow status is offline
ifTextExists(WorkflowDefineLocator.WORKFLOW_STATE,WorkflowDefineData.WORKFLOW_OFFLINE_STATE);
ifTextExists(WorkflowDefineLocator.WORKFLOW_STATE, workflowDefineData.getWorkflowDefineData("offline"));
// click online button
System.out.println("Click online workflow button");
clickButton(WorkflowDefineLocator.CLICK_ONLINE_WORKFLOW_BUTTON);
return ifTitleContains(WorkflowDefineData.WORKFLOW_TITLE);
return ifTextExists(WorkflowDefineLocator.WORKFLOW_STATE, workflowDefineData.getWorkflowDefineData("online"));
}
public boolean offlineWorkflow() throws InterruptedException {
clickElement(WorkflowDefineLocator.CLICK_WORKFLOW_DEFINE);
// Determine whether the workflow status is online
ifTextExists(WorkflowDefineLocator.WORKFLOW_STATE,WorkflowDefineData.WORKFLOW_ONLINE_STATE);
ifTextExists(WorkflowDefineLocator.WORKFLOW_STATE, workflowDefineData.getWorkflowDefineData("online"));
// click offline button
System.out.println("offline workflow");
clickButton(WorkflowDefineLocator.CLICK_OFFLINE_WORKFLOW_BUTTON);
return ifTitleContains(WorkflowDefineData.WORKFLOW_TITLE);
return ifTextExists(WorkflowDefineLocator.WORKFLOW_STATE, workflowDefineData.getWorkflowDefineData("offline"));
}
@ -229,7 +230,7 @@ public class WorkflowDefinePage extends PageCommon {
clickElement(WorkflowDefineLocator.CLICK_WORKFLOW_DEFINE);
// Determine whether the workflow status is offline
ifTextExists(WorkflowDefineLocator.WORKFLOW_STATE,WorkflowDefineData.WORKFLOW_OFFLINE_STATE);
ifTextExists(WorkflowDefineLocator.WORKFLOW_STATE, workflowDefineData.getWorkflowDefineData("offline"));
clickButton(WorkflowDefineLocator.DELETE_WORKFLOW_BOTTOM);
@ -237,6 +238,6 @@ public class WorkflowDefinePage extends PageCommon {
clickButton(WorkflowDefineLocator.CONFIRM_DELETE_WORKFLOW_BOTTOM);
// Whether to enter the specified page after submit
return ifTitleContains(WorkflowDefineData.WORKFLOW_TITLE);
return ifTitleContains(workflowDefineData.getWorkflowDefineData("workflowDefineTitle"));
}
}

14
e2e/src/test/java/org/apache/dolphinscheduler/page/security/AlertManagePage.java

@ -22,6 +22,8 @@ import org.apache.dolphinscheduler.locator.security.AlertManageLocator;
import org.openqa.selenium.WebDriver;
public class AlertManagePage extends PageCommon {
AlertManageData alertManageData = new AlertManageData();
/**
* Unique constructor
* @param driver driver
@ -41,26 +43,26 @@ public class AlertManagePage extends PageCommon {
clickElement(AlertManageLocator.CLICK_ALERT_MANAGE);
//determine whether the create alert button exists
ifTextExists(AlertManageLocator.CLICK_CREATE_ALERT,AlertManageData.CREATE_ALERT);
ifTextExists(AlertManageLocator.CLICK_CREATE_ALERT,alertManageData.getAlertData("createAlert"));
// click create alert button
System.out.println("start click create alert button");
clickElement(AlertManageLocator.CLICK_CREATE_ALERT);
// input alert data
System.out.println("start input alert ");
sendInput(AlertManageLocator.INPUT_ALERT_NAME, AlertManageData.ALERT_NAME);
sendInput(AlertManageLocator.INPUT_ALERT_NAME, alertManageData.getAlertData("alertName"));
clickElement(AlertManageLocator.CLICK_ALERT_TYPE);
clickElement(AlertManageLocator.SELECT_ALERT_EMAIL);
sendInput(AlertManageLocator.INPUT_ALERT_DESCRIPTION, AlertManageData.DESCRIPTION);
sendInput(AlertManageLocator.INPUT_ALERT_DESCRIPTION, alertManageData.getAlertData("description"));
// click button
clickButton(AlertManageLocator.SUBMIT_ALERT);
// Whether to enter the specified page after submit
return ifTextExists(AlertManageLocator.ALERT_NAME, AlertManageData.ALERT_NAME);
return ifTextExists(AlertManageLocator.ALERT_NAME, alertManageData.getAlertData("alertName"));
}
public boolean deleteAlert() throws InterruptedException {
@ -68,7 +70,7 @@ public class AlertManagePage extends PageCommon {
// click alert manage
clickElement(AlertManageLocator.CLICK_ALERT_MANAGE);
ifTextExists(AlertManageLocator.ALERT_NAME, AlertManageData.ALERT_NAME);
ifTextExists(AlertManageLocator.ALERT_NAME, alertManageData.getAlertData("alertName"));
// click delete alert button
clickButton(AlertManageLocator.DELETE_ALERT_BUTTON);
@ -77,6 +79,6 @@ public class AlertManagePage extends PageCommon {
clickButton(AlertManageLocator.CONFIRM_DELETE_ALERT_BUTTON);
// Whether to enter the specified page after submit
return ifTitleContains(AlertManageData.ALERT_MANAGE);
return ifTitleContains(alertManageData.getAlertData("alertTitle"));
}
}

18
e2e/src/test/java/org/apache/dolphinscheduler/page/security/QueueManagePage.java

@ -22,6 +22,8 @@ import org.apache.dolphinscheduler.locator.security.QueueManageLocator;
import org.openqa.selenium.WebDriver;
public class QueueManagePage extends PageCommon {
QueueManageData queueManageData = new QueueManageData();
/**
* Unique constructor
* @param driver driver
@ -41,7 +43,7 @@ public class QueueManagePage extends PageCommon {
clickElement(QueueManageLocator.CLICK_QUEUE_MANAGE);
//determine whether the create queue button exists
ifTextExists(QueueManageLocator.CLICK_CREATE_QUEUE,QueueManageData.CREATE_QUEUE);
ifTextExists(QueueManageLocator.CLICK_CREATE_QUEUE, queueManageData.getQueueData("createQueueButton"));
// click create queue button
System.out.println("start click create queue button");
@ -49,15 +51,15 @@ public class QueueManagePage extends PageCommon {
// input queue data
System.out.println("start input queue");
sendInput(QueueManageLocator.INPUT_QUEUE_NAME, QueueManageData.QUEUE_NAME);
sendInput(QueueManageLocator.INPUT_QUEUE_NAME, queueManageData.getQueueData("queueName"));
sendInput(QueueManageLocator.INPUT_QUEUE_VALUE, QueueManageData.QUEUE_VALUE);
sendInput(QueueManageLocator.INPUT_QUEUE_VALUE, queueManageData.getQueueData("queueValue"));
// click button
clickButton(QueueManageLocator.SUBMIT_QUEUE);
// Whether to enter the specified page after submit
return ifTextExists(QueueManageLocator.LIST_QUEUE_NAME, QueueManageData.QUEUE_NAME);
return ifTextExists(QueueManageLocator.LIST_QUEUE_NAME, queueManageData.getQueueData("queueName"));
}
@ -70,19 +72,19 @@ public class QueueManagePage extends PageCommon {
// click queue manage
clickElement(QueueManageLocator.CLICK_QUEUE_MANAGE);
ifTextExists(QueueManageLocator.LIST_QUEUE_NAME, QueueManageData.QUEUE_NAME);
ifTextExists(QueueManageLocator.LIST_QUEUE_NAME, queueManageData.getQueueData("queueName"));
// click edit queue button
clickButton(QueueManageLocator.CLICK_EDIT_QUEUE);
// input queue data
clearSendInput(QueueManageLocator.INPUT_QUEUE_NAME, QueueManageData.EDIT_QUEUE_NAME);
clearSendInput(QueueManageLocator.INPUT_QUEUE_VALUE, QueueManageData.EDIT_QUEUE_VALUE);
clearSendInput(QueueManageLocator.INPUT_QUEUE_NAME, queueManageData.getQueueData("editQueueName"));
clearSendInput(QueueManageLocator.INPUT_QUEUE_VALUE, queueManageData.getQueueData("editQueueValue"));
// click button
clickButton(QueueManageLocator.SUBMIT_QUEUE);
// Whether to enter the specified page after submit
return ifTextExists(QueueManageLocator.LIST_QUEUE_NAME, QueueManageData.EDIT_QUEUE_NAME);
return ifTextExists(QueueManageLocator.LIST_QUEUE_NAME, queueManageData.getQueueData("editQueueName"));
}
}

16
e2e/src/test/java/org/apache/dolphinscheduler/page/security/TenantManagePage.java

@ -22,6 +22,8 @@ import org.apache.dolphinscheduler.locator.security.TenantManageLocator;
import org.openqa.selenium.WebDriver;
public class TenantManagePage extends PageCommon {
TenantManageData tenantManageData = new TenantManageData();
/**
* Unique constructor
* @param driver driver
@ -37,7 +39,7 @@ public class TenantManagePage extends PageCommon {
*/
public boolean jumpSecurity() throws InterruptedException {
clickTopElement(TenantManageLocator.SECURITY_CENTER);
return ifTitleContains(TenantManageData.TENANT_MANAGE);
return ifTitleContains(tenantManageData.getTenantData("tenantTitle"));
}
/**
@ -52,16 +54,16 @@ public class TenantManagePage extends PageCommon {
clickButton(TenantManageLocator.CREATE_TENANT_BUTTON);
// tenant data
sendInput(TenantManageLocator.TENANT_INPUT_CODE, TenantManageData.TENANT_CODE);
sendInput(TenantManageLocator.TENANT_INPUT_NAME, TenantManageData.TENANT_NAME);
sendInput(TenantManageLocator.QUEUE, TenantManageData.QUEUE);
sendInput(TenantManageLocator.DESCRIPTION, TenantManageData.DESCRIPTION);
sendInput(TenantManageLocator.TENANT_INPUT_CODE, tenantManageData.getTenantData("tenantCode"));
sendInput(TenantManageLocator.TENANT_INPUT_NAME, tenantManageData.getTenantData("tenantName"));
sendInput(TenantManageLocator.QUEUE, tenantManageData.getTenantData("queue"));
sendInput(TenantManageLocator.DESCRIPTION, tenantManageData.getTenantData("description"));
// click button
clickButton(TenantManageLocator.SUBMIT_BUTTON);
// Whether to enter the specified page after submit
return ifTextExists(TenantManageLocator.TENANT_CODE_FIRST, TenantManageData.TENANT_CODE);
return ifTextExists(TenantManageLocator.TENANT_CODE_FIRST, tenantManageData.getTenantData("tenantCode"));
}
public boolean deleteTenant() throws InterruptedException {
@ -74,6 +76,6 @@ public class TenantManagePage extends PageCommon {
clickButton(TenantManageLocator.CONFIRM_DELETE_TENANT_BUTTON);
// Whether to enter the specified page after submit
return ifTitleContains(TenantManageData.TENANT_MANAGE);
return ifTitleContains(tenantManageData.getTenantData("tenantTitle"));
}
}

14
e2e/src/test/java/org/apache/dolphinscheduler/page/security/TokenManagePage.java

@ -22,6 +22,8 @@ import org.apache.dolphinscheduler.locator.security.TokenManageLocator;
import org.openqa.selenium.WebDriver;
public class TokenManagePage extends PageCommon {
TokenManageData tokenManageData = new TokenManageData();
public TokenManagePage(WebDriver driver) {
super(driver);
}
@ -36,11 +38,13 @@ public class TokenManagePage extends PageCommon {
clickElement(TokenManageLocator.CLICK_TOKEN_MANAGE);
//determine whether the create token button exists
ifTextExists(TokenManageLocator.CLICK_CREATE_TOKEN,TokenManageData.CREATE_TOKEN);
ifTextExists(TokenManageLocator.CLICK_CREATE_TOKEN, tokenManageData.getTokenData("createTokenText"));
// click create token button
clickButton(TokenManageLocator.CLICK_CREATE_TOKEN);
ifTextExists(TokenManageLocator.CREATE_TOKEN_POPUP,tokenManageData.getTokenData("createTokenText"));
clickButton(TokenManageLocator.SELECT_USER);
clickButton(TokenManageLocator.CLICK_GENERATE_TOKEN_BUTTON);
@ -50,7 +54,7 @@ public class TokenManagePage extends PageCommon {
clickButton(TokenManageLocator.CLICK_SUBMIT_BUTTON);
// Whether to enter the specified page after submit
return ifTitleContains(TokenManageData.TOKEN_MANAGE);
return ifTitleContains(tokenManageData.getTokenData("tokenTitle"));
}
/**
@ -66,7 +70,7 @@ public class TokenManagePage extends PageCommon {
locateElement(TokenManageLocator.EDIT_TOKEN_BUTTON);
// click edit token button
clickButton(TokenManageLocator.CLICK_EDIT_BUTTON);
clickButton(TokenManageLocator.EDIT_TOKEN_BUTTON);
clickButton(TokenManageLocator.SELECT_USER);
@ -77,7 +81,7 @@ public class TokenManagePage extends PageCommon {
clickButton(TokenManageLocator.CLICK_SUBMIT_BUTTON);
// Whether to enter the specified page after submit
return ifTitleContains(TokenManageData.TOKEN_MANAGE);
return ifTitleContains(tokenManageData.getTokenData("tokenTitle"));
}
@ -89,7 +93,7 @@ public class TokenManagePage extends PageCommon {
clickButton(TokenManageLocator.CLICK_DELETE_BUTTON);
clickButton(TokenManageLocator.CLICK_CONFIRM_DELETE_BUTTON);
return ifTitleContains(TokenManageData.TOKEN_MANAGE);
return ifTitleContains(tokenManageData.getTokenData("tokenTitle"));
}
}

33
e2e/src/test/java/org/apache/dolphinscheduler/page/security/UserManagePage.java

@ -22,6 +22,8 @@ import org.apache.dolphinscheduler.locator.security.UserManageLocator;
import org.openqa.selenium.WebDriver;
public class UserManagePage extends PageCommon {
UserManageData userManageData = new UserManageData();
public UserManagePage(WebDriver driver) {
super(driver);
}
@ -34,22 +36,21 @@ public class UserManagePage extends PageCommon {
public boolean createUser() throws InterruptedException {
// click user manage
clickElement(UserManageLocator.CLICK_USER_MANAGE);
//determine whether the create user button exists
ifTextExists(UserManageLocator.CLICK_CREATE_USER_BUTTON,UserManageData.CREATE_USER_BUTTON);
ifTextExists(UserManageLocator.CLICK_CREATE_USER_BUTTON, userManageData.getUserData("createUserButton"));
// 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);
sendInput(UserManageLocator.INPUT_USERNAME, userManageData.getUserData("userName"));
sendInput(UserManageLocator.INPUT_PASSWORD, userManageData.getUserData("password"));
clickButton(UserManageLocator.CLICK_TENANT);
clickButton(UserManageLocator.SELECT_TENANT);
clickButton(UserManageLocator.CLICK_QUEUE);
clickButton(UserManageLocator.SELECT_QUEUE);
sendInput(UserManageLocator.INPUT_EMAIL, UserManageData.EMAIL);
sendInput(UserManageLocator.INPUT_PHONE, UserManageData.PHONE);
sendInput(UserManageLocator.INPUT_EMAIL, userManageData.getUserData("email"));
sendInput(UserManageLocator.INPUT_PHONE, userManageData.getUserData("phone"));
clickElement(UserManageLocator.SELECT_STOP_STATE);
clickElement(UserManageLocator.SELECT_ENABLE_STATE);
@ -57,7 +58,7 @@ public class UserManagePage extends PageCommon {
clickButton(UserManageLocator.SUBMIT);
// Whether to enter the specified page after submit
return ifTitleContains(UserManageData.USER_MANAGE);
return ifTextExists(UserManageLocator.USERNAME, userManageData.getUserData("userName"));
}
/**
@ -70,14 +71,14 @@ public class UserManagePage extends PageCommon {
clickElement(UserManageLocator.CLICK_USER_MANAGE);
//determine whether the general user exists
ifTextExists(UserManageLocator.USER_NAME,UserManageData.USERNAME);
ifTextExists(UserManageLocator.USERNAME, userManageData.getUserData("userName"));
// click edit user button
clickButton(UserManageLocator.EDIT_GENERAL_USER_BUTTON );
// input user data
clearSendInput(UserManageLocator.INPUT_USERNAME, UserManageData.EDIT_USERNAME);
clearSendInput(UserManageLocator.INPUT_PASSWORD, UserManageData.EDIT_PASSWORD);
clearSendInput(UserManageLocator.INPUT_USERNAME, userManageData.getUserData("editUserName"));
clearSendInput(UserManageLocator.INPUT_PASSWORD, userManageData.getUserData("editPassword"));
clickButton(UserManageLocator.CLICK_TENANT);
clickButton(UserManageLocator.SELECT_TENANT);
@ -85,8 +86,8 @@ public class UserManagePage extends PageCommon {
clickButton(UserManageLocator.CLICK_QUEUE);
clickButton(UserManageLocator.SELECT_QUEUE);
clearSendInput(UserManageLocator.INPUT_EMAIL, UserManageData.EDIT_EMAIL);
clearSendInput(UserManageLocator.INPUT_PHONE, UserManageData.EDIT_PHONE);
clearSendInput(UserManageLocator.INPUT_EMAIL, userManageData.getUserData("editEmail"));
clearSendInput(UserManageLocator.INPUT_PHONE, userManageData.getUserData("editPhone"));
clickElement(UserManageLocator.SELECT_STOP_STATE);
clickElement(UserManageLocator.SELECT_ENABLE_STATE);
@ -96,7 +97,7 @@ public class UserManagePage extends PageCommon {
System.out.println("end edit general user");
// Whether to enter the specified page after submit
return ifTitleContains(UserManageData.USER_MANAGE);
return ifTitleContains(userManageData.getUserData("userTitle"));
}
/**
@ -109,7 +110,7 @@ public class UserManagePage extends PageCommon {
clickElement(UserManageLocator.CLICK_USER_MANAGE);
//determine whether the general user edit success
ifTextExists(UserManageLocator.USER_NAME,UserManageData.EDIT_USERNAME);
ifTextExists(UserManageLocator.USER_NAME,userManageData.getUserData("editUserName"));
// click edit user button
clickButton(UserManageLocator.EDIT_ADMIN_USER_BUTTON );
@ -123,7 +124,7 @@ public class UserManagePage extends PageCommon {
clickButton(UserManageLocator.SUBMIT);
System.out.println("end edit admin user");
// Whether to enter the specified page after submit
return ifTitleContains(UserManageData.USER_MANAGE);
return ifTitleContains(userManageData.getUserData("userTitle"));
}
@ -144,6 +145,6 @@ public class UserManagePage extends PageCommon {
clickButton(UserManageLocator.CONFIRM_DELETE_USER_BUTTON);
// Whether to enter the specified page after submit
return ifTitleContains(UserManageData.USER_MANAGE);
return ifTitleContains(userManageData.getUserData("userTitle"));
}
}

55
e2e/src/test/resources/testData/security_zh_cn.yml

@ -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.
#
userManage:
userName: selenium_user_11111
password: 123456qwe
email: 123456789@qq.com
phone: '15811112222'
createUserButton: 创建用户
editUserName: selenium_user_edit
editPassword: 123456qwe@asd
editEmail: 123456_edit@qq.com
editPhone: '15800001111'
userTitle: 用户管理 - DolphinScheduler
tenantManage:
tenantCode: selenium_tenant_code_1
tenantName: selenium_tenant_Name
queue: default
description: create tenant test
tenantTitle: 租户管理 - DolphinScheduler
alertManage:
alertName: selenium_alert_Name
createAlert: 创建告警组
alertType: 邮件
description: create alert test
alertTitle: 告警组管理 - DolphinScheduler
queueManage:
queueName: selenium_queue_name
queueValue: selenium_queue_value
createQueueButton: 创建队列
editQueueName: selenium_queue_value_edit
editQueueValue: selenium_queue_value_edit
queueTitle: 队列管理 - DolphinScheduler
tokenManage:
tokenTitle: 令牌管理 - DolphinScheduler
createTokenText: 创建令牌
userName: admin

63
e2e/src/test/resources/testData/workflow_zh_cn.yml

@ -0,0 +1,63 @@
#
# 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.
#
projectManage:
createProjectButton: 创建项目
projectName: selenium_project_1
description: test create project description
projectTitle: 项目 - DolphinScheduler
workflowDefine:
workflowDefine: 工作流定义
shellTaskName: shell_task_selenium_1
shellTaskDescription: shell task description test
taskTimeout: '60'
shellScript: echo "shell task test"
customParameter1: selenium_parameter
customParameterValue1: selenium_parameter_123
customParameter2: selenium_parameter_delete
customParameterValue2: selenium_parameter_delete_456
workflowDefineTitle: 工作流定义 - DolphinScheduler
createWorkflowTitle: 创建流程定义 - DolphinScheduler
workflowName: selenium_shell_1
workflowDescription: test selenium_shell_1 description
workflowTimeout: '30'
globalParameter1: selenium_global_parameters_1
globalParameterValue1: selenium_global_parameters_value_1
globalParameter2: selenium_global_parameters_2
globalParameterValue2: selenium_global_parameters_value_2
online: 上线
offline: 下线
runWorkflow:
recipient: 123456789@qq.com
Cc: qwe12312sds@qq.com
online: 上线
offline: 下线
timing:
recipient: test123456@qq.com
Cc: test.123qwe@qq.com
editRecipient: test.edit123456@qq.com
editCc: test.edit123qwe@qq.com
timingTitle: 定时任务列表 - DolphinScheduler
online: 上线
offline: 下线
processInstance:
processInstanceTitle: 工作流实例 - DolphinScheduler
rerun: 重跑

2
e2e/testng.xml

@ -56,9 +56,9 @@
<!--<class name="org.apache.dolphinscheduler.testcase.testProject.TestTiming">-->
<!--<methods>-->
<!--<include name="testCreateTiming" />-->
<!--<include name="testEditTiming" />-->
<!--<include name="testOnlineTiming" />-->
<!--<include name="testOfflineTiming" />-->
<!--<include name="testEditTiming" />-->
<!--<include name="testDeleteTiming" />-->
<!--</methods>-->
<!--</class>-->

Loading…
Cancel
Save