diff --git a/README.md b/README.md
index 58191b1..1290a88 100644
--- a/README.md
+++ b/README.md
@@ -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:
@@ -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:
diff --git a/cypress/e2e/press.cy.ts b/cypress/e2e/press.cy.ts
index 4fdb40e..5ac98ce 100644
--- a/cypress/e2e/press.cy.ts
+++ b/cypress/e2e/press.cy.ts
@@ -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 = ``;
+ 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();
diff --git a/cypress/e2e/type.cy.ts b/cypress/e2e/type.cy.ts
index c71393a..346c1bf 100644
--- a/cypress/e2e/type.cy.ts
+++ b/cypress/e2e/type.cy.ts
@@ -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);
+ });
});
diff --git a/src/commands/realPress.ts b/src/commands/realPress.ts
index f4e10d9..21f6d3e 100644
--- a/src/commands/realPress.ts
+++ b/src/commands/realPress.ts
@@ -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}'.`);
}
@@ -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;
+export type KeyOrShortcut = Key | Array;
/** @ignore this, update documentation for this function at index.d.ts */
export async function realPress(
- keyOrShortcut: KeyOrShortcut,
+ keyOrShortcut: string | string[],
options: RealPressOptions = {},
) {
let log;
diff --git a/src/commands/realType.ts b/src/commands/realType.ts
index 5461c24..f67a053 100644
--- a/src/commands/realType.ts
+++ b/src/commands/realType.ts
@@ -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)
@@ -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;
@@ -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,
});