storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
83.49k stars 9.13k forks source link

[Bug]: Should not be able to write in inert form #27138

Open codingedgar opened 2 months ago

codingedgar commented 2 months ago

Describe the bug

image

when a form is inert tests consider you can write and that it is enabled, they pass when they actually failed.

To Reproduce

https://stackblitz.com/edit/github-h8mbsw?file=src%2Fstories%2FCase.stories.tsx

System

Storybook Environment Info:

  System:
    OS: macOS 14.4.1
    CPU: (8) x64 Intel(R) Core(TM) i5-8279U CPU @ 2.40GHz
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 18.17.0 - ~/.nvm/versions/node/v18.17.0/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v18.17.0/bin/yarn <----- active
    npm: 9.6.7 - ~/.nvm/versions/node/v18.17.0/bin/npm
  Browsers:
    Chrome: 124.0.6367.201
    Edge: 124.0.2478.97
    Firefox: 125.0.3
    Safari: 17.4.1
  npmPackages:
    @storybook/addon-actions: 8.0.9 => 8.0.9 
    @storybook/addon-essentials: 8.0.9 => 8.0.9 
    @storybook/addon-interactions: 8.0.9 => 8.0.9 
    @storybook/addon-links: 8.0.9 => 8.0.9 
    @storybook/react: 8.0.9 => 8.0.9 
    @storybook/react-vite: 8.0.9 => 8.0.9 
    @storybook/test: ^8.0.9 => 8.0.9 
    chromatic: ^11.3.0 => 11.3.0 
    eslint-plugin-storybook: 0.8.0 => 0.8.0 
    msw-storybook-addon: 2.0.0 => 2.0.0 
    storybook: 8.0.9 => 8.0.9 
    storybook-addon-pseudo-states: 3.1.0 => 3.1.0 
    storybook-dark-mode: 4.0.1 => 4.0.1

Additional context

No response

codingedgar commented 2 months ago

Leaving this here in case the sandbox gets deleted

import type { Meta, StoryObj } from '@storybook/react';
import { within, userEvent, expect } from '@storybook/test';
import { ComponentProps } from 'react';

function Case(props: ComponentProps<'form'>) {
  return (
    <form {...props}>
      <input placeholder="not focusable" />
    </form>
  );
}

const meta = {
  title: 'Case',
  component: Case,
  parameters: {
    // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout
    layout: 'fullscreen',
  },
} satisfies Meta<typeof Case>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Enabled: Story = {
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    const input = canvas.getByPlaceholderText('not focusable');
    await expect(input).toBeEnabled();
    await userEvent.type(input, 'can write');
    await expect(canvas.queryByDisplayValue('can write')).toBeInTheDocument();
  },
};

export const Disabled: Story = {
  args: {
    inert: '',
  },
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    const input = canvas.getByPlaceholderText('not focusable');
    await expect(input).toBeEnabled();
    await userEvent.type(input, 'can write');
  },
};

export const RedundantTest: Story = {
  args: {
    inert: '',
  },
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    const input = canvas.getByPlaceholderText('not focusable');
    await expect(input).toBeEnabled();
    await userEvent.type(input, 'can write');
    await expect(
      canvas.queryByDisplayValue('can write')
    ).not.toBeInTheDocument();
  },
};

export const Expected: Story = {
  args: {
    inert: '',
  },
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    const input = canvas.getByPlaceholderText('not focusable');
    // to pass
    await expect(input).toBeDisabled();
    // to fail
    await userEvent.type(input, 'can write');
  },
};
codingedgar commented 2 months ago

Seems like the issue comes from here https://github.com/capricorn86/happy-dom/issues/1422

codingedgar commented 2 months ago

jsdom has the same issue: https://github.com/jsdom/jsdom/issues/3605

shilman commented 1 month ago

Good catch @codingedgar . Looks like you've already filed it here https://github.com/testing-library/user-event/issues/1215