reactjscypresscypress-component-test-runnerwindow-object

In Cypress component tests, changes to window object made inside component render cycle do not persevere


I need to expose some of my component's internals to Cypress component tests via window object, but I'm failing to pass and read it properly. Consider this code:

// component
import React, { FC } from 'react'

(window as any).publicDictionary = { }
export const getPublicDict = () => (window as any).publicDictionary
const addToPublicDict = (id: string) => (window as any).publicDictionary[id] = true

addToPublicDict('foo')

export const MyComponent: FC = () => {
   addToPublicDict('bar')
   return null
}
// test
it('Applies default value', () => {
   mount(<MyComponent/>)

   const dict = getPublicDict();

   cy.log({
      window,
      dict,
      foo: dict.foo,
      bar: dict.bar,
      dictKeys: Object.keys(dict),
   } as any)
})

This code behaves very weirdly when inspected via Chrome devtools: enter image description here

... when logging publicDict directly, both foo and bar properties seem to be present - but when I try to access them, bar turns out to be undefined, because it was set inside the component's render cycle. foo, on the other hand, can be read and accessed as expected.

What is going on? What can I do to successfully pass my component's internals to Cypress in component tests?


Solution

  • I haven't found the cause, but I found the solution.

    window object only works properly for me, when I access it while chained after cy.window command:

    import { getPublicDict } from './utils'
    
    // This works:
    it('works', () => {
      cy.window().then(() => {
        // Here, window and its properties work as expected
        const dict = getPublicDict();  
      })
    })
    
    // This doesn't:
    it('works', () => {
      // Here, window tends to get quite quirky
      const dict = getPublicDict(); 
    })
    

    This way it works well - I don't even have to use the window object yielded by cy.window - it's sufficient I access window while chained after cy.window.

    If anyone knows why this is, I'm curious.