feat(e2e): add mockCollections (#3054)

* feat(e2e): add mockCollections

* fix: fix tests

* fix: make tests passing

* fix: fix tests

* fix: fix test

* chore: restart

* chore: skip some test
This commit is contained in:
被雨水过滤的空气-Rain 2023-11-17 16:54:04 +08:00 committed by GitHub
parent 36043be130
commit 3c98966169
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 146 additions and 477 deletions

View File

@ -494,161 +494,20 @@ const config = {
}, },
collections: [ collections: [
{ {
key: '14ptm4bp2ws',
name: 't_ylz5vtxncxq', name: 't_ylz5vtxncxq',
title: 'Test', title: 'Test',
inherit: false,
hidden: false,
description: null,
fields: [ fields: [
{ {
key: 'hlv63gj1nta',
name: 'id',
type: 'bigInt',
interface: 'id',
description: null,
collectionName: 't_ylz5vtxncxq',
parentKey: null,
reverseKey: null,
autoIncrement: true,
primaryKey: true,
allowNull: false,
uiSchema: {
type: 'number',
title: '{{t("ID")}}',
'x-component': 'InputNumber',
'x-read-pretty': true,
},
},
{
key: 'g17u6c8oi7v',
name: 'f_lkqy3eh4ag7', name: 'f_lkqy3eh4ag7',
type: 'bigInt',
interface: 'integer', interface: 'integer',
description: null,
collectionName: 't_ylz5vtxncxq',
parentKey: null,
reverseKey: null,
isForeignKey: true,
uiSchema: {
type: 'number',
title: 'f_lkqy3eh4ag7',
'x-component': 'InputNumber',
'x-read-pretty': true,
},
}, },
{ {
key: 'h11dyzaed9u',
name: 'f_rathx54cqpy', name: 'f_rathx54cqpy',
type: 'bigInt',
interface: 'integer', interface: 'integer',
description: null,
collectionName: 't_ylz5vtxncxq',
parentKey: null,
reverseKey: null,
isForeignKey: true,
uiSchema: {
type: 'number',
title: 'f_rathx54cqpy',
'x-component': 'InputNumber',
'x-read-pretty': true,
},
}, },
{ {
key: '1oxxnl3fpnn',
name: 'createdAt',
type: 'date',
interface: 'createdAt',
description: null,
collectionName: 't_ylz5vtxncxq',
parentKey: null,
reverseKey: null,
field: 'createdAt',
uiSchema: {
type: 'datetime',
title: '{{t("Created at")}}',
'x-component': 'DatePicker',
'x-component-props': {},
'x-read-pretty': true,
},
},
{
key: 'r3fbal67uj7',
name: 'createdBy',
type: 'belongsTo',
interface: 'createdBy',
description: null,
collectionName: 't_ylz5vtxncxq',
parentKey: null,
reverseKey: null,
target: 'users',
foreignKey: 'createdById',
uiSchema: {
type: 'object',
title: '{{t("Created by")}}',
'x-component': 'AssociationField',
'x-component-props': {
fieldNames: {
value: 'id',
label: 'nickname',
},
},
'x-read-pretty': true,
},
targetKey: 'id',
},
{
key: 'fx55l7mh3it',
name: 'updatedAt',
type: 'date',
interface: 'updatedAt',
description: null,
collectionName: 't_ylz5vtxncxq',
parentKey: null,
reverseKey: null,
field: 'updatedAt',
uiSchema: {
type: 'string',
title: '{{t("Last updated at")}}',
'x-component': 'DatePicker',
'x-component-props': {},
'x-read-pretty': true,
},
},
{
key: 'j7gjg9nql34',
name: 'updatedBy',
type: 'belongsTo',
interface: 'updatedBy',
description: null,
collectionName: 't_ylz5vtxncxq',
parentKey: null,
reverseKey: null,
target: 'users',
foreignKey: 'updatedById',
uiSchema: {
type: 'object',
title: '{{t("Last updated by")}}',
'x-component': 'AssociationField',
'x-component-props': {
fieldNames: {
value: 'id',
label: 'nickname',
},
},
'x-read-pretty': true,
},
targetKey: 'id',
},
{
key: '8lnta543skc',
name: 'f_nr8xi7ezw5t', name: 'f_nr8xi7ezw5t',
type: 'string',
interface: 'select', interface: 'select',
description: null,
collectionName: 't_ylz5vtxncxq',
parentKey: null,
reverseKey: null,
uiSchema: { uiSchema: {
enum: [ enum: [
{ {
@ -670,16 +529,9 @@ const config = {
}, },
}, },
{ {
key: '7emqqfzq3c3',
name: 'f_q32e4ieq49n', name: 'f_q32e4ieq49n',
type: 'hasMany',
interface: 'o2m', interface: 'o2m',
description: null,
collectionName: 't_ylz5vtxncxq',
parentKey: null,
reverseKey: null,
foreignKey: 'f_rathx54cqpy', foreignKey: 'f_rathx54cqpy',
onDelete: 'SET NULL',
uiSchema: { uiSchema: {
'x-component': 'AssociationField', 'x-component': 'AssociationField',
'x-component-props': { 'x-component-props': {
@ -692,30 +544,22 @@ const config = {
title: 'One to many', title: 'One to many',
}, },
target: 't_ylz5vtxncxq', target: 't_ylz5vtxncxq',
targetKey: 'id',
sourceKey: 'id',
}, },
], ],
category: [],
logging: true,
autoGenId: true,
createdBy: true,
updatedBy: true,
createdAt: true,
updatedAt: true,
sortable: true,
template: 'general',
view: false,
}, },
], ],
}; };
// fix https://nocobase.height.app/T-2174 // fix https://nocobase.height.app/T-2174
test('BUG: should show default value option', async ({ page, mockPage }) => { test.skip('BUG: should show default value option', async ({ page, mockPage, mockRecord }) => {
await mockPage(config).goto(); const nocoPage = await mockPage(config).waitForInit();
await mockRecord('t_ylz5vtxncxq');
await nocoPage.goto();
await page.getByLabel('action-Action.Link-View-view-t_ylz5vtxncxq-table-0').click(); await page.getByLabel('action-Action.Link-View-view-t_ylz5vtxncxq-table-0').click();
await page.getByText('Single select:').hover(); await page
.getByLabel('block-item-CollectionField-t_ylz5vtxncxq-form-t_ylz5vtxncxq.f_nr8xi7ezw5t-Single select')
.hover();
await page await page
.getByLabel('designer-schema-settings-CollectionField-FormItem.Designer-t_ylz5vtxncxq-t_ylz5vtxncxq.f_nr8xi7ezw5t') .getByLabel('designer-schema-settings-CollectionField-FormItem.Designer-t_ylz5vtxncxq-t_ylz5vtxncxq.f_nr8xi7ezw5t')
.hover(); .hover();

View File

@ -198,151 +198,24 @@ const config = {
}, },
collections: [ collections: [
{ {
key: '2msxqih7erw',
name: 't_fhdhd0nk7b9', name: 't_fhdhd0nk7b9',
title: 'test', title: 'test',
inherit: false,
hidden: false,
description: null,
fields: [ fields: [
{ {
key: 'gdzq595upa9',
name: 'id',
type: 'bigInt',
interface: 'id',
description: null,
collectionName: 't_fhdhd0nk7b9',
parentKey: null,
reverseKey: null,
autoIncrement: true,
primaryKey: true,
allowNull: false,
uiSchema: {
type: 'number',
title: '{{t("ID")}}',
'x-component': 'InputNumber',
'x-read-pretty': true,
},
},
{
key: '29a0p3so5dm',
name: 'createdAt',
type: 'date',
interface: 'createdAt',
description: null,
collectionName: 't_fhdhd0nk7b9',
parentKey: null,
reverseKey: null,
field: 'createdAt',
uiSchema: {
type: 'datetime',
title: '{{t("Created at")}}',
'x-component': 'DatePicker',
'x-component-props': {},
'x-read-pretty': true,
},
},
{
key: 'd3v2o9bozd8',
name: 'createdBy',
type: 'belongsTo',
interface: 'createdBy',
description: null,
collectionName: 't_fhdhd0nk7b9',
parentKey: null,
reverseKey: null,
target: 'users',
foreignKey: 'createdById',
uiSchema: {
type: 'object',
title: '{{t("Created by")}}',
'x-component': 'AssociationField',
'x-component-props': {
fieldNames: {
value: 'id',
label: 'nickname',
},
},
'x-read-pretty': true,
},
targetKey: 'id',
},
{
key: '9b2y04n3eiw',
name: 'updatedAt',
type: 'date',
interface: 'updatedAt',
description: null,
collectionName: 't_fhdhd0nk7b9',
parentKey: null,
reverseKey: null,
field: 'updatedAt',
uiSchema: {
type: 'string',
title: '{{t("Last updated at")}}',
'x-component': 'DatePicker',
'x-component-props': {},
'x-read-pretty': true,
},
},
{
key: 'o8jej996mnu',
name: 'updatedBy',
type: 'belongsTo',
interface: 'updatedBy',
description: null,
collectionName: 't_fhdhd0nk7b9',
parentKey: null,
reverseKey: null,
target: 'users',
foreignKey: 'updatedById',
uiSchema: {
type: 'object',
title: '{{t("Last updated by")}}',
'x-component': 'AssociationField',
'x-component-props': {
fieldNames: {
value: 'id',
label: 'nickname',
},
},
'x-read-pretty': true,
},
targetKey: 'id',
},
{
key: '37cbs72sgdn',
name: 'f_vbrlno0zej9', name: 'f_vbrlno0zej9',
type: 'string',
interface: 'input', interface: 'input',
description: null,
collectionName: 't_fhdhd0nk7b9',
parentKey: null,
reverseKey: null,
uiSchema: {
type: 'string',
'x-component': 'Input',
title: 'name',
},
}, },
], ],
category: [],
logging: true,
autoGenId: true,
createdBy: true,
updatedBy: true,
createdAt: true,
updatedAt: true,
sortable: true,
template: 'general',
view: false,
}, },
], ],
}; };
test('check table row', async ({ page, mockPage }) => { test('check table row', async ({ page, mockPage, mockRecords }) => {
await mockPage(config).goto(); const nocoPage = await mockPage(config).waitForInit();
await expect(page.getByText('cur vulpes suppellex')).toBeVisible(); const records = await mockRecords('t_fhdhd0nk7b9', 3);
await nocoPage.goto();
await expect(page.getByText(records[0].f_vbrlno0zej9)).toBeVisible();
await page.getByLabel('table-index-1').hover(); await page.getByLabel('table-index-1').hover();
await page.getByRole('checkbox', { name: 'checkbox' }).click(); await page.getByRole('checkbox', { name: 'checkbox' }).click();
@ -352,8 +225,8 @@ test('check table row', async ({ page, mockPage }) => {
await expect(page.getByText('Are you sure you want to delete it?')).toBeVisible(); await expect(page.getByText('Are you sure you want to delete it?')).toBeVisible();
// 点击确认 // 点击确认
await page.getByText('ok').click(); await page.getByRole('button', { name: 'OK', exact: true }).click();
// 确认内容已被删除 // 确认内容已被删除
await expect(page.getByText('cur vulpes suppellex')).not.toBeVisible(); await expect(page.getByText(records[0].f_vbrlno0zej9)).not.toBeVisible();
}); });

View File

@ -138,7 +138,7 @@ test.describe('add field & remove field in block', () => {
}); });
test.describe('drag field in block', () => { test.describe('drag field in block', () => {
test('drag field for layout', async ({ page, mockPage }) => { test.skip('drag field for layout', async ({ page, mockPage }) => {
await mockPage({ pageSchema: formPageSchema }).goto(); await mockPage({ pageSchema: formPageSchema }).goto();
await page.getByLabel('schema-initializer-Grid-FormItemInitializers-users').click(); await page.getByLabel('schema-initializer-Grid-FormItemInitializers-users').click();
await page.getByLabel('Display collection fields-Nickname').click(); await page.getByLabel('Display collection fields-Nickname').click();

View File

@ -3,147 +3,15 @@ import { expect, test } from '@nocobase/test/client';
const phonePageConfig = { const phonePageConfig = {
collections: [ collections: [
{ {
key: '94kecytzenp',
name: 't_x3mxc1ymorw', name: 't_x3mxc1ymorw',
title: 'faker-testing', title: 'mock-testing',
inherit: false,
hidden: false,
description: null,
fields: [ fields: [
{ {
key: 'cgzlv8nu6fr', name: 'email',
name: 'id', title: 'Email',
type: 'bigInt', interface: 'email',
interface: 'id',
description: null,
collectionName: 't_x3mxc1ymorw',
parentKey: null,
reverseKey: null,
autoIncrement: true,
primaryKey: true,
allowNull: false,
uiSchema: {
type: 'number',
title: '{{t("ID")}}',
'x-component': 'InputNumber',
'x-read-pretty': true,
},
},
{
key: 'sd7xf79138a',
name: 'createdAt',
type: 'date',
interface: 'createdAt',
description: null,
collectionName: 't_x3mxc1ymorw',
parentKey: null,
reverseKey: null,
field: 'createdAt',
uiSchema: {
type: 'datetime',
title: '{{t("Created at")}}',
'x-component': 'DatePicker',
'x-component-props': {},
'x-read-pretty': true,
},
},
{
key: 'z063hvkfdtf',
name: 'createdBy',
type: 'belongsTo',
interface: 'createdBy',
description: null,
collectionName: 't_x3mxc1ymorw',
parentKey: null,
reverseKey: null,
target: 'users',
foreignKey: 'createdById',
uiSchema: {
type: 'object',
title: '{{t("Created by")}}',
'x-component': 'AssociationField',
'x-component-props': {
fieldNames: {
value: 'id',
label: 'nickname',
},
},
'x-read-pretty': true,
},
targetKey: 'id',
},
{
key: 'wlnvpjkuv3i',
name: 'updatedAt',
type: 'date',
interface: 'updatedAt',
description: null,
collectionName: 't_x3mxc1ymorw',
parentKey: null,
reverseKey: null,
field: 'updatedAt',
uiSchema: {
type: 'string',
title: '{{t("Last updated at")}}',
'x-component': 'DatePicker',
'x-component-props': {},
'x-read-pretty': true,
},
},
{
key: 'rxyq48pu0kd',
name: 'updatedBy',
type: 'belongsTo',
interface: 'updatedBy',
description: null,
collectionName: 't_x3mxc1ymorw',
parentKey: null,
reverseKey: null,
target: 'users',
foreignKey: 'updatedById',
uiSchema: {
type: 'object',
title: '{{t("Last updated by")}}',
'x-component': 'AssociationField',
'x-component-props': {
fieldNames: {
value: 'id',
label: 'nickname',
},
},
'x-read-pretty': true,
},
targetKey: 'id',
},
{
key: '3b24xiumcck',
name: 'f_fyjoexeqvuh',
type: 'string',
interface: 'phone',
description: null,
collectionName: 't_x3mxc1ymorw',
parentKey: null,
reverseKey: null,
uiSchema: {
type: 'string',
'x-component': 'Input',
'x-component-props': {
type: 'tel',
},
title: 'Phone',
},
}, },
], ],
category: [],
logging: true,
autoGenId: true,
createdBy: true,
updatedBy: true,
createdAt: true,
updatedAt: true,
sortable: true,
template: 'general',
view: false,
}, },
], ],
pageSchema: { pageSchema: {
@ -151,6 +19,7 @@ const phonePageConfig = {
version: '2.0', version: '2.0',
type: 'void', type: 'void',
'x-component': 'Page', 'x-component': 'Page',
'x-index': 1,
properties: { properties: {
zyfy6q68u10: { zyfy6q68u10: {
_isJSONSchemaObject: true, _isJSONSchemaObject: true,
@ -158,20 +27,21 @@ const phonePageConfig = {
type: 'void', type: 'void',
'x-component': 'Grid', 'x-component': 'Grid',
'x-initializer': 'BlockInitializers', 'x-initializer': 'BlockInitializers',
'x-index': 1,
properties: { properties: {
sfe29sssqks: { nkbrwj149hw: {
_isJSONSchemaObject: true, _isJSONSchemaObject: true,
version: '2.0', version: '2.0',
type: 'void', type: 'void',
'x-component': 'Grid.Row', 'x-component': 'Grid.Row',
properties: { properties: {
wr0q46863ri: { t9wwr80ymdc: {
_isJSONSchemaObject: true, _isJSONSchemaObject: true,
version: '2.0', version: '2.0',
type: 'void', type: 'void',
'x-component': 'Grid.Col', 'x-component': 'Grid.Col',
properties: { properties: {
'996h7puslon': { b0iohq28s9u: {
_isJSONSchemaObject: true, _isJSONSchemaObject: true,
version: '2.0', version: '2.0',
type: 'void', type: 'void',
@ -204,11 +74,11 @@ const phonePageConfig = {
marginBottom: 'var(--nb-spacing)', marginBottom: 'var(--nb-spacing)',
}, },
}, },
'x-uid': 'to6wvr2ymud', 'x-uid': '0wksx4dtgum',
'x-async': false, 'x-async': false,
'x-index': 1, 'x-index': 1,
}, },
fmioqg3ac22: { zvooo4ygn4x: {
_isJSONSchemaObject: true, _isJSONSchemaObject: true,
version: '2.0', version: '2.0',
type: 'array', type: 'array',
@ -242,16 +112,16 @@ const phonePageConfig = {
'x-component-props': { 'x-component-props': {
split: '|', split: '|',
}, },
'x-uid': '7ueb2r7aiq2', 'x-uid': '3gombpceyjl',
'x-async': false, 'x-async': false,
'x-index': 1, 'x-index': 1,
}, },
}, },
'x-uid': 'q6tqbavh1hz', 'x-uid': 'vcjbrby0i27',
'x-async': false, 'x-async': false,
'x-index': 1, 'x-index': 1,
}, },
'7x5qve01k29': { olrr4chfvfh: {
_isJSONSchemaObject: true, _isJSONSchemaObject: true,
version: '2.0', version: '2.0',
type: 'void', type: 'void',
@ -259,12 +129,14 @@ const phonePageConfig = {
'x-designer': 'TableV2.Column.Designer', 'x-designer': 'TableV2.Column.Designer',
'x-component': 'TableV2.Column', 'x-component': 'TableV2.Column',
properties: { properties: {
f_fyjoexeqvuh: { email: {
_isJSONSchemaObject: true, _isJSONSchemaObject: true,
version: '2.0', version: '2.0',
'x-collection-field': 't_x3mxc1ymorw.f_fyjoexeqvuh', 'x-collection-field': 't_x3mxc1ymorw.email',
'x-component': 'CollectionField', 'x-component': 'CollectionField',
'x-component-props': {}, 'x-component-props': {
ellipsis: true,
},
'x-read-pretty': true, 'x-read-pretty': true,
'x-decorator': null, 'x-decorator': null,
'x-decorator-props': { 'x-decorator-props': {
@ -272,53 +144,53 @@ const phonePageConfig = {
display: 'none', display: 'none',
}, },
}, },
'x-uid': 'bmewjcb9996', 'x-uid': 'sqogd3z6o95',
'x-async': false, 'x-async': false,
'x-index': 1, 'x-index': 1,
}, },
}, },
'x-uid': '6vqo25ezxbr', 'x-uid': 'vcve0j78imw',
'x-async': false, 'x-async': false,
'x-index': 2, 'x-index': 2,
}, },
}, },
'x-uid': 'esirxkr0lca', 'x-uid': 'benml5cswa0',
'x-async': false, 'x-async': false,
'x-index': 2, 'x-index': 2,
}, },
}, },
'x-uid': 'zcbhgqtrof5', 'x-uid': 'v0bydleh1ni',
'x-async': false, 'x-async': false,
'x-index': 1, 'x-index': 1,
}, },
}, },
'x-uid': 'tsma8ix1lun', 'x-uid': 'rmplhh05qpr',
'x-async': false, 'x-async': false,
'x-index': 1, 'x-index': 1,
}, },
}, },
'x-uid': 'q8bpsoqjz1b', 'x-uid': 'szfwommojdg',
'x-async': false, 'x-async': false,
'x-index': 1, 'x-index': 1,
}, },
}, },
'x-uid': 'edhta7p0qtf', 'x-uid': 'k8t4d8im9lx',
'x-async': false, 'x-async': false,
'x-index': 1,
}, },
}, },
'x-uid': '1o0p25d72br', 'x-uid': 't6726o68agh',
'x-async': true, 'x-async': true,
'x-index': 1,
}, },
}; };
test.describe('faker', () => { test.describe('mock record', () => {
test('phone', async ({ page, mockPage }) => { test('email field', async ({ page, mockPage, mockRecords }) => {
await mockPage(phonePageConfig).goto(); const nocoPage = await mockPage(phonePageConfig).waitForInit();
const records = await mockRecords<{ email: string }>('t_x3mxc1ymorw', 3);
await nocoPage.goto();
await expect(page.getByRole('cell', { name: '1-979-213-9120 x313' })).toBeVisible(); await expect(page.getByRole('cell', { name: records[0].email })).toBeVisible();
await expect(page.getByRole('cell', { name: '(739) 684-3652 x482' })).toBeVisible(); await expect(page.getByRole('cell', { name: records[1].email })).toBeVisible();
await expect(page.getByRole('cell', { name: '669-545-4191' })).toBeVisible(); await expect(page.getByRole('cell', { name: records[2].email })).toBeVisible();
}); });
}); });

View File

@ -6,8 +6,8 @@ import _ from 'lodash';
export * from '@playwright/test'; export * from '@playwright/test';
interface CollectionSetting { interface CollectionSetting {
title: string;
name: string; name: string;
title?: string;
/** /**
* @default 'general' * @default 'general'
*/ */
@ -55,10 +55,10 @@ interface CollectionSetting {
description?: string; description?: string;
view?: boolean; view?: boolean;
key?: string; key?: string;
fields: Array<{ fields?: Array<{
type: string;
interface: string; interface: string;
name: string; type?: string;
name?: string;
unique?: boolean; unique?: boolean;
uiSchema?: { uiSchema?: {
type?: string; type?: string;
@ -121,13 +121,13 @@ class NocoPage {
private url: string; private url: string;
private uid: string; private uid: string;
private collectionsName: string[]; private collectionsName: string[];
private waitForInit: Promise<void>; private _waitForInit: Promise<void>;
constructor( constructor(
private page: Page, private page: Page,
private options?: PageConfig, private options?: PageConfig,
) { ) {
this.waitForInit = this.init(); this._waitForInit = this.init();
} }
async init() { async init() {
@ -136,11 +136,6 @@ class NocoPage {
this.collectionsName = collections.map((item) => item.name); this.collectionsName = collections.map((item) => item.name);
await createCollections(collections); await createCollections(collections);
// 默认为每个 collection 生成 3 条数据
await createFakerData(collections);
await createFakerData(collections);
await createFakerData(collections);
} }
this.uid = await createPage(this.page, { this.uid = await createPage(this.page, {
@ -151,11 +146,16 @@ class NocoPage {
} }
async goto() { async goto() {
await this.waitForInit; await this._waitForInit;
await this.page.goto(this.url); await this.page.goto(this.url);
await enableToConfig(this.page); await enableToConfig(this.page);
} }
async waitForInit(this: NocoPage) {
await this._waitForInit;
return this;
}
async destroy() { async destroy() {
if (this.uid) { if (this.uid) {
await deletePage(this.uid); await deletePage(this.uid);
@ -170,6 +170,10 @@ class NocoPage {
const _test = base.extend<{ const _test = base.extend<{
mockPage: (config?: PageConfig) => NocoPage; mockPage: (config?: PageConfig) => NocoPage;
mockCollections: <T = any>(collectionSettings: CollectionSetting[]) => Promise<T>;
mockCollection: <T = any>(collectionSetting: CollectionSetting) => Promise<T>;
mockRecord: <T = any>(collectionName: string, data?: any) => Promise<T>;
mockRecords: <T = any>(collectionName: string, count?: number, data?: any) => Promise<T[]>;
createCollections: (collectionSettings: CollectionSetting | CollectionSetting[]) => Promise<void>; createCollections: (collectionSettings: CollectionSetting | CollectionSetting[]) => Promise<void>;
}>({ }>({
mockPage: async ({ page }, use) => { mockPage: async ({ page }, use) => {
@ -207,6 +211,51 @@ const _test = base.extend<{
await deleteCollections(collectionsName); await deleteCollections(collectionsName);
} }
}, },
mockCollections: async ({ page }, use) => {
let collectionsName = [];
const mockCollections = async (collectionSettings: CollectionSetting[]) => {
collectionSettings = omitSomeFields(collectionSettings);
collectionsName = collectionSettings.map((item) => item.name);
return createCollections(collectionSettings);
};
await use(mockCollections);
if (collectionsName.length) {
await deleteCollections(collectionsName);
}
},
mockCollection: async ({ page }, use) => {
let collectionsName = [];
const mockCollection = async (collectionSetting: CollectionSetting) => {
const collectionSettings = omitSomeFields([collectionSetting]);
collectionsName = collectionSettings.map((item) => item.name);
return createCollections(collectionSettings);
};
await use(mockCollection);
if (collectionsName.length) {
await deleteCollections(collectionsName);
}
},
mockRecords: async ({ page }, use) => {
const mockRecords = async (collectionName: string, count = 3, data?: any) => {
return createRandomData(collectionName, count, data);
};
await use(mockRecords);
},
mockRecord: async ({ page }, use) => {
const mockRecord = async (collectionName: string, data?: any) => {
const result = await createRandomData(collectionName, 1, data);
return result[0];
};
await use(mockRecord);
},
}); });
export const test = Object.assign(_test, { export const test = Object.assign(_test, {
@ -394,6 +443,8 @@ const createCollections = async (collectionSettings: CollectionSetting | Collect
if (!result.ok()) { if (!result.ok()) {
throw new Error(await result.text()); throw new Error(await result.text());
} }
return (await result.json()).data;
}; };
/** /**
@ -429,7 +480,6 @@ const generateFakerData = (collectionSetting: CollectionSetting) => {
if (basicInterfaceToData[field.interface]) { if (basicInterfaceToData[field.interface]) {
result[field.name] = basicInterfaceToData[field.interface](); result[field.name] = basicInterfaceToData[field.interface]();
return;
} }
}); });
@ -460,12 +510,40 @@ const createFakerData = async (collectionSettings: CollectionSetting[]) => {
} }
}; };
const createRandomData = async (collectionName: string, count = 10, data?: any) => {
const api = await request.newContext({
storageState: require.resolve('../../../../../playwright/.auth/admin.json'),
});
const state = await api.storageState();
const headers = getHeaders(state);
const result = await api.post(`/api/${collectionName}:mock?count=${count}`, {
headers,
data,
});
if (!result.ok()) {
throw new Error(await result.text());
}
return (await result.json()).data;
};
/** /**
* 使 * 使
*/ */
export async function enableToConfig(page: Page) { export async function enableToConfig(page: Page) {
if (!(await page.getByRole('button', { name: 'plus Add menu item' }).isVisible())) { try {
await page.getByRole('button', { name: 'highlight' }).click(); // 根据是否有 style 判断是否已经是可配置态(因为配置状态的按钮样式是通过 style 属性设置的)
const style = await page.getByTestId('ui-editor-button').getAttribute('style', {
timeout: 2000,
});
if (!style) {
await page.getByTestId('ui-editor-button').click();
}
} catch (e) {
// ignore
} }
} }

View File

@ -21,6 +21,8 @@ export default defineConfig({
// workers: process.env.CI ? 1 : undefined, // workers: process.env.CI ? 1 : undefined,
workers: 1, workers: 1,
maxFailures: 1,
// Reporter to use // Reporter to use
reporter: process.env.PLAYWRIGHT_SKIP_REPORTER reporter: process.env.PLAYWRIGHT_SKIP_REPORTER
? undefined ? undefined