mirror of
https://gitee.com/nocobase/nocobase.git
synced 2024-12-02 04:07:50 +08:00
test: approvals workflow e2e (#4781)
This commit is contained in:
parent
acac61199d
commit
99f88ee09f
@ -97,14 +97,15 @@ export class ApprovalTriggerNode {
|
||||
configureFieldsButton: Locator;
|
||||
configureActionsButton: Locator;
|
||||
saveDraftSwitch: Locator;
|
||||
preloadAssociationsDropDown: 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.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
|
||||
.getByLabel('block-item-DataSourceCollectionCascader-workflows-Collection')
|
||||
.locator('.ant-select-selection-search-input');
|
||||
@ -117,10 +118,9 @@ export class ApprovalTriggerNode {
|
||||
this.addBlockButton = page.getByLabel(`schema-initializer-Grid-ApprovalApplyAddBlockButton-${collectionName}`);
|
||||
this.addApplyFormMenu = page.getByRole('menuitem', { name: 'Apply form' });
|
||||
this.configureFieldsButton = page.getByLabel(`schema-initializer-Grid-form:configureFields-${collectionName}`);
|
||||
this.configureActionsButton = page.getByLabel(
|
||||
`schema-initializer-ActionBar-ApprovalApplyAddActionButton-${collectionName}`,
|
||||
);
|
||||
this.configureActionsButton = page.getByLabel(`schema-initializer-ActionBar-ApprovalApplyAddActionButton-${collectionName}`);
|
||||
this.saveDraftSwitch = page.getByRole('menuitem', { name: 'Save draft' }).getByRole('switch');
|
||||
this.preloadAssociationsDropDown = page.getByTestId('select-field-Preload associations');
|
||||
this.submitButton = page.getByLabel('action-Action-Submit-workflows');
|
||||
this.cancelButton = page.getByLabel('action-Action-Cancel-workflows');
|
||||
this.addNodeButton = this.addNodeButton = page.getByLabel('add-button', { exact: true });
|
||||
@ -133,10 +133,13 @@ export class ApprovalPassthroughModeNode {
|
||||
nodeTitle: Locator;
|
||||
nodeConfigure: Locator;
|
||||
addAssigneesButton: Locator;
|
||||
addSelectAssigneesMenu: Locator;
|
||||
addQueryAssigneesMenu: Locator;
|
||||
assigneesDropDown: Locator;
|
||||
OrRadio: Locator;
|
||||
AndRadio: Locator;
|
||||
votingRadio: Locator;
|
||||
votingThresholdEditBox: Locator;
|
||||
parallellyRadio: Locator;
|
||||
sequentiallyRadio: Locator;
|
||||
goToconfigureButton: Locator;
|
||||
@ -161,18 +164,19 @@ export class ApprovalPassthroughModeNode {
|
||||
.getByLabel(`Approval-${nodeName}`, { exact: true })
|
||||
.getByRole('button', { name: 'Configure' });
|
||||
this.addAssigneesButton = page.getByRole('button', { name: 'plus Add assignee' });
|
||||
this.addSelectAssigneesMenu = page.getByRole('button', { name: 'Select assignees' });
|
||||
this.addQueryAssigneesMenu = page.getByRole('button', { name: 'Query assignees' });
|
||||
this.assigneesDropDown = page.getByTestId('select-single');
|
||||
this.OrRadio = page.getByLabel('Or', { exact: true });
|
||||
this.AndRadio = page.getByLabel('And', { exact: true });
|
||||
this.votingRadio = page.getByLabel('Voting', { exact: true });
|
||||
this.votingThresholdEditBox = page.getByLabel('block-item-NegotiationConfig-workflows-Negotiation mode').getByRole('spinbutton');
|
||||
this.parallellyRadio = page.getByLabel('Parallelly', { exact: true });
|
||||
this.sequentiallyRadio = page.getByLabel('Sequentially', { exact: true });
|
||||
this.goToconfigureButton = page.getByRole('button', { name: 'Go to configure' });
|
||||
this.addBlockButton = page.getByLabel('schema-initializer-Grid-ApprovalProcessAddBlockButton-workflows');
|
||||
this.addDetailsMenu = page.getByRole('menuitem', { name: 'Details' });
|
||||
this.detailsConfigureFieldsButton = page.getByLabel(
|
||||
`schema-initializer-Grid-ReadPrettyFormItemInitializers-${collectionName}`,
|
||||
);
|
||||
this.detailsConfigureFieldsButton = page.getByLabel(`schema-initializer-Grid-details:configureFields-${collectionName}`);
|
||||
this.addActionsMenu = page.getByRole('menuitem', { name: 'Actions' }).getByRole('switch');
|
||||
this.actionsConfigureFieldsButton = page.getByLabel('schema-initializer-Grid-FormItemInitializers-approvalRecords');
|
||||
this.actionsConfigureActionsButton = page.getByLabel(
|
||||
@ -188,6 +192,79 @@ export class ApprovalPassthroughModeNode {
|
||||
}
|
||||
}
|
||||
|
||||
export class ApprovalBranchModeNode {
|
||||
readonly page: Page;
|
||||
node: Locator;
|
||||
nodeTitle: Locator;
|
||||
nodeConfigure: Locator;
|
||||
addAssigneesButton: Locator;
|
||||
addSelectAssigneesMenu: Locator;
|
||||
addQueryAssigneesMenu: Locator;
|
||||
assigneesDropDown: Locator;
|
||||
OrRadio: Locator;
|
||||
AndRadio: Locator;
|
||||
votingRadio: Locator;
|
||||
votingThresholdEditBox: Locator;
|
||||
parallellyRadio: Locator;
|
||||
sequentiallyRadio: Locator;
|
||||
goToconfigureButton: Locator;
|
||||
addBlockButton: Locator;
|
||||
addDetailsMenu: Locator;
|
||||
detailsConfigureFieldsButton: Locator;
|
||||
addActionsMenu: Locator;
|
||||
actionsConfigureFieldsButton: Locator;
|
||||
actionsConfigureActionsButton: Locator;
|
||||
addApproveButton: Locator;
|
||||
addRejectButton: Locator;
|
||||
addReturnButton: Locator;
|
||||
addNodeResult: Locator;
|
||||
submitButton: Locator;
|
||||
cancelButton: Locator;
|
||||
addNodeButton: Locator;
|
||||
addReturnBranchNodeButton: Locator;
|
||||
addRejectBranchNodeButton: Locator;
|
||||
addApproveBranchNodeButton: Locator;
|
||||
endOnRejectCheckbox: Locator;
|
||||
constructor(page: Page, nodeName: string, collectionName: string) {
|
||||
this.page = page;
|
||||
this.node = page.getByLabel(`Approval-${nodeName}`, { exact: true });
|
||||
this.nodeTitle = page.getByLabel(`Approval-${nodeName}`, { exact: true }).getByRole('textbox');
|
||||
this.nodeConfigure = page
|
||||
.getByLabel(`Approval-${nodeName}`, { exact: true })
|
||||
.getByRole('button', { name: 'Configure' });
|
||||
this.addAssigneesButton = page.getByRole('button', { name: 'plus Add assignee' });
|
||||
this.addSelectAssigneesMenu = page.getByRole('button', { name: 'Select assignees' });
|
||||
this.addQueryAssigneesMenu = page.getByRole('button', { name: 'Query assignees' });
|
||||
this.assigneesDropDown = page.getByTestId('select-single');
|
||||
this.OrRadio = page.getByLabel('Or', { exact: true });
|
||||
this.AndRadio = page.getByLabel('And', { exact: true });
|
||||
this.votingRadio = page.getByLabel('Voting', { exact: true });
|
||||
this.votingThresholdEditBox = page.getByLabel('block-item-NegotiationConfig-workflows-Negotiation mode').getByRole('spinbutton');
|
||||
this.parallellyRadio = page.getByLabel('Parallelly', { exact: true });
|
||||
this.sequentiallyRadio = page.getByLabel('Sequentially', { exact: true });
|
||||
this.goToconfigureButton = page.getByRole('button', { name: 'Go to configure' });
|
||||
this.addBlockButton = page.getByLabel('schema-initializer-Grid-ApprovalProcessAddBlockButton-workflows');
|
||||
this.addDetailsMenu = page.getByRole('menuitem', { name: 'Details' });
|
||||
this.detailsConfigureFieldsButton = page.getByLabel(`schema-initializer-Grid-details:configureFields-${collectionName}`);
|
||||
this.addActionsMenu = page.getByRole('menuitem', { name: 'Actions' }).getByRole('switch');
|
||||
this.actionsConfigureFieldsButton = page.getByLabel('schema-initializer-Grid-FormItemInitializers-approvalRecords');
|
||||
this.actionsConfigureActionsButton = page.getByLabel(
|
||||
'schema-initializer-ActionBar-ApprovalProcessAddActionButton-approvalRecords',
|
||||
);
|
||||
this.addApproveButton = page.getByRole('menuitem', { name: 'Approve' }).getByRole('switch');
|
||||
this.addRejectButton = page.getByRole('menuitem', { name: 'Reject' }).getByRole('switch');
|
||||
this.addReturnButton = page.getByRole('menuitem', { name: 'Return' }).getByRole('switch');
|
||||
this.addNodeResult = page.getByRole('menuitem', { name: 'Node result right' });
|
||||
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 });
|
||||
this.addReturnBranchNodeButton = page.getByLabel(`add-button-approval-${nodeName}-1`);
|
||||
this.addApproveBranchNodeButton = page.getByLabel(`add-button-approval-${nodeName}-2`);
|
||||
this.addRejectBranchNodeButton = page.getByLabel(`add-button-approval-${nodeName}--1`);
|
||||
this.endOnRejectCheckbox = page.getByLabel('End the workflow after');
|
||||
}
|
||||
}
|
||||
|
||||
export class ScheduleTriggerNode {
|
||||
readonly page: Page;
|
||||
node: Locator;
|
||||
@ -656,4 +733,5 @@ export default module.exports = {
|
||||
ConditionBranchNode,
|
||||
SQLNode,
|
||||
ParallelBranchNode,
|
||||
ApprovalBranchModeNode
|
||||
};
|
||||
|
@ -7,7 +7,7 @@
|
||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||
*/
|
||||
|
||||
import { request, Page } from '@nocobase/test/e2e';
|
||||
import { request, Browser } from '@nocobase/test/e2e';
|
||||
|
||||
const PORT = process.env.APP_PORT || 20000;
|
||||
const APP_BASE_URL = process.env.APP_BASE_URL || `http://localhost:${PORT}`;
|
||||
@ -881,6 +881,68 @@ export const apiApplyApprovalEvent = async (data: any) => {
|
||||
return (await result.json()).data;
|
||||
};
|
||||
|
||||
// 新增字段
|
||||
export const apiCreateField = async (collectionName: string, data: any) => {
|
||||
const api = await request.newContext({
|
||||
storageState: process.env.PLAYWRIGHT_AUTH_FILE,
|
||||
});
|
||||
const state = await api.storageState();
|
||||
const headers = getHeaders(state);
|
||||
/*
|
||||
{
|
||||
"sourceKey": "id",
|
||||
"foreignKey": "orgid",
|
||||
"onDelete": "SET NULL",
|
||||
"name": "dept",
|
||||
"type": "hasMany",
|
||||
"uiSchema": {
|
||||
"x-component": "AssociationField",
|
||||
"x-component-props": {
|
||||
"multiple": true
|
||||
},
|
||||
"title": "dept"
|
||||
},
|
||||
"interface": "o2m",
|
||||
"target": "tt_mnt_dept",
|
||||
"targetKey": "id"
|
||||
}
|
||||
*/
|
||||
const result = await api.post(`/api/collections/${collectionName}/fields:create`, {
|
||||
headers,
|
||||
data,
|
||||
});
|
||||
|
||||
if (!result.ok()) {
|
||||
throw new Error(await result.text());
|
||||
}
|
||||
return (await result.json()).data;
|
||||
};
|
||||
/*
|
||||
{
|
||||
"data": {
|
||||
"key": "np4llsa0fsx",
|
||||
"name": "dept1",
|
||||
"type": "hasMany",
|
||||
"interface": "o2m",
|
||||
"collectionName": "tt_mnt_org",
|
||||
"description": null,
|
||||
"parentKey": null,
|
||||
"reverseKey": null,
|
||||
"sourceKey": "id",
|
||||
"foreignKey": "orgid",
|
||||
"onDelete": "SET NULL",
|
||||
"uiSchema": {
|
||||
"x-component": "AssociationField",
|
||||
"x-component-props": {
|
||||
"multiple": true
|
||||
},
|
||||
"title": "dept1"
|
||||
},
|
||||
"target": "tt_mnt_dept",
|
||||
"targetKey": "id"
|
||||
}
|
||||
}
|
||||
*/
|
||||
const getStorageItem = (key: string, storageState: any) => {
|
||||
return storageState.origins
|
||||
.find((item) => item.origin === APP_BASE_URL)
|
||||
@ -927,13 +989,15 @@ function getHeaders(storageState: any) {
|
||||
}
|
||||
|
||||
// 用户登录新会话
|
||||
export const userLogin = async (page: Page, approvalUserEmail: string, approvalUser: string) => {
|
||||
await page.goto(`${process.env.APP_BASE_URL}/signin`);
|
||||
export const userLogin = async (browser: Browser, approvalUserEmail: string, approvalUser: string) => {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
await page.goto('signin');
|
||||
await page.getByPlaceholder('Email').fill(approvalUserEmail);
|
||||
await page.getByPlaceholder('Password').fill(approvalUser);
|
||||
await page.getByRole('button', { name: 'Sign in' }).click();
|
||||
await page.waitForLoadState('networkidle');
|
||||
return page;
|
||||
return context;
|
||||
};
|
||||
|
||||
export default module.exports = {
|
||||
@ -956,4 +1020,5 @@ export default module.exports = {
|
||||
apiCreateRecordTriggerActionEvent,
|
||||
apiApplyApprovalEvent,
|
||||
userLogin,
|
||||
apiCreateField
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user