Closed titenis closed 1 year ago
Hi! That's an interesting question. The thing that comes to mind for me is the print
prop, which lets you pass in your own function to call instead of window.print
. Could you pass your mock into that?
const mockedPrint = someMockingLib((iframe: HTMLIframeElement) => {
// We're printing, do something
// Can return a Promise here as well and `react-to-print` will wait for it to resolve
});
const handlePrint = useReactToPrint({
// ...
print: mockedPrint,
// ...
});
But that means I would have to alter my app specifically for a test to work, which, if Im not wrong, is a testing anti pattern
I would posit that you trying to test 3rd party code (react-to-print
's internal call of window.print
) is a testing anti pattern. You should test that you call react-to-print
correctly. You shouldn't test that a 3rd party library works or doesn't. For that, feel free to make a PR adding tests to this repo ❤️ 🙏
That is also correct. Thanks
Will close for now, but am very open to figuring out how to add better tests to this library. The way I currently test is to go through each example on Chrome, Firefox, and Safari, but of course that isn't fully comprehensive (I don't normally test on mobile devices for example)
Just to be clear, the option provided here only works for unit tests. An integration test, like cypress, isn't able to inject props, so the option provided isn't feasible.
@daniel-butler do you have any suggestions for how we can make testing in an integration framework such as Cypress easy? If there's some low-hanging fruit here I would be very happy to address it
I haven't been able to find a working solution, but I am thinking the <iframe id="printWindow" ...
print function needs to be stubbed. In general Cypress doesn't really support the print dialogue, so the solution without this great library is to stub the windows print function with the code below.
cy.stub(cy.state('window'), 'print', () => {
// mock implementation
});
I would posit that you trying to test 3rd party code (
react-to-print
's internal call ofwindow.print
) is a testing anti pattern. You should test that you callreact-to-print
correctly. You shouldn't test that a 3rd party library works or doesn't. For that, feel free to make a PR adding tests to this repo ❤️ 🙏
I believe you are confusing unit test with integration/e2e tests, or you are using broad overly generalized statement as an inflexible rule that doesn't actually answer the question. Fortunately ChatGPT has a working response to OP:
// Set up a MutationObserver to listen for the iframe being added to the DOM
cy.window().then((win) => {
const observer = new MutationObserver((mutationsList, observer) => {
for (const mutation of mutationsList) {
if (mutation.type === "childList") {
for (const node of mutation.addedNodes) {
if (node.tagName === "IFRAME") {
const iframeWindow = node.contentWindow;
cy.stub(iframeWindow, "print").as("iframePrint");
observer.disconnect(); // Stop observing once iframe is found and stubbed
return;
}
}
}
}
});
observer.observe(win.document.body, { childList: true, subtree: true });
});
Hello, Any ideas how to test stuff written with this lib? I've been unsuccessfully trying to assert that
window.print
is called, but seems that is not possible. First of all - unable to mock/stub window.print in jest/vitest, since the mocking happens in parent window and the actual printing happens in child iframe window, which ignores mocks. Same thing with cypress, only stubing parent window print and the iframe is not even in the dom before the printing function is initiated. I could mock whole react-to-print module, but I dont see real value in such test.