3

I have got a print button, on click on the button display a print layout. How to interact with the 'print' layout using cypress. I would like to check few things here:

cypress version: 3.5.0 (latest)

1) Check the text "Print" available in `h1` inside the header container div, see image

enter image description here

2) Click on the `Cancel` button: please see the html image below 

enter image description here

Below is my cypress test, but this failed to identify CypressError: Timed out retrying: Expected to find element: 'print-preview-app', but never found it.

context('Print button tests', () => {
            it.only('Print action displays correct data', () => {
                cy.get('.timetable-filter-panel-button.btn.btn-primary > span')
                    .contains("Print current view")
                    .click();
                cy.get('print-preview-app').find('#sidebar').find('#header').find('#headerContainer').find('h1').contains("Print")

            })
        })
soccerway
  • 10,371
  • 19
  • 67
  • 132
  • This is the standard chrome print dialog - why are you testing that? I'm sure the Google developers already have. – Richard Matsen Oct 25 '19 at 01:42
  • @RichardMatsen We have a 'print' button on the web page, I got a automation task to check whether if it is displaying the print dialog/ window. And close the dialog after that. Since after click on the print button, the dialog still remains open and the rest of test in other specs failed as the dialog sits on top of the window. – soccerway Oct 25 '19 at 01:53
  • I am not planning to check any of the print related features inside dialog. – soccerway Oct 25 '19 at 01:54
  • This was my first question though, now trying to close the `print` window once its open. – soccerway Oct 25 '19 at 01:56
  • Yeah, I saw the other question. – Richard Matsen Oct 25 '19 at 06:11
  • @RichardMatsen Thanks for the reply...At the moment, I skipped the test and checking it manually. – soccerway Oct 25 '19 at 06:13
  • I test a print button, but all I do is stub `window.print` (so the click never opens the dialog), then assert that window.print method was called. If you want to do that, I can post my code. Note there may be other ways of invoking print features (e.g PrintJS library) so stubbing `window.print` may not actually work in your scenario. – Richard Matsen Oct 25 '19 at 06:15
  • Thank would be helpful, could you please post it, I will give a try.. – soccerway Oct 25 '19 at 06:16

2 Answers2

4

This is my code for testing a button that invokes the window.print() method, which opens the print dialog.

I use stub because it blocks the actual print method, as well as recording it happened. The other option is spy which records the method call but 'passes-through' so the actual call will occur.

Cypress.Commands.add('wasCalled', (stubOrSpy) => {
  expect(stubOrSpy).to.be.called;
})

it(`should call Print dialog`, () => {

  /* NOTE: Cannot stub outside of it() */
  let printStub

  cy.window().then(win => {
    printStub = cy.stub(win, 'print')
    cy.contains(selectorForPrintButton, 'Print').click();
    cy.wasCalled(printStub)
  })
})

I just added a small command cy.wasCalled() because it seems (from the docs this section) that the only way to test the stub was to use an expect(...) expression.

Using expect sequentially in the test could be a problem in some scenarios because, as I understand it, expect is synchronous and therefore may fire before some preceding cy commands finish (e.g a click() which invokes animation).

By putting it in a custom command, the expect is effectively added to the command chain. I may have misunderstood something here, but can't find any official Cypress example other than the pattern expect(stub).to.be.called.


If you want to actually open the Print dialog, then close it, you might be able to do it by typing {esc} on document, maybe cy.document().type({esc}). I haven't tried this. - does not work.

If we presume the print dialog is another window, then this answer Access a new window - cypress.io says you can't interact with it.

It does however show how to properly test that the stub was called (see my notes above),

cy.window().its('print').should('be.called')
Richard Matsen
  • 20,671
  • 3
  • 43
  • 77
0

https://stackoverflow.com/a/58553587/1212791 is the right direction.

I also want to share my code with the stub if you are looking for a working example.

describe('Test print', () => {
  beforeEach(() => {
    cy.visit('https://www.abc.net.au/news/2022-07-14/canada-raises-rates-1-percentage-point-could-australia-follow/101239294', {
      onBeforeLoad(win) {
        // Stub window.print functions here
        cy.stub(win, 'print')
      },
    })

  })

  it('click print button should call the print dialog', () => {
    cy.get('button._1KwgR._22AuU').click()
    cy.get('button._1KwgR.vGCs_._2-5J1').click()
    cy.window().its('print').should('be.called')
  })
})
Tim Yao
  • 1,077
  • 1
  • 13
  • 17