Michal Kurz
Michal Kurz

Reputation: 2094

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?

Upvotes: 0

Views: 1179

Answers (2)

Michal Kurz
Michal Kurz

Reputation: 2094

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.

Upvotes: 1

TesterDick
TesterDick

Reputation: 10560

You're exporting export const getPublicDict... so import it like this

import {getPublicDict} from '../src/my-component'

With this import, the properties show up.

Note, the window object isn't the same in test and app. In component testing they mount the component on the test runner window.

Upvotes: 3

Related Questions