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

Global before() and after() hooks are executed multiple times when running tests with Command Line but only one time when running tests with Test Runner #5160

Closed
TomaszG opened this issue Sep 18, 2019 · 6 comments
Labels
type: duplicate This issue or pull request already exists

Comments

@TomaszG
Copy link
Contributor

TomaszG commented Sep 18, 2019

Current behavior:

If user defines global before() or after() hook in the support file (support/index.js) then the hook is executed only one time when running all tests with the Test Runner (npx cypress open => Run all specs button).

However if we run the same code with CLI (npx cypress run) then the global hooks are executed for each .spec file in the suite.

Desired behavior:

Global before() and after() hooks should be run only once per test run.

Steps to reproduce: (app code and test code)

  1. Define global hooks in support/index.js
// support/index.js

(...)

before(() => {
  cy.log('Global Before Hook');
});

after(() => {
  cy.log('Global After Hook');
});
  1. Add multiple spec files
  2. Run all tests with CLI - npx cypress run
  3. Run all tests with Test Runner - npx cypress open => Run all specs button
  4. Check in logs/videos how many times global hooks were executed.

Versions

Cypress 3.4.1

@jennifer-shehane
Copy link
Member

jennifer-shehane commented Sep 18, 2019

The 'Run all specs' doesn't reflect how the tests are run during cypress run. There is an issue open to change this behavior. #1586 So going to close this as duplicate.

The intended behavior is to close and reopen the browser in between each spec file, so the before and after hooks would run once before and after each spec file is run. So the 'Run all specs' button will be changed to reflect this behavior also.

@jennifer-shehane jennifer-shehane added the type: duplicate This issue or pull request already exists label Sep 18, 2019
trotzig added a commit to happo/happo-cypress that referenced this issue May 26, 2020
After a lot of debugging and exploration, I've landed in a fix for the
problem where a Cypress run creates multiple happo reports, one per test
file.

This was first reported last week and to begin with I couldn't repro it.
In short, this was the bug:

When you have multiple test files, Happo creates one report per file,
instead of one combined report.

When running with `cypress open`, the `after` hook was only called once
per full run. But if you ran `cypress run`, the behavior changed to
calling `after` once per test file. There's a bug for this in the
Cypress issue tracker: cypress-io/cypress#5160

To mitigate this, I tried hard to find a place/hook or something where
Cypress would tell me one of these things:
The full suite is done, or
These are the specs in the full run

Either of those would be sufficient enough for our plugin to
conditionally create the Happo report once the `after` hook is called
for the last time. But I couldn't find any of this information available
from Cypress. So I did what Percy.io is doing -- added a wrapper command
that you need to use instead of `cypress run`:

happo-cypress -- cypress run

This call will set up a server locally, invoke the wrapped command,
accept `requestIds` to be POSTed to the server and then finally, once
the wrapped command is done, create the full Happo report.

It's a little unfortunate that we have to go down this route as there's
a lot of complexity involved:
- Users will have to make sure to wrap the Cypress command
- We have to be careful about choosing a good port (for now this is
hard-coded).
trotzig added a commit to happo/happo-cypress that referenced this issue May 26, 2020
After a lot of debugging and exploration, I've landed in a fix for the
problem where a Cypress run creates multiple happo reports, one per test
file.

This was first reported last week and to begin with I couldn't repro it.
In short, this was the bug:

When you have multiple test files, Happo creates one report per file,
instead of one combined report.

When running with `cypress open`, the `after` hook was only called once
per full run. But if you ran `cypress run`, the behavior changed to
calling `after` once per test file. There's a bug for this in the
Cypress issue tracker: cypress-io/cypress#5160

To mitigate this, I tried hard to find a place/hook or something where
Cypress would tell me one of these things:
The full suite is done, or
These are the specs in the full run

Either of those would be sufficient enough for our plugin to
conditionally create the Happo report once the `after` hook is called
for the last time. But I couldn't find any of this information available
from Cypress. So I did what Percy.io is doing -- added a wrapper command
that you need to use instead of `cypress run`:

happo-cypress -- cypress run

This call will set up a server locally, invoke the wrapped command,
accept `requestIds` to be POSTed to the server and then finally, once
the wrapped command is done, create the full Happo report.

It's a little unfortunate that we have to go down this route as there's
a lot of complexity involved:
- Users will have to make sure to wrap the Cypress command
- We have to be careful about choosing a good port (for now this is
hard-coded).
@appanasantosh

This comment has been minimized.

@jprealini
Copy link

@jennifer-shehane I am still trying to find a way to solve workaround this. I opened the feature request #29432 a couple of weeks ago.

One thing I can´t completely understand is why does Cypress run what is supposed to be a global before and after hook (from the support file) actually before and after every spec.... Doesn't each spec have its own "before" and "after" hooks for that?

I would expect, by logic, that the hooks would work something like this:

Support file "before" hook - RUN ONCE AT THE BEGINNING OF THE TEST RUN
Support file "beforeEach" hook - RUN BEFORE EACH SPEC (in case there is some common logic you need to run before every spec ... This is what the global before does now)
Support file "afterEach" hook - RUN AFTER EACH SPEC
Support file "after" hook - RUN ONCE AT THE END OF THE TEST RUN

And this would simplify a lot scenarios where one has to run custom commands to setup data (call apis to populate databases with test data or similar)

Do you think this could be possible to implement?

Thanks

@jennifer-shehane
Copy link
Member

@jprealini If you're running specs in parallel machines, would we run the before spec one time? On which machine? Would the other machines get the effect of that before run?

@jprealini
Copy link

@jennifer-shehane hmm... I guess you have a point there. I didn´t think about that. I was following up on some threads about this same feature requested a few years ago, and I see the before:run after:run events where added to solve this. The caveat here is that if we have some logic that needs to run inside the before:run but which has heavy dependency on Cypress, then we can't run it and we need to refactor/redesign our code to NOT use any cypress commands to be able to run it inside the before:run event...
It would be great to have the chance to make use of cypress (custom commands, cy.request, etc) as part of a "real global before" hook...
In my particular case, I need to hit an api to create test users/customers with a lot of test data, configurations, etc... The whole process consumes about 3 minutes. It's a piece of cake to use cy.request to hit that api.... The only option I have if I want to run that only once and use those customers/users across the whole test run, is using a third party library like Axios or whatever and redo all my code....
Hope that explains the insistence... 😄 In the feature request I created you said this: "I'm not sure if we could hook into this once a spec has begun, so that you could run Cypress tests.... it would require quite a bit of rework anyway" #29432 (comment)

Do you think there is a remote possibility that this could be achieved sooner or later?

Thanks

@jennifer-shehane
Copy link
Member

@jprealini It's not currently something that we're looking at unfortunately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

4 participants