test: workflow e2e (#3261)
* test: workflow e2e * test: workflow e2e * fix: merge main, fix incompatibility * test: remove unneeded test cases * fix: process.env.PLAYWRIGHT_AUTH_FILE * fix: workflow e2e * test: increase e2e timeout-minutes to 180 * fix: error * fix: workflow aggregate e2e test * fix: cancel useTransaction * fix: updateRecord * fix: queryRecord * fix: queryRecord * fix: queryRecord * fix: formEvent * fix: format files * fix: test * fix: error * fix: error * fix: split files * fix: ci * fix: error * fix: error * fix: client end * fix: test * fix: test * feat: concurrency=10 * fix: concurrency=3 * test: increase timeout * test: p-test --------- Co-authored-by: chenos <chenlinxh@gmail.com> Co-authored-by: Zeke Zhang <958414905@qq.com>
This commit is contained in:
parent
0c60780b50
commit
e7c2c9ff83
@ -27,4 +27,6 @@ packages/core/cli/templates/plugin/src/client/*.tpl
|
||||
packages/app/client/src/.plugins
|
||||
docker
|
||||
storage
|
||||
benchmark
|
||||
benchmark
|
||||
packages/core/cli/src
|
||||
t.js
|
6
.github/workflows/nocobase-test-e2e.yml
vendored
6
.github/workflows/nocobase-test-e2e.yml
vendored
@ -63,11 +63,9 @@ jobs:
|
||||
__E2E__: true
|
||||
- run: npx playwright install chromium --with-deps
|
||||
- name: Test with postgres
|
||||
run: yarn e2e test -x --skip-reporter
|
||||
run: yarn e2e p-test --stop-on-error
|
||||
env:
|
||||
__E2E__: true
|
||||
APP_BASE_URL: http://127.0.0.1:13000
|
||||
APP_PORT: 13000
|
||||
APP_ENV: production
|
||||
LOGGER_LEVEL: error
|
||||
DB_DIALECT: postgres
|
||||
@ -76,4 +74,4 @@ jobs:
|
||||
DB_USER: nocobase
|
||||
DB_PASSWORD: password
|
||||
DB_DATABASE: nocobase
|
||||
timeout-minutes: 90
|
||||
timeout-minutes: 180
|
||||
|
@ -19,6 +19,7 @@
|
||||
"fs-extra": "^11.1.1",
|
||||
"pm2": "^5.2.0",
|
||||
"portfinder": "^1.0.28",
|
||||
"p-all": "3.0.0",
|
||||
"serve": "^13.0.2",
|
||||
"tsx": "^4.6.2"
|
||||
},
|
||||
|
@ -2,6 +2,7 @@ const { Command } = require('commander');
|
||||
const { run, isPortReachable } = require('../util');
|
||||
const { execSync } = require('node:child_process');
|
||||
const axios = require('axios');
|
||||
const { pTest } = require('./p-test');
|
||||
|
||||
/**
|
||||
* 检查服务是否启动成功
|
||||
@ -200,4 +201,12 @@ module.exports = (cli) => {
|
||||
e2e.command('install-deps').action(async () => {
|
||||
await run('npx', ['playwright', 'install', '--with-deps']);
|
||||
});
|
||||
|
||||
e2e
|
||||
.command('p-test')
|
||||
.option('--stop-on-error')
|
||||
.option('--concurrency [concurrency]', '', 3)
|
||||
.action(async (opts) => {
|
||||
await pTest(opts);
|
||||
});
|
||||
};
|
||||
|
68
packages/core/cli/src/commands/p-test.js
Normal file
68
packages/core/cli/src/commands/p-test.js
Normal file
@ -0,0 +1,68 @@
|
||||
const execa = require('execa');
|
||||
const { resolve, dirname } = require('path');
|
||||
const pAll = require('p-all');
|
||||
const dotenv = require('dotenv');
|
||||
const fs = require('fs');
|
||||
const { Client } = require('pg');
|
||||
const glob = require('glob');
|
||||
|
||||
let ENV_FILE = resolve(process.cwd(), '.env.e2e');
|
||||
|
||||
if (!fs.existsSync(ENV_FILE)) {
|
||||
ENV_FILE = resolve(process.cwd(), '.env.e2e.example');
|
||||
}
|
||||
|
||||
const data = fs.readFileSync(ENV_FILE, 'utf-8');
|
||||
const config = {
|
||||
...dotenv.parse(data),
|
||||
...process.env,
|
||||
};
|
||||
|
||||
async function runApp(index = 1, dir) {
|
||||
const database = `nocobase${index}`;
|
||||
const client = new Client({
|
||||
host: config['DB_HOST'],
|
||||
port: Number(config['DB_PORT']),
|
||||
user: config['DB_USER'],
|
||||
password: config['DB_PASSWORD'],
|
||||
database: 'postgres',
|
||||
});
|
||||
await client.connect();
|
||||
await client.query(`DROP DATABASE IF EXISTS "${database}"`);
|
||||
await client.query(`CREATE DATABASE "${database}";`);
|
||||
await client.end();
|
||||
return execa('yarn', ['nocobase', 'e2e', 'test', dir, '-x', '--skip-reporter'], {
|
||||
shell: true,
|
||||
stdio: 'inherit',
|
||||
env: {
|
||||
...config,
|
||||
CI: true,
|
||||
__E2E__: true,
|
||||
APP_BASE_URL: undefined,
|
||||
LOGGER_LEVEL: 'error',
|
||||
APP_ENV: 'production',
|
||||
APP_PORT: 20000 + index,
|
||||
DB_DATABASE: `nocobase${index}`,
|
||||
SOCKET_PATH: `storage/gateway-e2e-${index}.sock`,
|
||||
PM2_HOME: resolve(process.cwd(), `storage/.pm2-${index}`),
|
||||
PLAYWRIGHT_AUTH_FILE: resolve(process.cwd(), `storage/playwright/.auth/admin-${index}.json`),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
exports.pTest = async (options) => {
|
||||
const files = glob.sync('packages/**/__e2e__/**/*.test.ts', {
|
||||
root: process.cwd(),
|
||||
});
|
||||
const fileSet = new Set();
|
||||
|
||||
for (const file of files) {
|
||||
fileSet.add(dirname(file));
|
||||
}
|
||||
|
||||
const commands = [...fileSet.values()].map((v, i) => {
|
||||
return () => runApp(i + 1, v);
|
||||
});
|
||||
|
||||
await pAll(commands, { concurrency: 3, stopOnError: false, ...options });
|
||||
};
|
@ -217,6 +217,9 @@ exports.genTsConfigPaths = function genTsConfigPaths() {
|
||||
paths[`${packageJsonName}/server`] = [`${relativePath}/src/server`];
|
||||
paths[`${packageJsonName}/e2e`] = [`${relativePath}/src/e2e`];
|
||||
}
|
||||
if (packageJsonName === '@nocobase/plugin-workflow-test') {
|
||||
paths[`${packageJsonName}/e2e`] = [`${relativePath}/src/e2e`];
|
||||
}
|
||||
});
|
||||
|
||||
const tsConfigJsonPath = join(cwd, './tsconfig.paths.json');
|
||||
@ -272,7 +275,7 @@ exports.initEnv = function initEnv() {
|
||||
}
|
||||
}
|
||||
|
||||
if (process.argv[2] === 'e2e') {
|
||||
if (!process.env.APP_ENV_PATH && process.argv[2] === 'e2e') {
|
||||
// 用于存放 playwright 自动生成的相关的文件
|
||||
generatePlaywrightPath();
|
||||
if (!fs.existsSync('.env.e2e') && fs.existsSync('.env.e2e.example')) {
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { expect, oneFormBlockBasedOnUsers, test } from '@nocobase/test/e2e';
|
||||
|
||||
test('fields', async ({ page, mockPage }) => {
|
||||
// 在 CI 中多进程跑的时候,可能需要等待更长的时间
|
||||
test.slow();
|
||||
await mockPage(oneFormBlockBasedOnUsers).goto();
|
||||
await page.getByLabel('schema-initializer-Grid-FormItemInitializers-users').click();
|
||||
await page.getByRole('menuitem', { name: 'Nickname' }).click();
|
||||
|
@ -117,7 +117,7 @@ test.describe('table block schema settings', () => {
|
||||
.dragTo(page.getByLabel('table-index-1').getByRole('img', { name: 'menu' }));
|
||||
|
||||
// 等待表格刷新
|
||||
await page.waitForTimeout(1000);
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
email1 = await page.getByText(records[0].email).boundingBox();
|
||||
email2 = await page.getByText(records[1].email).boundingBox();
|
||||
|
@ -253,7 +253,7 @@ export class NocoPage {
|
||||
const _test = base.extend<ExtendUtils>({
|
||||
mockPage: async ({ page }, use) => {
|
||||
// 保证每个测试运行时 faker 的随机值都是一样的
|
||||
faker.seed(1);
|
||||
// faker.seed(1);
|
||||
|
||||
const nocoPages: NocoPage[] = [];
|
||||
const mockPage = (config?: PageConfig) => {
|
||||
@ -284,27 +284,27 @@ const _test = base.extend<ExtendUtils>({
|
||||
collectionSettings = omitSomeFields(
|
||||
Array.isArray(collectionSettings) ? collectionSettings : [collectionSettings],
|
||||
);
|
||||
collectionsName = collectionSettings.map((item) => item.name);
|
||||
collectionsName = [...collectionsName, ...collectionSettings.map((item) => item.name)];
|
||||
await createCollections(collectionSettings);
|
||||
};
|
||||
|
||||
await use(_createCollections);
|
||||
|
||||
if (collectionsName.length) {
|
||||
await deleteCollections(collectionsName);
|
||||
await deleteCollections(_.uniq(collectionsName));
|
||||
}
|
||||
},
|
||||
mockCollections: async ({ page }, use) => {
|
||||
let collectionsName = [];
|
||||
const destroy = async () => {
|
||||
if (collectionsName.length) {
|
||||
await deleteCollections(collectionsName);
|
||||
await deleteCollections(_.uniq(collectionsName));
|
||||
}
|
||||
};
|
||||
|
||||
const mockCollections = async (collectionSettings: CollectionSetting[]) => {
|
||||
collectionSettings = omitSomeFields(collectionSettings);
|
||||
collectionsName = collectionSettings.map((item) => item.name);
|
||||
collectionsName = [...collectionsName, ...collectionSettings.map((item) => item.name)];
|
||||
return createCollections(collectionSettings);
|
||||
};
|
||||
|
||||
@ -315,13 +315,13 @@ const _test = base.extend<ExtendUtils>({
|
||||
let collectionsName = [];
|
||||
const destroy = async () => {
|
||||
if (collectionsName.length) {
|
||||
await deleteCollections(collectionsName);
|
||||
await deleteCollections(_.uniq(collectionsName));
|
||||
}
|
||||
};
|
||||
|
||||
const mockCollection = async (collectionSetting: CollectionSetting, options?: { manualDestroy: boolean }) => {
|
||||
const collectionSettings = omitSomeFields([collectionSetting]);
|
||||
collectionsName = collectionSettings.map((item) => item.name);
|
||||
collectionsName = [...collectionsName, ...collectionSettings.map((item) => item.name)];
|
||||
return createCollections(collectionSettings);
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,519 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import {
|
||||
AggregateNode,
|
||||
CollectionTriggerNode,
|
||||
apiCreateWorkflow,
|
||||
apiDeleteWorkflow,
|
||||
apiGetWorkflow,
|
||||
apiGetWorkflowNodeExecutions,
|
||||
apiUpdateWorkflowTrigger,
|
||||
appendJsonCollectionName,
|
||||
generalWithNoRelationalFields,
|
||||
} from '@nocobase/plugin-workflow-test/e2e';
|
||||
import { expect, test } from '@nocobase/test/e2e';
|
||||
import { dayjs } from '@nocobase/utils';
|
||||
|
||||
test('Collection event add data trigger, aggregated data table, no filtering, normal table integer fields not de-emphasised COUNT', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = 'a' + faker.string.alphanumeric(4);
|
||||
const aggregateNodeAppendText = 'b' + faker.string.alphanumeric(4);
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
// 创建聚合节点数据表
|
||||
const aggregateNodeCollectionDisplayName = `自动>组织[普通表]${aggregateNodeAppendText}`;
|
||||
const aggregateNodeCollectionName = `tt_amt_org${aggregateNodeAppendText}`;
|
||||
const aggregateNodeFieldName = 'staffnum';
|
||||
const aggregateNodeFieldDisplayName = '员工人数(整数)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), aggregateNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
const aggregateNodeCollectionData = [
|
||||
{ staffnum: 3, regcapital: 3.12 },
|
||||
{ staffnum: 3, regcapital: 3.6 },
|
||||
{ staffnum: 4, regcapital: 4.6 },
|
||||
{ staffnum: 4, regcapital: 4.6 },
|
||||
{ staffnum: 5, regcapital: 5.6 },
|
||||
];
|
||||
const aggregateNodeCollectionRecords = await mockRecords(aggregateNodeCollectionName, aggregateNodeCollectionData);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置聚合数据节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'aggregate', exact: true }).click();
|
||||
const aggregateRecordNodeName = 'Aggregate' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Aggregate-Aggregate', { exact: true }).getByRole('textbox').fill(aggregateRecordNodeName);
|
||||
const aggregateRecordNode = new AggregateNode(page, aggregateRecordNodeName);
|
||||
const aggregateRecordNodeId = await aggregateRecordNode.node.locator('.workflow-node-id').innerText();
|
||||
await aggregateRecordNode.nodeConfigure.click();
|
||||
await aggregateRecordNode.collectionDropDown.click();
|
||||
await page.getByText(aggregateNodeCollectionDisplayName).click();
|
||||
await aggregateRecordNode.aggregatedFieldDropDown.click();
|
||||
await page.getByRole('option', { name: aggregateNodeFieldDisplayName }).click();
|
||||
await aggregateRecordNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,数据查询成功
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const queryRecordNodeJob = jobs.find((job) => job.nodeId.toString() === aggregateRecordNodeId);
|
||||
const queryRecordNodeJobResult = queryRecordNodeJob.result;
|
||||
expect(queryRecordNodeJobResult).toBe(aggregateNodeCollectionData.length);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, aggregated data table, no filtering, normal table integer fields not de-emphasised SUM', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = 'a' + faker.string.alphanumeric(4);
|
||||
const aggregateNodeAppendText = 'b' + faker.string.alphanumeric(4);
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
// 创建聚合节点数据表
|
||||
const aggregateNodeCollectionDisplayName = `自动>组织[普通表]${aggregateNodeAppendText}`;
|
||||
const aggregateNodeCollectionName = `tt_amt_org${aggregateNodeAppendText}`;
|
||||
const aggregateNodeFieldName = 'staffnum';
|
||||
const aggregateNodeFieldDisplayName = '员工人数(整数)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), aggregateNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
const aggregateNodeCollectionData = [
|
||||
{ staffnum: 3, regcapital: 3.12 },
|
||||
{ staffnum: 3, regcapital: 3.6 },
|
||||
{ staffnum: 4, regcapital: 4.6 },
|
||||
{ staffnum: 4, regcapital: 4.6 },
|
||||
{ staffnum: 5, regcapital: 5.6 },
|
||||
];
|
||||
const aggregateNodeCollectionRecords = await mockRecords(aggregateNodeCollectionName, aggregateNodeCollectionData);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置聚合数据节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'aggregate', exact: true }).click();
|
||||
const aggregateRecordNodeName = 'Aggregate' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Aggregate-Aggregate', { exact: true }).getByRole('textbox').fill(aggregateRecordNodeName);
|
||||
const aggregateRecordNode = new AggregateNode(page, aggregateRecordNodeName);
|
||||
const aggregateRecordNodeId = await aggregateRecordNode.node.locator('.workflow-node-id').innerText();
|
||||
await aggregateRecordNode.nodeConfigure.click();
|
||||
await aggregateRecordNode.sumRadio.click();
|
||||
await aggregateRecordNode.collectionDropDown.click();
|
||||
await page.getByText(aggregateNodeCollectionDisplayName).click();
|
||||
await aggregateRecordNode.aggregatedFieldDropDown.click();
|
||||
await page.getByRole('option', { name: aggregateNodeFieldDisplayName }).click();
|
||||
await aggregateRecordNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,数据查询成功
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const queryRecordNodeJob = jobs.find((job) => job.nodeId.toString() === aggregateRecordNodeId);
|
||||
const queryRecordNodeJobResult = queryRecordNodeJob.result;
|
||||
// aggregateNodeCollectionData中staffnum字段值总和
|
||||
const aggregateNodeCollectionDataSum = aggregateNodeCollectionData.reduce((total, currentValue) => {
|
||||
return total + currentValue.staffnum;
|
||||
}, 0);
|
||||
expect(queryRecordNodeJobResult).toBe(aggregateNodeCollectionDataSum);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, aggregated data table, no filtering, normal table integer fields not de-emphasised AVG', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = 'a' + faker.string.alphanumeric(4);
|
||||
const aggregateNodeAppendText = 'b' + faker.string.alphanumeric(4);
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
// 创建聚合节点数据表
|
||||
const aggregateNodeCollectionDisplayName = `自动>组织[普通表]${aggregateNodeAppendText}`;
|
||||
const aggregateNodeCollectionName = `tt_amt_org${aggregateNodeAppendText}`;
|
||||
const aggregateNodeFieldName = 'staffnum';
|
||||
const aggregateNodeFieldDisplayName = '员工人数(整数)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), aggregateNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
const aggregateNodeCollectionData = [
|
||||
{ staffnum: 3, regcapital: 3.12 },
|
||||
{ staffnum: 3, regcapital: 3.6 },
|
||||
{ staffnum: 4, regcapital: 4.6 },
|
||||
{ staffnum: 4, regcapital: 4.6 },
|
||||
{ staffnum: 5, regcapital: 5.6 },
|
||||
];
|
||||
const aggregateNodeCollectionRecords = await mockRecords(aggregateNodeCollectionName, aggregateNodeCollectionData);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
//配置聚合数据节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'aggregate', exact: true }).click();
|
||||
const aggregateRecordNodeName = 'Aggregate' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Aggregate-Aggregate', { exact: true }).getByRole('textbox').fill(aggregateRecordNodeName);
|
||||
const aggregateRecordNode = new AggregateNode(page, aggregateRecordNodeName);
|
||||
const aggregateRecordNodeId = await aggregateRecordNode.node.locator('.workflow-node-id').innerText();
|
||||
await aggregateRecordNode.nodeConfigure.click();
|
||||
await aggregateRecordNode.avgRadio.click();
|
||||
await aggregateRecordNode.collectionDropDown.click();
|
||||
await page.getByText(aggregateNodeCollectionDisplayName).click();
|
||||
await aggregateRecordNode.aggregatedFieldDropDown.click();
|
||||
await page.getByRole('option', { name: aggregateNodeFieldDisplayName }).click();
|
||||
await aggregateRecordNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,数据查询成功
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const queryRecordNodeJob = jobs.find((job) => job.nodeId.toString() === aggregateRecordNodeId);
|
||||
const queryRecordNodeJobResult = queryRecordNodeJob.result;
|
||||
// aggregateNodeCollectionData中staffnum字段值平均值
|
||||
const aggregateNodeCollectionDataAvg =
|
||||
aggregateNodeCollectionData.reduce((total, currentValue) => {
|
||||
return total + currentValue.staffnum;
|
||||
}, 0) / aggregateNodeCollectionData.length;
|
||||
expect(queryRecordNodeJobResult).toBe(aggregateNodeCollectionDataAvg);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, aggregated data table, no filtering, normal table integer fields not de-emphasised MIN', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = 'a' + faker.string.alphanumeric(4);
|
||||
const aggregateNodeAppendText = 'b' + faker.string.alphanumeric(4);
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
// 创建聚合节点数据表
|
||||
const aggregateNodeCollectionDisplayName = `自动>组织[普通表]${aggregateNodeAppendText}`;
|
||||
const aggregateNodeCollectionName = `tt_amt_org${aggregateNodeAppendText}`;
|
||||
const aggregateNodeFieldName = 'staffnum';
|
||||
const aggregateNodeFieldDisplayName = '员工人数(整数)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), aggregateNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
const aggregateNodeCollectionData = [
|
||||
{ staffnum: 3, regcapital: 3.12 },
|
||||
{ staffnum: 3, regcapital: 3.6 },
|
||||
{ staffnum: 4, regcapital: 4.6 },
|
||||
{ staffnum: 4, regcapital: 4.6 },
|
||||
{ staffnum: 5, regcapital: 5.6 },
|
||||
];
|
||||
const aggregateNodeCollectionRecords = await mockRecords(aggregateNodeCollectionName, aggregateNodeCollectionData);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置聚合数据节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'aggregate', exact: true }).click();
|
||||
const aggregateRecordNodeName = 'Aggregate' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Aggregate-Aggregate', { exact: true }).getByRole('textbox').fill(aggregateRecordNodeName);
|
||||
const aggregateRecordNode = new AggregateNode(page, aggregateRecordNodeName);
|
||||
const aggregateRecordNodeId = await aggregateRecordNode.node.locator('.workflow-node-id').innerText();
|
||||
await aggregateRecordNode.nodeConfigure.click();
|
||||
await aggregateRecordNode.minRadio.click();
|
||||
await aggregateRecordNode.collectionDropDown.click();
|
||||
await page.getByText(aggregateNodeCollectionDisplayName).click();
|
||||
await aggregateRecordNode.aggregatedFieldDropDown.click();
|
||||
await page.getByRole('option', { name: aggregateNodeFieldDisplayName }).click();
|
||||
await aggregateRecordNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,数据查询成功
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const queryRecordNodeJob = jobs.find((job) => job.nodeId.toString() === aggregateRecordNodeId);
|
||||
const queryRecordNodeJobResult = queryRecordNodeJob.result;
|
||||
// aggregateNodeCollectionData中staffnum字段值最小值
|
||||
const aggregateNodeCollectionDataMin = aggregateNodeCollectionData.reduce((min, currentValue) => {
|
||||
return currentValue.staffnum < min ? currentValue.staffnum : min;
|
||||
}, aggregateNodeCollectionData[0].staffnum);
|
||||
expect(queryRecordNodeJobResult).toBe(aggregateNodeCollectionDataMin);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, aggregated data table, no filtering, normal table integer fields not de-emphasised MAX', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = 'a' + faker.string.alphanumeric(4);
|
||||
const aggregateNodeAppendText = 'b' + faker.string.alphanumeric(4);
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
// 创建聚合节点数据表
|
||||
const aggregateNodeCollectionDisplayName = `自动>组织[普通表]${aggregateNodeAppendText}`;
|
||||
const aggregateNodeCollectionName = `tt_amt_org${aggregateNodeAppendText}`;
|
||||
const aggregateNodeFieldName = 'staffnum';
|
||||
const aggregateNodeFieldDisplayName = '员工人数(整数)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), aggregateNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
const aggregateNodeCollectionData = [
|
||||
{ staffnum: 3, regcapital: 3.12 },
|
||||
{ staffnum: 3, regcapital: 3.6 },
|
||||
{ staffnum: 4, regcapital: 4.6 },
|
||||
{ staffnum: 4, regcapital: 4.6 },
|
||||
{ staffnum: 5, regcapital: 5.6 },
|
||||
];
|
||||
const aggregateNodeCollectionRecords = await mockRecords(aggregateNodeCollectionName, aggregateNodeCollectionData);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置聚合数据节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'aggregate', exact: true }).click();
|
||||
const aggregateRecordNodeName = 'Aggregate' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Aggregate-Aggregate', { exact: true }).getByRole('textbox').fill(aggregateRecordNodeName);
|
||||
const aggregateRecordNode = new AggregateNode(page, aggregateRecordNodeName);
|
||||
const aggregateRecordNodeId = await aggregateRecordNode.node.locator('.workflow-node-id').innerText();
|
||||
await aggregateRecordNode.nodeConfigure.click();
|
||||
await aggregateRecordNode.maxRadio.click();
|
||||
await aggregateRecordNode.collectionDropDown.click();
|
||||
await page.getByText(aggregateNodeCollectionDisplayName).click();
|
||||
await aggregateRecordNode.aggregatedFieldDropDown.click();
|
||||
await page.getByRole('option', { name: aggregateNodeFieldDisplayName }).click();
|
||||
await aggregateRecordNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,数据查询成功
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const queryRecordNodeJob = jobs.find((job) => job.nodeId.toString() === aggregateRecordNodeId);
|
||||
const queryRecordNodeJobResult = queryRecordNodeJob.result;
|
||||
// aggregateNodeCollectionData中staffnum字段值最大值
|
||||
const aggregateNodeCollectionDataMax = aggregateNodeCollectionData.reduce((max, currentValue) => {
|
||||
return currentValue.staffnum > max ? currentValue.staffnum : max;
|
||||
}, aggregateNodeCollectionData[0].staffnum);
|
||||
expect(queryRecordNodeJobResult).toBe(aggregateNodeCollectionDataMax);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
@ -0,0 +1,659 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import {
|
||||
CreateWorkFlow,
|
||||
EditWorkFlow,
|
||||
FormEventTriggerNode,
|
||||
WorkflowListRecords,
|
||||
apiCreateRecordTriggerFormEvent,
|
||||
apiCreateWorkflow,
|
||||
apiDeleteWorkflow,
|
||||
apiGetWorkflow,
|
||||
apiUpdateWorkflowTrigger,
|
||||
appendJsonCollectionName,
|
||||
generalWithNoRelationalFields,
|
||||
} from '@nocobase/plugin-workflow-test/e2e';
|
||||
import { expect, test } from '@nocobase/test/e2e';
|
||||
import { dayjs } from '@nocobase/utils';
|
||||
|
||||
test.describe('Configuration page to configure the Trigger node', () => {
|
||||
test('Form Submit Button Binding Workflow Add Data Trigger', async ({
|
||||
page,
|
||||
mockPage,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'form',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
//配置工作流触发器
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const formEventTriggerNode = new FormEventTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await formEventTriggerNode.nodeConfigure.click();
|
||||
await formEventTriggerNode.collectionDropDown.click();
|
||||
await page.getByRole('option', { name: triggerNodeCollectionDisplayName }).click();
|
||||
await formEventTriggerNode.submitButton.click();
|
||||
|
||||
//配置录入数据区块
|
||||
const newPage = mockPage();
|
||||
await newPage.goto();
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel('schema-initializer-Grid-BlockInitializers').hover();
|
||||
await page.getByRole('menuitem', { name: 'table Table' }).hover();
|
||||
await page.getByRole('menuitem', { name: `${triggerNodeCollectionDisplayName}` }).click();
|
||||
|
||||
// 移开鼠标,关闭菜单
|
||||
await page.mouse.move(300, 0);
|
||||
|
||||
await page.getByText('Configure columns').hover();
|
||||
await page.getByText(triggerNodeFieldDisplayName).click();
|
||||
await page.getByText('Configure actions').hover();
|
||||
await page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch').click();
|
||||
await expect(page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch')).toBeEnabled();
|
||||
await page.getByLabel(`action-Action-Add new-create-${triggerNodeCollectionName}-table`).click();
|
||||
await page.getByLabel(`schema-initializer-Grid-CreateFormBlockInitializers-${triggerNodeCollectionName}`).hover();
|
||||
await page.getByRole('menuitem', { name: 'form Form' }).click();
|
||||
// 移开鼠标,关闭菜单
|
||||
await page.mouse.move(300, 0);
|
||||
await page
|
||||
.getByLabel(`schema-initializer-ActionBar-CreateFormActionInitializers-${triggerNodeCollectionName}`)
|
||||
.hover();
|
||||
await page.getByRole('menuitem', { name: 'Submit' }).click();
|
||||
// 绑定工作流
|
||||
await page.getByLabel(`schema-initializer-Grid-FormItemInitializers-${triggerNodeCollectionName}`).hover();
|
||||
await page.getByRole('menuitem', { name: `${triggerNodeFieldDisplayName}` }).click();
|
||||
await page.mouse.move(300, 0);
|
||||
await page.getByLabel(`action-Action-Submit-submit-${triggerNodeCollectionName}-form`).hover();
|
||||
await page
|
||||
.getByRole('button', { name: `designer-schema-settings-Action-Action.Designer-${triggerNodeCollectionName}` })
|
||||
.hover();
|
||||
await page.getByRole('menuitem', { name: 'Bind workflows' }).click();
|
||||
await page.getByRole('button', { name: 'plus Add workflow' }).click();
|
||||
await page.getByRole('button', { name: 'Select workflow' }).click();
|
||||
await page.getByRole('option', { name: workFlowName }).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
|
||||
// 2、测试步骤:进入“数据区块”-“添加”按钮,填写表单,点击“确定”按钮
|
||||
const fieldData = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByRole('textbox').fill(fieldData);
|
||||
await page.getByLabel(`action-Action-Submit-submit-${triggerNodeCollectionName}-form`, { exact: true }).click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:触发次数为1
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Form Submit to Workflow Button Add Data Trigger', async ({ page, mockPage, mockCollections, mockRecords }) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'form',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
//配置工作流触发器
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const formEventTriggerNode = new FormEventTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await formEventTriggerNode.nodeConfigure.click();
|
||||
await formEventTriggerNode.collectionDropDown.click();
|
||||
await page.getByRole('option', { name: triggerNodeCollectionDisplayName }).click();
|
||||
await formEventTriggerNode.submitButton.click();
|
||||
|
||||
//配置录入数据区块
|
||||
const newPage = mockPage();
|
||||
await newPage.goto();
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel('schema-initializer-Grid-BlockInitializers').hover();
|
||||
await page.getByRole('menuitem', { name: 'table Table' }).hover();
|
||||
await page.getByRole('menuitem', { name: `${triggerNodeCollectionDisplayName}` }).click();
|
||||
|
||||
// 移开鼠标,关闭菜单
|
||||
await page.mouse.move(300, 0);
|
||||
|
||||
await page.getByText('Configure columns').hover();
|
||||
await page.getByText(triggerNodeFieldDisplayName).click();
|
||||
await page.getByText('Configure actions').hover();
|
||||
await page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch').click();
|
||||
await expect(page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch')).toBeEnabled();
|
||||
|
||||
await page.getByLabel(`action-Action-Add new-create-${triggerNodeCollectionName}-table`).click();
|
||||
await page.getByLabel(`schema-initializer-Grid-CreateFormBlockInitializers-${triggerNodeCollectionName}`).hover();
|
||||
await page.getByRole('menuitem', { name: 'form Form' }).click();
|
||||
|
||||
// 移开鼠标,关闭菜单
|
||||
await page.mouse.move(300, 0);
|
||||
|
||||
// 绑定工作流
|
||||
await page
|
||||
.getByLabel(`schema-initializer-ActionBar-CreateFormActionInitializers-${triggerNodeCollectionName}`)
|
||||
.hover();
|
||||
await page.getByRole('menuitem', { name: 'Customize' }).hover();
|
||||
await page.getByRole('menuitem', { name: 'Submit to workflow' }).click();
|
||||
await page.getByLabel(`schema-initializer-Grid-FormItemInitializers-${triggerNodeCollectionName}`).hover();
|
||||
await page.getByRole('menuitem', { name: `${triggerNodeFieldDisplayName}` }).click();
|
||||
await page.mouse.move(300, 0);
|
||||
await page.getByRole('button', { name: 'Submit to workflow' }).hover();
|
||||
await page
|
||||
.getByRole('button', { name: `designer-schema-settings-Action-Action.Designer-${triggerNodeCollectionName}` })
|
||||
.hover();
|
||||
await page.getByRole('menuitem', { name: 'Bind workflows' }).click();
|
||||
await page.getByRole('button', { name: 'plus Add workflow' }).click();
|
||||
await page.getByRole('button', { name: 'Select workflow' }).click();
|
||||
await page.getByRole('option', { name: workFlowName }).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
|
||||
// 2、测试步骤:进入“数据区块”-“添加”按钮,填写表单,点击“确定”按钮
|
||||
const fieldData = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByRole('textbox').fill(fieldData);
|
||||
await page
|
||||
.getByLabel(`action-Action-Submit to workflow-customize:triggerWorkflows-${triggerNodeCollectionName}-form`)
|
||||
.click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:触发次数为1
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Configuration Page Path Jump Workflow Management Page', () => {
|
||||
test('Form event Workflow Configuration Page Path Jump Workflow Management Page', async ({
|
||||
page,
|
||||
mockPage,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
// const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
// const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
// const triggerNodeFieldName = 'orgname';
|
||||
// const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
// await mockCollections(appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText).collections);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'form',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
//配置工作流触发器
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// 2、测试步骤:跳转到工作流管理页面
|
||||
await page.getByRole('link', { name: 'Workflow' }).click();
|
||||
|
||||
// 3、预期结果:跳转路径正确
|
||||
await page.waitForLoadState('networkidle');
|
||||
expect(page.url()).toBe(`${process.env.APP_BASE_URL}/admin/settings/workflow`);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Form event Workflow History Version Configuration Page Path Jump Workflow Management Page', async ({
|
||||
page,
|
||||
mockPage,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'form',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
const WorkflowKey = workflowObj.key;
|
||||
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = { config: { collection: triggerNodeCollectionName, appends: [] } };
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne =
|
||||
triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const triggerWorkflows = WorkflowKey;
|
||||
const triggerNodeCollectionRecords = await apiCreateRecordTriggerFormEvent(
|
||||
triggerNodeCollectionName,
|
||||
triggerWorkflows,
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel('more').click();
|
||||
await page.getByLabel('revision').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
//元素重复
|
||||
await page.getByLabel('version', { exact: true }).click();
|
||||
await page.getByLabel('version-1').click();
|
||||
await page.getByRole('link', { name: 'Workflow' }).click();
|
||||
|
||||
// 3、预期结果:跳转路径正确
|
||||
await page.waitForLoadState('networkidle');
|
||||
expect(page.url()).toBe(`${process.env.APP_BASE_URL}/admin/settings/workflow`);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Form event Workflow Execution Log Page Path Jump Workflow Management Page', async ({
|
||||
page,
|
||||
mockPage,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'form',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
const WorkflowKey = workflowObj.key;
|
||||
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = { config: { collection: triggerNodeCollectionName, appends: [] } };
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne =
|
||||
triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const triggerWorkflows = WorkflowKey;
|
||||
const triggerNodeCollectionRecords = await apiCreateRecordTriggerFormEvent(
|
||||
triggerNodeCollectionName,
|
||||
triggerWorkflows,
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
const workflowListRecords = new WorkflowListRecords(page, workFlowName);
|
||||
await workflowListRecords.executionCountPopup.click();
|
||||
await page.getByText('View').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByRole('link', { name: 'Workflow', exact: true }).click();
|
||||
|
||||
// 3、预期结果:跳转路径正确
|
||||
await page.waitForLoadState('networkidle');
|
||||
expect(page.url()).toBe(`${process.env.APP_BASE_URL}/admin/settings/workflow`);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test.skip('Form event Workflow Execution Log Page Path Jump Execution Log Screen', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'form',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
const WorkflowKey = workflowObj.key;
|
||||
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = { config: { collection: triggerNodeCollectionName, appends: [] } };
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne =
|
||||
triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const triggerWorkflows = WorkflowKey;
|
||||
const triggerNodeCollectionRecords = await apiCreateRecordTriggerFormEvent(
|
||||
triggerNodeCollectionName,
|
||||
triggerWorkflows,
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
const workflowListRecords = new WorkflowListRecords(page, workFlowName);
|
||||
await workflowListRecords.executionCountPopup.click();
|
||||
await page.getByText('View').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
//跳转其他执行日志界面,元素无法定位
|
||||
|
||||
// 3、预期结果:跳转路径正确
|
||||
await page.waitForLoadState('networkidle');
|
||||
// expect(page.url()).toBe(`${process.env.APP_BASE_URL}/admin/settings/workflow`);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Configuration page version switching', () => {});
|
||||
|
||||
test.describe('Configuration page disable enable', () => {
|
||||
test('Form event Workflow Add Data Trigger Disable Do Not Trigger', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'form',
|
||||
enabled: false,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
const WorkflowKey = workflowObj.key;
|
||||
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = { config: { collection: triggerNodeCollectionName, appends: [] } };
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne =
|
||||
triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const triggerWorkflows = WorkflowKey;
|
||||
const triggerNodeCollectionRecords = await apiCreateRecordTriggerFormEvent(
|
||||
triggerNodeCollectionName,
|
||||
triggerWorkflows,
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:触发次数为1
|
||||
let getWorkflow = await apiGetWorkflow(workflowId);
|
||||
let getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
let getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(0);
|
||||
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByRole('switch', { name: 'On Off' }).click();
|
||||
|
||||
await apiCreateRecordTriggerFormEvent(triggerNodeCollectionName, triggerWorkflows, {
|
||||
orgname: triggerNodeCollectionRecordOne + '1',
|
||||
});
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
getWorkflow = await apiGetWorkflow(workflowId);
|
||||
getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Form event Workflow Add Data Trigger Disable Enable Post Trigger', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'form',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
const WorkflowKey = workflowObj.key;
|
||||
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = { config: { collection: triggerNodeCollectionName, appends: [] } };
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne =
|
||||
triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const triggerWorkflows = WorkflowKey;
|
||||
const triggerNodeCollectionRecords = await apiCreateRecordTriggerFormEvent(
|
||||
triggerNodeCollectionName,
|
||||
triggerWorkflows,
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:触发次数为1
|
||||
let getWorkflow = await apiGetWorkflow(workflowId);
|
||||
let getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
let getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByRole('switch', { name: 'On Off' }).click();
|
||||
|
||||
await apiCreateRecordTriggerFormEvent(triggerNodeCollectionName, triggerWorkflows, {
|
||||
orgname: triggerNodeCollectionRecordOne + '1',
|
||||
});
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
getWorkflow = await apiGetWorkflow(workflowId);
|
||||
getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Configuration page execution history', () => {});
|
||||
|
||||
test.describe('Configuration page copy to new version', () => {
|
||||
test('Copy the Form event of the Configuration Trigger node', async ({ page, mockCollections, mockRecords }) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'form',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
const WorkflowKey = workflowObj.key;
|
||||
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = { config: { collection: triggerNodeCollectionName, appends: [] } };
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne =
|
||||
triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const triggerWorkflows = WorkflowKey;
|
||||
const triggerNodeCollectionRecords = await apiCreateRecordTriggerFormEvent(
|
||||
triggerNodeCollectionName,
|
||||
triggerWorkflows,
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel('more').click();
|
||||
await page.getByLabel('revision').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// 3、预期结果:新版本工作流配置内容同旧版本一样
|
||||
const formEventTriggerNode = new FormEventTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await formEventTriggerNode.nodeConfigure.click();
|
||||
await expect(page.getByRole('button', { name: triggerNodeCollectionDisplayName })).toBeVisible();
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Configuration page delete version', () => {});
|
||||
|
||||
test.describe('Node Add Modify Delete', () => {});
|
@ -0,0 +1,175 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import {
|
||||
CreateWorkFlow,
|
||||
EditWorkFlow,
|
||||
FormEventTriggerNode,
|
||||
WorkflowListRecords,
|
||||
apiCreateRecordTriggerFormEvent,
|
||||
apiCreateWorkflow,
|
||||
apiDeleteWorkflow,
|
||||
apiGetWorkflow,
|
||||
apiUpdateWorkflowTrigger,
|
||||
appendJsonCollectionName,
|
||||
generalWithNoRelationalFields,
|
||||
} from '@nocobase/plugin-workflow-test/e2e';
|
||||
import { expect, test } from '@nocobase/test/e2e';
|
||||
import { dayjs } from '@nocobase/utils';
|
||||
|
||||
test.describe('Filter', () => {
|
||||
test('filter workflow name', async ({ page }) => {
|
||||
//添加工作流
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'form',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
// 2、筛选工作流
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel('action-Filter.Action-Filter-filter-workflows').click();
|
||||
await page.getByRole('textbox').fill(workFlowName);
|
||||
await page.getByRole('button', { name: 'Submit' }).click();
|
||||
|
||||
// 3、预期结果:列表中出现筛选的工作流
|
||||
await expect(page.getByText(workFlowName)).toBeAttached();
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Add new', () => {
|
||||
test('add new Form event', async ({ page }) => {
|
||||
// 添加工作流
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel('action-Action-Add new-workflows').click();
|
||||
const createWorkFlow = new CreateWorkFlow(page);
|
||||
const workFlowName = faker.string.alphanumeric(5);
|
||||
await createWorkFlow.name.fill(workFlowName);
|
||||
await createWorkFlow.triggerType.click();
|
||||
await page.getByRole('option', { name: 'Form event' }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
|
||||
// 3、预期结果:列表中出现新建的工作流
|
||||
await expect(page.getByText(workFlowName)).toBeVisible();
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await page.getByLabel('action-Filter.Action-Filter-filter-workflows').click();
|
||||
await page.getByRole('textbox').fill(workFlowName);
|
||||
await page.getByRole('button', { name: 'Submit' }).click();
|
||||
await page.getByLabel(`action-Action.Link-Delete-workflows-${workFlowName}`).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
await expect(page.getByText(workFlowName)).toBeHidden();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Sync', () => {});
|
||||
|
||||
test.describe('Delete', () => {
|
||||
test('delete Form event', async ({ page }) => {
|
||||
//添加工作流
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'form',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
// 删除工作流
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel('action-Filter.Action-Filter-filter-workflows').click();
|
||||
await page.getByRole('textbox').fill(workFlowName);
|
||||
await page.getByRole('button', { name: 'Submit' }).click();
|
||||
await page.getByLabel(`action-Action.Link-Delete-workflows-${workFlowName}`).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
|
||||
// 3、预期结果:列表中出现筛选的工作流
|
||||
await expect(page.getByText(workFlowName)).toBeHidden();
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Edit', () => {
|
||||
test('edit Form event name', async ({ page }) => {
|
||||
//添加工作流
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
let workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'form',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
// 编辑工作流
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel(`action-Action.Link-Edit-workflows-${workFlowName}`).click();
|
||||
const editWorkFlow = new EditWorkFlow(page, workFlowName);
|
||||
workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
await editWorkFlow.name.fill(workFlowName);
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
// 3、预期结果:编辑成功,列表中出现编辑后的工作流
|
||||
await expect(page.getByText(workFlowName)).toBeAttached();
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Duplicate', () => {
|
||||
test('Duplicate Form event triggers with only unconfigured trigger nodes', async ({ page }) => {
|
||||
//添加工作流
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'form',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
// 2、复制工作流
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel(`action-Action.Link-Duplicate-workflows-${workFlowName}`).click();
|
||||
await page.getByLabel(`action-Action-Submit-workflows-${workFlowName}`).click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
// 3、预期结果:列表中出现筛选的工作流
|
||||
await expect(page.getByText(`${workFlowName} copy`)).toBeAttached();
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await page.getByLabel(`action-Action.Link-Delete-workflows-${workFlowName} copy`).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
await expect(page.getByText(`${workFlowName} copy`)).toBeHidden();
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Executed', () => {});
|
2
packages/plugins/@nocobase/plugin-workflow-test/client.d.ts
vendored
Normal file
2
packages/plugins/@nocobase/plugin-workflow-test/client.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './dist/client';
|
||||
export { default } from './dist/client';
|
@ -0,0 +1 @@
|
||||
module.exports = require('./dist/client/index.js');
|
2
packages/plugins/@nocobase/plugin-workflow-test/e2e.d.ts
vendored
Normal file
2
packages/plugins/@nocobase/plugin-workflow-test/e2e.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './dist/e2e';
|
||||
export { default } from './dist/e2e';
|
1
packages/plugins/@nocobase/plugin-workflow-test/e2e.js
Normal file
1
packages/plugins/@nocobase/plugin-workflow-test/e2e.js
Normal file
@ -0,0 +1 @@
|
||||
module.exports = require('./dist/e2e/index.js');
|
@ -0,0 +1,3 @@
|
||||
import { Plugin } from '@nocobase/client';
|
||||
|
||||
export default class extends Plugin {}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,528 @@
|
||||
import { Locator, Page } from '@nocobase/test/e2e';
|
||||
export class CreateWorkFlow {
|
||||
readonly page: Page;
|
||||
name: Locator;
|
||||
triggerType: Locator;
|
||||
description: Locator;
|
||||
autoDeleteHistory: Locator;
|
||||
submitButton: Locator;
|
||||
cancelButton: Locator;
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.name = page.getByLabel('block-item-CollectionField-workflows-Name').getByRole('textbox');
|
||||
this.triggerType = page.getByTestId('select-single');
|
||||
this.description = page.getByTestId('description-item').getByRole('textbox');
|
||||
this.autoDeleteHistory = page.getByTestId('select-multiple');
|
||||
this.submitButton = page.getByLabel('action-Action-Submit-workflows');
|
||||
this.cancelButton = page.getByLabel('action-Action-Cancel-workflows');
|
||||
}
|
||||
}
|
||||
|
||||
export class EditWorkFlow {
|
||||
readonly page: Page;
|
||||
name: Locator;
|
||||
statusIsOn: Locator;
|
||||
statusIisOff: Locator;
|
||||
description: Locator;
|
||||
autoDeleteHistory: Locator;
|
||||
submitButton: Locator;
|
||||
cancelButton: Locator;
|
||||
constructor(page: Page, workFlowName: string) {
|
||||
this.page = page;
|
||||
this.name = page.getByLabel('block-item-CollectionField-workflows-Name').getByRole('textbox');
|
||||
this.statusIsOn = page.getByLabel('On', { exact: true });
|
||||
this.statusIisOff = page.getByLabel('Off');
|
||||
this.description = page.getByTestId('description-item').getByRole('textbox');
|
||||
this.autoDeleteHistory = page
|
||||
.getByTestId('deleteExecutionOnStatus-item')
|
||||
.getByTestId('antd-select')
|
||||
.locator('div')
|
||||
.nth(1);
|
||||
this.submitButton = page.getByLabel(`action-Action-Submit-workflows-${workFlowName}`);
|
||||
this.cancelButton = page.getByLabel(`action-Action-Cancel-workflows-${workFlowName}`);
|
||||
}
|
||||
}
|
||||
|
||||
export class WorkflowManagement {
|
||||
readonly page: Page;
|
||||
addNewButton: Locator;
|
||||
deleteButton: Locator;
|
||||
filterButton: Locator;
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.addNewButton = page.getByLabel('action-Action-Add new-workflows');
|
||||
this.deleteButton = page.getByLabel('action-Action-Delete-workflows');
|
||||
this.filterButton = page.getByLabel('action-Filter.Action-Filter-filter-workflows');
|
||||
}
|
||||
}
|
||||
|
||||
export class WorkflowListRecords {
|
||||
readonly page: Page;
|
||||
executionCountPopup: Locator;
|
||||
configureAction: Locator;
|
||||
editAction: Locator;
|
||||
duplicateAction: Locator;
|
||||
deleteAction: Locator;
|
||||
constructor(page: Page, workFlowName: string) {
|
||||
this.page = page;
|
||||
this.executionCountPopup = page.getByLabel(`executed-${workFlowName}`);
|
||||
this.configureAction = page.getByLabel(`action-WorkflowLink-Configure-workflows-${workFlowName}`);
|
||||
this.editAction = page.getByLabel(`action-Action.Link-Edit-workflows-${workFlowName}`);
|
||||
this.duplicateAction = page.getByLabel(`action-Action.Link-Duplicate-workflows-${workFlowName}`);
|
||||
this.deleteAction = page.getByLabel(`action-Action.Link-Delete-workflows-${workFlowName}`);
|
||||
}
|
||||
}
|
||||
|
||||
export class ApprovalTriggerNode {
|
||||
readonly page: Page;
|
||||
node: Locator;
|
||||
nodeTitle: Locator;
|
||||
nodeConfigure: Locator;
|
||||
collectionDropDown: Locator;
|
||||
checkWthdrawable: Locator;
|
||||
configureUserInterfaceButton: Locator;
|
||||
addBlockButton: Locator;
|
||||
addApplyFormMenu: Locator;
|
||||
configureFieldsButton: Locator;
|
||||
configureActionsButton: Locator;
|
||||
saveDraftSwitch: Locator;
|
||||
addNodeButton: Locator;
|
||||
constructor(page: Page, triggerName: string, collectionName: string) {
|
||||
this.page = page;
|
||||
this.node = page.getByText('TriggeraConfigure');
|
||||
this.nodeTitle = page.locator('textarea').filter({ hasText: triggerName });
|
||||
this.nodeConfigure = page.getByRole('button', { name: 'Configure' });
|
||||
this.collectionDropDown = page.getByRole('button', { name: 'Select collection' });
|
||||
this.checkWthdrawable = page.getByLabel('Withdrawable');
|
||||
this.configureUserInterfaceButton = page.getByRole('button', { name: 'Configure user interface' });
|
||||
this.addBlockButton = page.getByRole('button', { name: 'Add block' });
|
||||
this.addApplyFormMenu = page.getByRole('menuitem', { name: 'Apply form' });
|
||||
this.configureFieldsButton = page.getByTestId('configure-fields-button-of-form-item-' + collectionName);
|
||||
this.configureActionsButton = page.getByTestId(
|
||||
'approval-trigger-configure-form-actions-add-action-button-' + collectionName,
|
||||
);
|
||||
this.saveDraftSwitch = page.getByRole('menuitem', { name: 'Save draft' }).getByRole('switch');
|
||||
this.addNodeButton = page.getByLabel('add-button', { exact: true });
|
||||
}
|
||||
}
|
||||
|
||||
export class ApprovalNode {
|
||||
readonly page: Page;
|
||||
node: Locator;
|
||||
nodeTitle: Locator;
|
||||
nodeConfigure: Locator;
|
||||
assigneesDropDown: Locator;
|
||||
checkReturnable: Locator;
|
||||
configureUserInterfaceButton: Locator;
|
||||
addBlockButton: Locator;
|
||||
addApplyFormMenu: Locator;
|
||||
configureFieldsButton: Locator;
|
||||
configureActionsButton: Locator;
|
||||
saveDraftSwitch: Locator;
|
||||
addNodeButton: Locator;
|
||||
constructor(page: Page, nodeName: string, collectionName: string) {
|
||||
this.page = page;
|
||||
this.node = page.getByText('TriggeraConfigure');
|
||||
this.nodeTitle = page.locator('textarea').filter({ hasText: nodeName });
|
||||
this.nodeConfigure = page.getByRole('button', { name: 'Configure' });
|
||||
this.assigneesDropDown = page.getByLabel('Search');
|
||||
this.checkReturnable = page.getByLabel('Returnable');
|
||||
this.configureUserInterfaceButton = page.getByRole('button', { name: 'Configure user interface' });
|
||||
this.addBlockButton = page.getByTestId('add-block-button-in-workflow-workflows');
|
||||
this.addApplyFormMenu = page.getByRole('menuitem', { name: 'Apply form' });
|
||||
this.configureFieldsButton = page.getByTestId('configure-fields-button-of-form-item-' + collectionName);
|
||||
this.configureActionsButton = page.getByTestId(
|
||||
'approval-trigger-configure-form-actions-add-action-button-' + collectionName,
|
||||
);
|
||||
this.saveDraftSwitch = page.getByRole('menuitem', { name: 'Save draft' }).getByRole('switch');
|
||||
this.addNodeButton = page.getByLabel(`add-button-calculation-${nodeName}`, { exact: true });
|
||||
}
|
||||
}
|
||||
|
||||
export class ScheduleTriggerNode {
|
||||
readonly page: Page;
|
||||
node: Locator;
|
||||
nodeTitle: Locator;
|
||||
nodeConfigure: Locator;
|
||||
customTimeTriggerOptions: Locator;
|
||||
startTimeEntryBox: Locator;
|
||||
RrpeatModeDropdown: Locator;
|
||||
|
||||
dataTableTimeFieldOptions: Locator;
|
||||
collectionDropDown: Locator;
|
||||
startTimeDropdown: Locator;
|
||||
submitButton: Locator;
|
||||
cancelButton: Locator;
|
||||
addNodeButton: Locator;
|
||||
constructor(page: Page, triggerName: string, collectionName: string) {
|
||||
this.page = page;
|
||||
this.node = page.getByText('TriggeraConfigure');
|
||||
this.nodeTitle = page.locator('textarea').filter({ hasText: triggerName });
|
||||
this.nodeConfigure = page.getByRole('button', { name: 'Configure' });
|
||||
this.customTimeTriggerOptions = page.getByLabel('Based on certain date');
|
||||
this.startTimeEntryBox = page.getByPlaceholder('Select date');
|
||||
this.RrpeatModeDropdown = page.getByLabel('block-item-RepeatField-workflows-Repeat mode');
|
||||
|
||||
this.dataTableTimeFieldOptions = page.getByLabel('Based on date field of collection');
|
||||
this.collectionDropDown = page.getByRole('button', { name: 'Select collection' });
|
||||
this.startTimeDropdown = page.getByLabel('block-item-OnField-workflows-Starts on');
|
||||
this.submitButton = page.getByLabel('action-Action-Submit-workflows');
|
||||
this.cancelButton = page.getByLabel('action-Action-Cancel-workflows');
|
||||
this.addNodeButton = page.getByLabel('add-button', { exact: true });
|
||||
}
|
||||
}
|
||||
|
||||
export class CollectionTriggerNode {
|
||||
readonly page: Page;
|
||||
node: Locator;
|
||||
nodeTitle: Locator;
|
||||
nodeConfigure: Locator;
|
||||
collectionDropDown: Locator;
|
||||
triggerOnDropdown: Locator;
|
||||
submitButton: Locator;
|
||||
cancelButton: Locator;
|
||||
addNodeButton: Locator;
|
||||
constructor(page: Page, triggerName: string, collectionName: string) {
|
||||
this.page = page;
|
||||
this.node = page.getByLabel(`Trigger-${triggerName}`);
|
||||
this.nodeTitle = page.getByLabel(`Trigger-${triggerName}`).getByRole('textbox');
|
||||
this.nodeConfigure = page.getByLabel(`Trigger-${triggerName}`).getByRole('button', { name: 'Configure' });
|
||||
this.collectionDropDown = page.getByRole('button', { name: 'Select collection' });
|
||||
this.triggerOnDropdown = page
|
||||
.getByLabel('block-item-Select-workflows-Trigger on')
|
||||
.getByRole('button', { name: 'Trigger on' });
|
||||
this.submitButton = page.getByLabel('action-Action-Submit-workflows');
|
||||
this.cancelButton = page.getByLabel('action-Action-Cancel-workflows');
|
||||
this.addNodeButton = page.getByLabel('add-button', { exact: true });
|
||||
}
|
||||
}
|
||||
|
||||
export class FormEventTriggerNode {
|
||||
readonly page: Page;
|
||||
node: Locator;
|
||||
nodeTitle: Locator;
|
||||
nodeConfigure: Locator;
|
||||
collectionDropDown: Locator;
|
||||
relationalDataDropdown: Locator;
|
||||
submitButton: Locator;
|
||||
cancelButton: Locator;
|
||||
addNodeButton: Locator;
|
||||
constructor(page: Page, triggerName: string, collectionName: string) {
|
||||
this.page = page;
|
||||
this.node = page.getByLabel(`Trigger-${triggerName}`);
|
||||
this.nodeTitle = page.getByLabel(`Trigger-${triggerName}`).getByRole('textbox');
|
||||
this.nodeConfigure = page.getByLabel(`Trigger-${triggerName}`).getByRole('button', { name: 'Configure' });
|
||||
this.collectionDropDown = page.getByRole('button', { name: 'Select collection' });
|
||||
this.relationalDataDropdown = page.getByTestId('select-field-Preload associations');
|
||||
this.submitButton = page.getByLabel('action-Action-Submit-workflows');
|
||||
this.cancelButton = page.getByLabel('action-Action-Cancel-workflows');
|
||||
this.addNodeButton = page.getByLabel('add-button', { exact: true });
|
||||
}
|
||||
}
|
||||
|
||||
export class ClculationNode {
|
||||
readonly page: Page;
|
||||
node: Locator;
|
||||
nodeTitle: Locator;
|
||||
nodeConfigure: Locator;
|
||||
mathCalculationEngine: Locator;
|
||||
formulaCalculationEngine: Locator;
|
||||
calculationExpression: Locator;
|
||||
submitButton: Locator;
|
||||
cancelButton: Locator;
|
||||
addNodeButton: Locator;
|
||||
constructor(page: Page, nodeName: string) {
|
||||
this.page = page;
|
||||
this.node = page.getByLabel(`Calculation-${nodeName}`, { exact: true });
|
||||
this.nodeTitle = page.getByLabel(`Calculation-${nodeName}`, { exact: true }).getByRole('textbox');
|
||||
this.nodeConfigure = page
|
||||
.getByLabel(`Calculation-${nodeName}`, { exact: true })
|
||||
.getByRole('button', { name: 'Configure' });
|
||||
this.mathCalculationEngine = page.getByLabel('Math.js');
|
||||
this.formulaCalculationEngine = page.getByLabel('Formula.js');
|
||||
this.calculationExpression = page.getByLabel('textbox');
|
||||
this.submitButton = page.getByLabel('action-Action-Submit-workflows');
|
||||
this.cancelButton = page.getByLabel('action-Action-Cancel-workflows');
|
||||
this.addNodeButton = page.getByLabel(`add-button-calculation-${nodeName}`, { exact: true });
|
||||
}
|
||||
}
|
||||
|
||||
export class QueryRecordNode {
|
||||
readonly page: Page;
|
||||
node: Locator;
|
||||
nodeTitle: Locator;
|
||||
nodeConfigure: Locator;
|
||||
collectionDropDown: Locator;
|
||||
allowMultipleDataBoxesForResults: Locator;
|
||||
addSortFieldsButton: Locator;
|
||||
pageNumberEditBox: Locator;
|
||||
pageNumberVariableButton: Locator;
|
||||
pageSizeEditBox: Locator;
|
||||
exitProcessOptionsBoxWithEmptyResult: Locator;
|
||||
submitButton: Locator;
|
||||
cancelButton: Locator;
|
||||
addNodeButton: Locator;
|
||||
constructor(page: Page, nodeName: string) {
|
||||
this.page = page;
|
||||
this.node = page.getByLabel(`Query record-${nodeName}`, { exact: true });
|
||||
this.nodeTitle = page.getByLabel(`Query record-${nodeName}`, { exact: true }).getByRole('textbox');
|
||||
this.nodeConfigure = page
|
||||
.getByLabel(`Query record-${nodeName}`, { exact: true })
|
||||
.getByRole('button', { name: 'Configure' });
|
||||
this.collectionDropDown = page.getByRole('button', { name: 'Select collection' });
|
||||
this.allowMultipleDataBoxesForResults = page.getByLabel('Allow multiple records as');
|
||||
this.addSortFieldsButton = page.getByRole('button', { name: 'plus Add sort field' });
|
||||
this.pageNumberEditBox = page.getByLabel('variable-constant');
|
||||
this.pageNumberVariableButton = page.getByLabel('variable-button');
|
||||
this.pageSizeEditBox = page.getByLabel('block-item-InputNumber-workflows-Page size').getByRole('spinbutton');
|
||||
this.exitProcessOptionsBoxWithEmptyResult = page.getByLabel('Exit when query result is null');
|
||||
this.submitButton = page.getByLabel('action-Action-Submit-workflows');
|
||||
this.cancelButton = page.getByLabel('action-Action-Cancel-workflows');
|
||||
this.addNodeButton = page.getByLabel(`add-button-query-${nodeName}`, { exact: true });
|
||||
}
|
||||
}
|
||||
|
||||
export class CreateRecordNode {
|
||||
readonly page: Page;
|
||||
node: Locator;
|
||||
nodeTitle: Locator;
|
||||
nodeConfigure: Locator;
|
||||
collectionDropDown: Locator;
|
||||
addFieldsButton: Locator;
|
||||
submitButton: Locator;
|
||||
cancelButton: Locator;
|
||||
addNodeButton: Locator;
|
||||
constructor(page: Page, nodeName: string) {
|
||||
this.page = page;
|
||||
this.node = page.getByLabel(`Create record-${nodeName}`, { exact: true });
|
||||
this.nodeTitle = page.getByLabel(`Create record-${nodeName}`, { exact: true }).getByRole('textbox');
|
||||
this.nodeConfigure = page
|
||||
.getByLabel(`Create record-${nodeName}`, { exact: true })
|
||||
.getByRole('button', { name: 'Configure' });
|
||||
this.collectionDropDown = page.getByRole('button', { name: 'Select collection' });
|
||||
this.addFieldsButton = page.getByRole('button', { name: 'plus Add field' });
|
||||
this.submitButton = page.getByLabel('action-Action-Submit-workflows');
|
||||
this.cancelButton = page.getByLabel('action-Action-Cancel-workflows');
|
||||
this.addNodeButton = page.getByLabel(`add-button-create-${nodeName}`, { exact: true });
|
||||
}
|
||||
}
|
||||
|
||||
export class UpdateRecordNode {
|
||||
readonly page: Page;
|
||||
node: Locator;
|
||||
nodeTitle: Locator;
|
||||
nodeConfigure: Locator;
|
||||
collectionDropDown: Locator;
|
||||
batchUpdateModeRadio: Locator;
|
||||
articleByArticleUpdateModeRadio: Locator;
|
||||
addFieldsButton: Locator;
|
||||
submitButton: Locator;
|
||||
cancelButton: Locator;
|
||||
addNodeButton: Locator;
|
||||
constructor(page: Page, nodeName: string) {
|
||||
this.page = page;
|
||||
this.node = page.getByLabel(`Update record-${nodeName}`, { exact: true });
|
||||
this.nodeTitle = page.getByLabel(`Update record-${nodeName}`, { exact: true }).getByRole('textbox');
|
||||
this.nodeConfigure = page
|
||||
.getByLabel(`Update record-${nodeName}`, { exact: true })
|
||||
.getByRole('button', { name: 'Configure' });
|
||||
this.collectionDropDown = page.getByRole('button', { name: 'Select collection' });
|
||||
this.batchUpdateModeRadio = page
|
||||
.getByLabel('block-item-IndividualHooksRadioWithTooltip-workflows-Update mode')
|
||||
.getByLabel('Update in a batch');
|
||||
this.articleByArticleUpdateModeRadio = page
|
||||
.getByLabel('block-item-IndividualHooksRadioWithTooltip-workflows-Update mode')
|
||||
.getByLabel('Update one by one');
|
||||
this.addFieldsButton = page.getByRole('button', { name: 'plus Add field' });
|
||||
this.submitButton = page.getByLabel('action-Action-Submit-workflows');
|
||||
this.cancelButton = page.getByLabel('action-Action-Cancel-workflows');
|
||||
this.addNodeButton = page.getByLabel(`add-button-update-${nodeName}`, { exact: true });
|
||||
}
|
||||
}
|
||||
|
||||
export class DeleteRecordNode {
|
||||
readonly page: Page;
|
||||
node: Locator;
|
||||
nodeTitle: Locator;
|
||||
nodeConfigure: Locator;
|
||||
collectionDropDown: Locator;
|
||||
submitButton: Locator;
|
||||
cancelButton: Locator;
|
||||
addNodeButton: Locator;
|
||||
constructor(page: Page, nodeName: string) {
|
||||
this.page = page;
|
||||
this.node = page.getByLabel(`Delete record-${nodeName}`, { exact: true });
|
||||
this.nodeTitle = page.getByLabel(`Delete record-${nodeName}`, { exact: true }).getByRole('textbox');
|
||||
this.nodeConfigure = page
|
||||
.getByLabel(`Delete record-${nodeName}`, { exact: true })
|
||||
.getByRole('button', { name: 'Configure' });
|
||||
this.collectionDropDown = page.getByRole('button', { name: 'Select collection' });
|
||||
this.submitButton = page.getByLabel('action-Action-Submit-workflows');
|
||||
this.cancelButton = page.getByLabel('action-Action-Cancel-workflows');
|
||||
this.addNodeButton = page.getByLabel(`add-button-delete-${nodeName}`, { exact: true });
|
||||
}
|
||||
}
|
||||
|
||||
export class AggregateNode {
|
||||
readonly page: Page;
|
||||
node: Locator;
|
||||
nodeTitle: Locator;
|
||||
nodeConfigure: Locator;
|
||||
countRadio: Locator;
|
||||
sumRadio: Locator;
|
||||
avgRadio: Locator;
|
||||
maxRadio: Locator;
|
||||
minRadio: Locator;
|
||||
dataTableDataRadio: Locator;
|
||||
linkedDataTableDataRadio: Locator;
|
||||
collectionDropDown: Locator;
|
||||
aggregatedFieldDropDown: Locator;
|
||||
submitButton: Locator;
|
||||
cancelButton: Locator;
|
||||
addNodeButton: Locator;
|
||||
constructor(page: Page, nodeName: string) {
|
||||
this.page = page;
|
||||
this.node = page.getByLabel(`Aggregate-${nodeName}`, { exact: true });
|
||||
this.nodeTitle = page.getByLabel(`Aggregate-${nodeName}`, { exact: true }).getByRole('textbox');
|
||||
this.nodeConfigure = page
|
||||
.getByLabel(`Aggregate-${nodeName}`, { exact: true })
|
||||
.getByRole('button', { name: 'Configure' });
|
||||
this.countRadio = page.getByLabel('COUNT');
|
||||
this.sumRadio = page.getByLabel('SUM', { exact: true });
|
||||
this.avgRadio = page.getByLabel('AVG', { exact: true });
|
||||
this.maxRadio = page.getByLabel('MAX', { exact: true });
|
||||
this.minRadio = page.getByLabel('MIN', { exact: true });
|
||||
this.dataTableDataRadio = page.getByLabel('Data of collection');
|
||||
this.linkedDataTableDataRadio = page.getByLabel('Data of associated collection');
|
||||
this.collectionDropDown = page.getByRole('button', { name: 'Select collection' });
|
||||
// this.aggregatedFieldDropDown = page.getByLabel('block-item-FieldsSelect-workflows-Field to aggregate').getByRole('textbox').getByRole('combobox');
|
||||
this.aggregatedFieldDropDown = page.locator(
|
||||
'input.ant-select-selection-search-input[role="combobox"][aria-haspopup="listbox"]',
|
||||
);
|
||||
this.submitButton = page.getByLabel('action-Action-Submit-workflows');
|
||||
this.cancelButton = page.getByLabel('action-Action-Cancel-workflows');
|
||||
this.addNodeButton = page.getByLabel(`add-button-aggregate-${nodeName}`, { exact: true });
|
||||
}
|
||||
}
|
||||
|
||||
export class ManualNode {
|
||||
readonly page: Page;
|
||||
node: Locator;
|
||||
nodeTitle: Locator;
|
||||
nodeConfigure: Locator;
|
||||
assigneesDropDown: Locator;
|
||||
configureUserInterfaceButton: Locator;
|
||||
addBlockButton: Locator;
|
||||
triggerDataMenu: Locator;
|
||||
nodeDataMenu: Locator;
|
||||
customFormMenu: Locator;
|
||||
createRecordFormMenu: Locator;
|
||||
updateRecordFormMenu: Locator;
|
||||
submitButton: Locator;
|
||||
cancelButton: Locator;
|
||||
addNodeButton: Locator;
|
||||
constructor(page: Page, nodeName: string) {
|
||||
this.page = page;
|
||||
this.node = page.getByLabel(`Manual-${nodeName}`, { exact: true });
|
||||
this.nodeTitle = page.getByLabel(`Manual-${nodeName}`, { exact: true }).getByRole('textbox');
|
||||
this.nodeConfigure = page
|
||||
.getByLabel(`Manual-${nodeName}`, { exact: true })
|
||||
.getByRole('button', { name: 'Configure' });
|
||||
this.assigneesDropDown = page.getByTestId('select-single');
|
||||
this.configureUserInterfaceButton = page.getByRole('button', { name: 'Configure user interface' });
|
||||
this.addBlockButton = page.getByLabel('schema-initializer-Grid-AddBlockButton-workflows');
|
||||
this.triggerDataMenu = page.getByLabel('Data blocks-triggerData');
|
||||
this.nodeDataMenu = page.getByLabel('nodes', { exact: true });
|
||||
this.customFormMenu = page.getByRole('menuitem', { name: 'Custom form' });
|
||||
this.createRecordFormMenu = page.getByRole('menuitem', { name: 'Create record form' });
|
||||
this.updateRecordFormMenu = page.getByRole('menuitem', { name: 'Update record form' });
|
||||
this.submitButton = page.getByLabel('action-Action-Submit-workflows');
|
||||
this.cancelButton = page.getByLabel('action-Action-Cancel-workflows');
|
||||
this.addNodeButton = page.getByLabel(`add-button-manual-${nodeName}`, { exact: true });
|
||||
}
|
||||
}
|
||||
|
||||
export class ConditionYesNode {
|
||||
readonly page: Page;
|
||||
node: Locator;
|
||||
nodeTitle: Locator;
|
||||
nodeConfigure: Locator;
|
||||
basicRadio: Locator;
|
||||
mathRadio: Locator;
|
||||
formulaRadio: Locator;
|
||||
submitButton: Locator;
|
||||
cancelButton: Locator;
|
||||
addNodeButton: Locator;
|
||||
constructor(page: Page, nodeName: string) {
|
||||
this.page = page;
|
||||
this.node = page.getByLabel(`Condition-${nodeName}`, { exact: true });
|
||||
this.nodeTitle = page.getByLabel(`Condition-${nodeName}`, { exact: true }).getByRole('textbox');
|
||||
this.nodeConfigure = page
|
||||
.getByLabel(`Condition-${nodeName}`, { exact: true })
|
||||
.getByRole('button', { name: 'Configure' });
|
||||
// await page.getByLabel('variable-constant').first().click();
|
||||
// await page.getByLabel('variable-button').first().click();
|
||||
// await page.getByLabel('select-operator-calc').first().click();
|
||||
// await page.getByRole('option', { name: '=' }).click();
|
||||
// await page.getByLabel('variable-constant').nth(1).click();
|
||||
// await page.getByLabel('variable-button').nth(1).click();
|
||||
this.basicRadio = page.getByLabel('Basic');
|
||||
this.mathRadio = page.getByLabel('Math.js');
|
||||
this.formulaRadio = page.getByLabel('Formula.js');
|
||||
this.submitButton = page.getByLabel('action-Action-Submit-workflows');
|
||||
this.cancelButton = page.getByLabel('action-Action-Cancel-workflows');
|
||||
this.addNodeButton = page.getByLabel(`add-button-condition-${nodeName}`, { exact: true });
|
||||
}
|
||||
}
|
||||
|
||||
export class ConditionBranchNode {
|
||||
readonly page: Page;
|
||||
node: Locator;
|
||||
nodeTitle: Locator;
|
||||
nodeConfigure: Locator;
|
||||
basicRadio: Locator;
|
||||
mathRadio: Locator;
|
||||
formulaRadio: Locator;
|
||||
submitButton: Locator;
|
||||
cancelButton: Locator;
|
||||
addNoBranchNode: Locator;
|
||||
addYesBranchNode: Locator;
|
||||
addNodeButton: Locator;
|
||||
constructor(page: Page, nodeName: string) {
|
||||
this.page = page;
|
||||
this.node = page.getByLabel(`Condition-${nodeName}`, { exact: true });
|
||||
this.nodeTitle = page.getByLabel(`Condition-${nodeName}`, { exact: true }).getByRole('textbox');
|
||||
this.nodeConfigure = page
|
||||
.getByLabel(`Condition-${nodeName}`, { exact: true })
|
||||
.getByRole('button', { name: 'Configure' });
|
||||
this.submitButton = page.getByLabel('action-Action-Submit-workflows');
|
||||
this.cancelButton = page.getByLabel('action-Action-Cancel-workflows');
|
||||
this.addNodeButton = page.getByLabel(`add-button-condition-${nodeName}`, { exact: true });
|
||||
this.basicRadio = page.getByLabel('Basic');
|
||||
this.mathRadio = page.getByLabel('Math.js');
|
||||
this.formulaRadio = page.getByLabel('Formula.js');
|
||||
this.addNoBranchNode = page.getByLabel(`add-button-condition-${nodeName}-0`);
|
||||
this.addYesBranchNode = page.getByLabel(`add-button-condition-${nodeName}-1`);
|
||||
}
|
||||
}
|
||||
|
||||
export default module.exports = {
|
||||
CreateWorkFlow,
|
||||
EditWorkFlow,
|
||||
WorkflowManagement,
|
||||
WorkflowListRecords,
|
||||
ApprovalTriggerNode,
|
||||
ApprovalNode,
|
||||
ScheduleTriggerNode,
|
||||
CollectionTriggerNode,
|
||||
FormEventTriggerNode,
|
||||
ClculationNode,
|
||||
QueryRecordNode,
|
||||
CreateRecordNode,
|
||||
UpdateRecordNode,
|
||||
DeleteRecordNode,
|
||||
AggregateNode,
|
||||
ManualNode,
|
||||
ConditionYesNode,
|
||||
ConditionBranchNode,
|
||||
};
|
@ -0,0 +1,747 @@
|
||||
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);
|
||||
/*upstreamId前置节点id ,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,
|
||||
};
|
@ -0,0 +1,4 @@
|
||||
export * from './e2eCollectionModel';
|
||||
export * from './e2ePageObjectModel';
|
||||
export { default } from './e2ePageObjectModel';
|
||||
export * from './e2eUtils';
|
@ -0,0 +1,360 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import {
|
||||
CreateWorkFlow,
|
||||
EditWorkFlow,
|
||||
ScheduleTriggerNode,
|
||||
WorkflowListRecords,
|
||||
apiCreateWorkflow,
|
||||
apiDeleteWorkflow,
|
||||
apiGetWorkflow,
|
||||
apiUpdateWorkflowTrigger,
|
||||
appendJsonCollectionName,
|
||||
generalWithNoRelationalFields,
|
||||
} from '@nocobase/plugin-workflow-test/e2e';
|
||||
import { expect, test } from '@nocobase/test/e2e';
|
||||
import { dayjs } from '@nocobase/utils';
|
||||
|
||||
test.describe('Configuration page to configure the Trigger node', () => {
|
||||
test('Triggered one minute after the current time of the customized time', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
test.setTimeout(120000);
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'schedule',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
//配置工作流触发器
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const scheduleTriggerNode = new ScheduleTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await scheduleTriggerNode.nodeConfigure.click();
|
||||
await scheduleTriggerNode.startTimeEntryBox.click();
|
||||
await scheduleTriggerNode.startTimeEntryBox.fill(dayjs().add(60, 'second').format('YYYY-MM-DD HH:mm:ss'));
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
await scheduleTriggerNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:等待60秒
|
||||
await page.waitForTimeout(60000);
|
||||
|
||||
// 3、预期结果:工作流成功触发
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Configuration Page Path Jump Workflow Management Page', () => {
|
||||
test('Schedule event Workflow Configuration Page Path Jump Workflow Management Page', async ({ page }) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
// const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
// const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
// const triggerNodeFieldName = 'orgname';
|
||||
// const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
// await mockCollections(appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText).collections);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'schedule',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
//配置工作流触发器
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// 2、测试步骤:跳转到工作流管理页面
|
||||
await page.getByRole('link', { name: 'Workflow' }).click();
|
||||
|
||||
// 3、预期结果:跳转路径正确
|
||||
await page.waitForLoadState('networkidle');
|
||||
expect(page.url()).toBe(`${process.env.APP_BASE_URL}/admin/settings/workflow`);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Schedule event Workflow History Version Configuration Page Path Jump Workflow Management Page', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'schedule',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
//配置工作流触发器
|
||||
const now = new Date();
|
||||
now.setMinutes(now.getMinutes() + 1);
|
||||
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
const timeWithTimeZone = now.toLocaleString('en-US', { timeZone: timeZone });
|
||||
const triggerNodeData = { config: { mode: 0, startsOn: timeWithTimeZone } };
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
// 2、测试步骤:等待60秒
|
||||
await page.waitForTimeout(60000);
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel('more').click();
|
||||
await page.getByLabel('revision').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
//元素重复
|
||||
await page.getByLabel('version', { exact: true }).click();
|
||||
await page.getByLabel('version-1').click();
|
||||
await page.getByRole('link', { name: 'Workflow' }).click();
|
||||
|
||||
// 3、预期结果:跳转路径正确
|
||||
await page.waitForLoadState('networkidle');
|
||||
expect(page.url()).toBe(`${process.env.APP_BASE_URL}/admin/settings/workflow`);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Schedule event Workflow Execution Log Page Path Jump Workflow Management Page', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'schedule',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
//配置工作流触发器
|
||||
const now = new Date();
|
||||
now.setMinutes(now.getMinutes() + 1);
|
||||
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
const timeWithTimeZone = now.toLocaleString('en-US', { timeZone: timeZone });
|
||||
const triggerNodeData = { config: { mode: 0, startsOn: timeWithTimeZone } };
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
// 2、测试步骤:等待60秒
|
||||
await page.waitForTimeout(60000);
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
const workflowListRecords = new WorkflowListRecords(page, workFlowName);
|
||||
await workflowListRecords.executionCountPopup.click();
|
||||
await page.getByText('View').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByRole('link', { name: 'Workflow', exact: true }).click();
|
||||
|
||||
// 3、预期结果:跳转路径正确
|
||||
await page.waitForLoadState('networkidle');
|
||||
expect(page.url()).toBe(`${process.env.APP_BASE_URL}/admin/settings/workflow`);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test.skip('Schedule event Workflow Execution Log Page Path Jump Execution Log Screen', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'schedule',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
//配置工作流触发器
|
||||
const now = new Date();
|
||||
now.setMinutes(now.getMinutes() + 1);
|
||||
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
const timeWithTimeZone = now.toLocaleString('en-US', { timeZone: timeZone });
|
||||
const triggerNodeData = { config: { mode: 0, startsOn: timeWithTimeZone } };
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
// 2、测试步骤:等待60秒
|
||||
await page.waitForTimeout(60000);
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
const workflowListRecords = new WorkflowListRecords(page, workFlowName);
|
||||
await workflowListRecords.executionCountPopup.click();
|
||||
await page.getByText('View').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
//跳转其他执行日志界面,元素无法定位
|
||||
|
||||
// 3、预期结果:跳转路径正确
|
||||
await page.waitForLoadState('networkidle');
|
||||
// expect(page.url()).toBe(`${process.env.APP_BASE_URL}/admin/settings/workflow`);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Configuration page version switching', () => {});
|
||||
|
||||
test.describe('Configuration page disable enable', () => {});
|
||||
|
||||
test.describe('Configuration page execution history', () => {});
|
||||
|
||||
test.describe('Configuration page copy to new version', () => {
|
||||
test('Copy the Schedule event of the Configuration Trigger node', async ({ page, mockCollections, mockRecords }) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'schedule',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
//配置工作流触发器
|
||||
const now = new Date();
|
||||
now.setMinutes(now.getMinutes() + 1);
|
||||
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
const timeWithTimeZone = now.toLocaleString('en-US', { timeZone: timeZone });
|
||||
const triggerNodeData = { config: { mode: 0, startsOn: timeWithTimeZone } };
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
// 2、测试步骤:等待60秒
|
||||
await page.waitForTimeout(60000);
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
const workflowListRecords = new WorkflowListRecords(page, workFlowName);
|
||||
|
||||
await workflowListRecords.configureAction.click();
|
||||
await page.getByLabel('more').click();
|
||||
await page.getByLabel('revision').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
const scheduleTriggerNode = new ScheduleTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await scheduleTriggerNode.nodeConfigure.click();
|
||||
// 3、预期结果:startTime时间为60秒后的时间
|
||||
const timeWithoutTimeZonea = now.toLocaleString('en-US', { timeZone: timeZone, hour12: false });
|
||||
// 将 MM/DD/YYYY, HH:mm:ss 格式的字符串转换为 YYYY-MM-DD HH:mm:ss 格式
|
||||
const parts = timeWithoutTimeZonea.split(/[\s,/:]+/);
|
||||
const formattedTimeWithTimeZone = `${parts[2]}-${parts[0].padStart(2, '0')}-${parts[1].padStart(2, '0')} ${
|
||||
parts[3]
|
||||
}:${parts[4]}:${parts[5]}`;
|
||||
|
||||
await expect(scheduleTriggerNode.startTimeEntryBox).toHaveValue(formattedTimeWithTimeZone);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Configuration page delete version', () => {});
|
||||
|
||||
test.describe('Node Add Modify Delete', () => {});
|
@ -0,0 +1,174 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import {
|
||||
CreateWorkFlow,
|
||||
EditWorkFlow,
|
||||
ScheduleTriggerNode,
|
||||
WorkflowListRecords,
|
||||
apiCreateWorkflow,
|
||||
apiDeleteWorkflow,
|
||||
apiGetWorkflow,
|
||||
apiUpdateWorkflowTrigger,
|
||||
appendJsonCollectionName,
|
||||
generalWithNoRelationalFields,
|
||||
} from '@nocobase/plugin-workflow-test/e2e';
|
||||
import { expect, test } from '@nocobase/test/e2e';
|
||||
import { dayjs } from '@nocobase/utils';
|
||||
|
||||
test.describe('Filter', () => {
|
||||
test('filter workflow name', async ({ page }) => {
|
||||
//添加工作流
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'schedule',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
// 2、筛选工作流
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel('action-Filter.Action-Filter-filter-workflows').click();
|
||||
await page.getByRole('textbox').fill(workFlowName);
|
||||
await page.getByRole('button', { name: 'Submit', exact: true }).click();
|
||||
|
||||
// 3、预期结果:列表中出现筛选的工作流
|
||||
await expect(page.getByText(workFlowName)).toBeAttached();
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Add new', () => {
|
||||
test('add new Schedule event', async ({ page }) => {
|
||||
// 添加工作流
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel('action-Action-Add new-workflows').click();
|
||||
const createWorkFlow = new CreateWorkFlow(page);
|
||||
const workFlowName = faker.string.alphanumeric(5);
|
||||
await createWorkFlow.name.fill(workFlowName);
|
||||
await createWorkFlow.triggerType.click();
|
||||
await page.getByRole('option', { name: 'Schedule event' }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
|
||||
// 3、预期结果:列表中出现新建的工作流
|
||||
await expect(page.getByText(workFlowName)).toBeVisible();
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await page.getByLabel('action-Filter.Action-Filter-filter-workflows').click();
|
||||
await page.getByRole('textbox').fill(workFlowName);
|
||||
await page.getByRole('button', { name: 'Submit', exact: true }).click();
|
||||
await page.getByLabel(`action-Action.Link-Delete-workflows-${workFlowName}`).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
await expect(page.getByText(workFlowName)).toBeHidden();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Sync', () => {});
|
||||
|
||||
test.describe('Delete', () => {
|
||||
test('delete Schedule event', async ({ page }) => {
|
||||
//添加工作流
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'schedule',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
// 删除工作流
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel('action-Filter.Action-Filter-filter-workflows').click();
|
||||
await page.getByRole('textbox').fill(workFlowName);
|
||||
await page.getByRole('button', { name: 'Submit', exact: true }).click();
|
||||
await page.getByLabel(`action-Action.Link-Delete-workflows-${workFlowName}`).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
|
||||
// 3、预期结果:列表中出现筛选的工作流
|
||||
await expect(page.getByText(workFlowName)).toBeHidden();
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Edit', () => {
|
||||
test('edit Schedule event name', async ({ page }) => {
|
||||
//添加工作流
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
let workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'schedule',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
// 编辑工作流
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel(`action-Action.Link-Edit-workflows-${workFlowName}`).click();
|
||||
const editWorkFlow = new EditWorkFlow(page, workFlowName);
|
||||
workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
await editWorkFlow.name.fill(workFlowName);
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
// 3、预期结果:编辑成功,列表中出现编辑后的工作流
|
||||
await expect(page.getByText(workFlowName)).toBeAttached();
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Duplicate', () => {
|
||||
test('Duplicate Schedule event triggers with only unconfigured trigger nodes', async ({ page }) => {
|
||||
//添加工作流
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'schedule',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
// 2、复制工作流
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel(`action-Action.Link-Duplicate-workflows-${workFlowName}`).click();
|
||||
await page.getByLabel(`action-Action-Submit-workflows-${workFlowName}`).click();
|
||||
|
||||
// 3、预期结果:列表中出现筛选的工作流
|
||||
await expect(page.getByText(`${workFlowName} copy`)).toBeAttached();
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await page.getByLabel(`action-Action.Link-Delete-workflows-${workFlowName} copy`).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
await expect(page.getByText(`${workFlowName} copy`)).toBeHidden();
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Executed', () => {});
|
@ -0,0 +1,761 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import {
|
||||
AggregateNode,
|
||||
ClculationNode,
|
||||
CollectionTriggerNode,
|
||||
CreateRecordNode,
|
||||
QueryRecordNode,
|
||||
apiCreateWorkflow,
|
||||
apiCreateWorkflowNode,
|
||||
apiDeleteWorkflow,
|
||||
apiGetWorkflow,
|
||||
apiGetWorkflowNode,
|
||||
apiGetWorkflowNodeExecutions,
|
||||
apiUpdateWorkflowNode,
|
||||
apiUpdateWorkflowTrigger,
|
||||
appendJsonCollectionName,
|
||||
generalWithNoRelationalFields,
|
||||
} from '@nocobase/plugin-workflow-test/e2e';
|
||||
import { expect, test } from '@nocobase/test/e2e';
|
||||
import { dayjs } from '@nocobase/utils';
|
||||
|
||||
test('Collection event add data trigger, get trigger node single line text variable', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置计算节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'calculation', exact: true }).click();
|
||||
const calculationNodeName = 'calculation' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Calculation-Calculation', { exact: true }).getByRole('textbox').fill(calculationNodeName);
|
||||
const calculationNode = new ClculationNode(page, calculationNodeName);
|
||||
await calculationNode.nodeConfigure.click();
|
||||
await calculationNode.formulaCalculationEngine.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByText('Trigger variables').click();
|
||||
await page.getByText('Trigger data').click();
|
||||
await page.getByText('公司名称(单行文本)').click();
|
||||
await expect(page.getByLabel('textbox')).toHaveText('Trigger variables / Trigger data / 公司名称(单行文本)');
|
||||
await calculationNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const getWorkflowNodeExecutionsObjResult = getWorkflowNodeExecutionsObj[0].jobs[0].result;
|
||||
expect(getWorkflowNodeExecutionsObjResult).toBe(triggerNodeCollectionRecordOne);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data triggers, get predecessor Formula engine arithmetic node data', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置前置计算节点
|
||||
const preCalculationNodeTitle = 'calculation' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const preCalculationNodeData = {
|
||||
type: 'calculation',
|
||||
upstreamId: null,
|
||||
branchIndex: null,
|
||||
title: preCalculationNodeTitle,
|
||||
config: { engine: 'formula.js', expression: '{{$context.data.orgname}}' },
|
||||
};
|
||||
const preCalculationNode = await apiCreateWorkflowNode(workflowId, preCalculationNodeData);
|
||||
const preCalculationNodeObj = JSON.parse(JSON.stringify(preCalculationNode));
|
||||
const preCalculationNodeId = preCalculationNodeObj.id;
|
||||
const getPreCalculationNode = await apiGetWorkflowNode(preCalculationNodeId);
|
||||
const preCalculationNodeKey = getPreCalculationNode.key;
|
||||
|
||||
//配置计算节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const preCalculationNodePom = new ClculationNode(page, preCalculationNodeTitle);
|
||||
await preCalculationNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'calculation', exact: true }).click();
|
||||
const calculationNodeName = 'calculation' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Calculation-Calculation', { exact: true }).getByRole('textbox').fill(calculationNodeName);
|
||||
const calculationNode = new ClculationNode(page, calculationNodeName);
|
||||
const conditionNodeId = await calculationNode.node.locator('.workflow-node-id').innerText();
|
||||
await calculationNode.nodeConfigure.click();
|
||||
await calculationNode.formulaCalculationEngine.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByText('Node result').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: preCalculationNodeTitle }).click();
|
||||
await expect(page.getByLabel('textbox')).toHaveText(`Node result / ${preCalculationNodeTitle}`);
|
||||
await calculationNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const job = jobs.find((job) => job.nodeId.toString() === conditionNodeId);
|
||||
expect(job.result).toBe(triggerNodeCollectionRecordOne);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection events add data triggers, get single line of text data for front query data nodes', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置前置查询节点
|
||||
const preQueryRecordNodeTitle = 'Query record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const preQueryRecordNodeData = {
|
||||
type: 'query',
|
||||
upstreamId: null,
|
||||
branchIndex: null,
|
||||
title: preQueryRecordNodeTitle,
|
||||
config: {
|
||||
collection: triggerNodeCollectionName,
|
||||
params: {
|
||||
filter: { $and: [{ id: { $eq: '{{$context.data.id}}' } }] },
|
||||
sort: [],
|
||||
page: 1,
|
||||
pageSize: 20,
|
||||
appends: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
const preQueryRecordNode = await apiCreateWorkflowNode(workflowId, preQueryRecordNodeData);
|
||||
const preQueryRecordNodeObj = JSON.parse(JSON.stringify(preQueryRecordNode));
|
||||
const preQueryRecordNodeId = preQueryRecordNodeObj.id;
|
||||
const getPreQueryRecordNode = await apiGetWorkflowNode(preQueryRecordNodeId);
|
||||
const preQueryRecordNodeKey = getPreQueryRecordNode.key;
|
||||
|
||||
//配置计算节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'calculation', exact: true }).click();
|
||||
const calculationNodeName = 'calculation' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Calculation-Calculation', { exact: true }).getByRole('textbox').fill(calculationNodeName);
|
||||
const calculationNode = new ClculationNode(page, calculationNodeName);
|
||||
const conditionNodeId = await calculationNode.node.locator('.workflow-node-id').innerText();
|
||||
await calculationNode.nodeConfigure.click();
|
||||
await calculationNode.formulaCalculationEngine.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Node result' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: preQueryRecordNodeTitle }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: '公司名称(单行文本)' }).click();
|
||||
await expect(page.getByLabel('textbox')).toHaveText(`Node result / ${preQueryRecordNodeTitle} / 公司名称(单行文本)`);
|
||||
await calculationNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const job = jobs.find((job) => job.nodeId.toString() === conditionNodeId);
|
||||
expect(job.result).toBe(triggerNodeCollectionRecordOne);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, get front added data node single line text data', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
// 创建新增数据节点数据表
|
||||
const createRecordNodeAppendText = faker.string.alphanumeric(6);
|
||||
const createRecordNodeCollectionDisplayName = `自动>组织[普通表]${createRecordNodeAppendText}`;
|
||||
const createRecordNodeCollectionName = `tt_amt_org${createRecordNodeAppendText}`;
|
||||
const createRecordNodeFieldName = 'orgname';
|
||||
const createRecordNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), createRecordNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置前置添加数据节点
|
||||
const preCreateRecordNodeTitle = 'Create record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const preCreateRecordNodeData = {
|
||||
type: 'create',
|
||||
upstreamId: null,
|
||||
branchIndex: null,
|
||||
title: preCreateRecordNodeTitle,
|
||||
config: {
|
||||
params: { values: { orgname: '{{$context.data.orgname}}' }, appends: [] },
|
||||
collection: createRecordNodeCollectionName,
|
||||
},
|
||||
};
|
||||
const preCreateRecordNode = await apiCreateWorkflowNode(workflowId, preCreateRecordNodeData);
|
||||
const preCreateRecordNodeObj = JSON.parse(JSON.stringify(preCreateRecordNode));
|
||||
const preCreateRecordNodeId = preCreateRecordNodeObj.id;
|
||||
const getPreCreateRecordNode = await apiGetWorkflowNode(preCreateRecordNodeId);
|
||||
const preCreateRecordNodeKey = getPreCreateRecordNode.key;
|
||||
|
||||
//配置计算节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const preCreateRecordNodePom = new CreateRecordNode(page, preCreateRecordNodeTitle);
|
||||
await preCreateRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'calculation', exact: true }).click();
|
||||
const calculationNodeName = 'calculation' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Calculation-Calculation', { exact: true }).getByRole('textbox').fill(calculationNodeName);
|
||||
const calculationNode = new ClculationNode(page, calculationNodeName);
|
||||
const conditionNodeId = await calculationNode.node.locator('.workflow-node-id').innerText();
|
||||
await calculationNode.nodeConfigure.click();
|
||||
await calculationNode.formulaCalculationEngine.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Node result' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: preCreateRecordNodeTitle }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: '公司名称(单行文本)' }).click();
|
||||
await expect(page.getByLabel('textbox')).toHaveText(`Node result / ${preCreateRecordNodeTitle} / 公司名称(单行文本)`);
|
||||
await calculationNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const job = jobs.find((job) => job.nodeId.toString() === conditionNodeId);
|
||||
expect(job.result).toBe(triggerNodeCollectionRecordOne);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event adds data triggers, fetches data from front-end aggregation query nodes', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置前置聚合查询节点
|
||||
const preAggregateNodeTitle = 'Aggregate' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const preAggregateNodeData = {
|
||||
type: 'aggregate',
|
||||
upstreamId: null,
|
||||
branchIndex: null,
|
||||
title: preAggregateNodeTitle,
|
||||
config: {
|
||||
aggregator: 'count',
|
||||
associated: false,
|
||||
params: { field: 'id', filter: { $and: [] } },
|
||||
collection: triggerNodeCollectionName,
|
||||
},
|
||||
};
|
||||
const preAggregateNode = await apiCreateWorkflowNode(workflowId, preAggregateNodeData);
|
||||
const preAggregateNodeObj = JSON.parse(JSON.stringify(preAggregateNode));
|
||||
const preAggregateNodeId = preAggregateNodeObj.id;
|
||||
const getPreAggregateNode = await apiGetWorkflowNode(preAggregateNodeId);
|
||||
const preAggregateNodeKey = getPreAggregateNode.key;
|
||||
|
||||
//配置计算节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const preAggregateNodePom = new AggregateNode(page, preAggregateNodeTitle);
|
||||
await preAggregateNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'calculation', exact: true }).click();
|
||||
const calculationNodeName = 'calculation' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Calculation-Calculation', { exact: true }).getByRole('textbox').fill(calculationNodeName);
|
||||
const calculationNode = new ClculationNode(page, calculationNodeName);
|
||||
const conditionNodeId = await calculationNode.node.locator('.workflow-node-id').innerText();
|
||||
await calculationNode.nodeConfigure.click();
|
||||
await calculationNode.formulaCalculationEngine.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Node result' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: preAggregateNodeTitle }).click();
|
||||
await expect(page.getByLabel('textbox')).toHaveText(`Node result / ${preAggregateNodeTitle}`);
|
||||
await calculationNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const job = jobs.find((job) => job.nodeId.toString() === conditionNodeId);
|
||||
expect(job.result).toBe(1);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test.skip('Collection event add data trigger, get front manual node add form single line text data', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
// 创建触发器节点数据表
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
// 创建人工节点数据表
|
||||
const manualNodeAppendText = faker.string.alphanumeric(5);
|
||||
const manualNodeCollectionDisplayName = `自动>组织[普通表]${manualNodeAppendText}`;
|
||||
const manualNodeCollectionName = `tt_amt_org${manualNodeAppendText}`;
|
||||
const manualNodeFieldName = 'orgname';
|
||||
const manualNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), manualNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置前置人工节点新增数据表单
|
||||
const preManualNodeNodeTitle = 'Manual' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const preManualNodeNodeCustomFormTitle = 'Custom form' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const preManualNodeNodeData = { type: 'manual', upstreamId: null, branchIndex: null, title: 'Manual', config: {} };
|
||||
const preManualNodeNode = await apiCreateWorkflowNode(workflowId, preManualNodeNodeData);
|
||||
const preManualNodeNodeObj = JSON.parse(JSON.stringify(preManualNodeNode));
|
||||
const preManualNodeNodeId = preManualNodeNodeObj.id;
|
||||
const getPreManualNodeNode = await apiGetWorkflowNode(preManualNodeNodeId);
|
||||
const preAggregateNodeKey = getPreManualNodeNode.key;
|
||||
const preManualNodeNodeConfig = {
|
||||
config: {
|
||||
assignees: [1],
|
||||
schema: {
|
||||
tab1: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
title: '{{t("Manual", { ns: "workflow-manual" })}}',
|
||||
'x-component': 'Tabs.TabPane',
|
||||
'x-designer': 'Tabs.Designer',
|
||||
properties: {
|
||||
grid: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-initializer': 'AddBlockButton',
|
||||
name: 'grid',
|
||||
properties: {
|
||||
'59t231zx5vx': {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Row',
|
||||
properties: {
|
||||
'13do6fj5t73': {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Col',
|
||||
properties: {
|
||||
krb1bo0p486: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-decorator': 'FormBlockProvider',
|
||||
'x-decorator-props': {
|
||||
formType: 'create',
|
||||
resource: 'tt_mnt_org',
|
||||
collection: 'tt_mnt_org',
|
||||
},
|
||||
'x-designer': 'CreateFormDesigner',
|
||||
'x-component': 'CardItem',
|
||||
'x-component-props': {
|
||||
title: 'Create record4567',
|
||||
},
|
||||
properties: {
|
||||
kzqri0ib7ji: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'FormV2',
|
||||
'x-component-props': {
|
||||
useProps: '{{ useFormBlockProps }}',
|
||||
},
|
||||
properties: {
|
||||
grid: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-initializer': 'FormItemInitializers',
|
||||
name: 'grid',
|
||||
properties: {
|
||||
yt2rbpepdsl: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Row',
|
||||
properties: {
|
||||
eptw1hy20lm: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Col',
|
||||
properties: {
|
||||
orgname: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'string',
|
||||
name: 'orgname',
|
||||
'x-designer': 'FormItem.Designer',
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-collection-field': `${manualNodeCollectionName}.${manualNodeFieldName}`,
|
||||
'x-component-props': {},
|
||||
},
|
||||
},
|
||||
name: 'eptw1hy20lm',
|
||||
},
|
||||
},
|
||||
name: 'yt2rbpepdsl',
|
||||
},
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-initializer': 'AddActionButton',
|
||||
'x-component': 'ActionBar',
|
||||
'x-component-props': {
|
||||
layout: 'one-column',
|
||||
style: {
|
||||
marginTop: '1.5em',
|
||||
flexWrap: 'wrap',
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
resolve: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
title: '{{t("Continue the process", { ns: "workflow-manual" })}}',
|
||||
'x-decorator': 'ManualActionStatusProvider',
|
||||
'x-decorator-props': {
|
||||
value: 1,
|
||||
},
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
type: 'primary',
|
||||
useAction: '{{ useSubmit }}',
|
||||
},
|
||||
'x-designer': 'ManualActionDesigner',
|
||||
'x-designer-props': {},
|
||||
name: 'resolve',
|
||||
},
|
||||
},
|
||||
'x-decorator': 'ActionBarProvider',
|
||||
name: 'actions',
|
||||
},
|
||||
},
|
||||
name: 'kzqri0ib7ji',
|
||||
},
|
||||
},
|
||||
name: 'krb1bo0p486',
|
||||
},
|
||||
},
|
||||
name: '13do6fj5t73',
|
||||
},
|
||||
},
|
||||
name: '59t231zx5vx',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
name: 'tab1',
|
||||
},
|
||||
},
|
||||
forms: {
|
||||
kzqri0ib7ji: {
|
||||
type: 'create',
|
||||
title: preManualNodeNodeCustomFormTitle,
|
||||
actions: [
|
||||
{
|
||||
status: 1,
|
||||
key: 'resolve',
|
||||
},
|
||||
],
|
||||
collection: manualNodeCollectionName,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
await apiUpdateWorkflowNode(preManualNodeNodeId, preManualNodeNodeConfig);
|
||||
|
||||
//配置计算节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const preManualNodeNodePom = new AggregateNode(page, preManualNodeNodeTitle);
|
||||
await preManualNodeNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'calculation', exact: true }).click();
|
||||
const calculationNodeName = 'calculation' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Calculation-Calculation', { exact: true }).getByRole('textbox').fill(calculationNodeName);
|
||||
const calculationNode = new ClculationNode(page, calculationNodeName);
|
||||
const conditionNodeId = await calculationNode.node.locator('.workflow-node-id').innerText();
|
||||
await calculationNode.nodeConfigure.click();
|
||||
await calculationNode.formulaCalculationEngine.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Node result' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: preManualNodeNodeTitle }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: preManualNodeNodeCustomFormTitle }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: '公司名称(单行文本)' }).click();
|
||||
await expect(page.getByLabel('textbox')).toHaveText(
|
||||
`Node result / ${preManualNodeNodeTitle} / ${preManualNodeNodeCustomFormTitle} / 公司名称(单行文本)`,
|
||||
);
|
||||
await calculationNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
// api请求办理人工节点
|
||||
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const job = jobs.find((job) => job.nodeId.toString() === conditionNodeId);
|
||||
expect(job.result).toBe(triggerNodeCollectionRecordOne);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
@ -0,0 +1,755 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import {
|
||||
AggregateNode,
|
||||
ClculationNode,
|
||||
CollectionTriggerNode,
|
||||
CreateRecordNode,
|
||||
QueryRecordNode,
|
||||
apiCreateWorkflow,
|
||||
apiCreateWorkflowNode,
|
||||
apiDeleteWorkflow,
|
||||
apiGetWorkflow,
|
||||
apiGetWorkflowNode,
|
||||
apiGetWorkflowNodeExecutions,
|
||||
apiUpdateWorkflowNode,
|
||||
apiUpdateWorkflowTrigger,
|
||||
appendJsonCollectionName,
|
||||
generalWithNoRelationalFields,
|
||||
} from '@nocobase/plugin-workflow-test/e2e';
|
||||
import { expect, test } from '@nocobase/test/e2e';
|
||||
import { dayjs } from '@nocobase/utils';
|
||||
|
||||
test('Collection event add data trigger, get trigger node single line text variable', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置计算节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'calculation', exact: true }).click();
|
||||
const calculationNodeName = 'calculation' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Calculation-Calculation', { exact: true }).getByRole('textbox').fill(calculationNodeName);
|
||||
const calculationNode = new ClculationNode(page, calculationNodeName);
|
||||
await calculationNode.nodeConfigure.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByText('Trigger variables').click();
|
||||
await page.getByText('Trigger data').click();
|
||||
await page.getByText('公司名称(单行文本)').click();
|
||||
await expect(page.getByLabel('textbox')).toHaveText('Trigger variables / Trigger data / 公司名称(单行文本)');
|
||||
await calculationNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const getWorkflowNodeExecutionsObjResult = getWorkflowNodeExecutionsObj[0].jobs[0].result;
|
||||
expect(getWorkflowNodeExecutionsObjResult).toBe(triggerNodeCollectionRecordOne);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data triggers, get predecessor Math engine arithmetic node data', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置前置计算节点
|
||||
const preCalculationNodeTitle = 'calculation' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const preCalculationNodeData = {
|
||||
type: 'calculation',
|
||||
upstreamId: null,
|
||||
branchIndex: null,
|
||||
title: preCalculationNodeTitle,
|
||||
config: { engine: 'math.js', expression: '{{$context.data.orgname}}' },
|
||||
};
|
||||
const preCalculationNode = await apiCreateWorkflowNode(workflowId, preCalculationNodeData);
|
||||
const preCalculationNodeObj = JSON.parse(JSON.stringify(preCalculationNode));
|
||||
const preCalculationNodeId = preCalculationNodeObj.id;
|
||||
const getPreCalculationNode = await apiGetWorkflowNode(preCalculationNodeId);
|
||||
const preCalculationNodeKey = getPreCalculationNode.key;
|
||||
|
||||
//配置计算节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const preCalculationNodePom = new ClculationNode(page, preCalculationNodeTitle);
|
||||
await preCalculationNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'calculation', exact: true }).click();
|
||||
const calculationNodeName = 'calculation' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Calculation-Calculation', { exact: true }).getByRole('textbox').fill(calculationNodeName);
|
||||
const calculationNode = new ClculationNode(page, calculationNodeName);
|
||||
const conditionNodeId = await calculationNode.node.locator('.workflow-node-id').innerText();
|
||||
await calculationNode.nodeConfigure.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByText('Node result').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: preCalculationNodeTitle }).click();
|
||||
await expect(page.getByLabel('textbox')).toHaveText(`Node result / ${preCalculationNodeTitle}`);
|
||||
await calculationNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const job = jobs.find((job) => job.nodeId.toString() === conditionNodeId);
|
||||
expect(job.result).toBe(triggerNodeCollectionRecordOne);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection events add data triggers, get single line of text data for front query data nodes', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置前置查询节点
|
||||
const preQueryRecordNodeTitle = 'Query record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const preQueryRecordNodeData = {
|
||||
type: 'query',
|
||||
upstreamId: null,
|
||||
branchIndex: null,
|
||||
title: preQueryRecordNodeTitle,
|
||||
config: {
|
||||
collection: triggerNodeCollectionName,
|
||||
params: {
|
||||
filter: { $and: [{ id: { $eq: '{{$context.data.id}}' } }] },
|
||||
sort: [],
|
||||
page: 1,
|
||||
pageSize: 20,
|
||||
appends: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
const preQueryRecordNode = await apiCreateWorkflowNode(workflowId, preQueryRecordNodeData);
|
||||
const preQueryRecordNodeObj = JSON.parse(JSON.stringify(preQueryRecordNode));
|
||||
const preQueryRecordNodeId = preQueryRecordNodeObj.id;
|
||||
const getPreQueryRecordNode = await apiGetWorkflowNode(preQueryRecordNodeId);
|
||||
const preQueryRecordNodeKey = getPreQueryRecordNode.key;
|
||||
|
||||
//配置计算节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'calculation', exact: true }).click();
|
||||
const calculationNodeName = 'calculation' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Calculation-Calculation', { exact: true }).getByRole('textbox').fill(calculationNodeName);
|
||||
const calculationNode = new ClculationNode(page, calculationNodeName);
|
||||
const conditionNodeId = await calculationNode.node.locator('.workflow-node-id').innerText();
|
||||
await calculationNode.nodeConfigure.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Node result' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: preQueryRecordNodeTitle }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: '公司名称(单行文本)' }).click();
|
||||
await expect(page.getByLabel('textbox')).toHaveText(`Node result / ${preQueryRecordNodeTitle} / 公司名称(单行文本)`);
|
||||
await calculationNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const job = jobs.find((job) => job.nodeId.toString() === conditionNodeId);
|
||||
expect(job.result).toBe(triggerNodeCollectionRecordOne);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, get front added data node single line text data', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
// 创建新增数据节点数据表
|
||||
const createRecordNodeAppendText = faker.string.alphanumeric(6);
|
||||
const createRecordNodeCollectionDisplayName = `自动>组织[普通表]${createRecordNodeAppendText}`;
|
||||
const createRecordNodeCollectionName = `tt_amt_org${createRecordNodeAppendText}`;
|
||||
const createRecordNodeFieldName = 'orgname';
|
||||
const createRecordNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), createRecordNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置前置添加数据节点
|
||||
const preCreateRecordNodeTitle = 'Create record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const preCreateRecordNodeData = {
|
||||
type: 'create',
|
||||
upstreamId: null,
|
||||
branchIndex: null,
|
||||
title: preCreateRecordNodeTitle,
|
||||
config: {
|
||||
params: { values: { orgname: '{{$context.data.orgname}}' }, appends: [] },
|
||||
collection: createRecordNodeCollectionName,
|
||||
},
|
||||
};
|
||||
const preCreateRecordNode = await apiCreateWorkflowNode(workflowId, preCreateRecordNodeData);
|
||||
const preCreateRecordNodeObj = JSON.parse(JSON.stringify(preCreateRecordNode));
|
||||
const preCreateRecordNodeId = preCreateRecordNodeObj.id;
|
||||
const getPreCreateRecordNode = await apiGetWorkflowNode(preCreateRecordNodeId);
|
||||
const preCreateRecordNodeKey = getPreCreateRecordNode.key;
|
||||
|
||||
//配置计算节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const preCreateRecordNodePom = new CreateRecordNode(page, preCreateRecordNodeTitle);
|
||||
await preCreateRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'calculation', exact: true }).click();
|
||||
const calculationNodeName = 'calculation' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Calculation-Calculation', { exact: true }).getByRole('textbox').fill(calculationNodeName);
|
||||
const calculationNode = new ClculationNode(page, calculationNodeName);
|
||||
const conditionNodeId = await calculationNode.node.locator('.workflow-node-id').innerText();
|
||||
await calculationNode.nodeConfigure.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Node result' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: preCreateRecordNodeTitle }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: '公司名称(单行文本)' }).click();
|
||||
await expect(page.getByLabel('textbox')).toHaveText(`Node result / ${preCreateRecordNodeTitle} / 公司名称(单行文本)`);
|
||||
await calculationNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const job = jobs.find((job) => job.nodeId.toString() === conditionNodeId);
|
||||
expect(job.result).toBe(triggerNodeCollectionRecordOne);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event adds data triggers, fetches data from front-end aggregation query nodes', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置前置聚合查询节点
|
||||
const preAggregateNodeTitle = 'Aggregate' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const preAggregateNodeData = {
|
||||
type: 'aggregate',
|
||||
upstreamId: null,
|
||||
branchIndex: null,
|
||||
title: preAggregateNodeTitle,
|
||||
config: {
|
||||
aggregator: 'count',
|
||||
associated: false,
|
||||
params: { field: 'id', filter: { $and: [] } },
|
||||
collection: triggerNodeCollectionName,
|
||||
},
|
||||
};
|
||||
const preAggregateNode = await apiCreateWorkflowNode(workflowId, preAggregateNodeData);
|
||||
const preAggregateNodeObj = JSON.parse(JSON.stringify(preAggregateNode));
|
||||
const preAggregateNodeId = preAggregateNodeObj.id;
|
||||
const getPreAggregateNode = await apiGetWorkflowNode(preAggregateNodeId);
|
||||
const preAggregateNodeKey = getPreAggregateNode.key;
|
||||
|
||||
//配置计算节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const preAggregateNodePom = new AggregateNode(page, preAggregateNodeTitle);
|
||||
await preAggregateNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'calculation', exact: true }).click();
|
||||
const calculationNodeName = 'calculation' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Calculation-Calculation', { exact: true }).getByRole('textbox').fill(calculationNodeName);
|
||||
const calculationNode = new ClculationNode(page, calculationNodeName);
|
||||
const conditionNodeId = await calculationNode.node.locator('.workflow-node-id').innerText();
|
||||
await calculationNode.nodeConfigure.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Node result' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: preAggregateNodeTitle }).click();
|
||||
await expect(page.getByLabel('textbox')).toHaveText(`Node result / ${preAggregateNodeTitle}`);
|
||||
await calculationNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const job = jobs.find((job) => job.nodeId.toString() === conditionNodeId);
|
||||
expect(job.result).toBe(1);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test.skip('Collection event add data trigger, get front manual node add form single line text data', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
// 创建触发器节点数据表
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
// 创建人工节点数据表
|
||||
const manualNodeAppendText = faker.string.alphanumeric(5);
|
||||
const manualNodeCollectionDisplayName = `自动>组织[普通表]${manualNodeAppendText}`;
|
||||
const manualNodeCollectionName = `tt_amt_org${manualNodeAppendText}`;
|
||||
const manualNodeFieldName = 'orgname';
|
||||
const manualNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), manualNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置前置人工节点新增数据表单
|
||||
const preManualNodeNodeTitle = 'Manual' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const preManualNodeNodeCustomFormTitle = 'Custom form' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const preManualNodeNodeData = { type: 'manual', upstreamId: null, branchIndex: null, title: 'Manual', config: {} };
|
||||
const preManualNodeNode = await apiCreateWorkflowNode(workflowId, preManualNodeNodeData);
|
||||
const preManualNodeNodeObj = JSON.parse(JSON.stringify(preManualNodeNode));
|
||||
const preManualNodeNodeId = preManualNodeNodeObj.id;
|
||||
const getPreManualNodeNode = await apiGetWorkflowNode(preManualNodeNodeId);
|
||||
const preAggregateNodeKey = getPreManualNodeNode.key;
|
||||
const preManualNodeNodeConfig = {
|
||||
config: {
|
||||
assignees: [1],
|
||||
schema: {
|
||||
tab1: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
title: '{{t("Manual", { ns: "workflow-manual" })}}',
|
||||
'x-component': 'Tabs.TabPane',
|
||||
'x-designer': 'Tabs.Designer',
|
||||
properties: {
|
||||
grid: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-initializer': 'AddBlockButton',
|
||||
name: 'grid',
|
||||
properties: {
|
||||
'59t231zx5vx': {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Row',
|
||||
properties: {
|
||||
'13do6fj5t73': {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Col',
|
||||
properties: {
|
||||
krb1bo0p486: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-decorator': 'FormBlockProvider',
|
||||
'x-decorator-props': {
|
||||
formType: 'create',
|
||||
resource: 'tt_mnt_org',
|
||||
collection: 'tt_mnt_org',
|
||||
},
|
||||
'x-designer': 'CreateFormDesigner',
|
||||
'x-component': 'CardItem',
|
||||
'x-component-props': {
|
||||
title: 'Create record4567',
|
||||
},
|
||||
properties: {
|
||||
kzqri0ib7ji: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'FormV2',
|
||||
'x-component-props': {
|
||||
useProps: '{{ useFormBlockProps }}',
|
||||
},
|
||||
properties: {
|
||||
grid: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid',
|
||||
'x-initializer': 'FormItemInitializers',
|
||||
name: 'grid',
|
||||
properties: {
|
||||
yt2rbpepdsl: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Row',
|
||||
properties: {
|
||||
eptw1hy20lm: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-component': 'Grid.Col',
|
||||
properties: {
|
||||
orgname: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'string',
|
||||
name: 'orgname',
|
||||
'x-designer': 'FormItem.Designer',
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
'x-collection-field': `${manualNodeCollectionName}.${manualNodeFieldName}`,
|
||||
'x-component-props': {},
|
||||
},
|
||||
},
|
||||
name: 'eptw1hy20lm',
|
||||
},
|
||||
},
|
||||
name: 'yt2rbpepdsl',
|
||||
},
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
'x-initializer': 'AddActionButton',
|
||||
'x-component': 'ActionBar',
|
||||
'x-component-props': {
|
||||
layout: 'one-column',
|
||||
style: {
|
||||
marginTop: '1.5em',
|
||||
flexWrap: 'wrap',
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
resolve: {
|
||||
_isJSONSchemaObject: true,
|
||||
version: '2.0',
|
||||
type: 'void',
|
||||
title: '{{t("Continue the process", { ns: "workflow-manual" })}}',
|
||||
'x-decorator': 'ManualActionStatusProvider',
|
||||
'x-decorator-props': {
|
||||
value: 1,
|
||||
},
|
||||
'x-component': 'Action',
|
||||
'x-component-props': {
|
||||
type: 'primary',
|
||||
useAction: '{{ useSubmit }}',
|
||||
},
|
||||
'x-designer': 'ManualActionDesigner',
|
||||
'x-designer-props': {},
|
||||
name: 'resolve',
|
||||
},
|
||||
},
|
||||
'x-decorator': 'ActionBarProvider',
|
||||
name: 'actions',
|
||||
},
|
||||
},
|
||||
name: 'kzqri0ib7ji',
|
||||
},
|
||||
},
|
||||
name: 'krb1bo0p486',
|
||||
},
|
||||
},
|
||||
name: '13do6fj5t73',
|
||||
},
|
||||
},
|
||||
name: '59t231zx5vx',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
name: 'tab1',
|
||||
},
|
||||
},
|
||||
forms: {
|
||||
kzqri0ib7ji: {
|
||||
type: 'create',
|
||||
title: preManualNodeNodeCustomFormTitle,
|
||||
actions: [
|
||||
{
|
||||
status: 1,
|
||||
key: 'resolve',
|
||||
},
|
||||
],
|
||||
collection: manualNodeCollectionName,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
await apiUpdateWorkflowNode(preManualNodeNodeId, preManualNodeNodeConfig);
|
||||
|
||||
//配置计算节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const preManualNodeNodePom = new AggregateNode(page, preManualNodeNodeTitle);
|
||||
await preManualNodeNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'calculation', exact: true }).click();
|
||||
const calculationNodeName = 'calculation' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Calculation-Calculation', { exact: true }).getByRole('textbox').fill(calculationNodeName);
|
||||
const calculationNode = new ClculationNode(page, calculationNodeName);
|
||||
const conditionNodeId = await calculationNode.node.locator('.workflow-node-id').innerText();
|
||||
await calculationNode.nodeConfigure.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Node result' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: preManualNodeNodeTitle }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: preManualNodeNodeCustomFormTitle }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: '公司名称(单行文本)' }).click();
|
||||
await expect(page.getByLabel('textbox')).toHaveText(
|
||||
`Node result / ${preManualNodeNodeTitle} / ${preManualNodeNodeCustomFormTitle} / 公司名称(单行文本)`,
|
||||
);
|
||||
await calculationNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
// api请求办理人工节点
|
||||
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const job = jobs.find((job) => job.nodeId.toString() === conditionNodeId);
|
||||
expect(job.result).toBe(triggerNodeCollectionRecordOne);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
@ -0,0 +1,735 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import {
|
||||
CollectionTriggerNode,
|
||||
CreateWorkFlow,
|
||||
EditWorkFlow,
|
||||
WorkflowListRecords,
|
||||
apiCreateWorkflow,
|
||||
apiDeleteWorkflow,
|
||||
apiGetWorkflow,
|
||||
apiUpdateRecord,
|
||||
apiUpdateWorkflowTrigger,
|
||||
appendJsonCollectionName,
|
||||
generalWithNoRelationalFields,
|
||||
} from '@nocobase/plugin-workflow-test/e2e';
|
||||
import { expect, test } from '@nocobase/test/e2e';
|
||||
|
||||
test.describe('Configuration page to configure the Trigger node', () => {
|
||||
test('Add Data Trigger with No Filter', async ({ page, mockCollections, mockRecords }) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
//配置工作流触发器
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.nodeConfigure.click();
|
||||
await collectionTriggerNode.collectionDropDown.click();
|
||||
await page.getByRole('option', { name: triggerNodeCollectionDisplayName }).click();
|
||||
await collectionTriggerNode.triggerOnDropdown.click();
|
||||
await page.getByText('After record added', { exact: true }).click();
|
||||
await collectionTriggerNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Modify Data Without Filter Trigger', async ({ page, mockCollections, mockRecords }) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
//配置工作流触发器
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.nodeConfigure.click();
|
||||
await collectionTriggerNode.collectionDropDown.click();
|
||||
await page.getByRole('option', { name: triggerNodeCollectionDisplayName }).click();
|
||||
await collectionTriggerNode.triggerOnDropdown.click();
|
||||
await page.getByText('After record updated', { exact: true }).click();
|
||||
await collectionTriggerNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据,编辑数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
const recordId = triggerNodeCollectionRecords[0].id;
|
||||
await apiUpdateRecord(triggerNodeCollectionName, recordId, { orgname: triggerNodeCollectionRecordOne + '1' });
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('No-filter new or modified data triggers', async ({ page, mockCollections, mockRecords }) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
//配置工作流触发器
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.nodeConfigure.click();
|
||||
await collectionTriggerNode.collectionDropDown.click();
|
||||
await page.getByRole('option', { name: triggerNodeCollectionDisplayName }).click();
|
||||
await collectionTriggerNode.triggerOnDropdown.click();
|
||||
await page.getByText('After record added or updated', { exact: true }).click();
|
||||
await collectionTriggerNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据,编辑数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
const recordId = triggerNodeCollectionRecords[0].id;
|
||||
await apiUpdateRecord(triggerNodeCollectionName, recordId, { orgname: triggerNodeCollectionRecordOne + '1' });
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(2);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Filter radio fields equal to a specific value new data trigger', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
//配置工作流触发器
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.nodeConfigure.click();
|
||||
await collectionTriggerNode.collectionDropDown.click();
|
||||
await page.getByRole('option', { name: triggerNodeCollectionDisplayName }).click();
|
||||
await collectionTriggerNode.triggerOnDropdown.click();
|
||||
await page.getByText('After record added or updated', { exact: true }).click();
|
||||
// 设置触发器过滤条件
|
||||
await page.getByText('Add condition', { exact: true }).click();
|
||||
await page
|
||||
.getByLabel('block-item-Filter-workflows-Only triggers when match conditions')
|
||||
.getByRole('button', { name: 'Select field' })
|
||||
.click();
|
||||
await page.getByText('公司状态(下拉单选)').click();
|
||||
await page
|
||||
.getByLabel('block-item-Filter-workflows-Only triggers when match conditions')
|
||||
.getByTestId('select-single')
|
||||
.click();
|
||||
await page.getByRole('option', { name: '存续' }).click();
|
||||
await collectionTriggerNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据,编辑数据触发工作流
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [{ status_singleselect: '1' }]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Filter radio fields equal to a specific value Edit Data Trigger', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
//配置工作流触发器
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.nodeConfigure.click();
|
||||
await collectionTriggerNode.collectionDropDown.click();
|
||||
await page.getByRole('option', { name: triggerNodeCollectionDisplayName }).click();
|
||||
await collectionTriggerNode.triggerOnDropdown.click();
|
||||
await page.getByText('After record updated', { exact: true }).click();
|
||||
// 设置触发器过滤条件
|
||||
await page.getByText('Add condition', { exact: true }).click();
|
||||
await page
|
||||
.getByLabel('block-item-Filter-workflows-Only triggers when match conditions')
|
||||
.getByRole('button', { name: 'Select field' })
|
||||
.click();
|
||||
await page.getByText('公司状态(下拉单选)').click();
|
||||
await page
|
||||
.getByLabel('block-item-Filter-workflows-Only triggers when match conditions')
|
||||
.getByTestId('select-single')
|
||||
.click();
|
||||
await page.getByRole('option', { name: '存续' }).click();
|
||||
await collectionTriggerNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据,编辑数据触发工作流
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [{ status_singleselect: '1' }]);
|
||||
await page.waitForTimeout(1000);
|
||||
const recordId = triggerNodeCollectionRecords[0].id;
|
||||
await apiUpdateRecord(triggerNodeCollectionName, recordId, { orgname: '1' });
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:工作流成功触发
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Configuration Page Path Jump Workflow Management Page', () => {
|
||||
test('Collection event Workflow Configuration Page Path Jump Workflow Management Page', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
// const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
// const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
// const triggerNodeFieldName = 'orgname';
|
||||
// const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
// await mockCollections(appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText).collections);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
//配置工作流触发器
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// 2、测试步骤:跳转到工作流管理页面
|
||||
await page.getByRole('link', { name: 'Workflow' }).click();
|
||||
|
||||
// 3、预期结果:跳转路径正确
|
||||
await page.waitForLoadState('networkidle');
|
||||
expect(page.url()).toBe(`${process.env.APP_BASE_URL}/admin/settings/workflow`);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event Workflow History Version Configuration Page Path Jump Workflow Management Page', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel('more').click();
|
||||
await page.getByLabel('revision').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
//元素重复
|
||||
await page.getByLabel('version', { exact: true }).click();
|
||||
await page.getByLabel('version-1').click();
|
||||
await page.getByRole('link', { name: 'Workflow' }).click();
|
||||
|
||||
// 3、预期结果:跳转路径正确
|
||||
await page.waitForLoadState('networkidle');
|
||||
expect(page.url()).toBe(`${process.env.APP_BASE_URL}/admin/settings/workflow`);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event Workflow Execution Log Page Path Jump Workflow Management Page', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
const workflowListRecords = new WorkflowListRecords(page, workFlowName);
|
||||
await workflowListRecords.executionCountPopup.click();
|
||||
await page.getByText('View').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByRole('link', { name: 'Workflow', exact: true }).click();
|
||||
|
||||
// 3、预期结果:跳转路径正确
|
||||
await page.waitForLoadState('networkidle');
|
||||
expect(page.url()).toBe(`${process.env.APP_BASE_URL}/admin/settings/workflow`);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test.skip('Collection event Workflow Execution Log Page Path Jump Execution Log Screen', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
const workflowListRecords = new WorkflowListRecords(page, workFlowName);
|
||||
await expect(workflowListRecords.executionCountPopup).toHaveText('1');
|
||||
await workflowListRecords.executionCountPopup.click();
|
||||
await page.getByText('View').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
//跳转其他执行日志界面,元素无法定位
|
||||
|
||||
// 3、预期结果:跳转路径正确
|
||||
await page.waitForLoadState('networkidle');
|
||||
// expect(page.url()).toBe(`${process.env.APP_BASE_URL}/admin/settings/workflow`);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Configuration page version switching', () => {});
|
||||
|
||||
test.describe('Configuration page disable enable', () => {
|
||||
test('Collection Event Workflow Add Data Trigger Disable Do Not Trigger', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:触发次数为1
|
||||
let getWorkflow = await apiGetWorkflow(workflowId);
|
||||
let getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
let getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByRole('switch', { name: 'On Off' }).click();
|
||||
await mockRecords(triggerNodeCollectionName, [{ orgname: triggerNodeCollectionRecordOne + '1' }]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
getWorkflow = await apiGetWorkflow(workflowId);
|
||||
getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection Event Workflow Add Data Trigger Disable Enable Post Trigger', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: false,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:触发次数为1
|
||||
let getWorkflow = await apiGetWorkflow(workflowId);
|
||||
let getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
let getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(0);
|
||||
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByRole('switch', { name: 'On Off' }).click();
|
||||
await mockRecords(triggerNodeCollectionName, [{ orgname: triggerNodeCollectionRecordOne + '1' }]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
getWorkflow = await apiGetWorkflow(workflowId);
|
||||
getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Configuration page execution history', () => {});
|
||||
|
||||
test.describe('Configuration page copy to new version', () => {
|
||||
test('Copy the Collection event of the Configuration Trigger node', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.locator('.workflow-toolbar').getByLabel('more').hover();
|
||||
await page.getByLabel('revision').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
// 3、预期结果:新版本工作流配置内容同旧版本一样
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.nodeConfigure.click();
|
||||
await expect(page.getByRole('button', { name: triggerNodeCollectionDisplayName })).toBeVisible();
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Configuration page delete version', () => {});
|
||||
|
||||
test.describe('Node Add Modify Delete', () => {});
|
@ -0,0 +1,174 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import {
|
||||
CollectionTriggerNode,
|
||||
CreateWorkFlow,
|
||||
EditWorkFlow,
|
||||
WorkflowListRecords,
|
||||
apiCreateWorkflow,
|
||||
apiDeleteWorkflow,
|
||||
apiGetWorkflow,
|
||||
apiUpdateRecord,
|
||||
apiUpdateWorkflowTrigger,
|
||||
appendJsonCollectionName,
|
||||
generalWithNoRelationalFields,
|
||||
} from '@nocobase/plugin-workflow-test/e2e';
|
||||
import { expect, test } from '@nocobase/test/e2e';
|
||||
|
||||
test.describe('Filter', () => {
|
||||
test('filter workflow name', async ({ page }) => {
|
||||
//添加工作流
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
// 2、筛选工作流
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel('action-Filter.Action-Filter-filter-workflows').click();
|
||||
await page.getByRole('textbox').fill(workFlowName);
|
||||
await page.getByRole('button', { name: 'Submit' }).click();
|
||||
|
||||
// 3、预期结果:列表中出现筛选的工作流
|
||||
await expect(page.getByText(workFlowName)).toBeAttached();
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Add new', () => {
|
||||
test('add new Collection event', async ({ page }) => {
|
||||
// 添加工作流
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel('action-Action-Add new-workflows').click();
|
||||
const createWorkFlow = new CreateWorkFlow(page);
|
||||
const workFlowName = faker.string.alphanumeric(5);
|
||||
await createWorkFlow.name.fill(workFlowName);
|
||||
await createWorkFlow.triggerType.click();
|
||||
await page.getByRole('option', { name: 'Collection event' }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
|
||||
// 3、预期结果:列表中出现新建的工作流
|
||||
await expect(page.getByText(workFlowName)).toBeVisible();
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await page.getByLabel('action-Filter.Action-Filter-filter-workflows').click();
|
||||
await page.getByRole('textbox').fill(workFlowName);
|
||||
await page.getByRole('button', { name: 'Submit' }).click();
|
||||
await page.getByLabel(`action-Action.Link-Delete-workflows-${workFlowName}`).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
await expect(page.getByText(workFlowName)).toBeHidden();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Sync', () => {});
|
||||
|
||||
test.describe('Delete', () => {
|
||||
test('delete Collection event', async ({ page }) => {
|
||||
//添加工作流
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
// 删除工作流
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel('action-Filter.Action-Filter-filter-workflows').click();
|
||||
await page.getByRole('textbox').fill(workFlowName);
|
||||
await page.getByRole('button', { name: 'Submit' }).click();
|
||||
await page.getByLabel(`action-Action.Link-Delete-workflows-${workFlowName}`).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
|
||||
// 3、预期结果:列表中出现筛选的工作流
|
||||
await expect(page.getByText(workFlowName)).toBeHidden();
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Edit', () => {
|
||||
test('edit Collection event name', async ({ page }) => {
|
||||
//添加工作流
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
let workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
// 编辑工作流
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel(`action-Action.Link-Edit-workflows-${workFlowName}`).click();
|
||||
const editWorkFlow = new EditWorkFlow(page, workFlowName);
|
||||
workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
await editWorkFlow.name.fill(workFlowName);
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
// 3、预期结果:编辑成功,列表中出现编辑后的工作流
|
||||
await expect(page.getByText(workFlowName)).toBeAttached();
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Duplicate', () => {
|
||||
test('Duplicate Collection event triggers with only unconfigured trigger nodes', async ({ page }) => {
|
||||
//添加工作流
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
|
||||
// 2、复制工作流
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel(`action-Action.Link-Duplicate-workflows-${workFlowName}`).click();
|
||||
await page.getByLabel(`action-Action-Submit-workflows-${workFlowName}`).click();
|
||||
|
||||
// 3、预期结果:列表中出现筛选的工作流
|
||||
await expect(page.getByText(`${workFlowName} copy`)).toBeAttached();
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await page.getByLabel(`action-Action.Link-Delete-workflows-${workFlowName} copy`).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
await expect(page.getByText(`${workFlowName} copy`)).toBeHidden();
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Executed', () => {});
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,481 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import {
|
||||
ClculationNode,
|
||||
CollectionTriggerNode,
|
||||
ConditionBranchNode,
|
||||
ConditionYesNode,
|
||||
QueryRecordNode,
|
||||
apiCreateWorkflow,
|
||||
apiCreateWorkflowNode,
|
||||
apiDeleteWorkflow,
|
||||
apiGetWorkflow,
|
||||
apiGetWorkflowNode,
|
||||
apiGetWorkflowNodeExecutions,
|
||||
apiUpdateWorkflowTrigger,
|
||||
appendJsonCollectionName,
|
||||
generalWithNoRelationalFields,
|
||||
} from '@nocobase/plugin-workflow-test/e2e';
|
||||
import { expect, test } from '@nocobase/test/e2e';
|
||||
import { dayjs } from '@nocobase/utils';
|
||||
|
||||
test('Collection event add data trigger, determine trigger node integer field variable is equal to an equal constant, pass.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'staffnum';
|
||||
const triggerNodeFieldDisplayName = '员工人数(整数)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
const conditionNodeId = await conditionNode.node.locator('.workflow-node-id').innerText();
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await conditionNode.mathRadio.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await page.getByLabel('textbox').focus();
|
||||
const conditionalRightConstant = faker.number.int();
|
||||
await page.keyboard.type(`==${conditionalRightConstant}`);
|
||||
await expect(page.getByLabel('textbox')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}==${conditionalRightConstant}`,
|
||||
);
|
||||
await conditionNode.submitButton.click();
|
||||
//添加No分支计算节点
|
||||
await conditionNode.addNoBranchNode.click();
|
||||
await page.getByRole('button', { name: 'calculation', exact: true }).click();
|
||||
const noBranchcalCulationNodeName = 'calculation' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page
|
||||
.getByLabel('Calculation-Calculation', { exact: true })
|
||||
.getByRole('textbox')
|
||||
.fill(noBranchcalCulationNodeName);
|
||||
const noBranchcalCulationNode = new ClculationNode(page, noBranchcalCulationNodeName);
|
||||
const noBranchcalCulationNodeId = await noBranchcalCulationNode.node.locator('.workflow-node-id').innerText();
|
||||
await noBranchcalCulationNode.nodeConfigure.click();
|
||||
await page.getByLabel('textbox').fill('0');
|
||||
await noBranchcalCulationNode.submitButton.click();
|
||||
//添加Yes分支计算节点
|
||||
await conditionNode.addYesBranchNode.click();
|
||||
await page.getByRole('button', { name: 'calculation', exact: true }).click();
|
||||
const yesBranchcalCulationNodeName = 'calculation' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page
|
||||
.getByLabel('Calculation-Calculation', { exact: true })
|
||||
.getByRole('textbox')
|
||||
.fill(yesBranchcalCulationNodeName);
|
||||
const yesBranchcalCulationNode = new ClculationNode(page, yesBranchcalCulationNodeName);
|
||||
const yesBranchcalCulationNodeId = await yesBranchcalCulationNode.node.locator('.workflow-node-id').innerText();
|
||||
await yesBranchcalCulationNode.nodeConfigure.click();
|
||||
await page.getByLabel('textbox').fill('1');
|
||||
await yesBranchcalCulationNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = conditionalRightConstant;
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ staffnum: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,判断节点true
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const conditionNodeJob = jobs.find((job) => job.nodeId.toString() === conditionNodeId);
|
||||
expect(conditionNodeJob.result).toBe(true);
|
||||
const noBranchcalCulationNodeJob = jobs.find((job) => job.nodeId.toString() === noBranchcalCulationNodeId);
|
||||
expect(noBranchcalCulationNodeJob).toBe(undefined);
|
||||
const yesBranchcalCulationNodeJob = jobs.find((job) => job.nodeId.toString() === yesBranchcalCulationNodeId);
|
||||
expect(yesBranchcalCulationNodeJob.result).toBe(1);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event Add Data Trigger, determines that the trigger node integer field variable is equal to an unequal constant, fails.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'staffnum';
|
||||
const triggerNodeFieldDisplayName = '员工人数(整数)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
const conditionNodeId = await conditionNode.node.locator('.workflow-node-id').innerText();
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await conditionNode.mathRadio.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await page.getByLabel('textbox').focus();
|
||||
const conditionalRightConstant = faker.number.int();
|
||||
await page.keyboard.type(`==${conditionalRightConstant}`);
|
||||
await expect(page.getByLabel('textbox')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}==${conditionalRightConstant}`,
|
||||
);
|
||||
await conditionNode.submitButton.click();
|
||||
//添加No分支计算节点
|
||||
await conditionNode.addNoBranchNode.click();
|
||||
await page.getByRole('button', { name: 'calculation', exact: true }).click();
|
||||
const noBranchcalCulationNodeName = 'calculation' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page
|
||||
.getByLabel('Calculation-Calculation', { exact: true })
|
||||
.getByRole('textbox')
|
||||
.fill(noBranchcalCulationNodeName);
|
||||
const noBranchcalCulationNode = new ClculationNode(page, noBranchcalCulationNodeName);
|
||||
const noBranchcalCulationNodeId = await noBranchcalCulationNode.node.locator('.workflow-node-id').innerText();
|
||||
await noBranchcalCulationNode.nodeConfigure.click();
|
||||
await page.getByLabel('textbox').fill('0');
|
||||
await noBranchcalCulationNode.submitButton.click();
|
||||
//添加Yes分支计算节点
|
||||
await conditionNode.addYesBranchNode.click();
|
||||
await page.getByRole('button', { name: 'calculation', exact: true }).click();
|
||||
const yesBranchcalCulationNodeName = 'calculation' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page
|
||||
.getByLabel('Calculation-Calculation', { exact: true })
|
||||
.getByRole('textbox')
|
||||
.fill(yesBranchcalCulationNodeName);
|
||||
const yesBranchcalCulationNode = new ClculationNode(page, yesBranchcalCulationNodeName);
|
||||
const yesBranchcalCulationNodeId = await yesBranchcalCulationNode.node.locator('.workflow-node-id').innerText();
|
||||
await yesBranchcalCulationNode.nodeConfigure.click();
|
||||
await page.getByLabel('textbox').fill('1');
|
||||
await yesBranchcalCulationNode.submitButton.click();
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordTwo = faker.number.int();
|
||||
await mockRecords(triggerNodeCollectionName, [{ staffnum: triggerNodeCollectionRecordTwo }]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,判断节点false
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const conditionNodeJob = jobs.find((job) => job.nodeId.toString() === conditionNodeId);
|
||||
expect(conditionNodeJob.result).toBe(false);
|
||||
const noBranchcalCulationNodeJob = jobs.find((job) => job.nodeId.toString() === noBranchcalCulationNodeId);
|
||||
expect(noBranchcalCulationNodeJob.result).toBe(0);
|
||||
const yesBranchcalCulationNodeJob = jobs.find((job) => job.nodeId.toString() === yesBranchcalCulationNodeId);
|
||||
expect(yesBranchcalCulationNodeJob).toBe(undefined);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event Add Data Trigger, determines that the trigger node integer field variable is not equal to an equal constant, fails.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'staffnum';
|
||||
const triggerNodeFieldDisplayName = '员工人数(整数)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
const conditionNodeId = await conditionNode.node.locator('.workflow-node-id').innerText();
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await conditionNode.mathRadio.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await page.getByLabel('textbox').focus();
|
||||
const conditionalRightConstant = faker.number.int();
|
||||
await page.keyboard.type(`!=${conditionalRightConstant}`);
|
||||
await expect(page.getByLabel('textbox')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}!=${conditionalRightConstant}`,
|
||||
);
|
||||
await conditionNode.submitButton.click();
|
||||
//添加No分支计算节点
|
||||
await conditionNode.addNoBranchNode.click();
|
||||
await page.getByRole('button', { name: 'calculation', exact: true }).click();
|
||||
const noBranchcalCulationNodeName = 'calculation' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page
|
||||
.getByLabel('Calculation-Calculation', { exact: true })
|
||||
.getByRole('textbox')
|
||||
.fill(noBranchcalCulationNodeName);
|
||||
const noBranchcalCulationNode = new ClculationNode(page, noBranchcalCulationNodeName);
|
||||
const noBranchcalCulationNodeId = await noBranchcalCulationNode.node.locator('.workflow-node-id').innerText();
|
||||
await noBranchcalCulationNode.nodeConfigure.click();
|
||||
await page.getByLabel('textbox').fill('0');
|
||||
await noBranchcalCulationNode.submitButton.click();
|
||||
//添加Yes分支计算节点
|
||||
await conditionNode.addYesBranchNode.click();
|
||||
await page.getByRole('button', { name: 'calculation', exact: true }).click();
|
||||
const yesBranchcalCulationNodeName = 'calculation' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page
|
||||
.getByLabel('Calculation-Calculation', { exact: true })
|
||||
.getByRole('textbox')
|
||||
.fill(yesBranchcalCulationNodeName);
|
||||
const yesBranchcalCulationNode = new ClculationNode(page, yesBranchcalCulationNodeName);
|
||||
const yesBranchcalCulationNodeId = await yesBranchcalCulationNode.node.locator('.workflow-node-id').innerText();
|
||||
await yesBranchcalCulationNode.nodeConfigure.click();
|
||||
await page.getByLabel('textbox').fill('1');
|
||||
await yesBranchcalCulationNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordTwo = conditionalRightConstant;
|
||||
await mockRecords(triggerNodeCollectionName, [{ staffnum: triggerNodeCollectionRecordTwo }]);
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:工作流成功触发,判断节点false
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const conditionNodeJob = jobs.find((job) => job.nodeId.toString() === conditionNodeId);
|
||||
expect(conditionNodeJob.result).toBe(false);
|
||||
const noBranchcalCulationNodeJob = jobs.find((job) => job.nodeId.toString() === noBranchcalCulationNodeId);
|
||||
expect(noBranchcalCulationNodeJob.result).toBe(0);
|
||||
const yesBranchcalCulationNodeJob = jobs.find((job) => job.nodeId.toString() === yesBranchcalCulationNodeId);
|
||||
expect(yesBranchcalCulationNodeJob).toBe(undefined);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, determines that the trigger node integer field variable is not equal to an unequal constant, passes.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'staffnum';
|
||||
const triggerNodeFieldDisplayName = '员工人数(整数)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('branch').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionBranchNode(page, conditionNodeName);
|
||||
const conditionNodeId = await conditionNode.node.locator('.workflow-node-id').innerText();
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await conditionNode.mathRadio.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await page.getByLabel('textbox').focus();
|
||||
const conditionalRightConstant = faker.number.int();
|
||||
await page.keyboard.type(`!=${conditionalRightConstant}`);
|
||||
await expect(page.getByLabel('textbox')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}!=${conditionalRightConstant}`,
|
||||
);
|
||||
await conditionNode.submitButton.click();
|
||||
//添加No分支计算节点
|
||||
await conditionNode.addNoBranchNode.click();
|
||||
await page.getByRole('button', { name: 'calculation', exact: true }).click();
|
||||
const noBranchcalCulationNodeName = 'calculation' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page
|
||||
.getByLabel('Calculation-Calculation', { exact: true })
|
||||
.getByRole('textbox')
|
||||
.fill(noBranchcalCulationNodeName);
|
||||
const noBranchcalCulationNode = new ClculationNode(page, noBranchcalCulationNodeName);
|
||||
const noBranchcalCulationNodeId = await noBranchcalCulationNode.node.locator('.workflow-node-id').innerText();
|
||||
await noBranchcalCulationNode.nodeConfigure.click();
|
||||
await page.getByLabel('textbox').fill('0');
|
||||
await noBranchcalCulationNode.submitButton.click();
|
||||
//添加Yes分支计算节点
|
||||
await conditionNode.addYesBranchNode.click();
|
||||
await page.getByRole('button', { name: 'calculation', exact: true }).click();
|
||||
const yesBranchcalCulationNodeName = 'calculation' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page
|
||||
.getByLabel('Calculation-Calculation', { exact: true })
|
||||
.getByRole('textbox')
|
||||
.fill(yesBranchcalCulationNodeName);
|
||||
const yesBranchcalCulationNode = new ClculationNode(page, yesBranchcalCulationNodeName);
|
||||
const yesBranchcalCulationNodeId = await yesBranchcalCulationNode.node.locator('.workflow-node-id').innerText();
|
||||
await yesBranchcalCulationNode.nodeConfigure.click();
|
||||
await page.getByLabel('textbox').fill('1');
|
||||
await yesBranchcalCulationNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.number.int();
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ staffnum: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,判断节点true
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const conditionNodeJob = jobs.find((job) => job.nodeId.toString() === conditionNodeId);
|
||||
expect(conditionNodeJob.result).toBe(true);
|
||||
const noBranchcalCulationNodeJob = jobs.find((job) => job.nodeId.toString() === noBranchcalCulationNodeId);
|
||||
expect(noBranchcalCulationNodeJob).toBe(undefined);
|
||||
const yesBranchcalCulationNodeJob = jobs.find((job) => job.nodeId.toString() === yesBranchcalCulationNodeId);
|
||||
expect(yesBranchcalCulationNodeJob.result).toBe(1);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
@ -0,0 +1,812 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import {
|
||||
ClculationNode,
|
||||
CollectionTriggerNode,
|
||||
ConditionBranchNode,
|
||||
ConditionYesNode,
|
||||
QueryRecordNode,
|
||||
apiCreateWorkflow,
|
||||
apiCreateWorkflowNode,
|
||||
apiDeleteWorkflow,
|
||||
apiGetWorkflow,
|
||||
apiGetWorkflowNode,
|
||||
apiGetWorkflowNodeExecutions,
|
||||
apiUpdateWorkflowTrigger,
|
||||
appendJsonCollectionName,
|
||||
generalWithNoRelationalFields,
|
||||
} from '@nocobase/plugin-workflow-test/e2e';
|
||||
import { expect, test } from '@nocobase/test/e2e';
|
||||
import { dayjs } from '@nocobase/utils';
|
||||
|
||||
test('Collection event add data trigger, determines that the trigger node single line text field variable is equal to an equal constant, passes.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
const conditionNodeId = await conditionNode.node.locator('.workflow-node-id').innerText();
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await page.getByText('Add condition', { exact: true }).click();
|
||||
await page.getByLabel('variable-button').first().click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByText(triggerNodeFieldDisplayName).click();
|
||||
await expect(page.getByLabel('variable-tag')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}`,
|
||||
);
|
||||
const conditionalRightConstant = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('variable-constant').fill(conditionalRightConstant);
|
||||
await conditionNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = conditionalRightConstant;
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const getWorkflowNodeExecutionsObjResult = getWorkflowNodeExecutionsObj[0].jobs[0].result;
|
||||
expect(getWorkflowNodeExecutionsObjResult).toBe(true);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, determines that the trigger node single line text field variable is equal to an unequal constant, fails.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
const conditionNodeId = await conditionNode.node.locator('.workflow-node-id').innerText();
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await page.getByText('Add condition', { exact: true }).click();
|
||||
await page.getByLabel('variable-button').first().click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByText(triggerNodeFieldDisplayName).click();
|
||||
await expect(page.getByLabel('variable-tag')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}`,
|
||||
);
|
||||
const conditionalRightConstant = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('variable-constant').fill(conditionalRightConstant);
|
||||
await conditionNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const getWorkflowNodeExecutionsObjResult = getWorkflowNodeExecutionsObj[0].jobs[0].result;
|
||||
expect(getWorkflowNodeExecutionsObjResult).toBe(false);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event Add Data Trigger, determines that the trigger node single line text field variable is not equal to an equal constant, fails.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
const conditionNodeId = await conditionNode.node.locator('.workflow-node-id').innerText();
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await page.getByText('Add condition', { exact: true }).click();
|
||||
await page.getByLabel('variable-button').first().click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByText(triggerNodeFieldDisplayName).click();
|
||||
await expect(page.getByLabel('variable-tag')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}`,
|
||||
);
|
||||
await page.getByLabel('select-operator-calc').first().click();
|
||||
await page.getByRole('option', { name: '≠' }).click();
|
||||
const conditionalRightConstant = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('variable-constant').fill(conditionalRightConstant);
|
||||
await conditionNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = conditionalRightConstant;
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const getWorkflowNodeExecutionsObjResult = getWorkflowNodeExecutionsObj[0].jobs[0].result;
|
||||
expect(getWorkflowNodeExecutionsObjResult).toBe(false);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, determines that the trigger node single line text field variable is not equal to an unequal constant, passes.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
const conditionNodeId = await conditionNode.node.locator('.workflow-node-id').innerText();
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await page.getByText('Add condition', { exact: true }).click();
|
||||
await page.getByLabel('variable-button').first().click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByText(triggerNodeFieldDisplayName).click();
|
||||
await expect(page.getByLabel('variable-tag')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}`,
|
||||
);
|
||||
await page.getByLabel('select-operator-calc').first().click();
|
||||
await page.getByRole('option', { name: '≠' }).click();
|
||||
const conditionalRightConstant = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('variable-constant').fill(conditionalRightConstant);
|
||||
await conditionNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = conditionalRightConstant + '1';
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const getWorkflowNodeExecutionsObjResult = getWorkflowNodeExecutionsObj[0].jobs[0].result;
|
||||
expect(getWorkflowNodeExecutionsObjResult).toBe(true);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, determine trigger node integer variable equal to query node equal integer variable, pass.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'staffnum';
|
||||
const triggerNodeFieldDisplayName = '员工人数(整数)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置前置查询节点
|
||||
const preQueryRecordNodeTitle = 'Query record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const preQueryRecordNodeData = {
|
||||
type: 'query',
|
||||
upstreamId: null,
|
||||
branchIndex: null,
|
||||
title: preQueryRecordNodeTitle,
|
||||
config: {
|
||||
collection: triggerNodeCollectionName,
|
||||
params: {
|
||||
filter: { $and: [{ id: { $eq: '{{$context.data.id}}' } }] },
|
||||
sort: [],
|
||||
page: 1,
|
||||
pageSize: 20,
|
||||
appends: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
const preQueryRecordNode = await apiCreateWorkflowNode(workflowId, preQueryRecordNodeData);
|
||||
const preQueryRecordNodeObj = JSON.parse(JSON.stringify(preQueryRecordNode));
|
||||
const preQueryRecordNodeId = preQueryRecordNodeObj.id;
|
||||
const getPreQueryRecordNode = await apiGetWorkflowNode(preQueryRecordNodeId);
|
||||
const preQueryRecordNodeKey = getPreQueryRecordNode.key;
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
const conditionNodeId = await conditionNode.node.locator('.workflow-node-id').innerText();
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await page.getByText('Add condition', { exact: true }).click();
|
||||
await page.getByLabel('variable-button').first().click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await expect(page.getByLabel('variable-tag')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}`,
|
||||
);
|
||||
await page.getByLabel('variable-button').nth(1).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Node result' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: preQueryRecordNodeTitle }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await expect(page.getByLabel('variable-tag').nth(1)).toHaveText(
|
||||
`Node result / ${preQueryRecordNodeTitle} / ${triggerNodeFieldDisplayName}`,
|
||||
);
|
||||
await conditionNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.number.int();
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ staffnum: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const job = jobs.find((job) => job.nodeId.toString() === conditionNodeId);
|
||||
expect(job.result).toBe(true);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, determine trigger node integer variable is equal to query node not equal integer variable, not pass.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'staffnum';
|
||||
const triggerNodeFieldDisplayName = '员工人数(整数)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
const triggerNodeCollectionRecordOne = faker.number.int();
|
||||
await mockRecords(triggerNodeCollectionName, [{ staffnum: triggerNodeCollectionRecordOne }]);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置前置查询节点
|
||||
const preQueryRecordNodeTitle = 'Query record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const preQueryRecordNodeData = {
|
||||
type: 'query',
|
||||
upstreamId: null,
|
||||
branchIndex: null,
|
||||
title: preQueryRecordNodeTitle,
|
||||
config: {
|
||||
collection: triggerNodeCollectionName,
|
||||
params: {
|
||||
filter: { $and: [{ id: { $ne: '{{$context.data.id}}' } }] },
|
||||
sort: [],
|
||||
page: 1,
|
||||
pageSize: 20,
|
||||
appends: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
const preQueryRecordNode = await apiCreateWorkflowNode(workflowId, preQueryRecordNodeData);
|
||||
const preQueryRecordNodeObj = JSON.parse(JSON.stringify(preQueryRecordNode));
|
||||
const preQueryRecordNodeId = preQueryRecordNodeObj.id;
|
||||
const getPreQueryRecordNode = await apiGetWorkflowNode(preQueryRecordNodeId);
|
||||
const preQueryRecordNodeKey = getPreQueryRecordNode.key;
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
const conditionNodeId = await conditionNode.node.locator('.workflow-node-id').innerText();
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await page.getByText('Add condition', { exact: true }).click();
|
||||
await page.getByLabel('variable-button').first().click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await expect(page.getByLabel('variable-tag')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}`,
|
||||
);
|
||||
await page.getByLabel('variable-button').nth(1).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Node result' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: preQueryRecordNodeTitle }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await expect(page.getByLabel('variable-tag').nth(1)).toHaveText(
|
||||
`Node result / ${preQueryRecordNodeTitle} / ${triggerNodeFieldDisplayName}`,
|
||||
);
|
||||
await conditionNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordTwo = faker.number.int();
|
||||
await mockRecords(triggerNodeCollectionName, [{ staffnum: triggerNodeCollectionRecordTwo }]);
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const job = jobs.find((job) => job.nodeId.toString() === conditionNodeId);
|
||||
expect(job.result).toBe(false);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, determine trigger node integer variable is not equal to query node equal integer variable, not pass.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'staffnum';
|
||||
const triggerNodeFieldDisplayName = '员工人数(整数)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置前置查询节点
|
||||
const preQueryRecordNodeTitle = 'Query record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const preQueryRecordNodeData = {
|
||||
type: 'query',
|
||||
upstreamId: null,
|
||||
branchIndex: null,
|
||||
title: preQueryRecordNodeTitle,
|
||||
config: {
|
||||
collection: triggerNodeCollectionName,
|
||||
params: {
|
||||
filter: { $and: [{ id: { $eq: '{{$context.data.id}}' } }] },
|
||||
sort: [],
|
||||
page: 1,
|
||||
pageSize: 20,
|
||||
appends: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
const preQueryRecordNode = await apiCreateWorkflowNode(workflowId, preQueryRecordNodeData);
|
||||
const preQueryRecordNodeObj = JSON.parse(JSON.stringify(preQueryRecordNode));
|
||||
const preQueryRecordNodeId = preQueryRecordNodeObj.id;
|
||||
const getPreQueryRecordNode = await apiGetWorkflowNode(preQueryRecordNodeId);
|
||||
const preQueryRecordNodeKey = getPreQueryRecordNode.key;
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
const conditionNodeId = await conditionNode.node.locator('.workflow-node-id').innerText();
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await page.getByText('Add condition', { exact: true }).click();
|
||||
await page.getByLabel('variable-button').first().click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await expect(page.getByLabel('variable-tag')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}`,
|
||||
);
|
||||
await page.getByLabel('select-operator-calc').first().click();
|
||||
await page.getByRole('option', { name: '≠' }).click();
|
||||
await page.getByLabel('variable-button').nth(1).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Node result' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: preQueryRecordNodeTitle }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await expect(page.getByLabel('variable-tag').nth(1)).toHaveText(
|
||||
`Node result / ${preQueryRecordNodeTitle} / ${triggerNodeFieldDisplayName}`,
|
||||
);
|
||||
await conditionNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.number.int();
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ staffnum: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const job = jobs.find((job) => job.nodeId.toString() === conditionNodeId);
|
||||
expect(job.result).toBe(false);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, determine trigger node integer variable is not equal to query node not equal integer variable, pass.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'staffnum';
|
||||
const triggerNodeFieldDisplayName = '员工人数(整数)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
const triggerNodeCollectionRecordOne = faker.number.int();
|
||||
await mockRecords(triggerNodeCollectionName, [{ staffnum: triggerNodeCollectionRecordOne }]);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置前置查询节点
|
||||
const preQueryRecordNodeTitle = 'Query record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const preQueryRecordNodeData = {
|
||||
type: 'query',
|
||||
upstreamId: null,
|
||||
branchIndex: null,
|
||||
title: preQueryRecordNodeTitle,
|
||||
config: {
|
||||
collection: triggerNodeCollectionName,
|
||||
params: {
|
||||
filter: { $and: [{ id: { $ne: '{{$context.data.id}}' } }] },
|
||||
sort: [],
|
||||
page: 1,
|
||||
pageSize: 20,
|
||||
appends: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
const preQueryRecordNode = await apiCreateWorkflowNode(workflowId, preQueryRecordNodeData);
|
||||
const preQueryRecordNodeObj = JSON.parse(JSON.stringify(preQueryRecordNode));
|
||||
const preQueryRecordNodeId = preQueryRecordNodeObj.id;
|
||||
const getPreQueryRecordNode = await apiGetWorkflowNode(preQueryRecordNodeId);
|
||||
const preQueryRecordNodeKey = getPreQueryRecordNode.key;
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
const conditionNodeId = await conditionNode.node.locator('.workflow-node-id').innerText();
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await page.getByText('Add condition', { exact: true }).click();
|
||||
await page.getByLabel('variable-button').first().click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await expect(page.getByLabel('variable-tag')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}`,
|
||||
);
|
||||
await page.getByLabel('select-operator-calc').first().click();
|
||||
await page.getByRole('option', { name: '≠' }).click();
|
||||
await page.getByLabel('variable-button').nth(1).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Node result' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: preQueryRecordNodeTitle }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await expect(page.getByLabel('variable-tag').nth(1)).toHaveText(
|
||||
`Node result / ${preQueryRecordNodeTitle} / ${triggerNodeFieldDisplayName}`,
|
||||
);
|
||||
await conditionNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordTwo = faker.number.int();
|
||||
await mockRecords(triggerNodeCollectionName, [{ staffnum: triggerNodeCollectionRecordTwo }]);
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const job = jobs.find((job) => job.nodeId.toString() === conditionNodeId);
|
||||
expect(job.result).toBe(true);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
@ -0,0 +1,790 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import {
|
||||
ClculationNode,
|
||||
CollectionTriggerNode,
|
||||
ConditionBranchNode,
|
||||
ConditionYesNode,
|
||||
QueryRecordNode,
|
||||
apiCreateWorkflow,
|
||||
apiCreateWorkflowNode,
|
||||
apiDeleteWorkflow,
|
||||
apiGetWorkflow,
|
||||
apiGetWorkflowNode,
|
||||
apiGetWorkflowNodeExecutions,
|
||||
apiUpdateWorkflowTrigger,
|
||||
appendJsonCollectionName,
|
||||
generalWithNoRelationalFields,
|
||||
} from '@nocobase/plugin-workflow-test/e2e';
|
||||
import { expect, test } from '@nocobase/test/e2e';
|
||||
import { dayjs } from '@nocobase/utils';
|
||||
|
||||
test('Collection event Add Data Trigger, Formula engine, determines that the trigger node single line text field variable is equal to an equal constant, passes.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await conditionNode.formulaRadio.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await page.getByLabel('textbox').focus();
|
||||
const conditionalRightConstant = faker.string.alphanumeric(10);
|
||||
await page.keyboard.type(`=='${conditionalRightConstant}'`);
|
||||
await expect(page.getByLabel('textbox')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}=='${conditionalRightConstant}'`,
|
||||
);
|
||||
await conditionNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = conditionalRightConstant;
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const getWorkflowNodeExecutionsObjResult = getWorkflowNodeExecutionsObj[0].jobs[0].result;
|
||||
expect(getWorkflowNodeExecutionsObjResult).toBe(true);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event Add Data Trigger, Formula engine, determines that the trigger node single line text field variable is equal to an unequal constant, fails.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await conditionNode.formulaRadio.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await page.getByLabel('textbox').focus();
|
||||
const conditionalRightConstant = faker.string.alphanumeric(10);
|
||||
await page.keyboard.type(`=='${conditionalRightConstant}'`);
|
||||
await expect(page.getByLabel('textbox')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}=='${conditionalRightConstant}'`,
|
||||
);
|
||||
await conditionNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const getWorkflowNodeExecutionsObjResult = getWorkflowNodeExecutionsObj[0].jobs[0].result;
|
||||
expect(getWorkflowNodeExecutionsObjResult).toBe(false);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event Add Data Trigger, Formula engine, determines that the trigger node single line text field variable is not equal to an equal constant, fails.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await conditionNode.formulaRadio.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await page.getByLabel('textbox').focus();
|
||||
const conditionalRightConstant = faker.string.alphanumeric(10);
|
||||
await page.keyboard.type(`!='${conditionalRightConstant}'`);
|
||||
await expect(page.getByLabel('textbox')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}!='${conditionalRightConstant}'`,
|
||||
);
|
||||
await conditionNode.submitButton.click();
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = conditionalRightConstant;
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const getWorkflowNodeExecutionsObjResult = getWorkflowNodeExecutionsObj[0].jobs[0].result;
|
||||
expect(getWorkflowNodeExecutionsObjResult).toBe(false);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event Add Data Trigger, Formula engine, determines that the trigger node single line text field variable is not equal to an unequal constant, passes.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await conditionNode.formulaRadio.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await page.getByLabel('textbox').focus();
|
||||
const conditionalRightConstant = faker.string.alphanumeric(10);
|
||||
await page.keyboard.type(`!='${conditionalRightConstant}'`);
|
||||
await expect(page.getByLabel('textbox')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}!='${conditionalRightConstant}'`,
|
||||
);
|
||||
await conditionNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.string.alphanumeric(9);
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const getWorkflowNodeExecutionsObjResult = getWorkflowNodeExecutionsObj[0].jobs[0].result;
|
||||
expect(getWorkflowNodeExecutionsObjResult).toBe(true);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, Formula engine, determine the trigger node integer variable is equal to the query node equal integer variable, pass.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'staffnum';
|
||||
const triggerNodeFieldDisplayName = '员工人数(整数)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
const triggerNodeCollectionRecordOne = faker.number.int();
|
||||
await mockRecords(triggerNodeCollectionName, [{ staffnum: triggerNodeCollectionRecordOne }]);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置前置查询节点
|
||||
const preQueryRecordNodeTitle = 'Query record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const preQueryRecordNodeData = {
|
||||
type: 'query',
|
||||
upstreamId: null,
|
||||
branchIndex: null,
|
||||
title: preQueryRecordNodeTitle,
|
||||
config: {
|
||||
collection: triggerNodeCollectionName,
|
||||
params: {
|
||||
filter: { $and: [{ id: { $eq: '{{$context.data.id}}' } }] },
|
||||
sort: [],
|
||||
page: 1,
|
||||
pageSize: 20,
|
||||
appends: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
const preQueryRecordNode = await apiCreateWorkflowNode(workflowId, preQueryRecordNodeData);
|
||||
const preQueryRecordNodeObj = JSON.parse(JSON.stringify(preQueryRecordNode));
|
||||
const preQueryRecordNodeId = preQueryRecordNodeObj.id;
|
||||
const getPreQueryRecordNode = await apiGetWorkflowNode(preQueryRecordNodeId);
|
||||
const preQueryRecordNodeKey = getPreQueryRecordNode.key;
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
const conditionNodeId = await conditionNode.node.locator('.workflow-node-id').innerText();
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await conditionNode.formulaRadio.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await page.getByLabel('textbox').focus();
|
||||
await page.keyboard.type('==');
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Node result' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: preQueryRecordNodeTitle }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await expect(page.getByLabel('textbox')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}==Node result / ${preQueryRecordNodeTitle} / ${triggerNodeFieldDisplayName}`,
|
||||
);
|
||||
await conditionNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordTwo = faker.number.int();
|
||||
await mockRecords(triggerNodeCollectionName, [{ staffnum: triggerNodeCollectionRecordTwo }]);
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const job = jobs.find((job) => job.nodeId.toString() === conditionNodeId);
|
||||
expect(job.result).toBe(true);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, Formula engine, determine trigger node integer variable is equal to query node not equal integer variable, not pass.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'staffnum';
|
||||
const triggerNodeFieldDisplayName = '员工人数(整数)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
const triggerNodeCollectionRecordOne = faker.number.int();
|
||||
await mockRecords(triggerNodeCollectionName, [{ staffnum: triggerNodeCollectionRecordOne }]);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置前置查询节点
|
||||
const preQueryRecordNodeTitle = 'Query record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const preQueryRecordNodeData = {
|
||||
type: 'query',
|
||||
upstreamId: null,
|
||||
branchIndex: null,
|
||||
title: preQueryRecordNodeTitle,
|
||||
config: {
|
||||
collection: triggerNodeCollectionName,
|
||||
params: {
|
||||
filter: { $and: [{ id: { $ne: '{{$context.data.id}}' } }] },
|
||||
sort: [],
|
||||
page: 1,
|
||||
pageSize: 20,
|
||||
appends: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
const preQueryRecordNode = await apiCreateWorkflowNode(workflowId, preQueryRecordNodeData);
|
||||
const preQueryRecordNodeObj = JSON.parse(JSON.stringify(preQueryRecordNode));
|
||||
const preQueryRecordNodeId = preQueryRecordNodeObj.id;
|
||||
const getPreQueryRecordNode = await apiGetWorkflowNode(preQueryRecordNodeId);
|
||||
const preQueryRecordNodeKey = getPreQueryRecordNode.key;
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
const conditionNodeId = await conditionNode.node.locator('.workflow-node-id').innerText();
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await conditionNode.formulaRadio.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await page.getByLabel('textbox').focus();
|
||||
await page.keyboard.type('==');
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Node result' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: preQueryRecordNodeTitle }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await expect(page.getByLabel('textbox')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}==Node result / ${preQueryRecordNodeTitle} / ${triggerNodeFieldDisplayName}`,
|
||||
);
|
||||
await conditionNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordTwo = faker.number.int();
|
||||
await mockRecords(triggerNodeCollectionName, [{ staffnum: triggerNodeCollectionRecordTwo }]);
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const job = jobs.find((job) => job.nodeId.toString() === conditionNodeId);
|
||||
expect(job.result).toBe(false);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, Formula engine, determine trigger node integer variable is not equal to query node equal integer variable, not pass.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'staffnum';
|
||||
const triggerNodeFieldDisplayName = '员工人数(整数)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置前置查询节点
|
||||
const preQueryRecordNodeTitle = 'Query record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const preQueryRecordNodeData = {
|
||||
type: 'query',
|
||||
upstreamId: null,
|
||||
branchIndex: null,
|
||||
title: preQueryRecordNodeTitle,
|
||||
config: {
|
||||
collection: triggerNodeCollectionName,
|
||||
params: {
|
||||
filter: { $and: [{ id: { $eq: '{{$context.data.id}}' } }] },
|
||||
sort: [],
|
||||
page: 1,
|
||||
pageSize: 20,
|
||||
appends: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
const preQueryRecordNode = await apiCreateWorkflowNode(workflowId, preQueryRecordNodeData);
|
||||
const preQueryRecordNodeObj = JSON.parse(JSON.stringify(preQueryRecordNode));
|
||||
const preQueryRecordNodeId = preQueryRecordNodeObj.id;
|
||||
const getPreQueryRecordNode = await apiGetWorkflowNode(preQueryRecordNodeId);
|
||||
const preQueryRecordNodeKey = getPreQueryRecordNode.key;
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
const conditionNodeId = await conditionNode.node.locator('.workflow-node-id').innerText();
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await conditionNode.formulaRadio.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await page.getByLabel('textbox').focus();
|
||||
await page.keyboard.type('!=');
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Node result' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: preQueryRecordNodeTitle }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await expect(page.getByLabel('textbox')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}!=Node result / ${preQueryRecordNodeTitle} / ${triggerNodeFieldDisplayName}`,
|
||||
);
|
||||
await conditionNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordTwo = faker.number.int();
|
||||
await mockRecords(triggerNodeCollectionName, [{ staffnum: triggerNodeCollectionRecordTwo }]);
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const job = jobs.find((job) => job.nodeId.toString() === conditionNodeId);
|
||||
expect(job.result).toBe(false);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, Formula engine, determine the trigger node integer variable is not equal to the query node not equal integer variable, pass.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'staffnum';
|
||||
const triggerNodeFieldDisplayName = '员工人数(整数)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
const triggerNodeCollectionRecordOne = faker.number.int();
|
||||
await mockRecords(triggerNodeCollectionName, [{ staffnum: triggerNodeCollectionRecordOne }]);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置前置查询节点
|
||||
const preQueryRecordNodeTitle = 'Query record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const preQueryRecordNodeData = {
|
||||
type: 'query',
|
||||
upstreamId: null,
|
||||
branchIndex: null,
|
||||
title: preQueryRecordNodeTitle,
|
||||
config: {
|
||||
collection: triggerNodeCollectionName,
|
||||
params: {
|
||||
filter: { $and: [{ id: { $ne: '{{$context.data.id}}' } }] },
|
||||
sort: [],
|
||||
page: 1,
|
||||
pageSize: 20,
|
||||
appends: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
const preQueryRecordNode = await apiCreateWorkflowNode(workflowId, preQueryRecordNodeData);
|
||||
const preQueryRecordNodeObj = JSON.parse(JSON.stringify(preQueryRecordNode));
|
||||
const preQueryRecordNodeId = preQueryRecordNodeObj.id;
|
||||
const getPreQueryRecordNode = await apiGetWorkflowNode(preQueryRecordNodeId);
|
||||
const preQueryRecordNodeKey = getPreQueryRecordNode.key;
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const preQueryRecordNodePom = new QueryRecordNode(page, preQueryRecordNodeTitle);
|
||||
await preQueryRecordNodePom.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
const conditionNodeId = await conditionNode.node.locator('.workflow-node-id').innerText();
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await conditionNode.formulaRadio.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await page.getByLabel('textbox').focus();
|
||||
await page.keyboard.type('!=');
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Node result' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: preQueryRecordNodeTitle }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await expect(page.getByLabel('textbox')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}!=Node result / ${preQueryRecordNodeTitle} / ${triggerNodeFieldDisplayName}`,
|
||||
);
|
||||
await conditionNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordTwo = faker.number.int();
|
||||
await mockRecords(triggerNodeCollectionName, [{ staffnum: triggerNodeCollectionRecordTwo }]);
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const job = jobs.find((job) => job.nodeId.toString() === conditionNodeId);
|
||||
expect(job.result).toBe(true);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
@ -0,0 +1,354 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import {
|
||||
ClculationNode,
|
||||
CollectionTriggerNode,
|
||||
ConditionBranchNode,
|
||||
ConditionYesNode,
|
||||
QueryRecordNode,
|
||||
apiCreateWorkflow,
|
||||
apiCreateWorkflowNode,
|
||||
apiDeleteWorkflow,
|
||||
apiGetWorkflow,
|
||||
apiGetWorkflowNode,
|
||||
apiGetWorkflowNodeExecutions,
|
||||
apiUpdateWorkflowTrigger,
|
||||
appendJsonCollectionName,
|
||||
generalWithNoRelationalFields,
|
||||
} from '@nocobase/plugin-workflow-test/e2e';
|
||||
import { expect, test } from '@nocobase/test/e2e';
|
||||
import { dayjs } from '@nocobase/utils';
|
||||
|
||||
test('Collection event add data trigger, Math engine, determine trigger node integer field variable is equal to an equal constant, pass.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'staffnum';
|
||||
const triggerNodeFieldDisplayName = '员工人数(整数)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
const conditionNodeId = await conditionNode.node.locator('.workflow-node-id').innerText();
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await conditionNode.mathRadio.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await page.getByLabel('textbox').focus();
|
||||
const conditionalRightConstant = faker.number.int();
|
||||
await page.keyboard.type(`==${conditionalRightConstant}`);
|
||||
await expect(page.getByLabel('textbox')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}==${conditionalRightConstant}`,
|
||||
);
|
||||
await conditionNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = conditionalRightConstant;
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ staffnum: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const getWorkflowNodeExecutionsObjResult = getWorkflowNodeExecutionsObj[0].jobs[0].result;
|
||||
expect(getWorkflowNodeExecutionsObjResult).toBe(true);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event Add Data Trigger, Math engine, determines that the trigger node integer field variable is equal to an unequal constant, fails.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'staffnum';
|
||||
const triggerNodeFieldDisplayName = '员工人数(整数)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
const conditionNodeId = await conditionNode.node.locator('.workflow-node-id').innerText();
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await conditionNode.mathRadio.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await page.getByLabel('textbox').focus();
|
||||
const conditionalRightConstant = faker.number.int();
|
||||
await page.keyboard.type(`==${conditionalRightConstant}`);
|
||||
await expect(page.getByLabel('textbox')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}==${conditionalRightConstant}`,
|
||||
);
|
||||
await conditionNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.number.int();
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ staffnum: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const getWorkflowNodeExecutionsObjResult = getWorkflowNodeExecutionsObj[0].jobs[0].result;
|
||||
expect(getWorkflowNodeExecutionsObjResult).toBe(false);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event Add Data Trigger, Math engine, determines that the trigger node integer field variable is not equal to an equal constant, fails.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'staffnum';
|
||||
const triggerNodeFieldDisplayName = '员工人数(整数)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await conditionNode.mathRadio.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await page.getByLabel('textbox').focus();
|
||||
const conditionalRightConstant = faker.number.int();
|
||||
await page.keyboard.type(`!=${conditionalRightConstant}`);
|
||||
await expect(page.getByLabel('textbox')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}!=${conditionalRightConstant}`,
|
||||
);
|
||||
await conditionNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = conditionalRightConstant;
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ staffnum: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const getWorkflowNodeExecutionsObjResult = getWorkflowNodeExecutionsObj[0].jobs[0].result;
|
||||
expect(getWorkflowNodeExecutionsObjResult).toBe(false);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, Math engine, determines that the trigger node integer field variable is not equal to an unequal constant, passes.', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'staffnum';
|
||||
const triggerNodeFieldDisplayName = '员工人数(整数)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置判断节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'condition', exact: true }).hover();
|
||||
await page.getByLabel('rejectOnFalse').click();
|
||||
const conditionNodeName = 'condition' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Condition-Condition', { exact: true }).getByRole('textbox').fill(conditionNodeName);
|
||||
const conditionNode = new ConditionYesNode(page, conditionNodeName);
|
||||
await conditionNode.nodeConfigure.click();
|
||||
await conditionNode.mathRadio.click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await page.getByLabel('textbox').focus();
|
||||
const conditionalRightConstant = faker.number.int();
|
||||
await page.keyboard.type(`!=${conditionalRightConstant}`);
|
||||
await expect(page.getByLabel('textbox')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}!=${conditionalRightConstant}`,
|
||||
);
|
||||
await conditionNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = faker.number.int();
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ staffnum: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,判断节点true通过
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const getWorkflowNodeExecutionsObjResult = getWorkflowNodeExecutionsObj[0].jobs[0].result;
|
||||
expect(getWorkflowNodeExecutionsObjResult).toBe(true);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,207 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import {
|
||||
CollectionTriggerNode,
|
||||
DeleteRecordNode,
|
||||
apiCreateWorkflow,
|
||||
apiDeleteWorkflow,
|
||||
apiGetList,
|
||||
apiUpdateWorkflowTrigger,
|
||||
appendJsonCollectionName,
|
||||
generalWithNoRelationalFields,
|
||||
} from '@nocobase/plugin-workflow-test/e2e';
|
||||
import { expect, test } from '@nocobase/test/e2e';
|
||||
import { dayjs } from '@nocobase/utils';
|
||||
|
||||
test('Collection event add data trigger, filter single line text field not null, delete common table data', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = 'a' + faker.string.alphanumeric(4);
|
||||
const deleteNodeAppendText = 'b' + faker.string.alphanumeric(4);
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
// 创建删除数据节点数据表
|
||||
const deleteNodeCollectionDisplayName = `自动>组织[普通表]${deleteNodeAppendText}`;
|
||||
const deleteNodeCollectionName = `tt_amt_org${deleteNodeAppendText}`;
|
||||
const deleteNodeFieldName = 'orgname';
|
||||
const deleteNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), deleteNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
const deleteNodeCollectionRecordOne = 'a' + faker.string.alphanumeric(4);
|
||||
const deleteNodeCollectionRecordTwo = 'b' + faker.string.alphanumeric(4);
|
||||
const deleteNodeCollectionRecordThree = 'c' + faker.string.alphanumeric(4);
|
||||
const deleteNodeCollectionRecords = await mockRecords(deleteNodeCollectionName, [
|
||||
{ orgname: deleteNodeCollectionRecordOne },
|
||||
{ orgname: deleteNodeCollectionRecordTwo },
|
||||
{ orgname: deleteNodeCollectionRecordThree },
|
||||
]);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置删除数据节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'destroy', exact: true }).click();
|
||||
const deleteRecordNodeName = 'Delete record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Delete record-Delete record', { exact: true }).getByRole('textbox').fill(deleteRecordNodeName);
|
||||
const deleteRecordNode = new DeleteRecordNode(page, deleteRecordNodeName);
|
||||
await deleteRecordNode.nodeConfigure.click();
|
||||
await deleteRecordNode.collectionDropDown.click();
|
||||
await page.getByText(deleteNodeCollectionDisplayName).click();
|
||||
// 设置过滤条件
|
||||
await page.getByText('Add condition', { exact: true }).click();
|
||||
await page.getByLabel('block-item-Filter-workflows-Filter').getByRole('button', { name: 'Select field' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: deleteNodeFieldDisplayName.toString() }).click();
|
||||
await page.getByTestId('select-filter-operator').click();
|
||||
await page.getByRole('option', { name: 'is not empty' }).click();
|
||||
await deleteRecordNode.submitButton.click();
|
||||
// 查看删除前数据
|
||||
let deleteNodeCollectionData = await apiGetList(deleteNodeCollectionName);
|
||||
let deleteNodeCollectionDataObj = JSON.parse(JSON.stringify(deleteNodeCollectionData));
|
||||
expect(deleteNodeCollectionDataObj.meta.count).toBe(3);
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,数据删除成功
|
||||
deleteNodeCollectionData = await apiGetList(deleteNodeCollectionName);
|
||||
deleteNodeCollectionDataObj = JSON.parse(JSON.stringify(deleteNodeCollectionData));
|
||||
expect(deleteNodeCollectionDataObj.meta.count).toBe(0);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, filter single line text field is trigger node single line text field variable , delete common table data', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = 'a' + faker.string.alphanumeric(4);
|
||||
const deleteNodeAppendText = 'b' + faker.string.alphanumeric(4);
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
// 创建删除数据节点数据表
|
||||
const deleteNodeCollectionDisplayName = `自动>组织[普通表]${deleteNodeAppendText}`;
|
||||
const deleteNodeCollectionName = `tt_amt_org${deleteNodeAppendText}`;
|
||||
const deleteNodeFieldName = 'orgname';
|
||||
const deleteNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), deleteNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
const deleteNodeCollectionRecordOne = 'a' + faker.string.alphanumeric(4);
|
||||
const deleteNodeCollectionRecordTwo = 'b' + faker.string.alphanumeric(4);
|
||||
const deleteNodeCollectionRecordThree = 'c' + faker.string.alphanumeric(4);
|
||||
const deleteNodeCollectionRecords = await mockRecords(deleteNodeCollectionName, [
|
||||
{ orgname: deleteNodeCollectionRecordOne },
|
||||
{ orgname: deleteNodeCollectionRecordTwo },
|
||||
{ orgname: deleteNodeCollectionRecordThree },
|
||||
]);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置删除数据节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'destroy', exact: true }).click();
|
||||
const deleteRecordNodeName = 'Delete record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Delete record-Delete record', { exact: true }).getByRole('textbox').fill(deleteRecordNodeName);
|
||||
const deleteRecordNode = new DeleteRecordNode(page, deleteRecordNodeName);
|
||||
await deleteRecordNode.nodeConfigure.click();
|
||||
await deleteRecordNode.collectionDropDown.click();
|
||||
await page.getByText(deleteNodeCollectionDisplayName).click();
|
||||
// 设置过滤条件
|
||||
await page.getByText('Add condition', { exact: true }).click();
|
||||
await page.getByLabel('block-item-Filter-workflows-Filter').getByRole('button', { name: 'Select field' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: deleteNodeFieldDisplayName.toString() }).click();
|
||||
await page.getByLabel('variable-button').click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger variables' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: 'Trigger data' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: triggerNodeFieldDisplayName }).click();
|
||||
await expect(page.getByLabel('block-item-Filter-workflows-Filter').getByLabel('variable-tag')).toHaveText(
|
||||
`Trigger variables / Trigger data / ${triggerNodeFieldDisplayName}`,
|
||||
);
|
||||
await deleteRecordNode.submitButton.click();
|
||||
|
||||
// 查看删除前数据
|
||||
let deleteNodeCollectionData = await apiGetList(deleteNodeCollectionName);
|
||||
let deleteNodeCollectionDataObj = JSON.parse(JSON.stringify(deleteNodeCollectionData));
|
||||
expect(deleteNodeCollectionDataObj.meta.count).toBe(3);
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = deleteNodeCollectionRecordOne;
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,数据删除成功
|
||||
deleteNodeCollectionData = await apiGetList(deleteNodeCollectionName);
|
||||
deleteNodeCollectionDataObj = JSON.parse(JSON.stringify(deleteNodeCollectionData));
|
||||
expect(deleteNodeCollectionDataObj.meta.count).toBe(2);
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
@ -0,0 +1,928 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import {
|
||||
CollectionTriggerNode,
|
||||
QueryRecordNode,
|
||||
apiCreateWorkflow,
|
||||
apiDeleteWorkflow,
|
||||
apiGetWorkflow,
|
||||
apiGetWorkflowNodeExecutions,
|
||||
apiUpdateWorkflowTrigger,
|
||||
appendJsonCollectionName,
|
||||
generalWithNoRelationalFields,
|
||||
} from '@nocobase/plugin-workflow-test/e2e';
|
||||
import { expect, test } from '@nocobase/test/e2e';
|
||||
import { dayjs } from '@nocobase/utils';
|
||||
|
||||
test('Collection event add data trigger, no filter no sort query common table 1 record', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置查询节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'query', exact: true }).click();
|
||||
const queryRecordNodeName = 'Query record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Query record-Query record', { exact: true }).getByRole('textbox').fill(queryRecordNodeName);
|
||||
const queryRecordNode = new QueryRecordNode(page, queryRecordNodeName);
|
||||
const queryRecordNodeId = await queryRecordNode.node.locator('.workflow-node-id').innerText();
|
||||
await queryRecordNode.nodeConfigure.click();
|
||||
await queryRecordNode.collectionDropDown.click();
|
||||
await page.getByRole('option', { name: triggerNodeCollectionDisplayName }).click();
|
||||
await queryRecordNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,数据查询成功
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const queryRecordNodeJob = jobs.find((job) => job.nodeId.toString() === queryRecordNodeId);
|
||||
const queryRecordNodeJobResult = queryRecordNodeJob.result;
|
||||
expect(queryRecordNodeJobResult.orgname).toBe(triggerNodeCollectionRecordOne);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, no filtering and no sorting, query common table multiple records, set page 1 20 per page', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
const triggerNodeCollectionRecordNumber = faker.number.int({ min: 0, max: 19 });
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, triggerNodeCollectionRecordNumber);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置查询节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'query', exact: true }).click();
|
||||
const queryRecordNodeName = 'Query record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Query record-Query record', { exact: true }).getByRole('textbox').fill(queryRecordNodeName);
|
||||
const queryRecordNode = new QueryRecordNode(page, queryRecordNodeName);
|
||||
const queryRecordNodeId = await queryRecordNode.node.locator('.workflow-node-id').innerText();
|
||||
await queryRecordNode.nodeConfigure.click();
|
||||
await queryRecordNode.collectionDropDown.click();
|
||||
await page.getByRole('option', { name: triggerNodeCollectionDisplayName }).click();
|
||||
await queryRecordNode.allowMultipleDataBoxesForResults.check();
|
||||
await expect(queryRecordNode.pageNumberEditBox).toHaveValue('1');
|
||||
await expect(queryRecordNode.pageSizeEditBox).toHaveValue('20');
|
||||
await queryRecordNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await mockRecords(triggerNodeCollectionName, [{ orgname: triggerNodeCollectionRecordOne }]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,数据查询成功
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const queryRecordNodeJob = jobs.find((job) => job.nodeId.toString() === queryRecordNodeId);
|
||||
const queryRecordNodeJobResult = queryRecordNodeJob.result;
|
||||
expect(queryRecordNodeJobResult.length).toBe(triggerNodeCollectionRecordNumber + 1);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, no filter ID ascending, query common table with multiple records, set page X to Y per page', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
const triggerNodeCollectionRecordNumber = faker.number.int({ min: 0, max: 19 });
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, triggerNodeCollectionRecordNumber);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置查询节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'query', exact: true }).click();
|
||||
const queryRecordNodeName = 'Query record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Query record-Query record', { exact: true }).getByRole('textbox').fill(queryRecordNodeName);
|
||||
const queryRecordNode = new QueryRecordNode(page, queryRecordNodeName);
|
||||
const queryRecordNodeId = await queryRecordNode.node.locator('.workflow-node-id').innerText();
|
||||
await queryRecordNode.nodeConfigure.click();
|
||||
await queryRecordNode.collectionDropDown.click();
|
||||
await page.getByRole('option', { name: triggerNodeCollectionDisplayName }).click();
|
||||
await queryRecordNode.allowMultipleDataBoxesForResults.check();
|
||||
// 设置排序条件
|
||||
await queryRecordNode.addSortFieldsButton.click();
|
||||
await page.getByTestId('select-single').click();
|
||||
await page.getByRole('option', { name: 'ID', exact: true }).click();
|
||||
await page.getByLabel('block-item-Radio.Group-workflows').getByText('ASC').click();
|
||||
await expect(queryRecordNode.pageNumberEditBox).toHaveValue('1');
|
||||
await expect(queryRecordNode.pageSizeEditBox).toHaveValue('20');
|
||||
const pageNumber = faker.number.int({ min: 1, max: 5 });
|
||||
const pageSize = faker.number.int({ min: 1, max: 4 });
|
||||
await queryRecordNode.pageNumberEditBox.fill(pageNumber.toString());
|
||||
await queryRecordNode.pageSizeEditBox.fill(pageSize.toString());
|
||||
await queryRecordNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await mockRecords(triggerNodeCollectionName, [{ orgname: triggerNodeCollectionRecordOne }]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,数据查询成功
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const queryRecordNodeJob = jobs.find((job) => job.nodeId.toString() === queryRecordNodeId);
|
||||
const queryRecordNodeJobResult = queryRecordNodeJob.result;
|
||||
let nodeResultRecords = 0;
|
||||
const recordCount = triggerNodeCollectionRecordNumber + 1;
|
||||
if (pageNumber > Math.ceil(recordCount / pageSize)) {
|
||||
nodeResultRecords = 0;
|
||||
expect(queryRecordNodeJobResult).toEqual([]);
|
||||
} else if (pageNumber * pageSize > recordCount) {
|
||||
nodeResultRecords = recordCount - (pageNumber - 1) * pageSize;
|
||||
expect(queryRecordNodeJobResult.length).toBe(nodeResultRecords);
|
||||
// 获取数组中对象下ID的值
|
||||
const nodeResultRecordsIDArray = queryRecordNodeJobResult.map((obj) => obj.id);
|
||||
// 断言数组的最小值等于(页码-1)*每页记录数+1
|
||||
expect(Math.min(...nodeResultRecordsIDArray)).toBe((pageNumber - 1) * pageSize + 1);
|
||||
// 断言数组的最大值等于总记录数
|
||||
expect(Math.max(...nodeResultRecordsIDArray)).toBe(recordCount);
|
||||
} else {
|
||||
nodeResultRecords = pageSize;
|
||||
expect(queryRecordNodeJobResult.length).toBe(nodeResultRecords);
|
||||
const nodeResultRecordsIDArray = queryRecordNodeJobResult.map((obj) => obj.id);
|
||||
// 断言数组的最小值等于(页码-1)*每页记录数+1
|
||||
expect(Math.min(...nodeResultRecordsIDArray)).toBe((pageNumber - 1) * pageSize + 1);
|
||||
// 断言数组的最大值等于pageNumber * pageSize
|
||||
expect(Math.max(...nodeResultRecordsIDArray)).toBe(pageNumber * pageSize);
|
||||
}
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, no filter ID descending, query common table with multiple records, set page X to Y per page', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
const triggerNodeCollectionRecordNumber = faker.number.int({ min: 0, max: 19 });
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, triggerNodeCollectionRecordNumber);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
//配置查询节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'query', exact: true }).click();
|
||||
const queryRecordNodeName = 'Query record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Query record-Query record', { exact: true }).getByRole('textbox').fill(queryRecordNodeName);
|
||||
const queryRecordNode = new QueryRecordNode(page, queryRecordNodeName);
|
||||
const queryRecordNodeId = await queryRecordNode.node.locator('.workflow-node-id').innerText();
|
||||
await queryRecordNode.nodeConfigure.click();
|
||||
await queryRecordNode.collectionDropDown.click();
|
||||
await page.getByRole('option', { name: triggerNodeCollectionDisplayName }).click();
|
||||
await queryRecordNode.allowMultipleDataBoxesForResults.check();
|
||||
// 设置排序条件
|
||||
await queryRecordNode.addSortFieldsButton.click();
|
||||
await page.getByTestId('select-single').click();
|
||||
await page.getByRole('option', { name: 'ID', exact: true }).click();
|
||||
await page.getByLabel('block-item-Radio.Group-workflows').getByText('DESC').click();
|
||||
await expect(queryRecordNode.pageNumberEditBox).toHaveValue('1');
|
||||
await expect(queryRecordNode.pageSizeEditBox).toHaveValue('20');
|
||||
const pageNumber = faker.number.int({ min: 1, max: 5 });
|
||||
const pageSize = faker.number.int({ min: 1, max: 4 });
|
||||
await queryRecordNode.pageNumberEditBox.fill(pageNumber.toString());
|
||||
await queryRecordNode.pageSizeEditBox.fill(pageSize.toString());
|
||||
await queryRecordNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await mockRecords(triggerNodeCollectionName, [{ orgname: triggerNodeCollectionRecordOne }]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,数据查询成功
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const queryRecordNodeJob = jobs.find((job) => job.nodeId.toString() === queryRecordNodeId);
|
||||
const queryRecordNodeJobResult = queryRecordNodeJob.result;
|
||||
let nodeResultRecords = 0;
|
||||
const recordCount = triggerNodeCollectionRecordNumber + 1;
|
||||
if (pageNumber > Math.ceil(recordCount / pageSize)) {
|
||||
nodeResultRecords = 0;
|
||||
expect(queryRecordNodeJobResult).toEqual([]);
|
||||
} else if (pageNumber * pageSize > recordCount) {
|
||||
nodeResultRecords = recordCount - (pageNumber - 1) * pageSize;
|
||||
expect(queryRecordNodeJobResult.length).toBe(nodeResultRecords);
|
||||
// 获取数组中对象下ID的值
|
||||
const nodeResultRecordsIDArray = queryRecordNodeJobResult.map((obj) => obj.id);
|
||||
// 断言数组的最小值等于1
|
||||
expect(Math.min(...nodeResultRecordsIDArray)).toBe(1);
|
||||
// 断言数组的最大值等于总记录数
|
||||
expect(Math.max(...nodeResultRecordsIDArray)).toBe(nodeResultRecords);
|
||||
} else {
|
||||
nodeResultRecords = pageSize;
|
||||
expect(queryRecordNodeJobResult.length).toBe(nodeResultRecords);
|
||||
const nodeResultRecordsIDArray = queryRecordNodeJobResult.map((obj) => obj.id);
|
||||
// 断言数组的最小值等于(页码-1)*每页记录数+1
|
||||
expect(Math.min(...nodeResultRecordsIDArray)).toBe(recordCount - pageNumber * pageSize + 1);
|
||||
// 断言数组的最大值等于pageNumber * pageSize
|
||||
expect(Math.max(...nodeResultRecordsIDArray)).toBe(recordCount - (pageNumber - 1) * pageSize);
|
||||
}
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, no filtering and no sorting, query multiple records of a common table, set page X to Y per page', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
const triggerNodeCollectionRecordNumber = faker.number.int({ min: 0, max: 19 });
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, triggerNodeCollectionRecordNumber);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
|
||||
//配置查询节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'query', exact: true }).click();
|
||||
const queryRecordNodeName = 'Query record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Query record-Query record', { exact: true }).getByRole('textbox').fill(queryRecordNodeName);
|
||||
const queryRecordNode = new QueryRecordNode(page, queryRecordNodeName);
|
||||
const queryRecordNodeId = await queryRecordNode.node.locator('.workflow-node-id').innerText();
|
||||
await queryRecordNode.nodeConfigure.click();
|
||||
await queryRecordNode.collectionDropDown.click();
|
||||
await page.getByRole('option', { name: triggerNodeCollectionDisplayName }).click();
|
||||
await queryRecordNode.allowMultipleDataBoxesForResults.check();
|
||||
await expect(queryRecordNode.pageNumberEditBox).toHaveValue('1');
|
||||
await expect(queryRecordNode.pageSizeEditBox).toHaveValue('20');
|
||||
const pageNumber = faker.number.int({ min: 1, max: 5 });
|
||||
const pageSize = faker.number.int({ min: 1, max: 4 });
|
||||
await queryRecordNode.pageNumberEditBox.fill(pageNumber.toString());
|
||||
await queryRecordNode.pageSizeEditBox.fill(pageSize.toString());
|
||||
await queryRecordNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await mockRecords(triggerNodeCollectionName, [{ orgname: triggerNodeCollectionRecordOne }]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,数据查询成功
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const queryRecordNodeJob = jobs.find((job) => job.nodeId.toString() === queryRecordNodeId);
|
||||
const queryRecordNodeJobResult = queryRecordNodeJob.result;
|
||||
let nodeResultRecords = 0;
|
||||
const recordCount = triggerNodeCollectionRecordNumber + 1;
|
||||
if (pageNumber > Math.ceil(recordCount / pageSize)) {
|
||||
nodeResultRecords = 0;
|
||||
expect(queryRecordNodeJobResult).toEqual([]);
|
||||
} else if (pageNumber * pageSize > recordCount) {
|
||||
nodeResultRecords = recordCount - (pageNumber - 1) * pageSize;
|
||||
expect(queryRecordNodeJobResult.length).toBe(nodeResultRecords);
|
||||
// 获取数组中对象下ID的值
|
||||
const nodeResultRecordsIDArray = queryRecordNodeJobResult.map((obj) => obj.id);
|
||||
// 断言数组的最小值等于(页码-1)*每页记录数+1
|
||||
expect(Math.min(...nodeResultRecordsIDArray)).toBe((pageNumber - 1) * pageSize + 1);
|
||||
// 断言数组的最大值等于总记录数
|
||||
expect(Math.max(...nodeResultRecordsIDArray)).toBe(recordCount);
|
||||
} else {
|
||||
nodeResultRecords = pageSize;
|
||||
expect(queryRecordNodeJobResult.length).toBe(nodeResultRecords);
|
||||
const nodeResultRecordsIDArray = queryRecordNodeJobResult.map((obj) => obj.id);
|
||||
// 断言数组的最小值等于(页码-1)*每页记录数+1
|
||||
expect(Math.min(...nodeResultRecordsIDArray)).toBe((pageNumber - 1) * pageSize + 1);
|
||||
// 断言数组的最大值等于pageNumber * pageSize
|
||||
expect(Math.max(...nodeResultRecordsIDArray)).toBe(pageNumber * pageSize);
|
||||
}
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, no filtering and no sorting, query the ordinary table 1 record, set the X page Y per page, query the results of the empty, exit the process', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
const triggerNodeCollectionRecordNumber = faker.number.int({ min: 0, max: 19 });
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, triggerNodeCollectionRecordNumber);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
//配置查询节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'query', exact: true }).click();
|
||||
const queryRecordNodeName = 'Query record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Query record-Query record', { exact: true }).getByRole('textbox').fill(queryRecordNodeName);
|
||||
const queryRecordNode = new QueryRecordNode(page, queryRecordNodeName);
|
||||
const queryRecordNodeId = await queryRecordNode.node.locator('.workflow-node-id').innerText();
|
||||
await queryRecordNode.nodeConfigure.click();
|
||||
await queryRecordNode.collectionDropDown.click();
|
||||
await page.getByRole('option', { name: triggerNodeCollectionDisplayName }).click();
|
||||
// await queryRecordNode.allowMultipleDataBoxesForResults.check();
|
||||
await expect(queryRecordNode.pageNumberEditBox).toHaveValue('1');
|
||||
await expect(queryRecordNode.pageSizeEditBox).toHaveValue('20');
|
||||
const pageNumber = faker.number.int({ min: 5, max: 5 });
|
||||
const pageSize = faker.number.int({ min: 5, max: 5 });
|
||||
await queryRecordNode.pageNumberEditBox.fill(pageNumber.toString());
|
||||
await queryRecordNode.pageSizeEditBox.fill(pageSize.toString());
|
||||
await queryRecordNode.exitProcessOptionsBoxWithEmptyResult.check();
|
||||
await expect(queryRecordNode.exitProcessOptionsBoxWithEmptyResult).toBeChecked();
|
||||
await queryRecordNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await mockRecords(triggerNodeCollectionName, [{ orgname: triggerNodeCollectionRecordOne }]);
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:工作流成功触发,数据查询成功
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const queryRecordNodeJob = jobs.find((job) => job.nodeId.toString() === queryRecordNodeId);
|
||||
const queryRecordNodeJobResult = queryRecordNodeJob.result;
|
||||
let nodeResultRecords = 0;
|
||||
const recordCount = triggerNodeCollectionRecordNumber + 1;
|
||||
if (pageNumber > Math.ceil(recordCount / pageSize)) {
|
||||
nodeResultRecords = 0;
|
||||
// expect(queryRecordNodeJobResult).toEqual([]);
|
||||
expect(queryRecordNodeJobResult).toBeNull();
|
||||
} else if (pageNumber * pageSize > recordCount) {
|
||||
nodeResultRecords = recordCount - (pageNumber - 1) * pageSize;
|
||||
expect(queryRecordNodeJobResult.length).toBe(nodeResultRecords);
|
||||
// 获取数组中对象下ID的值
|
||||
const nodeResultRecordsIDArray = queryRecordNodeJobResult.map((obj) => obj.id);
|
||||
// 断言数组的最小值等于(页码-1)*每页记录数+1
|
||||
expect(Math.min(...nodeResultRecordsIDArray)).toBe((pageNumber - 1) * pageSize + 1);
|
||||
// 断言数组的最大值等于总记录数
|
||||
expect(Math.max(...nodeResultRecordsIDArray)).toBe(recordCount);
|
||||
} else {
|
||||
nodeResultRecords = pageSize;
|
||||
expect(queryRecordNodeJobResult.length).toBe(nodeResultRecords);
|
||||
const nodeResultRecordsIDArray = queryRecordNodeJobResult.map((obj) => obj.id);
|
||||
// 断言数组的最小值等于(页码-1)*每页记录数+1
|
||||
expect(Math.min(...nodeResultRecordsIDArray)).toBe((pageNumber - 1) * pageSize + 1);
|
||||
// 断言数组的最大值等于pageNumber * pageSize
|
||||
expect(Math.max(...nodeResultRecordsIDArray)).toBe(pageNumber * pageSize);
|
||||
}
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, no filtering and no sorting, query the common table multiple records, set the X page Y per page, query results are empty, exit the process', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = faker.string.alphanumeric(5);
|
||||
//创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
const triggerNodeCollectionRecordNumber = faker.number.int({ min: 0, max: 19 });
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, triggerNodeCollectionRecordNumber);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
//配置查询节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'query', exact: true }).click();
|
||||
const queryRecordNodeName = 'Query record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Query record-Query record', { exact: true }).getByRole('textbox').fill(queryRecordNodeName);
|
||||
const queryRecordNode = new QueryRecordNode(page, queryRecordNodeName);
|
||||
const queryRecordNodeId = await queryRecordNode.node.locator('.workflow-node-id').innerText();
|
||||
await queryRecordNode.nodeConfigure.click();
|
||||
await queryRecordNode.collectionDropDown.click();
|
||||
await page.getByRole('option', { name: triggerNodeCollectionDisplayName }).click();
|
||||
await queryRecordNode.allowMultipleDataBoxesForResults.check();
|
||||
await expect(queryRecordNode.pageNumberEditBox).toHaveValue('1');
|
||||
await expect(queryRecordNode.pageSizeEditBox).toHaveValue('20');
|
||||
const pageNumber = faker.number.int({ min: 5, max: 5 });
|
||||
const pageSize = faker.number.int({ min: 5, max: 5 });
|
||||
await queryRecordNode.pageNumberEditBox.fill(pageNumber.toString());
|
||||
await queryRecordNode.pageSizeEditBox.fill(pageSize.toString());
|
||||
await queryRecordNode.exitProcessOptionsBoxWithEmptyResult.check();
|
||||
await expect(queryRecordNode.exitProcessOptionsBoxWithEmptyResult).toBeChecked();
|
||||
await queryRecordNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await mockRecords(triggerNodeCollectionName, [{ orgname: triggerNodeCollectionRecordOne }]);
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:工作流成功触发,数据查询成功
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const queryRecordNodeJob = jobs.find((job) => job.nodeId.toString() === queryRecordNodeId);
|
||||
const queryRecordNodeJobResult = queryRecordNodeJob.result;
|
||||
let nodeResultRecords = 0;
|
||||
const recordCount = triggerNodeCollectionRecordNumber + 1;
|
||||
if (pageNumber > Math.ceil(recordCount / pageSize)) {
|
||||
nodeResultRecords = 0;
|
||||
expect(queryRecordNodeJobResult).toEqual([]);
|
||||
} else if (pageNumber * pageSize > recordCount) {
|
||||
nodeResultRecords = recordCount - (pageNumber - 1) * pageSize;
|
||||
expect(queryRecordNodeJobResult.length).toBe(nodeResultRecords);
|
||||
// 获取数组中对象下ID的值
|
||||
const nodeResultRecordsIDArray = queryRecordNodeJobResult.map((obj) => obj.id);
|
||||
// 断言数组的最小值等于(页码-1)*每页记录数+1
|
||||
expect(Math.min(...nodeResultRecordsIDArray)).toBe((pageNumber - 1) * pageSize + 1);
|
||||
// 断言数组的最大值等于总记录数
|
||||
expect(Math.max(...nodeResultRecordsIDArray)).toBe(recordCount);
|
||||
} else {
|
||||
nodeResultRecords = pageSize;
|
||||
expect(queryRecordNodeJobResult.length).toBe(nodeResultRecords);
|
||||
const nodeResultRecordsIDArray = queryRecordNodeJobResult.map((obj) => obj.id);
|
||||
// 断言数组的最小值等于(页码-1)*每页记录数+1
|
||||
expect(Math.min(...nodeResultRecordsIDArray)).toBe((pageNumber - 1) * pageSize + 1);
|
||||
// 断言数组的最大值等于pageNumber * pageSize
|
||||
expect(Math.max(...nodeResultRecordsIDArray)).toBe(pageNumber * pageSize);
|
||||
}
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, filter to meet all conditions (status_singleselect=1 and staffnum>20) unsorted, query normal table 1 record', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = 'a' + faker.string.alphanumeric(4);
|
||||
const queryNodeAppendText = 'b' + faker.string.alphanumeric(4);
|
||||
// 创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
// 创建查询节点数据表
|
||||
const queryNodeCollectionDisplayName = `自动>组织[普通表]${queryNodeAppendText}`;
|
||||
const queryNodeCollectionName = `tt_amt_org${queryNodeAppendText}`;
|
||||
const queryNodeFieldName = 'orgname';
|
||||
const queryNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), queryNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
const queryNodeCollectioRecordOne = [{ status_singleselect: '1', staffnum: 10 }];
|
||||
const queryNodeCollectioRecordTwo = [{ status_singleselect: '1', staffnum: 20 }];
|
||||
const queryNodeCollectioRecordThree = [{ status_singleselect: '1', staffnum: 30 }];
|
||||
const queryNodeCollectioRecordFour = [{ status_singleselect: '1', staffnum: 40 }];
|
||||
const queryNodeCollectioRecordFive = [{ status_singleselect: '2', staffnum: 10 }];
|
||||
const queryNodeCollectioRecordSix = [{ status_singleselect: '2', staffnum: 20 }];
|
||||
const queryNodeCollectioRecordSeven = [{ status_singleselect: '2', staffnum: 30 }];
|
||||
const queryNodeCollectioRecordEight = [{ status_singleselect: '2', staffnum: 40 }];
|
||||
await mockRecords(queryNodeCollectionName, queryNodeCollectioRecordOne);
|
||||
await mockRecords(queryNodeCollectionName, queryNodeCollectioRecordTwo);
|
||||
await mockRecords(queryNodeCollectionName, queryNodeCollectioRecordThree);
|
||||
await mockRecords(queryNodeCollectionName, queryNodeCollectioRecordFour);
|
||||
await mockRecords(queryNodeCollectionName, queryNodeCollectioRecordFive);
|
||||
await mockRecords(queryNodeCollectionName, queryNodeCollectioRecordSix);
|
||||
await mockRecords(queryNodeCollectionName, queryNodeCollectioRecordSeven);
|
||||
await mockRecords(queryNodeCollectionName, queryNodeCollectioRecordEight);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
//配置查询节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'query', exact: true }).click();
|
||||
const queryRecordNodeName = 'Query record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Query record-Query record', { exact: true }).getByRole('textbox').fill(queryRecordNodeName);
|
||||
const queryRecordNode = new QueryRecordNode(page, queryRecordNodeName);
|
||||
const queryRecordNodeId = await queryRecordNode.node.locator('.workflow-node-id').innerText();
|
||||
await queryRecordNode.nodeConfigure.click();
|
||||
await queryRecordNode.collectionDropDown.click();
|
||||
await page.getByText(queryNodeCollectionDisplayName).click();
|
||||
// await queryRecordNode.allowMultipleDataBoxesForResults.check();
|
||||
// 设置过滤条件
|
||||
await page.getByText('Add condition', { exact: true }).click();
|
||||
await page.getByLabel('block-item-Filter-workflows-Filter').getByRole('button', { name: 'Select field' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: '公司状态(下拉单选)' }).click();
|
||||
await page.getByTestId('select-single').click();
|
||||
await page.getByRole('option', { name: '存续' }).click();
|
||||
await page.getByText('Add condition', { exact: true }).click();
|
||||
await page.getByLabel('block-item-Filter-workflows-Filter').getByRole('button', { name: 'Select field' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: '员工人数(整数)' }).click();
|
||||
await page.getByRole('button', { name: '=' }).click();
|
||||
await page.getByRole('option', { name: '>' }).click();
|
||||
await page.getByLabel('block-item-Filter-workflows-Filter').getByRole('spinbutton').fill('20');
|
||||
await queryRecordNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
// 3、预期结果:工作流成功触发,数据查询成功
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const queryRecordNodeJob = jobs.find((job) => job.nodeId.toString() === queryRecordNodeId);
|
||||
const queryRecordNodeJobResult = queryRecordNodeJob.result;
|
||||
const nodeResultRecordID = queryRecordNodeJobResult.id;
|
||||
const expectRecordIDArray = [3, 4];
|
||||
// 断言nodeResultRecordID的值在expectRecordIDArray数组中
|
||||
expect(expectRecordIDArray).toContain(nodeResultRecordID);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
||||
|
||||
test('Collection event add data trigger, filter to satisfy any condition (status_singleselect=1 or staffnum>20) unsorted, query common table for multiple rows, set page X to Y per page', async ({
|
||||
page,
|
||||
mockCollections,
|
||||
mockRecords,
|
||||
}) => {
|
||||
//数据表后缀标识
|
||||
const triggerNodeAppendText = 'a' + faker.string.alphanumeric(4);
|
||||
const queryNodeAppendText = 'b' + faker.string.alphanumeric(4);
|
||||
// 创建触发器节点数据表
|
||||
const triggerNodeCollectionDisplayName = `自动>组织[普通表]${triggerNodeAppendText}`;
|
||||
const triggerNodeCollectionName = `tt_amt_org${triggerNodeAppendText}`;
|
||||
const triggerNodeFieldName = 'orgname';
|
||||
const triggerNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), triggerNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
// 创建查询节点数据表
|
||||
const queryNodeCollectionDisplayName = `自动>组织[普通表]${queryNodeAppendText}`;
|
||||
const queryNodeCollectionName = `tt_amt_org${queryNodeAppendText}`;
|
||||
const queryNodeFieldName = 'orgname';
|
||||
const queryNodeFieldDisplayName = '公司名称(单行文本)';
|
||||
await mockCollections(
|
||||
appendJsonCollectionName(JSON.parse(JSON.stringify(generalWithNoRelationalFields)), queryNodeAppendText)
|
||||
.collections,
|
||||
);
|
||||
const queryNodeCollectioRecordOne = [{ status_singleselect: '1', staffnum: 10 }];
|
||||
const queryNodeCollectioRecordTwo = [{ status_singleselect: '1', staffnum: 20 }];
|
||||
const queryNodeCollectioRecordThree = [{ status_singleselect: '1', staffnum: 30 }];
|
||||
const queryNodeCollectioRecordFour = [{ status_singleselect: '1', staffnum: 40 }];
|
||||
const queryNodeCollectioRecordFive = [{ status_singleselect: '2', staffnum: 10 }];
|
||||
const queryNodeCollectioRecordSix = [{ status_singleselect: '2', staffnum: 20 }];
|
||||
const queryNodeCollectioRecordSeven = [{ status_singleselect: '2', staffnum: 30 }];
|
||||
const queryNodeCollectioRecordEight = [{ status_singleselect: '2', staffnum: 40 }];
|
||||
await mockRecords(queryNodeCollectionName, queryNodeCollectioRecordOne);
|
||||
await mockRecords(queryNodeCollectionName, queryNodeCollectioRecordTwo);
|
||||
await mockRecords(queryNodeCollectionName, queryNodeCollectioRecordThree);
|
||||
await mockRecords(queryNodeCollectionName, queryNodeCollectioRecordFour);
|
||||
await mockRecords(queryNodeCollectionName, queryNodeCollectioRecordFive);
|
||||
await mockRecords(queryNodeCollectionName, queryNodeCollectioRecordSix);
|
||||
await mockRecords(queryNodeCollectionName, queryNodeCollectioRecordSeven);
|
||||
await mockRecords(queryNodeCollectionName, queryNodeCollectioRecordEight);
|
||||
//添加工作流
|
||||
const workFlowName = faker.string.alphanumeric(5) + triggerNodeAppendText;
|
||||
const workflowData = {
|
||||
current: true,
|
||||
options: { deleteExecutionOnStatus: [] },
|
||||
title: workFlowName,
|
||||
type: 'collection',
|
||||
enabled: true,
|
||||
};
|
||||
const workflow = await apiCreateWorkflow(workflowData);
|
||||
const workflowObj = JSON.parse(JSON.stringify(workflow));
|
||||
const workflowId = workflowObj.id;
|
||||
//配置工作流触发器
|
||||
const triggerNodeData = {
|
||||
config: { appends: [], collection: triggerNodeCollectionName, changed: [], condition: { $and: [] }, mode: 1 },
|
||||
};
|
||||
const triggerNode = await apiUpdateWorkflowTrigger(workflowId, triggerNodeData);
|
||||
const triggerNodeObj = JSON.parse(JSON.stringify(triggerNode));
|
||||
//配置查询节点
|
||||
await page.goto(`admin/workflow/workflows/${workflowId}`);
|
||||
await page.waitForLoadState('networkidle');
|
||||
const collectionTriggerNode = new CollectionTriggerNode(page, workFlowName, triggerNodeCollectionName);
|
||||
await collectionTriggerNode.addNodeButton.click();
|
||||
await page.getByRole('button', { name: 'query', exact: true }).click();
|
||||
const queryRecordNodeName = 'Query record' + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByLabel('Query record-Query record', { exact: true }).getByRole('textbox').fill(queryRecordNodeName);
|
||||
const queryRecordNode = new QueryRecordNode(page, queryRecordNodeName);
|
||||
const queryRecordNodeId = await queryRecordNode.node.locator('.workflow-node-id').innerText();
|
||||
await queryRecordNode.nodeConfigure.click();
|
||||
await queryRecordNode.collectionDropDown.click();
|
||||
await page.getByText(queryNodeCollectionDisplayName).click();
|
||||
await queryRecordNode.allowMultipleDataBoxesForResults.check();
|
||||
// 设置过滤条件
|
||||
await page.getByTestId('filter-select-all-or-any').click();
|
||||
await page.getByRole('option', { name: 'Any' }).click();
|
||||
await page.getByText('Add condition', { exact: true }).click();
|
||||
await page.getByLabel('block-item-Filter-workflows-Filter').getByRole('button', { name: 'Select field' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: '公司状态(下拉单选)' }).click();
|
||||
await page.getByTestId('select-single').click();
|
||||
await page.getByRole('option', { name: '存续' }).click();
|
||||
await page.getByText('Add condition', { exact: true }).click();
|
||||
await page.getByLabel('block-item-Filter-workflows-Filter').getByRole('button', { name: 'Select field' }).click();
|
||||
await page.getByRole('menuitemcheckbox', { name: '员工人数(整数)' }).click();
|
||||
await page.getByRole('button', { name: '=' }).click();
|
||||
await page.getByRole('option', { name: '>' }).click();
|
||||
await page.getByLabel('block-item-Filter-workflows-Filter').getByRole('spinbutton').fill('20');
|
||||
await queryRecordNode.submitButton.click();
|
||||
|
||||
// 2、测试步骤:添加数据触发工作流
|
||||
const triggerNodeCollectionRecordOne = triggerNodeFieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
const triggerNodeCollectionRecords = await mockRecords(triggerNodeCollectionName, [
|
||||
{ orgname: triggerNodeCollectionRecordOne },
|
||||
]);
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// 3、预期结果:工作流成功触发,数据查询成功
|
||||
const getWorkflow = await apiGetWorkflow(workflowId);
|
||||
const getWorkflowObj = JSON.parse(JSON.stringify(getWorkflow));
|
||||
const getWorkflowExecuted = getWorkflowObj.executed;
|
||||
expect(getWorkflowExecuted).toBe(1);
|
||||
const getWorkflowNodeExecutions = await apiGetWorkflowNodeExecutions(workflowId);
|
||||
const getWorkflowNodeExecutionsObj = JSON.parse(JSON.stringify(getWorkflowNodeExecutions));
|
||||
getWorkflowNodeExecutionsObj.sort(function (a: { id: number }, b: { id: number }) {
|
||||
return b.id - a.id;
|
||||
});
|
||||
const jobs = getWorkflowNodeExecutionsObj[0].jobs;
|
||||
const queryRecordNodeJob = jobs.find((job) => job.nodeId.toString() === queryRecordNodeId);
|
||||
const queryRecordNodeJobResult = queryRecordNodeJob.result;
|
||||
expect(queryRecordNodeJobResult.length).toBe(6);
|
||||
// 4、后置处理:删除工作流
|
||||
await apiDeleteWorkflow(workflowId);
|
||||
});
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,36 +0,0 @@
|
||||
import { expect, test } from '@nocobase/test/e2e';
|
||||
import { dayjs } from '@nocobase/utils';
|
||||
import { CreateWorkFlow } from './pageobject/workFlow';
|
||||
|
||||
test.describe('workflow manage', () => {
|
||||
test('add new from event', async ({ page }) => {
|
||||
//用例编号
|
||||
const caseNum = 'WF02AA';
|
||||
//用例标题
|
||||
const caseTitle = 'add new from event';
|
||||
|
||||
// 1、前置条件:已登录
|
||||
|
||||
// 2、测试步骤:进入“工作流管理”-“新建”按钮,填写表单,点击“确定”按钮
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel('action-Action-Add new-workflows').click();
|
||||
const createWorkFlow = new CreateWorkFlow(page);
|
||||
const workFlowName = caseTitle + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await createWorkFlow.name.fill(workFlowName);
|
||||
await createWorkFlow.triggerType.click();
|
||||
await page.getByRole('option', { name: 'Form event' }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
|
||||
// 3、预期结果:新建成功,列表中出现新建的工作流
|
||||
await expect(page.getByText(workFlowName)).toBeVisible();
|
||||
|
||||
// 4、后置处理:删除新建的工作流
|
||||
await page.getByLabel('action-Filter.Action-Filter-filter-workflows').click();
|
||||
await page.getByRole('textbox').fill(workFlowName);
|
||||
await page.getByRole('button', { name: 'Submit' }).click();
|
||||
await page.getByLabel(`action-Action.Link-Delete-workflows-${workFlowName}`).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
await expect(page.getByText(workFlowName)).toBeHidden();
|
||||
});
|
||||
});
|
@ -1,43 +0,0 @@
|
||||
import { expect, test } from '@nocobase/test/e2e';
|
||||
import { dayjs } from '@nocobase/utils';
|
||||
import { CreateWorkFlow, EditWorkFlow } from './pageobject/workFlow';
|
||||
|
||||
test.describe('workflow manage', () => {
|
||||
test('edit from event name', async ({ page }) => {
|
||||
//用例编号
|
||||
const caseNum = 'WF05AA';
|
||||
//用例标题
|
||||
const caseTitle = 'edit from event name';
|
||||
|
||||
// 1、前置条件:1.1、已登录,1.2、存在一个工作流
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel('action-Action-Add new-workflows').click();
|
||||
const createWorkFlow = new CreateWorkFlow(page);
|
||||
let workFlowName = caseTitle + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await createWorkFlow.name.fill(workFlowName);
|
||||
await createWorkFlow.triggerType.click();
|
||||
await page.getByRole('option', { name: 'Form event' }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
|
||||
await expect(page.getByText(workFlowName)).toBeAttached();
|
||||
|
||||
// 2、测试步骤:进入“工作流管理”-“编辑”按钮,编辑名称,点击“确定”按钮
|
||||
await page.getByLabel(`action-Action.Link-Edit-workflows-${workFlowName}`).click();
|
||||
const editWorkFlow = new EditWorkFlow(page);
|
||||
workFlowName = caseTitle + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await createWorkFlow.name.fill(workFlowName);
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
|
||||
// 3、预期结果:编辑成功,列表中出现编辑后的工作流
|
||||
await expect(page.getByText(workFlowName)).toBeAttached();
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await page.getByLabel('action-Filter.Action-Filter-filter-workflows').click();
|
||||
await page.getByRole('textbox').fill(workFlowName);
|
||||
await page.getByRole('button', { name: 'Submit' }).click();
|
||||
await page.getByLabel(`action-Action.Link-Delete-workflows-${workFlowName}`).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
await expect(page.getByText(workFlowName)).toBeHidden();
|
||||
});
|
||||
});
|
File diff suppressed because it is too large
Load Diff
@ -1,39 +0,0 @@
|
||||
import type { Locator, Page } from '@nocobase/test/e2e';
|
||||
|
||||
export class CreateWorkFlow {
|
||||
readonly page: Page;
|
||||
name: Locator;
|
||||
triggerType: Locator;
|
||||
description: Locator;
|
||||
autoDeleteHistory: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.name = page.getByLabel('block-item-CollectionField-workflows-Name').getByRole('textbox');
|
||||
this.triggerType = page.getByTestId('select-single');
|
||||
this.description = page.getByTestId('description-item').getByRole('textbox');
|
||||
this.autoDeleteHistory = page.getByTestId('select-multiple');
|
||||
}
|
||||
}
|
||||
|
||||
export class EditWorkFlow {
|
||||
readonly page: Page;
|
||||
name: Locator;
|
||||
statusIsOn: Locator;
|
||||
statusIisOff: Locator;
|
||||
description: Locator;
|
||||
autoDeleteHistory: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.name = page.getByTestId('title-item').getByRole('textbox');
|
||||
this.statusIsOn = page.getByTestId('enabled-item').getByLabel('On');
|
||||
this.statusIisOff = page.getByLabel('Off');
|
||||
this.description = page.getByTestId('description-item').getByRole('textbox');
|
||||
this.autoDeleteHistory = page
|
||||
.getByTestId('deleteExecutionOnStatus-item')
|
||||
.getByTestId('antd-select')
|
||||
.locator('div')
|
||||
.nth(1);
|
||||
}
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
import { expect, test } from '@nocobase/test/e2e';
|
||||
import { dayjs } from '@nocobase/utils';
|
||||
import { appendJsonCollectionName, e2e_GeneralFormsTable, generateRandomLetters } from './pageobject/e2eTemplateJson';
|
||||
import { CreateWorkFlow } from './pageobject/workFlow';
|
||||
|
||||
test.describe('trigger collection events', () => {
|
||||
test('add data to trigger collection events', async ({ page, mockPage }) => {
|
||||
//用例编号
|
||||
const caseNum = 'WF20AA';
|
||||
//后缀标识,用于不同用例调用e2eTemplateJson.ts中相同模板JSON生成不同的数据表标识、名称
|
||||
const appendText = caseNum.toLowerCase() + generateRandomLetters().toString();
|
||||
//用例标题
|
||||
const caseTitle = 'add data to trigger collection events';
|
||||
|
||||
// 1、前置条件:1.1、已登录;1.2、存在一个配置好数据表的表单事件工作流;1.3、存在一个添加数据的区块
|
||||
//创建数据表
|
||||
const e2eJsonCollectionDisplayName = '自动>组织[普通表]';
|
||||
const e2eJsonCollectionName = 'tt_amt_org';
|
||||
|
||||
const collectionDisplayName = e2eJsonCollectionDisplayName + appendText;
|
||||
const collectionName = e2eJsonCollectionName + appendText;
|
||||
const fieldName = 'orgname';
|
||||
const fieldDisplayName = '公司名称(单行文本)';
|
||||
|
||||
const newPage = mockPage(appendJsonCollectionName(e2e_GeneralFormsTable, appendText));
|
||||
//配置工作流
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await page.waitForLoadState('networkidle');
|
||||
await page.getByLabel('action-Action-Add new-workflows').click();
|
||||
const createWorkFlow = new CreateWorkFlow(page);
|
||||
const workFlowName = caseTitle + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await createWorkFlow.name.fill(workFlowName);
|
||||
await createWorkFlow.triggerType.click();
|
||||
await page.getByTitle('Collection event').getByText('Collection event').click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
await expect(page.getByText(workFlowName)).toBeVisible();
|
||||
|
||||
//配置工作流触发器
|
||||
await page.getByLabel(`action-WorkflowLink-Configure-workflows-${workFlowName}`).click();
|
||||
await page.getByRole('button', { name: 'Configure' }).click();
|
||||
await page.getByTestId('select-collection').click();
|
||||
await page.getByText(collectionDisplayName).click();
|
||||
await page.getByTestId('select-single').click();
|
||||
await page.getByText('After record added', { exact: true }).click();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
await page.getByRole('link', { name: 'Workflow' }).click();
|
||||
await page.getByLabel(`action-Action.Link-Edit-workflows-${workFlowName}`).click();
|
||||
await page.getByLabel('On', { exact: true }).check();
|
||||
await page.getByLabel('action-Action-Submit-workflows').click();
|
||||
|
||||
//配置录入数据区块
|
||||
await newPage.goto();
|
||||
await page.getByLabel('schema-initializer-Grid-BlockInitializers').hover();
|
||||
await page.getByRole('menuitem', { name: 'table Table' }).hover();
|
||||
await page.getByRole('menuitem', { name: collectionDisplayName }).click();
|
||||
|
||||
// 移开鼠标,关闭菜单
|
||||
await page.mouse.move(300, 0);
|
||||
|
||||
await page.getByText('Configure columns').hover();
|
||||
await page.getByText(fieldDisplayName).click();
|
||||
await page.getByText('Configure actions').hover();
|
||||
await page.getByRole('menuitem', { name: 'Add new' }).click();
|
||||
await expect(page.getByRole('menuitem', { name: 'Add new' }).getByRole('switch')).toBeEnabled();
|
||||
|
||||
await page.getByLabel(`action-Action-Add new-create-tt_amt_org${appendText}-table`).click();
|
||||
await page.getByLabel(`schema-initializer-Grid-CreateFormBlockInitializers-tt_amt_org${appendText}`).hover();
|
||||
await page.getByRole('menuitem', { name: 'form Form' }).click();
|
||||
|
||||
// 移开鼠标,关闭菜单
|
||||
await page.mouse.move(300, 0);
|
||||
|
||||
await page.getByLabel(`schema-initializer-ActionBar-CreateFormActionInitializers-tt_amt_org${appendText}`).hover();
|
||||
await page.getByRole('menuitem', { name: 'Submit' }).click();
|
||||
await page.getByLabel(`schema-initializer-Grid-FormItemInitializers-tt_amt_org${appendText}`).hover();
|
||||
await page.getByRole('menuitem', { name: fieldDisplayName }).click();
|
||||
|
||||
await page.mouse.move(300, 0);
|
||||
|
||||
// 2、测试步骤:进入“数据区块”-“添加”按钮,填写表单,点击“确定”按钮
|
||||
const fieldData = fieldDisplayName + dayjs().format('YYYYMMDDHHmmss.SSS').toString();
|
||||
await page.getByRole('textbox').fill(fieldData);
|
||||
await page.getByLabel(`action-Action-Submit-submit-${collectionName}-form`, { exact: true }).click();
|
||||
await expect(page.getByText(fieldData)).toBeVisible();
|
||||
|
||||
// 3、预期结果:数据添加成功,工作流成功触发
|
||||
await expect(page.getByText(fieldData)).toBeVisible();
|
||||
await page.goto('/admin/settings/workflow');
|
||||
await expect(page.getByRole('table').locator('a').filter({ hasText: '1' })).toBeVisible();
|
||||
|
||||
// 4、后置处理:删除工作流
|
||||
await page.getByLabel('action-Filter.Action-Filter-filter-workflows').click();
|
||||
await page.getByRole('textbox').fill(workFlowName);
|
||||
await page.getByRole('button', { name: 'Submit' }).click();
|
||||
await page.getByLabel(`action-Action.Link-Delete-workflows-${workFlowName}`).click();
|
||||
await page.getByRole('button', { name: 'OK', exact: true }).click();
|
||||
await expect(page.getByText(workFlowName)).toBeHidden();
|
||||
});
|
||||
});
|
@ -19128,6 +19128,13 @@ osx-release@^1.0.0:
|
||||
dependencies:
|
||||
minimist "^1.1.0"
|
||||
|
||||
p-all@3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.npmmirror.com/p-all/-/p-all-3.0.0.tgz#077c023c37e75e760193badab2bad3ccd5782bfb"
|
||||
integrity sha512-qUZbvbBFVXm6uJ7U/WDiO0fv6waBMbjlCm4E66oZdRR+egswICarIdHyVSZZHudH8T5SF8x/JG0q0duFzPnlBw==
|
||||
dependencies:
|
||||
p-map "^4.0.0"
|
||||
|
||||
p-cancelable@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmmirror.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc"
|
||||
|
Loading…
Reference in New Issue
Block a user