refactor(e2e): support batch creation of collections (#2778)

* chore: types

* refactor: optimize create collections

* chore: make throw error

* chore: export createCollections
This commit is contained in:
被雨水过滤的空气-Rain 2023-10-10 07:46:24 +08:00 committed by GitHub
parent bebe1d15e5
commit f85fb6d7ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 48 additions and 53 deletions

View File

@ -279,7 +279,8 @@ const config = {
}, },
}; };
test('BUG: https://nocobase.height.app/T-2165', async ({ page, mockPage }) => { // fix https://nocobase.height.app/T-2165
test('BUG: variable labels should be displayed normally', async ({ page, mockPage }) => {
await mockPage(config).goto(); await mockPage(config).goto();
await page.getByTestId('users-resource').hover(); await page.getByTestId('users-resource').hover();

View File

@ -317,8 +317,8 @@ test.describe('faker', () => {
test('phone', async ({ page, mockPage }) => { test('phone', async ({ page, mockPage }) => {
await mockPage(phonePageConfig).goto(); await mockPage(phonePageConfig).goto();
await expect(page.getByRole('cell', { name: '14979013912' })).toBeVisible(); await expect(page.getByRole('cell', { name: '1-979-213-9120 x313' })).toBeVisible();
await expect(page.getByRole('cell', { name: '10313363958' })).toBeVisible(); await expect(page.getByRole('cell', { name: '(739) 684-3652 x482' })).toBeVisible();
await expect(page.getByRole('cell', { name: '14365248205' })).toBeVisible(); await expect(page.getByRole('cell', { name: '669-545-4191' })).toBeVisible();
}); });
}); });

View File

@ -45,7 +45,7 @@ interface CollectionSetting {
* Records can be sorted * Records can be sorted
* @default true * @default true
*/ */
sortable?: boolean; sortable?: boolean | string;
/** /**
* @default false * @default false
*/ */
@ -60,13 +60,13 @@ interface CollectionSetting {
interface: string; interface: string;
name: string; name: string;
unique?: boolean; unique?: boolean;
uiSchema: { uiSchema?: {
type?: string; type?: string;
title?: string; title?: string;
required?: boolean; required?: boolean;
'x-component'?: string; 'x-component'?: string;
'x-read-pretty'?: boolean; 'x-read-pretty'?: boolean;
'x-validator'?: string; 'x-validator'?: any;
'x-component-props'?: Record<string, any>; 'x-component-props'?: Record<string, any>;
[key: string]: any; [key: string]: any;
}; };
@ -132,7 +132,7 @@ class NocoPage {
const collections: any = deleteKeyOfCollection(this.options.collections); const collections: any = deleteKeyOfCollection(this.options.collections);
this.collectionsName = collections.map((item) => item.name); this.collectionsName = collections.map((item) => item.name);
await createCollections(this.page, collections); await createCollections(collections);
// 默认为每个 collection 生成 3 条数据 // 默认为每个 collection 生成 3 条数据
await createFakerData(collections); await createFakerData(collections);
@ -317,37 +317,6 @@ const deletePage = async (pageUid: string) => {
} }
}; };
const createCollection = async (collectionSetting: CollectionSetting) => {
const api = await request.newContext({
storageState: require.resolve('../../../../../playwright/.auth/admin.json'),
});
const state = await api.storageState();
const token = getStorageItem('NOCOBASE_TOKEN', state);
const defaultCollectionSetting: Partial<CollectionSetting> = {
template: 'general',
logging: true,
autoGenId: true,
createdBy: true,
updatedBy: true,
createdAt: true,
updatedAt: true,
sortable: true,
view: false,
};
const result = await api.post(`/api/collections:create`, {
headers: {
Authorization: `Bearer ${token}`,
},
data: Object.assign(defaultCollectionSetting, collectionSetting),
});
if (!result.ok()) {
throw new Error(await result.text());
}
};
const deleteCollections = async (collectionNames: string[]) => { const deleteCollections = async (collectionNames: string[]) => {
const api = await request.newContext({ const api = await request.newContext({
storageState: require.resolve('../../../../../playwright/.auth/admin.json'), storageState: require.resolve('../../../../../playwright/.auth/admin.json'),
@ -388,13 +357,38 @@ const deleteKeyOfCollection = (collectionSettings: CollectionSetting[]) => {
* @param collectionSettings * @param collectionSettings
* @returns * @returns
*/ */
const createCollections = async (page: Page, collectionSettings: CollectionSetting[]) => { export const createCollections = async (collectionSettings: CollectionSetting | CollectionSetting[]) => {
// TODO: 这里如果改成并发创建的话性能会更好,但是会出现只创建一个 collection 的情况,暂时不知道原因 const api = await request.newContext({
for (const item of collectionSettings) { storageState: require.resolve('../../../../../playwright/.auth/admin.json'),
await createCollection(item); });
const state = await api.storageState();
const token = getStorageItem('NOCOBASE_TOKEN', state);
// const defaultCollectionSetting: Partial<CollectionSetting> = {
// template: 'general',
// logging: true,
// autoGenId: true,
// createdBy: true,
// updatedBy: true,
// createdAt: true,
// updatedAt: true,
// sortable: true,
// view: false,
// };
collectionSettings = Array.isArray(collectionSettings) ? collectionSettings : [collectionSettings];
const result = await api.post(`/api/collections:create`, {
headers: {
Authorization: `Bearer ${token}`,
},
// data: collectionSettings.map((item) => Object.assign(defaultCollectionSetting, item)),
data: collectionSettings.filter((item) => !['users', 'roles'].includes(item.name)),
});
if (!result.ok()) {
throw new Error(await result.text());
} }
// @ts-ignore
page._collectionNames = collectionSettings.map((item) => item.name);
}; };
/** /**
@ -409,12 +403,12 @@ const generateFakerData = (collectionSetting: CollectionSetting) => {
input: () => faker.lorem.words(), input: () => faker.lorem.words(),
textarea: () => faker.lorem.paragraph(), textarea: () => faker.lorem.paragraph(),
richText: () => faker.lorem.paragraph(), richText: () => faker.lorem.paragraph(),
phone: () => faker.phone.number('1##########'), phone: () => faker.phone.number(),
email: () => faker.internet.email(), email: () => faker.internet.email(),
url: () => faker.internet.url(), url: () => faker.internet.url(),
integer: () => faker.datatype.number(), integer: () => faker.number.int(),
number: () => faker.datatype.number(), number: () => faker.number.int(),
percent: () => faker.datatype.float(), percent: () => faker.number.float(),
password: () => faker.internet.password(), password: () => faker.internet.password(),
color: () => faker.internet.color(), color: () => faker.internet.color(),
icon: () => 'checkcircleoutlined', icon: () => 'checkcircleoutlined',

View File

@ -1,7 +1,7 @@
import { defineConfig, devices } from '@playwright/test'; import { defineConfig, devices } from '@playwright/test';
export default defineConfig({ export default defineConfig({
timeout: 20 * 1000, timeout: 30 * 1000,
// Look for test files in the "tests" directory, relative to this configuration file. // Look for test files in the "tests" directory, relative to this configuration file.
testDir: 'packages', testDir: 'packages',

View File

@ -8,7 +8,7 @@ const run = async () => {
await awaitForNocoBase(); await awaitForNocoBase();
console.log('Start running tests...'); console.log('Start running tests...');
runCommand('npx', ['playwright', 'test', ...process.argv.slice(2)]); await runCommand('npx', ['playwright', 'test', ...process.argv.slice(2)]);
kill?.('SIGKILL'); kill?.('SIGKILL');
}; };

View File

@ -44,7 +44,7 @@ function checkPort(port) {
/** /**
* *
*/ */
const checkServer = async (duration = 1000, max = 30) => { const checkServer = async (duration = 1000, max = 60) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let count = 0; let count = 0;
const timer = setInterval(async () => { const timer = setInterval(async () => {
@ -76,7 +76,7 @@ const checkServer = async (duration = 1000, max = 30) => {
* UI * UI
* @param duration * @param duration
*/ */
const checkUI = async (duration = 1000, max = 30) => { const checkUI = async (duration = 1000, max = 60) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let count = 0; let count = 0;
const timer = setInterval(async () => { const timer = setInterval(async () => {