console: fix broken storybook tests

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/9716
GitOrigin-RevId: 4ce9d0f2d00c4a52e3a975c2a7044d4a5ff1be91
This commit is contained in:
Matthew Goodwin 2023-06-30 12:07:49 -05:00 committed by hasura-bot
parent 37dd302729
commit d4e05a3cbb
5 changed files with 105 additions and 139 deletions

View File

@ -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"
>

View File

@ -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]);

View File

@ -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'),
};

View File

@ -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');
// });
// },
};

View File

@ -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