Working with user prompts in Selenium

Published by

on

In your tests you might encounter specialized popups, which are generated via Javascript, and which are called ‘user prompts’. These are very basic in functionality, and they come in three variants: an ‘alert’ which only displays an informational message and an ‘OK’ button; a ‘confirm’ which displays an informational message, together with an ‘OK’ and ‘Cancel’ button; a ‘prompt’ which displays an informational message, possibly an input field for typing into, and an ‘OK’ and ‘Cancel’ button.

Such a user prompt will be displayed usually when a user clicks a button, which triggers the prompt to be displayed. Understanding what type of user prompt will be displayed when a user clicks a button can be done by inspecting the HTML code of the button. It will have an attribute called ‘onclick’, whose value is the name of a Javascript function that will execute when the button is clicked. The location of the function can be either in the HTML file itself, or in a different file which is imported in the HTML file. You will find this information in the <script> section of your HTML file. If you find the function with the name equal to the ‘onclick’ attribute value, there you have it. If not, you will find an ‘import’ declaration, such as: <script src=”someExternalJsFile”>, where “someExternalJsFile” is the name of the file where the function which triggers a user prompt is defined.

The function you are looking for is of the following format:

<script>
function nameOfFunction() {
   ...
}
</script>

Of course, a script which triggers a user prompt to be displayed might do more than just show you the prompt. Based on what you click, some additional code might be executed in the script. That will depend on what product you are working on. However, the code which simply displays the user prompts is as follows:

  • Alert: this is a simple prompt with a text displayed (“theAlertMessage” in this example) and an OK button:
alert("theAlertMessage");
  • Confirm: this is a prompt with a text displayed (“theConfirmMessage” in this example) and an OK and Cancel buttons
confirm("theConfirmMessage");
  • Prompt: 
    • this is a prompt with a text displayed (“thePromptMessage” in this example), an empty input field in which the user can type, and an OK and Cancel buttons:
prompt("thePromptMessage");
    • this is a prompt with a text displayed (“thePromptMessage” in this example), a pre-filled input field (with the text “thePromptInputField”) in which the user can type, and an OK and Cancel buttons:
prompt("thePromptMessage", “thePromptInputField”);

Examples Setup

The HTML page that will be used in this post for showing how to work with prompts contains three buttons. Clicking on each of them will trigger a different type of user prompt to be displayed. 

………
<button id="alertButton" onclick="alertFunction()">Alert button</button>
<button id="confirmButton" onclick="confirmFunction()">Confirm button</button>
<button id="promptButton" onclick="promptFunction()">Prompt button</button>
<p id="userClicked"></p>
<script>
function alertFunction() {
  alert("This is the alert box");
}
function confirmFunction() {
  var confirmBoolean = confirm("Confirm modal");
  if (confirmBoolean == true) {
    document.getElementById("userClicked").innerHTML = "OK";
  } else {
    document.getElementById("userClicked").innerHTML = "Cancel";
  }
   txt;
}
function promptFunction() {
  var promptOption = prompt("Type something");
  if (promptOption != null) {
    document.getElementById("userClicked").innerHTML =
    "OK";
  }
  else {
  document.getElementById("userClicked").innerHTML =
    "Cancel";
  }
}
</script>
……………...

After this page is opened in the browser, when the button with id ‘alertButton’ is clicked, the ‘alertFunction()’ function from the <script> section of this page is executed. It triggers an ‘alert’ to be displayed. This alert displays the ‘This is the alert box’ text, and it also has an ‘OK’ button.

When the button with id ‘confirmButton’ is clicked, the ‘confirmFunction()’ function from the <script> section of this page is executed. It triggers a ‘confirm’ to be displayed. This confirm displays the ‘Confirm modal’ text, and it also has an ‘OK’ and a ‘Cancel’ buttons. When the user clicks on any of the two buttons, in the <p> tag with id ‘userClicked’ a text is displayed: ‘OK’ if the user clicked ‘OK’ and ‘Cancel’ if the user clicked the other button.

When the button with id ‘promptButton’ is clicked, the ‘promptFunction()’ function from the <script> section of this page is executed. It triggers a ‘prompt’ to be displayed. This prompt displays the ‘Type something’ text, has a typeable input field, and it also has an ‘OK’ and a ‘Cancel’ buttons. When the user clicks on any of the two buttons, in the <p> tag with id ‘userClicked’ a text is displayed: ‘OK’ if the user clicked ‘OK’ and ‘Cancel’ if the user clicked the other button.

Note: the paragraph which displays what the user clicked is created in this example only for demonstration purposes. It is up to the application you are developing to add some specific behavior based on what the user clicks on inside the ‘prompt’ or ‘confirm’.

The import section of the test (https://github.com/iamalittletester/selenium-tutorial/blob/master/src/test/java/tutorialsolution/userprompts/UserPromptsTest.java ) will contain the following entries:

import browser.BrowserGetter;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.openqa.selenium.Alert;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.PageFactory;
import tutorialsolution.pages.UserPromptsPage;
import java.io.File;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;

Because the examples in this post use JUnit 5, the junit jupiter related imports are used for the setup methods, for the test methods and for the assertion parts. The BrowserGetter, WebDriver and PageFactory imports are used for starting the browser, storing the driver instance and initializing the PageObject class elements. The UserPromptsPage is imported because that is the PageObject class where the WebElements for this test are created. The relevant import for demonstrating user prompts is the Alert class.

The @BeforeAll method contains the browser and PageObject class initialization, and the code which opens the ‘userPrompts.html’ page, where the code for the user prompt demo is stored. The browser will be closed in the @AfterAll class.

@BeforeAll
    public void beforeAll() {
        //initialize the Chrome browser here
        driver = browserGetter.getChromeDriver();
        //initialize page object class
        page = PageFactory.initElements(driver, UserPromptsPage.class);
        driver.get(new File("src/main/resources/userPrompts.html").getAbsolutePath());
    }

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

The PageObject class (https://github.com/iamalittletester/selenium-tutorial/blob/master/src/main/java/tutorialsolution/pages/UserPromptsPage.java) contains the WebElements corresponding to the buttons which, when clicked, trigger the alert/confirm/prompts. It also contains the WebElement of the paragraph in which, when the user clicks a button on confirm/prompt, a text corresponding to which button was clicked is displayed:

@FindBy(css = "#alertButton") public WebElement alertButton;
@FindBy(css = "#confirmButton") public WebElement confirmButton;
@FindBy(css = "#promptButton") public WebElement promptButton;
@FindBy(css = "#userClicked") public WebElement userClicked;

 1. Alert

The alert type of user prompt:

  • Displays:
    • A text
    • An OK button
  • Has the following JS code: alert(“theAlertMessage”);
  • Can be interacted with from Selenium by:
    • Clicking the OK button
    • Reading its text

In case more than one interaction with the alert is made in a test, it is worth storing a handle to the alert by creating an ‘Alert’ object variable. Getting the handle to it is easily done in the following code:

Alert alert = driver.switchTo().alert();

Now, in order to read the text of the alert or to click the OK button, while the alert is displayed, you can call the relevant methods for these actions directly on the ‘alert’ variable. Reading the label of the alert is done by using the ‘getText()’ method :

alert.getText()

Clicking on the OK button of this alert is easily done by using the ‘accept()’ method on the ‘alert’ variable:

alert.accept()

Once you defined the variable, you don’t need to call the ‘driver.switchTo()’ method, if you closed the alert and opened it again. Once the variable is defined for an alert, you can use it across your test, but only for that particular alert, as it returns a handle to that alert. 

If you only need to perform one action on the alert in your test (maybe just closing it), you don’t need to create a separate variable for the alert. It is not worth creating a variable which will only be used once. Therefore, in such a case, you could easily close the alert by writting the following code in your test, where you are chaining the method calls (first you switch to the alert, then click on it):

driver.switchTo().alert().accept();

This approach also has the benefit of writing less lines of code.

Note: when using the alert related method, like ‘accept()’ or ‘getText()’, you need to make sure you are doing this while the user prompt, which ever it is (alert,confirm or prompt) is displayed. If you try to use these methods when the alert is not displayed you will encounter the following ‘NoAlertPresentException’ Exception:

org.openqa.selenium.NoAlertPresentException: no alert open

Example

Scenario 1. Click on the button which opens an alert. Check that the text of the alert is ‘This is the alert box’. Then, close the alert.

Clicking on the button which will trigger the alert to be displayed is straightforward (see Example Setup section):

page.alertButton.click();

Now that the alert is displayed, create a new variable which will store a handle to the alert, so that you can interact with the alert in the tests:

Alert alert = driver.switchTo().alert();

This variable is of type ‘Alert’. Now you can read the text of the alert using the ‘getText()’ method and compare it to the expected one.

assertEquals("This is the alert box", alert.getText());

The last step of this test requires closing the alert, by using the ‘accept()’ method:

alert.accept();

Scenario 2. Click on the button which opens an alert. Close the alert.

For this test, there is only one action that needs to be performed on the alert, namely closing it once it is open. Therefore, there is no need to store the handle to the alert into a new variable. Instead, the entire test will consist of two steps: clicking the button which triggers the alert, then closing the alert:

page.alertButton.click();

driver.switchTo().alert().accept();

2. Confirm

The confirm type of user prompt:

  • Displays:
    • A text
    • An OK button
    • A Cancel button
  • Has the following JS code: confirm(“theConfirmMessage”);
  • Can be interacted with from Selenium by:
    • Clicking the OK button (accept)
    • Clicking the Cancel button (dismiss)
    • Reading its text

In case more than one interaction with the alert is made in a test, it is worth storing a handle to the confirm by creating an ‘Alert’ object variable. From a Selenium point view, whether the user prompt is an alert, a confirm or a prompt, the handle to a user prompt is stored in an ‘Alert’ object variable. There is no ‘Confirm’ or ‘Prompt’ variable. 

Getting the handle to it is easily done in the following code, which is also identical to the way you would get the handle to an alert or to a prompt:

Alert alert = driver.switchTo().alert();

Retrieving the text of the ‘confirm’ is also done just as for the alert from the previous subchapter:

alert.getText()

It is the same with clicking on the ‘OK’ button of the prompt:

alert.accept()

Up to now, these methods could be used on an alert type of user prompt too. The difference between a ‘confirm’ and an ‘alert’ si that the ‘confirm’ user prompt also has a ‘Cancel’ button, which can be clicked from a test. Doing so is done by calling the ‘dimiss()’ method on the ‘alert’ variable:

alert.dismiss()

In case only one interaction with the ‘confirm’ is required in the test, there is no need to create a new variable only for the one interaction. Instead, the desired methods for interactions can be called as follows (this is the example for clicking ‘OK’):

driver.switchTo().alert().accept();

Similarly, closing the ‘confirm’ by clicking the ‘Cancel’ button in a one-liner can be done:

driver.switchTo().alert().dismiss();

Example

Scenario 1.1. Click the button which triggers a ‘confirm’ to be displayed. Check that the text on the ‘confirm’ is ‘Confirm modal’. Click the ‘OK’ button on the ‘confirm’. Check that the field which displays what the user clicked now displays ‘OK’.

The first step is to click the button which triggers the ‘confirm’ to be displayed. Then, the handle to the newly opened ‘confirm’ will be stored to a variable of type ‘Alert’.

page.confirmButton.click();

Alert alert = driver.switchTo().alert();

Checking that the ‘confirm’ text is the expected one is done via the ‘getText()’ method:

assertEquals("Confirm modal", alert.getText());

Now, the ‘confirm’ can be closed, by clicking the ‘OK’ button.

alert.accept();

At this point, in this test, in the paragraph whose corresponding WebElement is named ‘userClicked’, the text ‘OK’ is displayed. To check this, the following assertion will be used:

assertEquals("OK", page.userClicked.getText());

Scenario 1.2. After scenario 1.1 is executed successfully, in the same test, open the ‘confirm’ again. Close the ‘confirm’ by clicking the ‘Cancel’ button. Check that the field which displays what the user clicked now displays ‘Cancel’.

Opening the ‘confirm’ again is done just as the first step of Scenario 1.1.:

page.confirmButton.click();

Close the ‘confirm’ by clicking the ‘Cancel’ button. This is done by using the ‘dismiss()’ method from Selenium. Now, think about what happened previously: first you opened the ‘confirm’ and you got a handle to it. Then you closed it. Now it opens again. Luckily there is no need to regenerate the handle to the ‘confirm’ (like it is the case with switching to windows). Once you created the ‘alert’ variable for the ‘confirm’ you can reuse that variable even if you closed, then reopened the ‘confirm’.

alert.dismiss();

Now, since the ‘Cancel’ button was clicked, check that the field which displays what the user clicked now displays ‘Cancel’:

assertEquals("Cancel", page.userClicked.getText());

Scenario 2. Open a ‘confirm’ type of user prompt. Close it by clicking the ‘Cancel’ button. Check that the paragraph which displays what the user clicked shows the text ‘Cancel’.

This is a short test, since there is only one interaction with the ‘confirm’ and there is no need to store the ‘confirm’ handle to a variable:

page.confirmButton.click();

driver.switchTo().alert().dismiss();

assertEquals("Cancel", page.userClicked.getText());

3. Prompt

The prompt type of user prompt:

  • Displays:
    • A text
    • An input field, with or without a predefined text
    • An OK button
    • A Cancel button
  • Has the following JS code: prompt(“thePromptMessage”); or prompt(“thePromptMessage”, “thePromptInputField”);
  • Can be interacted with from Selenium as:
    • Clicking the OK button (accept)
    • Clicking the Cancel button (dismiss)
    • Reading its text
    • Typing in the input field

In case more than one interaction with the ‘prompt’ is made in a test, it is worth storing a handle to the ‘prompt’ by creating an ‘Alert’ object variable. As mentioned in the previous subchapter, no matter what type of user prompt appears in the test, the type of variable used for storing its handle will be ‘Alert’. Storing the handle is done just as for the other types of user prompts:

Alert alert = driver.switchTo().alert();

Retrieving the text of the ‘prompt’ is also done just as for the ‘alert’ and ‘confirm’ from the previous subchapter:

alert.getText()

It is the same with clicking on the ‘OK’ button of the prompt:

alert.accept()

Clicking the ‘Cancel’ button of the ‘prompt’ is done by calling the ‘dimiss()’ method on the ‘alert’ variable:

alert.dismiss()

Aditionally, the user can type in an input field displayed on the ‘prompt’. This can be done using the ‘sendKeys()’ method from Selenium. Note that at the time of writing this post, this functionality does not work on ChromeDriver(). Its’ usage is:

alert.sendKeys(“textToType”)

Just as before, if there is no need to create a new variable in the test, the ‘prompt’ related methods can be called directly in the form:

driver.switchTo().alert().dismiss();

Example

Scenario 1. Open a new ‘prompt’ and check that the text displayed on it is ‘Type something’. Click the ‘OK’ button on the prompt, and check that the paragraph which displays what the user clicked now shows the text ‘OK’. Open the ‘prompt’ again, then close it by clicking the ‘Cancel’ button and check that the paragraph which dispays what the user clicked now shows ‘Cancel’.

Just as in the previous examples, for ‘alerts’ and ‘confirms’, first a button is clicked which triggers the ‘prompt’ to be displayed. Then, the handle to the ‘prompt’ is stored in an ‘Alert’ variable.

page.promptButton.click();

Alert alert = driver.switchTo().alert();

Checking the text of the ‘prompt’ and closing it (via the ‘Ok’ button) are covered by the following code:

assertEquals("Type something", alert.getText());

alert.accept();

Now the check that the paragraph displaying what the user clicked shows the text ‘OK’ is done through this assertion:

assertEquals("OK", page.userClicked.getText());

The next steps of this test are to reopen the prompt, then close it by clicking the ‘Cancel’ button, and finally checking that the label displaying what button was clicked is correct:

age.promptButton.click();

alert.dismiss();

assertEquals("Cancel", page.userClicked.getText());

Scenario 2. Open a new ‘prompt’ and close it by clicking the ‘Cancel’ button. Check that the paragraph which dispays what the user clicked now shows ‘Cancel’.

The code which covers this scenario is similar to previous subchapters:

page.promptButton.click();

 driver.switchTo().alert().dismiss();

 assertEquals("Cancel", page.userClicked.getText());

GitHub location of example code

PageObject class: https://github.com/iamalittletester/selenium-tutorial/blob/master/src/main/java/tutorialsolution/pages/UserPromptsPage.java  
Test class: https://github.com/iamalittletester/selenium-tutorial/blob/master/src/test/java/tutorialsolution/userprompts/UserPromptsTest.java 

Test methods: alertGetTextAndAccept, alertAccept, confirmGetTextAcceptAndDismiss, confirmAcceptAndDismiss, promptGetTextAcceptAndDismiss, promptAcceptAndDismiss
HTML code: https://github.com/iamalittletester/selenium-tutorial/blob/master/src/main/resources/userPrompts.html

One response to “Working with user prompts in Selenium”

  1. Venessa Serrao Avatar
    Venessa Serrao

    A good read. Thanks for the info.

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Blog at WordPress.com.