mirror of
https://github.com/nocobase/nocobase
synced 2024-11-15 04:15:19 +00:00
refactor: make testing more stable
This commit is contained in:
parent
767b81c65d
commit
3c7b3f3caf
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { render, screen, userEvent, waitFor } from 'testUtils';
|
||||
import { render, screen, sleep, userEvent, waitFor } from 'testUtils';
|
||||
import App1 from '../demos/demo1';
|
||||
import App2 from '../demos/demo2';
|
||||
import App3 from '../demos/demo3';
|
||||
@ -13,6 +13,9 @@ import App9 from '../demos/demo9';
|
||||
describe('DatePicker', () => {
|
||||
it('basic', async () => {
|
||||
const { container, getByText } = render(<App1 />);
|
||||
|
||||
await sleep();
|
||||
|
||||
const picker = container.querySelector('.ant-picker') as HTMLElement;
|
||||
const input = container.querySelector('input') as HTMLElement;
|
||||
|
||||
@ -35,6 +38,9 @@ describe('DatePicker', () => {
|
||||
|
||||
it('GMT', async () => {
|
||||
const { container, getByText } = render(<App2 />);
|
||||
|
||||
await sleep();
|
||||
|
||||
const picker = container.querySelector('.ant-picker') as HTMLElement;
|
||||
const input = container.querySelector('input') as HTMLElement;
|
||||
|
||||
@ -53,6 +59,9 @@ describe('DatePicker', () => {
|
||||
|
||||
it('non-UTC', async () => {
|
||||
const { container } = render(<App3 />);
|
||||
|
||||
await sleep();
|
||||
|
||||
const picker = container.querySelector('.ant-picker') as HTMLElement;
|
||||
const input = container.querySelector('input') as HTMLElement;
|
||||
|
||||
@ -74,6 +83,9 @@ describe('DatePicker', () => {
|
||||
describe('RangePicker', () => {
|
||||
it('GMT', async () => {
|
||||
const { container, getByPlaceholderText } = render(<App4 />);
|
||||
|
||||
await sleep();
|
||||
|
||||
const picker = container.querySelector('.ant-picker') as HTMLElement;
|
||||
const startInput = getByPlaceholderText('Start date');
|
||||
const endInput = getByPlaceholderText('End date');
|
||||
@ -92,6 +104,9 @@ describe('RangePicker', () => {
|
||||
|
||||
it('non-GMT', async () => {
|
||||
const { container, getByPlaceholderText } = render(<App5 />);
|
||||
|
||||
await sleep();
|
||||
|
||||
const picker = container.querySelector('.ant-picker') as HTMLElement;
|
||||
const startInput = getByPlaceholderText('Start date');
|
||||
const endInput = getByPlaceholderText('End date');
|
||||
@ -115,6 +130,9 @@ describe('RangePicker', () => {
|
||||
|
||||
it('non-UTC', async () => {
|
||||
const { container, getByPlaceholderText } = render(<App6 />);
|
||||
|
||||
await sleep();
|
||||
|
||||
const picker = container.querySelector('.ant-picker') as HTMLElement;
|
||||
const startInput = getByPlaceholderText('Start date');
|
||||
const endInput = getByPlaceholderText('End date');
|
||||
@ -133,6 +151,9 @@ describe('RangePicker', () => {
|
||||
|
||||
it('showTime=false,gmt=true,utc=true', async () => {
|
||||
const { container } = render(<App7 />);
|
||||
|
||||
await sleep();
|
||||
|
||||
const picker = container.querySelector('.ant-picker') as HTMLElement;
|
||||
const input = container.querySelector('input') as HTMLElement;
|
||||
|
||||
@ -152,6 +173,9 @@ describe('RangePicker', () => {
|
||||
|
||||
it('showTime=false,gmt=false,utc=true', async () => {
|
||||
const { container } = render(<App8 />);
|
||||
|
||||
await sleep();
|
||||
|
||||
const picker = container.querySelector('.ant-picker') as HTMLElement;
|
||||
const input = container.querySelector('input') as HTMLElement;
|
||||
|
||||
@ -175,6 +199,9 @@ describe('RangePicker', () => {
|
||||
it('showTime=false,gmt=true,utc=true & not input', async () => {
|
||||
const currentDateString = new Date().toISOString().split('T')[0];
|
||||
const { container } = render(<App9 />);
|
||||
|
||||
await sleep();
|
||||
|
||||
const picker = container.querySelector('.ant-picker') as HTMLElement;
|
||||
|
||||
await userEvent.click(picker);
|
||||
|
@ -1,11 +1,13 @@
|
||||
import React from 'react';
|
||||
import { render, screen } from 'testUtils';
|
||||
import { render, screen, waitFor } from 'testUtils';
|
||||
import App1 from '../demos/demo1';
|
||||
|
||||
describe('FormItem', () => {
|
||||
it('should render correctly', () => {
|
||||
it('should render correctly', async () => {
|
||||
render(<App1 />);
|
||||
|
||||
expect(screen.getByText('title')).toBeInTheDocument();
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('title')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,5 +1,18 @@
|
||||
import { FormItem, FormProvider, Input, SchemaComponent } from '@nocobase/client';
|
||||
import {
|
||||
APIClientProvider,
|
||||
CurrentUserProvider,
|
||||
FormItem,
|
||||
FormProvider,
|
||||
Input,
|
||||
SchemaComponent,
|
||||
} from '@nocobase/client';
|
||||
import React from 'react';
|
||||
import { mockAPIClient } from '../../../../test';
|
||||
|
||||
const { apiClient, mockRequest } = mockAPIClient();
|
||||
mockRequest.onGet('/auth:check').reply(() => {
|
||||
return [200, { data: {} }];
|
||||
});
|
||||
|
||||
const schema = {
|
||||
type: 'object',
|
||||
@ -15,8 +28,12 @@ const schema = {
|
||||
|
||||
export default () => {
|
||||
return (
|
||||
<FormProvider>
|
||||
<SchemaComponent components={{ FormItem, Input }} schema={schema} />
|
||||
</FormProvider>
|
||||
<APIClientProvider apiClient={apiClient}>
|
||||
<CurrentUserProvider>
|
||||
<FormProvider>
|
||||
<SchemaComponent components={{ FormItem, Input }} schema={schema} />
|
||||
</FormProvider>
|
||||
</CurrentUserProvider>
|
||||
</APIClientProvider>
|
||||
);
|
||||
};
|
||||
|
@ -8,11 +8,13 @@ describe('FormV2', () => {
|
||||
it('basic', async () => {
|
||||
render(<App1 />);
|
||||
|
||||
const input = document.querySelector('.ant-input') as HTMLInputElement;
|
||||
const submit = screen.getByText('Submit');
|
||||
|
||||
expect(input).toBeInTheDocument();
|
||||
expect(screen.getByText('Nickname')).toBeInTheDocument();
|
||||
let input, submit;
|
||||
await waitFor(() => {
|
||||
input = document.querySelector('.ant-input') as HTMLInputElement;
|
||||
submit = screen.getByText('Submit');
|
||||
expect(input).toBeInTheDocument();
|
||||
expect(screen.queryByText('Nickname')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
await userEvent.type(input, '李四');
|
||||
await userEvent.click(submit);
|
||||
@ -41,8 +43,7 @@ describe('FormV2', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// TODO: 等 @Testing-Library 升级到 14.x
|
||||
it.skip('read pretty', async () => {
|
||||
it('read pretty', async () => {
|
||||
render(<App3 />);
|
||||
|
||||
await waitFor(() => {
|
||||
|
@ -4,6 +4,7 @@ import {
|
||||
Action,
|
||||
CollectionField,
|
||||
CollectionManagerProvider,
|
||||
CurrentUserProvider,
|
||||
FormBlockProvider,
|
||||
FormItem,
|
||||
FormV2,
|
||||
@ -26,6 +27,9 @@ mockRequest.onPost('/users:update').reply((params) => {
|
||||
});
|
||||
return [200, JSON.parse(params.data)];
|
||||
});
|
||||
mockRequest.onGet('/auth:check').reply(() => {
|
||||
return [200, { data: {} }];
|
||||
});
|
||||
|
||||
function useAction() {
|
||||
const ctx = useFormBlockContext();
|
||||
@ -82,11 +86,13 @@ const schema: ISchema = {
|
||||
export default () => {
|
||||
return (
|
||||
<APIClientProvider apiClient={apiClient}>
|
||||
<CollectionManagerProvider collections={collections}>
|
||||
<SchemaComponentProvider components={{ FormBlockProvider, FormV2, FormItem, CollectionField, Action, Input }}>
|
||||
<SchemaComponent schema={schema} />
|
||||
</SchemaComponentProvider>
|
||||
</CollectionManagerProvider>
|
||||
<CurrentUserProvider>
|
||||
<CollectionManagerProvider collections={collections}>
|
||||
<SchemaComponentProvider components={{ FormBlockProvider, FormV2, FormItem, CollectionField, Action, Input }}>
|
||||
<SchemaComponent schema={schema} />
|
||||
</SchemaComponentProvider>
|
||||
</CollectionManagerProvider>
|
||||
</CurrentUserProvider>
|
||||
</APIClientProvider>
|
||||
);
|
||||
};
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
BlockSchemaComponentProvider,
|
||||
CollectionField,
|
||||
CollectionManagerProvider,
|
||||
CurrentUserProvider,
|
||||
FormBlockProvider,
|
||||
FormItem,
|
||||
FormV2,
|
||||
@ -36,6 +37,9 @@ mockRequest.onPost('/users:update').reply((params) => {
|
||||
});
|
||||
return [200, JSON.parse(params.data)];
|
||||
});
|
||||
mockRequest.onGet('/auth:check').reply(() => {
|
||||
return [200, { data: {} }];
|
||||
});
|
||||
|
||||
const useAction = () => {
|
||||
const ctx = useFormBlockContext();
|
||||
@ -107,15 +111,17 @@ const schema: ISchema = {
|
||||
export default () => {
|
||||
return (
|
||||
<APIClientProvider apiClient={apiClient}>
|
||||
<CollectionManagerProvider collections={collections}>
|
||||
<SchemaComponentProvider
|
||||
components={{ FormBlockProvider, FormItem, CollectionField, Input, Action, FormV2, Password }}
|
||||
>
|
||||
<BlockSchemaComponentProvider>
|
||||
<SchemaComponent schema={schema} />
|
||||
</BlockSchemaComponentProvider>
|
||||
</SchemaComponentProvider>
|
||||
</CollectionManagerProvider>
|
||||
<CurrentUserProvider>
|
||||
<CollectionManagerProvider collections={collections}>
|
||||
<SchemaComponentProvider
|
||||
components={{ FormBlockProvider, FormItem, CollectionField, Input, Action, FormV2, Password }}
|
||||
>
|
||||
<BlockSchemaComponentProvider>
|
||||
<SchemaComponent schema={schema} />
|
||||
</BlockSchemaComponentProvider>
|
||||
</SchemaComponentProvider>
|
||||
</CollectionManagerProvider>
|
||||
</CurrentUserProvider>
|
||||
</APIClientProvider>
|
||||
);
|
||||
};
|
||||
|
@ -5,9 +5,11 @@ import {
|
||||
BlockSchemaComponentProvider,
|
||||
CollectionField,
|
||||
CollectionManagerProvider,
|
||||
CurrentUserProvider,
|
||||
FormBlockProvider,
|
||||
FormItem,
|
||||
FormV2,
|
||||
Grid,
|
||||
Input,
|
||||
Password,
|
||||
SchemaComponent,
|
||||
@ -26,6 +28,9 @@ mockRequest.onGet('/users:get').reply(200, {
|
||||
password: '123456',
|
||||
},
|
||||
});
|
||||
mockRequest.onGet('/auth:check').reply(() => {
|
||||
return [200, { data: {} }];
|
||||
});
|
||||
|
||||
const schema: ISchema = {
|
||||
type: 'object',
|
||||
@ -93,15 +98,17 @@ const schema: ISchema = {
|
||||
export default () => {
|
||||
return (
|
||||
<APIClientProvider apiClient={apiClient}>
|
||||
<CollectionManagerProvider collections={collections}>
|
||||
<SchemaComponentProvider
|
||||
components={{ FormBlockProvider, FormItem, CollectionField, Input, Action, FormV2, Password }}
|
||||
>
|
||||
<BlockSchemaComponentProvider>
|
||||
<SchemaComponent schema={schema} />
|
||||
</BlockSchemaComponentProvider>
|
||||
</SchemaComponentProvider>
|
||||
</CollectionManagerProvider>
|
||||
<CurrentUserProvider>
|
||||
<CollectionManagerProvider collections={collections}>
|
||||
<SchemaComponentProvider
|
||||
components={{ FormBlockProvider, FormItem, CollectionField, Input, Action, FormV2, Password, Grid }}
|
||||
>
|
||||
<BlockSchemaComponentProvider>
|
||||
<SchemaComponent schema={schema} />
|
||||
</BlockSchemaComponentProvider>
|
||||
</SchemaComponentProvider>
|
||||
</CollectionManagerProvider>
|
||||
</CurrentUserProvider>
|
||||
</APIClientProvider>
|
||||
);
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { render, screen } from 'testUtils';
|
||||
import { render, screen, waitFor } from 'testUtils';
|
||||
import App1 from '../demos/demo1';
|
||||
import App2 from '../demos/demo2';
|
||||
import App3 from '../demos/demo3';
|
||||
@ -14,12 +14,13 @@ describe('Grid', () => {
|
||||
expect(screen.getByText('Block 1')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('input', () => {
|
||||
it('input', async () => {
|
||||
render(<App2 />);
|
||||
|
||||
const inputs = document.querySelectorAll('.ant-input');
|
||||
|
||||
expect(inputs.length).toBe(3);
|
||||
await waitFor(() => {
|
||||
const inputs = document.querySelectorAll('.ant-input');
|
||||
expect(inputs.length).toBe(3);
|
||||
});
|
||||
});
|
||||
|
||||
it('initializer', () => {
|
||||
|
@ -1,8 +1,24 @@
|
||||
import { ISchema } from '@formily/react';
|
||||
import { uid } from '@formily/shared';
|
||||
import { Form, FormItem, Grid, Input, SchemaComponent, SchemaComponentProvider } from '@nocobase/client';
|
||||
import {
|
||||
APIClientProvider,
|
||||
CurrentUserProvider,
|
||||
Form,
|
||||
FormItem,
|
||||
Grid,
|
||||
Input,
|
||||
SchemaComponent,
|
||||
SchemaComponentProvider,
|
||||
} from '@nocobase/client';
|
||||
import React from 'react';
|
||||
|
||||
import { mockAPIClient } from '../../../../test';
|
||||
|
||||
const { apiClient, mockRequest } = mockAPIClient();
|
||||
mockRequest.onGet('/auth:check').reply(() => {
|
||||
return [200, { data: {} }];
|
||||
});
|
||||
|
||||
const schema: ISchema = {
|
||||
type: 'void',
|
||||
name: 'grid1',
|
||||
@ -54,8 +70,12 @@ const schema: ISchema = {
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<SchemaComponentProvider components={{ Form, Grid, Input, FormItem }}>
|
||||
<SchemaComponent schema={schema} />
|
||||
</SchemaComponentProvider>
|
||||
<APIClientProvider apiClient={apiClient}>
|
||||
<CurrentUserProvider>
|
||||
<SchemaComponentProvider components={{ Form, Grid, Input, FormItem }}>
|
||||
<SchemaComponent schema={schema} />
|
||||
</SchemaComponentProvider>
|
||||
</CurrentUserProvider>
|
||||
</APIClientProvider>
|
||||
);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import {
|
||||
APIClientProvider,
|
||||
BlockSchemaComponentProvider,
|
||||
CollectionManagerProvider,
|
||||
CurrentUserProvider,
|
||||
SchemaComponent,
|
||||
SchemaComponentProvider,
|
||||
} from '@nocobase/client';
|
||||
@ -19,6 +20,9 @@ mockRequest.onGet('/t_j6omof6tza8:list').reply(async (config) => {
|
||||
await sleep(200);
|
||||
return [200, data];
|
||||
});
|
||||
mockRequest.onGet('/auth:check').reply(() => {
|
||||
return [200, { data: {} }];
|
||||
});
|
||||
|
||||
const schema: ISchema = {
|
||||
type: 'object',
|
||||
@ -69,15 +73,17 @@ const schema: ISchema = {
|
||||
export default () => {
|
||||
return (
|
||||
<APIClientProvider apiClient={apiClient}>
|
||||
<SchemaComponentProvider>
|
||||
<CollectionManagerProvider collections={collections}>
|
||||
<AntdSchemaComponentProvider>
|
||||
<BlockSchemaComponentProvider>
|
||||
<SchemaComponent schema={schema} />
|
||||
</BlockSchemaComponentProvider>
|
||||
</AntdSchemaComponentProvider>
|
||||
</CollectionManagerProvider>
|
||||
</SchemaComponentProvider>
|
||||
<CurrentUserProvider>
|
||||
<SchemaComponentProvider>
|
||||
<CollectionManagerProvider collections={collections}>
|
||||
<AntdSchemaComponentProvider>
|
||||
<BlockSchemaComponentProvider>
|
||||
<SchemaComponent schema={schema} />
|
||||
</BlockSchemaComponentProvider>
|
||||
</AntdSchemaComponentProvider>
|
||||
</CollectionManagerProvider>
|
||||
</SchemaComponentProvider>
|
||||
</CurrentUserProvider>
|
||||
</APIClientProvider>
|
||||
);
|
||||
};
|
||||
|
@ -6,15 +6,18 @@ describe('RecordPicker', () => {
|
||||
it('should show selected options', async () => {
|
||||
render(<App1 />);
|
||||
|
||||
const selector = document.querySelector('.ant-select-selector') as HTMLElement;
|
||||
expect(selector).toBeInTheDocument();
|
||||
let selector;
|
||||
await waitFor(() => {
|
||||
selector = document.querySelector('.ant-select-selector') as HTMLElement;
|
||||
expect(selector).toBeInTheDocument();
|
||||
});
|
||||
|
||||
await userEvent.click(selector);
|
||||
|
||||
await waitFor(() => {
|
||||
// 弹窗标题
|
||||
expect(screen.getByText(/select record/i)).toBeInTheDocument();
|
||||
expect(screen.queryByText(/select record/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const checkboxes = document.querySelectorAll('.ant-checkbox');
|
||||
|
||||
// 第 3 个选项的内容是: “软件开发”
|
||||
@ -22,8 +25,8 @@ describe('RecordPicker', () => {
|
||||
await userEvent.click(screen.getByText(/submit/i));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(within(selector).getByText(/软件开发/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/软件开发/i, { selector: '.test-record-picker-read-pretty-item' })).toBeInTheDocument();
|
||||
expect(within(selector).queryByText(/软件开发/i)).toBeInTheDocument();
|
||||
expect(screen.queryByText(/软件开发/i, { selector: '.test-record-picker-read-pretty-item' })).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -9,6 +9,7 @@ import {
|
||||
BlockItem,
|
||||
CollectionField,
|
||||
CollectionManagerProvider,
|
||||
CurrentUserProvider,
|
||||
FormItem,
|
||||
Input,
|
||||
RecordPicker,
|
||||
@ -23,6 +24,9 @@ import data from './mockData';
|
||||
|
||||
const { apiClient, mockRequest } = mockAPIClient();
|
||||
|
||||
mockRequest.onGet('/auth:check').reply(() => {
|
||||
return [200, { data: {} }];
|
||||
});
|
||||
mockRequest.onGet('/tt_bd_range:list').reply(({ params }) => {
|
||||
// 已选中的 id
|
||||
const ids = JSON.parse(params.filter).$and?.[0]?.['id.$ne'] || [];
|
||||
@ -172,11 +176,13 @@ export default () => {
|
||||
|
||||
return (
|
||||
<APIClientProvider apiClient={apiClient}>
|
||||
<CollectionManagerProvider collections={mainCollections}>
|
||||
<SchemaComponentProvider components={components}>
|
||||
<SchemaComponent schema={schema} />
|
||||
</SchemaComponentProvider>
|
||||
</CollectionManagerProvider>
|
||||
<CurrentUserProvider>
|
||||
<CollectionManagerProvider collections={mainCollections}>
|
||||
<SchemaComponentProvider components={components}>
|
||||
<SchemaComponent schema={schema} />
|
||||
</SchemaComponentProvider>
|
||||
</CollectionManagerProvider>
|
||||
</CurrentUserProvider>
|
||||
</APIClientProvider>
|
||||
);
|
||||
};
|
||||
|
@ -14,18 +14,18 @@ type VariablesCtx = {
|
||||
};
|
||||
|
||||
export const useVariablesCtx = (): VariablesCtx => {
|
||||
const { data } = useCurrentUserContext() || {};
|
||||
const currentUser = useCurrentUserContext();
|
||||
const { field, service, rowKey } = useTableBlockContext();
|
||||
const contextData = service?.data?.data?.filter((v) => (field?.data?.selectedRowKeys || [])?.includes(v[rowKey]));
|
||||
return useMemo(() => {
|
||||
return {
|
||||
$user: data?.data || {},
|
||||
$user: currentUser?.data?.data || {},
|
||||
$date: {
|
||||
now: () => dayjs().toISOString(),
|
||||
},
|
||||
$context: contextData,
|
||||
};
|
||||
}, [data]);
|
||||
}, [contextData, currentUser?.data?.data]);
|
||||
};
|
||||
|
||||
export const isVariable = (str: unknown) => {
|
||||
|
@ -68,11 +68,6 @@ function Label() {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!currentUser) {
|
||||
error('Please check if provide `CurrentUserProvider` in your app.');
|
||||
throw new Error('Please check if provide `CurrentUserProvider` in your app.');
|
||||
}
|
||||
|
||||
if (!systemSettings) {
|
||||
error('Please check if provide `SystemSettingsProvider` in your app.');
|
||||
throw new Error('Please check if provide `SystemSettingsProvider` in your app.');
|
||||
|
Loading…
Reference in New Issue
Block a user