From c2731890940d40957fe5ac47b000bcb6ebb784a2 Mon Sep 17 00:00:00 2001 From: Paul Jaffre Date: Tue, 18 Jan 2022 10:47:59 -0500 Subject: [PATCH] feat: add cy.mount() runner error (#19145) * add cy.mount error if called before overriding * added index ref & cleanup * added mount spec * feat: Allow Cypress.Commands.add on hover & mount (#19633) * add clarifying comments about special commands Co-authored-by: Tim Griesser --- .../cypress/e2e/commands/commands.cy.js | 18 +++++++++++ .../commands/actions/mount_spec.js | 30 +++++++++++++++++++ .../driver/src/cy/commands/actions/index.ts | 2 ++ .../driver/src/cy/commands/actions/mount.ts | 9 ++++++ packages/driver/src/cypress/commands.ts | 6 +++- packages/driver/src/cypress/error_messages.ts | 10 +++++++ 6 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 packages/driver/cypress/integration/commands/actions/mount_spec.js create mode 100644 packages/driver/src/cy/commands/actions/mount.ts diff --git a/packages/driver/cypress/e2e/commands/commands.cy.js b/packages/driver/cypress/e2e/commands/commands.cy.js index 6a81b91e89..adb845aff9 100644 --- a/packages/driver/cypress/e2e/commands/commands.cy.js +++ b/packages/driver/cypress/e2e/commands/commands.cy.js @@ -97,6 +97,24 @@ describe('src/cy/commands/commands', () => { }) }) + it('allows calling .add with hover / mount', () => { + let calls = 0 + + Cypress.Commands.add('hover', () => { + calls++ + }) + + Cypress.Commands.add('mount', () => { + calls++ + }) + + cy.mount() + cy.hover() + cy.then(() => { + expect(calls).to.eq(2) + }) + }) + it('throws when attempting to add a command with the same name as an internal function', (done) => { cy.on('fail', (err) => { expect(err.message).to.eq('`Cypress.Commands.add()` cannot create a new command named `addChainer` because that name is reserved internally by Cypress.') diff --git a/packages/driver/cypress/integration/commands/actions/mount_spec.js b/packages/driver/cypress/integration/commands/actions/mount_spec.js new file mode 100644 index 0000000000..c68677b804 --- /dev/null +++ b/packages/driver/cypress/integration/commands/actions/mount_spec.js @@ -0,0 +1,30 @@ +const { $ } = Cypress + +describe('src/cy/commands/actions/mount', () => { + before(() => { + cy + .visit('/fixtures/dom.html') + .then(function (win) { + this.body = win.document.body.outerHTML + }) + }) + + beforeEach(function () { + const doc = cy.state('document') + + $(doc.body).empty().html(this.body) + }) + + context('#mount', () => { + it('throws when invoking', (done) => { + cy.on('fail', (err) => { + expect(err.message).to.include('`cy.mount()`') + expect(err.docsUrl).to.eq('https://on.cypress.io/mount') + + done() + }) + + cy.mount() + }) + }) +}) diff --git a/packages/driver/src/cy/commands/actions/index.ts b/packages/driver/src/cy/commands/actions/index.ts index a81167ece3..fe8eb2123d 100644 --- a/packages/driver/src/cy/commands/actions/index.ts +++ b/packages/driver/src/cy/commands/actions/index.ts @@ -8,6 +8,7 @@ import * as SelectFile from './selectFile' import * as Submit from './submit' import * as Type from './type' import * as Trigger from './trigger' +import * as Mount from './mount' export { Check, @@ -20,4 +21,5 @@ export { Submit, Type, Trigger, + Mount, } diff --git a/packages/driver/src/cy/commands/actions/mount.ts b/packages/driver/src/cy/commands/actions/mount.ts new file mode 100644 index 0000000000..7b02568e75 --- /dev/null +++ b/packages/driver/src/cy/commands/actions/mount.ts @@ -0,0 +1,9 @@ +import $errUtils from '../../../cypress/error_utils' + +export default (Commands) => { + return Commands.addAll({ + mount () { + return $errUtils.throwErrByPath('mount.not_implemented') + }, + }) +} diff --git a/packages/driver/src/cypress/commands.ts b/packages/driver/src/cypress/commands.ts index b9ede6f1a7..738341c939 100644 --- a/packages/driver/src/cypress/commands.ts +++ b/packages/driver/src/cypress/commands.ts @@ -8,6 +8,8 @@ import $stackUtils from './stack_utils' import { allCommands } from '../cy/commands' import { addCommand } from '../cy/net-stubbing' +const PLACEHOLDER_COMMANDS = ['mount', 'hover'] + const builtInCommands = [ ..._.toArray(allCommands).map((c) => c.default || c), addCommand, @@ -229,7 +231,9 @@ export default { }) } - if (addingBuiltIns) { + // .hover & .mount are special case commands. allow as builtins so users + // may add them without throwing an error + if (addingBuiltIns && !PLACEHOLDER_COMMANDS.includes(name)) { builtInCommandNames[name] = true } diff --git a/packages/driver/src/cypress/error_messages.ts b/packages/driver/src/cypress/error_messages.ts index 9c0174df5c..02d1e26d0c 100644 --- a/packages/driver/src/cypress/error_messages.ts +++ b/packages/driver/src/cypress/error_messages.ts @@ -953,6 +953,16 @@ export default { }, + mount: { + not_implemented: { + message: [ + `${cmd('mount')} must be implemented by the user. There are`, + 'full instructions for doing so at the following location.', + ].join('\n'), + docsUrl: 'https://on.cypress.io/mount', + }, + }, + navigation: { cross_origin ({ message, originPolicy, configFile, projectRoot }) { return {