test(e2e): add tests for collection manager (#3253)

* refactor: optimize file structure

* test: add tests for collection templates

* test: fix errors

* fix: fix errors

* test: schemaInitializer of fields

* fix: test erros

* fix: test error

* test: make tests more stable

* test: fix tree template
This commit is contained in:
Zeke Zhang 2023-12-29 09:14:47 +08:00 committed by GitHub
parent e7c2c9ff83
commit 4121075a98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
116 changed files with 11712 additions and 5720 deletions

View File

@ -258,8 +258,6 @@ export const AddCollectionAction = (props) => {
}); });
} }
result.push({ result.push({
role: 'button',
'aria-label': `create-collection-${item.name}`,
label: compile(item.title), label: compile(item.title),
key: item.name, key: item.name,
}); });
@ -289,7 +287,7 @@ export const AddCollectionAction = (props) => {
<ActionContextProvider value={{ visible, setVisible }}> <ActionContextProvider value={{ visible, setVisible }}>
<Dropdown getPopupContainer={getContainer} trigger={trigger} align={align} menu={menu}> <Dropdown getPopupContainer={getContainer} trigger={trigger} align={align} menu={menu}>
{children || ( {children || (
<Button aria-label="Create collection" icon={<PlusOutlined />} type={'primary'}> <Button icon={<PlusOutlined />} type={'primary'}>
{t('Create collection')} <DownOutlined /> {t('Create collection')} <DownOutlined />
</Button> </Button>
)} )}

View File

@ -258,8 +258,6 @@ export const AddFieldAction = (props) => {
.filter((child) => ['m2o'].includes(child.name)) .filter((child) => ['m2o'].includes(child.name))
.map((child) => { .map((child) => {
return { return {
role: 'button',
'aria-label': `${compile(option.label)}-${child.name}`,
label: compile(child.title), label: compile(child.title),
title: compile(child.title), title: compile(child.title),
key: child.name, key: child.name,
@ -277,8 +275,6 @@ export const AddFieldAction = (props) => {
.filter((child) => !['o2o', 'subTable', 'linkTo'].includes(child.name)) .filter((child) => !['o2o', 'subTable', 'linkTo'].includes(child.name))
.map((child) => { .map((child) => {
return { return {
role: 'button',
'aria-label': `${compile(option.label)}-${child.name}`,
label: compile(child.title), label: compile(child.title),
title: compile(child.title), title: compile(child.title),
key: child.name, key: child.name,
@ -314,7 +310,7 @@ export const AddFieldAction = (props) => {
<ActionContextProvider value={{ visible, setVisible }}> <ActionContextProvider value={{ visible, setVisible }}>
<Dropdown getPopupContainer={getContainer} trigger={trigger} align={align} menu={menu}> <Dropdown getPopupContainer={getContainer} trigger={trigger} align={align} menu={menu}>
{children || ( {children || (
<Button aria-label="Add field" icon={<PlusOutlined />} type={'primary'}> <Button icon={<PlusOutlined />} type={'primary'}>
{t('Add field')} {t('Add field')}
</Button> </Button>
)} )}

View File

@ -191,8 +191,6 @@ export const ConfigurationTabs = () => {
return { return {
items: [ items: [
{ {
role: 'button',
'aria-label': 'edit-category',
key: 'edit', key: 'edit',
label: ( label: (
<SchemaComponent <SchemaComponent
@ -211,8 +209,6 @@ export const ConfigurationTabs = () => {
), ),
}, },
{ {
role: 'button',
'aria-label': 'delete-category',
key: 'delete', key: 'delete',
label: compile("{{t('Delete category')}}"), label: compile("{{t('Delete category')}}"),
onClick: () => remove(item.id), onClick: () => remove(item.id),

View File

@ -195,8 +195,8 @@ const APP_BASE_URL = process.env.APP_BASE_URL || `http://localhost:${PORT}`;
export class NocoPage { export class NocoPage {
private url: string; private url: string;
private uid: string; private uid: string | undefined;
private collectionsName: string[]; private collectionsName: string[] | undefined;
private _waitForInit: Promise<void>; private _waitForInit: Promise<void>;
constructor( constructor(
@ -278,7 +278,7 @@ const _test = base.extend<ExtendUtils>({
await use(mockManualDestroyPage); await use(mockManualDestroyPage);
}, },
createCollections: async ({ page }, use) => { createCollections: async ({ page }, use) => {
let collectionsName = []; let collectionsName: string[] = [];
const _createCollections = async (collectionSettings: CollectionSetting | CollectionSetting[]) => { const _createCollections = async (collectionSettings: CollectionSetting | CollectionSetting[]) => {
collectionSettings = omitSomeFields( collectionSettings = omitSomeFields(
@ -295,7 +295,7 @@ const _test = base.extend<ExtendUtils>({
} }
}, },
mockCollections: async ({ page }, use) => { mockCollections: async ({ page }, use) => {
let collectionsName = []; let collectionsName: string[] = [];
const destroy = async () => { const destroy = async () => {
if (collectionsName.length) { if (collectionsName.length) {
await deleteCollections(_.uniq(collectionsName)); await deleteCollections(_.uniq(collectionsName));
@ -312,7 +312,7 @@ const _test = base.extend<ExtendUtils>({
await destroy(); await destroy();
}, },
mockCollection: async ({ page }, use) => { mockCollection: async ({ page }, use) => {
let collectionsName = []; let collectionsName: string[] = [];
const destroy = async () => { const destroy = async () => {
if (collectionsName.length) { if (collectionsName.length) {
await deleteCollections(_.uniq(collectionsName)); await deleteCollections(_.uniq(collectionsName));
@ -618,12 +618,12 @@ const generateFakerData = (collectionSetting: CollectionSetting) => {
}; };
const result = {}; const result = {};
collectionSetting.fields.forEach((field) => { collectionSetting.fields?.forEach((field) => {
if (excludeField.includes(field.name)) { if (field.name && excludeField.includes(field.name)) {
return; return;
} }
if (basicInterfaceToData[field.interface]) { if (basicInterfaceToData[field.interface] && field.name) {
result[field.name] = basicInterfaceToData[field.interface](); result[field.name] = basicInterfaceToData[field.interface]();
} }
}); });
@ -631,30 +631,6 @@ const generateFakerData = (collectionSetting: CollectionSetting) => {
return result; return result;
}; };
/**
* 使 Faker collection
*/
const createFakerData = async (collectionSettings: CollectionSetting[]) => {
const api = await request.newContext({
storageState: process.env.PLAYWRIGHT_AUTH_FILE,
});
const state = await api.storageState();
const headers = getHeaders(state);
for (const item of collectionSettings) {
const data = generateFakerData(item);
const result = await api.post(`/api/${item.name}:create`, {
headers,
form: data,
});
if (!result.ok()) {
throw new Error(await result.text());
}
}
};
const createRandomData = async (collectionName: string, count = 10, data?: any) => { const createRandomData = async (collectionName: string, count = 10, data?: any) => {
const api = await request.newContext({ const api = await request.newContext({
storageState: process.env.PLAYWRIGHT_AUTH_FILE, storageState: process.env.PLAYWRIGHT_AUTH_FILE,
@ -714,15 +690,32 @@ function getHeaders(storageState: any) {
return headers; return headers;
} }
interface ExpectSettingsMenuParams {
showMenu: () => Promise<void>;
supportedOptions: string[];
page: Page;
unsupportedOptions?: string[];
}
/** /**
* SchemaSettings * SchemaSettings
* @param param0 * @param param0
*/ */
export async function expectSettingsMenu({ showMenu, supportedOptions, page }) { export async function expectSettingsMenu({
showMenu,
supportedOptions,
page,
unsupportedOptions,
}: ExpectSettingsMenuParams) {
await showMenu(); await showMenu();
for (const option of supportedOptions) { for (const option of supportedOptions) {
await expect(page.getByRole('menuitem', { name: option })).toBeVisible(); await expect(page.getByRole('menuitem', { name: option })).toBeVisible();
} }
if (unsupportedOptions) {
for (const option of unsupportedOptions) {
await expect(page.getByRole('menuitem', { name: option })).not.toBeVisible();
}
}
} }
/** /**
@ -732,7 +725,8 @@ export async function expectSettingsMenu({ showMenu, supportedOptions, page }) {
export async function expectInitializerMenu({ showMenu, supportedOptions, page }) { export async function expectInitializerMenu({ showMenu, supportedOptions, page }) {
await showMenu(); await showMenu();
for (const option of supportedOptions) { for (const option of supportedOptions) {
await expect(page.getByRole('menuitem', { name: option })).toBeVisible(); // 使用 first 方法避免有重名的导致报错
await expect(page.getByRole('menuitem', { name: option }).first()).toBeVisible();
} }
} }

View File

@ -0,0 +1,80 @@
import { expect, test } from '@nocobase/test/e2e';
import { uid } from '@nocobase/utils';
import { CollectionManagerPage } from '../utils';
test.describe('create collection', () => {
test('basic', async ({ page }) => {
const collectionDisplayName = uid();
// 避免以数字开头,会报错
const collectionName = `t_${uid()}`;
const description = uid();
const collectionManagerPage = new CollectionManagerPage(page);
await collectionManagerPage.goto();
const collectionSettings = await collectionManagerPage.createCollection('Calendar collection');
await collectionSettings.change('Collection display name', collectionDisplayName);
await collectionSettings.change('Collection name', collectionName);
await collectionSettings.change('Description', description);
await collectionSettings.submit();
await expect(page.getByRole('cell', { name: collectionDisplayName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: description, exact: true })).toBeVisible();
// Delete --------------------------------------------------------------------------------
await collectionManagerPage.deleteItem(collectionName);
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeHidden();
});
test('inherits', async ({ page }) => {
const collectionDisplayName = uid();
// 避免以数字开头,会报错
const collectionName = `t_${uid()}`;
const description = uid();
const collectionManagerPage = new CollectionManagerPage(page);
await collectionManagerPage.goto();
const collectionSettings = await collectionManagerPage.createCollection('Calendar collection');
await collectionSettings.change('Collection display name', collectionDisplayName);
await collectionSettings.change('Collection name', collectionName);
await collectionSettings.change('Description', description);
await collectionSettings.change('Inherits', ['Users']);
await collectionSettings.submit();
await expect(page.getByRole('cell', { name: collectionDisplayName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: description, exact: true })).toBeVisible();
await collectionManagerPage.deleteItem(collectionName);
});
test('categories', async ({ page }) => {
const categoriesName = uid();
const collectionDisplayName = uid();
// 避免以数字开头,会报错
const collectionName = `t_${uid()}`;
const description = uid();
const collectionManagerPage = new CollectionManagerPage(page);
await collectionManagerPage.goto();
await collectionManagerPage.addCategory(categoriesName, 'Red');
const collectionSettings = await collectionManagerPage.createCollection('Calendar collection');
await collectionSettings.change('Collection display name', collectionDisplayName);
await collectionSettings.change('Collection name', collectionName);
await collectionSettings.change('Description', description);
await collectionSettings.change('Categories', [categoriesName]);
await collectionSettings.submit();
await expect(page.getByRole('cell', { name: collectionDisplayName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: description, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: categoriesName, exact: true })).toBeVisible();
await collectionManagerPage.deleteCategory(categoriesName);
await collectionManagerPage.deleteItem(collectionName);
});
});
test.describe('configure fields', () => {});
test.describe('edit', () => {});

View File

@ -0,0 +1,7 @@
import { test } from '@nocobase/test/e2e';
test.describe('create collection', () => {});
test.describe('configure fields', () => {});
test.describe('edit', () => {});

View File

@ -0,0 +1,80 @@
import { expect, test } from '@nocobase/test/e2e';
import { uid } from '@nocobase/utils';
import { CollectionManagerPage } from '../utils';
test.describe('create collection', () => {
test('basic', async ({ page }) => {
const collectionDisplayName = uid();
// 避免以数字开头,会报错
const collectionName = `t_${uid()}`;
const description = uid();
const collectionManagerPage = new CollectionManagerPage(page);
await collectionManagerPage.goto();
const collectionSettings = await collectionManagerPage.createCollection('Expression collection');
await collectionSettings.change('Collection display name', collectionDisplayName);
await collectionSettings.change('Collection name', collectionName);
await collectionSettings.change('Description', description);
await collectionSettings.submit();
await expect(page.getByRole('cell', { name: collectionDisplayName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: description, exact: true })).toBeVisible();
// Delete --------------------------------------------------------------------------------
await collectionManagerPage.deleteItem(collectionName);
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeHidden();
});
test('inherits', async ({ page }) => {
const collectionDisplayName = uid();
// 避免以数字开头,会报错
const collectionName = `t_${uid()}`;
const description = uid();
const collectionManagerPage = new CollectionManagerPage(page);
await collectionManagerPage.goto();
const collectionSettings = await collectionManagerPage.createCollection('Expression collection');
await collectionSettings.change('Collection display name', collectionDisplayName);
await collectionSettings.change('Collection name', collectionName);
await collectionSettings.change('Description', description);
await collectionSettings.change('Inherits', ['Users']);
await collectionSettings.submit();
await expect(page.getByRole('cell', { name: collectionDisplayName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: description, exact: true })).toBeVisible();
await collectionManagerPage.deleteItem(collectionName);
});
test('categories', async ({ page }) => {
const categoriesName = uid();
const collectionDisplayName = uid();
// 避免以数字开头,会报错
const collectionName = `t_${uid()}`;
const description = uid();
const collectionManagerPage = new CollectionManagerPage(page);
await collectionManagerPage.goto();
await collectionManagerPage.addCategory(categoriesName, 'Red');
const collectionSettings = await collectionManagerPage.createCollection('Expression collection');
await collectionSettings.change('Collection display name', collectionDisplayName);
await collectionSettings.change('Collection name', collectionName);
await collectionSettings.change('Description', description);
await collectionSettings.change('Categories', [categoriesName]);
await collectionSettings.submit();
await expect(page.getByRole('cell', { name: collectionDisplayName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: description, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: categoriesName, exact: true })).toBeVisible();
await collectionManagerPage.deleteCategory(categoriesName);
await collectionManagerPage.deleteItem(collectionName);
});
});
test.describe('configure fields', () => {});
test.describe('edit', () => {});

View File

@ -0,0 +1,83 @@
import { expect, test } from '@nocobase/test/e2e';
import { uid } from '@nocobase/utils';
import { CollectionManagerPage } from '../utils';
test.describe('create collection', () => {
test('basic', async ({ page }) => {
const collectionDisplayName = uid();
// 避免以数字开头,会报错
const collectionName = `t_${uid()}`;
const description = uid();
const collectionManagerPage = new CollectionManagerPage(page);
await collectionManagerPage.goto();
const collectionSettings = await collectionManagerPage.createCollection('File collection');
await collectionSettings.change('Collection display name', collectionDisplayName);
await collectionSettings.change('Collection name', collectionName);
await collectionSettings.change('Description', description);
await collectionSettings.change('File storage', 'Local storage');
await collectionSettings.submit();
await expect(page.getByRole('cell', { name: collectionDisplayName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: description, exact: true })).toBeVisible();
// Delete --------------------------------------------------------------------------------
await collectionManagerPage.deleteItem(collectionName);
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeHidden();
});
test('inherits', async ({ page }) => {
const collectionDisplayName = uid();
// 避免以数字开头,会报错
const collectionName = `t_${uid()}`;
const description = uid();
const collectionManagerPage = new CollectionManagerPage(page);
await collectionManagerPage.goto();
const collectionSettings = await collectionManagerPage.createCollection('File collection');
await collectionSettings.change('Collection display name', collectionDisplayName);
await collectionSettings.change('Collection name', collectionName);
await collectionSettings.change('Description', description);
await collectionSettings.change('Inherits', ['Users']);
await collectionSettings.change('File storage', 'Local storage');
await collectionSettings.submit();
await expect(page.getByRole('cell', { name: collectionDisplayName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: description, exact: true })).toBeVisible();
await collectionManagerPage.deleteItem(collectionName);
});
test('categories', async ({ page }) => {
const categoriesName = uid();
const collectionDisplayName = uid();
// 避免以数字开头,会报错
const collectionName = `t_${uid()}`;
const description = uid();
const collectionManagerPage = new CollectionManagerPage(page);
await collectionManagerPage.goto();
await collectionManagerPage.addCategory(categoriesName, 'Red');
const collectionSettings = await collectionManagerPage.createCollection('File collection');
await collectionSettings.change('Collection display name', collectionDisplayName);
await collectionSettings.change('Collection name', collectionName);
await collectionSettings.change('Description', description);
await collectionSettings.change('Categories', [categoriesName]);
await collectionSettings.change('File storage', 'Local storage');
await collectionSettings.submit();
await expect(page.getByRole('cell', { name: collectionDisplayName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: description, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: categoriesName, exact: true })).toBeVisible();
await collectionManagerPage.deleteCategory(categoriesName);
await collectionManagerPage.deleteItem(collectionName);
});
});
test.describe('configure fields', () => {});
test.describe('edit', () => {});

View File

@ -0,0 +1,263 @@
import { expect, test } from '@nocobase/test/e2e';
import { uid } from '@nocobase/utils';
import { CollectionManagerPage, FieldInterface } from '../utils';
test.describe('create collection', () => {
test('basic', async ({ page }) => {
const collectionDisplayName = uid();
// 避免以数字开头,会报错
const collectionName = `t_${uid()}`;
const description = uid();
const collectionManagerPage = new CollectionManagerPage(page);
await collectionManagerPage.goto();
const collectionSettings = await collectionManagerPage.createCollection('General collection');
await collectionSettings.change('Collection display name', collectionDisplayName);
await collectionSettings.change('Collection name', collectionName);
await collectionSettings.change('Description', description);
await collectionSettings.submit();
await expect(page.getByRole('cell', { name: collectionDisplayName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: description, exact: true })).toBeVisible();
// Delete --------------------------------------------------------------------------------
await collectionManagerPage.deleteItem(collectionName);
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeHidden();
});
test('inherits', async ({ page }) => {
const collectionDisplayName = uid();
// 避免以数字开头,会报错
const collectionName = `t_${uid()}`;
const description = uid();
const collectionManagerPage = new CollectionManagerPage(page);
await collectionManagerPage.goto();
const collectionSettings = await collectionManagerPage.createCollection('General collection');
await collectionSettings.change('Collection display name', collectionDisplayName);
await collectionSettings.change('Collection name', collectionName);
await collectionSettings.change('Description', description);
await collectionSettings.change('Inherits', ['Users']);
await collectionSettings.submit();
await expect(page.getByRole('cell', { name: collectionDisplayName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: description, exact: true })).toBeVisible();
await collectionManagerPage.deleteItem(collectionName);
});
test('categories', async ({ page }) => {
const categoriesName = uid();
const collectionDisplayName = uid();
// 避免以数字开头,会报错
const collectionName = `t_${uid()}`;
const description = uid();
const collectionManagerPage = new CollectionManagerPage(page);
await collectionManagerPage.goto();
await collectionManagerPage.addCategory(categoriesName, 'Red');
const collectionSettings = await collectionManagerPage.createCollection('General collection');
await collectionSettings.change('Collection display name', collectionDisplayName);
await collectionSettings.change('Collection name', collectionName);
await collectionSettings.change('Description', description);
await collectionSettings.change('Categories', [categoriesName]);
await collectionSettings.submit();
await expect(page.getByRole('cell', { name: collectionDisplayName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: description, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: categoriesName, exact: true })).toBeVisible();
await collectionManagerPage.deleteCategory(categoriesName);
await collectionManagerPage.deleteItem(collectionName);
});
test('uncheck more options', async ({ page }) => {
const collectionDisplayName = uid();
// 避免以数字开头,会报错
const collectionName = `t_${uid()}`;
const collectionManagerPage = new CollectionManagerPage(page);
await collectionManagerPage.goto();
const collectionSettings = await collectionManagerPage.createCollection('General collection');
await collectionSettings.change('Collection display name', collectionDisplayName);
await collectionSettings.change('Collection name', collectionName);
await collectionSettings.change('Generate ID field automatically', false);
await collectionSettings.change('Store the creation user of each record', false);
await collectionSettings.change('Store the last update user of each record', false);
await collectionSettings.change('Store the creation time of each record', false);
await collectionSettings.change('Store the last update time of each record', false);
await collectionSettings.submit();
await expect(page.getByRole('cell', { name: collectionDisplayName, exact: true })).toBeVisible();
await collectionManagerPage.deleteItem(collectionName);
});
});
test.describe('configure fields', () => {
test('basic', async ({ page, mockCollections }) => {
test.slow();
const collectionDisplayName = uid();
// 避免以数字开头,会报错
const collectionName = `t_${uid()}`;
const collectionManagerPage = new CollectionManagerPage(page);
const targetCollectionName = `t_${uid()}`;
await mockCollections([
{
name: targetCollectionName,
},
{
name: collectionName,
title: collectionDisplayName,
},
]);
await collectionManagerPage.goto();
const fieldsSettings = await collectionManagerPage.configureFields(collectionName);
// 应该有这些字段显示出来
await expect(page.getByRole('cell', { name: 'id', exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: 'createdAt', exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: 'createdBy', exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: 'updatedAt', exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: 'updatedBy', exact: true })).toBeVisible();
// 添加 table oid 字段
const tableOIDDisplayName = uid();
const tableOIDSettings = await fieldsSettings.addField('Table OID');
await tableOIDSettings.change('Field display name', tableOIDDisplayName);
await tableOIDSettings.submit();
await expect(page.getByRole('cell', { name: tableOIDDisplayName, exact: true })).toBeVisible();
// 添加 basic 类型的字段
// 注意:有一些必填项之所以缺失,是因为其会被自动填充一个值
await addField('Single line text');
await addField('Long text');
await addField('Phone');
await addField('Email');
await addField('URL');
await addField('Integer');
await addField('Number');
await addField('Percent');
await addField('Password');
await addField('Color');
await addField('Icon');
// 添加 choices 字段
await addField('Checkbox');
await addField('Single select');
await addField('Multiple select');
await addField('Radio group');
await addField('Checkbox group');
await addField('China region');
// 添加 media 字段
await addField('Markdown');
await addField('Rich Text');
await addField('Attachment');
// 添加 date & time 字段
await addField('Datetime');
await addField('Time');
// 添加 relation 字段
// One to one (belongs to)
const belongsToDisplayName = uid();
const belongsToSettings = await fieldsSettings.addField('One to one (belongs to)');
await belongsToSettings.change('Field display name', belongsToDisplayName);
await belongsToSettings.change('Target collection', targetCollectionName);
await belongsToSettings.submit();
await expect(page.getByRole('cell', { name: belongsToDisplayName, exact: true })).toBeVisible();
// One to one (has one)
const hasOneDisplayName = uid();
const hasOneSettings = await fieldsSettings.addField('One to one (has one)');
await hasOneSettings.change('Field display name', hasOneDisplayName);
await hasOneSettings.change('Target collection', targetCollectionName);
await hasOneSettings.submit();
await expect(page.getByRole('cell', { name: hasOneDisplayName, exact: true })).toBeVisible();
// One to many
const oneToManyDisplayName = uid();
const oneToManySettings = await fieldsSettings.addField('One to many');
await oneToManySettings.change('Field display name', oneToManyDisplayName);
await oneToManySettings.change('Target collection', targetCollectionName);
await oneToManySettings.submit();
await expect(page.getByRole('cell', { name: oneToManyDisplayName, exact: true })).toBeVisible();
// Many to one
const manyToOneDisplayName = uid();
const manyToOneSettings = await fieldsSettings.addField('Many to one');
await manyToOneSettings.change('Field display name', manyToOneDisplayName);
await manyToOneSettings.change('Target collection', targetCollectionName);
await manyToOneSettings.submit();
await expect(page.getByRole('cell', { name: manyToOneDisplayName, exact: true })).toBeVisible();
// Many to many
const manyToManyDisplayName = uid();
const manyToManyName = `f_${uid()}`;
const manyToManySettings = await fieldsSettings.addField('Many to many');
await manyToManySettings.change('Field display name', manyToManyDisplayName);
await manyToManySettings.change('Field name', manyToManyName);
await manyToManySettings.change('Target collection', targetCollectionName);
await manyToManySettings.submit();
await expect(page.getByRole('cell', { name: manyToManyDisplayName, exact: true })).toBeVisible();
// 在这里测一下 many to many 字段的编辑和删除,其它字段先不测了
const newManyToManyDisplayName = uid();
const manyToManyEditing = await fieldsSettings.edit(manyToManyName, 'Many to many');
await manyToManyEditing.change('Field display name', newManyToManyDisplayName);
await manyToManyEditing.submit();
await expect(page.getByRole('cell', { name: newManyToManyDisplayName, exact: true })).toBeVisible();
await fieldsSettings.deleteItem(manyToManyName);
await expect(page.getByRole('cell', { name: newManyToManyDisplayName, exact: true })).toBeHidden();
// 添加 advanced 字段
// Formula
const formulaDisplayName = uid();
const formulaSettings = await fieldsSettings.addField('Formula');
await formulaSettings.change('Field display name', formulaDisplayName);
await formulaSettings.change('Expression', '1+1');
await formulaSettings.submit();
await expect(page.getByRole('cell', { name: formulaDisplayName, exact: true })).toBeVisible();
// Sequence
const sequenceDisplayName = uid();
const sequenceSettings = await fieldsSettings.addField('Sequence');
await sequenceSettings.change('Field display name', sequenceDisplayName);
await page.getByRole('button', { name: 'plus Add rule' }).click();
await sequenceSettings.submit();
await expect(page.getByRole('cell', { name: sequenceDisplayName, exact: true })).toBeVisible();
// JSON
await addField('JSON');
// Collection
await addField('Collection');
async function addField(fieldType: FieldInterface) {
const value = uid();
const fieldSettings = await fieldsSettings.addField(fieldType);
await fieldSettings.change('Field display name', value);
await fieldSettings.submit();
await expect(page.getByRole('cell', { name: value, exact: true })).toBeVisible();
}
});
});
test.describe('edit', () => {
test('basic', async ({ page, mockCollection }) => {
const collectionDisplayName = uid();
// 避免以数字开头,会报错
const collectionName = `t_${uid()}`;
const collectionManagerPage = new CollectionManagerPage(page);
await mockCollection({
name: collectionName,
title: collectionDisplayName,
});
await collectionManagerPage.goto();
const newCollectionDisplayName = uid();
const newDescription = uid();
const newCollectionSettings = await collectionManagerPage.edit(collectionName);
await newCollectionSettings.change('Collection display name', newCollectionDisplayName);
await newCollectionSettings.change('Description', newDescription);
await newCollectionSettings.submit();
await expect(page.getByRole('cell', { name: newCollectionDisplayName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: newDescription, exact: true })).toBeVisible();
});
});

View File

@ -0,0 +1,54 @@
import { expect, test } from '@nocobase/test/e2e';
import { uid } from '@nocobase/utils';
import { CollectionManagerPage } from '../utils';
test.describe('create collection', () => {
test('basic', async ({ page }) => {
const collectionDisplayName = uid();
// 避免以数字开头,会报错
const collectionName = `t_${uid()}`;
const collectionManagerPage = new CollectionManagerPage(page);
await collectionManagerPage.goto();
const collectionSettings = await collectionManagerPage.createCollection('SQL collection');
await collectionSettings.change('Collection display name', collectionDisplayName);
await collectionSettings.change('Collection name', collectionName);
await collectionSettings.change('SQL', 'SELECT * FROM users;');
await collectionSettings.submit();
await expect(page.getByRole('cell', { name: collectionDisplayName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeVisible();
// Delete --------------------------------------------------------------------------------
await collectionManagerPage.deleteItem(collectionName);
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeHidden();
});
test('categories', async ({ page }) => {
const categoriesName = uid();
const collectionDisplayName = uid();
// 避免以数字开头,会报错
const collectionName = `t_${uid()}`;
const collectionManagerPage = new CollectionManagerPage(page);
await collectionManagerPage.goto();
await collectionManagerPage.addCategory(categoriesName, 'Red');
const collectionSettings = await collectionManagerPage.createCollection('SQL collection');
await collectionSettings.change('Collection display name', collectionDisplayName);
await collectionSettings.change('Collection name', collectionName);
await collectionSettings.change('SQL', 'SELECT * FROM users;');
await collectionSettings.change('Categories', [categoriesName]);
await collectionSettings.submit();
await expect(page.getByRole('cell', { name: collectionDisplayName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: categoriesName, exact: true })).toBeVisible();
await collectionManagerPage.deleteCategory(categoriesName);
await collectionManagerPage.deleteItem(collectionName);
});
});
test.describe('configure fields', () => {});
test.describe('edit', () => {});

View File

@ -0,0 +1,101 @@
import { expect, test } from '@nocobase/test/e2e';
import { uid } from '@nocobase/utils';
import { CollectionManagerPage } from '../utils';
test.describe('create collection', () => {
test('basic', async ({ page }) => {
const collectionDisplayName = uid();
// 避免以数字开头,会报错
const collectionName = `t_${uid()}`;
const description = uid();
const collectionManagerPage = new CollectionManagerPage(page);
await collectionManagerPage.goto();
const collectionSettings = await collectionManagerPage.createCollection('Tree collection');
await collectionSettings.change('Collection display name', collectionDisplayName);
await collectionSettings.change('Collection name', collectionName);
await collectionSettings.change('Description', description);
await collectionSettings.submit();
await expect(page.getByRole('cell', { name: collectionDisplayName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: description, exact: true })).toBeVisible();
// Delete --------------------------------------------------------------------------------
await collectionManagerPage.deleteItem(collectionName);
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeHidden();
});
test('inherits', async ({ page }) => {
const collectionDisplayName = uid();
// 避免以数字开头,会报错
const collectionName = `t_${uid()}`;
const description = uid();
const collectionManagerPage = new CollectionManagerPage(page);
await collectionManagerPage.goto();
const collectionSettings = await collectionManagerPage.createCollection('Tree collection');
await collectionSettings.change('Collection display name', collectionDisplayName);
await collectionSettings.change('Collection name', collectionName);
await collectionSettings.change('Description', description);
await collectionSettings.change('Inherits', ['Users']);
await collectionSettings.submit();
await expect(page.getByRole('cell', { name: collectionDisplayName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: description, exact: true })).toBeVisible();
await collectionManagerPage.deleteItem(collectionName);
});
test('categories', async ({ page }) => {
const categoriesName = uid();
const collectionDisplayName = uid();
// 避免以数字开头,会报错
const collectionName = `t_${uid()}`;
const description = uid();
const collectionManagerPage = new CollectionManagerPage(page);
await collectionManagerPage.goto();
await collectionManagerPage.addCategory(categoriesName, 'Red');
const collectionSettings = await collectionManagerPage.createCollection('Tree collection');
await collectionSettings.change('Collection display name', collectionDisplayName);
await collectionSettings.change('Collection name', collectionName);
await collectionSettings.change('Description', description);
await collectionSettings.change('Categories', [categoriesName]);
await collectionSettings.submit();
await expect(page.getByRole('cell', { name: collectionDisplayName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: collectionName, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: description, exact: true })).toBeVisible();
await expect(page.getByRole('cell', { name: categoriesName, exact: true })).toBeVisible();
await collectionManagerPage.deleteCategory(categoriesName);
await collectionManagerPage.deleteItem(collectionName);
});
test('uncheck more options', async ({ page }) => {
const collectionDisplayName = uid();
// 避免以数字开头,会报错
const collectionName = `t_${uid()}`;
const collectionManagerPage = new CollectionManagerPage(page);
await collectionManagerPage.goto();
const collectionSettings = await collectionManagerPage.createCollection('Tree collection');
await collectionSettings.change('Collection display name', collectionDisplayName);
await collectionSettings.change('Collection name', collectionName);
await collectionSettings.change('Store the creation user of each record', false);
await collectionSettings.change('Store the last update user of each record', false);
await collectionSettings.change('Store the creation time of each record', false);
await collectionSettings.change('Store the last update time of each record', false);
await collectionSettings.submit();
await expect(page.getByRole('cell', { name: collectionDisplayName, exact: true })).toBeVisible();
await collectionManagerPage.deleteItem(collectionName);
});
});
test.describe('configure fields', () => {});
test.describe('edit', () => {});

View File

@ -0,0 +1,67 @@
import { expectInitializerMenu, oneTableBlockWithAddNewAndViewAndEditAndMediaFields, test } from '@nocobase/test/e2e';
test.describe('form item & create form', () => {
test('configure fields', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel('schema-initializer-Grid-FormItemInitializers-general').hover();
},
supportedOptions: ['markdown', 'richtext', 'attachment'],
});
});
});
test.describe('form item & edit form', () => {
test('configure fields', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel('schema-initializer-Grid-FormItemInitializers-general').hover();
},
supportedOptions: ['markdown', 'richtext', 'attachment'],
});
});
});
test.describe('form item & view form', () => {
test('configure fields', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel('schema-initializer-Grid-ReadPrettyFormItemInitializers-general').hover();
},
supportedOptions: ['markdown', 'richtext', 'attachment'],
});
});
});
test.describe('table column & table', () => {
test('configure columns', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByLabel('schema-initializer-TableV2-').hover();
},
supportedOptions: ['markdown', 'richtext', 'attachment'],
});
});
});

View File

@ -0,0 +1,285 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndMediaFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testPattern } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.attachment-attachment`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.attachment`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit description', 'Required', 'Pattern', 'Delete'],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
await testPattern({
page,
gotoPage: async () => {
await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).goto();
},
openDialog: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
},
showMenu: async () => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.attachment-attachment`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.attachment`, {
exact: true,
})
.hover();
},
expectEditable: async () => {
await expect(page.getByRole('button', { name: 'plus Upload' })).toBeVisible();
},
expectReadonly: async () => {
await expect(page.getByRole('button', { name: 'plus Upload' })).not.toBeVisible();
},
expectEasyReading: async () => {
await expect(page.getByRole('button', { name: 'plus Upload' })).not.toBeVisible();
},
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page
.getByLabel(`block-item-CollectionField-general-form-general.attachment-attachment`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.attachment`, {
exact: true,
})
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit description', 'Required', 'Pattern', 'Delete'],
unsupportedOptions: ['Set default value'],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
let record: any = null;
await testPattern({
page,
gotoPage: async () => {
record = await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
},
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'attachment'),
expectEditable: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.attachment-attachment')
.getByRole('link', { name: record.attachment.title })
.first(),
).toBeVisible();
},
expectReadonly: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.attachment-attachment')
.getByRole('link', { name: record.attachment.title })
.first()
.hover();
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.attachment-attachment')
.getByRole('button', { name: 'delete' }),
).not.toBeVisible();
},
expectEasyReading: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.attachment-attachment')
.getByRole('link', { name: record.attachment.title })
.first()
.hover();
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.attachment-attachment')
.getByRole('button', { name: 'delete' }),
).not.toBeVisible();
},
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
// 这里是为了等弹窗中的内容渲染稳定后,再去 hover防止错位导致测试报错
await page.waitForTimeout(1000);
await page
.getByLabel(`block-item-CollectionField-general-form-general.attachment-attachment`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.attachment`, {
exact: true,
})
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip', 'Size'],
unsupportedOptions: ['Set default value'],
});
});
test('size', async ({ page, mockPage, mockRecord }) => {
const record = await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
// 默认尺寸
// 这里的尺寸不稳定,所以用 try catch 来处理
const testDefault = async (value) => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.attachment-attachment')
.getByRole('link', { name: record.attachment.title })
.first(),
).toHaveJSProperty('offsetWidth', value, { timeout: 1000 });
};
try {
await testDefault(94);
} catch (error) {
try {
await testDefault(95);
} catch (err) {
await testDefault(96);
}
}
// 改为大尺寸
const testLarge = async (value) => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.attachment-attachment')
.getByRole('link', { name: record.attachment.title })
.first(),
).toHaveJSProperty('offsetWidth', value, { timeout: 1000 });
};
// 这里是为了等弹窗中的内容渲染稳定后,再去 hover防止错位导致测试报错
await page.waitForTimeout(1000);
await page
.getByLabel(`block-item-CollectionField-general-form-general.attachment-attachment`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.attachment`, {
exact: true,
})
.hover();
await page.getByRole('menuitem', { name: 'Size' }).click();
await page.getByRole('option', { name: 'Large' }).click();
try {
await testLarge(153);
} catch (err) {
try {
await testLarge(154);
} catch (err) {
await testLarge(152);
}
}
// 改为小尺寸
const testSmall = async (value) => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.attachment-attachment')
.getByRole('link', { name: record.attachment.title })
.first(),
).toHaveJSProperty('offsetWidth', value, { timeout: 1000 });
};
await (async (page: Page, fieldName: string) => {
// 这里是为了等弹窗中的内容渲染稳定后,再去 hover防止错位导致测试报错
await page.waitForTimeout(1000);
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'attachment');
await page.getByRole('menuitem', { name: 'Size' }).click();
await page.getByRole('option', { name: 'Small' }).click();
try {
await testSmall(25);
} catch (err) {
try {
await testSmall(26);
} catch (err) {
await testSmall(24);
}
}
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'attachment');
await showSettingsMenu(page, 'attachment');
},
supportedOptions: ['Custom column title', 'Column width', 'Delete'],
});
});
});

View File

@ -0,0 +1,73 @@
import {
expectInitializerMenu,
oneTableBlockWithAddNewAndViewAndEditAndAssociationFields,
test,
} from '@nocobase/test/e2e';
test.describe('form item & create form', () => {
test('configure fields', async ({ page, mockPage, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecords('users', 3);
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel('schema-initializer-Grid-FormItemInitializers-general').hover();
},
supportedOptions: ['oneToMany', 'manyToOne', 'manyToMany', 'oneToOneBelongsTo', 'oneToOneHasOne'],
});
});
});
test.describe('form item & edit form', () => {
test('configure fields', async ({ page, mockPage, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecords('users', 3);
await mockRecords('general', 1);
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel('schema-initializer-Grid-FormItemInitializers-general').hover();
},
supportedOptions: ['oneToMany', 'manyToOne', 'manyToMany', 'oneToOneBelongsTo', 'oneToOneHasOne'],
});
});
});
test.describe('form item & view form', () => {
test('configure fields', async ({ page, mockPage, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecords('general', 1);
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel('schema-initializer-Grid-ReadPrettyFormItemInitializers-general').hover();
},
supportedOptions: ['oneToMany', 'manyToOne', 'manyToMany', 'oneToOneBelongsTo', 'oneToOneHasOne'],
});
});
});
test.describe('table column & table', () => {
test('configure columns', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByLabel('schema-initializer-TableV2-').hover();
},
supportedOptions: ['oneToMany', 'manyToOne', 'manyToMany', 'oneToOneBelongsTo', 'oneToOneHasOne'],
});
});
});

View File

@ -0,0 +1,548 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndAssociationFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testPattern } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecords('users', 3);
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page
.getByLabel(`block-item-CollectionField-general-form-general.oneToOneBelongsTo-oneToOneBelongsTo`)
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.oneToOneBelongsTo`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set the data scope',
'Set default sorting rules',
'Field component',
'Quick create',
'Pattern',
'Title field',
'Delete',
],
});
});
test('set default value', async ({ page, mockPage, mockRecord, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneBelongsTo');
await expect(page.getByRole('menuitem', { name: 'Set default value' })).not.toBeVisible();
});
test('pattern', async ({ page, mockPage, mockRecords }) => {
let records;
await testPattern({
page,
gotoPage: async () => {
records = await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
},
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneBelongsTo'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.oneToOneBelongsTo-oneToOneBelongsTo')
.getByTestId(/select-object/)
.click();
await page.getByRole('option', { name: String(records[0].id), exact: true }).click();
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.oneToOneBelongsTo-oneToOneBelongsTo')
.getByTestId(/select-object/),
).toHaveClass(/ant-select-disabled/);
// 在这里等待一下,防止因闪烁导致下面的断言失败
await page.waitForTimeout(100);
},
expectEasyReading: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.oneToOneBelongsTo-oneToOneBelongsTo'),
).toHaveText(`oneToOneBelongsTo:${String(records[0].id)}`);
},
});
});
test('Set the data scope', async ({ page, mockPage, mockRecords }) => {
const records = await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneBelongsTo');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await page.getByText('Add condition', { exact: true }).click();
await page.getByTestId('select-filter-field').click();
await page.getByRole('menuitemcheckbox', { name: 'ID', exact: true }).click();
await page.getByRole('spinbutton').click();
await page.getByRole('spinbutton').fill(String(records[0].id));
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 再次打开弹窗,设置的值应该还在
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneBelongsTo');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await expect(page.getByTestId('select-filter-field')).toHaveText('ID');
await expect(page.getByRole('spinbutton')).toHaveValue(String(records[0].id));
await page.getByRole('button', { name: 'Cancel', exact: true }).click();
// 数据应该被过滤了
await page
.getByLabel('block-item-CollectionField-general-form-general.oneToOneBelongsTo-oneToOneBelongsTo')
.getByTestId('select-object-single')
.click();
await expect(page.getByRole('option', { name: String(records[0].id), exact: true })).toBeVisible();
await expect(page.getByRole('option')).toHaveCount(1);
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneBelongsTo');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Select', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Record picker', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form(Popover)', exact: true })).toBeVisible();
});
test('quick create', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneBelongsTo');
await expect(page.getByRole('menuitem', { name: 'Quick create' })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneBelongsTo');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockRecords, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecords('users', 3);
await mockRecords('general', 1);
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page
.getByLabel(`block-item-CollectionField-general-form-general.oneToOneBelongsTo-oneToOneBelongsTo`)
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.oneToOneBelongsTo`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set the data scope',
'Set default sorting rules',
'Field component',
'Quick create',
'Pattern',
'Title field',
'Delete',
],
unsupportedOptions: ['Set default value'],
});
});
test('pattern', async ({ page, mockPage, mockRecords }) => {
let record;
await testPattern({
page,
gotoPage: async () => {
record = (
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords)
).record;
},
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneBelongsTo'),
expectEditable: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.oneToOneBelongsTo-oneToOneBelongsTo')
.getByTestId(/select-object/),
).toHaveText(`${record.oneToOneBelongsTo.id}`);
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.oneToOneBelongsTo-oneToOneBelongsTo')
.getByTestId(/select-object/),
).toHaveClass(/ant-select-disabled/);
// 在这里等待一下,防止因闪烁导致下面的断言失败
await page.waitForTimeout(100);
},
expectEasyReading: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.oneToOneBelongsTo-oneToOneBelongsTo'),
).toHaveText(`oneToOneBelongsTo:${record.oneToOneBelongsTo.id}`);
},
});
});
test('Set the data scope', async ({ page, mockPage, mockRecords }) => {
const { recordsOfUser } = await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneBelongsTo');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await page.getByText('Add condition', { exact: true }).click();
await page.getByTestId('select-filter-field').click();
await page.getByRole('menuitemcheckbox', { name: 'ID', exact: true }).click();
await page.getByRole('spinbutton').click();
await page.getByRole('spinbutton').fill(String(recordsOfUser[0].id));
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 再次打开弹窗,设置的值应该还在
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneBelongsTo');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await expect(page.getByTestId('select-filter-field')).toHaveText('ID');
await expect(page.getByRole('spinbutton')).toHaveValue(String(recordsOfUser[0].id));
await page.getByRole('button', { name: 'Cancel', exact: true }).click();
// 数据应该被过滤了
await page
.getByLabel('block-item-CollectionField-general-form-general.oneToOneBelongsTo-oneToOneBelongsTo')
.getByTestId(/select-object/)
.click();
await expect(page.getByRole('option', { name: String(recordsOfUser[0].id), exact: true })).toBeVisible();
await expect(page.getByRole('option')).toHaveCount(2);
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneBelongsTo');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Select', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Record picker', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form(Popover)', exact: true })).toBeVisible();
});
test('quick create', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneBelongsTo');
await expect(page.getByRole('menuitem', { name: 'Quick create' })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneBelongsTo');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecords('general', 1);
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page
.getByLabel(`block-item-CollectionField-general-form-general.oneToOneBelongsTo-oneToOneBelongsTo`)
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.oneToOneBelongsTo`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit tooltip',
'Field component',
'Enable link',
'Title field',
'Delete',
],
unsupportedOptions: ['Set default value'],
});
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return record;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneBelongsTo');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Title', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Tag', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-details', exact: true })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return record;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneBelongsTo');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
test('enable link', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return record;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneBelongsTo');
await expect(page.getByRole('menuitem', { name: 'Enable link' }).getByRole('switch')).toBeChecked();
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'oneToOneBelongsTo');
await showSettingsMenu(page, 'oneToOneBelongsTo');
},
supportedOptions: [
'Custom column title',
'Column width',
'Enable link',
'Title field',
'Field component',
'Delete',
],
});
});
});

View File

@ -0,0 +1,67 @@
import { expectInitializerMenu, oneTableBlockWithAddNewAndViewAndEditAndChoicesFields, test } from '@nocobase/test/e2e';
test.describe('form item & create form', () => {
test('configure fields', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel('schema-initializer-Grid-FormItemInitializers-general').hover();
},
supportedOptions: ['checkbox', 'chinaRegion', 'multipleSelect', 'radioGroup', 'singleSelect', 'checkboxGroup'],
});
});
});
test.describe('form item & edit form', () => {
test('configure fields', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel('schema-initializer-Grid-FormItemInitializers-general').hover();
},
supportedOptions: ['checkbox', 'chinaRegion', 'multipleSelect', 'radioGroup', 'singleSelect', 'checkboxGroup'],
});
});
});
test.describe('form item & view form', () => {
test('configure fields', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel('schema-initializer-Grid-ReadPrettyFormItemInitializers-general').hover();
},
supportedOptions: ['checkbox', 'chinaRegion', 'multipleSelect', 'radioGroup', 'singleSelect', 'checkboxGroup'],
});
});
});
test.describe('table column & table', () => {
test('configure columns', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByLabel('schema-initializer-TableV2-').hover();
},
supportedOptions: ['checkbox', 'chinaRegion', 'multipleSelect', 'radioGroup', 'singleSelect', 'checkboxGroup'],
});
});
});

View File

@ -0,0 +1,241 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndChoicesFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testDefaultValue, testPattern } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.checkbox-checkbox`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.checkbox`, {
exact: true,
})
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Pattern',
'Delete',
'required',
'Set default value',
],
});
});
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'checkbox'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
// 默认应该是没有被选中的,点击后应该被选中
await page.getByLabel('block-item-VariableInput-').getByRole('checkbox').click();
},
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.checkbox-checkbox').getByRole('checkbox'),
).toBeChecked();
},
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
await testPattern({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'checkbox'),
expectEditable: async () => {
// 默认是未选中的状态,所以先选中
await page
.getByLabel('block-item-CollectionField-general-form-general.checkbox-checkbox')
.getByRole('checkbox')
.click();
},
expectReadonly: async () => {
// checkbox 应该被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.checkbox-checkbox').getByRole('checkbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
// checkbox 应该被隐藏,然后只显示一个图标
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.checkbox-checkbox').getByRole('checkbox'),
).not.toBeVisible();
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.checkbox-checkbox')
.getByRole('img', { name: 'check' }),
).toBeVisible();
},
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page
.getByLabel(`block-item-CollectionField-general-form-general.checkbox-checkbox`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.checkbox`, {
exact: true,
})
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit description', 'Required', 'Pattern', 'Delete'],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
let record: any = null;
await testPattern({
page,
gotoPage: async () => {
record = await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
},
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'checkbox'),
expectEditable: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.checkbox-checkbox').getByRole('checkbox'),
).toBeChecked({ checked: record.checkbox });
},
expectReadonly: async () => {
// checkbox 应该被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.checkbox-checkbox').getByRole('checkbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
// checkbox 应该被隐藏,然后只显示一个图标
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.checkbox-checkbox').getByRole('checkbox'),
).not.toBeVisible();
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.checkbox-checkbox')
.getByRole('img', { name: 'check' }),
).toBeVisible({ visible: record.checkbox });
},
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.checkbox-checkbox`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.checkbox`, {
exact: true,
})
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'checkbox');
await showSettingsMenu(page, 'checkbox');
},
supportedOptions: ['Custom column title', 'Column width', 'Delete'],
});
});
});

View File

@ -0,0 +1,248 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndChoicesFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testDefaultValue, testPattern } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.checkboxGroup-checkboxGroup`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.checkboxGroup`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Pattern',
'Delete',
'required',
'Set default value',
],
});
});
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'checkboxGroup'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').getByLabel('Option1').click();
},
expectConstantValue: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.checkboxGroup-checkboxGroup')
.getByRole('checkbox', { name: 'Option1' }),
).toBeChecked();
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'checkboxGroup'),
expectEditable: async () => {
// 默认是未选中的状态,所以先选中
await page
.getByLabel('block-item-CollectionField-general-form-general.checkboxGroup-checkboxGroup')
.getByRole('checkbox', { name: 'Option1' })
.click();
},
expectReadonly: async () => {
// checkbox 应该被禁用
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.checkboxGroup-checkboxGroup')
.getByRole('checkbox', { name: 'Option1' }),
).toBeDisabled();
},
expectEasyReading: async () => {
// checkbox 应该被隐藏,然后只显示一个标签
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.checkboxGroup-checkboxGroup')
.getByRole('checkbox', { name: 'Option1' }),
).not.toBeVisible();
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.checkboxGroup-checkboxGroup')
.getByText('Option1'),
).toBeVisible();
},
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page
.getByLabel(`block-item-CollectionField-general-form-general.checkboxGroup-checkboxGroup`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.checkboxGroup`, {
exact: true,
})
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit description', 'Required', 'Pattern', 'Delete'],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
let record = null;
await testPattern({
page,
gotoPage: async () => {
record = await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
},
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'checkboxGroup'),
expectEditable: async () => {
for (const option of record.checkboxGroup) {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.checkboxGroup-checkboxGroup')
.getByRole('checkbox', { name: option }),
).toBeChecked();
}
},
expectReadonly: async () => {
// checkbox 应该被禁用
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.checkboxGroup-checkboxGroup')
.getByRole('checkbox', { name: 'Option1' }),
).toBeDisabled();
},
expectEasyReading: async () => {
// checkbox 应该被隐藏,然后只显示标签
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.checkboxGroup-checkboxGroup')
.getByRole('checkbox', { name: 'Option1' }),
).not.toBeVisible();
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.checkboxGroup-checkboxGroup'),
).toHaveText(`checkboxGroup:${record.checkboxGroup.join('')}`, { ignoreCase: true });
},
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.checkboxGroup-checkboxGroup`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.checkboxGroup`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'checkboxGroup');
await showSettingsMenu(page, 'checkboxGroup');
},
supportedOptions: ['Custom column title', 'Column width', 'Delete'],
});
});
});

View File

@ -0,0 +1,249 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndChoicesFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testDefaultValue, testPattern } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.chinaRegion-chinaRegion`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.chinaRegion`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Pattern',
'Delete',
'required',
'Set default value',
],
});
});
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'chinaRegion'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').click();
await page.getByRole('menuitemcheckbox', { name: '北京市' }).click();
await page.getByRole('menuitemcheckbox', { name: '市辖区' }).click();
await page.getByRole('menuitemcheckbox', { name: '东城区' }).click();
},
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.chinaRegion-chinaRegion'),
).toHaveText('chinaRegion:北京市/市辖区/东城区');
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'chinaRegion'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.chinaRegion-chinaRegion')
.locator('.ant-select')
.click();
await page.getByRole('menuitemcheckbox', { name: '北京市' }).click();
await page.getByRole('menuitemcheckbox', { name: '市辖区' }).click();
await page.getByRole('menuitemcheckbox', { name: '东城区' }).click();
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.chinaRegion-chinaRegion')
.locator('.ant-select')
.getByRole('combobox'),
).toBeDisabled();
},
expectEasyReading: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.chinaRegion-chinaRegion')
.locator('.ant-select')
.getByRole('combobox'),
).not.toBeVisible();
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.chinaRegion-chinaRegion'),
).toHaveText('chinaRegion:北京市 / 市辖区 / 东城区');
},
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page
.getByLabel(`block-item-CollectionField-general-form-general.chinaRegion-chinaRegion`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.chinaRegion`, {
exact: true,
})
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit description', 'Required', 'Pattern', 'Delete'],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
let record = null;
await testPattern({
page,
gotoPage: async () => {
record = await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
},
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'chinaRegion'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.chinaRegion-chinaRegion')
.locator('.ant-select')
.click();
await page.getByRole('menuitemcheckbox', { name: '北京市' }).click();
await page.getByRole('menuitemcheckbox', { name: '市辖区' }).click();
await page.getByRole('menuitemcheckbox', { name: '东城区' }).click();
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.chinaRegion-chinaRegion')
.locator('.ant-select')
.getByRole('combobox'),
).toBeDisabled();
},
expectEasyReading: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.chinaRegion-chinaRegion')
.locator('.ant-select')
.getByRole('combobox'),
).not.toBeVisible();
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.chinaRegion-chinaRegion'),
).toHaveText('chinaRegion:北京市 / 市辖区 / 东城区');
},
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.chinaRegion-chinaRegion`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.chinaRegion`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'chinaRegion');
await showSettingsMenu(page, 'chinaRegion');
},
supportedOptions: ['Custom column title', 'Column width', 'Delete'],
});
});
});

View File

@ -0,0 +1,71 @@
import {
expectInitializerMenu,
oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields,
test,
} from '@nocobase/test/e2e';
test.describe('form item & create form', () => {
test('configure fields', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields).waitForInit();
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel('schema-initializer-Grid-FormItemInitializers-general').hover();
},
supportedOptions: ['formula', 'sequence', 'JSON', 'collection'],
});
});
});
test.describe('form item & edit form', () => {
test('configure fields', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel('schema-initializer-Grid-FormItemInitializers-general').hover();
},
supportedOptions: ['formula', 'sequence', 'JSON', 'collection'],
});
});
});
test.describe('form item & view form', () => {
test('configure fields', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel('schema-initializer-Grid-ReadPrettyFormItemInitializers-general').hover();
},
supportedOptions: ['formula', 'sequence', 'JSON', 'collection'],
});
});
});
test.describe('table column & table', () => {
test('configure columns', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByLabel('schema-initializer-TableV2-').hover();
},
supportedOptions: ['formula', 'sequence', 'JSON', 'collection'],
});
});
});

View File

@ -0,0 +1,91 @@
import { expectSettingsMenu, oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields, test } from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.collection-collection`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.collection`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set default value',
'Pattern',
'Delete',
],
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.collection-collection`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.collection`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit description', 'Required', 'Pattern', 'Delete'],
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.collection-collection`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.collection`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'collection');
await showSettingsMenu(page, 'collection');
},
supportedOptions: ['Custom column title', 'Column width', 'Sortable', 'Delete'],
});
});
});
test.describe('table column & table & record picker', () => {
test('supported options', async ({ page }) => {});
});

View File

@ -0,0 +1,115 @@
import { expectInitializerMenu, oneTableBlockWithAddNewAndViewAndEditAndBasicFields, test } from '@nocobase/test/e2e';
test.describe('form item & create form', () => {
test('configure fields', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel('schema-initializer-Grid-FormItemInitializers-general').hover();
},
supportedOptions: [
'color',
'email',
'icon',
'singleLineText',
'integer',
'number',
'password',
'percent',
'phone',
'longText',
'url',
],
});
});
});
test.describe('form item & edit form', () => {
test('configure fields', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel('schema-initializer-Grid-FormItemInitializers-general').hover();
},
supportedOptions: [
'color',
'email',
'icon',
'singleLineText',
'integer',
'number',
'password',
'percent',
'phone',
'longText',
'url',
],
});
});
});
test.describe('form item & view form', () => {
test('configure fields', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel('schema-initializer-Grid-ReadPrettyFormItemInitializers-general').hover();
},
supportedOptions: [
'color',
'email',
'icon',
'singleLineText',
'integer',
'number',
'password',
'percent',
'phone',
'longText',
'url',
],
});
});
});
test.describe('table column & table', () => {
test('configure columns', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByLabel('schema-initializer-TableV2-').hover();
},
supportedOptions: [
'color',
'email',
'icon',
'singleLineText',
'integer',
'number',
'password',
'percent',
'phone',
'longText',
'url',
],
});
});
});

View File

@ -0,0 +1,239 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndBasicFields,
test,
} from '@nocobase/test/e2e';
import {
clickDeleteAndOk,
createColumnItem,
showSettingsMenu,
testDisplayTitle,
testEditDescription,
testEditFieldTitle,
testPattern,
testRequired,
} from '../../utils';
test.describe('form item & create form', () => {
test('set default value', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.color-color`).hover();
await page.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.color`).hover();
// 简单测试下是否有选项,值的话无法选中,暂时测不了
await expect(page.getByRole('menuitem', { name: 'Set default value' })).toBeVisible();
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: async () => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
},
openDialog: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
},
showMenu: async () => {
await page.getByLabel(`block-item-CollectionField-general-form-general.color-color`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.color`)
.hover();
},
expectEditable: async () => {
// 默认情况下显示颜色选择框
await page.getByLabel('color-picker-normal').hover();
await expect(page.getByRole('button', { name: 'right Recommended', exact: true })).toBeVisible();
},
expectReadonly: async () => {
// 只读模式下,不会显示颜色弹窗
await page.getByLabel('color-picker-normal').hover();
await expect(page.getByRole('button', { name: 'right Recommended', exact: true })).not.toBeVisible();
},
expectEasyReading: async () => {
await expect(page.getByLabel('color-picker-read-pretty')).toBeVisible();
},
});
});
test('edit field title', async ({ page, mockPage, mockRecord, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.color-color`).hover();
await page.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.color`).hover();
await testEditFieldTitle(page);
});
test('display title', async ({ page, mockPage, mockRecord, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.color-color`).hover();
await page.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.color`).hover();
await testDisplayTitle(page, 'color');
});
test('delete', async ({ page, mockPage, mockRecord, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.color-color`).hover();
await page.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.color`).hover();
await clickDeleteAndOk(page);
await expect(page.getByText(`color:`)).not.toBeVisible();
});
test('edit description', async ({ page, mockPage, mockRecord, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.color-color`).hover();
await page.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.color`).hover();
await testEditDescription(page);
});
test('required', async ({ page, mockPage, mockRecord, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.color-color`).hover();
await page.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.color`).hover();
await testRequired(page);
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.color-color`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.color`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit description', 'Required', 'Pattern', 'Delete'],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
let record = null;
await testPattern({
page,
gotoPage: async () => {
record = await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
},
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'color'),
expectEditable: async () => {
// 默认情况下显示颜色选择框
await page.getByLabel('color-picker-normal').hover();
await expect(page.getByRole('button', { name: 'right Recommended', exact: true })).toBeVisible();
},
expectReadonly: async () => {
// 只读模式下,不会显示颜色弹窗
await page.getByLabel('color-picker-normal').hover();
await expect(page.getByRole('button', { name: 'right Recommended', exact: true })).not.toBeVisible();
},
expectEasyReading: async () => {
await expect(page.getByLabel('color-picker-read-pretty')).toBeVisible();
},
});
});
});
test.describe('form item & view form', () => {
test('edit field title', async ({ page, mockPage, mockRecord, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.color-color`).hover();
await page.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.color`).hover();
await testEditFieldTitle(page);
});
test('display title', async ({ page, mockPage, mockRecord, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.color-color`).hover();
await page.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.color`).hover();
await testDisplayTitle(page, 'color');
});
test('delete', async ({ page, mockPage, mockRecord, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.color-color`).hover();
await page.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.color`).hover();
await clickDeleteAndOk(page);
await expect(page.getByText(`color:`)).not.toBeVisible();
});
test('edit tooltip', async ({ page, mockPage, mockRecord, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.color-color`).hover();
await page.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.color`).hover();
await page.getByRole('menuitem', { name: 'Edit tooltip' }).click();
await page.getByRole('dialog').getByRole('textbox').click();
await page.getByRole('dialog').getByRole('textbox').fill('testing edit tooltip');
await page.getByRole('button', { name: 'OK', exact: true }).click();
await page.getByRole('img', { name: 'question-circle' }).hover();
await expect(page.getByText('testing edit tooltip')).toBeVisible();
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'color');
await showSettingsMenu(page, 'color');
},
supportedOptions: ['Custom column title', 'Column width', 'Delete'],
});
});
});

View File

@ -0,0 +1,71 @@
import {
expectInitializerMenu,
oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields,
test,
} from '@nocobase/test/e2e';
test.describe('form item & create form', () => {
test('configure fields', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel('schema-initializer-Grid-FormItemInitializers-general').hover();
},
supportedOptions: ['Created at', 'Last updated at', 'Created by', 'Last updated by', 'ID', 'Table OID'],
});
});
});
test.describe('form item & edit form', () => {
test('configure fields', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel('schema-initializer-Grid-FormItemInitializers-general').hover();
},
supportedOptions: ['Created at', 'Last updated at', 'Created by', 'Last updated by', 'ID', 'Table OID'],
});
});
});
test.describe('form item & view form', () => {
test('configure fields', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View').click();
await page.getByLabel('schema-initializer-Grid-ReadPrettyFormItemInitializers-general').hover();
},
supportedOptions: ['Created at', 'Last updated at', 'Created by', 'Last updated by', 'ID', 'Table OID'],
});
});
});
test.describe('table column & table', () => {
test('configure columns', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByLabel('schema-initializer-TableV2-').hover();
},
supportedOptions: ['Created at', 'Last updated at', 'Created by', 'Last updated by', 'ID', 'Table OID'],
});
});
});

View File

@ -0,0 +1,152 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.createdAt-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.createdAt`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit tooltip',
'Pattern',
'Date display format',
'Delete',
],
});
});
test('options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await nocoPage.goto();
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.createdAt-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.createdAt`)
.hover();
await expect(page.getByRole('menuitem', { name: 'Edit tooltip' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Date display format' })).toBeVisible();
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.createdAt-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.createdAt`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit tooltip',
'Pattern',
'Date display format',
'Delete',
],
});
});
test('options', async ({ page, mockPage, mockRecord }) => {
await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'createdAt');
await expect(page.getByRole('menuitem', { name: 'Edit tooltip' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Date display format' })).toBeVisible();
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.createdAt-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.createdAt`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip', 'Date display format'],
unsupportedOptions: ['Set default value'],
});
});
test('options', async ({ page, mockPage, mockRecord }) => {
await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'createdAt');
await expect(page.getByRole('menuitem', { name: 'Date display format' })).toBeVisible();
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'Created at');
await showSettingsMenu(page, 'Created at');
},
supportedOptions: ['Custom column title', 'Column width', 'Sortable', 'Date display format', 'Delete'],
});
});
});

View File

@ -0,0 +1,138 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.createdBy-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.createdBy`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit tooltip', 'Enable link', 'Pattern', 'Delete'],
});
});
test('options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await nocoPage.goto();
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.createdBy-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.createdBy`)
.hover();
await expect(page.getByRole('menuitem', { name: 'Edit tooltip' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Enable link' })).toBeVisible();
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.createdBy-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.createdBy`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit tooltip', 'Pattern', 'Enable link', 'Delete'],
});
});
test('options', async ({ page, mockPage, mockRecord }) => {
await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'createdBy');
await expect(page.getByRole('menuitem', { name: 'Edit tooltip' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Enable link' })).toBeVisible();
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.createdBy-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.createdBy`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip', 'Enable link'],
unsupportedOptions: ['Set default value'],
});
});
test('options', async ({ page, mockPage, mockRecord }) => {
await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'createdBy');
await expect(page.getByRole('menuitem', { name: 'Enable link' })).toBeVisible();
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'Created by');
await showSettingsMenu(page, 'Created by');
},
supportedOptions: ['Custom column title', 'Column width', 'Enable link', 'Delete'],
});
});
});

View File

@ -0,0 +1,71 @@
import {
expectInitializerMenu,
oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields,
test,
} from '@nocobase/test/e2e';
test.describe('form item & create form', () => {
test('configure fields', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel('schema-initializer-Grid-FormItemInitializers-general').hover();
},
supportedOptions: ['datetime', 'time'],
});
});
});
test.describe('form item & edit form', () => {
test('configure fields', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel('schema-initializer-Grid-FormItemInitializers-general').hover();
},
supportedOptions: ['datetime', 'time'],
});
});
});
test.describe('form item & view form', () => {
test('configure fields', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel('schema-initializer-Grid-ReadPrettyFormItemInitializers-general').hover();
},
supportedOptions: ['datetime', 'time'],
});
});
});
test.describe('table column & table', () => {
test('configure columns', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectInitializerMenu({
page,
showMenu: async () => {
await page.getByLabel('schema-initializer-TableV2-').hover();
},
supportedOptions: ['datetime', 'time'],
});
});
});

View File

@ -0,0 +1,327 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields,
test,
} from '@nocobase/test/e2e';
import dayjs from 'dayjs';
import { createColumnItem, showSettingsMenu, testDefaultValue, testPattern } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.datetime-datetime`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.datetime`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set default value',
'Pattern',
'Date display format',
'Delete',
],
});
});
test('set default value', async ({ page, mockPage, mockRecord }) => {
await testDefaultValue({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'datetime'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').getByPlaceholder('Select date').click();
await page.getByText('Today').click();
},
expectConstantValue: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.datetime-datetime')
.getByPlaceholder('Select date'),
).toHaveValue(dayjs().format('YYYY-MM-DD'));
},
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
await testPattern({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'datetime'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.datetime-datetime')
.getByPlaceholder('Select date')
.click();
await page.getByText('Today').click();
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.datetime-datetime')
.getByPlaceholder('Select date'),
).toBeDisabled();
},
expectEasyReading: async () => {
await expect(page.getByLabel('block-item-CollectionField-general-form-general.datetime-datetime')).toHaveText(
`datetime:${dayjs().format('YYYY-MM-DD')}`,
);
},
});
});
test('date display format', async ({ page, mockPage, mockRecord }) => {
await (async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
await nocoPage.goto();
})(mockPage);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'datetime');
await page.getByRole('menuitem', { name: 'Date display format' }).click();
await page.getByLabel('YYYY/MM/DD').click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 输入一个值,然后验证格式是否正确
await page
.getByLabel('block-item-CollectionField-general-form-general.datetime-datetime')
.getByPlaceholder('Select date')
.click();
await page.getByText('Today').click();
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.datetime-datetime')
.getByPlaceholder('Select date'),
).toHaveValue(dayjs().format('YYYY/MM/DD'));
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.datetime-datetime`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.datetime`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Pattern',
'Date display format',
'Delete',
],
unsupportedOptions: ['Set default value'],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
let record = null;
await testPattern({
page,
gotoPage: async () => {
record = await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
},
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'datetime'),
expectEditable: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.datetime-datetime')
.getByPlaceholder('Select date'),
).toHaveValue(dayjs(record.datetime).format('YYYY-MM-DD'));
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.datetime-datetime')
.getByPlaceholder('Select date'),
).toBeDisabled();
},
expectEasyReading: async () => {
await expect(page.getByLabel('block-item-CollectionField-general-form-general.datetime-datetime')).toHaveText(
`datetime:${dayjs(record.datetime).format('YYYY-MM-DD')}`,
);
},
});
});
test('date display format', async ({ page, mockPage, mockRecord }) => {
const record = await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'datetime');
await page.getByRole('menuitem', { name: 'Date display format' }).click();
await page.getByLabel('YYYY/MM/DD').click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.datetime-datetime')
.getByPlaceholder('Select date'),
).toHaveValue(dayjs(record.datetime).format('YYYY/MM/DD'));
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.datetime-datetime`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.datetime`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip', 'Date display format'],
unsupportedOptions: ['Set default value'],
});
});
test('date display format', async ({ page, mockPage, mockRecord }) => {
const record = await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'datetime');
await page.getByRole('menuitem', { name: 'Date display format' }).click();
await page.getByLabel('YYYY/MM/DD').click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.datetime-datetime')).toHaveText(
`datetime:${dayjs(record.datetime).format('YYYY/MM/DD')}`,
);
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'datetime');
await showSettingsMenu(page, 'datetime');
},
supportedOptions: ['Custom column title', 'Column width', 'Sortable', 'Date display format', 'Delete'],
});
});
test('date display format', async ({ page, mockPage, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
const records = await mockRecords('general', 1);
await nocoPage.goto();
await createColumnItem(page, 'datetime');
await showSettingsMenu(page, 'datetime');
await page.getByRole('menuitem', { name: 'Date display format' }).click();
await page.getByLabel('MM/DD/YY').click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
await expect(
page.getByRole('cell', { name: dayjs(records[0].datetime).format('MM/DD/YY'), exact: true }),
).toBeVisible();
});
});

View File

@ -0,0 +1,223 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndBasicFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testDefaultValue, testPattern } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.email-email`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.email`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Pattern',
'Delete',
'required',
'Set default value',
],
});
});
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'email'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
constantValue: 'test@nocobase.com',
variableValue: ['Current user', 'Email'],
expectConstantValue: () =>
expect(
page.getByLabel('block-item-CollectionField-general-form-general.email-email').getByRole('textbox'),
).toHaveValue('test@nocobase.com'),
expectVariableValue: () =>
expect(
page.getByLabel('block-item-CollectionField-general-form-general.email-email').getByRole('textbox'),
).toHaveValue('admin@nocobase.com'),
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'email'),
expectEditable: async () => {
// 填充一个值,方便后面断言
await page
.getByLabel('block-item-CollectionField-general-form-general.email-email')
.getByRole('textbox')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.email-email')
.getByRole('textbox')
.fill('admin@nocobase.com');
},
expectReadonly: async () => {
// 输入框应该被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.email-email').getByRole('textbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框应该消失,直接显示值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.email-email').getByRole('textbox'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.email-email')).toHaveText(
'email:admin@nocobase.com',
);
},
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.email-email`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.email`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit description', 'Required', 'Pattern', 'Delete'],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
let record = null;
await testPattern({
page,
gotoPage: async () => {
record = await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
},
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'email'),
expectEditable: async () => {
// 应该显示 record 中的值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.email-email').getByRole('textbox'),
).toHaveValue(record.email);
},
expectReadonly: async () => {
// 输入框应该被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.email-email').getByRole('textbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框应该消失,直接显示值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.email-email').getByRole('textbox'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.email-email')).toHaveText(
`email:${record.email}`,
);
},
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.email-email`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.email`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'email');
await showSettingsMenu(page, 'email');
},
supportedOptions: ['Custom column title', 'Column width', 'Sortable', 'Delete'],
});
});
});

View File

@ -0,0 +1,79 @@
import { expectSettingsMenu, oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields, test } from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.formula-formula`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.formula`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit tooltip', 'Pattern', 'Delete'],
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.formula-formula`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.formula`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit tooltip', 'Pattern', 'Delete'],
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.formula-formula`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.formula`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'formula');
await showSettingsMenu(page, 'formula');
},
supportedOptions: ['Custom column title', 'Column width', 'Sortable', 'Delete'],
});
});
});

View File

@ -0,0 +1,543 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndAssociationFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testPattern } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecords('users', 3);
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.oneToOneHasOne-oneToOneHasOne`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.oneToOneHasOne`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set the data scope',
'Set default sorting rules',
'Field component',
'Quick create',
'Pattern',
'Title field',
'Delete',
],
});
});
test('set default value', async ({ page, mockPage, mockRecord, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneHasOne');
await expect(page.getByRole('menuitem', { name: 'Set default value' })).not.toBeVisible();
});
test('pattern', async ({ page, mockPage, mockRecords }) => {
let records;
await testPattern({
page,
gotoPage: async () => {
records = await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
},
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneHasOne'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.oneToOneHasOne-oneToOneHasOne')
.getByTestId(/select-object/)
.click();
// 目前的情况下,在 one to one (has one) 的字段中,只有 ID 为 1 的数据可以被选中mock 的数据无法被选中
await page.getByRole('option', { name: '1', exact: true }).click();
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.oneToOneHasOne-oneToOneHasOne')
.getByTestId(/select-object/),
).toHaveClass(/ant-select-disabled/);
// 在这里等待一下,防止因闪烁导致下面的断言失败
await page.waitForTimeout(100);
},
expectEasyReading: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.oneToOneHasOne-oneToOneHasOne'),
).toHaveText(`oneToOneHasOne:1`);
},
});
});
test('Set the data scope', async ({ page, mockPage, mockRecords }) => {
const records = await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneHasOne');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await page.getByText('Add condition', { exact: true }).click();
await page.getByTestId('select-filter-field').click();
await page.getByRole('menuitemcheckbox', { name: 'ID', exact: true }).click();
await page.getByRole('spinbutton').click();
await page.getByRole('spinbutton').fill(String(records[0].id));
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 再次打开弹窗,设置的值应该还在
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneHasOne');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await expect(page.getByTestId('select-filter-field')).toHaveText('ID');
await expect(page.getByRole('spinbutton')).toHaveValue(String(records[0].id));
await page.getByRole('button', { name: 'Cancel', exact: true }).click();
// 数据应该被过滤了
await page
.getByLabel('block-item-CollectionField-general-form-general.oneToOneHasOne-oneToOneHasOne')
.getByTestId('select-object-single')
.click();
// 默认只显示 id 为 1 的数据,因为设置了只过滤 id 为 3 的数据,所以这里的下拉列表应该为空
await expect(page.getByRole('option')).toHaveCount(0);
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneHasOne');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Select', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Record picker', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form(Popover)', exact: true })).toBeVisible();
});
test('quick create', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneHasOne');
await expect(page.getByRole('menuitem', { name: 'Quick create' })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneHasOne');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockRecords, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecords('users', 3);
await mockRecords('general', 1);
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.oneToOneHasOne-oneToOneHasOne`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.oneToOneHasOne`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set the data scope',
'Set default sorting rules',
'Field component',
'Quick create',
'Pattern',
'Title field',
'Delete',
],
unsupportedOptions: ['Set default value'],
});
});
test('pattern', async ({ page, mockPage, mockRecords }) => {
let record;
await testPattern({
page,
gotoPage: async () => {
record = (
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords)
).record;
},
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneHasOne'),
expectEditable: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.oneToOneHasOne-oneToOneHasOne')
.getByTestId(/select-object/),
).toHaveText(`${record.oneToOneHasOne.id}`);
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.oneToOneHasOne-oneToOneHasOne')
.getByTestId(/select-object/),
).toHaveClass(/ant-select-disabled/);
// 在这里等待一下,防止因闪烁导致下面的断言失败
await page.waitForTimeout(100);
},
expectEasyReading: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.oneToOneHasOne-oneToOneHasOne'),
).toHaveText(`oneToOneHasOne:${record.oneToOneHasOne.id}`);
},
});
});
test('Set the data scope', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneHasOne');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await page.getByText('Add condition', { exact: true }).click();
await page.getByTestId('select-filter-field').click();
await page.getByRole('menuitemcheckbox', { name: 'ID', exact: true }).click();
await page.getByRole('spinbutton').click();
await page.getByRole('spinbutton').fill('1');
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 再次打开弹窗,设置的值应该还在
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneHasOne');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await expect(page.getByTestId('select-filter-field')).toHaveText('ID');
await expect(page.getByRole('spinbutton')).toHaveValue('1');
await page.getByRole('button', { name: 'Cancel', exact: true }).click();
// 数据应该被过滤了
await page
.getByLabel('block-item-CollectionField-general-form-general.oneToOneHasOne-oneToOneHasOne')
.getByTestId(/select-object/)
.click();
await expect(page.getByRole('option')).toHaveCount(2);
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneHasOne');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Select', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Record picker', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form(Popover)', exact: true })).toBeVisible();
});
test('quick create', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneHasOne');
await expect(page.getByRole('menuitem', { name: 'Quick create' })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneHasOne');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecords('general', 1);
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.oneToOneHasOne-oneToOneHasOne`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.oneToOneHasOne`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit tooltip',
'Field component',
'Enable link',
'Title field',
'Delete',
],
unsupportedOptions: ['Set default value'],
});
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return record;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneHasOne');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Title', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Tag', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-details', exact: true })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return record;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneHasOne');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
test('enable link', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return record;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToOneHasOne');
await expect(page.getByRole('menuitem', { name: 'Enable link' }).getByRole('switch')).toBeChecked();
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'oneToOneHasOne');
await showSettingsMenu(page, 'oneToOneHasOne');
},
supportedOptions: [
'Custom column title',
'Column width',
'Enable link',
'Title field',
'Field component',
'Delete',
],
});
});
});

View File

@ -0,0 +1,201 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndBasicFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testDefaultValue, testPattern } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.icon-icon`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.icon`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Pattern',
'Delete',
'required',
'Set default value',
],
});
});
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'icon'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').getByRole('button', { name: 'Select icon' }).click();
await page.getByLabel('account-book').locator('svg').click();
},
expectConstantValue: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.icon-icon')
.getByRole('button', { name: 'account-book' }),
).toBeVisible();
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'icon'),
expectEditable: async () => {
// 默认情况下可以编辑图标
await page.getByRole('button', { name: 'Select icon' }).click();
await page.getByLabel('account-book').locator('svg').click();
},
expectReadonly: async () => {
// 只读模式下,选择图标按钮会被禁用
await expect(page.getByRole('button', { name: 'account-book' })).toBeDisabled();
},
expectEasyReading: async () => {
// 按钮会消失,只剩下图标
await expect(page.getByRole('button', { name: 'account-book' })).not.toBeVisible();
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.icon-icon').getByLabel('account-book'),
).toBeVisible();
},
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.icon-icon`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.icon`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit description', 'Required', 'Pattern', 'Delete'],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
let record: any = null;
await testPattern({
page,
gotoPage: async () => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
record = await mockRecord('general');
await nocoPage.goto();
},
openDialog: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
},
showMenu: async () => {
await page.getByLabel(`block-item-CollectionField-general-form-general.icon-icon`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.icon`)
.hover();
},
expectEditable: async () => {
// 默认情况下可以编辑图标
await page.getByRole('button', { name: 'Select icon' }).click();
await page.getByLabel('account-book').locator('svg').click();
},
expectReadonly: async () => {
await expect(page.getByRole('button', { name: 'account-book' })).toBeDisabled();
},
expectEasyReading: async () => {
await expect(page.getByRole('button', { name: 'account-book' })).not.toBeVisible();
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.icon-icon').getByLabel('account-book'),
).toBeVisible();
},
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.icon-icon`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.icon`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'icon');
await showSettingsMenu(page, 'icon');
},
supportedOptions: ['Custom column title', 'Column width', 'Delete'],
});
});
});

View File

@ -0,0 +1,108 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.id-`).hover();
await page.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.id`).hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit tooltip', 'Pattern', 'Delete'],
});
});
test('options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await nocoPage.goto();
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.id-`).hover();
await page.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.id`).hover();
await expect(page.getByRole('menuitem', { name: 'Edit tooltip' })).toBeVisible();
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.id-`).hover();
await page.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.id`).hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit tooltip', 'Pattern', 'Delete'],
});
});
test('options', async ({ page, mockPage, mockRecord }) => {
await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'id');
await expect(page.getByRole('menuitem', { name: 'Edit tooltip' })).toBeVisible();
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.id-`).hover();
await page.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.id`).hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'ID');
await showSettingsMenu(page, 'ID');
},
supportedOptions: ['Custom column title', 'Column width', 'Sortable', 'Delete'],
});
});
});

View File

@ -0,0 +1,284 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndBasicFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testDefaultValue, testPattern, testSetValidationRules } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.integer-integer`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.integer`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Pattern',
'Delete',
'required',
'Set default value',
'Set validation rules',
],
});
});
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'integer'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
variableValue: ['Current user', 'ID'], // 值为 1
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').getByRole('spinbutton').click();
await page.getByLabel('block-item-VariableInput-').getByRole('spinbutton').fill('112233');
},
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.integer-integer').getByRole('spinbutton'),
).toHaveValue('112233');
},
expectVariableValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.integer-integer').getByRole('spinbutton'),
).toHaveValue('1');
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'integer'),
expectEditable: async () => {
// 默认情况下可以编辑
await page
.getByLabel('block-item-CollectionField-general-form-general.integer-integer')
.getByRole('spinbutton')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.integer-integer')
.getByRole('spinbutton')
.fill('112233');
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.integer-integer').getByRole('spinbutton'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框会消失,只剩下值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.integer-integer').getByRole('spinbutton'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.integer-integer')).toHaveText(
'integer:112233',
);
},
});
});
test('set validation rules', async ({ page, mockPage }) => {
await testSetValidationRules({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'integer'),
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.integer-integer`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.integer`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set validation rules',
'Pattern',
'Delete',
],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
let record: any = null;
await testPattern({
page,
gotoPage: async () => {
record = await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
},
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'integer'),
expectEditable: async () => {
// 应该显示 record 中的值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.integer-integer').getByRole('spinbutton'),
).toHaveValue(String(record.integer));
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.integer-integer').getByRole('spinbutton'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框会消失,只剩下值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.integer-integer').getByRole('spinbutton'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.integer-integer')).toHaveText(
`integer:${record.integer}`,
);
},
});
});
test('set validation rules', async ({ page, mockPage, mockRecord }) => {
await testSetValidationRules({
page,
gotoPage: () =>
(async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord),
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'integer'),
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.integer-integer`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.integer`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'integer');
await showSettingsMenu(page, 'integer');
},
supportedOptions: ['Custom column title', 'Column width', 'Sortable', 'Delete'],
});
});
});

View File

@ -0,0 +1,87 @@
import { expectSettingsMenu, oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields, test } from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.JSON-JSON`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.JSON`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set default value',
'Pattern',
'Delete',
],
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.JSON-JSON`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.JSON`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit description', 'Required', 'Pattern', 'Delete'],
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.JSON-JSON`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.JSON`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'JSON');
await showSettingsMenu(page, 'JSON');
},
supportedOptions: ['Custom column title', 'Column width', 'Sortable', 'Delete'],
});
});
});

View File

@ -0,0 +1,93 @@
import { expectSettingsMenu, oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields, test } from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.updatedAt-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.updatedAt`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit tooltip',
'Pattern',
'Date display format',
'Delete',
],
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.updatedAt-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.updatedAt`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit tooltip',
'Pattern',
'Date display format',
'Delete',
],
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.updatedAt-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.updatedAt`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip', 'Date display format'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'Last updated at');
await showSettingsMenu(page, 'Last updated at');
},
supportedOptions: ['Custom column title', 'Column width', 'Sortable', 'Date display format', 'Delete'],
});
});
});

View File

@ -0,0 +1,138 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.updatedBy-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.updatedBy`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit tooltip', 'Enable link', 'Pattern', 'Delete'],
});
});
test('options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await nocoPage.goto();
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.updatedBy-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.updatedBy`)
.hover();
await expect(page.getByRole('menuitem', { name: 'Edit tooltip' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Enable link' })).toBeVisible();
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.updatedBy-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.updatedBy`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit tooltip', 'Pattern', 'Enable link', 'Delete'],
});
});
test('options', async ({ page, mockPage, mockRecord }) => {
await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'updatedBy');
await expect(page.getByRole('menuitem', { name: 'Edit tooltip' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Enable link' })).toBeVisible();
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.updatedBy-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.updatedBy`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip', 'Enable link'],
unsupportedOptions: ['Set default value'],
});
});
test('options', async ({ page, mockPage, mockRecord }) => {
await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'updatedBy');
await expect(page.getByRole('menuitem', { name: 'Enable link' })).toBeVisible();
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'Last updated by');
await showSettingsMenu(page, 'Last updated by');
},
supportedOptions: ['Custom column title', 'Column width', 'Enable link', 'Delete'],
});
});
});

View File

@ -0,0 +1,286 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndBasicFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testDefaultValue, testPattern, testSetValidationRules } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.longText-longText`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.longText`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Pattern',
'Delete',
'required',
'Set default value',
'Set validation rules',
],
});
});
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
closeDialog: async () => {
await page.getByLabel('drawer-Action.Container-general-Add record-mask').click();
},
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'longText'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
constantValue: 'test long text',
variableValue: ['Current user', 'Email'], // 值为 admin@nocobase.com
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.longText-longText').getByRole('textbox'),
).toHaveValue('test long text');
},
expectVariableValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.longText-longText').getByRole('textbox'),
).toHaveValue('admin@nocobase.com');
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'longText'),
expectEditable: async () => {
// 默认情况下可以编辑
await page
.getByLabel('block-item-CollectionField-general-form-general.longText-longText')
.getByRole('textbox')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.longText-longText')
.getByRole('textbox')
.fill('test long text');
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.longText-longText').getByRole('textbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框会消失,只剩下值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.longText-longText').getByRole('textbox'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.longText-longText')).toHaveText(
'longText:test long text',
);
},
});
});
test('set validation rules', async ({ page, mockPage }) => {
await testSetValidationRules({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'longText'),
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.longText-longText`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.longText`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set validation rules',
'Pattern',
'Delete',
],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
let record: any = null;
await testPattern({
page,
gotoPage: async () => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
record = await mockRecord('general');
await nocoPage.goto();
},
openDialog: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
},
showMenu: async () => {
await page.getByLabel(`block-item-CollectionField-general-form-general.longText-longText`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.longText`)
.hover();
},
expectEditable: async () => {
// 应该显示 record 中的值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.longText-longText').getByRole('textbox'),
).toHaveValue(record.longText);
// 默认情况下可以编辑
await page
.getByLabel('block-item-CollectionField-general-form-general.longText-longText')
.getByRole('textbox')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.longText-longText')
.getByRole('textbox')
.fill('test long text');
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.longText-longText').getByRole('textbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.longText-longText').getByRole('textbox'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.longText-longText')).toHaveText(
`longText:test long text`,
);
},
});
});
test('set validation rules', async ({ page, mockPage, mockRecord }) => {
await testSetValidationRules({
page,
gotoPage: () =>
(async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord),
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'longText'),
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.longText-longText`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.longText`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'longText');
await showSettingsMenu(page, 'longText');
},
supportedOptions: ['Custom column title', 'Column width', 'Delete'],
});
});
});

View File

@ -0,0 +1,769 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndAssociationFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testDefaultValue, testPattern } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecords('users', 3);
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.manyToMany-manyToMany`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.manyToMany`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set default value',
'Set the data scope',
'Set default sorting rules',
'Field component',
'Quick create',
'Allow multiple',
'Pattern',
'Title field',
'Delete',
],
});
});
test('set default value', async ({ page, mockPage, mockRecords }) => {
let recordsOfUser;
await testDefaultValue({
page,
gotoPage: async () => {
recordsOfUser = await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
},
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').getByTestId('select-object-multiple').click();
await page.getByRole('option', { name: String(recordsOfUser[0].id), exact: true }).click();
await page.getByRole('option', { name: String(recordsOfUser[1].id), exact: true }).click();
await page.getByRole('option', { name: String(recordsOfUser[2].id), exact: true }).click();
},
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany'),
).toHaveText(`manyToMany:${recordsOfUser.map((record) => record.id).join('')}`);
},
});
});
test('pattern', async ({ page, mockPage, mockRecords }) => {
let records;
await testPattern({
page,
gotoPage: async () => {
records = await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
},
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.getByTestId('select-object-multiple')
.click();
await page.getByRole('option', { name: String(records[0].id), exact: true }).click();
await page.getByRole('option', { name: String(records[1].id), exact: true }).click();
await page.getByRole('option', { name: String(records[2].id), exact: true }).click();
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.getByTestId('select-object-multiple'),
).toHaveClass(/ant-select-disabled/);
// 在这里等待一下,防止因闪烁导致下面的断言失败
await page.waitForTimeout(100);
},
expectEasyReading: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany'),
).toHaveText(`manyToMany:${records.map((record) => record.id).join(',')}`);
},
});
});
test('Set the data scope', async ({ page, mockPage, mockRecords }) => {
const records = await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await page.getByText('Add condition', { exact: true }).click();
await page.getByTestId('select-filter-field').click();
await page.getByRole('menuitemcheckbox', { name: 'ID', exact: true }).click();
await page.getByRole('spinbutton').click();
await page.getByRole('spinbutton').fill(String(records[0].id));
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 再次打开弹窗,设置的值应该还在
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await expect(page.getByTestId('select-filter-field')).toHaveText('ID');
await expect(page.getByRole('spinbutton')).toHaveValue(String(records[0].id));
await page.getByRole('button', { name: 'Cancel', exact: true }).click();
// 数据应该被过滤了
await page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.getByTestId('select-object-multiple')
.click();
await expect(page.getByRole('option', { name: String(records[0].id), exact: true })).toBeVisible();
await expect(page.getByRole('option')).toHaveCount(1);
});
test('set default sorting rules', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Set default sorting rules' }).click();
// 配置
await page.getByRole('button', { name: 'Add sort field' }).click();
await page.getByTestId('select-single').click();
await page.getByRole('option', { name: 'ID', exact: true }).click();
await page.getByText('DESC', { exact: true }).click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 再次打开弹窗,设置的值应该还在
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Set default sorting rules' }).click();
await expect(page.getByRole('dialog').getByTestId('select-single')).toHaveText('ID');
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Select', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Record picker', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-table', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form(Popover)', exact: true })).toBeVisible();
// 选择 Record picker
await page.getByRole('option', { name: 'Record picker', exact: true }).click();
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.getByTestId('select-data-picker'),
).toBeVisible();
// 选择 Sub-table
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Field component' }).click();
await page.getByRole('option', { name: 'Sub-table', exact: true }).click();
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.getByLabel('schema-initializer-AssociationField.SubTable-TableColumnInitializers-users'),
).toBeVisible();
// 选择 Sub-form
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Field component' }).click();
await page.getByRole('option', { name: 'Sub-form', exact: true }).click();
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.getByLabel('schema-initializer-Grid-FormItemInitializers-users'),
).toBeVisible();
// 选择 Sub-form(Popover)
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Field component' }).click();
await page.getByRole('option', { name: 'Sub-form(Popover)', exact: true }).click();
await page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.getByRole('img', { name: 'edit' })
.click();
await expect(page.getByTestId('popover-CollectionField-general')).toBeVisible();
});
test('quick create', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany');
await expect(page.getByRole('menuitem', { name: 'Quick create' })).toBeVisible();
});
test('allow multiple', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany');
await expect(page.getByRole('menuitem', { name: 'Allow multiple' })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockRecords, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecords('users', 3);
await mockRecords('general', 1);
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.manyToMany-manyToMany`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.manyToMany`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set the data scope',
'Set default sorting rules',
'Field component',
'Quick create',
'Allow multiple',
'Pattern',
'Title field',
'Delete',
],
unsupportedOptions: ['Set default value'],
});
});
test('pattern', async ({ page, mockPage, mockRecords }) => {
let record;
await testPattern({
page,
gotoPage: async () => {
record = (
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords)
).record;
},
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany'),
expectEditable: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.getByTestId('select-object-multiple'),
).toHaveText(`${record.manyToMany.map((item) => item.id).join('')}`);
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.getByTestId('select-object-multiple'),
).toHaveClass(/ant-select-disabled/);
// 在这里等待一下,防止因闪烁导致下面的断言失败
await page.waitForTimeout(100);
},
expectEasyReading: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany'),
).toHaveText(`manyToMany:${record.manyToMany.map((item) => item.id).join(',')}`);
},
});
});
test('Set the data scope', async ({ page, mockPage, mockRecords }) => {
const { recordsOfUser } = await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await page.getByText('Add condition', { exact: true }).click();
await page.getByTestId('select-filter-field').click();
await page.getByRole('menuitemcheckbox', { name: 'ID', exact: true }).click();
await page.getByRole('spinbutton').click();
await page.getByRole('spinbutton').fill(String(recordsOfUser[0].id));
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 再次打开弹窗,设置的值应该还在
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await expect(page.getByTestId('select-filter-field')).toHaveText('ID');
await expect(page.getByRole('spinbutton')).toHaveValue(String(recordsOfUser[0].id));
await page.getByRole('button', { name: 'Cancel', exact: true }).click();
// 数据应该被过滤了
await page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.getByTestId('select-object-multiple')
.click();
await expect(page.getByRole('option', { name: String(recordsOfUser[0].id), exact: true })).toBeVisible();
});
test('set default sorting rules', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Set default sorting rules' }).click();
// 配置
await page.getByRole('button', { name: 'Add sort field' }).click();
await page.getByTestId('select-single').click();
await page.getByRole('option', { name: 'ID', exact: true }).click();
await page.getByText('DESC', { exact: true }).click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 再次打开弹窗,设置的值应该还在
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Set default sorting rules' }).click();
await expect(page.getByRole('dialog').getByTestId('select-single')).toHaveText('ID');
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Select', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Record picker', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-table', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form(Popover)', exact: true })).toBeVisible();
});
test('quick create', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany');
await expect(page.getByRole('menuitem', { name: 'Quick create' })).toBeVisible();
});
test('allow multiple', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany');
await expect(page.getByRole('menuitem', { name: 'Allow multiple' })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecords('general', 1);
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.manyToMany-manyToMany`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.manyToMany`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit tooltip',
'Field component',
'Enable link',
'Title field',
'Delete',
],
unsupportedOptions: ['Set default value'],
});
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return record;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Title', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Tag', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-details', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-table', exact: true })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return record;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
test('enable link', async ({ page, mockPage, mockRecords }) => {
// test.fail();
const record = await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return record;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
})(page);
// 初始状态是一个可点击的链接
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.locator('a')
.filter({ hasText: record.manyToMany[0].id }),
).toBeVisible();
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToMany');
// 默认情况下是开启状态
await expect(page.getByRole('menuitem', { name: 'Enable link' }).getByRole('switch')).toBeChecked();
await page.getByRole('menuitem', { name: 'Enable link' }).click();
await expect(page.getByRole('menuitem', { name: 'Enable link' }).getByRole('switch')).not.toBeChecked();
// 应变为非链接状态
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.locator('a')
.filter({ hasText: record.manyToMany[0].id }),
).not.toBeVisible();
// 再次开启链接状态
await page.getByRole('menuitem', { name: 'Enable link' }).click();
await expect(page.getByRole('menuitem', { name: 'Enable link' }).getByRole('switch')).toBeChecked();
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.locator('a')
.filter({ hasText: record.manyToMany[0].id }),
).toBeVisible();
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'manyToMany');
await showSettingsMenu(page, 'manyToMany');
},
supportedOptions: [
'Custom column title',
'Column width',
'Enable link',
'Title field',
'Field component',
'Delete',
],
});
});
});

View File

@ -0,0 +1,639 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndAssociationFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testDefaultValue, testPattern } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecords('users', 3);
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.manyToOne-manyToOne`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.manyToOne`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set default value',
'Set the data scope',
'Set default sorting rules',
'Field component',
'Quick create',
'Pattern',
'Title field',
'Delete',
],
});
});
test('set default value', async ({ page, mockPage, mockRecords }) => {
let records;
await testDefaultValue({
page,
gotoPage: async () => {
records = await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
},
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToOne'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page
.getByLabel('block-item-VariableInput-')
.getByTestId(/select-object/)
.click();
await page.getByRole('option', { name: String(records[0].id), exact: true }).click();
await page
.getByLabel('block-item-VariableInput-')
.getByTestId(/select-object/)
.click();
await page.getByRole('option', { name: String(records[1].id), exact: true }).click();
await page
.getByLabel('block-item-VariableInput-')
.getByTestId(/select-object/)
.click();
await page.getByRole('option', { name: String(records[2].id), exact: true }).click();
},
expectConstantValue: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.manyToOne-manyToOne')
.getByTestId(/select-object/),
).toHaveText(String(records[2].id));
},
});
});
test('pattern', async ({ page, mockPage, mockRecords }) => {
let records;
await testPattern({
page,
gotoPage: async () => {
records = await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
},
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToOne'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.manyToOne-manyToOne')
.getByTestId(/select-object/)
.click();
await page.getByRole('option', { name: String(records[0].id), exact: true }).click();
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.manyToOne-manyToOne')
.getByTestId(/select-object/),
).toHaveClass(/ant-select-disabled/);
// 在这里等待一下,防止因闪烁导致下面的断言失败
await page.waitForTimeout(100);
},
expectEasyReading: async () => {
await expect(page.getByLabel('block-item-CollectionField-general-form-general.manyToOne-manyToOne')).toHaveText(
`manyToOne:${String(records[0].id)}`,
);
},
});
});
test('Set the data scope', async ({ page, mockPage, mockRecords }) => {
const records = await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToOne');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await page.getByText('Add condition', { exact: true }).click();
await page.getByTestId('select-filter-field').click();
await page.getByRole('menuitemcheckbox', { name: 'ID', exact: true }).click();
await page.getByRole('spinbutton').click();
await page.getByRole('spinbutton').fill(String(records[0].id));
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 再次打开弹窗,设置的值应该还在
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToOne');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await expect(page.getByTestId('select-filter-field')).toHaveText('ID');
await expect(page.getByRole('spinbutton')).toHaveValue(String(records[0].id));
await page.getByRole('button', { name: 'Cancel', exact: true }).click();
// 数据应该被过滤了
await page
.getByLabel('block-item-CollectionField-general-form-general.manyToOne-manyToOne')
.getByTestId('select-object-single')
.click();
await expect(page.getByRole('option', { name: String(records[0].id), exact: true })).toBeVisible();
await expect(page.getByRole('option')).toHaveCount(1);
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToOne');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Select', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Record picker', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form(Popover)', exact: true })).toBeVisible();
});
test('quick create', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToOne');
await expect(page.getByRole('menuitem', { name: 'Quick create' })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToOne');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockRecords, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecords('users', 3);
await mockRecords('general', 1);
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.manyToOne-manyToOne`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.manyToOne`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set the data scope',
'Set default sorting rules',
'Field component',
'Quick create',
'Pattern',
'Title field',
'Delete',
],
unsupportedOptions: ['Set default value'],
});
});
test('pattern', async ({ page, mockPage, mockRecords }) => {
let record;
await testPattern({
page,
gotoPage: async () => {
record = (
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords)
).record;
},
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToOne'),
expectEditable: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.manyToOne-manyToOne')
.getByTestId(/select-object/),
).toHaveText(`${record.manyToOne.id}`);
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.manyToOne-manyToOne')
.getByTestId(/select-object/),
).toHaveClass(/ant-select-disabled/);
// 在这里等待一下,防止因闪烁导致下面的断言失败
await page.waitForTimeout(100);
},
expectEasyReading: async () => {
await expect(page.getByLabel('block-item-CollectionField-general-form-general.manyToOne-manyToOne')).toHaveText(
`manyToOne:${record.manyToOne.id}`,
);
},
});
});
test('Set the data scope', async ({ page, mockPage, mockRecords }) => {
const { recordsOfUser } = await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToOne');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await page.getByText('Add condition', { exact: true }).click();
await page.getByTestId('select-filter-field').click();
await page.getByRole('menuitemcheckbox', { name: 'ID', exact: true }).click();
await page.getByRole('spinbutton').click();
await page.getByRole('spinbutton').fill(String(recordsOfUser[0].id));
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 再次打开弹窗,设置的值应该还在
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToOne');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await expect(page.getByTestId('select-filter-field')).toHaveText('ID');
await expect(page.getByRole('spinbutton')).toHaveValue(String(recordsOfUser[0].id));
await page.getByRole('button', { name: 'Cancel', exact: true }).click();
// 数据应该被过滤了
await page
.getByLabel('block-item-CollectionField-general-form-general.manyToOne-manyToOne')
.getByTestId(/select-object/)
.click();
await expect(page.getByRole('option', { name: String(recordsOfUser[0].id), exact: true })).toBeVisible();
await expect(page.getByRole('option')).toHaveCount(2);
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToOne');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Select', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Record picker', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form(Popover)', exact: true })).toBeVisible();
});
test('quick create', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToOne');
await expect(page.getByRole('menuitem', { name: 'Quick create' })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToOne');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecords('general', 1);
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.manyToOne-manyToOne`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.manyToOne`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit tooltip',
'Field component',
'Enable link',
'Title field',
'Delete',
],
unsupportedOptions: ['Set default value'],
});
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return record;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToOne');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Title', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Tag', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-details', exact: true })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return record;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToOne');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
test('enable link', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return record;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'manyToOne');
await expect(page.getByRole('menuitem', { name: 'Enable link' }).getByRole('switch')).toBeChecked();
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'manyToOne');
await showSettingsMenu(page, 'manyToOne');
},
supportedOptions: [
'Custom column title',
'Column width',
'Enable link',
'Title field',
'Field component',
'Delete',
],
});
});
test('enable link', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
await createColumnItem(page, 'manyToOne');
await showSettingsMenu(page, 'manyToOne');
// 默认开启 enable link
await expect(page.getByRole('menuitem', { name: 'Enable link' }).getByRole('switch')).toBeChecked();
await expect(page.locator('a').filter({ has: page.getByText(record.manyToOne.id, { exact: true }) })).toBeVisible();
// 关闭 enable link
await page.getByRole('menuitem', { name: 'Enable link' }).click();
await expect(page.getByRole('menuitem', { name: 'Enable link' }).getByRole('switch')).not.toBeChecked();
await expect(page.locator('a').filter({ has: page.getByText(record.manyToOne.id, { exact: true }) })).toBeHidden();
// 再次开启
await page.getByRole('menuitem', { name: 'Enable link' }).click();
await expect(page.getByRole('menuitem', { name: 'Enable link' }).getByRole('switch')).toBeChecked();
await expect(page.locator('a').filter({ has: page.getByText(record.manyToOne.id, { exact: true }) })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
await createColumnItem(page, 'manyToOne');
await showSettingsMenu(page, 'manyToOne');
// 默认是 ID
await expect(page.getByRole('menuitem', { name: 'Title field' })).toHaveText('Title fieldID');
await expect(page.getByRole('cell', { name: record.manyToOne.id, exact: true })).toBeVisible();
// 修改为 nickname
await page.getByRole('menuitem', { name: 'Title field' }).click();
await page.getByRole('option', { name: 'Nickname' }).click();
await page.mouse.move(300, 0);
await expect(page.getByRole('cell', { name: record.manyToOne.nickname, exact: true })).toBeVisible();
});
test('field component', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
await createColumnItem(page, 'manyToOne');
await showSettingsMenu(page, 'manyToOne');
// 默认是 Title
await expect(page.getByRole('menuitem', { name: 'Field component' })).toHaveText('Field componentTitle');
// 修改为 Tag
await page.getByRole('menuitem', { name: 'Field component' }).click();
await page.getByRole('option', { name: 'Tag' }).click();
// 修改成功之后会显示 Tag color field 选项
await expect(page.getByRole('menuitem', { name: 'Tag color field' })).toBeVisible();
await expect(
page.getByRole('cell', { name: record.manyToOne.id, exact: true }).filter({ has: page.locator('.ant-tag') }),
).toBeVisible();
});
});

View File

@ -0,0 +1,280 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndMediaFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testDefaultValue, testPattern, testSetValidationRules } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.markdown-markdown`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.markdown`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set default value',
'Pattern',
'Delete',
'Set validation rules',
],
});
});
test('set default value', async ({ page, mockPage, mockRecord }) => {
await testDefaultValue({
page,
gotoPage: async () => {
await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).goto();
},
openDialog: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
},
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: async () => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.markdown-markdown`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.markdown`, {
exact: true,
})
.hover();
},
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
constantValue: 'test markdown',
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.markdown-markdown').getByRole('textbox'),
).toHaveValue('test markdown');
},
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
await testPattern({
page,
gotoPage: async () => {
await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).goto();
},
openDialog: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
},
showMenu: async () => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.markdown-markdown`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.markdown`, {
exact: true,
})
.hover();
},
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.markdown-markdown')
.getByRole('textbox')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.markdown-markdown')
.getByRole('textbox')
.fill('test markdown pattern');
},
expectReadonly: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.markdown-markdown').getByRole('textbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.markdown-markdown').getByRole('textbox'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.markdown-markdown')).toHaveText(
`markdown:test markdown pattern`,
);
},
});
});
test('Set validation rules', async ({ page, mockPage }) => {
await testSetValidationRules({
page,
gotoPage: async () => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
await nocoPage.goto();
},
openDialog: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
},
showMenu: async () => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.markdown-markdown`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.markdown`, {
exact: true,
})
.hover();
},
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.markdown-markdown`, { exact: true }).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.markdown`, {
exact: true,
})
.hover();
await expectSettingsMenu({
page,
showMenu: async () => {},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set validation rules',
'Pattern',
'Delete',
],
unsupportedOptions: ['Set default value'],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
let record: any = null;
await testPattern({
page,
gotoPage: async () => {
record = await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
},
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'markdown'),
expectEditable: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.markdown-markdown').getByRole('textbox'),
).toHaveValue(record.markdown);
},
expectReadonly: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.markdown-markdown').getByRole('textbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.markdown-markdown').getByRole('textbox'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.markdown-markdown')).toHaveText(
`markdown:${record.markdown}`,
);
},
});
});
test('Set validation rules', async ({ page, mockPage, mockRecord }) => {
await testSetValidationRules({
page,
gotoPage: () =>
(async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord),
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'markdown'),
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.markdown-markdown`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.markdown`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'markdown');
await showSettingsMenu(page, 'markdown');
},
supportedOptions: ['Custom column title', 'Column width', 'Delete'],
});
});
});

View File

@ -0,0 +1,243 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndChoicesFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testDefaultValue, testPattern } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.multipleSelect-multipleSelect`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.multipleSelect`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Pattern',
'Delete',
'required',
'Set default value',
],
});
});
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'multipleSelect'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').getByTestId('select-multiple').click();
await page.getByRole('option', { name: 'Option1' }).click();
await page.getByRole('option', { name: 'Option2' }).click();
await page.getByRole('option', { name: 'Option3' }).click();
},
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.multipleSelect-multipleSelect'),
).toHaveText('multipleSelect:Option1Option2Option3');
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'multipleSelect'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.multipleSelect-multipleSelect')
.getByTestId('select-multiple')
.click();
await page.getByRole('option', { name: 'Option1' }).click();
await page.getByRole('option', { name: 'Option2' }).click();
await page.getByRole('option', { name: 'Option3' }).click();
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.multipleSelect-multipleSelect')
.getByTestId('select-multiple'),
).toHaveClass(/ant-select-disabled/);
},
expectEasyReading: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.multipleSelect-multipleSelect')
.getByTestId('select-multiple'),
).not.toBeVisible();
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.multipleSelect-multipleSelect'),
).toHaveText('multipleSelect:Option1Option2Option3');
},
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page
.getByLabel(`block-item-CollectionField-general-form-general.multipleSelect-multipleSelect`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.multipleSelect`, {
exact: true,
})
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit description', 'Required', 'Pattern', 'Delete'],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
let record = null;
await testPattern({
page,
gotoPage: async () => {
record = await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
},
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'multipleSelect'),
expectEditable: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.multipleSelect-multipleSelect')
.getByTestId('select-multiple'),
).toHaveText(`${record.multipleSelect.join('')}`, { ignoreCase: true });
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.multipleSelect-multipleSelect')
.getByTestId('select-multiple'),
).toHaveClass(/ant-select-disabled/);
},
expectEasyReading: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.multipleSelect-multipleSelect')
.getByTestId('select-multiple'),
).not.toBeVisible();
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.multipleSelect-multipleSelect'),
).toHaveText(`multipleSelect:${record.multipleSelect.join('')}`, { ignoreCase: true });
},
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.multipleSelect-multipleSelect`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.multipleSelect`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'multipleSelect');
await showSettingsMenu(page, 'multipleSelect');
},
supportedOptions: ['Custom column title', 'Column width', 'Delete'],
});
});
});

View File

@ -0,0 +1,298 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndBasicFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testDefaultValue, testPattern, testSetValidationRules } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.number-number`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.number`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Pattern',
'Delete',
'required',
'Set default value',
'Set validation rules',
],
});
});
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'number'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').getByRole('spinbutton').click();
await page.getByLabel('block-item-VariableInput-').getByRole('spinbutton').fill('11.22');
},
variableValue: ['Current user', 'ID'], // 值为 1
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.number-number').getByRole('spinbutton'),
).toHaveValue('11.22');
},
expectVariableValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.number-number').getByRole('spinbutton'),
).toHaveValue('1');
},
});
});
test('pattern', async ({ page, mockPage }) => {
// TODO: number 类型的字段,当输入了小数,然后把 Pattern 切换成 Easy-reading 模式,小数不应该被去掉;
test.fail();
await testPattern({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'number'),
expectEditable: async () => {
// 默认情况下可以编辑
await page
.getByLabel('block-item-CollectionField-general-form-general.number-number')
.getByRole('spinbutton')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.number-number')
.getByRole('spinbutton')
.fill('11.22');
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.number-number').getByRole('spinbutton'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框会消失,只剩下值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.number-number').getByRole('spinbutton'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.number-number')).toHaveText(
'number:11.22',
);
},
});
});
test('set validation rules', async ({ page, mockPage }) => {
await testSetValidationRules({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'number'),
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.number-number`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.number`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set validation rules',
'Pattern',
'Delete',
],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
// TODO: number 类型的字段,当输入了小数,然后把 Pattern 切换成 Easy-reading 模式,小数不应该被去掉;
test.fail();
let record = null;
await testPattern({
page,
gotoPage: async () => {
record = await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
},
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'number'),
expectEditable: async () => {
// 应该显示 record 中的值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.number-number').getByRole('spinbutton'),
).toHaveValue(String(record.number));
// 默认情况下可以编辑
await page
.getByLabel('block-item-CollectionField-general-form-general.number-number')
.getByRole('spinbutton')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.number-number')
.getByRole('spinbutton')
.fill('11.22');
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.number-number').getByRole('spinbutton'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框会消失,只剩下值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.number-number').getByRole('spinbutton'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.number-number')).toHaveText(
'number:11.22',
);
},
});
});
test('set validation rules', async ({ page, mockPage, mockRecord }) => {
await testSetValidationRules({
page,
gotoPage: () =>
(async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord),
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'number'),
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.number-number`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.number`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'number');
await showSettingsMenu(page, 'number');
},
supportedOptions: ['Custom column title', 'Column width', 'Sortable', 'Delete'],
});
});
});

View File

@ -0,0 +1,588 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndAssociationFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testPattern } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecords('users', 3);
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.oneToMany-oneToMany`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.oneToMany`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set the data scope',
'Set default sorting rules',
'Field component',
'Quick create',
'Allow multiple',
'Pattern',
'Title field',
'Delete',
],
});
});
test('set default value', async ({ page, mockPage, mockRecord, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToMany');
await expect(page.getByRole('menuitem', { name: 'Set default value' })).not.toBeVisible();
});
test('pattern', async ({ page, mockPage, mockRecords }) => {
await testPattern({
page,
gotoPage: async () => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
},
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToMany'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.oneToMany-oneToMany')
.getByTestId('select-object-multiple')
.click();
// 目前的情况下,在 one to many 的字段中,只有 ID 为 1 的数据可以被选中
await page.getByRole('option', { name: '1', exact: true }).click();
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.oneToMany-oneToMany')
.getByTestId('select-object-multiple'),
).toHaveClass(/ant-select-disabled/);
// 在这里等待一下,防止因闪烁导致下面的断言失败
await page.waitForTimeout(100);
},
expectEasyReading: async () => {
await expect(page.getByLabel('block-item-CollectionField-general-form-general.oneToMany-oneToMany')).toHaveText(
`oneToMany:1`,
);
},
});
});
test('Set the data scope', async ({ page, mockPage, mockRecords }) => {
const records = await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToMany');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await page.getByText('Add condition', { exact: true }).click();
await page.getByTestId('select-filter-field').click();
await page.getByRole('menuitemcheckbox', { name: 'ID', exact: true }).click();
await page.getByRole('spinbutton').click();
await page.getByRole('spinbutton').fill(String(records[0].id));
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 再次打开弹窗,设置的值应该还在
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToMany');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await expect(page.getByTestId('select-filter-field')).toHaveText('ID');
await expect(page.getByRole('spinbutton')).toHaveValue(String(records[0].id));
await page.getByRole('button', { name: 'Cancel', exact: true }).click();
// 数据应该被过滤了
await page
.getByLabel('block-item-CollectionField-general-form-general.oneToMany-oneToMany')
.getByTestId('select-object-multiple')
.click();
// 默认只显示 id 为 1 的数据,因为设置了只过滤 id 为 3 的数据所以这里的下拉列表应该为空mock 的数据无法被选中
await expect(page.getByRole('option')).toHaveCount(0);
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToMany');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Select', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Record picker', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-table', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form(Popover)', exact: true })).toBeVisible();
});
test('quick create', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToMany');
await expect(page.getByRole('menuitem', { name: 'Quick create' })).toBeVisible();
});
test('allow multiple', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToMany');
await expect(page.getByRole('menuitem', { name: 'Allow multiple' })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToMany');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockRecords, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecords('users', 3);
await mockRecords('general', 1);
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.oneToMany-oneToMany`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.oneToMany`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set the data scope',
'Set default sorting rules',
'Field component',
'Quick create',
'Allow multiple',
'Pattern',
'Title field',
'Delete',
],
unsupportedOptions: ['Set default value'],
});
});
test('pattern', async ({ page, mockPage, mockRecords }) => {
let record;
await testPattern({
page,
gotoPage: async () => {
record = (
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords)
).record;
},
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToMany'),
expectEditable: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.oneToMany-oneToMany')
.getByTestId('select-object-multiple'),
).toHaveText(`${record.oneToMany.map((item) => item.id).join('')}`);
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.oneToMany-oneToMany')
.getByTestId('select-object-multiple'),
).toHaveClass(/ant-select-disabled/);
// 在这里等待一下,防止因闪烁导致下面的断言失败
await page.waitForTimeout(100);
},
expectEasyReading: async () => {
await expect(page.getByLabel('block-item-CollectionField-general-form-general.oneToMany-oneToMany')).toHaveText(
`oneToMany:${record.oneToMany.map((item) => item.id).join(',')}`,
);
},
});
});
test('Set the data scope', async ({ page, mockPage, mockRecords }) => {
const { record } = await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToMany');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await page.getByText('Add condition', { exact: true }).click();
await page.getByTestId('select-filter-field').click();
await page.getByRole('menuitemcheckbox', { name: 'ID', exact: true }).click();
await page.getByRole('spinbutton').click();
await page.getByRole('spinbutton').fill('1');
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 再次打开弹窗,设置的值应该还在
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToMany');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await expect(page.getByTestId('select-filter-field')).toHaveText('ID');
await expect(page.getByRole('spinbutton')).toHaveValue('1');
await page.getByRole('button', { name: 'Cancel', exact: true }).click();
// 数据应该被过滤了
await page
.getByLabel('block-item-CollectionField-general-form-general.oneToMany-oneToMany')
.getByTestId('select-object-multiple')
.click();
// 但是在编辑模式下,本身已经有数据,所以需要加上已有数据的个数
await expect(page.getByRole('option')).toHaveCount(1 + record.oneToMany.length);
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToMany');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Select', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Record picker', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-table', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form(Popover)', exact: true })).toBeVisible();
});
test('quick create', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToMany');
await expect(page.getByRole('menuitem', { name: 'Quick create' })).toBeVisible();
});
test('allow multiple', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToMany');
await expect(page.getByRole('menuitem', { name: 'Allow multiple' })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return { record, recordsOfUser };
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToMany');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecords('general', 1);
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.oneToMany-oneToMany`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.oneToMany`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit tooltip',
'Field component',
'Enable link',
'Title field',
'Delete',
],
unsupportedOptions: ['Set default value'],
});
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return record;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToMany');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Title', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Tag', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-table', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-details', exact: true })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return record;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToMany');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
test('enable link', async ({ page, mockPage, mockRecords }) => {
await (async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return record;
})(mockPage, mockRecords);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'oneToMany');
await expect(page.getByRole('menuitem', { name: 'Enable link' }).getByRole('switch')).toBeChecked();
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'oneToMany');
await showSettingsMenu(page, 'oneToMany');
},
supportedOptions: [
'Custom column title',
'Column width',
'Enable link',
'Title field',
'Field component',
'Delete',
],
});
});
});

View File

@ -0,0 +1,280 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndBasicFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testDefaultValue, testPattern, testSetValidationRules } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.password-password`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.password`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Pattern',
'Delete',
'required',
'Set default value',
'Set validation rules',
],
});
});
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'password'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
constantValue: 'test112233password',
variableValue: ['Current user', 'Email'], // 值为 admin@nocobase.com
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.password-password').getByRole('textbox'),
).toHaveValue('test112233password');
},
expectVariableValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.password-password').getByRole('textbox'),
).toHaveValue('admin@nocobase.com');
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'password'),
expectEditable: async () => {
// 默认情况下可以编辑
await page
.getByLabel('block-item-CollectionField-general-form-general.password-password')
.getByRole('textbox')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.password-password')
.getByRole('textbox')
.fill('test112233password');
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.password-password').getByRole('textbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框会消失,只剩下值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.password-password').getByRole('textbox'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.password-password')).toHaveText(
'password:********',
);
},
});
});
test('set validation rules', async ({ page, mockPage }) => {
await testSetValidationRules({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'password'),
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.password-password`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.password`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set validation rules',
'Pattern',
'Delete',
],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
let record: any = null;
await testPattern({
page,
gotoPage: async () => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
record = await mockRecord('general');
await nocoPage.goto();
},
openDialog: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
},
showMenu: async () => {
await page.getByLabel(`block-item-CollectionField-general-form-general.password-password`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.password`)
.hover();
},
expectEditable: async () => {
// 默认情况下可以编辑
await page
.getByLabel('block-item-CollectionField-general-form-general.password-password')
.getByRole('textbox')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.password-password')
.getByRole('textbox')
.fill('test112233password');
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.password-password').getByRole('textbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框会消失,只剩下值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.password-password').getByRole('textbox'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.password-password')).toHaveText(
'password:********',
);
},
});
});
test('set validation rules', async ({ page, mockPage, mockRecord }) => {
await testSetValidationRules({
page,
gotoPage: () =>
(async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord),
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'password'),
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.password-password`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.password`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'password');
await showSettingsMenu(page, 'password');
},
supportedOptions: ['Custom column title', 'Column width', 'Delete'],
});
});
});

View File

@ -0,0 +1,299 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndBasicFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testDefaultValue, testPattern, testSetValidationRules } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.percent-percent`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.percent`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Pattern',
'Delete',
'required',
'Set default value',
'Set validation rules',
],
});
});
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'percent'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').getByRole('spinbutton').click();
await page.getByLabel('block-item-VariableInput-').getByRole('spinbutton').fill('11.22');
},
variableValue: ['Current user', 'ID'], // 值为 1
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.percent-percent').getByRole('spinbutton'),
).toHaveValue('11.22');
},
expectVariableValue: async () => {
// 数字 1 转换为百分比后为 100%
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.percent-percent').getByRole('spinbutton'),
).toHaveValue('100');
},
});
});
test('pattern', async ({ page, mockPage }) => {
// TODO: percent 类型的字段,当输入了小数,然后把 Pattern 切换成 Easy-reading 模式,小数点不应该被去掉;
test.fail();
await testPattern({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'percent'),
expectEditable: async () => {
// 默认情况下可以编辑
await page
.getByLabel('block-item-CollectionField-general-form-general.percent-percent')
.getByRole('spinbutton')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.percent-percent')
.getByRole('spinbutton')
.fill('11.22');
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.percent-percent').getByRole('spinbutton'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框会消失,只剩下值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.percent-percent').getByRole('spinbutton'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.percent-percent')).toHaveText(
'percent:11.22%',
);
},
});
});
test('set validation rules', async ({ page, mockPage }) => {
await testSetValidationRules({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'percent'),
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.percent-percent`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.percent`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set validation rules',
'Pattern',
'Delete',
],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
// TODO: percent 类型的字段,当输入了小数,然后把 Pattern 切换成 Easy-reading 模式,小数点不应该被去掉;
test.fail();
let record = null;
await testPattern({
page,
gotoPage: async () => {
record = await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
},
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'percent'),
expectEditable: async () => {
// 应该显示 record 中的值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.percent-percent').getByRole('spinbutton'),
).toHaveValue(String(record.percent));
// 默认情况下可以编辑
await page
.getByLabel('block-item-CollectionField-general-form-general.percent-percent')
.getByRole('spinbutton')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.percent-percent')
.getByRole('spinbutton')
.fill('11.22');
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.percent-percent').getByRole('spinbutton'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框会消失,只剩下值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.percent-percent').getByRole('spinbutton'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.percent-percent')).toHaveText(
'percent:11.22%',
);
},
});
});
test('set validation rules', async ({ page, mockPage, mockRecord }) => {
await testSetValidationRules({
page,
gotoPage: () =>
(async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord),
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'percent'),
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.percent-percent`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.percent`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'percent');
await showSettingsMenu(page, 'percent');
},
supportedOptions: ['Custom column title', 'Column width', 'Sortable', 'Delete'],
});
});
});

View File

@ -0,0 +1,224 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndBasicFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testDefaultValue, testPattern } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.phone-phone`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.phone`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Pattern',
'Delete',
'required',
'Set default value',
],
});
});
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'phone'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
constantValue: '17777777777',
variableValue: ['Current user', 'ID'], // 值为 1
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.phone-phone').getByRole('textbox'),
).toHaveValue('17777777777');
},
expectVariableValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.phone-phone').getByRole('textbox'),
).toHaveValue('1');
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'phone'),
expectEditable: async () => {
// 默认情况下可以编辑
await page
.getByLabel('block-item-CollectionField-general-form-general.phone-phone')
.getByRole('textbox')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.phone-phone')
.getByRole('textbox')
.fill('17777777777');
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.phone-phone').getByRole('textbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框会消失,只剩下值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.phone-phone').getByRole('textbox'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.phone-phone')).toHaveText(
'phone:17777777777',
);
},
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.phone-phone`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.phone`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit description', 'Required', 'Pattern', 'Delete'],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
let record = null;
await testPattern({
page,
gotoPage: async () => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
record = await mockRecord('general');
await nocoPage.goto();
},
openDialog: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
},
showMenu: async () => {
await page.getByLabel(`block-item-CollectionField-general-form-general.phone-phone`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.phone`)
.hover();
},
expectEditable: async () => {
// 默认情况下可以编辑
await page
.getByLabel('block-item-CollectionField-general-form-general.phone-phone')
.getByRole('textbox')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.phone-phone')
.getByRole('textbox')
.fill('17777777777');
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.phone-phone').getByRole('textbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框会消失,只剩下值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.phone-phone').getByRole('textbox'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.phone-phone')).toHaveText(
'phone:17777777777',
);
},
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.phone-phone`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.phone`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'phone');
await showSettingsMenu(page, 'phone');
},
supportedOptions: ['Custom column title', 'Column width', 'Sortable', 'Delete'],
});
});
});

View File

@ -0,0 +1,241 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndChoicesFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testDefaultValue, testPattern } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.radioGroup-radioGroup`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.radioGroup`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Pattern',
'Delete',
'required',
'Set default value',
],
});
});
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'radioGroup'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').getByLabel('Option2').click();
},
expectConstantValue: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.radioGroup-radioGroup')
.getByLabel('Option2'),
).toBeChecked();
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'radioGroup'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.radioGroup-radioGroup')
.getByLabel('Option2')
.click();
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.radioGroup-radioGroup')
.getByLabel('Option2'),
).toBeDisabled();
},
expectEasyReading: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.radioGroup-radioGroup')
.getByLabel('Option2'),
).not.toBeVisible();
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.radioGroup-radioGroup'),
).toHaveText('radioGroup:Option2');
},
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page
.getByLabel(`block-item-CollectionField-general-form-general.radioGroup-radioGroup`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.radioGroup`, {
exact: true,
})
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit description', 'Required', 'Pattern', 'Delete'],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
let record = null;
await testPattern({
page,
gotoPage: async () => {
record = await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
},
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'radioGroup'),
expectEditable: async () => {
if (record.radioGroup) {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.radioGroup-radioGroup')
.getByLabel(record.radioGroup),
).toBeChecked();
}
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.radioGroup-radioGroup')
.getByLabel('Option2'),
).toBeDisabled();
},
expectEasyReading: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.radioGroup-radioGroup')
.getByLabel('Option2'),
).not.toBeVisible();
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.radioGroup-radioGroup'),
).toHaveText(`radioGroup:${record.radioGroup}`, { ignoreCase: true });
},
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.radioGroup-radioGroup`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.radioGroup`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'radioGroup');
await showSettingsMenu(page, 'radioGroup');
},
supportedOptions: ['Custom column title', 'Column width', 'Sortable', 'Delete'],
});
});
});

View File

@ -0,0 +1,281 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndMediaFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testDefaultValue, testPattern, testSetValidationRules } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.richText-richText`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.richText`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set default value',
'Pattern',
'Delete',
'Set validation rules',
],
});
});
test('set default value', async ({ page, mockPage, mockRecord }) => {
await testDefaultValue({
page,
gotoPage: async () => {
await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).goto();
},
openDialog: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
},
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: async () => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.richText-richText`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.richText`, {
exact: true,
})
.hover();
},
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-CollectionField-general-general.richText').locator('.ql-editor').click();
await page.keyboard.type('test rich text');
},
expectConstantValue: async () => {
await expect(page.getByLabel('block-item-CollectionField-general-form-general.richText-richText')).toHaveText(
/test rich text/,
);
},
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
await testPattern({
page,
gotoPage: async () => {
await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).goto();
},
openDialog: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
},
showMenu: async () => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.richText-richText`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.richText`, {
exact: true,
})
.hover();
},
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.richText-richText')
.locator('.ql-editor')
.click();
await page.keyboard.type('test rich text pattern');
},
expectReadonly: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.richText-richText').locator('.ql-container'),
).toHaveClass(/ql-disabled/);
},
expectEasyReading: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.richText-richText').locator('.ql-container'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.richText-richText')).toHaveText(
/test rich text pattern/,
);
},
});
});
test('Set validation rules', async ({ page, mockPage }) => {
await testSetValidationRules({
page,
gotoPage: async () => {
await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).goto();
},
openDialog: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
},
showMenu: async () => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.markdown-markdown`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.markdown`, {
exact: true,
})
.hover();
},
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.richText-richText`, { exact: true }).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.richText`, {
exact: true,
})
.hover();
await expectSettingsMenu({
page,
showMenu: async () => {},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set validation rules',
'Pattern',
'Delete',
],
unsupportedOptions: ['Set default value'],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
let record = null;
await testPattern({
page,
gotoPage: async () => {
record = await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
},
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'richText'),
expectEditable: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.richText-richText').locator('.ql-editor'),
).toHaveText(record.richText);
},
expectReadonly: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.richText-richText').locator('.ql-container'),
).toHaveClass(/ql-disabled/);
},
expectEasyReading: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.richText-richText').locator('.ql-container'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.richText-richText')).toHaveText(
`richText:${record.richText}`,
);
},
});
});
test('Set validation rules', async ({ page, mockPage, mockRecord }) => {
await testSetValidationRules({
page,
gotoPage: () =>
(async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord),
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'markdown'),
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
// 等待页面稳定
await page.waitForTimeout(1000);
await page.getByLabel(`block-item-CollectionField-general-form-general.richText-richText`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.richText`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'richText');
await showSettingsMenu(page, 'richText');
},
supportedOptions: ['Custom column title', 'Column width', 'Delete'],
});
});
});

View File

@ -0,0 +1,79 @@
import { expectSettingsMenu, oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields, test } from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.sequence-sequence`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.sequence`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit description', 'Pattern', 'Delete', 'required'],
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.sequence-sequence`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.sequence`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit description', 'Required', 'Pattern', 'Delete'],
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.sequence-sequence`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.sequence`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'sequence');
await showSettingsMenu(page, 'sequence');
},
supportedOptions: ['Custom column title', 'Column width', 'Sortable', 'Delete'],
});
});
});

View File

@ -0,0 +1,376 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndBasicFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testDefaultValue, testPattern, testSetValidationRules } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.singleLineText-singleLineText`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.singleLineText`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Pattern',
'Delete',
'required',
'Set default value',
'Set validation rules',
],
});
});
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'singleLineText'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
constantValue: 'test single line text',
variableValue: ['Current user', 'Email'], // 值为 admin@nocobase.com
expectConstantValue: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.singleLineText-singleLineText')
.getByRole('textbox'),
).toHaveValue('test single line text');
},
expectVariableValue: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.singleLineText-singleLineText')
.getByRole('textbox'),
).toHaveValue('admin@nocobase.com');
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'singleLineText'),
expectEditable: async () => {
// 默认情况下可以编辑
await page
.getByLabel('block-item-CollectionField-general-form-general.singleLineText-singleLineText')
.getByRole('textbox')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.singleLineText-singleLineText')
.getByRole('textbox')
.fill('test single line text');
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.singleLineText-singleLineText')
.getByRole('textbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框会消失,只剩下值
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.singleLineText-singleLineText')
.getByRole('textbox'),
).not.toBeVisible();
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.singleLineText-singleLineText'),
).toHaveText('singleLineText:test single line text');
},
});
});
test('Set validation rules', async ({ page, mockPage }) => {
await testSetValidationRules({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'singleLineText'),
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.singleLineText-singleLineText`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.singleLineText`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set validation rules',
'Pattern',
'Delete',
],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
let record = null;
await testPattern({
page,
gotoPage: async () => {
record = await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
},
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'singleLineText'),
expectEditable: async () => {
// 应该显示 record 中的值
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.singleLineText-singleLineText')
.getByRole('textbox'),
).toHaveValue(record.singleLineText);
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.singleLineText-singleLineText')
.getByRole('textbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框会消失,只剩下值
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.singleLineText-singleLineText')
.getByRole('textbox'),
).not.toBeVisible();
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.singleLineText-singleLineText'),
).toHaveText(`singleLineText:${record.singleLineText}`);
},
});
});
test('Set validation rules', async ({ page, mockPage, mockRecord }) => {
await testSetValidationRules({
page,
gotoPage: () =>
(async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord),
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'singleLineText'),
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.singleLineText-singleLineText`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.singleLineText`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'singleLineText');
await showSettingsMenu(page, 'singleLineText');
},
supportedOptions: ['Custom column title', 'Column width', 'Sortable', 'Delete'],
});
});
test('custom column title', async ({ page, mockPage, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecords('general');
await nocoPage.goto();
await createColumnItem(page, 'singleLineText');
await showSettingsMenu(page, 'singleLineText');
await page.getByRole('menuitem', { name: 'Custom column title' }).click();
// 显示出原字段名称
await expect(page.getByRole('dialog').getByText('Original field title: singleLineText')).toBeVisible();
// 输入新字段名称
await page.getByLabel('block-item-Input-general-column title').getByRole('textbox').click();
await page.getByLabel('block-item-Input-general-column title').getByRole('textbox').fill('new column title');
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 新名称应该显示出来
await expect(page.getByRole('button', { name: 'new column title', exact: true })).toBeVisible();
});
test('column width', async ({ page, mockPage, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecords('general');
await nocoPage.goto();
await createColumnItem(page, 'singleLineText');
await showSettingsMenu(page, 'singleLineText');
await page.getByRole('menuitem', { name: 'Column width' }).click();
await page.getByRole('dialog').getByRole('spinbutton').click();
await page.getByRole('dialog').getByRole('spinbutton').fill('600');
await page.getByRole('button', { name: 'OK', exact: true }).click();
const columnHeadSize = await page.getByRole('columnheader', { name: 'singleLineText' }).boundingBox();
expect(Math.floor(columnHeadSize.width)).toBe(600);
});
test('sortable', async ({ page, mockPage, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecords('general', [{ singleLineText: 'a' }, { singleLineText: 'b' }]);
await nocoPage.goto();
await createColumnItem(page, 'singleLineText');
await showSettingsMenu(page, 'singleLineText');
// 默认不可排序
await expect(page.getByRole('menuitem', { name: 'Sortable' }).getByRole('switch')).not.toBeChecked();
// 开启排序
await page.getByRole('menuitem', { name: 'Sortable' }).click();
// TODO: 此处菜单在点击后不应该消失
// await expect(page.getByRole('menuitem', { name: 'Sortable' }).getByRole('switch')).toBeChecked();
// 鼠标 hover 时,有提示
await page.getByRole('columnheader', { name: 'singleLineText' }).hover();
await expect(page.getByRole('tooltip', { name: 'Click to sort ascending' })).toBeVisible();
// 点击第一下,升序
await page.getByRole('columnheader', { name: 'singleLineText' }).click();
let sizeA = await page.getByRole('cell', { name: 'a', exact: true }).boundingBox();
let sizeB = await page.getByRole('cell', { name: 'b', exact: true }).boundingBox();
expect(sizeA.y).toBeLessThan(sizeB.y);
// 点击第二下,降序
await page.getByRole('columnheader', { name: 'singleLineText' }).click();
sizeA = await page.getByRole('cell', { name: 'a', exact: true }).boundingBox();
sizeB = await page.getByRole('cell', { name: 'b', exact: true }).boundingBox();
expect(sizeA.y).toBeGreaterThan(sizeB.y);
});
test('delete', async ({ page, mockPage, mockRecords }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecords('general');
await nocoPage.goto();
await createColumnItem(page, 'singleLineText');
await showSettingsMenu(page, 'singleLineText');
await page.getByRole('menuitem', { name: 'Delete' }).click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
await expect(page.getByRole('columnheader', { name: 'singleLineText' })).toBeHidden();
});
});

View File

@ -0,0 +1,239 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndChoicesFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testDefaultValue, testPattern } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.singleSelect-singleSelect`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.singleSelect`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Pattern',
'Delete',
'required',
'Set default value',
],
});
});
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'singleSelect'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').click();
await page.getByRole('option', { name: 'Option1' }).click();
},
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.singleSelect-singleSelect'),
).toHaveText('singleSelect:Option1');
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'singleSelect'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.singleSelect-singleSelect')
.getByTestId('select-single')
.click();
await page.getByRole('option', { name: 'Option1' }).click();
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.singleSelect-singleSelect')
.getByTestId('select-single'),
).toHaveClass(/ant-select-disabled/);
},
expectEasyReading: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.singleSelect-singleSelect')
.getByTestId('select-single'),
).not.toBeVisible();
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.singleSelect-singleSelect'),
).toHaveText('singleSelect:Option1');
},
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page
.getByLabel(`block-item-CollectionField-general-form-general.singleSelect-singleSelect`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.singleSelect`, {
exact: true,
})
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit description', 'Required', 'Pattern', 'Delete'],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
let record = null;
await testPattern({
page,
gotoPage: async () => {
record = await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
},
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
})(page, 'singleSelect'),
expectEditable: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.singleSelect-singleSelect')
.getByTestId('select-single'),
).toHaveText(record.singleSelect, { ignoreCase: true });
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.singleSelect-singleSelect')
.getByTestId('select-single'),
).toHaveClass(/ant-select-disabled/);
},
expectEasyReading: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.singleSelect-singleSelect')
.getByTestId('select-single'),
).not.toBeVisible();
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.singleSelect-singleSelect'),
).toHaveText(`singleSelect:${record.singleSelect}`, { ignoreCase: true });
},
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.singleSelect-singleSelect`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.singleSelect`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'singleSelect');
await showSettingsMenu(page, 'singleSelect');
},
supportedOptions: ['Custom column title', 'Column width', 'Sortable', 'Delete'],
});
});
});

View File

@ -0,0 +1,136 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.tableoid-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.tableoid`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit tooltip', 'Pattern', 'Delete'],
});
});
test('options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await nocoPage.goto();
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.tableoid-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.tableoid`)
.hover();
await expect(page.getByRole('menuitem', { name: 'Edit tooltip' })).toBeVisible();
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.tableoid-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.tableoid`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit tooltip', 'Pattern', 'Delete'],
});
});
test('options', async ({ page, mockPage, mockRecord }) => {
await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'tableoid');
await expect(page.getByRole('menuitem', { name: 'Edit tooltip' })).toBeVisible();
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.tableoid-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.tableoid`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
test('options', async ({ page, mockPage, mockRecord }) => {
await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
await (async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
})(page);
await (async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'tableoid');
await expect(page.getByRole('menuitem', { name: 'Edit tooltip' })).toBeVisible();
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'Table OID');
await showSettingsMenu(page, 'Table OID');
},
supportedOptions: ['Custom column title', 'Column width', 'Sortable', 'Delete'],
});
});
});

View File

@ -0,0 +1,21 @@
import { test } from '@nocobase/test/e2e';
test('form item & create form', async ({ page, mockPage }) => {});
test('form item & edit form', async ({ page, mockPage }) => {});
test('form item & view form', async ({ page, mockPage }) => {});
test('form item & filter form', async ({ page, mockPage }) => {});
test('table column & table', async ({ page, mockPage }) => {});
test('table column & table & record picker', async ({ page, mockPage }) => {});
test('table column & table & Relationship block', async ({ page, mockPage }) => {});
test('table column & sub table & create from', async ({ page, mockPage }) => {});
test('table column & sub table & edit from', async ({ page, mockPage }) => {});
test('table column & sub table & view from', async ({ page, mockPage }) => {});

View File

@ -0,0 +1,208 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields,
test,
} from '@nocobase/test/e2e';
import dayjs from 'dayjs';
import { createColumnItem, showSettingsMenu, testDefaultValue, testPattern } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.time-time`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.time`)
.hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Required',
'Set default value',
'Pattern',
'Delete',
],
});
});
test('set default value', async ({ page, mockPage, mockRecord }) => {
let nowTime;
await testDefaultValue({
page,
gotoPage: async () => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
await nocoPage.goto();
},
openDialog: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
},
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: async () => {
await page.getByLabel(`block-item-CollectionField-general-form-general.time-time`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.time`)
.hover();
},
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').getByPlaceholder('Select time').click();
await page.getByText('Now').click();
nowTime = dayjs();
},
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.time-time').getByPlaceholder('Select time'),
).toHaveValue(new RegExp(nowTime.format('HH:mm:ss')));
},
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
await testPattern({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'time'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.time-time')
.getByPlaceholder('Select time')
.click();
await page.getByText('Now').click();
},
expectReadonly: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.time-time').getByPlaceholder('Select time'),
).toBeDisabled();
},
expectEasyReading: async () => {
await expect(page.getByLabel('block-item-CollectionField-general-form-general.time-time')).toHaveText(
new RegExp(`time:${dayjs().format('HH:mm:')}`),
);
},
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.time-time`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.time`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit description', 'Required', 'Pattern', 'Delete'],
unsupportedOptions: ['Set default value'],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
let record = null;
await testPattern({
page,
gotoPage: async () => {
record = await (async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
})(mockPage, mockRecord);
},
openDialog: () =>
(async (page: Page) => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'time'),
expectEditable: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.time-time').getByPlaceholder('Select time'),
).toHaveValue(record.time);
},
expectReadonly: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.time-time').getByPlaceholder('Select time'),
).toBeDisabled();
},
expectEasyReading: async () => {
await expect(page.getByLabel('block-item-CollectionField-general-form-general.time-time')).toHaveText(
new RegExp(`time:${record.time}`),
);
},
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.time-time`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.time`)
.hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'time');
await showSettingsMenu(page, 'time');
},
supportedOptions: ['Custom column title', 'Column width', 'Sortable', 'Delete'],
});
});
});

View File

@ -0,0 +1,212 @@
import {
Page,
expect,
expectSettingsMenu,
oneTableBlockWithAddNewAndViewAndEditAndBasicFields,
test,
} from '@nocobase/test/e2e';
import { createColumnItem, showSettingsMenu, testDefaultValue, testPattern } from '../../utils';
test.describe('form item & create form', () => {
test('supported options', async ({ page, mockPage }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByRole('button', { name: 'Add new' }).click();
await page.getByLabel(`block-item-CollectionField-general-form-general.url-url`).hover();
await page.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.url`).hover();
},
supportedOptions: [
'Edit field title',
'Display title',
'Edit description',
'Pattern',
'Delete',
'required',
'Set default value',
],
});
});
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
closeDialog: async () => {
await page.getByLabel('drawer-Action.Container-general-Add record-mask').click();
},
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'url'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
constantValue: 'https://nocobase.com',
variableValue: ['Current user', 'Email'], // 值为 admin@nocobase.com
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.url-url').getByRole('textbox'),
).toHaveValue('https://nocobase.com');
},
expectVariableValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.url-url').getByRole('textbox'),
).toHaveValue('admin@nocobase.com');
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () =>
(async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
})(mockPage),
openDialog: () =>
(async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
})(page),
showMenu: () =>
(async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
})(page, 'url'),
expectEditable: async () => {
// 默认情况下可以编辑
await page.getByLabel('block-item-CollectionField-general-form-general.url-url').getByRole('textbox').click();
await page
.getByLabel('block-item-CollectionField-general-form-general.url-url')
.getByRole('textbox')
.fill('https://nocobase.com');
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.url-url').getByRole('textbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框会消失,只剩下值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.url-url').getByRole('textbox'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.url-url')).toHaveText(
'url:https://nocobase.com',
);
},
});
});
});
test.describe('form item & edit form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.url-url`).hover();
await page.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.url`).hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Edit description', 'Required', 'Pattern', 'Delete'],
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
let record: any = null;
await testPattern({
page,
gotoPage: async () => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
record = await mockRecord('general');
await nocoPage.goto();
},
openDialog: async () => {
await page.getByLabel('action-Action.Link-Edit record-update-general-table-0').click();
},
showMenu: async () => {
await page.getByLabel(`block-item-CollectionField-general-form-general.url-url`).hover();
await page.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.url`).hover();
},
expectEditable: async () => {
// 默认情况下可以编辑
await page.getByLabel('block-item-CollectionField-general-form-general.url-url').getByRole('textbox').click();
await page
.getByLabel('block-item-CollectionField-general-form-general.url-url')
.getByRole('textbox')
.fill('https://nocobase.com');
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.url-url').getByRole('textbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
// url 类型数据不会被 mock所以这里不会显示值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.url-url').getByRole('textbox'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.url-url')).toHaveText(
'url:https://nocobase.com',
);
},
});
});
});
test.describe('form item & view form', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
await page.getByLabel(`block-item-CollectionField-general-form-general.url-url`).hover();
await page.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.url`).hover();
},
supportedOptions: ['Edit field title', 'Display title', 'Delete', 'Edit tooltip'],
unsupportedOptions: ['Set default value'],
});
});
});
test.describe('table column & table', () => {
test('supported options', async ({ page, mockPage, mockRecord }) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
await expectSettingsMenu({
page,
showMenu: async () => {
await createColumnItem(page, 'url');
await showSettingsMenu(page, 'url');
},
supportedOptions: ['Custom column title', 'Column width', 'Delete'],
});
});
});

View File

@ -1,278 +0,0 @@
import { Page, expect, test } from '@nocobase/test/e2e';
export async function testEditFieldTitle(page: Page) {
await page.getByRole('menuitem', { name: 'Edit field title' }).click();
await page.getByLabel('block-item-Input-general-').getByRole('textbox').click();
await page.getByLabel('block-item-Input-general-').getByRole('textbox').fill('testing edit field title');
await page.getByRole('button', { name: 'OK', exact: true }).click();
await expect(page.getByText('testing edit field title')).toBeVisible();
}
export async function testDisplayTitle(page: Page, title: string) {
// 默认情况下是开启状态
await expect(page.getByRole('menuitem', { name: 'Display title' }).getByRole('switch')).toBeChecked();
await page.getByRole('menuitem', { name: 'Display title' }).click();
await expect(page.getByRole('menuitem', { name: 'Display title' }).getByRole('switch')).not.toBeChecked();
await expect(page.getByText(`${title}:`, { exact: true })).not.toBeVisible();
}
export async function testEditDescription(page: Page) {
await page.getByRole('menuitem', { name: 'Edit description' }).click();
await page.getByLabel('block-item-Input.TextArea-').getByRole('textbox').click();
await page.getByLabel('block-item-Input.TextArea-').getByRole('textbox').fill('testing edit description');
await page.getByRole('button', { name: 'OK', exact: true }).click();
await expect(page.getByText('testing edit description')).toBeVisible();
}
export async function testRequired(page: Page) {
// 默认情况下是关闭状态
await expect(page.getByRole('menuitem', { name: 'Required' }).getByRole('switch')).not.toBeChecked();
await page.getByRole('menuitem', { name: 'Required' }).click();
await expect(page.getByRole('menuitem', { name: 'Required' }).getByRole('switch')).toBeChecked();
}
export async function clickDeleteAndOk(page: Page) {
await page.getByRole('menuitem', { name: 'Delete' }).click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
}
export const commonTesting = ({
openDialogAndShowMenu,
fieldName,
blockType = 'creating',
fieldType,
mode = 'details',
}: {
openDialogAndShowMenu: ({
page,
mockPage,
mockRecord,
mockRecords,
fieldName,
}: {
page: Page;
mockPage: any;
mockRecord: any;
mockRecords: any;
fieldName: string;
}) => Promise<void>;
fieldName: string;
blockType?: 'creating' | 'viewing' | 'editing';
fieldType?: 'relation' | 'system';
/**
* options
* details
*/
mode?: 'options' | 'details';
}) => {
if (mode === 'details') {
test('edit field title', async ({ page, mockPage, mockRecord, mockRecords }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, mockRecords, fieldName });
await testEditFieldTitle(page);
});
test('display title', async ({ page, mockPage, mockRecord, mockRecords }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, mockRecords, fieldName });
await testDisplayTitle(page, fieldName);
});
test('delete', async ({ page, mockPage, mockRecord, mockRecords }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, mockRecords, fieldName });
await clickDeleteAndOk(page);
await expect(page.getByText(`${fieldName}:`)).not.toBeVisible();
});
if (['creating', 'editing'].includes(blockType)) {
test('edit description', async ({ page, mockPage, mockRecord, mockRecords }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, mockRecords, fieldName });
await testEditDescription(page);
});
test('required', async ({ page, mockPage, mockRecord, mockRecords }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, mockRecords, fieldName });
await testRequired(page);
});
}
if (blockType === 'viewing') {
test('edit tooltip', async ({ page, mockPage, mockRecord, mockRecords }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, mockRecords, fieldName });
await page.getByRole('menuitem', { name: 'Edit tooltip' }).click();
await page.getByRole('dialog').getByRole('textbox').click();
await page.getByRole('dialog').getByRole('textbox').fill('testing edit tooltip');
await page.getByRole('button', { name: 'OK', exact: true }).click();
await page.getByRole('img', { name: 'question-circle' }).hover();
await expect(page.getByText('testing edit tooltip')).toBeVisible();
});
}
}
if (mode === 'options') {
test('should display correct options', async ({ page, mockPage, mockRecord, mockRecords }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, mockRecords, fieldName });
await expect(page.getByRole('menuitem', { name: 'Edit field title' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Display title' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
if (['creating', 'editing'].includes(blockType) && fieldType !== 'system') {
await expect(page.getByRole('menuitem', { name: 'Edit description' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Required' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Pattern' })).toBeVisible();
}
if (blockType === 'viewing') {
await expect(page.getByRole('menuitem', { name: 'Edit tooltip' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Pattern' })).not.toBeVisible();
}
if (
blockType === 'creating' &&
!fieldName.startsWith('oneTo') &&
!['attachment'].includes(fieldName) &&
!['system'].includes(fieldType)
) {
await expect(page.getByRole('menuitem', { name: 'Set default value' })).toBeVisible();
}
if (['editing', 'viewing'].includes(blockType)) {
await expect(page.getByRole('menuitem', { name: 'Set default value' })).not.toBeVisible();
}
if (fieldType === 'relation' && ['creating', 'editing'].includes(blockType)) {
await expect(page.getByRole('menuitem', { name: 'Set default sorting rules' })).toBeVisible();
}
});
}
};
export async function testDefaultValue({
page,
openDialog,
closeDialog,
gotoPage,
showMenu,
supportVariables,
constantValue,
variableValue,
inputConstantValue,
expectConstantValue,
expectVariableValue,
}: {
page: Page;
openDialog: () => Promise<void>;
closeDialog: () => Promise<void>;
gotoPage: () => Promise<void>;
showMenu: () => Promise<void>;
/** 支持的变量列表,如:['Current user', 'Date variables', 'Current form'] */
supportVariables: string[];
/** 常量默认值 */
constantValue?: string | number;
/** 变量默认值 */
variableValue?: string[];
/** 输入常量默认值 */
inputConstantValue?: () => Promise<void>;
/** 对常量默认值进行断言 */
expectConstantValue?: () => Promise<void>;
/** 对变量默认值进行断言 */
expectVariableValue?: () => Promise<void>;
}) {
await gotoPage();
await openDialog();
await showMenu();
if (constantValue || inputConstantValue) {
// 设置一个常量作为默认值
await page.getByRole('menuitem', { name: 'Set default value' }).click();
if (inputConstantValue) {
await inputConstantValue();
} else {
await page.getByLabel('block-item-VariableInput-').getByRole('textbox').click();
await page.getByLabel('block-item-VariableInput-').getByRole('textbox').fill(String(constantValue));
}
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 关闭弹窗,然后再次打开后,应该显示刚才设置的默认值
await closeDialog();
await openDialog();
await expectConstantValue();
}
if (variableValue) {
// 设置一个变量作为默认值
await showMenu();
await page.getByRole('menuitem', { name: 'Set default value' }).click();
await page.getByLabel('variable-button').click();
for (const value of supportVariables) {
await expect(page.getByRole('menuitemcheckbox', { name: value })).toBeVisible();
}
for (const value of variableValue) {
await page.getByRole('menuitemcheckbox', { name: value }).click();
}
await page.getByRole('button', { name: 'OK', exact: true }).click();
await closeDialog();
await openDialog();
await expectVariableValue();
}
}
export async function testPattern({
page,
gotoPage,
openDialog,
showMenu,
expectEditable,
expectReadonly,
expectEasyReading,
}: {
page: Page;
gotoPage: () => Promise<void>;
openDialog: () => Promise<void>;
showMenu: () => Promise<void>;
/** 断言选项为 Editable 的情况 */
expectEditable: () => Promise<void>;
/** 断言选项为 Readonly 的情况 */
expectReadonly: () => Promise<void>;
/** 断言选项为 Easy-reading 的情况 */
expectEasyReading: () => Promise<void>;
}) {
await gotoPage();
await openDialog();
// 默认情况下,显示的是 Editable
await expectEditable();
await showMenu();
await expect(page.getByText('PatternEditable')).toBeVisible();
// 更改为 Readonly
await page.getByRole('menuitem', { name: 'Pattern' }).click();
await page.getByRole('option', { name: 'Readonly' }).click();
await expectReadonly();
// 更改为 Easy-reading
await showMenu();
await expect(page.getByText('PatternReadonly')).toBeVisible();
await page.getByRole('menuitem', { name: 'Pattern' }).click();
await page.getByRole('option', { name: 'Easy-reading' }).click();
await expectEasyReading();
await showMenu();
await expect(page.getByText('PatternEasy-reading')).toBeVisible();
}
export async function testSetValidationRules({
page,
gotoPage,
openDialog,
showMenu,
}: {
page: Page;
gotoPage: () => Promise<void>;
openDialog: () => Promise<void>;
showMenu: () => Promise<void>;
}) {
await gotoPage();
await openDialog();
await showMenu();
await page.getByRole('menuitem', { name: 'Set validation rules' }).click();
await expect(page.getByRole('dialog').getByText('Set validation rules')).toBeVisible();
// TODO: 更详细的测试
}

View File

@ -1,51 +0,0 @@
import { Page, oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields, test } from '@nocobase/test/e2e';
import { commonTesting } from '../commonTesting';
test.describe('collection', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'collection', blockType: 'viewing', mode: 'options' });
});
test.describe('JSON', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'JSON', blockType: 'viewing', mode: 'options' });
});
test.describe('formula', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'formula', blockType: 'viewing', mode: 'options' });
});
test.describe('sequence', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'sequence', blockType: 'viewing', mode: 'options' });
});
const gotoPage = async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields).waitForInit();
await mockRecord('general');
await nocoPage.goto();
};
const openDialog = async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
};
const showMenu = async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
};
async function openDialogAndShowMenu({
page,
mockPage,
mockRecord,
fieldName,
}: {
page: Page;
mockPage;
mockRecord;
fieldName: string;
}) {
await gotoPage(mockPage, mockRecord);
await openDialog(page);
await showMenu(page, fieldName);
}

View File

@ -1,81 +0,0 @@
import { Page, oneTableBlockWithAddNewAndViewAndEditAndBasicFields, test } from '@nocobase/test/e2e';
import { commonTesting } from '../commonTesting';
test.describe('color', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'color', blockType: 'viewing' });
});
test.describe('email', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'email', blockType: 'viewing', mode: 'options' });
});
test.describe('icon', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'icon', blockType: 'viewing', mode: 'options' });
});
test.describe('single line text', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'singleLineText', blockType: 'viewing', mode: 'options' });
});
test.describe('integer', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'integer', blockType: 'viewing', mode: 'options' });
});
test.describe('number', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'number', blockType: 'viewing', mode: 'options' });
});
test.describe('password', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'password', blockType: 'viewing', mode: 'options' });
});
test.describe('percent', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'percent', blockType: 'viewing', mode: 'options' });
});
test.describe('phone', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'phone', blockType: 'viewing', mode: 'options' });
});
test.describe('long text', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'longText', blockType: 'viewing', mode: 'options' });
});
test.describe('URL', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'url', blockType: 'viewing', mode: 'options' });
});
const gotoPage = async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
};
const openDialog = async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
};
const showMenu = async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
};
async function openDialogAndShowMenu({
page,
mockPage,
mockRecord,
fieldName,
}: {
page: Page;
mockPage;
mockRecord;
fieldName: string;
}) {
await gotoPage(mockPage, mockRecord);
await openDialog(page);
await showMenu(page, fieldName);
}

View File

@ -1,65 +0,0 @@
import { Page, oneTableBlockWithAddNewAndViewAndEditAndChoicesFields, test } from '@nocobase/test/e2e';
import { commonTesting } from '../commonTesting';
test.describe('checkbox', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'checkbox', blockType: 'viewing', mode: 'options' });
});
test.describe('checkbox group', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'checkboxGroup', blockType: 'viewing', mode: 'options' });
});
test.describe('china region', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'chinaRegion', blockType: 'viewing', mode: 'options' });
});
test.describe('multiple select', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'multipleSelect', blockType: 'viewing', mode: 'options' });
});
test.describe('radio group', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'radioGroup', blockType: 'viewing', mode: 'options' });
});
test.describe('single select', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'singleSelect', blockType: 'viewing', mode: 'options' });
});
const gotoPage = async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
};
const openDialog = async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
};
const showMenu = async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
};
async function openDialogAndShowMenu({
page,
mockPage,
mockRecord,
fieldName,
}: {
page: Page;
mockPage;
mockRecord;
fieldName: string;
}) {
await gotoPage(mockPage, mockRecord);
await openDialog(page);
await showMenu(page, fieldName);
}

View File

@ -1,59 +0,0 @@
import { Page, expect, oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields, test } from '@nocobase/test/e2e';
import dayjs from 'dayjs';
import { commonTesting } from '../commonTesting';
test.describe('datetime', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'datetime', blockType: 'viewing', mode: 'options' });
test('date display format', async ({ page, mockPage, mockRecord }) => {
const record = await openDialogAndShowMenu({ page, mockPage, mockRecord, fieldName: 'datetime' });
await page.getByRole('menuitem', { name: 'Date display format' }).click();
await page.getByLabel('YYYY/MM/DD').click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.datetime-datetime')).toHaveText(
`datetime:${dayjs(record.datetime).format('YYYY/MM/DD')}`,
);
});
});
test.describe('time', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'time', blockType: 'viewing', mode: 'options' });
});
const gotoPage = async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
};
const openDialog = async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
};
const showMenu = async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
};
async function openDialogAndShowMenu({
page,
mockPage,
mockRecord,
fieldName,
}: {
page: Page;
mockPage;
mockRecord;
fieldName: string;
}) {
const record = await gotoPage(mockPage, mockRecord);
await openDialog(page);
await showMenu(page, fieldName);
return record;
}

View File

@ -1,124 +0,0 @@
import { Page, expect, oneTableBlockWithAddNewAndViewAndEditAndMediaFields, test } from '@nocobase/test/e2e';
import { commonTesting } from '../commonTesting';
test.describe('markdown', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'markdown', blockType: 'viewing', mode: 'options' });
});
test.describe('rich text', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'richText', blockType: 'viewing', mode: 'options' });
});
test.describe('attachment', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'attachment', blockType: 'viewing', mode: 'options' });
test('size', async ({ page, mockPage, mockRecord }) => {
const record = await gotoPage(mockPage, mockRecord);
await openDialog(page);
// 默认尺寸
// 这里的尺寸不稳定,所以用 try catch 来处理
const testDefault = async (value) => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.attachment-attachment')
.getByRole('link', { name: record.attachment.title })
.first(),
).toHaveJSProperty('offsetWidth', value, { timeout: 1000 });
};
try {
await testDefault(94);
} catch (error) {
try {
await testDefault(95);
} catch (err) {
await testDefault(96);
}
}
// 改为大尺寸
const testLarge = async (value) => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.attachment-attachment')
.getByRole('link', { name: record.attachment.title })
.first(),
).toHaveJSProperty('offsetWidth', value, { timeout: 1000 });
};
await showMenu(page, 'attachment');
await page.getByRole('menuitem', { name: 'Size' }).click();
await page.getByRole('option', { name: 'Large' }).click();
try {
await testLarge(153);
} catch (err) {
try {
await testLarge(154);
} catch (err) {
await testLarge(152);
}
}
// 改为小尺寸
const testSmall = async (value) => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.attachment-attachment')
.getByRole('link', { name: record.attachment.title })
.first(),
).toHaveJSProperty('offsetWidth', value, { timeout: 1000 });
};
await showMenu(page, 'attachment');
await page.getByRole('menuitem', { name: 'Size' }).click();
await page.getByRole('option', { name: 'Small' }).click();
try {
await testSmall(25);
} catch (err) {
try {
await testSmall(26);
} catch (err) {
await testSmall(24);
}
}
});
});
const gotoPage = async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
};
const openDialog = async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
};
const showMenu = async (page: Page, fieldName: string) => {
// 这里是为了等弹窗中的内容渲染稳定后,再去 hover防止错位导致测试报错
await page.waitForTimeout(1000);
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
};
async function openDialogAndShowMenu({
page,
mockPage,
mockRecord,
fieldName,
}: {
page: Page;
mockPage;
mockRecord;
fieldName: string;
}) {
await gotoPage(mockPage, mockRecord);
await openDialog(page);
await showMenu(page, fieldName);
}

View File

@ -1,256 +0,0 @@
import { Page, expect, oneTableBlockWithAddNewAndViewAndEditAndAssociationFields, test } from '@nocobase/test/e2e';
import { commonTesting } from '../commonTesting';
test.describe('many to many', () => {
commonTesting({
openDialogAndShowMenu,
fieldName: 'manyToMany',
fieldType: 'relation',
mode: 'options',
blockType: 'viewing',
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Title', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Tag', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-details', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-table', exact: true })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'manyToMany');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
test('enable link', async ({ page, mockPage, mockRecords }) => {
// test.fail();
const record = await gotoPage(mockPage, mockRecords);
await openDialog(page);
// 初始状态是一个可点击的链接
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.locator('a')
.filter({ hasText: record.manyToMany[0].id }),
).toBeVisible();
await showMenu(page, 'manyToMany');
// 默认情况下是开启状态
await expect(page.getByRole('menuitem', { name: 'Enable link' }).getByRole('switch')).toBeChecked();
await page.getByRole('menuitem', { name: 'Enable link' }).click();
await expect(page.getByRole('menuitem', { name: 'Enable link' }).getByRole('switch')).not.toBeChecked();
// 应变为非链接状态
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.locator('a')
.filter({ hasText: record.manyToMany[0].id }),
).not.toBeVisible();
// 再次开启链接状态
await page.getByRole('menuitem', { name: 'Enable link' }).click();
await expect(page.getByRole('menuitem', { name: 'Enable link' }).getByRole('switch')).toBeChecked();
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.locator('a')
.filter({ hasText: record.manyToMany[0].id }),
).toBeVisible();
});
});
test.describe('many to one', () => {
commonTesting({
openDialogAndShowMenu,
fieldName: 'manyToOne',
fieldType: 'relation',
mode: 'options',
blockType: 'viewing',
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'manyToOne');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Title', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Tag', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-details', exact: true })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'manyToOne');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
test('enable link', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'manyToOne');
await expect(page.getByRole('menuitem', { name: 'Enable link' }).getByRole('switch')).toBeChecked();
});
});
test.describe('one to many', () => {
commonTesting({
openDialogAndShowMenu,
fieldName: 'oneToMany',
fieldType: 'relation',
mode: 'options',
blockType: 'viewing',
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'oneToMany');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Title', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Tag', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-table', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-details', exact: true })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'oneToMany');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
test('enable link', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'oneToMany');
await expect(page.getByRole('menuitem', { name: 'Enable link' }).getByRole('switch')).toBeChecked();
});
});
test.describe('one to one (belongs to)', () => {
commonTesting({
openDialogAndShowMenu,
fieldName: 'oneToOneBelongsTo',
fieldType: 'relation',
mode: 'options',
blockType: 'viewing',
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'oneToOneBelongsTo');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Title', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Tag', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-details', exact: true })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'oneToOneBelongsTo');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
test('enable link', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'oneToOneBelongsTo');
await expect(page.getByRole('menuitem', { name: 'Enable link' }).getByRole('switch')).toBeChecked();
});
});
test.describe('one to one (has one)', () => {
commonTesting({
openDialogAndShowMenu,
fieldName: 'oneToOneHasOne',
fieldType: 'relation',
mode: 'options',
blockType: 'viewing',
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'oneToOneHasOne');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Title', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Tag', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-details', exact: true })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'oneToOneHasOne');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
test('enable link', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'oneToOneHasOne');
await expect(page.getByRole('menuitem', { name: 'Enable link' }).getByRole('switch')).toBeChecked();
});
});
const gotoPage = async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const record = (await mockRecords('general', 1))[0];
await nocoPage.goto();
return record;
};
const openDialog = async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
};
const showMenu = async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
};
async function openDialogAndShowMenu({
page,
mockPage,
mockRecords,
fieldName,
}: {
page: Page;
mockPage;
mockRecord;
mockRecords;
fieldName: string;
}) {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, fieldName);
}

View File

@ -1,106 +0,0 @@
import { Page, expect, oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields, test } from '@nocobase/test/e2e';
import { commonTesting } from '../commonTesting';
test.describe('created at', () => {
commonTesting({
openDialogAndShowMenu,
fieldName: 'createdAt',
fieldType: 'system',
mode: 'options',
blockType: 'viewing',
});
test('options', async ({ page, mockPage, mockRecord }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, fieldName: 'createdAt' });
await expect(page.getByRole('menuitem', { name: 'Date display format' })).toBeVisible();
});
});
test.describe('created by', () => {
commonTesting({
openDialogAndShowMenu,
fieldName: 'createdBy',
fieldType: 'system',
mode: 'options',
blockType: 'viewing',
});
test('options', async ({ page, mockPage, mockRecord }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, fieldName: 'createdBy' });
await expect(page.getByRole('menuitem', { name: 'Enable link' })).toBeVisible();
});
});
test.describe('id', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'id', fieldType: 'system', mode: 'options', blockType: 'viewing' });
});
test.describe('table oid', () => {
commonTesting({
openDialogAndShowMenu,
fieldName: 'tableoid',
fieldType: 'system',
mode: 'options',
blockType: 'viewing',
});
test('options', async ({ page, mockPage, mockRecord }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, fieldName: 'tableoid' });
await expect(page.getByRole('menuitem', { name: 'Edit tooltip' })).toBeVisible();
});
});
test.describe('last updated at', () => {
commonTesting({
openDialogAndShowMenu,
fieldName: 'updatedAt',
fieldType: 'system',
mode: 'options',
blockType: 'viewing',
});
});
test.describe('last updated by', () => {
commonTesting({
openDialogAndShowMenu,
fieldName: 'updatedBy',
fieldType: 'system',
mode: 'options',
blockType: 'viewing',
});
test('options', async ({ page, mockPage, mockRecord }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, fieldName: 'updatedBy' });
await expect(page.getByRole('menuitem', { name: 'Enable link' })).toBeVisible();
});
});
const gotoPage = async (mockPage, mockRecord) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
const record = await mockRecord('general');
await nocoPage.goto();
return record;
};
const openDialog = async (page: Page) => {
await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
};
const showMenu = async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
};
async function openDialogAndShowMenu({
page,
mockPage,
mockRecord,
fieldName,
}: {
page: Page;
mockPage;
mockRecord;
fieldName: string;
}) {
await gotoPage(mockPage, mockRecord);
await openDialog(page);
await showMenu(page, fieldName);
}

View File

@ -1,62 +0,0 @@
import { Page, expect, oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields, test } from '@nocobase/test/e2e';
import { commonTesting } from '../commonTesting';
test.describe('collection', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'collection', mode: 'options' });
});
test.describe('JSON', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'JSON', mode: 'options' });
});
test.describe('formula', () => {
test('should display correct options', async ({ page, mockPage, mockRecord, mockRecords }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, fieldName: 'formula' });
await expect(page.getByRole('menuitem', { name: 'Edit field title' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Display title' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Pattern' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Edit tooltip' })).toBeVisible();
});
});
test.describe('sequence', () => {
test('should display correct options', async ({ page, mockPage, mockRecord, mockRecords }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, fieldName: 'sequence' });
await expect(page.getByRole('menuitem', { name: 'Edit field title' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Display title' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Delete' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Pattern' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Edit description' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'required' })).toBeVisible();
});
});
const gotoPage = async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAdvancedFields).waitForInit();
await nocoPage.goto();
};
const openDialog = async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
};
const showMenu = async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
};
async function openDialogAndShowMenu({
page,
mockPage,
mockRecord,
fieldName,
}: {
page: Page;
mockPage;
mockRecord;
fieldName: string;
}) {
await gotoPage(mockPage);
await openDialog(page);
await showMenu(page, fieldName);
}

View File

@ -1,750 +0,0 @@
import { expect, oneTableBlockWithAddNewAndViewAndEditAndBasicFields, test } from '@nocobase/test/e2e';
import { commonTesting, testDefaultValue, testPattern, testSetValidationRules } from '../commonTesting';
test.describe('color', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'color' });
test('set default value', async ({ page, mockPage, mockRecord }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, fieldName: 'color' });
// 简单测试下是否有选项,值的话无法选中,暂时测不了
await expect(page.getByRole('menuitem', { name: 'Set default value' })).toBeVisible();
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'color'),
expectEditable: async () => {
// 默认情况下显示颜色选择框
await page.getByLabel('color-picker-normal').hover();
await expect(page.getByRole('button', { name: 'right Recommended', exact: true })).toBeVisible();
},
expectReadonly: async () => {
// 只读模式下,不会显示颜色弹窗
await page.getByLabel('color-picker-normal').hover();
await expect(page.getByRole('button', { name: 'right Recommended', exact: true })).not.toBeVisible();
},
expectEasyReading: async () => {
await expect(page.getByLabel('color-picker-read-pretty')).toBeVisible();
},
});
});
});
test.describe('email', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'email', mode: 'options' });
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () => showMenu(page, 'email'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
constantValue: 'test@nocobase.com',
variableValue: ['Current user', 'Email'],
expectConstantValue: () =>
expect(
page.getByLabel('block-item-CollectionField-general-form-general.email-email').getByRole('textbox'),
).toHaveValue('test@nocobase.com'),
expectVariableValue: () =>
expect(
page.getByLabel('block-item-CollectionField-general-form-general.email-email').getByRole('textbox'),
).toHaveValue('admin@nocobase.com'),
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'email'),
expectEditable: async () => {
// 填充一个值,方便后面断言
await page
.getByLabel('block-item-CollectionField-general-form-general.email-email')
.getByRole('textbox')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.email-email')
.getByRole('textbox')
.fill('admin@nocobase.com');
},
expectReadonly: async () => {
// 输入框应该被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.email-email').getByRole('textbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框应该消失,直接显示值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.email-email').getByRole('textbox'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.email-email')).toHaveText(
'email:admin@nocobase.com',
);
},
});
});
});
test.describe('icon', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'icon', mode: 'options' });
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () => showMenu(page, 'icon'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').getByRole('button', { name: 'Select icon' }).click();
await page.getByLabel('account-book').locator('svg').click();
},
expectConstantValue: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.icon-icon')
.getByRole('button', { name: 'account-book' }),
).toBeVisible();
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'icon'),
expectEditable: async () => {
// 默认情况下可以编辑图标
await page.getByRole('button', { name: 'Select icon' }).click();
await page.getByLabel('account-book').locator('svg').click();
},
expectReadonly: async () => {
// 只读模式下,选择图标按钮会被禁用
await expect(page.getByRole('button', { name: 'account-book' })).toBeDisabled();
},
expectEasyReading: async () => {
// 按钮会消失,只剩下图标
await expect(page.getByRole('button', { name: 'account-book' })).not.toBeVisible();
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.icon-icon').getByLabel('account-book'),
).toBeVisible();
},
});
});
});
test.describe('single line text', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'singleLineText', mode: 'options' });
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () => showMenu(page, 'singleLineText'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
constantValue: 'test single line text',
variableValue: ['Current user', 'Email'], // 值为 admin@nocobase.com
expectConstantValue: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.singleLineText-singleLineText')
.getByRole('textbox'),
).toHaveValue('test single line text');
},
expectVariableValue: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.singleLineText-singleLineText')
.getByRole('textbox'),
).toHaveValue('admin@nocobase.com');
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'singleLineText'),
expectEditable: async () => {
// 默认情况下可以编辑
await page
.getByLabel('block-item-CollectionField-general-form-general.singleLineText-singleLineText')
.getByRole('textbox')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.singleLineText-singleLineText')
.getByRole('textbox')
.fill('test single line text');
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.singleLineText-singleLineText')
.getByRole('textbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框会消失,只剩下值
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.singleLineText-singleLineText')
.getByRole('textbox'),
).not.toBeVisible();
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.singleLineText-singleLineText'),
).toHaveText('singleLineText:test single line text');
},
});
});
test('Set validation rules', async ({ page, mockPage }) => {
await testSetValidationRules({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'singleLineText'),
});
});
});
test.describe('integer', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'integer', mode: 'options' });
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () => showMenu(page, 'integer'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
variableValue: ['Current user', 'ID'], // 值为 1
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').getByRole('spinbutton').click();
await page.getByLabel('block-item-VariableInput-').getByRole('spinbutton').fill('112233');
},
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.integer-integer').getByRole('spinbutton'),
).toHaveValue('112233');
},
expectVariableValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.integer-integer').getByRole('spinbutton'),
).toHaveValue('1');
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'integer'),
expectEditable: async () => {
// 默认情况下可以编辑
await page
.getByLabel('block-item-CollectionField-general-form-general.integer-integer')
.getByRole('spinbutton')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.integer-integer')
.getByRole('spinbutton')
.fill('112233');
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.integer-integer').getByRole('spinbutton'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框会消失,只剩下值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.integer-integer').getByRole('spinbutton'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.integer-integer')).toHaveText(
'integer:112233',
);
},
});
});
test('set validation rules', async ({ page, mockPage }) => {
await testSetValidationRules({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'integer'),
});
});
});
test.describe('number', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'number', mode: 'options' });
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () => showMenu(page, 'number'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').getByRole('spinbutton').click();
await page.getByLabel('block-item-VariableInput-').getByRole('spinbutton').fill('11.22');
},
variableValue: ['Current user', 'ID'], // 值为 1
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.number-number').getByRole('spinbutton'),
).toHaveValue('11.22');
},
expectVariableValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.number-number').getByRole('spinbutton'),
).toHaveValue('1');
},
});
});
test('pattern', async ({ page, mockPage }) => {
// TODO: number 类型的字段,当输入了小数,然后把 Pattern 切换成 Easy-reading 模式,小数不应该被去掉;
test.fail();
await testPattern({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'number'),
expectEditable: async () => {
// 默认情况下可以编辑
await page
.getByLabel('block-item-CollectionField-general-form-general.number-number')
.getByRole('spinbutton')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.number-number')
.getByRole('spinbutton')
.fill('11.22');
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.number-number').getByRole('spinbutton'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框会消失,只剩下值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.number-number').getByRole('spinbutton'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.number-number')).toHaveText(
'number:11.22',
);
},
});
});
test('set validation rules', async ({ page, mockPage }) => {
await testSetValidationRules({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'number'),
});
});
});
test.describe('password', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'password', mode: 'options' });
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () => showMenu(page, 'password'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
constantValue: 'test112233password',
variableValue: ['Current user', 'Email'], // 值为 admin@nocobase.com
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.password-password').getByRole('textbox'),
).toHaveValue('test112233password');
},
expectVariableValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.password-password').getByRole('textbox'),
).toHaveValue('admin@nocobase.com');
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'password'),
expectEditable: async () => {
// 默认情况下可以编辑
await page
.getByLabel('block-item-CollectionField-general-form-general.password-password')
.getByRole('textbox')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.password-password')
.getByRole('textbox')
.fill('test112233password');
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.password-password').getByRole('textbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框会消失,只剩下值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.password-password').getByRole('textbox'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.password-password')).toHaveText(
'password:********',
);
},
});
});
test('set validation rules', async ({ page, mockPage }) => {
await testSetValidationRules({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'password'),
});
});
});
test.describe('percent', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'percent', mode: 'options' });
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () => showMenu(page, 'percent'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').getByRole('spinbutton').click();
await page.getByLabel('block-item-VariableInput-').getByRole('spinbutton').fill('11.22');
},
variableValue: ['Current user', 'ID'], // 值为 1
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.percent-percent').getByRole('spinbutton'),
).toHaveValue('11.22');
},
expectVariableValue: async () => {
// 数字 1 转换为百分比后为 100%
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.percent-percent').getByRole('spinbutton'),
).toHaveValue('100');
},
});
});
test('pattern', async ({ page, mockPage }) => {
// TODO: percent 类型的字段,当输入了小数,然后把 Pattern 切换成 Easy-reading 模式,小数点不应该被去掉;
test.fail();
await testPattern({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'percent'),
expectEditable: async () => {
// 默认情况下可以编辑
await page
.getByLabel('block-item-CollectionField-general-form-general.percent-percent')
.getByRole('spinbutton')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.percent-percent')
.getByRole('spinbutton')
.fill('11.22');
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.percent-percent').getByRole('spinbutton'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框会消失,只剩下值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.percent-percent').getByRole('spinbutton'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.percent-percent')).toHaveText(
'percent:11.22%',
);
},
});
});
test('set validation rules', async ({ page, mockPage }) => {
await testSetValidationRules({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'percent'),
});
});
});
test.describe('phone', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'phone', mode: 'options' });
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () => showMenu(page, 'phone'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
constantValue: '17777777777',
variableValue: ['Current user', 'ID'], // 值为 1
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.phone-phone').getByRole('textbox'),
).toHaveValue('17777777777');
},
expectVariableValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.phone-phone').getByRole('textbox'),
).toHaveValue('1');
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'phone'),
expectEditable: async () => {
// 默认情况下可以编辑
await page
.getByLabel('block-item-CollectionField-general-form-general.phone-phone')
.getByRole('textbox')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.phone-phone')
.getByRole('textbox')
.fill('17777777777');
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.phone-phone').getByRole('textbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框会消失,只剩下值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.phone-phone').getByRole('textbox'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.phone-phone')).toHaveText(
'phone:17777777777',
);
},
});
});
});
test.describe('long text', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'longText', mode: 'options' });
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
closeDialog: async () => {
await page.getByLabel('drawer-Action.Container-general-Add record-mask').click();
},
showMenu: () => showMenu(page, 'longText'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
constantValue: 'test long text',
variableValue: ['Current user', 'Email'], // 值为 admin@nocobase.com
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.longText-longText').getByRole('textbox'),
).toHaveValue('test long text');
},
expectVariableValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.longText-longText').getByRole('textbox'),
).toHaveValue('admin@nocobase.com');
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'longText'),
expectEditable: async () => {
// 默认情况下可以编辑
await page
.getByLabel('block-item-CollectionField-general-form-general.longText-longText')
.getByRole('textbox')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.longText-longText')
.getByRole('textbox')
.fill('test long text');
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.longText-longText').getByRole('textbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框会消失,只剩下值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.longText-longText').getByRole('textbox'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.longText-longText')).toHaveText(
'longText:test long text',
);
},
});
});
test('set validation rules', async ({ page, mockPage }) => {
await testSetValidationRules({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'longText'),
});
});
});
test.describe('URL', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'url', mode: 'options' });
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
closeDialog: async () => {
await page.getByLabel('drawer-Action.Container-general-Add record-mask').click();
},
showMenu: () => showMenu(page, 'url'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
constantValue: 'https://nocobase.com',
variableValue: ['Current user', 'Email'], // 值为 admin@nocobase.com
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.url-url').getByRole('textbox'),
).toHaveValue('https://nocobase.com');
},
expectVariableValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.url-url').getByRole('textbox'),
).toHaveValue('admin@nocobase.com');
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'url'),
expectEditable: async () => {
// 默认情况下可以编辑
await page.getByLabel('block-item-CollectionField-general-form-general.url-url').getByRole('textbox').click();
await page
.getByLabel('block-item-CollectionField-general-form-general.url-url')
.getByRole('textbox')
.fill('https://nocobase.com');
},
expectReadonly: async () => {
// 只读模式下,输入框会被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.url-url').getByRole('textbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
// 输入框会消失,只剩下值
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.url-url').getByRole('textbox'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.url-url')).toHaveText(
'url:https://nocobase.com',
);
},
});
});
});
const gotoPage = async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndBasicFields).waitForInit();
await nocoPage.goto();
};
const openDialog = async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
};
const showMenu = async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
};
async function openDialogAndShowMenu({
page,
mockPage,
mockRecord,
fieldName,
}: {
page: Page;
mockPage;
mockRecord;
fieldName: string;
}) {
await gotoPage(mockPage);
await openDialog(page);
await showMenu(page, fieldName);
}

View File

@ -1,395 +0,0 @@
import { Page, expect, oneTableBlockWithAddNewAndViewAndEditAndChoicesFields, test } from '@nocobase/test/e2e';
import { commonTesting, testDefaultValue, testPattern } from '../commonTesting';
test.describe('checkbox', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'checkbox', mode: 'options' });
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () => showMenu(page, 'checkbox'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
// 默认应该是没有被选中的,点击后应该被选中
await page.getByLabel('block-item-VariableInput-').getByRole('checkbox').click();
},
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.checkbox-checkbox').getByRole('checkbox'),
).toBeChecked();
},
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
await testPattern({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'checkbox'),
expectEditable: async () => {
// 默认是未选中的状态,所以先选中
await page
.getByLabel('block-item-CollectionField-general-form-general.checkbox-checkbox')
.getByRole('checkbox')
.click();
},
expectReadonly: async () => {
// checkbox 应该被禁用
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.checkbox-checkbox').getByRole('checkbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
// checkbox 应该被隐藏,然后只显示一个图标
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.checkbox-checkbox').getByRole('checkbox'),
).not.toBeVisible();
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.checkbox-checkbox')
.getByRole('img', { name: 'check' }),
).toBeVisible();
},
});
});
});
test.describe('checkbox group', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'checkboxGroup', mode: 'options' });
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () => showMenu(page, 'checkboxGroup'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').getByLabel('Option1').click();
},
expectConstantValue: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.checkboxGroup-checkboxGroup')
.getByRole('checkbox', { name: 'Option1' }),
).toBeChecked();
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'checkboxGroup'),
expectEditable: async () => {
// 默认是未选中的状态,所以先选中
await page
.getByLabel('block-item-CollectionField-general-form-general.checkboxGroup-checkboxGroup')
.getByRole('checkbox', { name: 'Option1' })
.click();
},
expectReadonly: async () => {
// checkbox 应该被禁用
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.checkboxGroup-checkboxGroup')
.getByRole('checkbox', { name: 'Option1' }),
).toBeDisabled();
},
expectEasyReading: async () => {
// checkbox 应该被隐藏,然后只显示一个标签
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.checkboxGroup-checkboxGroup')
.getByRole('checkbox', { name: 'Option1' }),
).not.toBeVisible();
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.checkboxGroup-checkboxGroup')
.getByText('Option1'),
).toBeVisible();
},
});
});
});
test.describe('china region', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'chinaRegion', mode: 'options' });
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () => showMenu(page, 'chinaRegion'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').click();
await page.getByRole('menuitemcheckbox', { name: '北京市' }).click();
await page.getByRole('menuitemcheckbox', { name: '市辖区' }).click();
await page.getByRole('menuitemcheckbox', { name: '东城区' }).click();
},
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.chinaRegion-chinaRegion'),
).toHaveText('chinaRegion:北京市/市辖区/东城区');
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'chinaRegion'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.chinaRegion-chinaRegion')
.locator('.ant-select')
.click();
await page.getByRole('menuitemcheckbox', { name: '北京市' }).click();
await page.getByRole('menuitemcheckbox', { name: '市辖区' }).click();
await page.getByRole('menuitemcheckbox', { name: '东城区' }).click();
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.chinaRegion-chinaRegion')
.locator('.ant-select')
.getByRole('combobox'),
).toBeDisabled();
},
expectEasyReading: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.chinaRegion-chinaRegion')
.locator('.ant-select')
.getByRole('combobox'),
).not.toBeVisible();
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.chinaRegion-chinaRegion'),
).toHaveText('chinaRegion:北京市 / 市辖区 / 东城区');
},
});
});
});
test.describe('multiple select', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'multipleSelect', mode: 'options' });
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () => showMenu(page, 'multipleSelect'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').getByTestId('select-multiple').click();
await page.getByRole('option', { name: 'Option1' }).click();
await page.getByRole('option', { name: 'Option2' }).click();
await page.getByRole('option', { name: 'Option3' }).click();
},
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.multipleSelect-multipleSelect'),
).toHaveText('multipleSelect:Option1Option2Option3');
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'multipleSelect'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.multipleSelect-multipleSelect')
.getByTestId('select-multiple')
.click();
await page.getByRole('option', { name: 'Option1' }).click();
await page.getByRole('option', { name: 'Option2' }).click();
await page.getByRole('option', { name: 'Option3' }).click();
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.multipleSelect-multipleSelect')
.getByTestId('select-multiple'),
).toHaveClass(/ant-select-disabled/);
},
expectEasyReading: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.multipleSelect-multipleSelect')
.getByTestId('select-multiple'),
).not.toBeVisible();
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.multipleSelect-multipleSelect'),
).toHaveText('multipleSelect:Option1Option2Option3');
},
});
});
});
test.describe('radio group', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'radioGroup', mode: 'options' });
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () => showMenu(page, 'radioGroup'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').getByLabel('Option2').click();
},
expectConstantValue: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.radioGroup-radioGroup')
.getByLabel('Option2'),
).toBeChecked();
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'radioGroup'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.radioGroup-radioGroup')
.getByLabel('Option2')
.click();
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.radioGroup-radioGroup')
.getByLabel('Option2'),
).toBeDisabled();
},
expectEasyReading: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.radioGroup-radioGroup')
.getByLabel('Option2'),
).not.toBeVisible();
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.radioGroup-radioGroup'),
).toHaveText('radioGroup:Option2');
},
});
});
});
test.describe('single select', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'singleSelect', mode: 'options' });
test('set default value', async ({ page, mockPage }) => {
await testDefaultValue({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () => showMenu(page, 'singleSelect'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').click();
await page.getByRole('option', { name: 'Option1' }).click();
},
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.singleSelect-singleSelect'),
).toHaveText('singleSelect:Option1');
},
});
});
test('pattern', async ({ page, mockPage }) => {
await testPattern({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'singleSelect'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.singleSelect-singleSelect')
.getByTestId('select-single')
.click();
await page.getByRole('option', { name: 'Option1' }).click();
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.singleSelect-singleSelect')
.getByTestId('select-single'),
).toHaveClass(/ant-select-disabled/);
},
expectEasyReading: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.singleSelect-singleSelect')
.getByTestId('select-single'),
).not.toBeVisible();
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.singleSelect-singleSelect'),
).toHaveText('singleSelect:Option1');
},
});
});
});
const gotoPage = async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndChoicesFields).waitForInit();
await nocoPage.goto();
};
const openDialog = async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
};
const showMenu = async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
};
async function openDialogAndShowMenu({
page,
mockPage,
mockRecord,
fieldName,
}: {
page: Page;
mockPage;
mockRecord;
fieldName: string;
}) {
await gotoPage(mockPage);
await openDialog(page);
await showMenu(page, fieldName);
}

View File

@ -1,158 +0,0 @@
import { Page, expect, oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields, test } from '@nocobase/test/e2e';
import dayjs from 'dayjs';
import { commonTesting, testDefaultValue, testPattern } from '../commonTesting';
test.describe('datetime', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'datetime', blockType: 'creating', mode: 'options' });
test('set default value', async ({ page, mockPage, mockRecord }) => {
await testDefaultValue({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () => showMenu(page, 'datetime'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').getByPlaceholder('Select date').click();
await page.getByText('Today').click();
},
expectConstantValue: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.datetime-datetime')
.getByPlaceholder('Select date'),
).toHaveValue(dayjs().format('YYYY-MM-DD'));
},
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
await testPattern({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'datetime'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.datetime-datetime')
.getByPlaceholder('Select date')
.click();
await page.getByText('Today').click();
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.datetime-datetime')
.getByPlaceholder('Select date'),
).toBeDisabled();
},
expectEasyReading: async () => {
await expect(page.getByLabel('block-item-CollectionField-general-form-general.datetime-datetime')).toHaveText(
`datetime:${dayjs().format('YYYY-MM-DD')}`,
);
},
});
});
test('date display format', async ({ page, mockPage, mockRecord }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, fieldName: 'datetime' });
await page.getByRole('menuitem', { name: 'Date display format' }).click();
await page.getByLabel('YYYY/MM/DD').click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 输入一个值,然后验证格式是否正确
await page
.getByLabel('block-item-CollectionField-general-form-general.datetime-datetime')
.getByPlaceholder('Select date')
.click();
await page.getByText('Today').click();
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.datetime-datetime')
.getByPlaceholder('Select date'),
).toHaveValue(dayjs().format('YYYY/MM/DD'));
});
});
test.describe('time', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'time', blockType: 'creating', mode: 'options' });
test('set default value', async ({ page, mockPage, mockRecord }) => {
await testDefaultValue({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () => showMenu(page, 'time'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').getByPlaceholder('Select time').click();
await page.getByText('Now').click();
},
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.time-time').getByPlaceholder('Select time'),
).toHaveValue(new RegExp(dayjs().format('HH:mm:'))); // 去掉后面的秒,是因为可能因为延迟导致秒数不一致
},
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
await testPattern({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'time'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.time-time')
.getByPlaceholder('Select time')
.click();
await page.getByText('Now').click();
},
expectReadonly: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.time-time').getByPlaceholder('Select time'),
).toBeDisabled();
},
expectEasyReading: async () => {
await expect(page.getByLabel('block-item-CollectionField-general-form-general.time-time')).toHaveText(
new RegExp(`time:${dayjs().format('HH:mm:')}`),
);
},
});
});
});
const gotoPage = async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndDatetimeFields).waitForInit();
await nocoPage.goto();
};
const openDialog = async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
};
const showMenu = async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
};
async function openDialogAndShowMenu({
page,
mockPage,
mockRecord,
fieldName,
}: {
page: Page;
mockPage;
mockRecord;
fieldName: string;
}) {
await gotoPage(mockPage);
await openDialog(page);
await showMenu(page, fieldName);
}

View File

@ -1,184 +0,0 @@
import { Page, expect, oneTableBlockWithAddNewAndViewAndEditAndMediaFields, test } from '@nocobase/test/e2e';
import { commonTesting, testDefaultValue, testPattern, testSetValidationRules } from '../commonTesting';
test.describe('markdown', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'markdown', mode: 'options' });
test('set default value', async ({ page, mockPage, mockRecord }) => {
await testDefaultValue({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () => showMenu(page, 'markdown'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
constantValue: 'test markdown',
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.markdown-markdown').getByRole('textbox'),
).toHaveValue('test markdown');
},
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
await testPattern({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'markdown'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.markdown-markdown')
.getByRole('textbox')
.click();
await page
.getByLabel('block-item-CollectionField-general-form-general.markdown-markdown')
.getByRole('textbox')
.fill('test markdown pattern');
},
expectReadonly: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.markdown-markdown').getByRole('textbox'),
).toBeDisabled();
},
expectEasyReading: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.markdown-markdown').getByRole('textbox'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.markdown-markdown')).toHaveText(
`markdown:test markdown pattern`,
);
},
});
});
test('Set validation rules', async ({ page, mockPage }) => {
await testSetValidationRules({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'markdown'),
});
});
});
test.describe('rich text', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'richText', mode: 'options' });
test('set default value', async ({ page, mockPage, mockRecord }) => {
await testDefaultValue({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () => showMenu(page, 'richText'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-CollectionField-general-general.richText').locator('.ql-editor').click();
await page.keyboard.type('test rich text');
},
expectConstantValue: async () => {
await expect(page.getByLabel('block-item-CollectionField-general-form-general.richText-richText')).toHaveText(
/test rich text/,
);
},
});
});
test('pattern', async ({ page, mockPage, mockRecord }) => {
await testPattern({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'richText'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.richText-richText')
.locator('.ql-editor')
.click();
await page.keyboard.type('test rich text pattern');
},
expectReadonly: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.richText-richText').locator('.ql-container'),
).toHaveClass(/ql-disabled/);
},
expectEasyReading: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.richText-richText').locator('.ql-container'),
).not.toBeVisible();
await expect(page.getByLabel('block-item-CollectionField-general-form-general.richText-richText')).toHaveText(
/test rich text pattern/,
);
},
});
});
test('Set validation rules', async ({ page, mockPage }) => {
await testSetValidationRules({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'markdown'),
});
});
});
test.describe('attachment', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'attachment', mode: 'options' });
test('pattern', async ({ page, mockPage, mockRecord }) => {
await testPattern({
page,
gotoPage: () => gotoPage(mockPage),
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'attachment'),
expectEditable: async () => {
await expect(page.getByRole('button', { name: 'plus Upload' })).toBeVisible();
},
expectReadonly: async () => {
await expect(page.getByRole('button', { name: 'plus Upload' })).not.toBeVisible();
},
expectEasyReading: async () => {
await expect(page.getByRole('button', { name: 'plus Upload' })).not.toBeVisible();
},
});
});
});
const gotoPage = async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndMediaFields).waitForInit();
await nocoPage.goto();
};
const openDialog = async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
};
const showMenu = async (page: Page, fieldName: string) => {
await page
.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`, { exact: true })
.hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`, {
exact: true,
})
.hover();
};
async function openDialogAndShowMenu({
page,
mockPage,
mockRecord,
fieldName,
}: {
page: Page;
mockPage;
mockRecord;
fieldName: string;
}) {
await gotoPage(mockPage);
await openDialog(page);
await showMenu(page, fieldName);
}

View File

@ -1,658 +0,0 @@
import { Page, expect, oneTableBlockWithAddNewAndViewAndEditAndAssociationFields, test } from '@nocobase/test/e2e';
import { commonTesting, testDefaultValue, testPattern } from '../commonTesting';
test.describe('many to many', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'manyToMany', fieldType: 'relation', mode: 'options' });
test('set default value', async ({ page, mockPage, mockRecords }) => {
let recordsOfUser;
await testDefaultValue({
page,
gotoPage: async () => {
recordsOfUser = await gotoPage(mockPage, mockRecords);
},
openDialog: () => openDialog(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () => showMenu(page, 'manyToMany'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page.getByLabel('block-item-VariableInput-').getByTestId('select-object-multiple').click();
await page.getByRole('option', { name: String(recordsOfUser[0].id), exact: true }).click();
await page.getByRole('option', { name: String(recordsOfUser[1].id), exact: true }).click();
await page.getByRole('option', { name: String(recordsOfUser[2].id), exact: true }).click();
},
expectConstantValue: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany'),
).toHaveText(`manyToMany:${recordsOfUser.map((record) => record.id).join('')}`);
},
});
});
test('pattern', async ({ page, mockPage, mockRecords }) => {
let records;
await testPattern({
page,
gotoPage: async () => {
records = await gotoPage(mockPage, mockRecords);
},
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'manyToMany'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.getByTestId('select-object-multiple')
.click();
await page.getByRole('option', { name: String(records[0].id), exact: true }).click();
await page.getByRole('option', { name: String(records[1].id), exact: true }).click();
await page.getByRole('option', { name: String(records[2].id), exact: true }).click();
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.getByTestId('select-object-multiple'),
).toHaveClass(/ant-select-disabled/);
// 在这里等待一下,防止因闪烁导致下面的断言失败
await page.waitForTimeout(100);
},
expectEasyReading: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany'),
).toHaveText(`manyToMany:${records.map((record) => record.id).join(',')}`);
},
});
});
test('Set the data scope', async ({ page, mockPage, mockRecords }) => {
const records = await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await page.getByText('Add condition', { exact: true }).click();
await page.getByTestId('select-filter-field').click();
await page.getByRole('menuitemcheckbox', { name: 'ID', exact: true }).click();
await page.getByRole('spinbutton').click();
await page.getByRole('spinbutton').fill(String(records[0].id));
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 再次打开弹窗,设置的值应该还在
await showMenu(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await expect(page.getByTestId('select-filter-field')).toHaveText('ID');
await expect(page.getByRole('spinbutton')).toHaveValue(String(records[0].id));
await page.getByRole('button', { name: 'Cancel', exact: true }).click();
// 数据应该被过滤了
await page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.getByTestId('select-object-multiple')
.click();
await expect(page.getByRole('option', { name: String(records[0].id), exact: true })).toBeVisible();
await expect(page.getByRole('option')).toHaveCount(1);
});
test('set default sorting rules', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Set default sorting rules' }).click();
// 配置
await page.getByRole('button', { name: 'Add sort field' }).click();
await page.getByTestId('select-single').click();
await page.getByRole('option', { name: 'ID', exact: true }).click();
await page.getByText('DESC', { exact: true }).click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 再次打开弹窗,设置的值应该还在
await showMenu(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Set default sorting rules' }).click();
await expect(page.getByRole('dialog').getByTestId('select-single')).toHaveText('ID');
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Select', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Record picker', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-table', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form(Popover)', exact: true })).toBeVisible();
// 选择 Record picker
await page.getByRole('option', { name: 'Record picker', exact: true }).click();
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.getByTestId('select-data-picker'),
).toBeVisible();
// 选择 Sub-table
await showMenu(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Field component' }).click();
await page.getByRole('option', { name: 'Sub-table', exact: true }).click();
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.getByLabel('schema-initializer-AssociationField.SubTable-TableColumnInitializers-users'),
).toBeVisible();
// 选择 Sub-form
await showMenu(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Field component' }).click();
await page.getByRole('option', { name: 'Sub-form', exact: true }).click();
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.getByLabel('schema-initializer-Grid-FormItemInitializers-users'),
).toBeVisible();
// 选择 Sub-form(Popover)
await showMenu(page, 'manyToMany');
await page.getByRole('menuitem', { name: 'Field component' }).click();
await page.getByRole('option', { name: 'Sub-form(Popover)', exact: true }).click();
await page
.getByLabel('block-item-CollectionField-general-form-general.manyToMany-manyToMany')
.getByRole('img', { name: 'edit' })
.click();
await expect(page.getByTestId('popover-CollectionField-general')).toBeVisible();
});
test('quick create', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'manyToMany');
await expect(page.getByRole('menuitem', { name: 'Quick create' })).toBeVisible();
});
test('allow multiple', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'manyToMany');
await expect(page.getByRole('menuitem', { name: 'Allow multiple' })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'manyToMany');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
});
test.describe('many to one', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'manyToOne', fieldType: 'relation', mode: 'options' });
test('set default value', async ({ page, mockPage, mockRecords }) => {
let records;
await testDefaultValue({
page,
gotoPage: async () => {
records = await gotoPage(mockPage, mockRecords);
},
openDialog: () => openDialog(page),
closeDialog: () => page.getByLabel('drawer-Action.Container-general-Add record-mask').click(),
showMenu: () => showMenu(page, 'manyToOne'),
supportVariables: ['Constant', 'Current user', 'Date variables', 'Current form'],
inputConstantValue: async () => {
await page
.getByLabel('block-item-VariableInput-')
.getByTestId(/select-object/)
.click();
await page.getByRole('option', { name: String(records[0].id), exact: true }).click();
await page
.getByLabel('block-item-VariableInput-')
.getByTestId(/select-object/)
.click();
await page.getByRole('option', { name: String(records[1].id), exact: true }).click();
await page
.getByLabel('block-item-VariableInput-')
.getByTestId(/select-object/)
.click();
await page.getByRole('option', { name: String(records[2].id), exact: true }).click();
},
expectConstantValue: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.manyToOne-manyToOne')
.getByTestId(/select-object/),
).toHaveText(String(records[2].id));
},
});
});
test('pattern', async ({ page, mockPage, mockRecords }) => {
let records;
await testPattern({
page,
gotoPage: async () => {
records = await gotoPage(mockPage, mockRecords);
},
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'manyToOne'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.manyToOne-manyToOne')
.getByTestId(/select-object/)
.click();
await page.getByRole('option', { name: String(records[0].id), exact: true }).click();
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.manyToOne-manyToOne')
.getByTestId(/select-object/),
).toHaveClass(/ant-select-disabled/);
// 在这里等待一下,防止因闪烁导致下面的断言失败
await page.waitForTimeout(100);
},
expectEasyReading: async () => {
await expect(page.getByLabel('block-item-CollectionField-general-form-general.manyToOne-manyToOne')).toHaveText(
`manyToOne:${String(records[0].id)}`,
);
},
});
});
test('Set the data scope', async ({ page, mockPage, mockRecords }) => {
const records = await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'manyToOne');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await page.getByText('Add condition', { exact: true }).click();
await page.getByTestId('select-filter-field').click();
await page.getByRole('menuitemcheckbox', { name: 'ID', exact: true }).click();
await page.getByRole('spinbutton').click();
await page.getByRole('spinbutton').fill(String(records[0].id));
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 再次打开弹窗,设置的值应该还在
await showMenu(page, 'manyToOne');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await expect(page.getByTestId('select-filter-field')).toHaveText('ID');
await expect(page.getByRole('spinbutton')).toHaveValue(String(records[0].id));
await page.getByRole('button', { name: 'Cancel', exact: true }).click();
// 数据应该被过滤了
await page
.getByLabel('block-item-CollectionField-general-form-general.manyToOne-manyToOne')
.getByTestId('select-object-single')
.click();
await expect(page.getByRole('option', { name: String(records[0].id), exact: true })).toBeVisible();
await expect(page.getByRole('option')).toHaveCount(1);
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'manyToOne');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Select', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Record picker', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form(Popover)', exact: true })).toBeVisible();
});
test('quick create', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'manyToOne');
await expect(page.getByRole('menuitem', { name: 'Quick create' })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'manyToOne');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
});
test.describe('one to many', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'oneToMany', fieldType: 'relation', mode: 'options' });
test('set default value', async ({ page, mockPage, mockRecord, mockRecords }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, mockRecords, fieldName: 'oneToMany' });
await expect(page.getByRole('menuitem', { name: 'Set default value' })).not.toBeVisible();
});
test('pattern', async ({ page, mockPage, mockRecords }) => {
await testPattern({
page,
gotoPage: async () => {
await gotoPage(mockPage, mockRecords);
},
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'oneToMany'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.oneToMany-oneToMany')
.getByTestId('select-object-multiple')
.click();
// 目前的情况下,在 one to many 的字段中,只有 ID 为 1 的数据可以被选中
await page.getByRole('option', { name: '1', exact: true }).click();
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.oneToMany-oneToMany')
.getByTestId('select-object-multiple'),
).toHaveClass(/ant-select-disabled/);
// 在这里等待一下,防止因闪烁导致下面的断言失败
await page.waitForTimeout(100);
},
expectEasyReading: async () => {
await expect(page.getByLabel('block-item-CollectionField-general-form-general.oneToMany-oneToMany')).toHaveText(
`oneToMany:1`,
);
},
});
});
test('Set the data scope', async ({ page, mockPage, mockRecords }) => {
const records = await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'oneToMany');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await page.getByText('Add condition', { exact: true }).click();
await page.getByTestId('select-filter-field').click();
await page.getByRole('menuitemcheckbox', { name: 'ID', exact: true }).click();
await page.getByRole('spinbutton').click();
await page.getByRole('spinbutton').fill(String(records[0].id));
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 再次打开弹窗,设置的值应该还在
await showMenu(page, 'oneToMany');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await expect(page.getByTestId('select-filter-field')).toHaveText('ID');
await expect(page.getByRole('spinbutton')).toHaveValue(String(records[0].id));
await page.getByRole('button', { name: 'Cancel', exact: true }).click();
// 数据应该被过滤了
await page
.getByLabel('block-item-CollectionField-general-form-general.oneToMany-oneToMany')
.getByTestId('select-object-multiple')
.click();
// 默认只显示 id 为 1 的数据,因为设置了只过滤 id 为 3 的数据所以这里的下拉列表应该为空mock 的数据无法被选中
await expect(page.getByRole('option')).toHaveCount(0);
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'oneToMany');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Select', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Record picker', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-table', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form(Popover)', exact: true })).toBeVisible();
});
test('quick create', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'oneToMany');
await expect(page.getByRole('menuitem', { name: 'Quick create' })).toBeVisible();
});
test('allow multiple', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'oneToMany');
await expect(page.getByRole('menuitem', { name: 'Allow multiple' })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'oneToMany');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
});
test.describe('one to one (belongs to)', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'oneToOneBelongsTo', fieldType: 'relation', mode: 'options' });
test('set default value', async ({ page, mockPage, mockRecord, mockRecords }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, mockRecords, fieldName: 'oneToOneBelongsTo' });
await expect(page.getByRole('menuitem', { name: 'Set default value' })).not.toBeVisible();
});
test('pattern', async ({ page, mockPage, mockRecords }) => {
let records;
await testPattern({
page,
gotoPage: async () => {
records = await gotoPage(mockPage, mockRecords);
},
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'oneToOneBelongsTo'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.oneToOneBelongsTo-oneToOneBelongsTo')
.getByTestId(/select-object/)
.click();
await page.getByRole('option', { name: String(records[0].id), exact: true }).click();
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.oneToOneBelongsTo-oneToOneBelongsTo')
.getByTestId(/select-object/),
).toHaveClass(/ant-select-disabled/);
// 在这里等待一下,防止因闪烁导致下面的断言失败
await page.waitForTimeout(100);
},
expectEasyReading: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.oneToOneBelongsTo-oneToOneBelongsTo'),
).toHaveText(`oneToOneBelongsTo:${String(records[0].id)}`);
},
});
});
test('Set the data scope', async ({ page, mockPage, mockRecords }) => {
const records = await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'oneToOneBelongsTo');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await page.getByText('Add condition', { exact: true }).click();
await page.getByTestId('select-filter-field').click();
await page.getByRole('menuitemcheckbox', { name: 'ID', exact: true }).click();
await page.getByRole('spinbutton').click();
await page.getByRole('spinbutton').fill(String(records[0].id));
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 再次打开弹窗,设置的值应该还在
await showMenu(page, 'oneToOneBelongsTo');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await expect(page.getByTestId('select-filter-field')).toHaveText('ID');
await expect(page.getByRole('spinbutton')).toHaveValue(String(records[0].id));
await page.getByRole('button', { name: 'Cancel', exact: true }).click();
// 数据应该被过滤了
await page
.getByLabel('block-item-CollectionField-general-form-general.oneToOneBelongsTo-oneToOneBelongsTo')
.getByTestId('select-object-single')
.click();
await expect(page.getByRole('option', { name: String(records[0].id), exact: true })).toBeVisible();
await expect(page.getByRole('option')).toHaveCount(1);
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'oneToOneBelongsTo');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Select', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Record picker', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form(Popover)', exact: true })).toBeVisible();
});
test('quick create', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'oneToOneBelongsTo');
await expect(page.getByRole('menuitem', { name: 'Quick create' })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'oneToOneBelongsTo');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
});
test.describe('one to one (has one)', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'oneToOneHasOne', fieldType: 'relation', mode: 'options' });
test('set default value', async ({ page, mockPage, mockRecord, mockRecords }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, mockRecords, fieldName: 'oneToOneHasOne' });
await expect(page.getByRole('menuitem', { name: 'Set default value' })).not.toBeVisible();
});
test('pattern', async ({ page, mockPage, mockRecords }) => {
let records;
await testPattern({
page,
gotoPage: async () => {
records = await gotoPage(mockPage, mockRecords);
},
openDialog: () => openDialog(page),
showMenu: () => showMenu(page, 'oneToOneHasOne'),
expectEditable: async () => {
await page
.getByLabel('block-item-CollectionField-general-form-general.oneToOneHasOne-oneToOneHasOne')
.getByTestId(/select-object/)
.click();
// 目前的情况下,在 one to one (has one) 的字段中,只有 ID 为 1 的数据可以被选中mock 的数据无法被选中
await page.getByRole('option', { name: '1', exact: true }).click();
},
expectReadonly: async () => {
await expect(
page
.getByLabel('block-item-CollectionField-general-form-general.oneToOneHasOne-oneToOneHasOne')
.getByTestId(/select-object/),
).toHaveClass(/ant-select-disabled/);
// 在这里等待一下,防止因闪烁导致下面的断言失败
await page.waitForTimeout(100);
},
expectEasyReading: async () => {
await expect(
page.getByLabel('block-item-CollectionField-general-form-general.oneToOneHasOne-oneToOneHasOne'),
).toHaveText(`oneToOneHasOne:1`);
},
});
});
test('Set the data scope', async ({ page, mockPage, mockRecords }) => {
const records = await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'oneToOneHasOne');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await page.getByText('Add condition', { exact: true }).click();
await page.getByTestId('select-filter-field').click();
await page.getByRole('menuitemcheckbox', { name: 'ID', exact: true }).click();
await page.getByRole('spinbutton').click();
await page.getByRole('spinbutton').fill(String(records[0].id));
await page.getByRole('button', { name: 'OK', exact: true }).click();
// 再次打开弹窗,设置的值应该还在
await showMenu(page, 'oneToOneHasOne');
await page.getByRole('menuitem', { name: 'Set the data scope' }).click();
await expect(page.getByTestId('select-filter-field')).toHaveText('ID');
await expect(page.getByRole('spinbutton')).toHaveValue(String(records[0].id));
await page.getByRole('button', { name: 'Cancel', exact: true }).click();
// 数据应该被过滤了
await page
.getByLabel('block-item-CollectionField-general-form-general.oneToOneHasOne-oneToOneHasOne')
.getByTestId('select-object-single')
.click();
// 默认只显示 id 为 1 的数据,因为设置了只过滤 id 为 3 的数据,所以这里的下拉列表应该为空
await expect(page.getByRole('option')).toHaveCount(0);
});
test('field component', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'oneToOneHasOne');
await page.getByRole('menuitem', { name: 'Field component' }).click();
// 断言支持的选项
await expect(page.getByRole('option', { name: 'Select', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Record picker', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form', exact: true })).toBeVisible();
await expect(page.getByRole('option', { name: 'Sub-form(Popover)', exact: true })).toBeVisible();
});
test('quick create', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'oneToOneHasOne');
await expect(page.getByRole('menuitem', { name: 'Quick create' })).toBeVisible();
});
test('title field', async ({ page, mockPage, mockRecords }) => {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, 'oneToOneHasOne');
await expect(page.getByRole('menuitem', { name: 'Title field' })).toBeVisible();
});
});
const gotoPage = async (mockPage, mockRecords) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
const recordsOfUser = await mockRecords('users', 3);
await nocoPage.goto();
return recordsOfUser;
};
const openDialog = async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
};
const showMenu = async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
};
async function openDialogAndShowMenu({
page,
mockPage,
mockRecords,
fieldName,
}: {
page: Page;
mockPage;
mockRecord;
mockRecords;
fieldName: string;
}) {
await gotoPage(mockPage, mockRecords);
await openDialog(page);
await showMenu(page, fieldName);
}

View File

@ -1,81 +0,0 @@
import { Page, expect, oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields, test } from '@nocobase/test/e2e';
import { commonTesting } from '../commonTesting';
test.describe('created at', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'createdAt', fieldType: 'system', mode: 'options' });
test('options', async ({ page, mockPage, mockRecord }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, fieldName: 'createdAt' });
await expect(page.getByRole('menuitem', { name: 'Edit tooltip' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Date display format' })).toBeVisible();
});
});
test.describe('created by', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'createdBy', fieldType: 'system', mode: 'options' });
test('options', async ({ page, mockPage, mockRecord }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, fieldName: 'createdBy' });
await expect(page.getByRole('menuitem', { name: 'Edit tooltip' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Enable link' })).toBeVisible();
});
});
test.describe('id', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'id', fieldType: 'system', mode: 'options' });
test('options', async ({ page, mockPage, mockRecord }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, fieldName: 'id' });
await expect(page.getByRole('menuitem', { name: 'Edit tooltip' })).toBeVisible();
});
});
test.describe('table oid', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'tableoid', fieldType: 'system', mode: 'options' });
test('options', async ({ page, mockPage, mockRecord }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, fieldName: 'tableoid' });
await expect(page.getByRole('menuitem', { name: 'Edit tooltip' })).toBeVisible();
});
});
test.describe('last updated at', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'updatedAt', fieldType: 'system', mode: 'options' });
});
test.describe('last updated by', () => {
commonTesting({ openDialogAndShowMenu, fieldName: 'updatedBy', fieldType: 'system', mode: 'options' });
test('options', async ({ page, mockPage, mockRecord }) => {
await openDialogAndShowMenu({ page, mockPage, mockRecord, fieldName: 'updatedBy' });
await expect(page.getByRole('menuitem', { name: 'Edit tooltip' })).toBeVisible();
await expect(page.getByRole('menuitem', { name: 'Enable link' })).toBeVisible();
});
});
const gotoPage = async (mockPage) => {
const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndSystemInfoFields).waitForInit();
await nocoPage.goto();
};
const openDialog = async (page: Page) => {
await page.getByRole('button', { name: 'Add new' }).click();
};
const showMenu = async (page: Page, fieldName: string) => {
await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-`).hover();
await page
.getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
.hover();
};
async function openDialogAndShowMenu({
page,
mockPage,
mockRecord,
fieldName,
}: {
page: Page;
mockPage;
mockRecord;
fieldName: string;
}) {
await gotoPage(mockPage);
await openDialog(page);
await showMenu(page, fieldName);
}

Some files were not shown because too many files have changed in this diff Show More