DEV Community

Cover image for Testing Text Truncation: Effective Strategies
David
David

Posted on • Updated on

Testing Text Truncation: Effective Strategies

I think many developers have encountered issues with broken UI layouts caused by unexpectedly long text elements on the frontend.
When text content exceeds the available space, truncation techniques like CSS's text-overflow or JavaScript functions need to be applied.

Ensuring that these truncations work flawlessly across various scenarios requires effective testing strategies. In this article, we will delve into approaches for testing UI components that involve truncation, whether achieved through CSS (text-overflow) or JavaScript functions.

Truncation Implemented with JavaScript

When utilizing JavaScript for truncating text, either through libraries like the popular lodash _.truncate function or custom implementations, testing becomes relatively straightforward. We can write unit tests to cover the different scenarios we expect to encounter.

For instance, when using a custom truncation function, a simple test could involve verifying the return value:

import { truncate } from './custom-truncation.js';

it("truncates the text") {
  expect(truncate("your long text", 10)).toEqual("expected")
}
Enter fullscreen mode Exit fullscreen mode

In scenarios involving libraries, it might be worthwhile to test the truncation within the component itself. For instance, in a React component:

import { render, screen } from '@testing-library/react'

it('should render menu with truncated header', () => {
  render(<Menu {...props} />)

  const header = screen.getByRole('header')
  expect(title).toHaveTextContent('This is some looong title too long...')
})
Enter fullscreen mode Exit fullscreen mode

Component-level testing provides a more direct insight into how the truncation behaves in the context of your UI.

Handling Truncation through CSS

However, things become more intricate when dealing with truncation accomplished via CSS properties like text-overflow: ellipsis. The initial instinct might be to write tests similar to those above—render the component and inspect the text content. But, unfortunately, this approach will not yield accurate results.

Due to the nature of text-overflow truncation, the entire text remains within the HTML element, causing assertions to fail.

Image with truncated HTML element using CSS and JS

Link to the pen.

So, how do we effectively test CSS-based truncation?

To confirm successful truncation via text-overflow, we can implement a simple validation technique by comparing offsetWidth and scrollWidth:

function isEllipsisActive(e: HTMLElement) {
  return (e.offsetWidth < e.scrollWidth);
}
Enter fullscreen mode Exit fullscreen mode

(For a quick refresher on offsetWidth and scrollWidth, refer to this explanation).

However, there's a catch. If your testing library relies on jsdom, accessing offsetWidth and scrollWidth directly from an element might not work due to rendering limitations. This limitation is further elaborated upon here.

Nonetheless, if you're using a library like Cypress, which performs actual rendering, you can incorporate this validation into your test:

it("should render menu with truncated header", () => {
  cy.visit("your_page_url"); // Replace with the URL of the page containing the element

  cy.get('[data-testid="your_element_id"]').then(($element) => {
    const offsetWidth = $element[0].offsetWidth;
    const scrollWidth = $element[0].scrollWidth;

    expect(offsetWidth).to.be.lessThan(scrollWidth);
  });
});
Enter fullscreen mode Exit fullscreen mode

But what if your only option is a library that relies on jsdom, and accessing params such as offsetWidth is not feasible?

In that case, an alternative approach involves validating the existence of specific styles applied to the HTML element:

it('should render menu with truncated header', () => {
  // selection of element
  // ...

  expect(element).toHaveStyle('text-overflow: ellipsis');
  expect(element).toHaveStyle('overflow: hidden');
  expect(element).toHaveStyle('white-space: nowrap');
});
Enter fullscreen mode Exit fullscreen mode

While not as robust as testing the actual rendered value, this method can still serve as a viable solution in certain scenarios.

Results

  • JavaScript Truncation:
    • Write unit tests covering your truncation function
    • Write component tests checking the actual text inside DOM after truncation
  • CSS Truncation:
    • Verify truncation using rendering libraries like Cypress, comparing offsetWidth and scrollWidth
    • For jsdom-based libraries ensure expected CSS properties are present

By following these steps, we can ensure consistent and reliable truncation behavior.

Top comments (0)