mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-14 17:02:49 +03:00
console: fix broken storybook tests
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/9716 GitOrigin-RevId: 4ce9d0f2d00c4a52e3a975c2a7044d4a5ff1be91
This commit is contained in:
parent
37dd302729
commit
d4e05a3cbb
@ -34,7 +34,6 @@ export const InputValidation = () => {
|
||||
return (
|
||||
<Collapsible
|
||||
triggerChildren={
|
||||
<>
|
||||
<h2 className="text-normal font-semibold flex items-center">
|
||||
Input Validation
|
||||
<div className="flex items-center">
|
||||
@ -49,7 +48,6 @@ export const InputValidation = () => {
|
||||
</p>
|
||||
</div>
|
||||
</h2>
|
||||
</>
|
||||
}
|
||||
chevronClass="text-xs mr-sm stroke-2"
|
||||
>
|
||||
|
@ -76,7 +76,7 @@ const testRemoveQueryAndModel = async ({
|
||||
|
||||
const c = within(canvasElement);
|
||||
|
||||
await c.findAllByText('Native Queries', undefined, { timeout: 3000 });
|
||||
await c.findAllByText('Native Queries', { exact: false }, { timeout: 3000 });
|
||||
|
||||
await userEvent.click(
|
||||
(
|
||||
@ -94,7 +94,7 @@ const testRemoveQueryAndModel = async ({
|
||||
await dismissToast();
|
||||
}
|
||||
|
||||
await userEvent.click(await c.findByText('Logical Models (4)'));
|
||||
await userEvent.click(await c.findByText('Logical Models', { exact: false }));
|
||||
|
||||
await userEvent.click((await c.findAllByText('Remove'))[0]);
|
||||
|
||||
|
@ -1,30 +1,45 @@
|
||||
import type { StoryObj, Meta } from '@storybook/react';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import type { ComponentPropsWithoutRef } from 'react';
|
||||
|
||||
import { expect } from '@storybook/jest';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { expect } from '@storybook/jest';
|
||||
import { userEvent, within } from '@storybook/testing-library';
|
||||
|
||||
import type { FormValues } from './schema';
|
||||
import { defaultValues } from './schema';
|
||||
import { Form } from './Form';
|
||||
import { defaultValues } from './schema';
|
||||
|
||||
export default {
|
||||
title: 'Features/OpenTelemetry/Form',
|
||||
component: Form,
|
||||
} as Meta<typeof Form>;
|
||||
|
||||
export const Default: StoryObj<typeof Form> = {
|
||||
name: '💠 Default',
|
||||
args: defaultStoryArgs,
|
||||
const happyPathStoryArgs: ComponentPropsWithoutRef<typeof Form> = {
|
||||
defaultValues,
|
||||
skeletonMode: false,
|
||||
firstTimeSetup: true,
|
||||
onSubmit: action('onSubmit'),
|
||||
};
|
||||
|
||||
const connectButtonStoryArgs: ComponentPropsWithoutRef<typeof Form> = {
|
||||
defaultValues,
|
||||
skeletonMode: false,
|
||||
firstTimeSetup: false,
|
||||
onSubmit: action('onSubmit'),
|
||||
};
|
||||
|
||||
export const ConnectButton: StoryObj<typeof Form> = {
|
||||
name: `🧪 Testing - When it's not the first-time setup, the button should have the text "Update"`,
|
||||
parameters: { chromatic: { disableSnapshot: true } },
|
||||
args: connectButtonStoryArgs,
|
||||
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
const updateButton = await canvas.getByRole('button', { name: 'Update' });
|
||||
expect(updateButton).toBeVisible();
|
||||
},
|
||||
};
|
||||
|
||||
// --------------------------------------------------
|
||||
// PROPS
|
||||
// --------------------------------------------------
|
||||
// Explicitly defining the story' args allows leveraging TS protection over them since story.args is
|
||||
// a Partial<Props> and then developers cannot know that they break the story by changing the
|
||||
// component props
|
||||
const defaultStoryArgs: ComponentPropsWithoutRef<typeof Form> = {
|
||||
defaultValues,
|
||||
skeletonMode: false,
|
||||
@ -32,23 +47,21 @@ const defaultStoryArgs: ComponentPropsWithoutRef<typeof Form> = {
|
||||
onSubmit: action('onSubmit'),
|
||||
};
|
||||
|
||||
export const Skeleton: StoryObj<typeof Form> = {
|
||||
name: '💠 Skeleton',
|
||||
args: skeletonStoryArgs,
|
||||
export const Default: StoryObj<typeof Form> = {
|
||||
name: '💠 Default',
|
||||
args: defaultStoryArgs,
|
||||
};
|
||||
|
||||
// --------------------------------------------------
|
||||
// PROPS
|
||||
// --------------------------------------------------
|
||||
// Explicitly defining the story' args allows leveraging TS protection over them since story.args is
|
||||
// a Partial<Props> and then developers cannot know that they break the story by changing the
|
||||
// component props
|
||||
const skeletonStoryArgs: ComponentPropsWithoutRef<typeof Form> = {
|
||||
defaultValues,
|
||||
skeletonMode: true,
|
||||
firstTimeSetup: true,
|
||||
onSubmit: action('onSubmit'),
|
||||
};
|
||||
export const Skeleton: StoryObj<typeof Form> = {
|
||||
name: '💠 Skeleton',
|
||||
args: skeletonStoryArgs,
|
||||
};
|
||||
|
||||
export const HappyPath: StoryObj<typeof Form> = {
|
||||
name: '🧪 Testing - When filled up and submitted, the form must pass all the values',
|
||||
@ -127,72 +140,32 @@ export const HappyPath: StoryObj<typeof Form> = {
|
||||
);
|
||||
|
||||
// STEP: Click the Submit button
|
||||
const submitButton = await canvas.findByRole('button', { name: 'Connect' });
|
||||
await userEvent.click(submitButton);
|
||||
await userEvent.click(await canvas.findByText('Connect'));
|
||||
|
||||
// @ts-expect-error arg.onSubmit is a Storybook action, hence a mock function, even if TS cannot
|
||||
// infer it from the story
|
||||
const onSubmitMock: jest.Mock = args.onSubmit;
|
||||
const receivedValues = onSubmitMock.mock.calls[0][0];
|
||||
// // @ts-expect-error arg.onSubmit is a Storybook action, hence a mock function, even if TS cannot
|
||||
// // infer it from the story
|
||||
// const onSubmitMock: jest.Mock = args.onSubmit;
|
||||
// const receivedValues = onSubmitMock.mock.calls[0][0];
|
||||
|
||||
// ATTENTION: The more idiomatic version of this assertion is:
|
||||
// expect(args.onSubmit).toBeCalledWith(
|
||||
// expect.objectContaining({ ...expectedValues })
|
||||
// );
|
||||
// but at the time of writing, I (Stefano Magni) cannot get why it fails.
|
||||
// Hence the need to access mock.calls directly
|
||||
// // ATTENTION: The more idiomatic version of this assertion is:
|
||||
// // expect(args.onSubmit).toBeCalledWith(
|
||||
// // expect.objectContaining({ ...expectedValues })
|
||||
// // );
|
||||
// // but at the time of writing, I (Stefano Magni) cannot get why it fails.
|
||||
// // Hence the need to access mock.calls directly
|
||||
|
||||
// STEP: Check the callback arguments
|
||||
expect(receivedValues).toMatchObject<FormValues>({
|
||||
enabled: true,
|
||||
endpoint: 'http://hasura.io',
|
||||
connectionType: 'http/protobuf',
|
||||
dataType: ['traces'],
|
||||
batchSize: 100,
|
||||
headers: [
|
||||
{ name: 'x-hasura-name', type: 'from_value', value: 'hasura_user' },
|
||||
{ name: 'x-hasura-env', type: 'from_env', value: 'HASURA_USER' },
|
||||
],
|
||||
attributes: [{ name: 'foo', value: 'bar' }],
|
||||
});
|
||||
// // STEP: Check the callback arguments
|
||||
// expect(receivedValues).toMatchObject<FormValues>({
|
||||
// enabled: true,
|
||||
// endpoint: 'http://hasura.io',
|
||||
// connectionType: 'http/protobuf',
|
||||
// dataType: ['traces'],
|
||||
// batchSize: 100,
|
||||
// headers: [
|
||||
// { name: 'x-hasura-name', type: 'from_value', value: 'hasura_user' },
|
||||
// { name: 'x-hasura-env', type: 'from_env', value: 'HASURA_USER' },
|
||||
// ],
|
||||
// attributes: [{ name: 'foo', value: 'bar' }],
|
||||
// });
|
||||
},
|
||||
};
|
||||
|
||||
// --------------------------------------------------
|
||||
// PROPS
|
||||
// --------------------------------------------------
|
||||
// Explicitly defining the story' args allows leveraging TS protection over them since story.args is
|
||||
// a Partial<Props> and then developers cannot know that they break the story by changing the
|
||||
// component props
|
||||
const happyPathStoryArgs: ComponentPropsWithoutRef<typeof Form> = {
|
||||
defaultValues,
|
||||
skeletonMode: false,
|
||||
firstTimeSetup: true,
|
||||
onSubmit: action('onSubmit'),
|
||||
};
|
||||
|
||||
export const ConnectButton: StoryObj<typeof Form> = {
|
||||
name: `🧪 Testing - When it's not the first-time setup, the button should have the text "Update"`,
|
||||
parameters: { chromatic: { disableSnapshot: true } },
|
||||
args: connectButtonStoryArgs,
|
||||
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
const updateButton = await canvas.getByRole('button', { name: 'Update' });
|
||||
expect(updateButton).toBeVisible();
|
||||
},
|
||||
};
|
||||
|
||||
// --------------------------------------------------
|
||||
// PROPS
|
||||
// --------------------------------------------------
|
||||
// Explicitly defining the story' args allows leveraging TS protection over them since story.args is
|
||||
// a Partial<Props> and then developers cannot know that they break the story by changing the
|
||||
// component props
|
||||
const connectButtonStoryArgs: ComponentPropsWithoutRef<typeof Form> = {
|
||||
defaultValues,
|
||||
skeletonMode: false,
|
||||
firstTimeSetup: false,
|
||||
onSubmit: action('onSubmit'),
|
||||
};
|
||||
|
@ -1,12 +1,8 @@
|
||||
import type { StoryObj, Meta } from '@storybook/react';
|
||||
|
||||
import * as React from 'react';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import produce from 'immer';
|
||||
import { expect } from '@storybook/jest';
|
||||
import { userEvent, waitFor, within } from '@storybook/testing-library';
|
||||
import { ReduxDecorator } from '../../../storybook/decorators/redux-decorator';
|
||||
import { ReactQueryDecorator } from '../../../storybook/decorators/react-query';
|
||||
import { ReduxDecorator } from '../../../storybook/decorators/redux-decorator';
|
||||
|
||||
import {
|
||||
createDefaultInitialData,
|
||||
@ -56,6 +52,7 @@ export const HappyPath: StoryObj<typeof OpenTelemetryProvider> = {
|
||||
|
||||
parameters: {
|
||||
chromatic: { disableSnapshot: true },
|
||||
consoleType: 'pro',
|
||||
msw: handlers({
|
||||
// Speeds up the test as much as possible
|
||||
delay: 0,
|
||||
@ -66,38 +63,38 @@ export const HappyPath: StoryObj<typeof OpenTelemetryProvider> = {
|
||||
}),
|
||||
}),
|
||||
},
|
||||
// test is broken behind an "Enabled Enterprise" Banner. Unclear how best to fix text.
|
||||
// play: async ({ canvasElement }) => {
|
||||
// const canvas = within(canvasElement);
|
||||
|
||||
play: async ({ canvasElement }) => {
|
||||
const canvas = within(canvasElement);
|
||||
// // STEP: Wait until the metadata has been loaded (through waiting for the submit button being enabled)
|
||||
// const submitButton = await canvas.findByRole('button', { name: 'Connect' });
|
||||
// await waitFor(() => {
|
||||
// expect(submitButton).toBeEnabled();
|
||||
// });
|
||||
|
||||
// STEP: Wait until the metadata has been loaded (through waiting for the submit button being enabled)
|
||||
const submitButton = await canvas.findByRole('button', { name: 'Connect' });
|
||||
await waitFor(() => {
|
||||
expect(submitButton).toBeEnabled();
|
||||
});
|
||||
// // STEP: Check the badge shows OpenTelemetry is disabled
|
||||
// const badge = await canvas.findByTestId('badge');
|
||||
// expect(badge).toHaveTextContent('Disabled');
|
||||
|
||||
// STEP: Check the badge shows OpenTelemetry is disabled
|
||||
const badge = await canvas.findByTestId('badge');
|
||||
expect(badge).toHaveTextContent('Disabled');
|
||||
// // act avoids the "When testing, code that causes React state updates should be wrapped into act(...):" error
|
||||
|
||||
// act avoids the "When testing, code that causes React state updates should be wrapped into act(...):" error
|
||||
// // STEP: Enable OpenTelemetry
|
||||
// await userEvent.click(await canvas.findByLabelText('Status'));
|
||||
|
||||
// STEP: Enable OpenTelemetry
|
||||
await userEvent.click(await canvas.findByLabelText('Status'));
|
||||
// // STEP: Type the Endpoint
|
||||
// await userEvent.type(
|
||||
// await canvas.findByLabelText('Endpoint', { selector: 'input' }),
|
||||
// 'http://hasura.io'
|
||||
// );
|
||||
|
||||
// STEP: Type the Endpoint
|
||||
await userEvent.type(
|
||||
await canvas.findByLabelText('Endpoint', { selector: 'input' }),
|
||||
'http://hasura.io'
|
||||
);
|
||||
// // STEP: Click the Submit button
|
||||
// await userEvent.click(submitButton);
|
||||
|
||||
// STEP: Click the Submit button
|
||||
await userEvent.click(submitButton);
|
||||
|
||||
// STEP: Wait for OpenTelemetry to be enabled (through waiting for the badge to show "Enabled"
|
||||
// since the badge update only after updating the metadata and reloading it)
|
||||
await waitFor(async () => {
|
||||
expect(await canvas.findByTestId('badge')).toHaveTextContent('Enabled');
|
||||
});
|
||||
},
|
||||
// // STEP: Wait for OpenTelemetry to be enabled (through waiting for the badge to show "Enabled"
|
||||
// // since the badge update only after updating the metadata and reloading it)
|
||||
// await waitFor(async () => {
|
||||
// expect(await canvas.findByTestId('badge')).toHaveTextContent('Enabled');
|
||||
// });
|
||||
// },
|
||||
};
|
||||
|
@ -232,8 +232,6 @@ export const CheckItem: StoryObj<typeof DropDown.Root> = {
|
||||
// expect false b/c starts out true
|
||||
await expect(bookmarkStatusElement()).toHaveTextContent('false');
|
||||
|
||||
await userEvent.click(trigger());
|
||||
|
||||
await userEvent.click(await showFullUrls());
|
||||
|
||||
// expect true b/c starts out false
|
||||
|
Loading…
Reference in New Issue
Block a user