How to test next/image's onError in Storybook play function?

148 views Asked by At

I want to test when the onError event is called, for the case when image is not found at the following component, but I don't know how to do this.

'use client';

import type { ComponentProps } from 'react';
import React, { useState } from 'react';
import NextImage from 'next/image';
import fallbackImage from './images/fallback-image.png';

type Props = ComponentProps<typeof NextImage> & {
  className?: string;
  fallbackImageUrl?: string;
};

export const Image = ({ className, fallbackImageUrl = fallbackImage.src, ...rest }: Props) => {
  const [imgSrc, setImgSrc] = useState(rest.src);

  return (
    <NextImage
      className={className}
      {...rest}
      src={imgSrc}
      onError={(event) => {
        rest.onError?.(event);
        setImgSrc(fallbackImageUrl);
      }}
    />
  );
};

I'm using storybook and I want to test using a play function. I've already written some test code to check the fallback image will be loaded and this is working well, but I couldn't figure out how to test whether onError has been called or not?

export const NotFound: Story = {
  args: {
    ...Default.args,
    src: 'https://example.com/not-found.png',
  },
  play: async ({ canvasElement, args, step }) => {
    const canvas = within(canvasElement);
    const targetElement = canvas.getByRole('img');

    // waiting for loading image
    setTimeout(async () => {
      const srcAttrValue = targetElement.getAttribute('src')?.split('/').slice(-1)[0].split('?')[0];
      const srcPropsValue = args.src.toString().split('/').slice(-1)[0].split('?')[0];

      await step('not-found.png will not load', async () => {
        expect(srcAttrValue).not.toMatch(srcPropsValue);
      });

      await step('fallback-image.png wil load', async () => {
        expect(srcAttrValue).toMatch('fallback-image.png');
      });
    }, 800);
  },
};
``` 
0

There are 0 answers