Skip to content

Commit

Permalink
Merge pull request #235 from thefrontside/dl/cypress@12-expect-fix
Browse files Browse the repository at this point in the history
Dl/cypress@12 expect fix
  • Loading branch information
wKich authored Aug 30, 2023
2 parents 1d471d9 + 4615e5b commit 944d64b
Show file tree
Hide file tree
Showing 13 changed files with 1,175 additions and 234 deletions.
5 changes: 5 additions & 0 deletions .changeset/two-cougars-smile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@interactors/with-cypress": patch
---

Fix overwriting `expect` command for cypress@12
20 changes: 20 additions & 0 deletions packages/with-cypress/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { defineConfig } from 'cypress'

export default defineConfig({
video: false,
screenshotOnRunFailure: false,
defaultCommandTimeout: 20000,
fixturesFolder: 'cypress/fixtures',
screenshotsFolder: 'cypress/screenshots',
videosFolder: 'cypress/videos',
configFile: 'cypress/tsconfig.json',
e2e: {
// We've imported your old cypress plugins here.
// You may want to clean this up later by importing these.
setupNodeEvents(on, config) {
return require('./cypress/plugins/index.js')(on, config)
},
baseUrl: 'http://localhost:3000',
specPattern: 'cypress/e2e/**/*.cy.*',
},
})
13 changes: 0 additions & 13 deletions packages/with-cypress/cypress.json

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@ describe('Cypress with Interactors', () => {
it('single interactor per command', () => {
cy
.do(Button('SIGN IN').click())
.expect(Button('LOG OUT').exists())
.expectThat(Button('LOG OUT').exists())
});
it('array of interactors', () => {
cy
.do([
Button('SIGN IN').click(),
Button('LOG OUT').click()
])
.expect([
.expectThat([
Button('SIGN IN').exists(),
Button('LOG OUT').absent()
]);
});
it('interactors with matchers', () => {
cy
.expect([
.expectThat([
Button(including('SIGN')).exists(),
Button(matching(/SI(.*)IN/)).exists()
]);
Expand Down
6 changes: 3 additions & 3 deletions packages/with-cypress/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
"@interactors/globals": "^1.0.0-rc1.2"
},
"peerDependencies": {
"cypress": ">=6.0.0 <11.0.0"
"cypress": ">=6.0.0 <13.0.0"
},
"scripts": {
"start": "cd ../../sample/ && npm install && npm run start -- -p 3000",
"cypress:run": "npx cypress run --spec 'cypress/integration/*.spec.ts'",
"cypress:run": "npx cypress run",
"test": "start-server-and-test 'npm run start' http://localhost:3000 cypress:run",
"prepack": "tsc --build",
"lint": "eslint \"src/**/*.ts\""
Expand All @@ -33,7 +33,7 @@
"@frontside/tsconfig": "^1.2.0",
"@frontside/typescript": "^1.1.1",
"@interactors/html": "^1.0.0-rc1.3",
"cypress": "^8.0.0",
"cypress": "^12.0.0",
"start-server-and-test": "^1.11.7",
"ts-node": "^10.4.0"
},
Expand Down
38 changes: 23 additions & 15 deletions packages/with-cypress/src/cypress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import { Interaction, isInteraction, AssertionInteraction } from '@interactors/c
declare global {
namespace Cypress {
interface Chainable<Subject> {
do(interaction: Interaction<Element> | Interaction<Element>[]): Chainable<Subject>;
expect(interaction: AssertionInteraction<Element> | AssertionInteraction<Element>[]): Chainable<Subject>;
do<E extends Element>(interaction: Interaction<E, void> | Interaction<E, void>[]): Chainable<Subject>;
expect<E extends Element>(interaction: AssertionInteraction<E, void> | AssertionInteraction<E, void>[]): Chainable<Subject>;
expectThat<E extends Element>(interaction: AssertionInteraction<E, void> | AssertionInteraction<E, void>[]): Chainable<Subject>;
}
}
}
Expand All @@ -24,9 +25,10 @@ addInteractionWrapper((operation, interaction) =>
}
);

function interact(interactions: Interaction<Element>[], command: CypressCommand): void {
function interact(interactions: Interaction<Element, void>[], command: CypressCommand): void {
interactions
.reduce((cy: Cypress.Chainable<void>, interaction) =>
// eslint-disable-next-line @typescript-eslint/no-explicit-any
.reduce((cy: Cypress.Chainable<any>, interaction) =>
cy
.then(() => interaction)
.then(() => {
Expand All @@ -39,37 +41,43 @@ function interact(interactions: Interaction<Element>[], command: CypressCommand)
).then(() => (cypressCommand = null))
};

function isInteractions(interactions: unknown[]): interactions is AssertionInteraction<Element>[] {
function isInteractions(interactions: unknown[]): interactions is AssertionInteraction<Element, void>[] {
return interactions.every(isInteraction)
}

if (typeof Cypress !== 'undefined' ) {
Cypress.Commands.add('do', (interaction: Interaction<Element> | Interaction<Element>[]) =>
interact(([] as Interaction<Element>[]).concat(interaction), 'do')
Cypress.Commands.add('do', (interaction: Interaction<Element, void> | Interaction<Element, void>[]) =>
interact(([] as Interaction<Element, void>[]).concat(interaction), 'do')
);

// NOTE: Save the original `expect` assertion method
let chaiExpect = cy.expect as (value: unknown, message?: string) => unknown

let interactionExpect = (interaction: AssertionInteraction<Element> | AssertionInteraction<Element>[]) => (
interact(([] as AssertionInteraction<Element>[]).concat(interaction), 'expect')
let interactionExpect = (interaction: AssertionInteraction<Element, void> | AssertionInteraction<Element, void>[]) => (
interact(([] as AssertionInteraction<Element, void>[]).concat(interaction), 'expect')
)
try {
// NOTE: Add interaction assertion function, Cypress also overrides `expect` method to a wrapper function
// This need for Cypress <10 versions
Cypress.Commands.add('expect', interactionExpect);
}
catch (e) {}
// @ts-expect-error Cypress stores a reference to commands object and use it to check overwiritability of commands
// https://github.com/cypress-io/cypress/blob/d378ec423a4a2799f90a6536f82e4504bc8b3c9e/packages/driver/src/cypress/commands.ts#L155
Cypress.Commands._commands['expect'] = interactionExpect;
// NOTE: Add interaction assertion function, Cypress also overrides `expect` method to a wrapper function
Cypress.Commands.overwrite('expect', interactionExpect);
if ('_commands' in Cypress.Commands) {
// @ts-expect-error Cypress stores a reference to commands object and use it to check overwritability of commands
// https://github.com/cypress-io/cypress/blob/d378ec423a4a2799f90a6536f82e4504bc8b3c9e/packages/driver/src/cypress/commands.ts#L155
Cypress.Commands._commands['expect'] = interactionExpect;
// NOTE: Add interaction assertion function, Cypress also overrides `expect` method to a wrapper function
// @ts-expect-error TypeScript complains that signature doesn't match with declared one
Cypress.Commands.overwrite('expect', interactionExpect);
}

// NOTE: Fallback alias for `expect` assertion method
Cypress.Commands.add('expectThat', interactionExpect);

// NOTE: Override Cypress's wrapper to our combined `expect`
// @ts-expect-error TypeScript complains that signature doesn't match with declared one
cy.expect = (
interaction: AssertionInteraction<Element> | AssertionInteraction<Element>[] | unknown,
interaction: AssertionInteraction<Element, void> | AssertionInteraction<Element, void>[] | unknown,
message?: string
) => {
let interactions = Array.isArray(interaction) ? interaction : [interaction]
Expand Down
6 changes: 3 additions & 3 deletions sample/app/app-pkg.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
"@babel/core": "^7.12.10",
"@babel/preset-env": "^7.12.11",
"@babel/preset-react": "^7.12.10",
"@interactors/html": "^0.33.0",
"@interactors/with-cypress": "^0.1.3",
"@interactors/html": "^1.0.0-rc1.4",
"@interactors/with-cypress": "^1.0.0-rc1.2",
"@testing-library/react": "^11.1.0",
"babel-jest": "^26.6.3",
"bigtest": "0.14.4",
"cypress": "^8.0.0",
"cypress": "^12.0.0",
"eslint": "^7.17.0",
"eslint-plugin-cypress": "^2.11.2",
"jest": "^26.6.3",
Expand Down
17 changes: 17 additions & 0 deletions sample/app/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { defineConfig } from 'cypress'

export default defineConfig({
video: false,
screenshotOnRunFailure: false,
defaultCommandTimeout: 20000,
fixturesFolder: 'cypress/fixtures',
e2e: {
// We've imported your old cypress plugins here.
// You may want to clean this up later by importing these.
setupNodeEvents(on, config) {
return require('./cypress/plugins/index.js')(on, config)
},
baseUrl: 'http://localhost:3000',
specPattern: 'src/test//**/*.spec.*',
},
})
11 changes: 0 additions & 11 deletions sample/app/cypress.json

This file was deleted.

File renamed without changes.
Loading

0 comments on commit 944d64b

Please sign in to comment.