DEV Community

Andrew Chaa
Andrew Chaa

Posted on

3

Mocking navigator.clipboard.writeText in Jest

If you're working on a web application that interacts with the clipboard API, you may need to write tests for functionality that calls navigator.clipboard.writeText. However, mocking this API can be tricky, especially when using Jest in ES6. In this post, I'll walk you through the issues I encountered and how I resolved them.

The first approach I tried was to overwrite the clipboard object directly. Unfortunately, this doesn't work in ES6 because the clipboard object has only a getter, making it read-only. Attempting to assign a new value to clipboard will result in an error.

// This won't work
navigator.clipboard = {
  writeText: jest.fn()
};
Enter fullscreen mode Exit fullscreen mode

The solution is to use jest.spyOn to create a mock implementation of the writeText method. Here's how you can do that:

jest.spyOn(navigator.clipboard, 'writeText');
Enter fullscreen mode Exit fullscreen mode

However, when I tried this approach, I ran into another issue: a DOMException with the message "Type text/plain does not match the blob's type". After some digging, I realized that this error was occurring because the Jest environment doesn't implement the Clipboard API.

To work around this, I had to mock the writeText method using spyOn and make it return a resolved Promise:

const writeTextMock = jest.spyOn(navigator.clipboard, 'writeText').mockResolvedValue();
Enter fullscreen mode Exit fullscreen mode

With this approach, my tests could call navigator.clipboard.writeText without throwing any errors, and I could use the writeTextMock to assert that the method was called with the expected arguments.

describe('MessagePane', () => {
  it('should copy content to clipboard when button is clicked', async () => {
    const messages = [
      { author: 'USER', content: 'Hello' },
      { author: 'BOT', content: 'Hi' },
    ];

    const { user } = renderWithProviders(
      <MessagePane messages={messages} />, {}
    );

    const writeTextMock = jest.spyOn(navigator.clipboard, 'writeText').mockResolvedValue();
    const copyButtons = screen.getAllByRole('button');
    await user.click(copyButtons[1]);

    expect(writeTextMock).toHaveBeenCalledWith('Hi');
  });
});
Enter fullscreen mode Exit fullscreen mode

In summary, mocking the navigator.clipboard.writeText method in Jest requires a few steps:

  1. Use jest.spyOn to create a mock implementation of the writeText method.
  2. Make the mock implementation return a resolved Promise to avoid DOMException errors.
  3. Use the mock instance to assert that the method was called as expected in your tests.

I hope this blog post helps you navigate the intricacies of mocking the Clipboard API in Jest. Happy testing!

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay