Testing styling with Jest - a comprehensive guide

Currently, I am working on a React project that utilizes SASS (SCSS syntax) for styling and Jest for unit testing. I've run into some difficulties when it comes to testing the styling in my project. To illustrate this issue, let's consider the following example:

Within component.js (which imports an external stylesheet)...

const Component = () => {
     return (
        <div className="greeting">Hello</div>
     )
}

In my .scss file...

.greeting {
    background-color: red;
}

For my test file...

test('background color should be red', () => {
    render(<Component />);
    expect(screen.getByText('Hello')).toHaveStyle('background-color: red');
})

The test fails with the following message:

expect(element).toHaveStyle()

    - Expected

    - background-color: red;

However, if I choose to use inline styling (

<div style={{backgroundColor: red}}>Hello</div>
), the test passes successfully.

I would appreciate hearing from anyone who has encountered this particular issue. Additionally, I'm curious to learn about different approaches people have taken for testing styling in Jest, especially when styles are stored in a separate .scss file.

For my tests, I rely on screen from @testing-library/dom and render from @testing-library/react.

Answer №1

If you want to retrieve the computed styles for an element, including those from class declarations, you can utilize the window.getComputedStyle() method.

To verify the background color of a div element in your scenario, you could implement the following test:

test('confirming background color is red', () => {
    render(<Component />);

    const targetElement = screen.getByText('Hello');
    const calculatedStyles = getComputedStyle(targetElement);

    expect(calculatedStyles.backgroundColor).toBe('red');
})

Answer №2

My opinion aligns with Dominik's viewpoint. I find Jest to be effective for testing the attributes of your displayed HTML content. If the styling is not embedded directly in the HTML code, Jest may miss it, as you previously mentioned. The farthest extent you can test without including styles inline is confirming the presence of the correct class name.

Perhaps exploring a testing framework designed for browser execution like Cypress could offer additional solutions. Check out Cypress visual testing guidelines for further insights.

Answer №3

Struggling with testing non-inlined CSS styles was a challenge I faced recently.

Using Gatsby to replicate a web page for experimentation led me to explore testing styles in jest without relying on a browser like playwright.

Fortunately, I came across jest-transform-css, which enabled me to successfully execute a proof of concept style unit test.

Although my setup involves CSS Modules and not SASS or SCSS, following the instructions provided in their README documentation allowed me to create tests like the one below:

import '@testing-library/jest-dom'

import * as React from 'react'
import {render, fireEvent, screen} from '@testing-library/react'
import * as styles from "../../styles/navbar.module.css"
import { HomeNavButton } from "../buttons"

test('test HomeNavButton', () => {
    const testMessage = 'Test Message'
    render(<HomeNavButton href={"/test"} text={testMessage} className={styles.homeItem}/>)

    const div = screen.getByText(testMessage).parentElement
    const computedStyle = window.getComputedStyle(div)
    expect(computedStyle.margin).toBe('auto auto auto 0px')
}

In this test, the margin style of auto auto auto 0px is derived from the styles.homeItem.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

utilize rows as columns in a table

I'm having a row with 4 columns, and I need the last 2 columns to stack below and utilize all available width. How can I achieve this? https://i.sstatic.net/VqEGZ.png <table border="1" style="width: 100%;"> <t ...

Attempting to change the appearance of my jQuery arrow image when toggling the visibility of content

Here is a sample of my JQuery code: $(document).ready(function() { $(".neverseen img").click(function() { $(".neverseen p").slideToggle("slow"); return false; }); }); Below is the corresponding HTML: <div class="neverseen"> <h1> ...

Respond.min.js is specifically optimized for compatibility with IE 8 emulation mode within IE 11

The respond.min.js script seems to only work on Internet Explorer 8 emulation within the developer's mode of IE 11. However, when tested on the actual IE 8, it fails to function without any indication, and in the IE Tester tool, it throws an error sta ...

Directly download a file from an S3 bucket to the React client without the need to route it through a Node.js server

While articles such as this one from Heroku demonstrate the ability to sign a request in a Node server and upload large files directly to S3 from the client, I have been unable to locate a similar solution for downloading large files directly from S3 to th ...

The function cannot be called on a type that does not have a callable signature. The specified type, 'number | Dispatch<SetStateAction<number>>', does not have any compatible call signatures

Currently, I am working on setting up state to be passed through context in React using hooks. However, when I attempt to use the dispatched state updater function, an error is thrown: Cannot invoke an expression whose type lacks a call signature. Type &a ...

Creating Custom GTK Themes using CSS3

Just a quick question: Can CSS3 be used to style GTK3 applications? ...

Having trouble changing the color of the MUI TextField component?

The following code snippet: import Typography from '@mui/material/Typography'; import { FormControl, TextField, InputLabel } from '@mui/material'; import styled from '@emotion/styled'; const ModalFormControl = styled(FormCont ...

Using CSS to position elements absolutely while also adjusting the width of the div

In one section of my website, I have a specific div structure. This structure consists of two divs stacked on top of each other. The first div is divided into two parts: one part with a width of 63% and another part with a button. Beneath the first div, t ...

Looking to incorporate multiple accordion drop down menus on your website? Utilize a combination of HTML, CSS, and JavaScript to

I am experiencing a challenge with implementing multiple accordion menus on my website. Whenever I attempt to duplicate the code, the new accordion menu appears but clicking on the first bar simply scrolls me back to the top of the webpage. Below is the H ...

Error in using TypeScript while subscribing to and rendering meshes imported through GLTF due to lack of context

My current project involves rendering instanced meshes in the scene using the code snippet below: interface IInstanceContext { [key: string]: Mesh<BufferGeometry<NormalBufferAttributes>, Material | Material[], Object3DEventMap> } const cont ...

Difficulty displaying list items/links in Bootstrap Navbar

Currently, I am diving into the world of Bootstrap and experimenting with different components, particularly the navbar feature. However, I've encountered an issue where my links or list items are not visible on the page. I have double-checked the co ...

Mastering CSS positioning and perfect alignment

I'm currently working on a website where I want the text to be centered on the page without scrolling. Although I have the container div centered, I'm struggling to align the text properly. It's crucial that h1 has a position: fixed because ...

Interacting between React and Express with CKEditor 5: How to send a request

import React, { Component, useState, useEffect } from 'react'; import { CKEditor } from '@ckeditor/ckeditor5-react'; import ClassicEditor from '@ckeditor/ckeditor5-build-classic'; import axios from 'axios'; import pa ...

Verify the user's admin role before granting access to a specific page in a web application built with React, Express, NodeJS, and

To ensure that only admin users can access the "Users" page, which displays all registered users on the website, a specific component is needed: <Route path="/users" exact component={Users} /> Although I attempted the following code below, it did n ...

Using the ProtectedRoutes component and implementing redux useSelector() concept

Here is the structure of my AppRoutes. <Switch> <ProtectedRoute exact path="/" component={Home} /> <Route path="/login" component={Login} /> </Switch> I created a custom function called Protecte ...

What is the best way to stretch my background image to cover the entire screen?

I am working on a Python Django project and I want to create a full-screen background. The HTML code: { % load static %} <!DOCTYPE html> <html lang="en"> <head> <!-- Required meta tags--> <meta charset=" ...

Keep the animation keyframes looping endlessly

I am creating a countdown timer circle. The animation functions properly on the initial iteration, however, the circle animation remains full after the first iteration and does not reset. Despite this, the countdown number continues to function correctly, ...

Utilizing Next.js routing to accommodate two distinct subdomains on a single website

I am looking to develop a new platform using Next.js (React.js and React-router). The platform will have two distinct spaces - one for users and another for the owner to manage all users. To achieve this, I plan on splitting both areas into two subdomains: ...

Begin the Material UI Datepicker from the first day of the upcoming month

I'm trying to see if it's possible to set the default current date of a material-UI picker to the first day of next month, but I haven't been able to find any information on how to do this. Can anyone confirm if there is an option for that? ...

What is causing the button to only respond on the second click in reactjs?

Whenever I try to log in using the login button, I encounter a strange issue. If all input fields are correctly filled for the first time, everything works fine. However, if there's an error and I have to correct it, I find myself clicking the login b ...