Input
This section contains the APIs related to input commands.
Perform Actions
Actions selectThreeOptions =
actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);
input.perform(windowHandle, selectThreeOptions.getSequences());/examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ActionsTest.java
package dev.selenium.bidirectional.webdriver_bidi;
import dev.selenium.BaseTest;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Input;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.interactions.Actions;
class ActionsTest extends BaseTest {
private Input input;
private String windowHandle;
@BeforeEach
public void setup() {
FirefoxOptions options = new FirefoxOptions();
options.setCapability("webSocketUrl", true);
driver = new FirefoxDriver(options);
windowHandle = driver.getWindowHandle();
input = new Input(driver);
}
@Test
void canPerformInputActions() {
driver.get("https://www.selenium.dev/selenium/web/formSelectionPage.html");
List<WebElement> options = driver.findElements(By.tagName("option"));
Actions actions = new Actions(driver);
Actions selectThreeOptions =
actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);
input.perform(windowHandle, selectThreeOptions.getSequences());
WebElement showButton = driver.findElement(By.name("showselected"));
showButton.click();
WebElement resultElement = driver.findElement(By.id("result"));
Assertions.assertTrue(resultElement.getText().contains("roquefort parmigiano cheddar"));
}
@Test
void canPerformReleaseAction() {
driver.get("https://www.selenium.dev/selenium/web/bidi/release_action.html");
WebElement inputTextBox = driver.findElement(By.id("keys"));
Actions sendLowercase =
new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");
input.perform(windowHandle, sendLowercase.getSequences());
((JavascriptExecutor) driver).executeScript("resetEvents()");
input.release(windowHandle);
List<Map<String, Object>> events =
(List<Map<String, Object>>)
((JavascriptExecutor) driver).executeScript("return allEvents.events");
Assertions.assertEquals("KeyB", events.get(0).get("code"));
Assertions.assertEquals("KeyA", events.get(1).get("code"));
}
}
it 'sends keyboard input' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
input_field = driver.find_element(id: 'textInput')
input_field.send_keys('Hello World')
expect(input_field.attribute('value')).to eq('Hello World')
end
/examples/ruby/spec/bidi/input_spec.rb
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Input' do
let(:driver) { start_bidi_session }
let(:wait) { Selenium::WebDriver::Wait.new(timeout: 5) }
it 'sends keyboard input' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
input_field = driver.find_element(id: 'textInput')
input_field.send_keys('Hello World')
expect(input_field.attribute('value')).to eq('Hello World')
end
it 'sends key press' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
input_field = driver.find_element(id: 'textInput')
input_field.send_keys('a')
expect(input_field.attribute('value')).to include('a')
end
it 'clicks element' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
button = driver.find_element(id: 'consoleLog')
button.click
expect(button).not_to be_nil
end
it 'double clicks element' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
element = driver.find_element(tag_name: 'body')
driver.action.double_click(element).perform
end
it 'right clicks element' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
element = driver.find_element(tag_name: 'body')
driver.action.context_click(element).perform
end
it 'dispatches keyboard events' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
driver.execute_script(<<~SCRIPT)
document.addEventListener('keydown', function(e) {
console.log('Key pressed: ' + e.key);
});
SCRIPT
body = driver.find_element(tag_name: 'body')
body.send_keys('a')
end
it 'dispatches mouse events' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
button = driver.find_element(id: 'consoleLog')
driver.execute_script(<<~SCRIPT, button)
arguments[0].addEventListener('mouseover', function(e) {
console.log('Mouse over');
});
SCRIPT
driver.action.move_to(button).perform
end
it 'performs drag and drop' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
element = driver.find_element(tag_name: 'body')
driver.action.drag_and_drop(element, element).perform
end
end
const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()
await input.perform(browsingContextId, actions)/examples/javascript/test/bidirectional/input.spec.js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, Key, Builder} = require("selenium-webdriver")
const Input = require('selenium-webdriver/bidi/input')
describe('Input module', function () {
let driver
beforeEach(async function () {
driver = new Builder()
.forBrowser('firefox')
.setFirefoxOptions(new firefox.Options().enableBidi())
.build()
})
afterEach(async function () {
await driver.quit()
})
it('can perform input action', async function () {
const browsingContextId = await driver.getWindowHandle()
const input = await Input(driver)
await driver.get('https://www.selenium.dev/selenium/web/formSelectionPage.html')
let options = await driver.findElements(By.tagName('option'))
const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()
await input.perform(browsingContextId, actions)
let showButton = await driver.findElement(By.name('showselected'))
showButton.click()
let resultElement = await driver.findElement(By.id('result'))
await resultElement.getText().then(function (text) {
assert(text.includes('oquefort parmigiano cheddar'), `text is: ${text}`)
})
})
it('can execute release in browsing context', async function () {
const browsingContextId = await driver.getWindowHandle()
const input = await Input(driver)
await driver.get('https://www.selenium.dev/selenium/web/bidi/release_action.html')
let inputTextBox = await driver.findElement(By.id('keys'))
await driver.executeScript('arguments[0].focus()', inputTextBox)
const actions = driver.actions().keyDown('a').keyDown('b').getSequences()
await input.perform(browsingContextId, actions)
await driver.executeScript('resetEvents()')
await input.release(browsingContextId)
const events = await driver.executeScript('return allEvents.events')
assert.strictEqual(events[0].code, 'KeyB')
assert.strictEqual(events[1].code, 'KeyA')
})
})
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
input_field = driver.find_element(id="textInput")
input_field.send_keys("Hello World")
assert input_field.get_attribute("value") == "Hello World"
@pytest.mark.driver_type("bidi")
def test_input_mouse_click(driver):
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
button = driver.find_element(id="consoleLog")
button.click()
# Verify click occurred
assert button is not None/examples/python/tests/bidi/test_bidi_input.py
import pytest
from selenium.webdriver.common.action_chains import ActionChains
@pytest.mark.driver_type("bidi")
def test_input_keyboard_actions(driver):
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
input_field = driver.find_element(id="textInput")
input_field.send_keys("Hello World")
assert input_field.get_attribute("value") == "Hello World"
@pytest.mark.driver_type("bidi")
def test_input_mouse_click(driver):
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
button = driver.find_element(id="consoleLog")
button.click()
# Verify click occurred
assert button is not None
@pytest.mark.driver_type("bidi")
def test_dispatch_keyboard_events(driver):
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
driver.execute_script("""
document.addEventListener('keydown', function(e) {
console.log('Key pressed: ' + e.key);
});
""")
body = driver.find_element(tag_name="body")
body.send_keys("a")
@pytest.mark.driver_type("bidi")
def test_dispatch_mouse_events(driver):
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
button = driver.find_element(id="consoleLog")
driver.execute_script("""
arguments[0].addEventListener('mouseover', function(e) {
console.log('Mouse over');
});
""", button)
actions = ActionChains(driver)
actions.move_to_element(button).perform()
@pytest.mark.driver_type("bidi")
def test_double_click(driver):
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
element = driver.find_element(tag_name="body")
actions = ActionChains(driver)
actions.double_click(element).perform()
@pytest.mark.driver_type("bidi")
def test_right_click(driver):
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
element = driver.find_element(tag_name="body")
actions = ActionChains(driver)
actions.context_click(element).perform()
@pytest.mark.driver_type("bidi")
def test_drag_and_drop(driver):
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
element = driver.find_element(tag_name="body")
actions = ActionChains(driver)
actions.drag_and_drop(element, element).perform()
Release Actions
Actions sendLowercase =
new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");
input.perform(windowHandle, sendLowercase.getSequences());
((JavascriptExecutor) driver).executeScript("resetEvents()");
input.release(windowHandle);/examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ActionsTest.java
package dev.selenium.bidirectional.webdriver_bidi;
import dev.selenium.BaseTest;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Input;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.interactions.Actions;
class ActionsTest extends BaseTest {
private Input input;
private String windowHandle;
@BeforeEach
public void setup() {
FirefoxOptions options = new FirefoxOptions();
options.setCapability("webSocketUrl", true);
driver = new FirefoxDriver(options);
windowHandle = driver.getWindowHandle();
input = new Input(driver);
}
@Test
void canPerformInputActions() {
driver.get("https://www.selenium.dev/selenium/web/formSelectionPage.html");
List<WebElement> options = driver.findElements(By.tagName("option"));
Actions actions = new Actions(driver);
Actions selectThreeOptions =
actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);
input.perform(windowHandle, selectThreeOptions.getSequences());
WebElement showButton = driver.findElement(By.name("showselected"));
showButton.click();
WebElement resultElement = driver.findElement(By.id("result"));
Assertions.assertTrue(resultElement.getText().contains("roquefort parmigiano cheddar"));
}
@Test
void canPerformReleaseAction() {
driver.get("https://www.selenium.dev/selenium/web/bidi/release_action.html");
WebElement inputTextBox = driver.findElement(By.id("keys"));
Actions sendLowercase =
new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");
input.perform(windowHandle, sendLowercase.getSequences());
((JavascriptExecutor) driver).executeScript("resetEvents()");
input.release(windowHandle);
List<Map<String, Object>> events =
(List<Map<String, Object>>)
((JavascriptExecutor) driver).executeScript("return allEvents.events");
Assertions.assertEquals("KeyB", events.get(0).get("code"));
Assertions.assertEquals("KeyA", events.get(1).get("code"));
}
}
input_field = driver.find_element(id: 'textInput')
input_field.send_keys('a')
expect(input_field.attribute('value')).to include('a')
end
it 'clicks element' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
button = driver.find_element(id: 'consoleLog')
button.click/examples/ruby/spec/bidi/input_spec.rb
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Input' do
let(:driver) { start_bidi_session }
let(:wait) { Selenium::WebDriver::Wait.new(timeout: 5) }
it 'sends keyboard input' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
input_field = driver.find_element(id: 'textInput')
input_field.send_keys('Hello World')
expect(input_field.attribute('value')).to eq('Hello World')
end
it 'sends key press' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
input_field = driver.find_element(id: 'textInput')
input_field.send_keys('a')
expect(input_field.attribute('value')).to include('a')
end
it 'clicks element' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
button = driver.find_element(id: 'consoleLog')
button.click
expect(button).not_to be_nil
end
it 'double clicks element' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
element = driver.find_element(tag_name: 'body')
driver.action.double_click(element).perform
end
it 'right clicks element' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
element = driver.find_element(tag_name: 'body')
driver.action.context_click(element).perform
end
it 'dispatches keyboard events' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
driver.execute_script(<<~SCRIPT)
document.addEventListener('keydown', function(e) {
console.log('Key pressed: ' + e.key);
});
SCRIPT
body = driver.find_element(tag_name: 'body')
body.send_keys('a')
end
it 'dispatches mouse events' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
button = driver.find_element(id: 'consoleLog')
driver.execute_script(<<~SCRIPT, button)
arguments[0].addEventListener('mouseover', function(e) {
console.log('Mouse over');
});
SCRIPT
driver.action.move_to(button).perform
end
it 'performs drag and drop' do
driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
element = driver.find_element(tag_name: 'body')
driver.action.drag_and_drop(element, element).perform
end
end
await input.release(browsingContextId)/examples/javascript/test/bidirectional/input.spec.js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, Key, Builder} = require("selenium-webdriver")
const Input = require('selenium-webdriver/bidi/input')
describe('Input module', function () {
let driver
beforeEach(async function () {
driver = new Builder()
.forBrowser('firefox')
.setFirefoxOptions(new firefox.Options().enableBidi())
.build()
})
afterEach(async function () {
await driver.quit()
})
it('can perform input action', async function () {
const browsingContextId = await driver.getWindowHandle()
const input = await Input(driver)
await driver.get('https://www.selenium.dev/selenium/web/formSelectionPage.html')
let options = await driver.findElements(By.tagName('option'))
const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()
await input.perform(browsingContextId, actions)
let showButton = await driver.findElement(By.name('showselected'))
showButton.click()
let resultElement = await driver.findElement(By.id('result'))
await resultElement.getText().then(function (text) {
assert(text.includes('oquefort parmigiano cheddar'), `text is: ${text}`)
})
})
it('can execute release in browsing context', async function () {
const browsingContextId = await driver.getWindowHandle()
const input = await Input(driver)
await driver.get('https://www.selenium.dev/selenium/web/bidi/release_action.html')
let inputTextBox = await driver.findElement(By.id('keys'))
await driver.executeScript('arguments[0].focus()', inputTextBox)
const actions = driver.actions().keyDown('a').keyDown('b').getSequences()
await input.perform(browsingContextId, actions)
await driver.executeScript('resetEvents()')
await input.release(browsingContextId)
const events = await driver.executeScript('return allEvents.events')
assert.strictEqual(events[0].code, 'KeyB')
assert.strictEqual(events[1].code, 'KeyA')
})
})
@pytest.mark.driver_type("bidi")
def test_dispatch_keyboard_events(driver):
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
driver.execute_script("""
document.addEventListener('keydown', function(e) {
console.log('Key pressed: ' + e.key);
});
""")
body = driver.find_element(tag_name="body")
body.send_keys("a")
@pytest.mark.driver_type("bidi")
def test_dispatch_mouse_events(driver):
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
/examples/python/tests/bidi/test_bidi_input.py
import pytest
from selenium.webdriver.common.action_chains import ActionChains
@pytest.mark.driver_type("bidi")
def test_input_keyboard_actions(driver):
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
input_field = driver.find_element(id="textInput")
input_field.send_keys("Hello World")
assert input_field.get_attribute("value") == "Hello World"
@pytest.mark.driver_type("bidi")
def test_input_mouse_click(driver):
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
button = driver.find_element(id="consoleLog")
button.click()
# Verify click occurred
assert button is not None
@pytest.mark.driver_type("bidi")
def test_dispatch_keyboard_events(driver):
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
driver.execute_script("""
document.addEventListener('keydown', function(e) {
console.log('Key pressed: ' + e.key);
});
""")
body = driver.find_element(tag_name="body")
body.send_keys("a")
@pytest.mark.driver_type("bidi")
def test_dispatch_mouse_events(driver):
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
button = driver.find_element(id="consoleLog")
driver.execute_script("""
arguments[0].addEventListener('mouseover', function(e) {
console.log('Mouse over');
});
""", button)
actions = ActionChains(driver)
actions.move_to_element(button).perform()
@pytest.mark.driver_type("bidi")
def test_double_click(driver):
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
element = driver.find_element(tag_name="body")
actions = ActionChains(driver)
actions.double_click(element).perform()
@pytest.mark.driver_type("bidi")
def test_right_click(driver):
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
element = driver.find_element(tag_name="body")
actions = ActionChains(driver)
actions.context_click(element).perform()
@pytest.mark.driver_type("bidi")
def test_drag_and_drop(driver):
driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
element = driver.find_element(tag_name="body")
actions = ActionChains(driver)
actions.drag_and_drop(element, element).perform()
Last modified May 7, 2026: Phase 2: Update documentation with Ruby and Python BiDi code references (fcf23f0d63)




