Skip to content

Commit

Permalink
feat: Add shiftKey modifier to keyboard events (#514)
Browse files Browse the repository at this point in the history
* add shiftKey option to some events

* add test cases

* revert unrelated formatting changes

* add shiftKey option for mouseUp event

* one more formatting revert

---------

Co-authored-by: Dmitriy <dmtr.kovalenko@outlook.com>
  • Loading branch information
Minilfat and dmtrKovalenko committed Jul 17, 2023
1 parent f90bdb2 commit 769273d
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 8 deletions.
30 changes: 30 additions & 0 deletions cypress/e2e/modifiers.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
describe("Events behavior with shiftKey modifier applied", () => {
beforeEach(() => {
cy.visit("./cypress/fixtures/modifiers-test.html");
});

it("detects shift key modifier on click", () => {
cy.get("#action-button").realClick({ shiftKey: true });
cy.contains("Shift key was pressed");
});

it("detects shift key modifier on hover", () => {
cy.get("#mouse-move-div").realHover({ shiftKey: true });
cy.contains("Shift key was pressed");
});

it("detects shift key modifier on mousedown", () => {
cy.get("#mouse-down-div").realMouseDown({ shiftKey: true });
cy.contains("Shift key was pressed");
});

it("detects shift key modifier on mpuseup", () => {
cy.get("#mouse-up-div").realMouseUp({ shiftKey: true });
cy.contains("Shift key was pressed");
});

it("detects shift key modifier on mousemove", () => {
cy.get("#mouse-move-div").realMouseMove(100, 50, { shiftKey: true });
cy.contains("Shift key was pressed");
});
});
46 changes: 46 additions & 0 deletions cypress/fixtures/modifiers-test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<!DOCTYPE html>
<html lang="en">
<body>
<button id="action-button">Click on me with shift pressed</button>
<hr />
<div id="mouse-move-div">Hover/mousemove over me with shift pressed</div>
<hr />
<div id="mouse-down-div">Initiate mouse down with shift pressed</div>
<hr />
<div id="mouse-up-div">Initiate mouse up with shift pressed</div>
<hr />

<p id="result"></p>
</body>
<script>
const resultBox = document.getElementById("result");

function commonHandler(e) {
resultBox.innerHTML = "";
if (e.shiftKey) resultBox.innerHTML = "Shift key was pressed";
}

document
.getElementById("action-button")
.addEventListener("click", commonHandler);

document
.getElementById("mouse-move-div")
.addEventListener("mousemove", commonHandler);

document
.getElementById("mouse-down-div")
.addEventListener("mousedown", commonHandler);

document
.getElementById("mouse-up-div")
.addEventListener("mouseup", commonHandler);
</script>
<style>
div {
width: 100%;
height: 100px;
background-color: aqua;
}
</style>
</html>
7 changes: 7 additions & 0 deletions src/commands/mouseDown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
Position,
} from "../getCypressElementCoordinates";
import { mouseButtonNumbers } from "../mouseButtonNumbers";
import { keyToModifierBitMap } from "../keyToModifierBitMap";

export interface realMouseDownOptions {
/** Pointer type for realMouseDown, if "pen" touch simulated */
Expand All @@ -24,6 +25,11 @@ export interface realMouseDownOptions {
* @default "left"
*/
button?: keyof typeof mouseButtonNumbers;
/**
* Indicates whether the shift key was pressed or not when an event occurred
* @example cy.realMouseDown({ shiftKey: true });
*/
shiftKey?: boolean;
}

/** @ignore this, update documentation for this function at index.d.ts */
Expand Down Expand Up @@ -51,6 +57,7 @@ export async function realMouseDown(
buttons: mouseButtonNumbers[options.button ?? "left"],
pointerType: options.pointer ?? "mouse",
button: options.button ?? "left",
modifiers: options.shiftKey ? keyToModifierBitMap.Shift : 0,
});

log.snapshot("after").end();
Expand Down
9 changes: 8 additions & 1 deletion src/commands/mouseMove.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
Position,
ScrollBehaviorOptions,
} from "../getCypressElementCoordinates";
import { keyToModifierBitMap } from "../keyToModifierBitMap";

export interface RealMouseMoveOptions {
/**
Expand All @@ -14,9 +15,14 @@ export interface RealMouseMoveOptions {
position?: Position;
/**
* Controls how the page is scrolled to bring the subject into view, if needed.
* @example cy.realClick({ scrollBehavior: "top" });
* @example cy.realMouseMove({ scrollBehavior: "top" });
*/
scrollBehavior?: ScrollBehaviorOptions;
/**
* Indicates whether the shift key was pressed or not when an event occurred
* @example cy.realMouseMove({ shiftKey: true });
*/
shiftKey?: boolean;
}

/** @ignore this, update documentation for this function at index.d.ts */
Expand Down Expand Up @@ -46,6 +52,7 @@ export async function realMouseMove(
type: "mouseMoved",
x: x * basePosition.frameScale + basePosition.x,
y: y * basePosition.frameScale + basePosition.y,
modifiers: options.shiftKey ? keyToModifierBitMap.Shift : 0,
});

log.snapshot("after").end();
Expand Down
7 changes: 7 additions & 0 deletions src/commands/mouseUp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
Position,
} from "../getCypressElementCoordinates";
import { mouseButtonNumbers } from "../mouseButtonNumbers";
import { keyToModifierBitMap } from "../keyToModifierBitMap";

export interface realMouseUpOptions {
/** Pointer type for realMouseUp, if "pen" touch simulated */
Expand All @@ -23,6 +24,11 @@ export interface realMouseUpOptions {
* @default "left"
*/
button?: keyof typeof mouseButtonNumbers;
/**
* Indicates whether the shift key was pressed or not when an event occurred
* @example cy.realMouseUp({ shiftKey: true });
*/
shiftKey?: boolean;
}

/** @ignore this, update documentation for this function at index.d.ts */
Expand Down Expand Up @@ -50,6 +56,7 @@ export async function realMouseUp(
buttons: mouseButtonNumbers[options.button ?? "left"],
pointerType: options.pointer ?? "mouse",
button: options.button ?? "left",
modifiers: options.shiftKey ? keyToModifierBitMap.Shift : 0,
});

log.snapshot("after").end();
Expand Down
8 changes: 8 additions & 0 deletions src/commands/realClick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
Position,
} from "../getCypressElementCoordinates";
import { mouseButtonNumbers } from "../mouseButtonNumbers";
import { keyToModifierBitMap } from "../keyToModifierBitMap";

export interface RealClickOptions {
/** Pointer type for realClick, if "pen" touch simulated */
Expand Down Expand Up @@ -38,6 +39,11 @@ export interface RealClickOptions {
* @example cy.realClick({ clickCount: 2 });
*/
clickCount?: number;
/**
* Indicates whether the shift key was pressed or not when an event occurred
* @example cy.realClick({ shiftKey: true });
*/
shiftKey?: boolean;
}

/** @ignore this, update documentation for this function at index.d.ts */
Expand Down Expand Up @@ -78,6 +84,7 @@ export async function realClick(
buttons: mouseButtonNumbers[options.button ?? "left"],
pointerType: options.pointer ?? "mouse",
button: options.button ?? "left",
modifiers: options.shiftKey ? keyToModifierBitMap.Shift : 0,
});

await fireCdpCommand("Input.dispatchMouseEvent", {
Expand All @@ -88,6 +95,7 @@ export async function realClick(
buttons: mouseButtonNumbers[options.button ?? "left"],
pointerType: options.pointer ?? "mouse",
button: options.button ?? "left",
modifiers: options.shiftKey ? keyToModifierBitMap.Shift : 0,
});
}

Expand Down
7 changes: 7 additions & 0 deletions src/commands/realHover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
ScrollBehaviorOptions,
getCypressElementCoordinates,
} from "../getCypressElementCoordinates";
import { keyToModifierBitMap } from "../keyToModifierBitMap";

export interface RealHoverOptions {
/**
Expand All @@ -20,6 +21,11 @@ export interface RealHoverOptions {
* @example cy.realHover({ scrollBehavior: "top" });
*/
scrollBehavior?: ScrollBehaviorOptions;
/**
* Indicates whether the shift key was pressed or not when an event occurred
* @example cy.realHover({ shiftKey: true });
*/
shiftKey?: boolean;
}

/** @ignore this, update documentation for this function at index.d.ts */
Expand All @@ -44,6 +50,7 @@ export async function realHover(
type: "mouseMoved",
button: "none",
pointerType: options.pointer ?? "mouse",
modifiers: options.shiftKey ? keyToModifierBitMap.Shift : 0,
});

log.snapshot().end();
Expand Down
8 changes: 1 addition & 7 deletions src/commands/realPress.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { fireCdpCommand } from "../fireCdpCommand";
import { keyCodeDefinitions } from "../keyCodeDefinitions";
import { keyToModifierBitMap } from "../keyToModifierBitMap";

export interface RealPressOptions {
/**
Expand Down Expand Up @@ -34,13 +35,6 @@ function getKeyDefinition(key: keyof typeof keyCodeDefinitions) {
};
}

const keyToModifierBitMap: Record<string, number> = {
Alt: 1,
Control: 2,
Meta: 4,
Shift: 8,
};

type Key = keyof typeof keyCodeDefinitions;
// unfortunately passing a string like Shift+P is not possible cause typescript template literals can not handle such giant union
type KeyOrShortcut = Key | Array<Key>;
Expand Down
6 changes: 6 additions & 0 deletions src/keyToModifierBitMap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const keyToModifierBitMap: Record<string, number> = {
Alt: 1,
Control: 2,
Meta: 4,
Shift: 8,
};

0 comments on commit 769273d

Please sign in to comment.