Unexpected Behavior of JavaScript Execution in WebDriver

Currently, I am using the JBehave-Web distribution (3.3.4) with Webdriver to conduct testing on an application. I have encountered a peculiar issue:

My challenge lies in interacting with a modalPanel from Richfaces, as it consistently throws an ElementNotVisibleException. To address this, I have resorted to using JavaScript:

Below is the snippet of code from my page object, which extends from org.jbehave.web.selenium.WebDriverPage:

protected void changeModalPanelInputText(String elementId, String textToEnter){
    makeNonLazy();
    JavascriptExecutor je = (JavascriptExecutor) webDriver();
    String script ="document.getElementById('" + elementId + "').value = '" + textToEnter + "';";
    je.executeScript(script);
}

What baffles me is that when I run the test normally, nothing happens. However, if I place a breakpoint on the last line (in Eclipse), select the line, and execute it from Eclipse (Ctrl + U), I can observe the changes in the browser.

I have examined the JavascriptExecutor and WebDriver classes to check for any potential buffering mechanisms, but so far, I have come up empty. Any insights?

EDIT Upon experimentation, I have discovered that introducing a 1-second thread sleep allows the code to work. It seems to be some sort of race condition, but the root cause remains elusive...

This is the workaround that somewhat "solves" the issue, although I am not entirely satisfied with it:

protected void changeModalPanelInputText(String elementId, String textToEnter){
    String script ="document.getElementById('" + elementId + "').value = '" + textToEnter + "';";
    executeJavascript(script);
}

private void executeJavascript(String script){
    makeNonLazy();
    JavascriptExecutor je = (JavascriptExecutor) webDriver();
    try {
        Thread.sleep(1500);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    je.executeScript(script);       
}

Attempts to place the wait in different positions have proved futile...

Answer №1

Initial suggestion:

Check if the target element is initialized and enumerable to avoid null return:

Object objValue = je.executeScript(
    "return document.getElementById('"+elementId+"');");

If you are using makeNonLazy(), it may be helpful to include the target as a WebElement member of your Page Object (assuming Page Factory initialization in JBehave).

Another approach:

Use explicit waiting for the element to be present before making changes:

/**
 * Utility class for reusability
 */
public static class ElementAvailable implements Predicate<WebDriver> {

    private static String IS_NOT_UNDEFINED = 
        "return (typeof document.getElementById('%s') != 'undefined');";
    private final String elementId;

    private ElementAvailable(String elementId) {
        this.elementId = elementId;
    }

    @Override
    public boolean apply(WebDriver driver) {
        Object objValue = ((JavascriptExecutor)driver).executeScript(
                String.format(IS_NOT_UNDEFINED, elementId));
        return (objValue instanceof Boolean && ((Boolean)objValue));
    }
}

...

protected void modifyModalPanelInputText(String elementId, String textToEnter){
    makeNonLazy();

    // Wait up to 3 seconds before throwing an unchecked Exception
    long timeout = 3;
    (new WebDriverWait(webDriver(), timeout))
            .until(new ElementAvailable(elementId));

    // Element is now definitely available
    String script = String.format(
            "document.getElementById('%s').value = '%s';",
            elementId,
            textToEnter);
    ((JavascriptExecutor) webDriver()).executeScript(script);
}

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

Implementing sliders for interactive functionality with an HTML table

I need to implement sorting and sliding features on an HTML table using jQuery. Sorting has already been achieved by utilizing the DataTable.js jQuery library. The challenge now is to incorporate a slider into the table, with all subject columns being scro ...

Encountered an error while trying to set up the route due to Router.use() needing

Within my app.js file, I have the following code: app.use('/', require('./routes')); //old routes app.use('/api', require('./api')); Additionally, I have an api folder containing an index.js file. This is what the ...

There are times when window.onload doesn't do the trick, but using alert() can make

I recently posted a question related to this, so I apologize for reaching out again. I am struggling to grasp this concept as I am still in the process of learning JavaScript/HTML. Currently, I am loading an SVG into my HTML using SVGInject and implementi ...

Is there a method to obtain over 10 markers on the map?

Trying to find nearby places from my current location. The issue I'm currently facing is that I'm only able to see 10 markers on the map, and no more locations are being displayed. Is there a way to bypass or resolve this problem? I've come ...

Problem with Bcryptjs Async Implementation

I have implemented a function in my node server using bcryptjs to hash and compare passwords. Here is the code snippet: this.comparePasswords = function(password1, password2, callback) { bcrypt.compare(password1, password2, function(error, result) { ...

Issues with jQuery .on() hover functionality in HTML5 select element not being resolved

I'm currently working on capturing the event triggered when the mouse hovers over a select box, regardless of whether it's collapsed or expanded. My approach involves using .on() in the following manner: $(document).on('hover', "select ...

What causes a React Ref callback to be invoked multiple times during the initial loading of a page?

To find more information, please visit this URL within the React DOCS. You can also access a version of this code here. I acknowledge that it is recommended to use the useCallback hook in a Functional React Component to create a ref callback according to ...

Cross-origin resource sharing (CORS) policy issue arises when the 'Access-Control-Allow-Origin' header is not included in the requested resource, especially when utilizing an iframe in a React

I am trying to link a website to a button using an iframe. This website allows access to all domain names. Below is the code for my button: <Button component={NavLink} activeClassName={classes.activeBtn} to="/searchEngine&qu ...

What could be causing the frontend to receive an empty object from the express server?

Struggling to understand how to execute this request and response interaction using JavaScript's fetch() along with an Express server. Here is the code for the server: var express = require('express'), stripeConnect = require('./r ...

The process of ensuring an element is ready for interaction in Selenium with Javascript

I am currently working on creating an automated test for a Single Page Application built with VueJs. When I click on the registration button, a form is loaded onto the page with various elements. However, since the elements are loaded dynamically, they are ...

Is it possible to access a nested web element within another web element?

Hey there, do you have a passion for web elements? I am curious to know if it's achievable to locate a specific web element using classes, IDs, or other selectors, and then search within that element to find another element by its class. Situation ...

Issue encountered while attempting to adjust a date (the modification was incorrect)

I am currently working on developing a calendar feature using Angular. Part of this project involves implementing drag and drop functionality to allow users to move appointments from one day to another. However, I have encountered a strange issue. When at ...

AngularJS: Unable to preserve the data

I'm currently working on an issue with saving updated functions using angularJS. I've managed to edit the data and update it on the database side, but the changes aren't reflecting on the frontend side unless I logout and login again. I need ...

Using JavaScript and HTML to show the current month, date, and year on a webpage

I am looking to display not only the time, but also the month, date and year. My attempted solution involved creating variables for the month, day and year, and then using getElementById. Here is an example of what I tried: var d = date.getDay(); var mn ...

Discovering xpath in Firefox version 57.0 without the use of Firepath

Struggling to locate xpath in the latest version of Firefox (57.0) without firepath. Unfortunately, firepath is no longer compatible with the new Firefox version. Does anyone have any suggestions for an alternative method for utilizing xpath? ...

WebDriver issue: Error message stating that the element '/?/?/button[@accessiblename='Close']' contains an invalid token

I am working on a simple test case to test a win32 app using Selenium Library. My goal is to close the app using Xpath. Below is the code snippet: *** Settings *** Library Process Suite Teardown Terminate All Processes kill=True *** TestCases *** ...

Converting JQuery Object (Ajax-response) to an Array Containing Keys and Values

When I make an $.ajax request, the response I receive looks like this: https://i.sstatic.net/UfnfQ.jpg (please don't worry about the Russian symbols, they are just strings of text:)) I am aware that when PHP sends the request, it is in a simple arr ...

When the buffer is sent through the socket in NodeJS, the console responds by stating that it is not recognized as a buffer

I've been exploring the implementation of AES encryption in ECB mode and here is the code snippet I'm working with. function encrypt (key, iv, plaintext) { if(algorithm == 'aes-128-ecb') iv = new Buffer(''); var ciphe ...

The process of altering the color of a table row in JavaScript can be done after dismissing a pop-up that was triggered by a button within the same row

I am tasked with changing the color of a specific table row based on user interaction. The table consists of multiple rows, each containing a button or image. When the user clicks on one of these buttons or images, a popup appears. Upon successful data sub ...

I attempted to post a collection of strings in ReactJS, only to receive a single string response from the Web

I was troubleshooting an issue where only one string from ReactJS was being sent to WebApi instead of an array of strings. Below is the ReactJS code snippet I used: import React, { useState } from "react"; import axios from "axios"; e ...