4

I've been running my component tests via cypress open-ct for a while now, relying on importing /node_modules/tailwindcss/dist/tailwindcss.min.css.

Since upgrading to Tailwind v3 some of my tests are failing as there is no prebuilt CSS file I can import - everything is generated just in time.

For example, testing if a modal closes when clicking on a overlay that is fixed and full width fails as the whole modal is rendered so that it is inaccessible by Cypress.

Another side-issue that stems from not having access to Tailwind classes is that videos recorded when running tests in CI are unusable as they are just a bunch of random native elements.

I've been importing Tailwind like this at the top of each Test file (before describes)

import { mount } from '@cypress/vue'
import '/node_modules/tailwindcss/dist/tailwind.min.css'
import MultiSelectField from './MultiSelectField.vue'
import { ref } from "vue";

Any ideas how to include Tailwind (preferably globally) so tests won't fail?

Gelboron
  • 43
  • 4

3 Answers3

7

You can use the Tailwind CLI to generate your stylesheet on the fly.

Add this plugin in cypress/plugins/tailwind.js (be sure to change the -i source from ./src/styles/globals.css to your base CSS file):

before(() => {
  cy.exec('npx tailwindcss -i ./src/styles/globals.css -m').then(
    ({ stdout }) => {
      if (!document.head.querySelector('#tailwind-style')) {
        const link = document.createElement('style')
        link.id = 'tailwind-style'
        link.innerHTML = stdout

        document.head.appendChild(link)
      }
    },
  )
})

Then, load the plugin by importing it in cypress/support/index.js:

import '../plugins/tailwind'

You should also set up a separate config file for your component tests, such as cypress/support/component.js, and specify that in your cypress.json config file:

{
  "component": {
    "supportFile": "cypress/support/component.js",
  },
  "e2e": {
    "supportFile": "cypress/support/e2e.js"
  }
}

Then, only include import '../plugins/tailwind' in your cypress/support/component.js config file, so that you don't perform the JIT compilation for your E2E tests (since it's unnecessary).

Michael Hays
  • 2,947
  • 3
  • 20
  • 30
  • 1
    Thanks for Your response! This is actually much cleaner and predictable and was a breeze to implement! Working as expected, thank you very much – Gelboron Jan 19 '22 at 14:04
  • I get an error: `ReferenceError: before is not defined` Is there any other imports needed in the `cypress/plugins/tailwind.js` file? – user1012181 May 12 '22 at 05:23
2

Michael Hays' solution works, but it rebuilds the whole .css file every time changes to the code are made, which slows tests down. An alternative would be to run tailwind externally in watch mode.

npm i -D concurrently
package.json
  "scripts": {
    "test": "concurrently \"tailwindcss -i ./src/index.css -o ./dist/index.css --watch\" \"cypress open\" "
  },
cypress/support/component.ts
import "../../dist/index.css";
0

I see you're using import '/node_modules/tailwindcss/dist/tailwind.min.css' which expects a pre-compiled bundle. If you have any customization added to the tailwind config, those would not be covered.

But if you can't use the generated css and don't have any tailwind customization, you could use the cdn version from https://cdn.tailwindcss.com/

Because you are running it in a test and don't want to add to possible "flakyness" of using remote dependency, you'll likely want to download that file and keep it in the repo and update it manually from time to time. You can also use some automation for getting the correct version from the cdn before running the test, but Ideally you'd use the generated css, since that's what you're shipping so that's the resource that should be getting tested.

Daniel
  • 34,125
  • 17
  • 102
  • 150
  • Thanks for you response. Customisation isn't much of an issue because I am using TailwindUI out of the box with minimal changes to tailwind config. I will try to fiddle with CDN but am curious how it will work out since the CDN version is no longer a CSS file, but a JS file that lets you specify your config on any website and using classes like `mt-[20px]`. – Gelboron Dec 13 '21 at 07:58
  • 1
    Allright - injecting the CDN in a ` – Gelboron Dec 13 '21 at 08:37