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.stub breaks after upgrade to 7.3.0 #16532

Closed
kevzettler opened this issue May 14, 2021 · 9 comments
Closed

cy.stub breaks after upgrade to 7.3.0 #16532

kevzettler opened this issue May 14, 2021 · 9 comments
Assignees
Labels
CT Issue related to component testing

Comments

@kevzettler
Copy link

kevzettler commented May 14, 2021

Current behavior

I am migrating a project from 6.5.0 to 7.3.0 The project has a large test suite. After installing 7.3.0 many previously successful tests are failing. After investigation it appears that the behavior of cy.stub has changed.

The existing tests have many 'module' stubs like:

const AuthProvider = require('../../../../src/providers/Auth'); 
cy.stub(AuthProvider, 'login', (email, password, callback) => {
    callback("hard value", undefined)
})

When the test is run this stub never gets called and the default AuthProvider.login function gets called. So the stub does nothing.

this stack overflow question demonstrates the same issue https://stackoverflow.com/questions/61944433/how-to-stub-a-module-function-with-cypress

Desired behavior

The behavior should be consistent with 6.5.0 I'm not seeing any documentation on this breaking change to cy.stub or how to stub modules like this.

Versions

$ node -v
v10.23.0
$ npm -v
6.14.8
$ cypress -v
Cypress package version: 7.3.0
Cypress binary version: 7.3.0
Electron version: 12.0.0-beta.14
Bundled Node version: 14.15.1

@lmiller1990
Copy link
Contributor

lmiller1990 commented May 17, 2021

cy.stub has (or certainly should not) have changed between 6.5 and 7.3. Is it consistently broken, or just for some examples? If you can provide a minimal repository showing the issue, that would be great.

@kevzettler
Copy link
Author

kevzettler commented May 17, 2021

To further clarify this is happening specifically in component tests. and these component tests are also in a migration from
"cypress-react-unit-test": "^4.17.2", to "@cypress/react": "^5.6.0"

I suspect that the mount function for component tests is different. Seems the component tests are now mounted in a separate scope and do not share scope with the stubbed modules. I'll try making a minimal repo but may take some time

@lmiller1990
Copy link
Contributor

lmiller1990 commented May 18, 2021

Knowing it's with the component testing runner is useful information. The mount function is the same, but the underlyling architecture changed (from webpack-preprocessor to webpack-dev-server). That might have introduced the regression.

Can you share the contents of ../../../../src/providers/Auth? That should be enough to go on. For now I'll try to reproduce it with the information here.

@lmiller1990
Copy link
Contributor

lmiller1990 commented May 18, 2021

I tried reproducing as best I could: see here. I could not reproduce - but it's likely the problem is project configuration. In my case, the stub was called.

When I copy pasted your example, my IDE gave me deprecation error around the cy.stub syntax. I changed it to what was recommended. Here's my full test code:

const React = require('react')
const { mount } = require('@cypress/react')
const { CyStub } = require('./CyStub.jsx')
const AuthProvider = require('./auth.js')

describe('cy.stub', () => {
  let calls = 0

  beforeEach(() => {
    cy.stub(AuthProvider, 'login').callsFake(() => {
      calls += 1
    })
  })

  it('should stub commonjs require', () => {
    mount(<CyStub />)
    cy.get('button').click().then(() => {
      expect(calls).to.eq(1)
    })
  })
})

If you can provide a minimal reproduction of the problem you are having, I can take a look.

@FelipeLahti
Copy link

Hi @lmiller1990
Here's a reproducible example:
FelipeLahti/cypress-react-component-example@7e7136d#diff-627a97a066b275dbbf813f6dafd9c9650279f8f3eb66d1a3a23cd62016cfc7b8

It's a fork from https://github.com/bahmutov/cypress-react-component-example

Stubbing the function calculate doesn't work using create react app.

//App.js
import { calculate } from './anModule';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>{calculate()}</p>
      </header>
    </div>
  );

//App.spec.js
import * as anModule from './anModule'

it('renders total is 10', () => {
  mount(<App />)
  cy.contains(/total is 10/i)
})

it('renders total is mocked value', () => {
  cy.stub(anModule, 'calculate').returns('total is 25')
  mount(<App />)
  cy.contains(/total is 25/i)
})

@p-christ
Copy link

i am also seeing a similar problem and have documented it here

@andymerskin
Copy link

andymerskin commented Jan 20, 2022

I tried following this official example for mocking imports by adding @babel/plugin-transform-modules-commonjs in my Craco configuration on CRA 5, to allow module exports to be overwritten by stubs:

// craco.config.js
module.exports = {
  babel: {
    plugins: [
      [
        '@babel/plugin-transform-modules-commonjs',
        {
          loose: true,
        },
      ],
    ],
  },
};

And ended up getting this error for basically every module in my application:

Module not found: Error: You attempted to import /ExampleProject/node_modules/@babel/runtime/helpers/interopRequireDefault.js which falls outside of the project src/ directory. Relative imports outside of src/ are not supported.
You can either move it inside src/, or add a symlink to it from project's node_modules/.

Link to example:
https://github.com/cypress-io/cypress/tree/master/npm/react/cypress/component/advanced/mocking-imports

@lmiller1990
Copy link
Contributor

lmiller1990 commented Jan 25, 2022

There error you are describing is actually a limitation of Create React App, see here for more. They talk about the ModuleScopePlugin here.

We actually modify the webpack config on the fly to support importing from cypress directories, that happens here.

We definitely need to investigate how we can handle stubbing ES modules. Transpiling to commonjs is one approach, I don't think it's a good long term solution, though. That said, if you do keep going down this route and remove that CRA limitation, you should be able to get this to work.

@lmiller1990 lmiller1990 added CT Issue related to component testing and removed component testing labels Aug 15, 2022
@rockindahizzy
Copy link
Contributor

Closing this issue. Please follow #22355 for updates on ES module mocking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CT Issue related to component testing
Projects
None yet
Development

No branches or pull requests

6 participants