Skip to content

Commit

Permalink
feat: Improve clicking with modifiers. (#8114)
Browse files Browse the repository at this point in the history
Co-authored-by: Jennifer Shehane <jennifer@cypress.io>
  • Loading branch information
sainthkh and jennifer-shehane committed Aug 10, 2020
1 parent 1690d41 commit 26f6228
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 1 deletion.
48 changes: 48 additions & 0 deletions cli/types/cypress.d.ts
Expand Up @@ -2319,6 +2319,54 @@ declare namespace Cypress {
* @default false
*/
multiple: boolean
/**
* Activates the control key during click
*
* @default false
*/
ctrlKey: boolean
/**
* Activates the control key during click
*
* @default false
*/
controlKey: boolean
/**
* Activates the alt key (option key for Mac) during click
*
* @default false
*/
altKey: boolean
/**
* Activates the alt key (option key for Mac) during click
*
* @default false
*/
optionKey: boolean
/**
* Activates the shift key during click
*
* @default false
*/
shiftKey: boolean
/**
* Activates the meta key (Windows key or command key for Mac) during click
*
* @default false
*/
metaKey: boolean
/**
* Activates the meta key (Windows key or command key for Mac) during click
*
* @default false
*/
commandKey: boolean
/**
* Activates the meta key (Windows key or command key for Mac) during click
*
* @default false
*/
cmdKey: boolean
}

interface ResolvedConfigOptions {
Expand Down
3 changes: 3 additions & 0 deletions cli/types/tests/chainer-examples.ts
Expand Up @@ -467,6 +467,9 @@ cy.writeFile('../file.path', '', {
})

cy.get('foo').click()
cy.get('foo').click({
ctrlKey: true,
})
cy.get('foo').rightclick()
cy.get('foo').dblclick()

Expand Down
33 changes: 33 additions & 0 deletions packages/driver/cypress/fixtures/issue-486.html
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<title>Issue 486</title>
</head>
<body>
<button id="button">modifier test</button>
<div id="result">Result</div>
<script type="text/javascript">
document.getElementById('button').addEventListener('click', (e) => {
const result = document.getElementById('result')

result.innerText = ''

if (e.ctrlKey) {
result.innerText += '{Ctrl}'
}

if (e.altKey) {
result.innerText += '{Alt}'
}

if (e.shiftKey) {
result.innerText += '{Shift}'
}

if (e.metaKey) {
result.innerText += '{Meta}'
}
})
</script>
</body>
</html>
99 changes: 99 additions & 0 deletions packages/driver/cypress/integration/commands/actions/click_spec.js
Expand Up @@ -882,6 +882,105 @@ describe('src/cy/commands/actions/click', () => {
})
})

describe('modifier options', () => {
beforeEach(() => {
cy.visit('/fixtures/issue-486.html')
})

it('ctrl', () => {
cy.get('#button').click({
ctrlKey: true,
})

cy.get('#result').should('contain', '{Ctrl}')

// ctrl should be released
cy.get('#button').click()
cy.get('#result').should('not.contain', '{Ctrl}')

cy.get('#button').click({
controlKey: true,
})

cy.get('#result').should('contain', '{Ctrl}')
})

it('alt', () => {
cy.get('#button').click({
altKey: true,
})

cy.get('#result').should('contain', '{Alt}')

// alt should be released
cy.get('#button').click()
cy.get('#result').should('not.contain', '{Alt}')

cy.get('#button').click({
optionKey: true,
})

cy.get('#result').should('contain', '{Alt}')
})

it('shift', () => {
cy.get('#button').click({
shiftKey: true,
})

cy.get('#result').should('contain', '{Shift}')

// shift should be released
cy.get('#button').click()
cy.get('#result').should('not.contain', '{Shift}')
})

it('meta', () => {
cy.get('#button').click({
metaKey: true,
})

cy.get('#result').should('contain', '{Meta}')

// shift should be released
cy.get('#button').click()
cy.get('#result').should('not.contain', '{Meta}')

cy.get('#button').click({
commandKey: true,
})

cy.get('#result').should('contain', '{Meta}')

cy.get('#button').click({
cmdKey: true,
})

cy.get('#result').should('contain', '{Meta}')
})

it('multiple', () => {
cy.get('#button').click({
ctrlKey: true,
altKey: true,
shiftKey: true,
metaKey: true,
})

cy.get('#result').should('contain', '{Ctrl}')
cy.get('#result').should('contain', '{Alt}')
cy.get('#result').should('contain', '{Shift}')
cy.get('#result').should('contain', '{Meta}')

// modifiers should be released
cy.get('#button').click()
cy.get('#result').should('not.contain', '{Ctrl}')
cy.get('#result').should('not.contain', '{Alt}')
cy.get('#result').should('not.contain', '{Shift}')
cy.get('#result').should('not.contain', '{Meta}')
})
})

describe('pointer-events:none', () => {
beforeEach(function () {
cy.$$('<div id="ptr" style="position:absolute;width:200px;height:200px;background-color:#08c18d;">behind #ptrNone</div>').appendTo(cy.$$('#dom'))
Expand Down
32 changes: 31 additions & 1 deletion packages/driver/src/cy/commands/actions/click.js
Expand Up @@ -34,7 +34,7 @@ const formatMouseEvents = (events) => {
}

module.exports = (Commands, Cypress, cy, state, config) => {
const { mouse } = cy.devices
const { mouse, keyboard } = cy.devices

const mouseAction = (eventName, { subject, positionOrX, y, userOptions, onReady, onTable, defaultOptions }) => {
let position
Expand All @@ -54,6 +54,14 @@ module.exports = (Commands, Cypress, cy, state, config) => {
errorOnSelect: true,
waitForAnimations: config('waitForAnimations'),
animationDistanceThreshold: config('animationDistanceThreshold'),
ctrlKey: false,
controlKey: false,
altKey: false,
optionKey: false,
shiftKey: false,
metaKey: false,
commandKey: false,
cmdKey: false,
...defaultOptions,
})

Expand All @@ -65,6 +73,24 @@ module.exports = (Commands, Cypress, cy, state, config) => {
})
}

const flagModifiers = (press) => {
if (options.ctrlKey || options.controlKey) {
keyboard.flagModifier({ key: 'Control' }, press)
}

if (options.altKey || options.optionKey) {
keyboard.flagModifier({ key: 'Alt' }, press)
}

if (options.shiftKey) {
keyboard.flagModifier({ key: 'Shift' }, press)
}

if (options.metaKey || options.commandKey || options.cmdKey) {
keyboard.flagModifier({ key: 'Meta' }, press)
}
}

const perform = (el) => {
let deltaOptions
const $el = $dom.wrap(el)
Expand Down Expand Up @@ -158,8 +184,12 @@ module.exports = (Commands, Cypress, cy, state, config) => {

const moveEvents = mouse.move(fromElViewport, forceEl)

flagModifiers(true)

const onReadyProps = onReady(fromElViewport, forceEl)

flagModifiers(false)

return createLog({
moveEvents,
...onReadyProps,
Expand Down

4 comments on commit 26f6228

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 26f6228 Aug 10, 2020

Choose a reason for hiding this comment

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

Circle has built the linux x64 version of the Test Runner.

You can install this pre-release platform-specific build using instructions at https://on.cypress.io/installing-cypress#Install-pre-release-version.

You will need to use custom CYPRESS_INSTALL_BINARY url and install Cypress using an url instead of the version.

export CYPRESS_INSTALL_BINARY=https://cdn.cypress.io/beta/binary/5.0.0/linux-x64/circle-develop-26f6228dc90d0863bdee2510d0b7cc640c763a5f-415727/cypress.zip
npm install https://cdn.cypress.io/beta/npm/5.0.0/circle-develop-26f6228dc90d0863bdee2510d0b7cc640c763a5f-415716/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 26f6228 Aug 10, 2020

Choose a reason for hiding this comment

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

AppVeyor has built the win32 ia32 version of the Test Runner.

You can install this pre-release platform-specific build using instructions at https://on.cypress.io/installing-cypress#Install-pre-release-version.

You will need to use custom CYPRESS_INSTALL_BINARY url and install Cypress using an url instead of the version.

Instructions are included below, depending on the shell you are using.

In Command Prompt (cmd.exe):

set CYPRESS_INSTALL_BINARY=https://cdn.cypress.io/beta/binary/5.0.0/win32-ia32/appveyor-develop-26f6228dc90d0863bdee2510d0b7cc640c763a5f-34569977/cypress.zip
npm install https://cdn.cypress.io/beta/npm/5.0.0/appveyor-develop-26f6228dc90d0863bdee2510d0b7cc640c763a5f-34569977/cypress.tgz

In PowerShell:

$env:CYPRESS_INSTALL_BINARY = https://cdn.cypress.io/beta/binary/5.0.0/win32-ia32/appveyor-develop-26f6228dc90d0863bdee2510d0b7cc640c763a5f-34569977/cypress.zip
npm install https://cdn.cypress.io/beta/npm/5.0.0/appveyor-develop-26f6228dc90d0863bdee2510d0b7cc640c763a5f-34569977/cypress.tgz

In Git Bash:

export CYPRESS_INSTALL_BINARY=https://cdn.cypress.io/beta/binary/5.0.0/win32-ia32/appveyor-develop-26f6228dc90d0863bdee2510d0b7cc640c763a5f-34569977/cypress.zip
npm install https://cdn.cypress.io/beta/npm/5.0.0/appveyor-develop-26f6228dc90d0863bdee2510d0b7cc640c763a5f-34569977/cypress.tgz

Using cross-env:

If the above commands do not work for you, you can also try using cross-env:

npm i -g cross-env
cross-env CYPRESS_INSTALL_BINARY=https://cdn.cypress.io/beta/binary/5.0.0/win32-ia32/appveyor-develop-26f6228dc90d0863bdee2510d0b7cc640c763a5f-34569977/cypress.zip npm install https://cdn.cypress.io/beta/npm/5.0.0/appveyor-develop-26f6228dc90d0863bdee2510d0b7cc640c763a5f-34569977/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 26f6228 Aug 10, 2020

Choose a reason for hiding this comment

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

AppVeyor has built the win32 x64 version of the Test Runner.

You can install this pre-release platform-specific build using instructions at https://on.cypress.io/installing-cypress#Install-pre-release-version.

You will need to use custom CYPRESS_INSTALL_BINARY url and install Cypress using an url instead of the version.

Instructions are included below, depending on the shell you are using.

In Command Prompt (cmd.exe):

set CYPRESS_INSTALL_BINARY=https://cdn.cypress.io/beta/binary/5.0.0/win32-x64/appveyor-develop-26f6228dc90d0863bdee2510d0b7cc640c763a5f-34569977/cypress.zip
npm install https://cdn.cypress.io/beta/npm/5.0.0/appveyor-develop-26f6228dc90d0863bdee2510d0b7cc640c763a5f-34569977/cypress.tgz

In PowerShell:

$env:CYPRESS_INSTALL_BINARY = https://cdn.cypress.io/beta/binary/5.0.0/win32-x64/appveyor-develop-26f6228dc90d0863bdee2510d0b7cc640c763a5f-34569977/cypress.zip
npm install https://cdn.cypress.io/beta/npm/5.0.0/appveyor-develop-26f6228dc90d0863bdee2510d0b7cc640c763a5f-34569977/cypress.tgz

In Git Bash:

export CYPRESS_INSTALL_BINARY=https://cdn.cypress.io/beta/binary/5.0.0/win32-x64/appveyor-develop-26f6228dc90d0863bdee2510d0b7cc640c763a5f-34569977/cypress.zip
npm install https://cdn.cypress.io/beta/npm/5.0.0/appveyor-develop-26f6228dc90d0863bdee2510d0b7cc640c763a5f-34569977/cypress.tgz

Using cross-env:

If the above commands do not work for you, you can also try using cross-env:

npm i -g cross-env
cross-env CYPRESS_INSTALL_BINARY=https://cdn.cypress.io/beta/binary/5.0.0/win32-x64/appveyor-develop-26f6228dc90d0863bdee2510d0b7cc640c763a5f-34569977/cypress.zip npm install https://cdn.cypress.io/beta/npm/5.0.0/appveyor-develop-26f6228dc90d0863bdee2510d0b7cc640c763a5f-34569977/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 26f6228 Aug 10, 2020

Choose a reason for hiding this comment

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

Circle has built the darwin x64 version of the Test Runner.

You can install this pre-release platform-specific build using instructions at https://on.cypress.io/installing-cypress#Install-pre-release-version.

You will need to use custom CYPRESS_INSTALL_BINARY url and install Cypress using an url instead of the version.

export CYPRESS_INSTALL_BINARY=https://cdn.cypress.io/beta/binary/5.0.0/darwin-x64/circle-develop-26f6228dc90d0863bdee2510d0b7cc640c763a5f-415799/cypress.zip
npm install https://cdn.cypress.io/beta/npm/5.0.0/circle-develop-26f6228dc90d0863bdee2510d0b7cc640c763a5f-415730/cypress.tgz

Please sign in to comment.