reactjs - 使用 React 测试库模拟 iframe 的内容

标签 reactjs iframe jestjs react-testing-library

我有一个 React 组件,它返回一个 iframe 并处理向 iframe 发送消息和从 iframe 接收消息。我完全困惑于如何模拟 iframe 并使用 React 测试库模拟在 iframe 中发布的消息。任何想法或例子都会非常有帮助。

组件:

const ContextualHelpClient: React.VFC<CHCProps> = ({ onAction, data }) => {
  const [iframe, setIframe] = React.useState<HTMLIFrameElement | null>(null);

  const handleMessage = React.useCallback((event: MessageEvent<ContextualHelpAction>) => {
    onAction(event.data);
  }, [onAction])

  const contentWindow = iframe?.contentWindow;

  React.useEffect(() => {
    if (contentWindow) {
      contentWindow.addEventListener('message', handleMessage);
      return () => contentWindow.removeEventListener('message', handleMessage);
    }
  }, [handleMessage, contentWindow]);

  React.useEffect(() => {
    if (contentWindow) {
      contentWindow.postMessage({ type: CONTEXTUAL_HELP_CLIENT_DATA, data }, "/");
    }
  }, [data, contentWindow]);

  return <iframe src={IFRAME_SOURCE} width={300} height={300} ref={setIframe} title={IFRAME_TITLE} />;
};

测试:

import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import ContextualHelpClient from '../ContextualHelpClient';
import { IFRAME_SOURCE, IFRAME_TITLE } from '../constants';

describe('<ContextualHelpClient />', () => {
  it('should call onAction when a message is posted', () => {
    const handleAction = jest.fn();
    const content = render(<ContextualHelpClient onAction={handleAction} />);
    const iframe = content.getByTitle(IFRAME_TITLE);
    fireEvent(iframe.contentWindow, new MessageEvent('data'));
    expect(handleAction).toBeCalled(); // fails
  });
});

最佳答案

就我而言,在 fireEvent 上使用 message 类型足以测试这一点。

import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import ContextualHelpClient from '../ContextualHelpClient';
import { IFRAME_SOURCE, IFRAME_TITLE } from '../constants';

describe('<ContextualHelpClient />', () => {
  it('should call onAction when a message is posted', () => {
    const handleAction = jest.fn();
    const content = render(<ContextualHelpClient onAction={handleAction} />);
    const iframe = content.getByTitle(IFRAME_TITLE);
    fireEvent(
      window,
      new MessageEvent('message', {origin:  window.location.origin}),
      );
    expect(handleAction).toBeCalled(); // fails
  });
});

关于reactjs - 使用 React 测试库模拟 iframe 的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71608996/

相关文章:

node.js - 如何在 Jest 中使用 babel-preset-env

javascript - 如何解决 TypeScript 编译器错误 "Namespace ' NodeJS' has no export member 'Global' "?

javascript - 使用 sinon 测试 promise 中的函数

javascript - 在 Redux 中实现撤销/重做

reactjs - 导入语句: with or without React?

iframe - 隐藏 Vimeo 播放/暂停按钮?

java - 关闭另一个 iframe 时,Selenium 切换到错误的 iframe

javascript - 状态更新后不重新渲染表组件

javascript - 如何根据状态禁用按钮?

ruby-on-rails - Facebook 应用程序与 Rails 上的 iframe