Actions API A low-level interface for providing virtualized device input actions to the web browser.
In addition to the high-level element interactions , the Actions API provides granular control over exactly what designated input devices can do. Selenium provides an interface for 3 kinds of input sources: a key input for keyboard devices, a pointer input for a mouse, pen or touch devices, and wheel inputs for scroll wheel devices (introduced in Selenium 4.2). Selenium allows you to construct individual action commands assigned to specific inputs and chain them together and call the associated perform method to execute them all at once.
Action Builder In the move from the legacy JSON Wire Protocol to the new W3C WebDriver Protocol, the low level building blocks of actions became especially detailed. It is extremely powerful, but each input device has a number of ways to use it and if you need to manage more than one device, you are responsible for ensuring proper synchronization between them.
Thankfully, you likely do not need to learn how to use the low level commands directly, since almost everything you might want to do has been given a convenience method that combines the lower level commands for you. These are all documented in keyboard , mouse , pen , and wheel pages.
Pause Pointer movements and Wheel scrolling allow the user to set a duration for the action, but sometimes you just need to wait a beat between actions for things to work correctly.
Java Python CSharp Ruby JavaScript Kotlin WebElement clickable = driver . findElement ( By . id ( "clickable" )); new Actions ( driver ) . moveToElement ( clickable ) . pause ( Duration . ofSeconds ( 1 )) . clickAndHold () . pause ( Duration . ofSeconds ( 1 )) . sendKeys ( "abc" ) . perform ();
examples/java/src/test/java/dev/selenium/actions_api/ActionsTest.java Copy Close
package dev.selenium.actions_api ; import dev.selenium.BaseChromeTest ; import org.junit.jupiter.api.Assertions ; import org.junit.jupiter.api.Test ; import org.openqa.selenium.By ; import org.openqa.selenium.Keys ; import org.openqa.selenium.WebElement ; import org.openqa.selenium.interactions.Actions ; import org.openqa.selenium.remote.RemoteWebDriver ; import java.time.Duration ; public class ActionsTest extends BaseChromeTest { @Test public void pause () { driver . get ( "https://www.selenium.dev/selenium/web/mouse_interaction.html" ); long start = System . currentTimeMillis (); WebElement clickable = driver . findElement ( By . id ( "clickable" )); new Actions ( driver ) . moveToElement ( clickable ) . pause ( Duration . ofSeconds ( 1 )) . clickAndHold () . pause ( Duration . ofSeconds ( 1 )) . sendKeys ( "abc" ) . perform (); long duration = System . currentTimeMillis () - start ; Assertions . assertTrue ( duration > 2000 ); Assertions . assertTrue ( duration < 3000 ); } @Test public void releasesAll () { driver . get ( "https://www.selenium.dev/selenium/web/mouse_interaction.html" ); WebElement clickable = driver . findElement ( By . id ( "clickable" )); Actions actions = new Actions ( driver ); actions . clickAndHold ( clickable ) . keyDown ( Keys . SHIFT ) . sendKeys ( "a" ) . perform (); (( RemoteWebDriver ) driver ). resetInputState (); actions . sendKeys ( "a" ). perform (); Assertions . assertEquals ( "A" , String . valueOf ( clickable . getAttribute ( "value" ). charAt ( 0 ))); Assertions . assertEquals ( "a" , String . valueOf ( clickable . getAttribute ( "value" ). charAt ( 1 ))); } }
clickable = driver . find_element ( By . ID , "clickable" ) ActionChains ( driver ) \ . move_to_element ( clickable ) \ . pause ( 1 ) \ . click_and_hold () \ . pause ( 1 ) \ . send_keys ( "abc" ) \ . perform ()
examples/python/tests/actions_api/test_actions.py Copy Close
from time import time from selenium.webdriver import Keys , ActionChains from selenium.webdriver.common.actions.action_builder import ActionBuilder from selenium.webdriver.common.by import By def test_pauses ( driver ): driver . get ( 'https://selenium.dev/selenium/web/mouse_interaction.html' ) start = time () clickable = driver . find_element ( By . ID , "clickable" ) ActionChains ( driver ) \ . move_to_element ( clickable ) \ . pause ( 1 ) \ . click_and_hold () \ . pause ( 1 ) \ . send_keys ( "abc" ) \ . perform () duration = time () - start assert duration > 2 assert duration < 3 def test_releases_all ( driver ): driver . get ( 'https://selenium.dev/selenium/web/mouse_interaction.html' ) clickable = driver . find_element ( By . ID , "clickable" ) ActionChains ( driver ) \ . click_and_hold ( clickable ) \ . key_down ( Keys . SHIFT ) \ . key_down ( "a" ) \ . perform () ActionBuilder ( driver ) . clear_actions () ActionChains ( driver ) . key_down ( 'a' ) . perform () assert clickable . get_attribute ( 'value' )[ 0 ] == "A" assert clickable . get_attribute ( 'value' )[ 1 ] == "a"
Selenium v4.2
IWebElement clickable = driver . FindElement ( By . Id ( "clickable" )); new Actions ( driver ) . MoveToElement ( clickable ) . Pause ( TimeSpan . FromSeconds ( 1 )) . ClickAndHold () . Pause ( TimeSpan . FromSeconds ( 1 )) . SendKeys ( "abc" ) . Perform ();
examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs Copy Close
using System ; using Microsoft.VisualStudio.TestTools.UnitTesting ; using OpenQA.Selenium ; using OpenQA.Selenium.Interactions ; namespace SeleniumDocs.ActionsAPI { [TestClass] public class ActionsTest : BaseChromeTest { [TestMethod] public void Pause () { driver . Url = "https://selenium.dev/selenium/web/mouse_interaction.html" ; DateTime start = DateTime . Now ; IWebElement clickable = driver . FindElement ( By . Id ( "clickable" )); new Actions ( driver ) . MoveToElement ( clickable ) . Pause ( TimeSpan . FromSeconds ( 1 )) . ClickAndHold () . Pause ( TimeSpan . FromSeconds ( 1 )) . SendKeys ( "abc" ) . Perform (); TimeSpan duration = DateTime . Now - start ; Assert . IsTrue ( duration > TimeSpan . FromSeconds ( 2 )); Assert . IsTrue ( duration < TimeSpan . FromSeconds ( 3 )); } [TestMethod] public void ReleaseAll () { driver . Url = "https://selenium.dev/selenium/web/mouse_interaction.html" ; IWebElement clickable = driver . FindElement ( By . Id ( "clickable" )); var actions = new Actions ( driver ); actions . ClickAndHold ( clickable ) . KeyDown ( Keys . Shift ) . SendKeys ( "a" ) . Perform (); (( WebDriver ) driver ). ResetInputState (); actions . SendKeys ( "a" ). Perform (); var value = clickable . GetAttribute ( "value" ); Assert . AreEqual ( "A" , value [.. 1 ]); Assert . AreEqual ( "a" , value . Substring ( 1 , 1 )); } } }
Selenium v4.2
clickable = driver . find_element ( id : 'clickable' ) driver . action . move_to ( clickable ) . pause ( duration : 1 ) . click_and_hold . pause ( duration : 1 ) . send_keys ( 'abc' ) . perform
examples/ruby/spec/actions_api/actions_spec.rb Copy Close
# frozen_string_literal: true require 'spec_helper' RSpec . describe 'Actions' do let ( :driver ) { start_session } it 'pauses' do driver . get 'https://www.selenium.dev/selenium/web/mouse_interaction.html' start = Time . now clickable = driver . find_element ( id : 'clickable' ) driver . action . move_to ( clickable ) . pause ( duration : 1 ) . click_and_hold . pause ( duration : 1 ) . send_keys ( 'abc' ) . perform duration = Time . now - start expect ( duration ) . to be > 2 expect ( duration ) . to be < 3 end it 'releases all' do driver . get 'https://www.selenium.dev/selenium/web/mouse_interaction.html' clickable = driver . find_element ( id : 'clickable' ) action = driver . action . click_and_hold ( clickable ) . key_down ( :shift ) . key_down ( 'a' ) action . perform driver . action . release_actions action . key_down ( 'a' ) . perform expect ( clickable . attribute ( 'value' ) [ 0 ] ) . to eq 'A' expect ( clickable . attribute ( 'value' ) [- 1 ] ) . to eq 'a' end end
const clickable = await driver . findElement ( By . id ( 'clickable' )) await driver . actions () . move ({ origin : clickable }) . pause ( 1000 ) . press () . pause ( 1000 ) . sendKeys ( 'abc' ) . perform ()
examples/javascript/test/actionsApi/actionsTest.spec.js Copy Close
const { By , Key , Browser , Builder } = require ( 'selenium-webdriver' ) const assert = require ( 'assert' ) describe ( 'Actions API - Pause and Release All Actions' , function () { let driver before ( async function () { driver = await new Builder (). forBrowser ( 'chrome' ). build (); }) after ( async () => await driver . quit ()) it ( 'Pause' , async function () { await driver . get ( 'https://selenium.dev/selenium/web/mouse_interaction.html' ) const start = Date . now () const clickable = await driver . findElement ( By . id ( 'clickable' )) await driver . actions () . move ({ origin : clickable }) . pause ( 1000 ) . press () . pause ( 1000 ) . sendKeys ( 'abc' ) . perform () const end = Date . now () - start assert . ok ( end > 2000 ) assert . ok ( end < 4000 ) }) it ( 'Clear' , async function () { await driver . get ( 'https://selenium.dev/selenium/web/mouse_interaction.html' ) const clickable = driver . findElement ( By . id ( 'clickable' )) await driver . actions () . click ( clickable ) . keyDown ( Key . SHIFT ) . sendKeys ( 'a' ) . perform () await driver . actions (). clear () await driver . actions (). sendKeys ( 'a' ). perform () const value = await clickable . getAttribute ( 'value' ) assert . deepStrictEqual ( 'A' , value . substring ( 0 , 1 )) assert . deepStrictEqual ( 'a' , value . substring ( 1 , 2 )) }) })
Actions ( driver ) . moveToElement ( clickable ) . pause ( Duration . ofSeconds ( 1 )) . clickAndHold () . pause ( Duration . ofSeconds ( 1 )) . sendKeys ( "abc" ) . perform ()
examples/kotlin/src/test/kotlin/dev/selenium/actions_api/ActionsTest.kt Copy Close
package dev.selenium.actions_api import dev.selenium.BaseTest import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test import org.openqa.selenium.By import org.openqa.selenium.Keys import org.openqa.selenium.interactions.Actions import org.openqa.selenium.remote.RemoteWebDriver import java.time.Duration class ActionsTest : BaseTest () { @Test fun pause () { driver . get ( "https://www.selenium.dev/selenium/web/mouse_interaction.html" ) val start = System . currentTimeMillis () val clickable = driver . findElement ( By . id ( "clickable" )) Actions ( driver ) . moveToElement ( clickable ) . pause ( Duration . ofSeconds ( 1 )) . clickAndHold () . pause ( Duration . ofSeconds ( 1 )) . sendKeys ( "abc" ) . perform () val duration = System . currentTimeMillis () - start Assertions . assertTrue ( duration > 2000 ) Assertions . assertTrue ( duration < 4000 ) } @Test fun releasesAll () { driver . get ( "https://www.selenium.dev/selenium/web/mouse_interaction.html" ) val clickable = driver . findElement ( By . id ( "clickable" )) val actions = Actions ( driver ) actions . clickAndHold ( clickable ) . keyDown ( Keys . SHIFT ) . sendKeys ( "a" ) . perform () ( driver as RemoteWebDriver ). resetInputState () actions . sendKeys ( "a" ). perform () Assertions . assertEquals ( "A" , clickable . getAttribute ( "value" ) !! . get ( 0 ). toString ()) Assertions . assertEquals ( "a" , clickable . getAttribute ( "value" ) !! . get ( 1 ). toString ()) } }
Release All Actions An important thing to note is that the driver remembers the state of all the input items throughout a session. Even if you create a new instance of an actions class, the depressed keys and the location of the pointer will be in whatever state a previously performed action left them.
There is a special method to release all currently depressed keys and pointer buttons. This method is implemented differently in each of the languages because it does not get executed with the perform method.
Java Python CSharp Ruby JavaScript Kotlin (( RemoteWebDriver ) driver ). resetInputState ();
examples/java/src/test/java/dev/selenium/actions_api/ActionsTest.java Copy Close
package dev.selenium.actions_api ; import dev.selenium.BaseChromeTest ; import org.junit.jupiter.api.Assertions ; import org.junit.jupiter.api.Test ; import org.openqa.selenium.By ; import org.openqa.selenium.Keys ; import org.openqa.selenium.WebElement ; import org.openqa.selenium.interactions.Actions ; import org.openqa.selenium.remote.RemoteWebDriver ; import java.time.Duration ; public class ActionsTest extends BaseChromeTest { @Test public void pause () { driver . get ( "https://www.selenium.dev/selenium/web/mouse_interaction.html" ); long start = System . currentTimeMillis (); WebElement clickable = driver . findElement ( By . id ( "clickable" )); new Actions ( driver ) . moveToElement ( clickable ) . pause ( Duration . ofSeconds ( 1 )) . clickAndHold () . pause ( Duration . ofSeconds ( 1 )) . sendKeys ( "abc" ) . perform (); long duration = System . currentTimeMillis () - start ; Assertions . assertTrue ( duration > 2000 ); Assertions . assertTrue ( duration < 3000 ); } @Test public void releasesAll () { driver . get ( "https://www.selenium.dev/selenium/web/mouse_interaction.html" ); WebElement clickable = driver . findElement ( By . id ( "clickable" )); Actions actions = new Actions ( driver ); actions . clickAndHold ( clickable ) . keyDown ( Keys . SHIFT ) . sendKeys ( "a" ) . perform (); (( RemoteWebDriver ) driver ). resetInputState (); actions . sendKeys ( "a" ). perform (); Assertions . assertEquals ( "A" , String . valueOf ( clickable . getAttribute ( "value" ). charAt ( 0 ))); Assertions . assertEquals ( "a" , String . valueOf ( clickable . getAttribute ( "value" ). charAt ( 1 ))); } }
ActionBuilder ( driver ) . clear_actions ()
examples/python/tests/actions_api/test_actions.py Copy Close
from time import time from selenium.webdriver import Keys , ActionChains from selenium.webdriver.common.actions.action_builder import ActionBuilder from selenium.webdriver.common.by import By def test_pauses ( driver ): driver . get ( 'https://selenium.dev/selenium/web/mouse_interaction.html' ) start = time () clickable = driver . find_element ( By . ID , "clickable" ) ActionChains ( driver ) \ . move_to_element ( clickable ) \ . pause ( 1 ) \ . click_and_hold () \ . pause ( 1 ) \ . send_keys ( "abc" ) \ . perform () duration = time () - start assert duration > 2 assert duration < 3 def test_releases_all ( driver ): driver . get ( 'https://selenium.dev/selenium/web/mouse_interaction.html' ) clickable = driver . find_element ( By . ID , "clickable" ) ActionChains ( driver ) \ . click_and_hold ( clickable ) \ . key_down ( Keys . SHIFT ) \ . key_down ( "a" ) \ . perform () ActionBuilder ( driver ) . clear_actions () ActionChains ( driver ) . key_down ( 'a' ) . perform () assert clickable . get_attribute ( 'value' )[ 0 ] == "A" assert clickable . get_attribute ( 'value' )[ 1 ] == "a"
(( WebDriver ) driver ). ResetInputState ();
examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs Copy Close
using System ; using Microsoft.VisualStudio.TestTools.UnitTesting ; using OpenQA.Selenium ; using OpenQA.Selenium.Interactions ; namespace SeleniumDocs.ActionsAPI { [TestClass] public class ActionsTest : BaseChromeTest { [TestMethod] public void Pause () { driver . Url = "https://selenium.dev/selenium/web/mouse_interaction.html" ; DateTime start = DateTime . Now ; IWebElement clickable = driver . FindElement ( By . Id ( "clickable" )); new Actions ( driver ) . MoveToElement ( clickable ) . Pause ( TimeSpan . FromSeconds ( 1 )) . ClickAndHold () . Pause ( TimeSpan . FromSeconds ( 1 )) . SendKeys ( "abc" ) . Perform (); TimeSpan duration = DateTime . Now - start ; Assert . IsTrue ( duration > TimeSpan . FromSeconds ( 2 )); Assert . IsTrue ( duration < TimeSpan . FromSeconds ( 3 )); } [TestMethod] public void ReleaseAll () { driver . Url = "https://selenium.dev/selenium/web/mouse_interaction.html" ; IWebElement clickable = driver . FindElement ( By . Id ( "clickable" )); var actions = new Actions ( driver ); actions . ClickAndHold ( clickable ) . KeyDown ( Keys . Shift ) . SendKeys ( "a" ) . Perform (); (( WebDriver ) driver ). ResetInputState (); actions . SendKeys ( "a" ). Perform (); var value = clickable . GetAttribute ( "value" ); Assert . AreEqual ( "A" , value [.. 1 ]); Assert . AreEqual ( "a" , value . Substring ( 1 , 1 )); } } }
driver . action . release_actions
examples/ruby/spec/actions_api/actions_spec.rb Copy Close
# frozen_string_literal: true require 'spec_helper' RSpec . describe 'Actions' do let ( :driver ) { start_session } it 'pauses' do driver . get 'https://www.selenium.dev/selenium/web/mouse_interaction.html' start = Time . now clickable = driver . find_element ( id : 'clickable' ) driver . action . move_to ( clickable ) . pause ( duration : 1 ) . click_and_hold . pause ( duration : 1 ) . send_keys ( 'abc' ) . perform duration = Time . now - start expect ( duration ) . to be > 2 expect ( duration ) . to be < 3 end it 'releases all' do driver . get 'https://www.selenium.dev/selenium/web/mouse_interaction.html' clickable = driver . find_element ( id : 'clickable' ) action = driver . action . click_and_hold ( clickable ) . key_down ( :shift ) . key_down ( 'a' ) action . perform driver . action . release_actions action . key_down ( 'a' ) . perform expect ( clickable . attribute ( 'value' ) [ 0 ] ) . to eq 'A' expect ( clickable . attribute ( 'value' ) [- 1 ] ) . to eq 'a' end end
await driver . actions (). clear ()
examples/javascript/test/actionsApi/actionsTest.spec.js Copy Close
const { By , Key , Browser , Builder } = require ( 'selenium-webdriver' ) const assert = require ( 'assert' ) describe ( 'Actions API - Pause and Release All Actions' , function () { let driver before ( async function () { driver = await new Builder (). forBrowser ( 'chrome' ). build (); }) after ( async () => await driver . quit ()) it ( 'Pause' , async function () { await driver . get ( 'https://selenium.dev/selenium/web/mouse_interaction.html' ) const start = Date . now () const clickable = await driver . findElement ( By . id ( 'clickable' )) await driver . actions () . move ({ origin : clickable }) . pause ( 1000 ) . press () . pause ( 1000 ) . sendKeys ( 'abc' ) . perform () const end = Date . now () - start assert . ok ( end > 2000 ) assert . ok ( end < 4000 ) }) it ( 'Clear' , async function () { await driver . get ( 'https://selenium.dev/selenium/web/mouse_interaction.html' ) const clickable = driver . findElement ( By . id ( 'clickable' )) await driver . actions () . click ( clickable ) . keyDown ( Key . SHIFT ) . sendKeys ( 'a' ) . perform () await driver . actions (). clear () await driver . actions (). sendKeys ( 'a' ). perform () const value = await clickable . getAttribute ( 'value' ) assert . deepStrictEqual ( 'A' , value . substring ( 0 , 1 )) assert . deepStrictEqual ( 'a' , value . substring ( 1 , 2 )) }) })
examples/kotlin/src/test/kotlin/dev/selenium/actions_api/ActionsTest.kt Copy Close
package dev.selenium.actions_api import dev.selenium.BaseTest import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test import org.openqa.selenium.By import org.openqa.selenium.Keys import org.openqa.selenium.interactions.Actions import org.openqa.selenium.remote.RemoteWebDriver import java.time.Duration class ActionsTest : BaseTest () { @Test fun pause () { driver . get ( "https://www.selenium.dev/selenium/web/mouse_interaction.html" ) val start = System . currentTimeMillis () val clickable = driver . findElement ( By . id ( "clickable" )) Actions ( driver ) . moveToElement ( clickable ) . pause ( Duration . ofSeconds ( 1 )) . clickAndHold () . pause ( Duration . ofSeconds ( 1 )) . sendKeys ( "abc" ) . perform () val duration = System . currentTimeMillis () - start Assertions . assertTrue ( duration > 2000 ) Assertions . assertTrue ( duration < 4000 ) } @Test fun releasesAll () { driver . get ( "https://www.selenium.dev/selenium/web/mouse_interaction.html" ) val clickable = driver . findElement ( By . id ( "clickable" )) val actions = Actions ( driver ) actions . clickAndHold ( clickable ) . keyDown ( Keys . SHIFT ) . sendKeys ( "a" ) . perform () ( driver as RemoteWebDriver ). resetInputState () actions . sendKeys ( "a" ). perform () Assertions . assertEquals ( "A" , clickable . getAttribute ( "value" ) !! . get ( 0 ). toString ()) Assertions . assertEquals ( "a" , clickable . getAttribute ( "value" ) !! . get ( 1 ). toString ()) } }
A representation of any key input device for interacting with a web page.
A representation of any pointer device for interacting with a web page.
A representation of a pen stylus kind of pointer input for interacting with a web page.
A representation of a scroll wheel input device for interacting with a web page.