tachybase_todo/packages/plugins/@nocobase/plugin-workflow-test/src/e2e/e2eUtils.ts

748 lines
20 KiB
TypeScript
Raw Normal View History

import { request } from '@nocobase/test/e2e';
const PORT = process.env.APP_PORT || 20000;
const APP_BASE_URL = process.env.APP_BASE_URL || `http://localhost:${PORT}`;
// 创建工作流
export const apiCreateWorkflow = async (data: any) => {
const api = await request.newContext({
storageState: process.env.PLAYWRIGHT_AUTH_FILE,
});
const state = await api.storageState();
const headers = getHeaders(state);
/*
{
"current": true,
"options": {
"deleteExecutionOnStatus": []
},
"title": "t3",
"type": "collection"
}
*/
const result = await api.post(`/api/workflows:create`, {
headers,
data,
});
if (!result.ok()) {
throw new Error(await result.text());
}
/*
{
"data": {
"id": 74,
"key": "il2nu3ovj53",
"updatedAt": "2023-12-12T06:53:21.232Z",
"createdAt": "2023-12-12T06:53:21.232Z",
"title": "t3",
"type": "collection",
"enabled": false,
"description": null,
"executed": 0,
"allExecuted": 0,
"config": {},
"current": true,
"options": {
"deleteExecutionOnStatus": []
},
"useTransaction": true
}
}
*/
return (await result.json()).data;
};
// 更新工作流
export const apiUpdateWorkflow = async (id: number, data: any) => {
const api = await request.newContext({
storageState: process.env.PLAYWRIGHT_AUTH_FILE,
});
const state = await api.storageState();
const headers = getHeaders(state);
/*
{
"id": 74,
"key": "il2nu3ovj53",
"updatedAt": "2023-12-12T06:53:21.232Z",
"createdAt": "2023-12-12T06:53:21.232Z",
"title": "t3",
"type": "collection",
"enabled": false,
"description": null,
"executed": 0,
"allExecuted": 0,
"current": true,
"options": {
"deleteExecutionOnStatus": []
},
"useTransaction": true
}
*/
const result = await api.post(`/api/workflows:update?filterByTk=${id}`, {
headers,
data,
});
if (!result.ok()) {
throw new Error(await result.text());
}
/*{
"data": [
{
"id": 72,
"createdAt": "2023-12-12T02:43:53.793Z",
"updatedAt": "2023-12-12T05:41:33.300Z",
"key": "fzk3j2oj4el",
"title": "a11",
"enabled": true,
"description": null,
"type": "collection",
"config": {},
"useTransaction": true,
"executed": 0,
"allExecuted": 0,
"current": true,
"options": {
"deleteExecutionOnStatus": []
}
}
]
}*/
return (await result.json()).data;
};
// 删除工作流
export const apiDeleteWorkflow = async (id: number) => {
const api = await request.newContext({
storageState: process.env.PLAYWRIGHT_AUTH_FILE,
});
const state = await api.storageState();
const headers = getHeaders(state);
const result = await api.post(`/api/workflows:destroy?filterByTk=${id}`, {
headers,
});
if (!result.ok()) {
throw new Error(await result.text());
}
// {"data":1}
return (await result.json()).data;
};
// 查询工作流
export const apiGetWorkflow = async (id: number) => {
const api = await request.newContext({
storageState: process.env.PLAYWRIGHT_AUTH_FILE,
});
const state = await api.storageState();
const headers = getHeaders(state);
const result = await api.get(`/api/workflows:get?filterByTk=${id}`, {
headers,
});
if (!result.ok()) {
throw new Error(await result.text());
}
/*
{
"data": {
"id": 73,
"createdAt": "2023-12-12T05:59:52.741Z",
"updatedAt": "2023-12-12T05:59:52.741Z",
"key": "1iuin0qchrh",
"title": "t2",
"enabled": false,
"description": null,
"type": "collection",
"config": { },
"useTransaction": true,
"executed": 0,
"allExecuted": 0,
"current": true,
"options": { }
}
}
*/
return (await result.json()).data;
};
// 更新工作流触发器节点
export const apiUpdateWorkflowTrigger = async (id: number, data: any) => {
const api = await request.newContext({
storageState: process.env.PLAYWRIGHT_AUTH_FILE,
});
const state = await api.storageState();
const headers = getHeaders(state);
/*
{
"config": {
"appends": [
"dept"
],
"collection": "tt_mnt_org",
"changed": [],
"condition": {
"$and": [
{
"id": {
"$eq": 1
}
}
]
},
"mode": 1
}
}
*/
const result = await api.post(`/api/workflows:update?filterByTk=${id}`, {
headers,
data,
});
if (!result.ok()) {
throw new Error(await result.text());
}
/*
{
"data": [
{
"id": 73,
"createdAt": "2023-12-12T05:59:52.741Z",
"updatedAt": "2023-12-12T06:13:36.068Z",
"key": "1iuin0qchrh",
"title": "t2",
"enabled": false,
"description": null,
"type": "collection",
"config": {
"appends": [
"dept"
],
"collection": "tt_mnt_org",
"changed": [],
"condition": {
"$and": [
{
"id": {
"$eq": 1
}
}
]
},
"mode": 1
},
"useTransaction": true,
"executed": 0,
"allExecuted": 0,
"current": true,
"options": {}
}
]
}
*/
return (await result.json()).data;
};
// 添加工作流节点
export const apiCreateWorkflowNode = async (workflowId: number, data: any) => {
const api = await request.newContext({
storageState: process.env.PLAYWRIGHT_AUTH_FILE,
});
const state = await api.storageState();
const headers = getHeaders(state);
/*upstreamIdid ,null
{
"type": "calculation",
"upstreamId": 263,
"branchIndex": null,
"title": "运算",
"config": {}
}
*/
const result = await api.post(`/api/workflows/${workflowId}/nodes:create`, {
headers,
data,
});
if (!result.ok()) {
throw new Error(await result.text());
}
/*
{
"data": {
"id": 265,
"type": "calculation",
"upstreamId": null,
"branchIndex": null,
"title": "运算",
"config": {},
"workflowId": 76,
"updatedAt": "2023-12-16T10:56:39.288Z",
"createdAt": "2023-12-16T10:56:39.281Z",
"key": "20jz2urt5w7",
"downstreamId": 263
}
}
*/
return (await result.json()).data;
};
// 查询工作流节点
export const apiGetWorkflowNode = async (id: number) => {
const api = await request.newContext({
storageState: process.env.PLAYWRIGHT_AUTH_FILE,
});
const state = await api.storageState();
const headers = getHeaders(state);
const result = await api.get(`/api/flow_nodes:get?filterByTk=${id}`, {
headers,
});
if (!result.ok()) {
throw new Error(await result.text());
}
/*
{
"data": {
"id": 267,
"createdAt": "2023-12-17T06:56:10.147Z",
"updatedAt": "2023-12-17T08:53:38.117Z",
"key": "idr5wibhyqn",
"title": "查询数据",
"upstreamId": 269,
"branchIndex": null,
"downstreamId": 270,
"type": "query",
"config": {
"collection": "users",
"params": {
"filter": {
"$and": [
{
"id": {
"$eq": "{{$context.data.id}}"
}
}
]
},
"sort": [],
"page": 1,
"pageSize": 20,
"appends": []
}
},
"workflowId": 76
}
}
*/
return (await result.json()).data;
};
// 更新工作流节点配置
export const apiUpdateWorkflowNode = async (id: number, data: any) => {
const api = await request.newContext({
storageState: process.env.PLAYWRIGHT_AUTH_FILE,
});
const state = await api.storageState();
const headers = getHeaders(state);
/*
{
"config": {
"engine": "math.js",
"expression": "1"
}
}
*/
const result = await api.post(`/api/flow_nodes:update?filterByTk=${id}`, {
headers,
data,
});
if (!result.ok()) {
throw new Error(await result.text());
}
/*
{
"data": [
{
"id": 266,
"createdAt": "2023-12-16T10:56:58.586Z",
"updatedAt": "2023-12-16T11:16:32.796Z",
"key": "atbyvcs5mwc",
"title": "运算",
"upstreamId": 263,
"branchIndex": null,
"downstreamId": null,
"type": "calculation",
"config": {
"engine": "math.js",
"expression": "1"
},
"workflowId": 76
}
]
}
*/
return (await result.json()).data;
};
// 查询节点执行历史
export const apiGetWorkflowNodeExecutions = async (id: number) => {
const api = await request.newContext({
storageState: process.env.PLAYWRIGHT_AUTH_FILE,
});
const state = await api.storageState();
const headers = getHeaders(state);
const url = `/api/executions:list?appends[]=jobs&filter[workflowId]=${id}&fields=id,createdAt,updatedAt,key,status,workflowId,jobs`;
const result = await api.get(url, {
headers,
});
if (!result.ok()) {
throw new Error(await result.text());
}
/*
{
"data": [
{
"id": 15,
"createdAt": "2023-12-13T02:13:13.737Z",
"updatedAt": "2023-12-13T02:13:13.799Z",
"key": "yibkv8h2uq6",
"useTransaction": false,
"status": 1,
"workflowId": 16,
"jobs": [
{
"id": 16,
"createdAt": "2023-12-13T02:13:13.783Z",
"updatedAt": "2023-12-13T02:13:13.783Z",
"executionId": 15,
"nodeId": 16,
"upstreamId": null,
"status": 1,
"result": false
},
{
"id": 17,
"createdAt": "2023-12-13T02:13:13.788Z",
"updatedAt": "2023-12-13T02:13:13.788Z",
"executionId": 15,
"nodeId": 17,
"upstreamId": 16,
"status": 1,
"result": true
}
]
},
{
"id": 14,
"createdAt": "2023-12-13T02:09:00.529Z",
"updatedAt": "2023-12-13T02:09:00.590Z",
"key": "yibkv8h2uq6",
"useTransaction": false,
"status": 1,
"workflowId": 16,
"jobs": [
{
"id": 14,
"createdAt": "2023-12-13T02:09:00.575Z",
"updatedAt": "2023-12-13T02:09:00.575Z",
"executionId": 14,
"nodeId": 16,
"upstreamId": null,
"status": 1,
"result": false
},
{
"id": 15,
"createdAt": "2023-12-13T02:09:00.583Z",
"updatedAt": "2023-12-13T02:09:00.583Z",
"executionId": 14,
"nodeId": 17,
"upstreamId": 14,
"status": 1,
"result": true
}
]
}
],
"meta": {
"count": 2,
"page": 1,
"pageSize": 20,
"totalPage": 1
}
}
*/
return (await result.json()).data;
};
// 更新业务表单条数据
export const apiUpdateRecord = async (collectionName: string, id: number, data: any) => {
const api = await request.newContext({
storageState: process.env.PLAYWRIGHT_AUTH_FILE,
});
const state = await api.storageState();
const headers = getHeaders(state);
const result = await api.post(`/api/${collectionName}:update?filterByTk=${id}`, {
headers,
data,
});
if (!result.ok()) {
throw new Error(await result.text());
}
/*
{
"data": [
{
"id": 1,
"createdAt": "2023-12-12T02:43:53.793Z",
"updatedAt": "2023-12-12T05:41:33.300Z",
"key": "fzk3j2oj4el",
"title": "a11",
"enabled": true,
"description": null
}
]
}
*/
return (await result.json()).data;
};
// 查询业务表单条数据
export const apiGetRecord = async (collectionName: string, id: number) => {
const api = await request.newContext({
storageState: process.env.PLAYWRIGHT_AUTH_FILE,
});
const state = await api.storageState();
const headers = getHeaders(state);
const result = await api.get(`/api/${collectionName}:get?filterByTk=${id}`, {
headers,
});
if (!result.ok()) {
throw new Error(await result.text());
}
/*
{
"data": {
"id": 1,
"createdAt": "2023-12-12T02:43:53.793Z",
"updatedAt": "2023-12-12T05:41:33.300Z",
"key": "fzk3j2oj4el",
"title": "a11",
"enabled": true,
"description": null
},
"meta": {
"allowedActions": {
"view": [
1
],
"update": [
1
],
"destroy": [
1
]
}
}
}
*/
return (await result.json()).data;
};
// 查询业务表list
export const apiGetList = async (collectionName: string) => {
const api = await request.newContext({
storageState: process.env.PLAYWRIGHT_AUTH_FILE,
});
const state = await api.storageState();
const headers = getHeaders(state);
const result = await api.get(`/api/${collectionName}:list`, {
headers,
});
if (!result.ok()) {
throw new Error(await result.text());
}
/*
{
"data": [
{
"id": 1,
"createdAt": "2023-12-12T02:43:53.793Z",
"updatedAt": "2023-12-12T05:41:33.300Z",
"key": "fzk3j2oj4el",
"title": "a11",
"enabled": true,
"description": null
}
],
"meta": {
"count": 1,
"page": 1,
"pageSize": 20,
"totalPage": 1
}
}
*/
return await result.json();
};
// 添加业务表单条数据触发工作流表单事件,triggerWorkflows=key1!field,key2,key3!field.subfield
export const apiCreateRecordTriggerFormEvent = async (collectionName: string, triggerWorkflows: string, data: any) => {
const api = await request.newContext({
storageState: process.env.PLAYWRIGHT_AUTH_FILE,
});
const state = await api.storageState();
const headers = getHeaders(state);
/*
{
"title": "a11",
"enabled": true,
"description": null
}
*/
const result = await api.post(`/api/${collectionName}:create?triggerWorkflows=${triggerWorkflows}`, {
headers,
data,
});
if (!result.ok()) {
throw new Error(await result.text());
}
/*
{
"data": {
"id": 1,
"createdAt": "2023-12-12T02:43:53.793Z",
"updatedAt": "2023-12-12T05:41:33.300Z",
"key": "fzk3j2oj4el",
"title": "a11",
"enabled": true,
"description": null
},
"meta": {
"allowedActions": {
"view": [
1
],
"update": [
1
],
"destroy": [
1
]
}
}
}
*/
return (await result.json()).data;
};
// 提交至工作流触发工作流表单事件
export const apiSubmitRecordTriggerFormEvent = async (triggerWorkflows: string, data: any) => {
const api = await request.newContext({
storageState: process.env.PLAYWRIGHT_AUTH_FILE,
});
const state = await api.storageState();
const headers = getHeaders(state);
/*
{
"title": "a11",
"enabled": true,
"description": null
}
*/
const result = await api.post(`/api/workflows:trigger?triggerWorkflows=${triggerWorkflows}`, {
headers,
data,
});
if (!result.ok()) {
throw new Error(await result.text());
}
/*
{}
*/
return await result.json();
};
const getStorageItem = (key: string, storageState: any) => {
return storageState.origins
.find((item) => item.origin === APP_BASE_URL)
?.localStorage.find((item) => item.name === key)?.value;
};
function getHeaders(storageState: any) {
const headers: any = {};
const token = getStorageItem('NOCOBASE_TOKEN', storageState);
const auth = getStorageItem('NOCOBASE_AUTH', storageState);
const subAppName = new URL(APP_BASE_URL).pathname.match(/^\/apps\/([^/]*)\/*/)?.[1];
const hostName = new URL(APP_BASE_URL).host;
const locale = getStorageItem('NOCOBASE_LOCALE', storageState);
const timezone = '+08:00';
const withAclMeta = 'true';
const role = getStorageItem('NOCOBASE_ROLE', storageState);
if (token) {
headers.Authorization = `Bearer ${token}`;
}
if (auth) {
headers['X-Authenticator'] = auth;
}
if (subAppName) {
headers['X-App'] = subAppName;
}
if (hostName) {
headers['X-Hostname'] = hostName;
}
if (locale) {
headers['X-Locale'] = locale;
}
if (timezone) {
headers['X-Timezone'] = timezone;
}
if (withAclMeta) {
headers['X-With-Acl-Meta'] = withAclMeta;
}
if (role) {
headers['X-Role'] = role;
}
return headers;
}
export default module.exports = {
apiCreateWorkflow,
apiUpdateWorkflow,
apiDeleteWorkflow,
apiGetWorkflow,
apiUpdateWorkflowTrigger,
apiGetWorkflowNodeExecutions,
apiCreateWorkflowNode,
apiUpdateWorkflowNode,
apiGetWorkflowNode,
apiUpdateRecord,
apiGetRecord,
apiGetList,
apiCreateRecordTriggerFormEvent,
apiSubmitRecordTriggerFormEvent,
};