Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does not take effect until the play function is executed #89

Open
kasir-barati opened this issue Sep 28, 2023 · 2 comments
Open

Does not take effect until the play function is executed #89

kasir-barati opened this issue Sep 28, 2023 · 2 comments

Comments

@kasir-barati
Copy link

Hi dear reader

I tried to hover on a element and then check if another element is being displayed to the user or not, but then I realized that it is not working like that since it waits until the play function is being completely executed. and that is really what makes trouble for me, because I have a play function like this:

import { StoryObj } from "@storybook/react"
import { expect } from "@storybook/jest"
import { within } from "@storybook/testing-library"
import { SomeComponentProps, SomeComponent } from "./some-component"

const Template: StoryObj<SomeComponentProps> = {
  render: (args) => <SomeComponent {...args} />,
  args: {
    children: "some random info",
  },
}

export const UnHovered: typeof Template = {
  parameters: { pseudo: { hover: false } },
  args: {
    children: "You cannot see me!",
  },
  play: async ({ canvasElement }) => {
    const canvas = await within(canvasElement)

    await retry({
      attempt: async () => {
        const infoIconContentElement = canvas.getByTestId("someTestId")

        await expect(infoIconContentElement).not.toBeVisible()
      },
      maxRetries: 7,
    })()
  },
}

function retry({ attempt, maxRetries }: { attempt: (...args: unknown[]) => Promise<unknown>; maxRetries: number }) {
  return async function (...args: unknown[]) {
    const slotTime = 500
    let retryCount = 0

    do {
      try {
        console.log("Attempting...", Date.now())
        return await attempt(...args)
      } catch (error) {
        const isLastAttempt = retryCount === maxRetries
        if (isLastAttempt) {
          console.error(error)
          return Promise.reject(error)
        }
      }

      const randomTime = Math.floor(Math.random() * slotTime)
      const delay = 2 ** retryCount * slotTime + randomTime
      // Wait for the exponentially increasing delay period before
      // retrying again.
      await new Promise((resolve) => setTimeout(resolve, delay))
    } while (retryCount++ < maxRetries)
  }
}

And here is the some-component.tsx:

interface SomeComponentProps {
  children: string
}
export function SomeComponent({ children }: SomeComponentProps) {
  return (
    <div className="group block">
      <h3>hover over me</h3>
      <p data-test="someTestId" className="group-hover:block">
        {children}
      </p>
    </div>
  )
}

Anything I am misunderstanding abut this addon or in general how play function and parameters work together?

@kasir-barati
Copy link
Author

I also know that:

Because this addon rewrites your stylesheets rather than toggle the actual browser behavior like DevTools does, it won't render any of the default user agent (browser) styles. Unfortunately there's no JavaScript API to toggle real pseudo states without using a browser extension.

And, but I did not get the message that it will change the UI after play function is executed and probably my tests failed 😢

Please update the doc or tell me if this is a 🐞

@kasir-barati
Copy link
Author

Here is what storybook official doc says:

Storybook's play functions are small code snippets that run once the story finishes rendering.

And also just by reading this doc I could not figure it out if the addon css changes takes effect first and then play function is executed or not.

Any help?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant