Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(commands): allow to fallback to charCodeAt if key is not in keyCodeDefinitions #631

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ cy.realPress(key, options);

| Name | Type | Default value | Description |
| --------- | -------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `key` | `string \| string[]` | - | key or keys to press. Should be the same as cypress's [type command argument](https://docs.cypress.io/api/commands/type.html#Arguments). All the keys available [here](https://github.com/dmtrKovalenko/cypress-real-events/blob/main/src/keyCodeDefinitions.ts) |
| `key` | `string \| string[]` | - | key or keys to press. Should be the same as cypress's [type command argument](https://docs.cypress.io/api/commands/type.html#Arguments). |
| `options` | Options | {} | |

Options:
Expand Down Expand Up @@ -217,7 +217,7 @@ cy.realType(text, options);

| Name | Type | Default value | Description |
| --------- | ------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `text` | string | - | text to type. Should be around the same as cypress's type command argument (https://docs.cypress.io/api/commands/type.html#Arguments. All the keys available [here](https://github.com/dmtrKovalenko/cypress-real-events/blob/main/src/keyCodeDefinitions.ts) |
| `text` | string | - | text to type. Should be around the same as cypress's type command argument |
| `options` | Options | {} | |

Options:
Expand Down
13 changes: 13 additions & 0 deletions cypress/e2e/press.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,19 @@ describe("cy.realPress", { retries: 10 }, () => {
cy.get("input").should("have.value", "cypress");
});

it("Can type non alpha-num into an input", () => {
cy.intercept("http://presstest.com/", (req) => {
const html = document.implementation.createHTMLDocument();
html.body.innerHTML = `<input type="text">`;
req.reply(html.documentElement.innerHTML);
});
cy.visit("http://presstest.com/");
cy.get("input").focus();

cy.realPress("😊");
cy.get("input").should("have.value", "😊");
});

it("Can fire native Tab focus switch", () => {
cy.visit("./cypress/fixtures/focus-order.html");
cy.window().focus();
Expand Down
7 changes: 7 additions & 0 deletions cypress/e2e/type.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,11 @@ describe("cy.realType", () => {
cy.realType("{{}test}");
cy.get("input[name=q]").should("have.value", "{test}");
});

it("can type text with emoji and cyrillic characters", () => {
const msg = "cypress-real-events is awesome! ❤️❤️❤️❤️❤️❤️ В";
cy.realType(msg);

cy.get("input[name=q]").should("have.value", msg);
});
});
27 changes: 23 additions & 4 deletions src/commands/realPress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,29 @@ export interface RealPressOptions {
log?: boolean;
}

function getKeyDefinition(key: keyof typeof keyCodeDefinitions) {
const keyDefinition = keyCodeDefinitions[key];
// Emoji Unicode range
const EMOJI_RE =
/[\u{1F600}-\u{1F64F}\u{1F300}-\u{1F5FF}\u{1F680}-\u{1F6FF}\u{1F700}-\u{1F77F}\u{1F780}-\u{1F7FF}\u{1F800}-\u{1F8FF}\u{1F900}-\u{1F9FF}\u{1FA00}-\u{1FA6F}\u{2600}-\u{26FF}\u{2700}-\u{27BF}]/u;

function isEmoji(char: string) {
return EMOJI_RE.test(char);
}

function getKeyDefinition(key: string) {
const keyDefinition =
keyCodeDefinitions[key as keyof typeof keyCodeDefinitions];

if (!keyDefinition) {
if (key.length === 1 || isEmoji(key)) {
return {
keyCode: key.charCodeAt(0),
key,
text: key,
code: `Key${key.toUpperCase()}`,
location: 0,
windowsVirtualKeyCode: key.charCodeAt(0),
};
}
throw new Error(`Unsupported key '${key}'.`);
}

Expand All @@ -38,11 +57,11 @@ function getKeyDefinition(key: keyof typeof keyCodeDefinitions) {

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>;
export type KeyOrShortcut = Key | Array<Key>;

/** @ignore this, update documentation for this function at index.d.ts */
export async function realPress(
keyOrShortcut: KeyOrShortcut,
keyOrShortcut: string | string[],
options: RealPressOptions = {},
) {
let log;
Expand Down
15 changes: 3 additions & 12 deletions src/commands/realType.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { realPress, type KeyOrShortcut } from "./";
import { keyCodeDefinitions } from "../keyCodeDefinitions";
import { realPress } from "./realPress";
import { wait } from "../utils";


export interface RealTypeOptions {
/**
* Delay after each keypress (ms)
Expand All @@ -20,15 +21,6 @@ export interface RealTypeOptions {
log?: boolean;
}

const availableChars = Object.keys(keyCodeDefinitions);
function assertChar(
char: string,
): asserts char is keyof typeof keyCodeDefinitions {
if (!availableChars.includes(char)) {
throw new Error(`Unrecognized character "${char}".`);
}
}

/** @ignore this, update documentation for this function at index.d.ts */
export async function realType(text: string, options: RealTypeOptions = {}) {
let log;
Expand All @@ -53,8 +45,7 @@ export async function realType(text: string, options: RealTypeOptions = {}) {
}, [] as string[]);

for (const char of chars) {
assertChar(char);
await realPress(char, {
await realPress(char as KeyOrShortcut, {
pressDelay: options.pressDelay ?? 15,
log: false,
});
Expand Down