How To Press Enter Without WebElement In Selenium Python
Tags: python, webdev, beginners, programming
Published: 2023-07-28 08:05:52

The Selenium WebDriver is an indispensable testing framework with many interactive features for automating web actions. However, the standard WebDriver methods of interacting with a web page may sometimes need to be revised to test specific features.

For instance, a web page that renders content asynchronously or dynamically may not arrange responses in order. Hence, using the WebDriver directly without a wrapper might be inefficient in interacting successfully with its web elements during [automation testing](https://www.lambdatest.com/automation-testing?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=webpage).
Your test scenario might also involve automating interactions such as mouse clicks, keyboard actions, and animated gestures sometimes. Leveraging the WebDriver’s *execute_script *method helps in such cases. And if your test needs to perform low-level gestures like dragging and dropping, [Selenium’s *ActionChains* class](https://www.lambdatest.com/blog/handling-keyboard-actions-in-selenium-webdriver/?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=blog) also comes in handy as a wrapper class to aid such actions.

Selenium’s *ActionChains* and *execute_script* are handy for automating a website’s response to keyboard and mouse actions and animated cursor gestures.

In this blog, I’ll show you how to press enter without WebElement in [Selenium Python](https://www.lambdatest.com/learning-hub/python-tutorial?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=learning_hub) using *ActionChains *and *execute_script*.

## What are ActionChains in Selenium?

*ActionChains* is a built-in class in Selenium for automating low-level interaction with the [DOM](https://www.lambdatest.com/blog/document-object-model/?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=blog). It arranges actions in a queue and features mouse actions, including click events, cursor, and touch gestures. It also supports keyboard simulations for pressing the keypads. Thus, it provides ways to interact with a web page like a regular user.

Although Selenium’s *ActionChains* queues actions sequentially in order of programmatic arrangement, it fires them at once when executed. Hence, unlike the conventional [WebDriver](https://www.lambdatest.com/learning-hub/webdriver?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=learning_hub) method, the success of the entire test step depends on each action step. Once a step fails, it invalidates the whole.

You might navigate a web page without using [CSS Selectors](https://www.lambdatest.com/learning-hub/css-selectors?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=learning_hub) in *ActionChains*. But this may be time-consuming and confusing.

*ActionChains* are typically easier to use if a web page handles only one action, such as filling out a focused form with a blinking cursor. Overall, *ActionChains* is intuitive and sensitive to component actions.

The *action.send_keys(data)* method; for example, automatically locates a focused form field to insert the specified information:

    from selenium.webdriver import Keys, ActionChains
    action = ActionChains()
    data = "omisola"
    action.send_keys(data).perform()

For instance, automating a search query on a web page that loads only a search box with a blinking cursor requires the following actions:

 1. Inputting the search term using the *send_keys* method.

 2. Press the *Enter key* to submit the search query.

However, web interaction using the *ActionChains* can be complex when automating several steps that involve moving between elements to execute several actions, including clicks, gestures, sending keys, and pressing the Tab and Enter keys, among many others.
In the next section of this blog on how to press enter without WebElement in Selenium Python, we will explore pros and cons of *ActionChains.*
>  **Boost Your Mobile App’s Performance! Discover Proven Strategies for [Mobile Performance Testing](https://www.lambdatest.com/learning-hub/mobile-performance-testing?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=learning_hub). Increase User Satisfaction & Rankings. Get Results Fast!**

## Pros of the ActionChains

Here’s why the *ActionChains* class is handy for testing a website:

* The *ActionChains* object stores automated actions in a queue to execute them sequentially in order of programmatic arrangement. This is helpful when you need to perform a large sequence of actions at a go.

* It includes mouse functionality, such as clicking and performing gestures for drag-and-drop actions.

* It simulates human keyboard actions like *Tab*, *Shift*, *Enter*, *Ctrl*, *PgUp*, and *PgDn*, among others, to navigate to any position within the DOM.

## Cons of the ActionChains

Although the *ActionChains* class lets you test a website using an array of actions, it has some shortcomings:

* Test steps depend on each other since actions are in a chain queue. Thus, once a step fails, it invalidates the entire chain, causing the test to fail without clarity about the point of failure.

* *ActionChains* can be hard to debug since it’s hard to tell which step in the chain causes the error.

Let’s consider some use cases of each approach before we discuss how to press enter without WebElement in Selenium Python. However, we need to first inspect the web elements:

![](https://cdn-images-1.medium.com/max/3200/0*NuiOzISc_T52uNJ4.jpg)

## ActionChains example use cases

In this blog section on how to press enter without WebElement in Selenium Python, shown below are the snippets of basic usage examples of *ActionChains*:

How to create an *ActionChains* object:

    from selenium.webdriver import Keys, ActionChains
    action = ActionChains()

**1. Drag and drop an element using the *ActionChains*.**

    from selenium.webdriver import Keys, ActionChains
    action = ActionChains()
    driver = webdriver.Chrome()
    driver.get("https://www.lambdatest.com/selenium-playground/drag-and-drop-demo")
    draggable = driver.find_element(By.ID, "draggable")
    dropZone = driver.find_element(By.ID, "droppable")
    action.drag_and_drop(draggable, dropZone).perform()

**2. Double-click an element in *ActionChains*.**

*xoffset* is an integer defining the pixel distance for left and right positions across the web page, while *yoffset* is an integer defining the pixel distance for vertical (up and down) movement across the web page.

The example below holds down the right mouse pad to drag the *draggable* to 150 pixels to the right and releases the mouse at the specified position to drop the held item:

    
    from selenium.webdriver import Keys, ActionChains
    action = ActionChains()
    driver = webdriver.Chrome()
    draggable = driver.find_element(By.ID, "draggable")
    action.drag_and_drop_by_offset(draggable, 150, 0).perform()

3. **Perform a click event using *ActionChains*.**

    
    from selenium.webdriver import Keys, ActionChains
    action = ActionChains()
    driver = webdriver.Chrome()
    element = driver.find_element(By.LINK_TEXT, "LambdaTest")
    action.click(element).perform()

4. **Double-click an element in *ActionChains*.**

    from selenium.webdriver import Keys, ActionChains
    action = ActionChains()
    driver = webdriver.Chrome()
    element = driver.find_element(By.LINK_TEXT, "LambdaTest")
    action.double_click(element).perform()

**5. Right-click an element in* ActionChains *(context-click).**

    from selenium.webdriver import Keys, ActionChains
    action = ActionChains()
    driver = webdriver.Chrome()
    element = driver.find_element(By.LINK_TEXT, "LambdaTest")
    action.context_click(element).perform()

**6. Click and hold an element.**

    
    from selenium.webdriver import Keys, ActionChains
    action = ActionChains()
    driver = webdriver.Chrome()
    element = driver.find_element(By.LINK_TEXT, "LambdaTest")
    action.click_and_hold(element).perform()

**7. Send keys and press the Enter key using the *ActionChains*.**

**Web page**: [https://www.lambdatest.com/selenium-playground/simple-form-demo.](https://www.lambdatest.com/selenium-playground/simple-form-demo?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=webpage)

**Web page inspection:**
>  **This guide focuses on [test automation metrics](https://www.lambdatest.com/learning-hub/test-automation-metrics?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=learning_hub), its significance, strategies, challenges, and key test automation metrics for measuring success.**

![](https://cdn-images-1.medium.com/max/3200/0*G6gujeK-FuConNVX.jpg)

    from selenium.webdriver import Keys, ActionChains
    action = ActionChains()
    driver = webdriver.Chrome()
    driver.get("https://www.lambdatest.com/selenium-playground/simple-form-demo")
    password = driver.find_elemnt(By.ID, "user-message")
    action.send_keys(password)
    action.send_keys(Keys.ENTER).perform()

**8. Press the Tab key using the *ActionChains*.**

    from selenium.webdriver import Keys, ActionChains
    action = ActionChains()
    driver = webdriver.Chrome()
    password = driver.find_elemnt(By.ID, "user-message")
    action.send_keys(password)
    action.send_keys(Keys.TAB).perform()

9. **Perform an action on key-up or key-down in *ActionChains*.**

    action.key_down(Keys.CONTROL).send_keys('Idowu').key_up(Keys.CONTROL).perform()

10. **Move to a specific element:**

    from selenium.webdriver import Keys, ActionChains
    action = ActionChains()
    driver = webdriver.Chrome()
    inputform = driver.find_element(By.ID, "user-message")
    action.move_to_element(inputform)

11. **Move the mouse relative to an element by offset.**

    from selenium.webdriver import Keys, ActionChains
    action = ActionChains()
    driver = webdriver.Chrome()
    inputform = driver.find_element(By.ID, "user-message")
    action.move_to_element_with_offset(inputform, 100, 200).perform()

12. **Move the mouse to a specific location by offset.**

    action.move_by_offset(100, 200)

## What is the execute_script method in Selenium?

The *execute_script* is a Selenium WebDriver method that allows the execution of JavaScript events and actions in the current window. It involves embedding pure JavaScript as a string into Python to modify the DOM.

While the *execute_script* method makes automation testing more flexible with browser API access, it’s easier with a knowledge of JavaScript.

Since it’s JavaScript, if you don’t want to use [Selenium locators](https://www.lambdatest.com/learning-hub/selenium-locators?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=learning_hub), you can use JavaScript’s document queries like *getElementById *or* getElementByClassName* to get web elements.

For example, the conventional locator takes the following form for locating an element by its ID:

    element = driver.find_element(By.ID, element_id)

However, the *execute_script* method takes the following form:

    element = driver.execute_script(“document.getElementById(‘user-message’);”)

In this blog on how to press enter without WebElement in Selenium Python, we’ll combine JavaScript’s *querySelector* and the *XPath* methods to interact with the web page elements.
>  **Learn the ins and outs of [test execution engines ](https://www.lambdatest.com/learning-hub/test-execution-engine?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=learning_hub)through our extensive guide, and enhance your testing workflow with automation.**

## Pros of the execute_script method

Here’s why you want to use the *execute_script* method:

* Since JavaScript has access to browser APIs, the *execute_script* method allows you to manipulate the DOM directly. For instance, you can leverage the embedded JavaScript to scroll to a particular position on a web page, insert an element into the DOM, get the website’s domain name, or even refresh the browser.

* It’s also suitable for testing applications and websites that render content asynchronously and dynamically.

* Since all modern browsers support JavaScript, the *execute_script* method can confer better [cross-browser compatibility](https://www.lambdatest.com/learning-hub/cross-browser-compatibility?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=learning_hub), as you can use JavaScript to tweak events to suit the test browser.

## Cons of execute_script method

* JavaScript is the language of the web. So using this automation method can introduce vulnerabilities to a website.

* JavaScript embedding can be hard to read, especially if you’re from a Python background with little or no knowledge of JavaScript.

## execute_script example use cases

This section on press enter without WebElement in Selenium Python discusses some applications of the *execute_script *method:

Here’s the basic syntax of *execute_script*:

    driver.execute_script(script)

1. Spin up an alert browser window using *execute_script*:

    driver.execute_script(“alert(‘this is a test’);”)

2. Type a text into an input field:

    driver.get("https://www.lambdatest.com/selenium-playground/checkbox-demo")
    driver.execute_script("document.getElementById('user-message').value='Idowu paul';")

3. Click an element (e.g., a button):

    button = driver.execute_script(“return document.getElementById(‘showInput’);”)
    driver.execute_script(“arguments[0].click()”, button)

4. Handle a checkbox using Boolean:

    driver.get(“https://www.lambdatest.com/selenium-playground/checkbox-demo")
    driver.execute_script(“document.getElementById(‘isAgeSelected’).checked=true;”)

To learn more about it, you can go through our earlier blog on [handling checkboxes in Selenium.](https://www.lambdatest.com/blog/how-to-select-multiple-checkboxes-in-selenium-webdriver/?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=blog)

5. Get the domain name of a website:

    domain_name = str(driver.execute_script("return document.domain;"))
    print(domain_name)

6. Create a new element in the DOM:

    driver.execute_script("var element=document.createElement('newButton');"
                          +"document.body.appendChild(element);")

7. Refresh a web page using execute_script in Selenium WebDriver:

    driver.get("https://www.lambdatest.com/selenium-playground/checkbox-demo")
    driver.execute_script("history.go(0)")

8. Get the height and width of a web page:

    driver.get("https://www.lambdatest.com/selenium-playground/checkbox-demo")
    page_height = str(driver.execute_script("return window.innerHeight;"))
    page_width = str(driver.execute_script("return window.innerWidth;"))
    print(page_height)
    print(page_width)
>  **This guide explores [Digital Transformation](https://www.lambdatest.com/learning-hub/digital-transformation?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=learning_hub), its benefits, goals, importance and challenges involved in Digital Transformation.**

## Demonstration: Using ActionChains and execute_script

In this section of our tutorial on press enter with WebElements in Selenium Python, I’ll demonstrate the test cases using the *ActionChains* class and the *execute_script* method in different code files. Both are a part of Selenium. So you don’t need to install them separately once you install Selenium.

We’ll also use the [Selenium pytest](https://www.lambdatest.com/learning-hub/selenium-pytest-tutorial?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=learning_hub) module for the test execution.

Our test website is [LambdaTest’s eCommerce playground.](https://ecommerce-playground.lambdatest.io/index.php?route=account/register?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=webpage)

Initially, we will showcase the process of navigating the registration page using Selenium’s *ActionChains *in a sequential manner. After understanding the functioning of the previous demonstration, we will proceed to repeat the test utilizing the *execute_script *method from Selenium WebDriver.

So this blog on how to press enter without WebElement in Selenium Python assumes you’ve already installed Python on your local machine. Our test cases in this blog use Python 3.10. You can follow pretty well using earlier versions, though.

We’ll also use VSCode for our [test suite ](https://www.lambdatest.com/learning-hub/test-suite?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=learning_hub)development in this blog on press enter without WebElement in Selenium Python. But you can stick to an IDE that works best for you.

{% youtube KZstMSOHIvQ %}

Don’t miss out on thе latеst tutorials on automation tеsting! Subscribe to thе [LambdaTеst YouTubе Channеl ](https://www.youtube.com/c/LambdaTest?sub_confirmation=1?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=youtube)for tutorials on [Sеlеnium tеsting](https://www.lambdatest.com/selenium-automation?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=webpage), [Playwright testing](https://www.lambdatest.com/playwright-testing?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=webpage), and more

## Install Dependencies

To set the ground for this automation testing, you must first install Selenium and pytest in your Python virtual environment. We’ll also mask dependencies using the environment variable (.env file). So you might want to include *python-dotenv* in your dependencies list.

Create a requirements.txt file in your project root directory and list the following packages:

**FileName — requirements.txt**

    pytest
    selenium
    python-dotenv

Next, run the following in your command line to install the listed packages:

    pip install -r requirements.txt

The dependencies install as shown:

![](https://cdn-images-1.medium.com/max/2844/0*w8BUL1Nr0jdXV6wN.jpg)

## Set up a pytest Configuration file

This blog section on press enter without WebElement in Selenium Python, we will see how to set up a pytest configuration file.

While it’s not a requirement, a pytest configuration file (*pytest.ini*) allows you to define more behaviors for your [test environment](https://www.lambdatest.com/blog/what-is-test-environment/?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=blog). For instance, you can use this file to declare how you want your test to log results in the terminal or inside a log file.

This file executes before other test files since it contains the test configurations and resides in the root directory.

In this case, we’ll ignore deprecation warnings using the *pytest.ini* file:

**FileName — pytest.ini**

    [pytest]
    filterwarnings = ignore::DeprecationWarning

The *pytest.ini* file has other configuration options besides ignoring deprecation warnings. But note that it doesn’t work without the [*pytest*] entry point — as written above.

For instance, among other settings, you can use it to configure the command-line outputs and custom-exit test execution once the test fails n times. You can also use it to point to your settings file while testing websites developed with complex web frameworks like Django locally. You can learn more about it through this tutorial on [pytest Django](https://www.lambdatest.com/blog/pytest-django-tutorial/?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=blog).

Here are a few more configuration options for *pytest.ini*:

* *Console_output_styl*e= **progress (default)**, **classic**, or **count**. Specify any of these options to customize how Pytest displays results. For example, while **progress** loads test results using percentages, **count** displays the number of tests executed.

* *faulthandler_timeout* = 10; exits the test after a 10-second timeout.

* *log_auto_indent* = **Boolean**; choose whether to allow auto-indentation of CLI logs.

* *log_cli* = **Boolean**; specify whether or not you want to see execution logs during test executions.

* *log_file *= log/log FileName.txt; write test logs into a file in your project root directory.

* *log_file_date_format* = %Y-%m-%d %H:%M:%S; append test time and date to log files.

* *log_level* = INFO; specify the log type.
>  **In this article, we will delve into the fundamentals of [Quality Assurance](https://www.lambdatest.com/learning-hub/quality-assurance?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=learning_hub), its key principles, methodologies, and its vital role in delivering excellence.**

## Project Structure

This section on press enter without WebElement in Selenium Python shows the entire test suite structure:

     
    test_directory
    ├─ .gitignore
    ├─ pytest.ini
    ├─ README.md
    ├─ settings
    │  └─ Setup.py
    ├─ suites
    │  ├─ test_reg_action_chain.py
    │  └─ test_reg_js_action.py
    └─ webactions
       ├─ javaScript_web_actions.py
       └─ action_chain_web_actions.py

**File descriptions:**

* ***settings/Setup.py *:** It contains the setup class for the entire test suite. All test demos share this setup.

* ***suites/test_reg_action_chain.py *:** Contains the *ActionChain *test demo. When executed, it runs the test using the *ActionChain* class.

* ***suites/test_reg_js_action.py *:** Holds the test execution class for the JavaScript web actions (execute_script).

* ***webactions/javascript_web_actions.py *:** This file contains the web page locator and the web action classes. We import and use it inside the **suites/test_reg_js_action.py **file.

* ***webactions/action_chain_web_action.py *:** Test suite web actions and locators that use the *ActionChain* are in this file. We import it into suites/test_reg_action_chain.py to use its class attributes and methods.

**General Test Setup:**

Here’s the setup code for the test suite.

**FileName — settings/Setup.py**

    from selenium import webdriver
    from dotenv import load_dotenv
    import os
    load_dotenv('.env')
    LT_USERNAME = os.getenv("LT_USERNAME")
    LT_ACCESS_KEY = os.getenv("LT_ACCESS_KEY")
    desired_caps = {
            'LT:Options' : {
                "user" : os.getenv("LT_USERNAME"),
                "accessKey" : os.getenv("LT_ACCESS_KEY"),
                "build" : "FireTest New",
                "name" : "FireBrowser",
                "platformName" : os.getenv("test_OS")
            },
            "browserName" : "FireFox",
            "browserVersion" : "103.0",
        }
    gridURL = "@hub.lambdatest.com/wd/hub">https://{}:{}@hub.lambdatest.com/wd/hub".format(LT_USERNAME, LT_ACCESS_KEY)
    class Setting:    
        def __init__(self):
            self.driver = webdriver.Remote(command_executor=gridURL, desired_capabilities= desired_caps)
        def setUp(self):
            self.driver.implicitly_wait(10)
            self.driver.maximize_window()
        def tearDown(self):
            if (self.driver != None):
                print("Cleaning the test environment")
                self.driver.quit()

The above code is the *Settings* class for the test suite. You start by importing the required libraries and loading your grid username and access key from the environment variable file using the dotenv package.

![](https://cdn-images-1.medium.com/max/2000/0*y4mSWrLTF6bJOf_k.png)

To obtain your grid username and access key, head over to your [LambdaTest Dashboard’s ](https://automation.lambdatest.com/build?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=webpage)**Builds** directory. Click the **Access Key** button at the top right to reveal your grid details.

![](https://cdn-images-1.medium.com/max/3200/0*91DW-Z9owXsbEjqj.jpg)
>  **This detailed guide explains how to detect [flaky tests](https://www.lambdatest.com/learning-hub/flaky-test?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=learning_hub), its causes, strategies to reduce flakiness and much more.**

The *Settings *class starts with the driver attribute. The driver attribute connects to the remote grid using the *webdriver.Remote* method; this accepts the *gridURL* variable and the desired_capabilities dictionary as the test executor and test capability settings, respectively.

In this blog on press enter without WebElement in Selenium Python, we will generate the test capabilities from the [LambdaTest Automation Capability Generator](https://www.lambdatest.com/capabilities-generator/?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=webpage) as done in this test demo.

We used Firefox version 103.0 as the test browser in this demo. The chosen OS platform is Windows 10 (loaded from the .env file as shown below).

![](https://cdn-images-1.medium.com/max/3200/0*z3y1l3E71m9NMVgI.png)

The *setUp *method pauses the driver implicitly for DOM elements to load. It then maximizes the window once it loads.

![](https://cdn-images-1.medium.com/max/2000/0*e3JodhnYrilUizOT.png)

The *tearDown* method cleans up the test environment and quits the browser after each test.

![](https://cdn-images-1.medium.com/max/2008/0*HkkcE5pugZNEpeaR.png)

We only need one setup file since the entire test suite shares the *Settings *class.

As mentioned earlier, I’ll start the test demonstration using Selenium’s *ActionChains*. Then I’ll show you how to run similar test steps using the JavaScript (*execute_script)* method.

So let’s get started with the demonstrations in the following sections.

## Testing with Selenium’s ActionChains

This section on press enter without WebElement in Selenium Python details the test demonstration using the *ActionChains* class.
We’ll start with the web actions ***(webactions/action_chain_web_action.py)***, which we’ll then import and use inside the *ActionChains* test runner (***suites/test_reg_action_chain.py***)

**Let’s look at our test scenario before we begin:**

 1. Open the test website.

 2. Press the Tab key until the mouse points to the first input field.

 3. Fill the input fields sequentially with data.

 4. Press the terms and conditions checkbox.

 5. Submit the registration form.

 6. Check for a successful registration by taking the title of the following web page.
>  **This guide focuses on [test automation metrics](https://www.lambdatest.com/learning-hub/test-automation-metrics?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=learning_hub), its significance, strategies, challenges, and key test automation metrics for measuring success.**

**FileName — webactions/action_chain_web_action.py**

    from selenium.webdriver.common.by import By
    import time
    class todoLocator:
        First_Name = 'input[placeholder=\"First Name\"]'
        Last_Name = 'input[placeholder=\"Last Name\"]'
        Email = 'input[placeholder=\"E-Mail\"]'
        Phone = 'input[placeholder=\"Telephone\"]'
        Password = 'input[placeholder=\"Password\"]'
        Password_Confirm = 'input[placeholder=\"Password Confirm\"]'
        Subscribe_yes = ".//*[contains(text(), 'Yes')]"
        Agree_Yes = ".//*[contains(text(), 'I have read and agree to the')]"
        Submit_Button ='input[value=\"Continue\"]'
    class registerJSWebActions(todoLocator):
        def __init__(self, driver) -> None:
            self.driver = driver
        def getWeb(self, URL):
            self.driver.get(URL)
    
        def getTitle(self):
            return self.driver.title    
        def inputfirstName(self, firstName):    
            first_name_field = self.driver.execute_script(
                "return document.querySelector('{}');".format(self.First_Name)
                )    
            return self.driver.execute_script(
                "arguments[0].value='{}';".format(firstName),
                  first_name_field
            )     
        def inputlastName(self, lastName):    
            last_name_field = self.driver.execute_script(
                "return document.querySelector('{}');".format(self.Last_Name)
                ) 
            return self.driver.execute_script(
                "arguments[0].value='{}';".format(lastName),
                  last_name_field
            )
        def inputEmail(self, email):
            Email_field = self.driver.execute_script(
                "return document.querySelector('{}');".format(self.Email)
                ) 
            return self.driver.execute_script(
                "arguments[0].value='{}';".format(email),
                  Email_field
            )
        def inputPhone(self, phone):
            phone_field = self.driver.execute_script(
                "return document.querySelector('{}');".format(self.Phone)
                )
            return self.driver.execute_script(
                "arguments[0].value='{}';".format(phone),
                  phone_field
            )
        def inputPassword(self, password):
            password_field = self.driver.execute_script(
                "return document.querySelector('{}');".format(self.Password)
                )
            return self.driver.execute_script(
                "arguments[0].value='{}';".format(password),
                  password_field
            )
     
        def inputpasswordConfirm(self, password_confirm):
            password_confirm_field = self.driver.execute_script(
                "return document.querySelector('{}');".format(self.Password_Confirm)
                )
            return self.driver.execute_script(
                "arguments[0].value='{}';".format(password_confirm),
                  password_confirm_field
            )
        def subScribe(self):
            subscribebox = self.driver.find_element(By.XPATH, self.Subscribe_yes)
            return self.driver.execute_script("arguments[0].click()", subscribebox)
        def agreetoTerms(self):
            agree_field = self.driver.find_element(By.XPATH, self.Agree_Yes)
            return self.driver.execute_script("arguments[0].click()", agree_field)
        def submit(self):
            submit_button = self.driver.execute_script(
                "return document.querySelector('{}')".format(self.Submit_Button)
                )
            self.driver.execute_script("arguments[0].click()", submit_button)
            time.sleep(10)

While you’ll typically write *ActionChains* in sequence, I separated each into methods to make it more readable, reusable, and callable while executing the test runner.

Since our test needs to send data and locate elements in an action chain, we start by importing **Keys, ActionChains**, and **By** from Selenium.

![](https://cdn-images-1.medium.com/max/2100/0*_6vJ7ryTbpqyF4Jl.png)

The locator class *(todoLocator)* only defines the website header element and the terms agreement checkbox.

![](https://cdn-images-1.medium.com/max/2808/0*-PC1dD6Uf3E4To8s.png)

The registration *WebAction* class *(registerWebActions)* inherits the locator class to use its attributes. It then initializes with the WebDriver; we’ll derive this from the *Settings* class while instantiating this object inside the test runner file.
Next is the declaration of the driver and the action attributes; these are the driver and the *ActionChains*, respectively.

![](https://cdn-images-1.medium.com/max/2100/0*4G5tASFI7kjOJ9O-.png)

Next are the methods for launching the web page URL and getting its title.

![](https://cdn-images-1.medium.com/max/2000/0*Cm2tt8ZlFS8Ks24x.png)
>  **Learn the ins and outs of [test execution engines](https://www.lambdatest.com/learning-hub/test-execution-engine?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=learning_hub) through our extensive guide, and enhance your testing workflow with automation.**

The header element is easy to locate since most web pages have one. I included it in the locator earlier because I wanted to start tabbing from the header element, and the test needs to click a blank point on the header to begin tabbing from there.

This allows you to count the number of times your test needs to press the Tab key to point the mouse to the first form field.

Think of this as navigating a web page using your keyboard without the mouse; you might need to press the Tab key a few times to get to a particular location. We applied a similar concept to mimic a user’s interaction with a web page.

In our case, the test clicks the header elements and presses the Tab Key six times before reaching the first input field.

![](https://cdn-images-1.medium.com/max/2804/0*zECsHVY_1Qv-9ubL.png)

We’ll also intermittently press the Tab key once or twice in some places. So next, we define methods for pressing Tab once and twice. These are handy while executing these actions inside the test runner file ***(suites/test_reg_action_chain.py)*.**

![](https://cdn-images-1.medium.com/max/2000/0*LK9Pmpix9HpXlTH0.png)

Next, we define functions for entering the user’s details into the form fields. As mentioned earlier, Selenium executes *ActionChains *sequentially. So Under the hood, each class method is a sequence of the previous one.

![](https://cdn-images-1.medium.com/max/2280/0*ong9C9PLwDCaRMDh.png)

As for the terms and agreement checkbox — it needs a ***click*** action before you can submit a registration form — so we located that previously using its text content parameter with the *XPath* method inside the todoLocator class. Locating a web element this way doesn’t require a CSS locator since [XPath](https://www.lambdatest.com/blog/complete-guide-for-using-xpath-in-selenium-with-examples/) finds it by the specified text.

However, multiple elements with the exact text content on the same web page can limit this method. But you can leverage XPath’s node (nth) feature to solve this problem.

Here’s how we call an action on the agreement checkbox:

![](https://cdn-images-1.medium.com/max/2500/0*OvG-7pihVkmKGJFS.png)
>  **Explore our comprehensive guide on [GUI Testing,](https://www.lambdatest.com/learning-hub/gui-testing?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=learning_hub) uncovering its vital role in software development. Learn about its different types, best practices, and steps for effective implementation to enhance your software’s user interaction.**

The *self.agree_yes* attribute comes from the inherited locator class (*todoLocator*).
The form-filling actions end with the submit method for submitting the form. This only involves pressing the Enter key (*Keys.Enter*).

![](https://cdn-images-1.medium.com/max/2000/0*g2q4Pv1RWttFplR3.png)

Finally, we define the action execution method (*executeactionChain*) to perform the declared actions inside an action chain. We achieve this using *ActionChains*’ *action.perform* method.

The *implicitly_wait* method is only a desired test property, not a requirement. It pauses the browser window for 10 seconds before exiting the test. You can remove it if you don’t want a pause after the test execution.

![](https://cdn-images-1.medium.com/max/2000/0*SDwpOc4-86E6wvA-.png)

**FileName — suites/test_reg_action_chain.py**

    import sys
    sys.path.append(sys.path[0] + "/..")
    from webactions.action_chain_web_action import registerWebActions
    from settings.Setup import Setting
    settings = Setting()
    webactions = registerWebActions(settings.driver)
    
    class TestUserReg():
        def test_user_registration(self):
            settings.setUp()
            webactions.getWeb(  "https://ecommerce-playground.lambdatest.io/index.php?route=account/register")
            title = webactions.getTitle()
            assert "Register" in title, "Todo is not in title"
            webactions.navigatetoForm()
            webactions.inputfirstName("Idowu")
            webactions.presstabOnce()
            webactions.inputlastName("Omisola")
            webactions.presstabOnce()
            webactions.inputEmail("miniTest12@gmail.com")
            webactions.presstabOnce()
            webactions.inputPhone("08044554455")
            webactions.presstabOnce()
            webactions.inputPassword("12345678")
            webactions.presstabOnce()
            webactions.inputpasswordConfirm("12345678")
            webactions.presstabTwice()
            webactions.agreetoTerms()
            webactions.presstabTwice()
            webactions.submit()
            webactions.executeactionChain()
            settings.driver.current_url
            current_title = webactions.getTitle()
            assert "Created" in current_title, "Created is not in title"
            settings.tearDown()

The code above executes the web action chains when you run the *pytest* command via the terminal.

First, we import the sys module and use this to append to the module system paths. Then we import the *registerWebActions* class from the *action_chain_web_action.py*module. We instantiate this as *webactions* using the driver attribute from the settings object; this allows the WebDriver to act on the test website as declared in the *ActionChains*.

We also import *Setting* from the setup module (instantiated as settings).

![](https://cdn-images-1.medium.com/max/2592/0*4t-4-6ZDoQ6uMl2F.png)

The *TestUserReg* class has only one method, *test_user_registration*, that executes the web action methods from the *registerWebActions* class.

We call the *setUp* method to set up the test environment and maximize the browser window. As a convention, the test starts by launching the test website.

Then we get the web page title using the *getTitle* method of the *webactions* object and assert if “Register” is in the title text.

![](https://cdn-images-1.medium.com/max/3200/0*AnFGHwbqUbRgPw-l.png)

Next are the test steps execution:

**Step 1:** Our test navigates to the first form field.

![](https://cdn-images-1.medium.com/max/2000/0*ICTpNJO-js7BWuor.png)

**Step 2:** Fill the form fields and press the Tab key once after filling each input field.

![](https://cdn-images-1.medium.com/max/2004/0*M6iz1hOFmwKIMUvH.png)
>  **Looking to manage your tests more efficiently? In this blog, explore a variety of [test case management](https://www.lambdatest.com/blog/best-test-management-tools/?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=blog) tools and select the one that suits your team’s needs.**

I maintained the default subscription option, which is **No**. So there was no need to click that since I didn’t want to subscribe. You might need to write methods to use the Left and Right keys within the action chain class to switch between **Yes** and **No** if you want your test to “Subscribe to Newsletter.”

Hence, the test presses Tab twice to skip that option and jump to the “I have read and agree to the Privacy Policy” checkbox, which requires a click action.

![](https://cdn-images-1.medium.com/max/2000/0*B3sEoXu6maBZ5XAp.png)

**Step 3:** “Privacy Policy” is in a separate element. So our test presses Tab twice once more to point the mouse to the Submit button. It then presses the Enter key to submit the registration form and executes this action chain by calling the *executeactionChain* method.

![](https://cdn-images-1.medium.com/max/2000/0*dub91tg9Es2xidHW.png)

Finally, we get the current URL and assert if “Created” is in its title text to confirm whether or not our test successfully registered a user. Then we call the *tearDown* method of the *Settings* class to clean up the test environment and exit the test.

![](https://cdn-images-1.medium.com/max/2440/0*efznyz4gIyqgtBv1.png)

## Execution of the ActionChains

Go to your project root directory and run the *pytest* command:

    pytest

Here’s the test execution on the command line:

![](https://cdn-images-1.medium.com/max/3200/0*P-8oBGBbaqcDAs3l.jpg)

Our test also runs successfully on the cloud grid as shown below. Here we are using a cloud grid offered by the LambdaTest platform.

LambdaTest is a digital experience testing platform that enables developers and QA engineers to perform [Selenium Python testing](https://www.lambdatest.com/selenium-python-testing?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=webpage) on over 3000+ real browsers and OS combinations. LambdaTest provides support for different [Python testing frameworks](https://www.lambdatest.com/blog/top-python-frameworks-for-automation/?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=blog) to [Python automation testing](https://www.lambdatest.com/python-automation-testing?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=webpage). In addition, you can parallelize your test execution to expedite software release cycles.

Visit our documentation to [get started with Selenium Python testing](https://www.lambdatest.com/support/docs/python-with-selenium-running-python-automation-scripts-on-lambdatest-selenium-grid/?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=support_doc)

![](https://cdn-images-1.medium.com/max/3200/0*5hk7VkaKKw5QrnLs.jpg)

## Using Selenium’s JavaScript Executor (execute_script)

In this section of this blog on press enter without WebElement in Selenium Python, now let’s see how to navigate the same web page using JavaScript embedding (*execute_script* method).

**Let’s start with our test scenario**

 1. Open the registration page (test website).

 2. Fill in the registration form fields using JavaScript actions (*execute_script*).

 3. Click the terms and agreement checkbox using JavaScript’s click event.

 4. Click the submit button using JavaScript’s click event.

 5. Take the title on the following page to check for successful registration.

**FileName — webactions/javaScript_web_actions.py**

    from selenium.webdriver.common.by import By
    import time
    class todoLocator:
        First_Name = 'input[placeholder=\"First Name\"]'
        Last_Name = 'input[placeholder=\"Last Name\"]'
        Email = 'input[placeholder=\"E-Mail\"]'
        Phone = 'input[placeholder=\"Telephone\"]'
        Password = 'input[placeholder=\"Password\"]'
        Password_Confirm = 'input[placeholder=\"Password Confirm\"]'
        Subscribe_yes = ".//*[contains(text(), 'Yes')]"
        Agree_Yes = ".//*[contains(text(), 'I have read and agree to the')]"
        Submit_Button ='input[value=\"Continue\"]'
    class registerJSWebActions(todoLocator):
        def __init__(self, driver) -> None:
            self.driver = driver
        def getWeb(self, URL):
            self.driver.get(URL)
    
        def getTitle(self):
            return self.driver.title    
        def inputfirstName(self, firstName):    
            first_name_field = self.driver.execute_script(
                "return document.querySelector('{}');".format(self.First_Name)
                )    
            return self.driver.execute_script(
                "arguments[0].value='{}';".format(firstName),
                  first_name_field
            )     
        def inputlastName(self, lastName):    
            last_name_field = self.driver.execute_script(
                "return document.querySelector('{}');".format(self.Last_Name)
                ) 
            return self.driver.execute_script(
                "arguments[0].value='{}';".format(lastName),
                  last_name_field
            )
        def inputEmail(self, email):
            Email_field = self.driver.execute_script(
                "return document.querySelector('{}');".format(self.Email)
                ) 
            return self.driver.execute_script(
                "arguments[0].value='{}';".format(email),
                  Email_field
            )
        def inputPhone(self, phone):
            phone_field = self.driver.execute_script(
                "return document.querySelector('{}');".format(self.Phone)
                )
            return self.driver.execute_script(
                "arguments[0].value='{}';".format(phone),
                  phone_field
            )
        def inputPassword(self, password):
            password_field = self.driver.execute_script(
                "return document.querySelector('{}');".format(self.Password)
                )
            return self.driver.execute_script(
                "arguments[0].value='{}';".format(password),
                  password_field
            )
     
        def inputpasswordConfirm(self, password_confirm):
            password_confirm_field = self.driver.execute_script(
                "return document.querySelector('{}');".format(self.Password_Confirm)
                )
            return self.driver.execute_script(
                "arguments[0].value='{}';".format(password_confirm),
                  password_confirm_field
            )
        def subScribe(self):
            subscribebox = self.driver.find_element(By.XPATH, self.Subscribe_yes)
            return self.driver.execute_script("arguments[0].click()", subscribebox)
        def agreetoTerms(self):
            agree_field = self.driver.find_element(By.XPATH, self.Agree_Yes)
            return self.driver.execute_script("arguments[0].click()", agree_field)
        def submit(self):
            submit_button = self.driver.execute_script(
                "return document.querySelector('{}')".format(self.Submit_Button)
                )
            self.driver.execute_script("arguments[0].click()", submit_button)
            time.sleep(10)
>  **The ultimate guide to [software testing metrics](https://www.lambdatest.com/learning-hub/software-testing-metrics?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=learning_hub): definition, types, and examples explained for informed decisions. Enhance your testing process now!**

The above code defines the web actions for JavaScript embedding demonstration. It starts with the *todoLocator* class, whose attributes are the web element locators. However, these locators don’t require web element inspection, as they’re visibly definitive.

Although we don’t know the underlying DOM structure, we know they’re input fields with placeholders.

Thankfully, we can get these input elements using their placeholders with JavaScript’s *querySelector*. You’ll see how that works down the line.

![](https://cdn-images-1.medium.com/max/2560/0*vrNXPW8h71ph6hE0.png)

We trace the “Subscribe” option and the terms checkbox by their peculiar text content using the *XPath* method since we’ve assumed that we don’t know anything about their elements.

![](https://cdn-images-1.medium.com/max/2684/0*x2bj8ZLAeWShaLbG.png)

For the Submit input, I wasn’t sure at first whether it was a button or an input tag. But it works with the input tag. So sticking to locating an input with a text that says, “Continue” using XPath works.

![](https://cdn-images-1.medium.com/max/2000/0*Zk8dQq2UPcaoaGSs.png)

As we did earlier for the *ActionChains*, the *registerJSWebActions* class inherits the *todoLocators* class and its attributes and initializes with the WebDriver.

![](https://cdn-images-1.medium.com/max/2000/0*v2z_UpOC_1B6sSsh.png)

As mentioned, we’ll use JavaScript’s *querySelector* to pick on web elements rather than CSS Selector.

This takes the following form:

    document.querySelector(element)

Thus, a typical input field as used in our test looks like this:

![](https://cdn-images-1.medium.com/max/2748/0*TSSEgEjaJ93LTiTd.png)

The first_name_field variable defines the First Name input element grabbed using the *querySelector*. Since the embedded JavaScript is a string, we insert the First_Name attribute (inherited from *todoLocator* class) using Python’s string *format* method.

The returned code line within this method uses JavaScript to write the required data (*firstName*) into the form field accordingly.

![](https://cdn-images-1.medium.com/max/2100/0*7c58lzI866DlBfnM.png)

This is the convention for the other input actions.

However, the *subscribe* and *agreetoTerms* methods use XPath to locate web elements based on specified text content. These require click action. So JavaScript does that for us.

![](https://cdn-images-1.medium.com/max/2900/0*j9g1skpe_IafcUmT.png)

Finally, the test locates the Submit input button using the *querySelector* and submits the registration form using JavaScript’s click action.

![](https://cdn-images-1.medium.com/max/2808/0*_tacCQiH_ZU5uPrZ.png)

**FileName-suites/test_reg_js_with_actions.py**

    import sys
    sys.path.append(sys.path[0] + "/..")
    from webactions.javaScript_web_actions import registerJSWebActions
    from settings.Setup import Setting
    settings = Setting()
    webactions = registerJSWebActions(settings.driver)
    class TestUserRegWithJS():
        def test_user_registration_js(self):
            settings.setUp()
            webactions.getWeb(     "https://ecommerce-playground.lambdatest.io/index.php?route=account/register")
            title = webactions.getTitle()
            assert "Register" in title, "Todo is not in title"
            webactions.inputfirstName("Idowu")
            webactions.inputlastName("Omisola")
            webactions.inputEmail("Iminsshjsyytdsas@gmail.com")
            webactions.inputPhone("08044554455")
            webactions.inputPassword("12345678")
            webactions.inputpasswordConfirm("12345678")
            webactions.subScribe()
            webactions.agreetoTerms()
            webactions.submit()
            settings.driver.current_url
            current_title = webactions.getTitle()
            assert "Created" in current_title, "Created is not in title"
            settings.tearDown()

The above code executes the JavaScript web actions written earlier. First, we import the registerJSWebActions and Setting from their respective modules.

We then instantiate the *Setting* class as *settings*. We instantiate the r*egisterJSWebActions* class as *WebActions* using the driver attribute from the *settings* object.

![](https://cdn-images-1.medium.com/max/2624/0*L-iY6OWWWsJ6PrOa.png)

The *TestUserRegWithJS* class holds the test execution method (*test_user_registration_js*).

**Step 1:** This starts with the test setup, website launching, and title grab with an assertion to check if the browser agent has loaded the test website successfully.

This is similar to the action chain option code.

![](https://cdn-images-1.medium.com/max/3200/0*Gotx_bBZ2IEb41ei.png)

**Step 2:** Next, we call the input actions as shown below:

![](https://cdn-images-1.medium.com/max/2068/0*ltjHOfagiHpFS4TB.png)

**Step 3:** Click the Subscribe and Terms agreement buttons:

![](https://cdn-images-1.medium.com/max/2000/0*kQSdFQe3ADYHmyTJ.png)

**Step 4:** Finally, click the Submit button, get the next page title, and assert whether or not the test registered the user successfully.

![](https://cdn-images-1.medium.com/max/2440/0*bsBmv4hVsKE8TTWV.png)

**Step 5:** Quit the browser and end the test by calling the *tearDown* method from the *Setting* class:

![](https://cdn-images-1.medium.com/max/2000/0*3TB4z2TuQU5CuFp7.png)

## JavaScript (execute_script) Demo Execution

To execute the JavaScript demonstration for navigating the web without an element, cd into your project root folder from the command line and run the *pytest* command:

    pytest

Provided the registered email address is unique, the test runs successfully, as seen via the command line:

![](https://cdn-images-1.medium.com/max/3200/0*emQEbcdHNBRvqwtH.jpg)

Our demo also runs successfully on the cloud grid, as shown below:

![](https://cdn-images-1.medium.com/max/3200/0*cQvkvDnH-Vvpe_YW.jpg)
>  **Deep dive to learn about test automation, its uasage, types and also gain insights on how to get started with [automated testing](https://www.lambdatest.com/learning-hub/automation-testing?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=learning_hub).**

## You can get creative with your automation testing

No cap fits it all when navigating a web page without specifying elements. While the options we’ve considered may save time in some cases, they could also be daunting for testing complex websites or executing [end-to-end testing.](https://www.lambdatest.com/learning-hub/end-to-end-testing?utm_source=devto&utm_medium=organic&utm_campaign=jul_27&utm_term=bh&utm_content=learning_hub)

If web elements are available, testing a website without inspecting its DOM for CSS Selectors isn’t a best practice. It could be costly, time-consuming, and confusing. However, such a situation might cross your way as a tester. Improvise your way with the test website — regardless of the odds.

As you’ve seen in our test demos, the *ActionChains* class and the *execute_script* methods are handy to navigate a website and press enter without WebElement in Selenium Python.

We had to go through some logical trials to navigate the test web page and complete the automation testing.

## Frequently Asked Questions (FAQs)

### What is the command for Enter text in Selenium?

In Selenium, the command for entering text into an input field is the *send_keys()* method. Here’s an example of how to use it:

    element = driver.find_element_by_id("myInput")
    element.send_keys("Hello, World!")

In this example, driver refers to the WebDriver instance, and *find_element_by_id(“myInput”)* is used to locate the input field element on the webpage. The *send_keys()* method is then called on the element to enter the desired text, which in this case is “Hello, World!”.

You can replace “*myInput*” with the appropriate locator method (find_element_by_name, find_element_by_xpath, *find_element_by_css_selector*, etc.) based on how you want to locate the element.

After using *send_keys()* to enter the text, you can interact with other elements or simulate additional actions as needed.