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: Queries, Detached DOM, and Retry-Ability #24628

Merged
merged 51 commits into from
Nov 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
0cc8b88
feat: Commands.addSelector, and migrate .get() to be a selector
BlueWinds Sep 1, 2022
0379058
Merge remote-tracking branch 'origin/develop' into issue-7306-addSele…
BlueWinds Sep 1, 2022
fc1bdb2
Merge remote-tracking branch 'origin/develop' into issue-7306-addSele…
BlueWinds Sep 6, 2022
e0ebba5
Fix for failed tests
BlueWinds Sep 6, 2022
b9be83b
Last test fix
BlueWinds Sep 6, 2022
c4de5d9
More test fixes
BlueWinds Sep 6, 2022
518bd72
Self review changes
BlueWinds Sep 6, 2022
e33e29f
Remove the concept of prevSubject from selectors entirely
BlueWinds Sep 7, 2022
1876e83
Merge remote-tracking branch 'origin/develop' into issue-7306-addSele…
BlueWinds Sep 7, 2022
789f71b
Rename addSelector to addQuery
BlueWinds Sep 7, 2022
3857845
Quick fix for last commit
BlueWinds Sep 7, 2022
a52b361
Fix TS
BlueWinds Sep 7, 2022
2ffa3c5
Fix merge from develop
BlueWinds Sep 7, 2022
661c305
Add types and other review updates
BlueWinds Sep 13, 2022
0009d3c
Merge branch 'develop' into issue-7306-addSelector-redux
Sep 13, 2022
443b636
Increase timeout to try fixing flakiness
BlueWinds Sep 14, 2022
caff894
Merge branch 'issue-7306-addSelector-redux' of github.com:cypress-io/…
BlueWinds Sep 14, 2022
ef57371
Rename addQuery to _addQuery
BlueWinds Sep 20, 2022
f9da4bb
Fix typo in previous commit
BlueWinds Sep 20, 2022
5d6e930
Merge branch 'develop' into issue-7306-addSelector-redux
BlueWinds Sep 20, 2022
98042e8
Merge remote-tracking branch 'origin/develop' into issue-7306-addSele…
BlueWinds Sep 26, 2022
5ce6250
Fix TS
BlueWinds Sep 26, 2022
14aa153
Include AUT assertion in cy.get()
BlueWinds Sep 26, 2022
1b4ebb8
Fix for previous commit
BlueWinds Sep 26, 2022
cd263af
Review feedback
BlueWinds Sep 26, 2022
7a88624
Merge branch 'develop' into issue-7306-addSelector-redux
Sep 26, 2022
dd05b4f
Minor test improvement
BlueWinds Sep 26, 2022
1ec423c
Swifter failure on sizzle syntax error
BlueWinds Sep 26, 2022
ec4a682
Better solution for refetching current subject in verifyUpcomingAsser…
BlueWinds Sep 26, 2022
514233a
Command IDs now include their chainerId
BlueWinds Sep 26, 2022
5a2db61
Merge branch 'develop' into issue-7306-addSelector-redux
Sep 27, 2022
9263b69
Merge branch 'develop' into issue-7306-addSelector-redux
Sep 28, 2022
233c269
Merge branch 'develop' into issue-7306-addSelector-redux
BlueWinds Sep 28, 2022
8e9fda8
Merge remote-tracking branch 'origin/develop' into issue-7306-addSele…
BlueWinds Sep 28, 2022
31b0661
Revert "chore: Revert "feat: _addQuery() (#23665)" (#24022)"
BlueWinds Sep 28, 2022
5731717
Merge remote-tracking branch 'origin/develop' into issue-7306-addSele…
BlueWinds Sep 29, 2022
0267ebe
Merge remote-tracking branch 'origin/develop' into issue-7306
BlueWinds Sep 29, 2022
8069e4f
Merge remote-tracking branch 'origin/develop' into issue-7306
BlueWinds Oct 3, 2022
555ed23
Merge remote-tracking branch 'origin/develop' into issue-7306
BlueWinds Oct 5, 2022
2326f96
feat: move .contains() and .shadow() to be queries; remove cy.ng() (#…
Oct 11, 2022
9d2c02e
Merge remote-tracking branch 'origin/develop' into issue-7306
BlueWinds Oct 11, 2022
4038b8b
Merge remote-tracking branch 'origin/develop' into issue-7306
BlueWinds Oct 12, 2022
989baec
Merge branch 'develop' into issue-7306
BlueWinds Oct 17, 2022
97e0e38
Merge remote-tracking branch 'origin/develop' into issue-7306
BlueWinds Oct 25, 2022
a052842
feat: addQuery Remaining Queries (#24203)
Oct 26, 2022
2e35f2a
Merge remote-tracking branch 'origin/develop' into issue-7306
BlueWinds Oct 31, 2022
45953f7
feat: Fix detached DOM errors for all Cypress commands (#24417)
Nov 9, 2022
9d2e8af
Merge remote-tracking branch 'origin/release/12.0.0' into issue-7306
BlueWinds Nov 9, 2022
b1518a6
Merge remote-tracking branch 'origin/release/12.0.0' into issue-7306
BlueWinds Nov 9, 2022
17003e9
Fix for hanging driver test after merge
BlueWinds Nov 9, 2022
9c2f198
Fix for app component test
BlueWinds Nov 9, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ mainBuildFilters: &mainBuildFilters
only:
- develop
- /^release\/\d+\.\d+\.\d+$/
- issue-7306

# usually we don't build Mac app - it takes a long time
# but sometimes we want to really confirm we are doing the right thing
Expand Down
71 changes: 68 additions & 3 deletions cli/types/cypress.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ declare namespace Cypress {
interface CommandFnWithOriginalFnAndSubject<T extends keyof Chainable, S> {
(this: Mocha.Context, originalFn: CommandOriginalFnWithSubject<T, S>, prevSubject: S, ...args: Parameters<ChainableMethods[T]>): ReturnType<ChainableMethods[T]> | void
}
interface QueryFn<T extends keyof ChainableMethods> {
(...args: Parameters<ChainableMethods[T]>): (subject: any) => any
}
interface ObjectLike {
[key: string]: any
}
Expand Down Expand Up @@ -462,30 +465,92 @@ declare namespace Cypress {
*/
log(options: Partial<LogConfig>): Log

/**
* @see https://on.cypress.io/api/commands
*/
Commands: {
/**
* Add a custom command
* @see https://on.cypress.io/api/commands
*/
add<T extends keyof Chainable>(name: T, fn: CommandFn<T>): void

/**
* Add a custom parent command
* @see https://on.cypress.io/api/commands#Parent-Commands
*/
add<T extends keyof Chainable>(name: T, options: CommandOptions & {prevSubject: false}, fn: CommandFn<T>): void

/**
* Add a custom child command
* @see https://on.cypress.io/api/commands#Child-Commands
*/
add<T extends keyof Chainable, S = any>(name: T, options: CommandOptions & {prevSubject: true}, fn: CommandFnWithSubject<T, S>): void

/**
* Add a custom child or dual command
* @see https://on.cypress.io/api/commands#Validations
*/
add<T extends keyof Chainable, S extends PrevSubject>(
name: T, options: CommandOptions & { prevSubject: S | ['optional'] }, fn: CommandFnWithSubject<T, PrevSubjectMap[S]>,
): void

/**
* Add a custom command that allows multiple types as the prevSubject
* @see https://on.cypress.io/api/commands#Validations#Allow-Multiple-Types
*/
add<T extends keyof Chainable, S extends PrevSubject>(
name: T, options: CommandOptions & { prevSubject: S[] }, fn: CommandFnWithSubject<T, PrevSubjectMap<void>[S]>,
): void

/**
* Add one or more custom commands
* @see https://on.cypress.io/api/commands
*/
addAll<T extends keyof Chainable>(fns: CommandFns): void

/**
* Add one or more custom parent commands
* @see https://on.cypress.io/api/commands#Parent-Commands
*/
addAll<T extends keyof Chainable>(options: CommandOptions & {prevSubject: false}, fns: CommandFns): void

/**
* Add one or more custom child commands
* @see https://on.cypress.io/api/commands#Child-Commands
*/
addAll<T extends keyof Chainable, S = any>(options: CommandOptions & { prevSubject: true }, fns: CommandFnsWithSubject<S>): void

/**
* Add one or more custom commands that validate their prevSubject
* @see https://on.cypress.io/api/commands#Validations
*/
addAll<T extends keyof Chainable, S extends PrevSubject>(
options: CommandOptions & { prevSubject: S | ['optional'] }, fns: CommandFnsWithSubject<PrevSubjectMap[S]>,
): void

/**
* Add one or more custom commands that allow multiple types as their prevSubject
* @see https://on.cypress.io/api/commands#Allow-Multiple-Types
*/
addAll<T extends keyof Chainable, S extends PrevSubject>(
options: CommandOptions & { prevSubject: S[] }, fns: CommandFnsWithSubject<PrevSubjectMap<void>[S]>,
): void

/**
* Overwrite an existing Cypress command with a new implementation
* @see https://on.cypress.io/api/commands#Overwrite-Existing-Commands
*/
overwrite<T extends keyof Chainable>(name: T, fn: CommandFnWithOriginalFn<T>): void

/**
* Overwrite an existing Cypress command with a new implementation
* @see https://on.cypress.io/api/commands#Overwrite-Existing-Commands
*/
overwrite<T extends keyof Chainable, S extends PrevSubject>(name: T, fn: CommandFnWithOriginalFnAndSubject<T, PrevSubjectMap[S]>): void

/**
* Add a custom query
* @see https://on.cypress.io/api/commands#Queries
*/
addQuery<T extends keyof Chainable>(name: T, fn: QueryFn<T>): void
}

/**
Expand Down
2 changes: 1 addition & 1 deletion npm/cypress-schematic/src/e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const cypressSchematicPackagePath = path.join(__dirname, '..')
const ANGULAR_PROJECTS: ProjectFixtureDir[] = ['angular-13', 'angular-14']

describe('ng add @cypress/schematic / only e2e', function () {
this.timeout(1000 * 60 * 4)
this.timeout(1000 * 60 * 5)

for (const project of ANGULAR_PROJECTS) {
it('should install e2e files by default', async () => {
Expand Down
5 changes: 3 additions & 2 deletions packages/app/cypress/e2e/reporter_header.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ describe('Reporter Header', () => {
cy.get('[data-selected-spec="false"]').should('have.length', '27')
})

it('filters the list of specs when searching for specs', () => {
// TODO: Reenable as part of https://github.com/cypress-io/cypress/issues/23902
it.skip('filters the list of specs when searching for specs', () => {
cy.get('body').type('f')

cy.findByTestId('specs-list-panel').within(() => {
Expand All @@ -28,7 +29,7 @@ describe('Reporter Header', () => {

cy.get('@searchInput').clear()

cy.get('[data-cy="spec-file-item"]').should('have.length', 3)
cy.get('[data-cy="spec-file-item"]').should('have.length', 23)

cy.get('@searchInput').type('asdf', { force: true })

Expand Down
12 changes: 6 additions & 6 deletions packages/app/cypress/e2e/runner/reporter-ct-mount-hover.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ type ProjectDirs = typeof fixtureDirs

const PROJECTS: {projectName: ProjectDirs[number], test: string}[] = [
{ projectName: 'angular-14', test: 'app.component' },
{ projectName: 'vueclivue2-configured', test: 'HelloWorld.cy' },
{ projectName: 'react-vite-ts-configured', test: 'App.cy' },
{ projectName: 'react18', test: 'App.cy' },
{ projectName: 'create-react-app-configured', test: 'App.cy' },
{ projectName: 'vueclivue3-configured', test: 'HelloWorld.cy' },
{ projectName: 'nuxtjs-vue2-configured', test: 'Tutorial.cy' },
// { projectName: 'vueclivue2-configured', test: 'HelloWorld.cy' },
// { projectName: 'react-vite-ts-configured', test: 'App.cy' },
// { projectName: 'react18', test: 'App.cy' },
// { projectName: 'create-react-app-configured', test: 'App.cy' },
// { projectName: 'vueclivue3-configured', test: 'HelloWorld.cy' },
// { projectName: 'nuxtjs-vue2-configured', test: 'Tutorial.cy' },
]

// TODO: Add these tests to another cy-in-cy framework test to reduce CI cost as these scaffolding is expensive
Expand Down
3 changes: 1 addition & 2 deletions packages/app/cypress/e2e/specs_list_e2e.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,7 @@ describe('App: Spec List (E2E)', () => {
cy.findByText('No specs matched your search:').should('not.be.visible')
})

// TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23305
it.skip('saves the filter when navigating to a spec and back', function () {
it('saves the filter when navigating to a spec and back', function () {
const targetSpecFile = 'accounts_list.spec.js'

clearSearchAndType(targetSpecFile)
Expand Down
10 changes: 5 additions & 5 deletions packages/app/cypress/e2e/top-nav.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ describe('App Top Nav Workflows', () => {
})

it('hides dropdown when version in header is clicked', () => {
cy.findByTestId('cypress-update-popover').findByRole('button', { expanded: false }).as('topNavVersionButton').click()
cy.findByTestId('cypress-update-popover').findAllByRole('button').first().as('topNavVersionButton').click()

cy.get('@topNavVersionButton').should('have.attr', 'aria-expanded', 'true')

Expand Down Expand Up @@ -541,7 +541,7 @@ describe('App Top Nav Workflows', () => {
cy.findByRole('button', { name: 'Log in' }).click()
})

cy.findByRole('dialog', { name: 'Log in to Cypress' }).within(() => {
cy.findByRole('dialog').within(() => {
cy.findByRole('button', { name: 'Log in' }).click()

cy.contains('http://127.0.0.1:0000/redirect-to-auth').should('be.visible')
Expand Down Expand Up @@ -573,7 +573,7 @@ describe('App Top Nav Workflows', () => {
cy.findByRole('button', { name: 'Log in' }).click()
})

cy.findByRole('dialog', { name: 'Log in to Cypress' }).within(() => {
cy.findByRole('dialog').within(() => {
cy.findByRole('button', { name: 'Log in' }).click()

cy.contains(loginText.titleFailed).should('be.visible')
Expand Down Expand Up @@ -623,7 +623,7 @@ describe('App Top Nav Workflows', () => {
cy.findByRole('button', { name: 'Log in' }).as('loginButton').click()
})

cy.findByRole('dialog', { name: 'Log in to Cypress' }).within(() => {
cy.findByRole('dialog').within(() => {
cy.findByRole('button', { name: 'Log in' }).click()

cy.contains(loginText.titleFailed).should('be.visible')
Expand Down Expand Up @@ -660,7 +660,7 @@ describe('App Top Nav Workflows', () => {
cy.findByRole('button', { name: 'Log in' }).as('loginButton').click()
})

cy.findByRole('dialog', { name: 'Log in to Cypress' }).within(() => {
cy.findByRole('dialog').within(() => {
cy.findByRole('button', { name: 'Log in' }).click()
cy.contains(loginText.titleFailed).should('be.visible')
cy.contains(loginText.bodyError).should('be.visible')
Expand Down
2 changes: 1 addition & 1 deletion packages/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"@intlify/vite-plugin-vue-i18n": "2.4.0",
"@packages/frontend-shared": "0.0.0-development",
"@percy/cypress": "^3.1.0",
"@testing-library/cypress": "8.0.0",
"@testing-library/cypress": "BlueWinds/cypress-testing-library#119054b5963b0d2e064b13c5cc6fc9db32c8b7b5",
"@types/faker": "5.5.8",
"@urql/core": "2.4.4",
"@urql/vue": "0.6.2",
Expand Down
4 changes: 2 additions & 2 deletions packages/app/src/specs/SpecItem.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe('SpecItem', () => {
const parentColor = getComputedStyle($el.parent()[0]).color
const highlightedElementColor = getComputedStyle($el[0]).color

cy.wrap(highlightedElementColor).should('not.equal', parentColor)
expect(highlightedElementColor).not.to.equal(parentColor)
})
})

Expand All @@ -35,7 +35,7 @@ describe('SpecItem', () => {
const parentColor = getComputedStyle($el.parent()[0]).color
const highlightedElementColor = getComputedStyle($el[0]).color

cy.wrap(highlightedElementColor).should('equal', parentColor)
expect(highlightedElementColor).to.equal(parentColor)
})
})

Expand Down
25 changes: 23 additions & 2 deletions packages/driver/cypress/e2e/commands/actions/check.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,27 @@ describe('src/cy/commands/actions/check', () => {
cy.get(checkbox).check()
})

it('requeries if the DOM rerenders during actionability', () => {
cy.$$('[name=colors]').first().prop('disabled', true)

const listener = _.after(3, () => {
cy.$$('[name=colors]').first().prop('disabled', false)

const parent = cy.$$('[name=colors]').parent()

parent.replaceWith(parent[0].outerHTML)
cy.off('command:retry', listener)
})

cy.on('command:retry', listener)

cy.get('[name=colors]').check().then(($inputs) => {
$inputs.each((i, el) => {
expect($(el)).to.be.checked
})
})
})

// readonly should only be limited to inputs, not checkboxes
it('can check readonly checkboxes', () => {
cy.get('#readonly-checkbox').check().then(($checkbox) => {
Expand Down Expand Up @@ -437,7 +458,7 @@ describe('src/cy/commands/actions/check', () => {

cy.on('fail', (err) => {
expect(checked).to.eq(1)
expect(err.message).to.include('`cy.check()` failed because this element')
expect(err.message).to.include('`cy.check()` failed because the page updated')

done()
})
Expand Down Expand Up @@ -1079,7 +1100,7 @@ describe('src/cy/commands/actions/check', () => {

cy.on('fail', (err) => {
expect(unchecked).to.eq(1)
expect(err.message).to.include('`cy.uncheck()` failed because this element')
expect(err.message).to.include('`cy.uncheck()` failed because the page updated')

done()
})
Expand Down
22 changes: 21 additions & 1 deletion packages/driver/cypress/e2e/commands/actions/clear.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,26 @@ describe('src/cy/commands/actions/type - #clear', () => {
})
})

it('requeries if the DOM rerenders during actionability', () => {
const clicked = cy.stub()
const retried = cy.stub()

const textarea = cy.$$('#comments').val('foo bar').prop('disabled', true)

cy.on('command:retry', _.after(3, () => {
if (!retried.callCount) {
textarea.replaceWith(textarea[0].outerHTML)
cy.$$('#comments').prop('disabled', false).on('click', clicked)
retried()
}
}))

cy.get('#comments').clear().then(() => {
expect(clicked).to.be.calledOnce
expect(retried).to.be.called
})
})

it('can force clear even when being covered by another element', () => {
const $input = $('<input />')
.attr('id', 'input-covered-in-span')
Expand Down Expand Up @@ -275,7 +295,7 @@ describe('src/cy/commands/actions/type - #clear', () => {

cy.on('fail', (err) => {
expect(cleared).to.be.calledOnce
expect(err.message).to.include('`cy.clear()` failed because this element')
expect(err.message).to.include('`cy.clear()` failed because the page updated')

done()
})
Expand Down
Loading