My program uses printJS which a library that helps format the content of the page for printing. I wanted to write tests with cypress to test that the print preview has been called. Currently I have a button that calls printJS when clicked and since cypress cannot interact with the print preview window, I thought it would be a good idea to stub the call to printJS then write an assertion that it was called once. I understand that this works with window.print() as you can stub that with this code.
cy.visit('http://127.0.0.1/',{
onBeforeLoad: (win) => {
cy.stub(win, 'print')
}
})
Then assert with this
cy.contains('print').click()
cy.window().then((win) => {
expect(win.print).to.be.calledOnce
})
My old button
<button type="button" class="btn btn-secnodary" onclick="window.print()">
Print
</button>
But instead I used printJS which means my button now looks like this
<button type="button" onclick="printJS({printable: 'id_preview_modal_body', type: 'html'})" data-dismiss="modal">
Print
</button>
The javascript gets loaded in as print.min.js which can be found here. I tried to stub the contentwindow but that doesn't seem to work so far. In the code for printJS, the printing happens here
frameElement.contentWindow.print()
from their github page, line 63
The way im stubbing it gives this issue
cy.visit('http://127.0.0.1:8000/notices/new/',{
onBeforeLoad: (win) => {
cy.stub(win, 'printJS')
}
})
Uncaught TypeError: Cannot stub non-existent own property printJS
The assertion also gives this error
cy.window().then((win) => {
expect(win.printJS).to.be.calledOnce
})
TypeError: [Function: init] is not a spy or a call to a spy!
I think the [Function: init]
is a referring to const printJS = print.init
from their index.js
file. But i don't know how to proceed further in debugging this issue. Any help would be appreciated. Thanks!
The problem is the onBeforeLoad
hook is called before printJS is initiated, when printJS is imported it invokes it's init()
function and overwrites your stub in window.print
.
This is stubbing too soon
cy.visit('http://127.0.0.1:8000/notices/new/',{
onBeforeLoad: (win) => {
cy.stub(win, 'printJS')
}
})
Stubbing after component has loaded and printJS is initiated
const printStub
before(function(){
cy.visit('http://127.0.0.1:8000/notices/new/')
// maybe wait for loading to complete
cy.window().then(win => {
printStub = cy.stub(win, 'printJS')
})
})
it('stubs printJS', () => {
cy.contains('button', 'Print').click()
cy.window().then(win => {
expect(printStub).to.be.calledOnce
})
})