Home > Software engineering >  react-testing-library: Verify text truncation
react-testing-library: Verify text truncation

Time:06-04

I have a component "Label" which has rudimentary truncation support:

import "./styles.css";
export default function Label(props) {
  const className = props.truncate ? "truncate" : "";
  return <label className={className}>{props.children}</label>;
}

The truncate css class:

.truncate {
  display: inline-block;
  overflow: hidden;
  white-space: pre;
  text-overflow: ellipsis;
  display: inline-flex;
  min-width: 0;
  max-width: 100%;
}

Here is a screenshot of codesandbox output


Now I'm at the point where I want to add some test coverage for the truncation feature. I'm using react-testing-library, but I'm not sure the best way to assert that the end of the text is not visible with truncation.

Here is my attempt:

const longText = 'START Lorem ipsum dolor sit amet, consectetur adipiscing elit. In ac commodo massa END';
describe('Label', () => {
  it('displays long text', () => {
    render(<Label>{longText}</Label>);
    expect(screen.getByText(/^START/)).toBeInTheDocument(); // pass
    expect(screen.getByText(/END$/)).toBeInTheDocument(); // pass
  });
  it('displays long text with truncation', () => {
    render(<Label truncate={true}>{longText}</Label>);
    expect(screen.getByText(/^START/)).toBeInTheDocument(); // pass
    expect(screen.queryByText(/END$/)).not.toBeVisible(); // FAILURE
  });
});

The last expect is failing with:

Received element is visible:
    <label  />

I understand that I could test for the presence of the class name, but our team feels that it's a poor practice to rely on that.

Is there a best-practice way to test for text truncation?

CodePudding user response:

If you add a screen.debug right after the render with truncate, like this:

render(<Label truncate={true}>{longText}</Label>);

screen.debug();

the output will be:

<label >
      START Lorem ipsum dolor sit amet, consectetur adipiscing elit. In ac commodo massa END
</label>

As you can see the entire text is rendered and what makes the text visible/not visible is the css overflow property.

Said that, I think the best approach here its just verify if the component has or hasn't the overflow property:

expect(screen.getByText(/^START/)).toHaveStyle("overflow: hidden");
  • Related