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

Alias created in before() only works on first test (but it's only used in the second test) #5351

Closed
dsesami opened this issue Oct 11, 2019 · 7 comments
Labels
type: duplicate This issue or pull request already exists

Comments

@dsesami
Copy link

dsesami commented Oct 11, 2019

Update 10/16: See #5351 (comment) for a clearer example and explanation.

Original Post Below This Line

------------------------------------------

This appears to be really similar to #2766 (and #665 in turn), but it seems like it's a bit different. The alias definition exists, like user as an object exists, and user.id exists, but the value of user.id is null.

Note that an alias created within the second test doesn't appear to work --

it('does something', function () {
  cy.createUser('xyz').as('user') // createUser is an exec() outside of the application
  this.user.something... 
    // expected this to be available, 
    // as this works if I stuck it into a beforeEach 
    // on any test, or a before on the first test
})

Current behavior:

The before() hook contains an alias. I would expect this to have this.user available as an object. If it is in the first test (I copy and move the test to the top), the test works. However, after the first test, this.user exists, but its value is empty and undefined.

Desired behavior:

I would expect this.user to remain a consistent object available throughout each test in the spec file. I can currently get around this with cy.createUser().then((user) => ), but that's why I wanted to use aliases in the first place. Alternatively, I'd expect an alias to be create-able within a test.

Steps to reproduce:

Test setup:

before(function() {
  cy.createUser('foo').as('user') // returns an object that has a value called user.id
})

it('is the first test') {
 // nothing happens here
}

it('is a second test') {
  cy.visit(`/users/${this.user.id}`)
}

Versions

Latest cypress (Oct 11 2019), chrome, fedora.

If you need more info, please feel free to ask.

@dsesami dsesami changed the title Alias created in before() only works on first test Alias created in before() only works on first test (but it's only used in the second test) Oct 11, 2019
@jennifer-shehane
Copy link
Member

@dsesami Can you provide an example of this behavior that we can run completely on our machines? We do not know what is happening within your custom createUser for example so cannot run this code to prove your theory. Please provide the complete code we can run to look into your issue - which tests are failing that should not fail. Thanks!

@dsesami
Copy link
Author

dsesami commented Oct 16, 2019

@jennifer-shehane here's a simpler example with the example tests that are generated with cypress initialization. npx cypress open on an empty directory will generate tests, and then you can substitute this following code in window.spec.js.

 /// <reference types="Cypress" />
 
 context('Window', () => {

    // new function
    before(() => {
      cy.visit('https://example.cypress.io/commands/window')
      cy.get('h1').as('obj') // here's the alias
    })  
    beforeEach(() => {
      cy.visit('https://example.cypress.io/commands/window')
    })  
 
    it('cy.window() - get the global window object', () => {
      // https://on.cypress.io/window
      cy.window().should('have.property', 'top')
      cy.get('@obj').value // calling this alias works
    })  
 
    it('cy.document() - get the document object', () => {
      // https://on.cypress.io/document
      cy.document().should('have.property', 'charset').and('eq', 'UTF-8')
      cy.get('@obj').value // calling this alias doesn't work
    })  
  })

Here's a screenshot:
Screenshot from 2019-10-16 12-19-00

Note that the alias is cleared after the first test when using before(). It feels like it should remain persistent; the point of before() is to do some setup before the test suite begins that remains static throughout all tests. I do understand that we want test isolation, but it feels weird that triggering an alias in before() just works for the first test. It'd probably be better to either:

  1. Throw an error and prohibit aliases in before(), and only allow them in beforeEach()
  2. Allow aliases created in before() to persist across tests. I'm putting it in a before() block specifically to save on API calls (as it's not changing).

@dsesami
Copy link
Author

dsesami commented Oct 22, 2019

@jennifer-shehane this is just a light ping, wondering if you've had a chance to look this over. Thank you!

@ronaiza-cardoso
Copy link

Hello, I'm having this issue too. I noticed that the alias inside the before hook just works if we have only one test.

"cypress": "^3.4.1",

node: v10.13.0
npm: 6.4.1

@jennifer-shehane
Copy link
Member

before code is only run once, and between the tests Cypress removes all of the aliases. So in subsequent tests it is not available.

Moving this code into a beforeEach will work.

Closing as duplicate of #665

@dsesami
Copy link
Author

dsesami commented Oct 25, 2019

@jennifer-shehane as this is apparently a very regularly-duplicated issue, may I suggest that the docs be updated to specify this nuance? Many users get tripped up by it.

@jennifer-shehane
Copy link
Member

@dsesami We updated the scope of the original issue to issue a warning when defining an alias in a before, please direct all comments to the original issue. #665 (comment)

@jennifer-shehane jennifer-shehane added the type: duplicate This issue or pull request already exists label Jan 3, 2020
@cypress-io cypress-io locked and limited conversation to collaborators Jan 3, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type: duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

3 participants