logo logo

Performing Page Interactions with Selenium Actions

Performing Page Interactions with Selenium Actions

Selenium Actions are used whenever you need a more complex interaction with an HTML element. More complex means it could be either: a double click, a hover, a right-click, or even drag and drop. Such interactions are very easy to make, and in this post, I want to go over some clear examples of how you can use the Selenium Actions class for this purpose.

Table of Contents – Performing Page Interactions with Selenium Actions


The Selenium Actions class

Whenever you want to perform some of the interactions I mentioned, first, in your test class, or in a base class your tests are extending, you need to import the Actions class. You can do this quite easily:

import org.openqa.selenium.interactions.Actions;

Then, you will need to declare a field (or variable, depending on how you structure your tests) of type Actions. In the examples I will show in this post, I will declare a field in my test class, as follows:

private Actions actions;

I will then initialize this field in the @BeforeAll method of my test class, right after I created my WebDriver instance (which I store in the ‘driver’ field):

actions = new Actions(driver);


In order to initialize the ‘actions’ field, I am calling the Actions class constructor, to which I am passing the ‘driver’ as a parameter. Once this step is done, we can get started with performing our required interactions.

Test setup

At the end of the article, I will provide a GitHub link where you can find the resources I used for these examples: the HTML code, the Page class, and the test class. The Page class is called ActionsPage. In the test class, ActionsTest, I first declare the page instance as a field, and then, in the @BeforeAll method, I initialize it. I  also open the test webpage in this method. This webpage is part of the test project I am using and can be found in the test ‘resources’ folder. The entire @BeforeAll and @AfterAll methods look like this:

@BeforeAll 
void beforeAll() 
{ 
   driver = browserGetter.getChromeDriver(); 
   page = PageFactory.initElements(driver, ActionsPage.class); 
   driver.get(new File("src/test/resources/htmls/tp/actions/actions.html").getAbsolutePath()); 
   actions = new Actions(driver); 
} 

@AfterAll 
void afterAll() 
{ 
   driver.quit(); 
}

Of course, after the entire test class runs, the browser will be closed.

Actions: Mouse hover

The first interaction I will look into is the mouse hover one. As an example, I will have an HTML element of type paragraph (a <p> tag). When this element is hovered, a tooltip with the text “Hover text displayed” is displayed. The test will need to check that upon hovering, the tooltip displays the correct text.

The corresponding HTML code is:

<div class="w3-panel w3-teal w3-center"> 
   <p class="tooltip">Element to hover <span class="tooltiptext">Hover text displayed</span></p> 
</div>

I am interested in creating 2 Selenium WebElements. The first one corresponds to the paragraph we want to hover. The second one corresponds to the tooltip. These 2 WebElements, created in the ActionsPage page class, are:

@FindBy(className = "tooltip") 
public WebElement elementToHover; 

@FindBy(className = "tooltiptext") 
public WebElement hoverTextElement;

Having created the WebElement used for identifying the paragraph to hover, we can now use the hover method from the Actions class, namely ‘moveToElement’. The usage of this method, in general, is, where ‘target’ is the WebElement we need to hover:

actions.moveToElement(target).perform();

The ‘perform’ method should always be called after calling the desired interaction method. It performs a required cleanup, so that the next time you are using the ‘actions’ field, you are not relating or adding an interaction to the previous one. You can think of this method as performing a reset. The actions can be chained, meaning you can perform further interactions after the hover is done, within the same line of code. I will show such an example later on.

For now, looking at our HTML page and the page class, we will write the part of the test which performs the hover over the paragraph. That means we will call the ‘moveToElement’ method while passing the ‘elementToHover’ WebElement as a parameter:

actions.moveToElement(page.elementToHover).perform();

Because we also want to check the text of the tooltip, we can use the ‘getText’ method to read the text of the WebElement which now needs to be displayed, namely ‘hoverTextElement’. We could use this in an assertion, as below, or even better, we could use a WebDriverWait based method for waiting for the text to be the expected one. For now, let’s check the text using an assertion:

assertEquals("Hover text displayed", page.hoverTextElement.getText());

Actions: Double click

Let’s now look at another example: here we have another paragraph. Before double-clicking on it, the text it displays is: Element to double click. After we double click, the new text it will display needs to be: The element was double-clicked.

The corresponding HTML for this paragraph is:

<div class="w3-panel w3-cyan w3-center"> 
   <p id="elementToDoubleClick" ondblclick="doubleClick()">Element to double click</p> 
</div>

The corresponding WebElement for the paragraph we want to double click on is:

@FindBy(id = "elementToDoubleClick") 
public WebElement elementToDoubleClick;

Before we perform the double click on the paragraph, we want to check that the text is the expected initial one:

assertEquals("Element to double click", page.elementToDoubleClick.getText());

Now, the actual interaction will take place, using the ‘doubleClick’ method. The general usage for this method is:

actions.doubleClick(target).perform();

When calling this method, there is no need for performing a hover before the click, as this step is already included in the ‘doubleClick’ method. The double click takes place in the middle of the defined WebElement. In our example, this method call, using our WebElement, is:

actions.doubleClick(page.elementToDoubleClick).perform();

After the double click was performed, we do want to check that the behavior of the paragraph is correct. Therefore, we will also make another assertion on its’ text, comparing it to the expected new one:

assertEquals("The element was double clicked", page.elementToDoubleClick.getText());

This assertion should be successful, which means our interaction was successful.

Actions: Right-click

We also have the option to perform a right-click on a WebElement. For demonstrating how this can be done, I will again use the ‘elementToDoubleClick’ WebElement we previously defined. The method to be used for this interaction is called ‘contextClick’ and its’ normal usage would be:

actions.contextClick(target).perform();

For our example, the corresponding right-click method call will be:

actions.contextClick(page.elementToDoubleClick).perform();

No hover is required in this case either, as it is already included in the ‘contextClick’ method. Of course, once the right-click is performed, you can continue with whatever steps your test requires.

Actions: Drag and drop

Let’s take a look at another example: we have a paragraph that we want to move over an empty <div>. The corresponding HTML code is:

<p id="elementToDrag" class="w3-card-4 w3-center w3-sand">Element to drag</p> 
<div class="droptarget w3-panel w3-pale-yellow w3-center"> </div>

The WebElements representing the element to drag and the element to drop it to are:

@FindBy(id = "elementToDrag") 
public WebElement elementToDrag; 

@FindBy(className = "droptarget") 
public WebElement dropContainer;

The drag and drop interaction, although normally consisting of several steps, can be done easily using the ‘dragAndDrop’ method. The normal usage for this method is:

actions.dragAndDrop(source, target).perform();

In our example, we want to drag the ‘elementToDrag’ element over the ‘dropContainer’ element. This is done as follows:

actions.dragAndDrop(page.elementToDrag, page.dropContainer).perform();

Once this interaction has been made, you could check that it was performed successfully by checking that the HTML code has been changed to reflect the new location of the element which was dragged.

Actions: Chaining

In some cases, you will need to perform several interactions on the same element. For example, you might need to first hover the element, and only then double click on it. This all depends on your underlying HTML. For multiple interactions on the same element, one after the other, you can still call the methods from the Actions class. In this case though, you will chain the method calls.

An example of how this can be done is to perform a drag and drop, but not by using the ‘dragAndDrop’ method. When you think about what this interaction is made of, you can easily see that first you need to click on a WebElement, hold the mouse down, drag the mouse to the location where you want to drop it, and then actually drop it. This, in terms of methods we can find in the Actions class, translates to:

actions.clickAndHold(page.elementToDrag).moveToElement(page.dropContainer).release().build().perform();

Here, the ‘clickAndHold’ method will perform exactly what the name suggests: first, a click is done, and then the mouse is not released. Right after this interaction, while the mouse is still clicked, the cursor moves over the element where we want to drop the element we are dragging. In order to drop it, we need to use the ‘release’ method, which will release the mouse click. Because there are several interactions we want to use on the same element, we will also call the ‘build’ method before calling the ‘perform’ one. And this is how we can chain any Actions methods we require.

Conclusion

In this article, I went over some of the most useful methods from the Selenium Actions class. All of them performed an interaction with an HTML element which we defined by means of a WebElement. In case you only have some coordinates on the screen for performing the interaction, there are some useful methods to help you out. For the complete list of available interaction methods, please check out the official documentation.

Resources

The HTML code used for the examples

The Page object class

The test class

About the author

Corina Pip

Corina is a Test & Automation Lead, with focus on testing by means of Java, Selenium, TestNG, Spring, Maven, and other cool frameworks and tools. Previous endeavours from her 11+ years testing career include working on navigation devices, in the online gaming industry, in the aviation software and automotive industries.
Apart from work, Corina is a testing blogger (https://imalittletester.com/) and a GitHub contributor (https://github.com/iamalittletester).
She is the creator of a wait based library for Selenium testing (https://github.com/iamalittletester/thewaiter) and creator of “The Little Tester” comic series (https://imalittletester.com/category/comics/). She also tweets at @imalittletester.

Leave a Reply

FacebookLinkedInTwitterEmail