Skip to main content
SeleniumDecoded

Keyboard Actions

Master keyboard interactions including special keys, key combinations, and the Actions API.

Selenium 3 & 4 Stable

Keyboard interactions go beyond simple typing. This guide covers special keys, key combinations, and advanced keyboard actions using the Actions API.

Special Keys

Selenium provides constants for special keys that can’t be typed directly:

Using Special Keys
Selenium 3 & 4 Stable
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
WebElement input = driver.findElement(By.id("search"));
// Navigation keys
input.sendKeys(Keys.ENTER); // Press Enter
input.sendKeys(Keys.TAB); // Move to next field
input.sendKeys(Keys.ESCAPE); // Press Escape
input.sendKeys(Keys.BACK_SPACE); // Delete character before cursor
input.sendKeys(Keys.DELETE); // Delete character after cursor
// Arrow keys
input.sendKeys(Keys.ARROW_UP);
input.sendKeys(Keys.ARROW_DOWN);
input.sendKeys(Keys.ARROW_LEFT);
input.sendKeys(Keys.ARROW_RIGHT);
// Home/End/Page
input.sendKeys(Keys.HOME); // Go to beginning
input.sendKeys(Keys.END); // Go to end
input.sendKeys(Keys.PAGE_UP);
input.sendKeys(Keys.PAGE_DOWN);
// Function keys
input.sendKeys(Keys.F1); // Help (in some apps)
input.sendKeys(Keys.F5); // Refresh (browser)
input.sendKeys(Keys.F12); // DevTools (browser)
// Combine with text
input.sendKeys("hello" + Keys.ENTER);
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
input_field = driver.find_element(By.ID, "search")
# Navigation keys
input_field.send_keys(Keys.ENTER) # Press Enter
input_field.send_keys(Keys.TAB) # Move to next field
input_field.send_keys(Keys.ESCAPE) # Press Escape
input_field.send_keys(Keys.BACK_SPACE) # Delete character before cursor
input_field.send_keys(Keys.DELETE) # Delete character after cursor
# Arrow keys
input_field.send_keys(Keys.ARROW_UP)
input_field.send_keys(Keys.ARROW_DOWN)
input_field.send_keys(Keys.ARROW_LEFT)
input_field.send_keys(Keys.ARROW_RIGHT)
# Home/End/Page
input_field.send_keys(Keys.HOME) # Go to beginning
input_field.send_keys(Keys.END) # Go to end
input_field.send_keys(Keys.PAGE_UP)
input_field.send_keys(Keys.PAGE_DOWN)
# Function keys
input_field.send_keys(Keys.F1) # Help (in some apps)
input_field.send_keys(Keys.F5) # Refresh (browser)
input_field.send_keys(Keys.F12) # DevTools (browser)
# Combine with text
input_field.send_keys("hello" + Keys.ENTER)
const { Key } = require('selenium-webdriver');
const input = await driver.findElement(By.id('search'));
// Navigation keys
await input.sendKeys(Key.ENTER); // Press Enter
await input.sendKeys(Key.TAB); // Move to next field
await input.sendKeys(Key.ESCAPE); // Press Escape
await input.sendKeys(Key.BACK_SPACE); // Delete character before cursor
await input.sendKeys(Key.DELETE); // Delete character after cursor
// Arrow keys
await input.sendKeys(Key.ARROW_UP);
await input.sendKeys(Key.ARROW_DOWN);
await input.sendKeys(Key.ARROW_LEFT);
await input.sendKeys(Key.ARROW_RIGHT);
// Home/End/Page
await input.sendKeys(Key.HOME); // Go to beginning
await input.sendKeys(Key.END); // Go to end
await input.sendKeys(Key.PAGE_UP);
await input.sendKeys(Key.PAGE_DOWN);
// Function keys
await input.sendKeys(Key.F1); // Help (in some apps)
await input.sendKeys(Key.F5); // Refresh (browser)
await input.sendKeys(Key.F12); // DevTools (browser)
// Combine with text
await input.sendKeys('hello', Key.ENTER);
using OpenQA.Selenium;
IWebElement input = driver.FindElement(By.Id("search"));
// Navigation keys
input.SendKeys(Keys.Enter); // Press Enter
input.SendKeys(Keys.Tab); // Move to next field
input.SendKeys(Keys.Escape); // Press Escape
input.SendKeys(Keys.Backspace); // Delete character before cursor
input.SendKeys(Keys.Delete); // Delete character after cursor
// Arrow keys
input.SendKeys(Keys.ArrowUp);
input.SendKeys(Keys.ArrowDown);
input.SendKeys(Keys.ArrowLeft);
input.SendKeys(Keys.ArrowRight);
// Home/End/Page
input.SendKeys(Keys.Home); // Go to beginning
input.SendKeys(Keys.End); // Go to end
input.SendKeys(Keys.PageUp);
input.SendKeys(Keys.PageDown);
// Function keys
input.SendKeys(Keys.F1); // Help (in some apps)
input.SendKeys(Keys.F5); // Refresh (browser)
input.SendKeys(Keys.F12); // DevTools (browser)
// Combine with text
input.SendKeys("hello" + Keys.Enter);

Key Combinations (Modifier Keys)

Use modifier keys (Ctrl, Alt, Shift) for keyboard shortcuts:

Key Combinations
Selenium 3 & 4 Stable
import org.openqa.selenium.Keys;
WebElement textArea = driver.findElement(By.id("editor"));
// Select all (Ctrl+A)
textArea.sendKeys(Keys.chord(Keys.CONTROL, "a"));
// Copy (Ctrl+C)
textArea.sendKeys(Keys.chord(Keys.CONTROL, "c"));
// Paste (Ctrl+V)
textArea.sendKeys(Keys.chord(Keys.CONTROL, "v"));
// Cut (Ctrl+X)
textArea.sendKeys(Keys.chord(Keys.CONTROL, "x"));
// Undo (Ctrl+Z)
textArea.sendKeys(Keys.chord(Keys.CONTROL, "z"));
// Redo (Ctrl+Y or Ctrl+Shift+Z)
textArea.sendKeys(Keys.chord(Keys.CONTROL, "y"));
textArea.sendKeys(Keys.chord(Keys.CONTROL, Keys.SHIFT, "z"));
// Save (Ctrl+S) - useful for web editors
textArea.sendKeys(Keys.chord(Keys.CONTROL, "s"));
// Find (Ctrl+F)
driver.findElement(By.tagName("body")).sendKeys(Keys.chord(Keys.CONTROL, "f"));
// New tab (Ctrl+T)
driver.findElement(By.tagName("body")).sendKeys(Keys.chord(Keys.CONTROL, "t"));
// Mac users: Use Keys.COMMAND instead of Keys.CONTROL
String osName = System.getProperty("os.name").toLowerCase();
Keys modifier = osName.contains("mac") ? Keys.COMMAND : Keys.CONTROL;
textArea.sendKeys(Keys.chord(modifier, "a"));
import platform
text_area = driver.find_element(By.ID, "editor")
# Select all (Ctrl+A)
text_area.send_keys(Keys.CONTROL + "a")
# Copy (Ctrl+C)
text_area.send_keys(Keys.CONTROL + "c")
# Paste (Ctrl+V)
text_area.send_keys(Keys.CONTROL + "v")
# Cut (Ctrl+X)
text_area.send_keys(Keys.CONTROL + "x")
# Undo (Ctrl+Z)
text_area.send_keys(Keys.CONTROL + "z")
# Redo (Ctrl+Y or Ctrl+Shift+Z)
text_area.send_keys(Keys.CONTROL + "y")
text_area.send_keys(Keys.CONTROL + Keys.SHIFT + "z")
# Save (Ctrl+S) - useful for web editors
text_area.send_keys(Keys.CONTROL + "s")
# Find (Ctrl+F)
driver.find_element(By.TAG_NAME, "body").send_keys(Keys.CONTROL + "f")
# Mac users: Use Keys.COMMAND instead of Keys.CONTROL
modifier = Keys.COMMAND if platform.system() == "Darwin" else Keys.CONTROL
text_area.send_keys(modifier + "a")
const input = await driver.findElement(By.id('editor'));
// Select all (Ctrl+A)
await input.sendKeys(Key.chord(Key.CONTROL, 'a'));
// Copy (Ctrl+C)
await input.sendKeys(Key.chord(Key.CONTROL, 'c'));
// Paste (Ctrl+V)
await input.sendKeys(Key.chord(Key.CONTROL, 'v'));
// Cut (Ctrl+X)
await input.sendKeys(Key.chord(Key.CONTROL, 'x'));
// Undo (Ctrl+Z)
await input.sendKeys(Key.chord(Key.CONTROL, 'z'));
// Redo (Ctrl+Y)
await input.sendKeys(Key.chord(Key.CONTROL, 'y'));
// Save (Ctrl+S)
await input.sendKeys(Key.chord(Key.CONTROL, 's'));
// Find (Ctrl+F)
const body = await driver.findElement(By.tagName('body'));
await body.sendKeys(Key.chord(Key.CONTROL, 'f'));
// Platform-specific modifier
const os = require('os');
const modifier = os.platform() === 'darwin' ? Key.COMMAND : Key.CONTROL;
await input.sendKeys(Key.chord(modifier, 'a'));
IWebElement textArea = driver.FindElement(By.Id("editor"));
// Select all (Ctrl+A)
textArea.SendKeys(Keys.Control + "a");
// Copy (Ctrl+C)
textArea.SendKeys(Keys.Control + "c");
// Paste (Ctrl+V)
textArea.SendKeys(Keys.Control + "v");
// Cut (Ctrl+X)
textArea.SendKeys(Keys.Control + "x");
// Undo (Ctrl+Z)
textArea.SendKeys(Keys.Control + "z");
// Redo (Ctrl+Y or Ctrl+Shift+Z)
textArea.SendKeys(Keys.Control + "y");
textArea.SendKeys(Keys.Control + Keys.Shift + "z");
// Save (Ctrl+S)
textArea.SendKeys(Keys.Control + "s");
// Find (Ctrl+F)
driver.FindElement(By.TagName("body")).SendKeys(Keys.Control + "f");
// Platform-specific modifier
bool isMac = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
string modifier = isMac ? Keys.Command : Keys.Control;
textArea.SendKeys(modifier + "a");

Actions API for Keyboard

The Actions API provides more control over keyboard interactions:

Actions API Keyboard Control
Selenium 3 & 4 Stable
import org.openqa.selenium.interactions.Actions;
Actions actions = new Actions(driver);
// Hold down modifier key while typing
actions.keyDown(Keys.SHIFT)
.sendKeys("hello") // Types "HELLO"
.keyUp(Keys.SHIFT)
.perform();
// Select text with Shift+Arrow
WebElement input = driver.findElement(By.id("text-field"));
input.sendKeys("Hello World");
input.sendKeys(Keys.HOME); // Go to start
actions.keyDown(Keys.SHIFT)
.sendKeys(Keys.END) // Select all
.keyUp(Keys.SHIFT)
.perform();
// Multiple key presses
actions.keyDown(Keys.CONTROL)
.keyDown(Keys.SHIFT)
.sendKeys("n") // Ctrl+Shift+N (new incognito window in Chrome)
.keyUp(Keys.SHIFT)
.keyUp(Keys.CONTROL)
.perform();
// Press and release keys without an element
actions.sendKeys(Keys.ESCAPE).perform();
// Send keys to specific element
actions.sendKeys(input, "typed text").perform();
from selenium.webdriver.common.action_chains import ActionChains
actions = ActionChains(driver)
# Hold down modifier key while typing
actions.key_down(Keys.SHIFT) .send_keys("hello") .key_up(Keys.SHIFT) .perform() # Types "HELLO"
# Select text with Shift+Arrow
input_field = driver.find_element(By.ID, "text-field")
input_field.send_keys("Hello World")
input_field.send_keys(Keys.HOME) # Go to start
actions = ActionChains(driver) # Reset chain
actions.key_down(Keys.SHIFT) .send_keys(Keys.END) .key_up(Keys.SHIFT) .perform() # Select all
# Multiple key presses
actions = ActionChains(driver)
actions.key_down(Keys.CONTROL) .key_down(Keys.SHIFT) .send_keys("n") .key_up(Keys.SHIFT) .key_up(Keys.CONTROL) .perform()
# Press and release keys without an element
actions = ActionChains(driver)
actions.send_keys(Keys.ESCAPE).perform()
# Send keys to specific element
actions = ActionChains(driver)
actions.send_keys_to_element(input_field, "typed text").perform()
const actions = driver.actions({ async: true });
// Hold down modifier key while typing
await actions
.keyDown(Key.SHIFT)
.sendKeys('hello') // Types "HELLO"
.keyUp(Key.SHIFT)
.perform();
// Select text with Shift+Arrow
const input = await driver.findElement(By.id('text-field'));
await input.sendKeys('Hello World');
await input.sendKeys(Key.HOME); // Go to start
await driver.actions({ async: true })
.keyDown(Key.SHIFT)
.sendKeys(Key.END) // Select all
.keyUp(Key.SHIFT)
.perform();
// Multiple key presses
await driver.actions({ async: true })
.keyDown(Key.CONTROL)
.keyDown(Key.SHIFT)
.sendKeys('n')
.keyUp(Key.SHIFT)
.keyUp(Key.CONTROL)
.perform();
// Press and release keys without an element
await driver.actions({ async: true })
.sendKeys(Key.ESCAPE)
.perform();
// Send keys to specific element
await driver.actions({ async: true })
.sendKeys(input, 'typed text')
.perform();
using OpenQA.Selenium.Interactions;
Actions actions = new Actions(driver);
// Hold down modifier key while typing
actions.KeyDown(Keys.Shift)
.SendKeys("hello") // Types "HELLO"
.KeyUp(Keys.Shift)
.Perform();
// Select text with Shift+Arrow
IWebElement input = driver.FindElement(By.Id("text-field"));
input.SendKeys("Hello World");
input.SendKeys(Keys.Home); // Go to start
new Actions(driver)
.KeyDown(Keys.Shift)
.SendKeys(Keys.End) // Select all
.KeyUp(Keys.Shift)
.Perform();
// Multiple key presses
new Actions(driver)
.KeyDown(Keys.Control)
.KeyDown(Keys.Shift)
.SendKeys("n")
.KeyUp(Keys.Shift)
.KeyUp(Keys.Control)
.Perform();
// Press and release keys without an element
new Actions(driver).SendKeys(Keys.Escape).Perform();
// Send keys to specific element
new Actions(driver).SendKeys(input, "typed text").Perform();

Common Keyboard Patterns

Tab Navigation

Tab Through Form Fields
Selenium 3 & 4 Stable
// Fill form using Tab to move between fields
driver.findElement(By.id("firstName")).sendKeys("John" + Keys.TAB);
// Cursor now in next field
driver.switchTo().activeElement().sendKeys("Doe" + Keys.TAB);
// Continue...
driver.switchTo().activeElement().sendKeys("john@example.com" + Keys.TAB);
// Shift+Tab to go backwards
driver.switchTo().activeElement().sendKeys(Keys.chord(Keys.SHIFT, Keys.TAB));
# Fill form using Tab to move between fields
driver.find_element(By.ID, "firstName").send_keys("John" + Keys.TAB)
# Cursor now in next field
driver.switch_to.active_element.send_keys("Doe" + Keys.TAB)
# Continue...
driver.switch_to.active_element.send_keys("john@example.com" + Keys.TAB)
# Shift+Tab to go backwards
driver.switch_to.active_element.send_keys(Keys.SHIFT + Keys.TAB)
// Fill form using Tab to move between fields
await driver.findElement(By.id('firstName')).sendKeys('John', Key.TAB);
// Cursor now in next field
await driver.switchTo().activeElement().sendKeys('Doe', Key.TAB);
// Continue...
await driver.switchTo().activeElement().sendKeys('john@example.com', Key.TAB);
// Shift+Tab to go backwards
await driver.switchTo().activeElement().sendKeys(Key.chord(Key.SHIFT, Key.TAB));
// Fill form using Tab to move between fields
driver.FindElement(By.Id("firstName")).SendKeys("John" + Keys.Tab);
// Cursor now in next field
driver.SwitchTo().ActiveElement().SendKeys("Doe" + Keys.Tab);
// Continue...
driver.SwitchTo().ActiveElement().SendKeys("john@example.com" + Keys.Tab);
// Shift+Tab to go backwards
driver.SwitchTo().ActiveElement().SendKeys(Keys.Shift + Keys.Tab);

Text Selection and Editing

Text Selection Patterns
Selenium 3 & 4 Stable
WebElement editor = driver.findElement(By.id("editor"));
editor.sendKeys("Hello World");
// Select word with double Ctrl+Shift+Arrow
Actions actions = new Actions(driver);
actions.click(editor)
.keyDown(Keys.CONTROL)
.keyDown(Keys.SHIFT)
.sendKeys(Keys.ARROW_LEFT) // Select previous word
.keyUp(Keys.SHIFT)
.keyUp(Keys.CONTROL)
.perform();
// Delete selected text
actions.sendKeys(Keys.DELETE).perform();
// Select all and replace
editor.sendKeys(Keys.chord(Keys.CONTROL, "a"));
editor.sendKeys("New content"); // Replaces all
editor = driver.find_element(By.ID, "editor")
editor.send_keys("Hello World")
# Select word with double Ctrl+Shift+Arrow
actions = ActionChains(driver)
actions.click(editor) .key_down(Keys.CONTROL) .key_down(Keys.SHIFT) .send_keys(Keys.ARROW_LEFT) .key_up(Keys.SHIFT) .key_up(Keys.CONTROL) .perform()
# Delete selected text
ActionChains(driver).send_keys(Keys.DELETE).perform()
# Select all and replace
editor.send_keys(Keys.CONTROL + "a")
editor.send_keys("New content") # Replaces all
const editor = await driver.findElement(By.id('editor'));
await editor.sendKeys('Hello World');
// Select word with Ctrl+Shift+Arrow
await driver.actions({ async: true })
.click(editor)
.keyDown(Key.CONTROL)
.keyDown(Key.SHIFT)
.sendKeys(Key.ARROW_LEFT) // Select previous word
.keyUp(Key.SHIFT)
.keyUp(Key.CONTROL)
.perform();
// Delete selected text
await driver.actions({ async: true })
.sendKeys(Key.DELETE)
.perform();
// Select all and replace
await editor.sendKeys(Key.chord(Key.CONTROL, 'a'));
await editor.sendKeys('New content'); // Replaces all
IWebElement editor = driver.FindElement(By.Id("editor"));
editor.SendKeys("Hello World");
// Select word with Ctrl+Shift+Arrow
new Actions(driver)
.Click(editor)
.KeyDown(Keys.Control)
.KeyDown(Keys.Shift)
.SendKeys(Keys.ArrowLeft) // Select previous word
.KeyUp(Keys.Shift)
.KeyUp(Keys.Control)
.Perform();
// Delete selected text
new Actions(driver).SendKeys(Keys.Delete).Perform();
// Select all and replace
editor.SendKeys(Keys.Control + "a");
editor.SendKeys("New content"); // Replaces all

Key Reference Table

ActionWindows/LinuxMac
Select AllCtrl+ACmd+A
CopyCtrl+CCmd+C
PasteCtrl+VCmd+V
CutCtrl+XCmd+X
UndoCtrl+ZCmd+Z
RedoCtrl+YCmd+Shift+Z
SaveCtrl+SCmd+S
FindCtrl+FCmd+F
New TabCtrl+TCmd+T
Close TabCtrl+WCmd+W

Best Practices

  1. Use Actions API for complex key sequences
  2. Always release modifier keys (keyUp after keyDown)
  3. Test on target OS - key combinations vary by platform
  4. Add small delays if keys are sent too fast
  5. Verify the active element before sending keys

Next Steps