1. 27
    Write Cypress Tests for our React Storybook Components with Nx
    5m 3s

Write Cypress Tests for our React Storybook Components with Nx

Share this video with your friends

Social Share Links

Send Tweet

Storybook is already powerful for being able to develop components in isolation as well as using those stories as living documentation for others. Nx goes a step further. It leverages the fact that Storybook exposes an iframe.html that allows to access the rendering of the story without the actual Storybook frame. On top of that, Nx generates a Cypress configuration to run tests against the Storybook stories.

Prefer to read along as well? Here's the accompanying article.

Instructor: [0:00] When we used Nx to generate the Storybook setup for our UI Library here, we also got some end-to-end tests, based on Cypress, generated for that Storybook.

[0:11] If we go and look into that integration test which also got generated, what you can see here is that the test basically launches behind the scenes, Storybook. Then, it directly accesses our page that Storybook exposes, which is this iframe HTML, which is directly the visualization of the Story itself. Based on the page, it then renders tests against it.

[0:35] To launch these Storybook tests, in our workspace.json file, we should have a project called ui-e2e. That should have an actual end-to-end target that allows us to execute end-to-end tests for the specific application.

[0:53] If we run nx e2e storybook-e2e ui-e2e, so this is basically the project name, which is based here, of that workspace.json configuration. Let's also run this immediately into watch mode. This will now launch Storybook behind the scenes, as you can see here, and then it will run Cypress and point to the Storybook port.

[1:16] Once Storybook and Cypress has been started, we can see the Cypress test runner. If you click here on that spec file, we see the test runner opens up that iframe page, which just visualizes the story itself, without the sidebar and anything that usually you have when you run Storybook, and then it executes test against it.

[1:36] This still fails because we need to implement the test based on the changes to our TopicButton component. Let's do that. If you go to our TopicButton spec, what we will want to test is, if we pass in a TopicButton topic name to this button here, it should visualize that name properly.

[1:57] Storybook allows to provide the inputs to a button with the so-called args property. Here in the URL, we can directly specify, args = topic-name, which is the input property of our button, :enter value, let's say, React. Once this renders, let's rename here this test that it should render the topic name. We can go ahead and verify whether the name matches our expectation.

[2:24] As a best practice, we should have a hook point in our HTML of the component. Let's open up the topicbutton.tsx file here. What we want to have here is, for the specific rendering of our button, we would want to have a hook point. That is usually done via data test ID property. Let's call this topic-name. This would allow us to use this property in our tests to identify the specific H2 tag here.

[2:52] In our tests we can then go and say, ci.get. We would now try to reference that test ID property that should contain topic-name. That specific element should then contain React, if that's what we specified.

[3:06] Let's now go to the Cypress runner. Let's refresh. We can see here, it opens up the button, it passes in the actual argument correctly, as we expected, so this is React. Then, it verifies whether this specific element contains React, what we passed in as an argument.

[3:23] The next thing that we want to verify, is that whenever we click on the button, that then gets fired properly, and it passes out the name of the topic that previously has been given to the actual component. We can just add another test down here. We would want to identify the button first. We can, again, use a test ID, which we need to specify afterwards.

[3:46] Let's say here, we have here the Topic button itself. If we click that, then we would want to have another such a hook point, such a test ID property, which has the name click-result. That should then, in turn, contain React, because that's what we passed in.

[4:05] We need to define these hook points. The first one is test ID Topic button. We would want to have that directly here on the main button, so this is the Topic button. Click-result is not in here, but it's, rather, in our Story rendering. On this div in our Story rendering, we would want to have the test ID, click-result.

[4:27] Let's go back again to our rendering. Let's refresh. You can see that it passes properly. It first visits, again, that endpoint, it grabs the actual button, it clicks on top of that button, grabs that element, and verifies it against what we have specified in our expectation.

[4:46] Again, this is a very powerful way, because now we can use Storybook, not only to develop our components in isolation, have them documented, but also to run Cypress tests against them, and therefore, test all of our Storybook components in our shared-UI library, in a very visual way, with Cypress.