Open rafael-anachoreta opened 6 years ago
I found that this happened when you visit url which is different to baseUrl in config.
I met the same bug.
In my case, it's worth noting that before
code runs twice only when all specs are run at once (ie click on Run all specs
). When run one by one, each spec behaves as expected.
@dirtyhenry Any code provided within the support
file will run before each spec file as documented here: https://on.cypress.io/writing-and-organizing-tests#Support-file
Hey @rafael-anachoreta, thank you for providing this great detail on this issue.
I have confirmed that indeed, these cy.task()
commands are running twice, which is unintended behavior. I've also confirmed that this bug is only present when baseUrl
is not defined.
I imagine this has to do with how we handle visiting sites when no baseUrl
is defined. See an explanation of this behavior here.
Workaround Today Provide a baseUrl
within your Cypress configuration
Hi @jennifer-shehane: I don't really understand your message since none of my code is in the support
file.
@jennifer-shehane same behaviour is when baseUrl
is defined but I want to visit other page. Ie. I set baseUrl='https://www.google.com/'
and in my test will do cy.visit('https://duckduckgo.com/')
then all before commands will run twice.
@dirtyhenry Sorry for not being clear. If you want code to run only once before each spec file as opposed to before each test, make sure to place the before
hook within your support file.
Hello everyone,
Any update ? In my case I am using cy.task()
to load/unload data in database using the before/after hooks, so it is causing unexpected behavior.
@jennifer-shehane Do you know of any workarounds other than setting baseUrl
?
I have the same issue even when baseUrl is set to http://localhost:3000.
I'm using this hack to avoid running the commands twice
in the cypress.json file I have
"firstRun": true
and in the in support index.js:
beforeEach(function() {
if (Cypress.config("firstRun")) {
cy.exec("your command");
Cypress.config("firstRun", false);
}
});
afterEach(function() {
Cypress.config("firstRun", true);
});
Totes looking forward to this fix! 😱🙊
Tried the Cypress.config("firstRun") workaround and baseUrl in config but still executes twice 😭
@jamesalexmorgan same here. still an issue for me. any workaround?
Have the same issue and can't set baseUrl because tests running in several environments. My workaround is setting baseURL in plugin file.
plugins/index.js
module.exports = (on, config) => {
const env = config.env.environment;
const url = config.env[env].url;
config.baseUrl = url;
return config
}
cypress.env.json
"env1": {
"url": "https://url.env1.com"
},
"env2": {
"url": "https://url.env2.com"
}
and runing commands
npx cypress run --env environment=env1
npx cypress open --env environment=env2
Have the same issue and can't set baseUrl because tests running in several environments. My workaround is setting baseURL in plugin file.
plugins/index.js
module.exports = (on, config) => { const env = config.env.environment; const url = config.env[env].url; config.baseUrl = url; return config }
cypress.env.json
"env1": { "url": "https://url.env1.com" }, "env2": { "url": "https://url.env2.com" }
and runing commands
npx cypress run --env environment=env1 npx cypress open --env environment=env2
Good job, thanks! 👍
I'm doing a full-cycle registration test in which a confirmation email is sent, then a task is triggered to open the email and find a confirmation link (with a domain different from the one set in baseUrl) in the inbox. Once the link is found, cy.visit(confirmationLink)
results in the test being run twice.
Really hope to see a feasible workaround for this.
@jennifer-shehane I see that you have labeled this as the intended workaround. However, have you seen occasions where this workaround does not work? It seems like I am not the only one who is unable to get this duplicate behavior to stop even when setting a baseUrl in the cypress.json
file
Had the same issue and realized it was because my beforeEach was an async function
I'm doing a full-cycle registration test in which a confirmation email is sent, then a task is triggered to open the email and find a confirmation link (with a domain different from the one set in baseUrl) in the inbox. Once the link is found,
cy.visit(confirmationLink)
results in the test being run twice.Really hope to see a feasible workaround for this.
@jennifer-shehane have You any idea how this could work? I have this same issue. And next case - i have this same problem in CI, when tests are running in pipeline.
Another example of this behavior is with people who set the baseUrl
dynamically. Mentioned in this issue: https://github.com/cypress-io/cypress/issues/3454
Having no baseUrl
set in cypress.json
, this code runs the task twice.
it('Should only log once', () => {
cy.task('log', 'running!')
Cypress.config('baseUrl', 'https://docs.cypress.io')
cy.visit('/')
})
A more realistic example is someone dynamically generating this url
Cypress.config('baseUrl', `https://${getOrigin()}.cypress.io`)
This is currently the best workaround in this situation I believe: https://github.com/cypress-io/cypress/issues/2777#issuecomment-668497010
I have the same issue however, I am using a before statement with a request statement to an api with a cypress custom command to create a user then beforeEach test case logs that newly created user in on the website that I'm building scripts on cypress for. So when this is running it creates two new users every time, sometimes it logs in the first user.
before(()=> cy.createAccount()); beforeEach(()=>cy.login()); it("test case"()=> cy.get("button").click(); )
I have the below for the config on support/index.js
module.exports = (on, config) => { const url = config.env["api"].url; config.baseUrl = url; return config; }
Where the config.env.json
{ "api":"url used in api create user" }
What's the eta on this to be completed? Otherwise, the database holding the users will be full in no time!
This is expected behavior based on the way we switch the top superdomain. We could forcibly restrict the before
from running when the top domain switches, but avoiding it would result in different breaking and unexpected behavior.
Thanks for getting back to me @brian-mann , Do you have any suggestions for this not to run basically twice?
I have my baseUrl set in my cypress.json and it still runs twice. For me, this is definitely specific to logic running cy.visit("different url from baseUrl") within a custom Command. It doesn't run everything twice, just the test case that calls the custom Command that invokes the cy.visit.
I'm doing a full-cycle registration test in which a confirmation email is sent, then a task is triggered to open the email and find a confirmation link (with a domain different from the one set in baseUrl) in the inbox. Once the link is found,
cy.visit(confirmationLink)
results in the test being run twice. Really hope to see a feasible workaround for this.@jennifer-shehane have You any idea how this could work? I have this same issue. And next case - i have this same problem in CI, when tests are running in pipeline.
I have not found a better solution than to make the fake first visit so that cypress understands which domain he needs to visit and so that he does not make visit twice to confirmation URL.
it('Confirm email', () => {
cy.task('loadData').then((userData) => {
// HACK: This visit is required.
// Сypress has a bug/feature that after changing the domain
// (in our case from yopmail in previous test to baseUrl in this test),
// it goes to the url specified in the first visit twice.
// This usually does not cause problems, but since we have an email confirmation URL,
// we cannot click on this link twice.
cy.visit('/');
cy.visit(userData.confirmUrl);
cy.contains('You have just used your one-time login link. Your account is now active and you are authenticated.');
})
})
Disabling the following setting in the cypress.config.ts helped me: testIsolation: false
Based on suggestions of using plugin file...
Adding the baseUrl
adjustment to setupNodeEvents
didn't help. setupNodeEvents
itself is being ran twice (When ran via Github Actions).
In the local development environment, I found that this double execution of a cy.request to a test data endpoint only occured when running Cypress in the CLI. With the GUI it runs just once. I managed to fix this by setting a baseUrl with its value being the same as our test data endpoint. However, the same trick will not work when running Cypress in GitLab. It's still executed twice there.
It's kind of crazy that this has been an issue since 2018.
I believe I have encountered the same bug when running component tests, is the baseUrl
workaround also recommended then? In my case I have set retries: { runMode: 1, ,
which sometimes causes cypress to run two attempts at once (very flaky behavior):
Based on suggestions of using plugin file...
Adding the
baseUrl
adjustment tosetupNodeEvents
didn't help.setupNodeEvents
itself is being ran twice (When ran via Github Actions).
I'm also encountering this issue. I have baseURL is set in cypress config, and tests are being executed twice in GitHub Actions.
Also encountering the same issue, commenting to increase visibility
Currently working on this bug at my company. If we can't find a workaround, we're switching to Playwright.
Current behavior:
Right now, whenever you start Cypress it will kick off some of the commands twice.
This isn't a problem most of the time as tests should be self contained anyway, but if you are using before hooks (for instance, to login and store cookies, as suggested by the docs) it becomes quite detrimental.
Desired behavior:
Cypress should only run once.
Steps to reproduce:
Results:
────────────────────────────────────────────────────────────────────────────────────────────────────
Running: __bug.spec.js... (1 of 1)
Bug I'm running! I'm running! ✓ Should only log once (1159ms)
Results:
If the commands are inverted (i.e., if you visit() before logging) then the results are fine, so maybe Cypress waits for visit then reboots?
Versions
Electron 59 headless Cypress 3.1.1 macOS High Sierra 10.13.6