cypress-io / cypress

Fast, easy and reliable testing for anything that runs in a browser.
https://cypress.io
MIT License
46.62k stars 3.16k forks source link

Watch non-spec files for changes and reload specs #456

Open brian-mann opened 7 years ago

brian-mann commented 7 years ago

Many of our users express the need to want to watch files on their system other than the *spec files that we normally watch.

Although we currently watch the spec file you're currently working in (and all of the subdependencies) many of our users express the need to watch other files (like their src files) for e2e/integration tests.

We should do one or both options:

a) give you the ability to specific additional glob paths via cypress.json b) give you the ability to watch things yourself and signal to cypress when to reload

With our upcoming CLI refactor we could offer something like this...

const chokidar = require('chokidar')
const cypress = require('cypress')

chokidar.watch(FILES)
.on('update', () => {
  cypress.reload()
})

cypress.open()
jagreehal commented 7 years ago

Allowing the user to configure using glob patterns would be awesome.

collinstevens commented 5 years ago

Is this looking to be picked up anytime soon? Having a glob pattern specified for /src/ would be incredibly useful when doing TDD with e2e tests.

bahmutov commented 5 years ago

@collinstevens for now you can use this plugin to watch arbitrary files and rerun the tests https://github.com/bahmutov/cypress-watch-and-reload

Shuunen commented 5 years ago

Hey @bahmutov , I didn't manage to have your plugin working.

Anyway I ended up putting this into my app source js :

if (module && module.hot) {
  const btn = window.top.document.querySelector('.reporter .restart')
  if (btn) {
    btn.click()
  }
}

Now I can TDD 🎉 :

Hope that will help others, it's too bad Cypress is not TDD ready out of the box 😢

bahmutov commented 5 years ago

Why didn’t the plugin work? Could you open an issue in the plugin repo

Sent from my iPhone

On Jun 8, 2019, at 13:17, Romain Racamier notifications@github.com wrote:

Hey @bahmutov , I didn't manage to have your plugin working.

Anyway I ended up putting this into my app source js :

if (module && module.hot) { const btn = window.top.document.querySelector('.reporter .restart') if (btn) { btn.click() } } Now I can TDD 🎉 :

if I change a js source file, cypress reload tests (with this fix) if I change a js test file, cypress reload tests (out of the box) Hope that will help others, it's too bad Cypress is not TDD ready out of the box 😢

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

Shuunen commented 5 years ago

Could you open an issue in the plugin repo ?

Sure, here it is : https://github.com/bahmutov/cypress-watch-and-reload/issues/20

jsphstls commented 4 years ago

I only need to re-run tests if Cypress's browser was reloaded by HMR. I do not want Cypress to watch for file changes because HMR already does that for me. HMR actually determines whether the preview window needs a reload since not every src file is a dependency of what is being previewed (such as in a monorepo).

Basically, if the browser window reloaded on its own, re-run the tests.

kuceb commented 4 years ago

Reloading alongside webpack-dev-server

@jsphstls This is what I use: I listen for webpack-dev-server HMR logs in the console, and trigger a re-run, as described here https://stackoverflow.com/questions/52231111/re-run-cypress-tests-in-gui-when-webpack-dev-server-causes-page-reload/57980326#57980326

Edit: But you should use Svish's package below

Svish commented 4 years ago

The method shared by @Bkucera doesn't work for me, as there's no such message being printed in the console. Agreeing with @jsphstls, that HMR already keeps track of changes, I decided to try hook into that. Ended up putting the result of the experiment in a simple package, and it seems to work pretty well on my machine with create-react-app at least 🙂👍

It connects to the webpack-dev-server socket and listens for HMR messages of type invalid, and if any arrive, it clicks the restart button after a short delay.

https://www.npmjs.com/package/cypress-hmr-restarter

kentcdodds commented 4 years ago

@Svish's package worked for me 👍 Thanks!

jpbourgeon commented 4 years ago

@cypressTeam

You should consider putting Svish's plugin (or an equivalent) forward. Maybe by making it an official plugin or referencing it somewhere ? It's simple yet effective and helps cypress achieve a true TDD experience:

amannn commented 4 years ago

I'm also really interested in this feature!

For me the package from @Svish sadly didn't work. I'm using Storybook, maybe the hot reloading is setup differently there.

However I got it working with this snippet:

// Re-run tests when source files change.
// Workaround for https://github.com/cypress-io/cypress/issues/456
Cypress.on('window:before:load', window => {
  const { XMLHttpRequest } = window;
  const originalOpen = XMLHttpRequest.prototype.open;
  XMLHttpRequest.prototype.open = function open(...args) {
    this.addEventListener('load', function load() {
      if (this.url.endsWith('hot-update.json')) {
        cy.$$('.stop', window.top.document).click();
        cy.$$('.restart', window.top.document).click();
      }
    });
    originalOpen.apply(this, args);
  };
});

I noticed that pressing the stop button before restart can be helpful if there's currently a test running.

EDIT: The same works for me with Next.js

jennifer-shehane commented 4 years ago

@Svish Could you open a pull request to add this plugin to our documentation? Thanks! Instructions here.

Svish commented 4 years ago

@jennifer-shehane Sure! Will try to get it done in the next few days 🙂

Zwimber commented 4 years ago

Anyone coming here for TDD on Angular @Bkucera's answer works brilliantly. Adding the "stop" to it from @amannn's answer for this brilliant TDD solution!

Cypress.on('window:before:load', (win)=>{
  const _consoleInfo = win.console.info
  win.console.info = function () {
    if (arguments[0].includes('App updated.')) {
      cy.$$('.stop', top.document).click()
      cy.$$('.restart', top.document).click()
    }
    return _consoleInfo.apply(win.console, arguments)
  }
})
Svish commented 4 years ago

For those here who tried out my cypress-hmr-restarter plugin, I finally got around to add the "pre restart stopping feature" (like @amannn also suggested). Tested it with our app here, and seems to work great. 🙂 👍

herrmannplatz commented 3 years ago

Whoever didnt had luck with @Svish awesome cypress-hmr-restarter plugin might wanna recheck it. It also works now with projects which use webpack-hot-middleware plugin (e.g. gatsby, nuxt?!? havent tested it)

strowk commented 3 years ago

@Svish plugin did not work for me right away and I created PR to fix https://github.com/Svish/cypress-hmr-restarter/pull/13 .

Svish commented 3 years ago

@strowk PR accepted, and also added an option to allow for overriding the URL completely.