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

Cypress aliases are not refreshed before assertion #5153

Closed
TomaszG opened this issue Sep 17, 2019 · 9 comments
Closed

Cypress aliases are not refreshed before assertion #5153

TomaszG opened this issue Sep 17, 2019 · 9 comments
Labels
stage: proposal 💡 No work has been done of this issue

Comments

@TomaszG
Copy link
Contributor

TomaszG commented Sep 17, 2019

Current behavior:

Cypress aliases refer to old DOM state when they're fetched/asserted in the test which leads to the assertions like below passing:

(...)
cy.get('@rows')
  .should('have.length', 2)

  .get('@rows')
  .should('have.length', 3);

Apparently first assertion is passing because of the cached DOM, and second one passes because alias gets refreshed as first try fails silently

Desired behavior:

Aliases should refer to the actual DOM state when they're used in the test.

Steps to reproduce:

  1. clone https://github.com/TomaszG/cypress-issue-5153
  2. npm i
  3. npm run start
  4. npx cypress run

Versions

Cypress 3.4.1
Chromium 78
macOS 10.14.6

@TomaszG
Copy link
Contributor Author

TomaszG commented Sep 20, 2019

Well, I wouldn't call it a fix, rather workaround which may not be valid for all scenarios as, e.g. in my tests I prefer pointing aliases at the elements which number is changing dynamically (and can have various parents). Also, if the alias is a reference pointing at some DOM elements then I believe it should reflect the current DOM state. What's more, there's some inconsistency in the behaviour - if I had removed the row instead of adding it, the alias would be working fine, is that right?

If this cannot be easily fixed maybe it's worth to provide users an option to refresh the alias as an option for the get('@alias') method?

@TomaszG
Copy link
Contributor Author

TomaszG commented Oct 3, 2019

It seems to be quite similar to that one #2971. Do you know how I can get a selector from alias? I was thinking about overwriting get() command and add to it an option to fetch the DOM using selector referenced by alias.

@TomaszG
Copy link
Contributor Author

TomaszG commented Oct 4, 2019

So I have the following piece of code which fails because of the issue mentioned in the ticket (previously @errormessages alias points to 2 elements, however, at this point there's only one such element)

(...)
  // then
  .get('@errorMessages')
  .should('have.length', 1)
  .and('have.text', expectedErrorMessage)

According to your advice, I tried the workaround in the test which worked fine:

  // then
  .get('@errorMessages').then(element => {
    cy.get(element.prevObject.selector)
      .should('have.length', 1)
      .and('have.text', expectedErrorMessage)
    })

So I tried to make it generic:

Cypress.Commands.overwrite('get', (originalFn, selector, options) => {
  if (selector.startsWith('@') && options && options.refereshAlias) {
    cy.get(selector).then(element => originalFn(element.prevObject.selector, options));
  }
  return originalFn(selector, options);
});

However, now when I run the test, even without providing refereshAlias option (so code inside the if instruction is not executed) I get the following error during execution one of get('@someOtherAlias') commands:

CONTAINS Object{5}
CypressError: cy.contains() can only accept a string, number or regular expression.

which doesn't make sense, as error comes up from get('@someOtherAlias') command (checked with debug()).

EDIT:

Also, I've noticed that element.prevObject.selector doesn't return "full" selector in a case when the alias was defined inside within(() => {}) block or was a result of e.g. find() command.

@jennifer-shehane jennifer-shehane added the stage: proposal 💡 No work has been done of this issue label Oct 25, 2019
@jennifer-shehane
Copy link
Member

We currently don't requery the DOM for aliased elements, as noted above from https://docs.cypress.io/guides/core-concepts/variables-and-aliases.html#Elements

I would consider this a duplicate of the proposal in #2971 Can we close this issue in favor of that please?

@TomaszG
Copy link
Contributor Author

TomaszG commented Oct 30, 2019

Sure thing, closing it now, thanks!

@TomaszG TomaszG closed this as completed Oct 30, 2019
@cypress-io cypress-io locked and limited conversation to collaborators Dec 31, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
stage: proposal 💡 No work has been done of this issue
Projects
None yet
Development

No branches or pull requests

3 participants
@TomaszG @jennifer-shehane and others