inovramadani
inovramadani

Reputation: 2047

How to simulate long hold key press on cypress?

I want to simulate a long key press of backquote key without selecting certain dom element, how can we achieve this using cypress? I have a functionality on my web app that will trigger when this key is pressed.

I have tried several code below and nothing works.

// 1st
cy.get('#sidepanel').trigger('keydown', { keycode: 192, release: false })

// 2nd
cy.get('body').type('`', { release: false })

// 3rd
cy.get('body').trigger('keydown', { keycode: 192, release: false })
cy.wait(15000)
cy.get('body').trigger('keyup', { keycode: 192, release: false })

I expect it will simulate the long and hold key press of backqoute, but it looks like the typing of backqoute only happens once and not hold.

Upvotes: 4

Views: 10195

Answers (4)

Lasecun
Lasecun

Reputation: 1

the accepted question it's ok. But for me it works changing keycode to keyCode

// expect: holding down for 5 seconds
// actual: cypress will hold the keys for 28 seconds
for (var i = 0; i < 100; i++) {
  cy.get('body').trigger('keydown', { keyCode: 87, release: false })
  cy.get('body').trigger('keypress', { keyCode: 87, release: false })
  cy.wait(50)
}
cy.get('body').trigger('keyup', { keyCode: 87, release: false })

Also I update the example because in my case need to press W to move forward.

Regards.

Upvotes: 0

m21-cerutti
m21-cerutti

Reputation: 1

In my case what it has worked is to explicitly set in the next events the ctrlkey. In this example it has permitted me to simulate a Ctrl+Click plus a movement of the mouse.

cy.get(target).focus();
cy.get(target).type('{ctrl}', { release: false });
cy.get(target).trigger('mousedown', point.x, point.y, { eventConstructor: 'MouseEvent', button: 0, ctrlKey: true, force: true })
point.x += -200;
point.y += 100;
cy.get(target).trigger('mousemove', point.x, point.y, { eventConstructor: 'MouseEvent', ctrlKey: true, force: true });
cy.wait(250);
point.x += -20;
point.y += 100;
cy.get(target).trigger('mousemove', point.x, point.y, { eventConstructor: 'MouseEvent', ctrlKey: true, force: true });
cy.get(target).trigger('mouseup', point.x, point.y, { eventConstructor: 'MouseEvent', ctrlKey: true, button: 0, force: true });
cy.get(target).trigger('mouseover', point.x, point.y, { eventConstructor: 'MouseEvent', ctrlKey: true, button: 0, force: true });
cy.get(target).type('{ctrl}');

I don't think all the arguments are necessary, but the eventConstructor, ctrlKey, and button were important in my process.

Upvotes: 0

inovramadani
inovramadani

Reputation: 2047

I don't know why, but when trying Zach Bloomquist answer months ago, it didn't work. Just now I tried again, it works. I tried it on different machine and re-install cypress version 3.3.2. Not really sure if it has different impact.

Somehow, solution from Zach does not give close to actual time key pressed. Running his solution actually will press the key for 28 seconds in Cypress runtime.

// expect: holding down for 5 seconds
// actual: cypress will hold the keys for 28 seconds
for (var i = 0; i < 100; i++) {
  cy.get('body').trigger('keydown', { keycode: 192, release: false })
  cy.get('body').trigger('keypress', { keycode: 192, release: false })
  cy.wait(50)
}
cy.get('body').trigger('keyup', { keycode: 192, release: false })

I have come up with simpler solution that match almost actual duration press time when run in cypress:

cy.get('body').trigger('keydown', { keyCode: 192 })
cy.wait(duration)
cy.get('body').trigger('keyup', { keyCode: 192 })

If you see clearly this solution the same like my third alternative in the question. Before it didn't work, but now it works. What I noticed different is the browser type when Cypress run. Before it's chrome, now Electron 61. Maybe it's the cause, need to investigate further to validate.

Upvotes: 4

Zach Bloomquist
Zach Bloomquist

Reputation: 5871

When you hold down a key in the browser, it actually ends up being many subsequent keydown/keypress events, followed by a keyup when you finally let go of the key.

You can verify this behavior by running this code in your browser:

['keydown','keypress','keyup'].map(e => {
  document.addEventListener(e, (p) => console.log(e, p))
})

Then, hold down a key and watch your console log to see what events are emitted. In Firefox, holding down the A key gives:

Screenshot of holding down A key


So, to do this with Cypress, you just need to emulate those events:

// holding down for 5 seconds
for (var i = 0; i < 100; i++) {
  cy.get('body').trigger('keydown', { keycode: 192, release: false })
  cy.get('body').trigger('keypress', { keycode: 192, release: false })
  cy.wait(50)
}
cy.get('body').trigger('keyup', { keycode: 192, release: false })

Upvotes: 4

Related Questions