Jest、Enzyme、React - 测试 Iframe OnLoad
Jest,Enzyme,React - Testing Iframe OnLoad
我正在编写一个反应组件,它将在 iframe 中加载 URL,然后当 iframe 的 onLoad 事件触发时,它将调用 contentWindow.postMessage()。我想使用 Jest、Enzyme 和 JSDOM 来证明这个功能。
我的组件包装了 react-iframe,看起来很简单:
export class FilteredIframe extends React.PureComponent<FilteredIframeProps> {
onload = (e:Window) => {
console.log("ONLOAD CALLED");
if (this.props.filters) {
e.postMessage(this.props.filters, this.props.url);
}
}
render() {
return (<Iframe url={this.props.url}
display="initial"
position="static"
onLoad={this.onload}
/>);
}
}
我正在尝试弄清楚如何让 enzyme/jsdom 对此进行测试,但我失败了:
test("Posts message once the frame has loaded", async () => {
const payLoad = { data: "data" };
const result = mount(<FilteredIframe url="https:///www.bing.com" filters={payLoad}/>);
})
开玩笑 运行 时,我从未在控制台中看到 "ONLOAD CALLED" 消息。我需要为 jsdom 或 enzyme 做一些特殊的事情来让它真正调用 onLoad 吗?
我重新审视了这个,发现我可以直接在我的组件中调用 iframe 的 onLoad() 。我现在有这样的东西:
test("Posts message once the frame has loaded", async () => {
const payLoad = { data: "data" };
const result = mount(<FilteredIframe url="https:///www.bing.com" filters={payLoad} />);
const iframe = result.find("iframe");
//mock contentWindow so we can examine messages
let receivedFilters = {};
const mockIFrameContents = {
contentWindow : {
postMessage: function (filters, url) {
receivedFilters = filters;
}
}
}
result.instance().setIframeRef(mockIFrameContents);
//Signal the contents have loaded
iframe.props().onLoad();
expect(receivedFilters === payLoad).toBeTruthy();
});
我还稍微修改了组件以对 iframe 本身使用 ref,并使用 ref 的 contentWindow 而不是事件目标。但这里真正的答案只是模拟 iframe contentWindow 并直接调用它的 onLoad(),而不是试图让它实际加载一些东西。
强制更新已安装的包装器对我有用。
<iframe onLoad={this.iframeLoaded}></iframe>
然后像这样测试...
const mountWrapper = mount(<App />);
let container;
describe('iframe', () => {
beforeEach(() => {
container = mountWrapper.find('iframe');
});
it('calls iframeLoaded() when loaded', () => {
const spy = jest.spyOn(mountWrapper.instance(), 'iframeLoaded');
mountWrapper.instance().forceUpdate();
container.simulate('load');
expect(spy).toHaveBeenCalledTimes(1);
});
});
您需要将挂载的 iframe 附加到文档,挂载的 attachTo 选项可以做到这一点。
OP 的回答有我需要的部分。如果您不需要加载 iframe,而只需要触发器(如果 iframe src 是 pdf),则触发 onLoad 和更新。
act(() => {
result.find('iframe').props().onLoad();
});
result.update();
我正在编写一个反应组件,它将在 iframe 中加载 URL,然后当 iframe 的 onLoad 事件触发时,它将调用 contentWindow.postMessage()。我想使用 Jest、Enzyme 和 JSDOM 来证明这个功能。
我的组件包装了 react-iframe,看起来很简单:
export class FilteredIframe extends React.PureComponent<FilteredIframeProps> {
onload = (e:Window) => {
console.log("ONLOAD CALLED");
if (this.props.filters) {
e.postMessage(this.props.filters, this.props.url);
}
}
render() {
return (<Iframe url={this.props.url}
display="initial"
position="static"
onLoad={this.onload}
/>);
}
}
我正在尝试弄清楚如何让 enzyme/jsdom 对此进行测试,但我失败了:
test("Posts message once the frame has loaded", async () => {
const payLoad = { data: "data" };
const result = mount(<FilteredIframe url="https:///www.bing.com" filters={payLoad}/>);
})
开玩笑 运行 时,我从未在控制台中看到 "ONLOAD CALLED" 消息。我需要为 jsdom 或 enzyme 做一些特殊的事情来让它真正调用 onLoad 吗?
我重新审视了这个,发现我可以直接在我的组件中调用 iframe 的 onLoad() 。我现在有这样的东西:
test("Posts message once the frame has loaded", async () => {
const payLoad = { data: "data" };
const result = mount(<FilteredIframe url="https:///www.bing.com" filters={payLoad} />);
const iframe = result.find("iframe");
//mock contentWindow so we can examine messages
let receivedFilters = {};
const mockIFrameContents = {
contentWindow : {
postMessage: function (filters, url) {
receivedFilters = filters;
}
}
}
result.instance().setIframeRef(mockIFrameContents);
//Signal the contents have loaded
iframe.props().onLoad();
expect(receivedFilters === payLoad).toBeTruthy();
});
我还稍微修改了组件以对 iframe 本身使用 ref,并使用 ref 的 contentWindow 而不是事件目标。但这里真正的答案只是模拟 iframe contentWindow 并直接调用它的 onLoad(),而不是试图让它实际加载一些东西。
强制更新已安装的包装器对我有用。
<iframe onLoad={this.iframeLoaded}></iframe>
然后像这样测试...
const mountWrapper = mount(<App />);
let container;
describe('iframe', () => {
beforeEach(() => {
container = mountWrapper.find('iframe');
});
it('calls iframeLoaded() when loaded', () => {
const spy = jest.spyOn(mountWrapper.instance(), 'iframeLoaded');
mountWrapper.instance().forceUpdate();
container.simulate('load');
expect(spy).toHaveBeenCalledTimes(1);
});
});
您需要将挂载的 iframe 附加到文档,挂载的 attachTo 选项可以做到这一点。
OP 的回答有我需要的部分。如果您不需要加载 iframe,而只需要触发器(如果 iframe src 是 pdf),则触发 onLoad 和更新。
act(() => {
result.find('iframe').props().onLoad();
});
result.update();