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

feat: Add 'type' option to .as to store aliases by value #25251

Merged
merged 13 commits into from
Jan 24, 2023

Conversation

BlueWinds
Copy link
Contributor

@BlueWinds BlueWinds commented Dec 21, 2022

User facing changelog

.as() now accepts an options argument, allowing test writers to store an alias as a "query" or "static".

A "query" alias (the default) re-quries the application for the current state whenever retrieved - it's a 'live' value.
A "static" alias is stored once, when the alias is created - it's a static value, and will never update.

Don't store DOM references as 'value's.

Additional details

it('allows users to store a static value', () => {
  const obj = { foo: 'bar' }

  cy.wrap(obj).its('foo').as('value', { type: 'static' })
  cy.wrap(obj).its('foo').as('query', { type: 'query' })

  cy.then(() => {
    obj.foo = 'baz'
  })

  cy.get('@value').should('eq', 'bar')
  cy.get('@query').should('eq', 'baz')
})

Steps to test

How has the user experience changed?

Before:
image

After:

Aliases are query by default. If the user sets the type to static, then it is included in the command log.

image

PR Tasks

@cypress-bot
Copy link
Contributor

cypress-bot bot commented Dec 21, 2022

Thanks for taking the time to open a PR!

@cypress
Copy link

cypress bot commented Dec 21, 2022



Test summary

4361 0 880 0Flakiness 7


Run details

Project cypress
Status Passed
Commit 0bdb731
Started Jan 24, 2023 3:34 PM
Ended Jan 24, 2023 3:50 PM
Duration 15:43 💡
OS Linux Debian -
Browser Multiple

View run in Cypress Dashboard ➡️


Flakiness

commands/net_stubbing.cy.ts Flakiness
1 network stubbing > intercepting request > can delay and throttle a StaticResponse
2 ... > with `times` > only uses each handler N times
3 ... > stops waiting when an xhr request is canceled
cypress/cypress.cy.js Flakiness
1 ... > correctly returns currentRetry
2 ... > correctly returns currentRetry
This comment includes only the first 5 flaky tests. See all 7 flaky tests in the Cypress Dashboard.

This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. You can manage this integration in this project's settings in the Cypress Dashboard

@@ -42,7 +58,7 @@ export default function (Commands, Cypress, cy) {

if (!alreadyAliasedLog && log) {
log.set({
alias,
alias: `@${alias}${options.type ? ` (${ options.type })` : ''}`,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
alias: `@${alias}${options.type ? ` (${ options.type })` : ''}`,
alias: `@${alias}${options.type ? ` (${ options.type })` : '(query)'}`,

the default is type query, so why not set this as the fallback?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Take a look at the "After" screenshot it the PR description, showing how it looks with (value) tagged onto the end - it's a bit visually busy, so I was trying to avoid it in the default case. If the user sets it explicitly - whether it be query or value - then it'll show up in the command log.

Can definitely make it always display if we like, just 'display less by default' was my intention here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@BlueWinds Because these wouldn't align

.as('name')
.as('name', { type: 'query' }

Could we only prepend when the non-default is used (i.e. only when type === value)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be helpful to also add this type to the dev tools log details when clicking a log that is referencing an alias to provide the in-depth context to how the alias value is resolved.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed it to be consistent, always displaying value and never displaying query; see updated screenshot in the PR description.

I'm going to push back against adding it to the console props for .get() when an alias is retrieved - the "type" of an alias is a property of how it's stored, not how it's retrieved, so we should display it where it's stored (which we do).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation PR says the type impacts how the value is retrieved later in the test. 😅


export default function (Commands, Cypress, cy) {
Commands.addQuery('as', function asFn (alias) {
Commands.addQuery('as', function asFn (alias, options = {} as Partial<Cypress.AsOptions>) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd expect to use Cypress.AsOptions directly . Should be able to if the keys are optional.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I opted here for consistency. Pre-existing commands all use Partial<> in this context, and do not have optional properties.

as(alias: string, options?: Partial<AsOptions>): Chainable<Subject>
blur(options?: Partial<BlurOptions>): Chainable<Subject>
check(options?: Partial<CheckOptions>): Chainable<Subject>

...snip...

  interface CheckOptions extends Loggable, Timeoutable, ActionableOptions {
    interval: number
  }

Removed the optional-ness of AsOptions.type it , since we have Partial<> everywhere AsOptions is used.

*/
action: 'select' | 'drag-drop'
type?: 'query' | 'value'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pulling comment forward from the docs - worth getting other opinions on I think.

These types seem very specific to element queries and context sharing. The query type seems like an odd name for aliasing requests or intercepts since they aren't query commands, but these types of aliases would likely need to default to query to work as expected.

Have we considered alternatives like dynamic and static or other names that can encompass/reflect non-query command aliases as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static does read nicer than value, switching over to that. Will update docs PR shortly. I do prefer query for the dynamic / default version though - "query" is a cypress concept we reference in the docs, and we should be consistent about its usage.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static as default please

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Defaulting to static would be a breaking change for everyone aliasing DOM nodes, which is more common than aliasing static values. Reducing or eliminating detached DOM errors was the motivation for making this change to alias behavior in the first place.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Humm ok, got it. Thank you!

packages/driver/src/cy/commands/aliasing.ts Outdated Show resolved Hide resolved
packages/driver/src/cy/commands/aliasing.ts Outdated Show resolved Hide resolved
Co-authored-by: Chris Breiding <[email protected]>
Copy link
Member

@emilyrohrbough emilyrohrbough left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be nice if the types description matched the documentation content.

Blue F and others added 2 commits January 23, 2023 15:28
@BlueWinds BlueWinds merged commit 094e3d0 into develop Jan 24, 2023
@BlueWinds BlueWinds deleted the issue-25173-alias-option branch January 24, 2023 16:02
@cypress-bot
Copy link
Contributor

cypress-bot bot commented Jan 24, 2023

Released in 12.4.0.

This comment thread has been locked. If you are still experiencing this issue after upgrading to
Cypress v12.4.0, please open a new issue.

@cypress-bot cypress-bot bot locked as resolved and limited conversation to collaborators Jan 24, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Alias seems to not store it's value
4 participants