Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cy.document() does not return an HTMLDocument #29569

Open
janakdr opened this issue May 24, 2024 · 4 comments
Open

cy.document() does not return an HTMLDocument #29569

janakdr opened this issue May 24, 2024 · 4 comments
Labels
stage: needs information Not enough info to reproduce the issue

Comments

@janakdr
Copy link

janakdr commented May 24, 2024

Current behavior

The following spec fails:

describe('document() does not produce an HTMLDocument', () => {
  it('produces another document', () => {
    cy.document().then((doc) => {
      console.log('doc is', doc, 'constructor:', doc.constructor.name, 'prototype:', doc.prototype, 'instanceof HTMLDocument', doc instanceof HTMLDocument);
      console.log('window.document is', window.document, 'constructor:', window.document.constructor.name, 'prototype:', window.document.prototype, 'instanceof HTMLDocument', window.document instanceof HTMLDocument);
      expect(window.document).to.be.an.instanceof(HTMLDocument);
      expect(doc).to.be.an.instanceof(HTMLDocument);
    });
  });
});

The window.document is, as expected, an HTMLDocument, but the doc returned by cy.document() is not.

Test failure message:

  1) document() does not produce an HTMLDocument
       produces another document:
     AssertionError: expected '<document>' to be an instance of HTMLDocument

Examining the produced document in the console, it looks exactly like an HTMLDocument, it even has an HTMLDocument constructor, but it's not an instanceof HTMLDocument.

Screenshot 2024-05-24 at 12 23 35 PM

I've seen this behavior as far back as Cypress 10.0.0, so it's not a recent regression.

Desired behavior

return an HTMLDocument from cy.document().

Test code to reproduce

See above. I can reproduce in Chrome and Electron, headed and headless.

Cypress Version

13.10.0

Node version

v18.20.3

Operating System

macOS 14.4.1

Debug Logs

See https://gist.github.com/janakdr/b8b046e5e8f80d18f46ec4dde62c84f8

Other

No response

@jennifer-shehane
Copy link
Member

@janakdr I think this is likely due to the HTML Document beind returned from cy.window() being the document within the iframe of the original document, which contains the Cypress interface.

@jennifer-shehane jennifer-shehane added the stage: needs information Not enough info to reproduce the issue label May 24, 2024
@janakdr
Copy link
Author

janakdr commented May 24, 2024

Thanks for the quick response! The immediate problem this is causing me is that cy.document()((doc) => doc.createElement('input')) does not produce an HTMLElement. My production code (and dependent libraries) interact with the document via document.getElementById and document.createElement. Stubbing those functions out and replacing them with the result of cy.document() used to work, but now one of my libraries (Google Maps) is checking the return type of document.createElement and erroring out because it's not an HTMLElement. Is there a best practice here for dealing with code that calls document.createElement within a Cypress test?

@jennifer-shehane
Copy link
Member

@janakdr I haven't encountered this situation exactly, but to get the window of the application under test, I think you'd want to do

cy.window().then((win) => {
 // work with this win document instead of window.document
})

@janakdr
Copy link
Author

janakdr commented May 24, 2024

My concern isn't the window per se, it's more about having to change all production code to use an injected document (or window) rather than the global document or window, which feels like standard Javascript. All jQuery id-based lookups would also have to be changed to be relative to the injected document.

At a basic level, I'm still unclear on why the document from the iframe shouldn't be an HTMLDocument: it's certainly doing a good imitation of one by saying its constructor.name is HTMLDocument!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stage: needs information Not enough info to reproduce the issue
Projects
None yet
Development

No branches or pull requests

2 participants