Fixing unresponsive element error in Selenium: clicking a button within a bootstrap modal using JavaScript

I have a basic webpage featuring a button that triggers a Bootstrap modal. However, even though the modal pops up, I can't seem to interact with the button inside the modal.

I've attempted three different approaches to tackle this issue: 1) trying to directly locate the element, 2) locating the element through the modal element itself, and 3) using an explicit wait. Unfortunately, all three methods result in the same error - ElementNotInteractableError: element not interactable.

While it's possible that this problem has been addressed elsewhere on Stack Overflow (which is why I tried multiple approaches), none of the solutions provided there were able to help me.

Here is the error stack trace:

DevTools listening on ws://127.0.0.1:50284/devtools/browser/1a87603d-af78-486d-bc37-161eeeed16ba [5396:11184:0428/110516.874:ERROR:browser_switcher_service.cc(238)] XXX Init() ElementNotInteractableError: element not interactable (Session info: chrome=81.0.4044.122) at Object.throwDecodedError (D:\ip300-gk\node_modules\selenium-webdriver\lib\error.js:550:15) at parseHttpResponse (D:\ip300-gk\node_modules\selenium-webdriver\lib\http.js:565:13) at Executor.execute (D:\ip300-gk\node_modules\selenium-webdriver\lib\http.js:491:26) at processTicksAndRejections (internal/process/task_queues.js:93:5) at async Driver.execute (D:\ip300-gk\node_modules\selenium-webdriver\lib\webdriver.js:700:17) at async uitest (D:\ip300-gk\Samples\bootstrap\bs-modal-selenium\uitest.js:26:11) { name: 'ElementNotInteractableError',

Below is the JavaScript test code where all three approaches were attempted:

const driver = require('selenium-webdriver')
const assert = require('assert').strict;
const {Builder, By, Key, until} = require('selenium-webdriver');

let fileName = "D:\\ip300-gk\\Samples\\bootstrap\\bs-modal-selenium\\index.html"
uitest()


async function uitest() {
    let driver = await new Builder().forBrowser('chrome').build();
    let modal, element


    try {
        await driver.get(fileName)
        await driver.findElement(By.id('launchModalButton')).click()

        // approach 1 - getting error - ElementNotInteractableError: element not interactable
        // await driver.findElement(By.id('saveChangesButton')).click()

        // approach 2 using explicit wait - getting error -  ElementNotInteractableError: element not interactable
          element = await driver.wait(until.elementLocated(By.id('saveChangesButton')))
          await element.click()

        // approach 3 - finding modal using root modal - getting error - //ElementNotInteractableError: element not interactable
        //   modal = await driver.findElement(By.id('exampleModal'))
        //   await modal.findElement(By.id('saveChangesButton')).click()


    } catch (err) {
        console.log(err)
    } finally {
        await driver.quit();
    }
}

This is the HTML code for the Bootstrap page:

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
          integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
    <title>Selenium </title>
</head>
<body>

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
        integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
        crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"
        integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49"
        crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"
        integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy"
        crossorigin="anonymous"></script>


<div class="container">
    <button type="button" id="launchModalButton" class="btn btn-primary mt-5" data-toggle="modal" data-target="#exampleModal">
        Launch modal
    </button>

    <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
         aria-hidden="true">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    Sample Modal
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                    <button id="saveChangesButton" type="button" class="btn btn-primary">Save changes</button>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
</html>

Answer №1

It appears that there may be an overlay covering the button or the button is not visible when running the test. To remedy this issue, consider using a JavaScript click command instead of the standard click.

element = await driver.wait(until.elementLocated(By.id('saveChangesButton')))
driver.executeScript("arguments[0].click();", element)

Answer №2

It seems that the modal did not load properly, causing Selenium to be unable to find the button inside and click it. Adding an implicit wait after launching the modal solved the problem.

await driver.findElement(By.id('launchModalButton')).click()
await driver.manage().setTimeouts( { implicit: 1000} )

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Populating Dropdown list with values based on input provided in Textbox

Can you assist me in finding the solution to this issue? I have a TextBox and a DropDown list. For example, if I type "Anu" into the textbox, I want it to populate the dropdown list based on the text entered. How can I achieve this? I am working with vb. ...

Leverage npm JavaScript packages within an Ionic2 TypeScript project

Just diving into my first project with Ionic2 (TypeScript) and I'm trying to incorporate the npm JavaScript package. Specifically, I am utilizing https://github.com/huttarichard/instagram-private-api I'm a bit confused on how to correctly use im ...

Tips for redirecting JavaScript requests to the target server using curl on a server

Currently, I am running a crawler on my server and require the execution of JavaScript to access certain data on the target site that I want to crawl. I recently had a question about a different approach to this issue, but for now, I need help with the fol ...

Remove an item from the options list in the select2 plugin after an event occurs

I am currently using the Select2 plugin in my project and I am facing an issue where I want to remove an option from the main list. However, when I click on the "x" button generated by the code, it only removes it temporarily from the plugin's list. U ...

When the collapse button is clicked, I aim to increase the top value by 100. Subsequently, upon a second click, the top value should

https://i.stack.imgur.com/p9owU.jpghttps://i.stack.imgur.com/Kwtnh.jpg I attempted to utilize jQuery toggle, but unfortunately, it is not functioning as expected. <script> $(document).ready(function () { $(".sidebar ul li&quo ...

The issue arises when the parameter value is used in conjunction with jQuery's :not()

Currently, I am developing a simple functionality for radio buttons that activates an input text box when clicked. If any other radio button is selected, the input field should go back to its disabled state. Initially, everything was working smoothly unti ...

I can't seem to locate the right-click menu in Chrome version 99 – any

I'm facing a challenge in locating the xPath of an element in the most recent version of Chrome (v99). It seems that the right-click menu in Chrome's "inspect" panel is inaccessible. Does anyone know how to determine the xPath of elements for Sel ...

Having trouble replacing bootstrap with external CSS

As a beginner in a coding bootcamp, I have been introduced to the world of bootstrap. While some of my friends shy away from using it for various reasons, I have no choice but to learn it in class. I've experimented with different techniques to style ...

Converting a dataset into an array of objects using Javascript or Typescript

I am working with an input object consisting of two arrays. payload columns:["col1", "col2","col3"], data: ["col1value1","col2value1" , "col1value3"] , ["col1value2","col2value2" , "col1value2"] My goal is to convert these two arrays into objects ...

Ensure that the text field in vue.js restricts input to integers and cannot be left empty

Trying to implement an input field in vue.js that only accepts integer values, ensures the quantity is not 0, and defaults to 1 if left empty. I attempted to block decimals with the code: <input type="number" min="1" @keydown="filterKey"></input& ...

Web audio: setTimeout slows down when mobile screen is turned off

In response to Yogi's feedback (refer to the discussion on "setTimeout" and "throttling" in https://developer.mozilla.org/en-US/docs/Web/API/setTimeout ), I attempted to enhance performance by integrating an AudioContext. document.addEventListener(&ap ...

I am sorry, but it seems like there is an issue with the definition of global in

I have a requirement to transform an XML String into JSON in order to retrieve user details. The approach I am taking involves utilizing the xml2js library. Here is my TypeScript code: typescript.ts sendXML(){ console.log("Inside sendXML method") ...

Is it possible to run a script continuously, without interruption, using Puppeteer and Node.js for 24 hours a day,

My current macro, the Macro Recorder, runs continuously without any breaks. It involves viewing an item in one tab, ordering a specific quantity in another tab, writing a message, and repeating the process. I am considering using Puppeteer to accomplish t ...

What is the best way to break out of a function halfway through?

What are your thoughts on using nested if statements? $scope.addToCart = function () { if (flagA) { if (flagB) { if (flagC) { alert('nononono!'); return; } } } e ...

Handling asynchronous behavior in the context of conditional statements can be a challenging aspect of

Currently, this code section is passing undefined to if(customerWaiting >0). It's an async issue that I'm struggling to resolve. Despite my efforts and research on other threads, I can't seem to make this basic newbie question work. I&a ...

Using jQuery to combine a conditional statement with a click event and disabling a button using the `.prop('disabled', true)` method

Looking for some assistance with this issue I've encountered. After researching on StackOverflow, I managed to find a solution to disable button clicking if the form is left empty using the $.trim(.....) code below! Success! However, adding that part ...

Retrieving arrays in subdocuments with MongoDB queries

Being a novice in the realm of mongodb, I welcome any corrections if my terminology is incorrect: The document snippet below showcases some information: { "_id" : ObjectId("524b0a1a7294ec8a39d4230f"), "name" : "Irbesartan", "decompositions" ...

Open a new lead form in Crm 2013 by clicking a button and automatically passing the details of the

I have integrated an Add New Lead button into the main form on the Homepage for contacts. Clicking this button triggers a script that opens a new form and passes "Crm Parameter FirstSelectedItemId" as a parameter. By selecting a contact and clicking crea ...

Utilizing PHP to query arrays and pass variables to jQuery

Currently, I am in the process of learning how to transfer data retrieved from MySQL through PHP to an HTML form using jQuery. Upon querying the php file, the data is returned in two array variables: $resultsa and $resultsb I would greatly appreciate any ...

How can we assign priority to the child element for detection by the "mouseover" event in jQuery?

Can you help me figure out how to make the "mouseover" event prioritize detecting the child element over its parent? This is the jQuery code I've been using: <script> $(function() { $("li").mouseover(function(event){ $('#log&a ...