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:
parent
36043be130
commit
3c98966169
@ -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();
|
||||||
|
@ -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();
|
||||||
});
|
});
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
});
|
});
|
||||||
});
|
});
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user