cypresssinonstubbinggtag.jsgoogle-optimize

In a Cypress test how can I stub argument of a function


I am writing a Cypress integration test for a Google Optimize experiment and I would like to stub the experiment variant value provided by gtag library.

The value is provided as the argument of callback for this function:

gtag('event', 'optimize.callback', {
    name: '<experiment_id_A>',
    callback: (value) => 'unknown',
 });

How can I stub argument "value"? (without stubbing the callback return)

--

Docs for:


Solution

  • I don't know much about gtag, but looking at the reference page it may be possible to stub if you are using the "external" function pattern shown on that page rather than the "inline" function you have above.

    The way to stub internal functions in a React or other framework is to expose it on the window object.

    function implementExperimentA(value) {
      if (value ==  '0') {
        // Provide code for visitors in the original.
      } else if (value == '1') {
        // Provide code for visitors in first variant.
      } else if (value == '2') {
        // Provide code for visitors in section variant.
      }
      ...
    }
    
    if (window.Cypress) {
      // Cypress is active
      console.log('referencing "implementExperimentA" on window')
      window.implementExperimentA = implementExperimentA;
    }   
    
    gtag('event', 'optimize.callback', {
        name: '<experiment_id_A>',
        callback: implementExperimentA
     })
    

    Then in the test, you might set up the stub in the beforeLoad event

    cy.visit('http://localhost:3000', {
      onBeforeLoad(win) {
        // Stub your functions here
        cy.stub(win, 'implementExperimentA').callsFake((realValue) => {
          const mockValue = 'abc'
          console.log(`implementExperimentA called with ${realValue}, subbing ${mockValue}`)
          return window.implementExperimentA(mockValue)
        })
      },
    })
    

    This should instantiate the stub at the earliest point in the page load, provided the reference has been set up.

    Check the console.logs are firing in the right order, if not then there might be a delay in referencing the function and you can choose the stub point with cy.window().

    cy.visit('http://localhost:3000')
    
    ...
    
    cy.window().then(win => {
      // Stub your functions here
      cy.stub(win, 'implementExperimentA').callsFake((realValue) => {
        const mockValue = 'abc'
        console.log(`implementExperimentA called with ${realValue}, subbing ${mockValue}`)
        return window.implementExperimentA(mockValue)
      })
    })