The behavior of JavaScript execution when typing in a text field does not align with the expected sendKeys method

Whenever I run my tests on a Linux machine, I encounter an issue with the way text is typed using the following code snippet:

visibleElement.clear();
visibleElement.sendKeys("I am running on linux machine");

Instead of typing the text correctly as expected, various permutations like "on linux machine I am running", "running on linux machine I am" etc appear in the UI.

To address this issue, I resorted to using JavaScript:

JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("arguments[0].value='I am running on linux machine';", visibleElement);

While this successfully types the text in the field, it disables the Save button which should actually be enabled. Interestingly, when I use sendKeys, the button is enabled.

I am seeking assistance in understanding why the JavaScript approach behaves differently and how to rectify it to ensure both functionalities work seamlessly without relying on hitting tab to enable the button, as that is not a viable solution for my scenario.

Answer №1

When you set arguments[0].value = "...", the value in the text field changes but no events are triggered on that element. The "Save" button is probably waiting for a change event to happen within the <form>. You will have to manually trigger a change event on the text box using JavaScript. For more information, refer to How can I trigger an onchange event manually?.

The way you describe the situation suggests that JavaScript may already be listening for the change event and rearranging the words in a Yoda-like manner. Manually triggering the change event could activate the "Save" button, potentially resulting in the same outcome as using sendKeys. In such cases, it might be necessary to also enable the "Save" button using JavaScript:

// Set the input text
jse.executeScript("arguments[0].value='I am running on linux machine';", visibleElement);

// Locate the "Save" button
WebElement saveButton = driver.findElement(...);

// Enable the save button
jse.executeScript("arguments[0].disabled = false;", saveButton);

saveButton.click();

Answer №2

Just because an element is initially visible doesn't necessarily mean it's also interactable, meaning it may not be clickable or ready to receive sendKeys().

In order to use sendKeys() on a specific element, you must wait for the element to become clickable using WebDriverWait along with the elementToBeClickable() method. You can follow this recommended Locator Strategy:

WebElement clickableElement = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(visibleElement))
clickableElement.click();
clickableElement.clear();
clickableElement.sendKeys("I am running on linux machine");

If you're interested in a more in-depth discussion, check out How to preserve the character sequence sent through SendKeys() method through Selenium and C#


tl; dr

For further insights, see Selenium: How selenium identifies elements visible or not? Is is possible that it is loaded in DOM but not rendered on UI?

Answer №3

Experiment with writing in either a promise style or async/await style.

async eraseContent(element) {
    // Using elem.clear() may not always work due to potential background JS interference
    await element.sendKeys(protractor.Key.chord(protractor.Key.CONTROL, 'a'));
    await element.sendKeys(protractor.Key.DELETE);
    // Waiting for Application Load can be done here
}

reverseText = str => str.split('').reverse().join();
// intersperse function inserts an item between each element of an array
// ex: intersperse('k')("abc") => ['a', 'k', 'b', 'k', 'c']
intersperse = char => string => string.split('').reduce((acc, char) => [...acc, c, char], []).slice(0, -1);

(async () => {
    // Assuming you have an element named visibleElement
    await browser.wait(protractor.ExpectedConditions.elementToBeClickable(visibleElement), default_timeout);

    await eraseContent(visibleElement);
    const reversedStr = reverseText('I am running on linux machine');
    const sequence = intersperse(protractor.Key.HOME)(reversedStr);
    // e, HOME, n, HOME, i, HOME, h, HOME, ...
    await visibleElement.sendKeys(protractor.Key.chord(...sequence));
})();

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

Ways to quickly terminate a pipeline in a JavaScript transformation

Issue: I am facing a challenge with handling large files (>10GB). At times, I need to process the entire file while other times I only need to sample a few lines. The processing mechanism involves a pipeline: pipeline( inStream, ...

Changing date and time into milliseconds within AngularJS

Today's date is: var timeFormat = 'dd MMM, yyyy hh:mm:ss a'; var todayDate = dateFormat(new Date(), timeFormat); Can we convert today's date to milliseconds using AngularJS? Alternatively, how can we use the JavaScript function getT ...

Are there any drawbacks to converting all instance methods into arrow functions in order to prevent binding loss?

What are the potential drawbacks of converting all instance methods into arrow functions to avoid the "lost binding" issue? For example, when using ReactJS, the statement onClick={this.foo} can lead to lost binding, as it translates to createElement({ ... ...

ES6 syntax makes use of variables enclosed in curly braces

Could you explain the impact of the bracket followed by a braces combination (for example, ({user}) below)? promise1.then(user => ({user})); ...

Navigating the data returned by an AJAX call can be quite perplexing

Every time a link is clicked on the website located at , an AJAX request triggers to load the content automatically. Lately, I have been encountering a perplexing piece of code injected into my response data: <script> var _q = document.createEle ...

python use selenium to select each checkbox individually instead of selecting all at once

df_new = list(df_current) for item in df_new: WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//html//body//div[2]//div//div[2]//div[1]//form//div//div[2]//div//div[2]//label[{}]//input".format(item)))).click() I suc ...

Testing VueX getters that rely on other getters in unit tests

I have successfully tested Vuex getters in isolation from other code, but I am encountering challenges when a getter relies on other getters. Here is an example to illustrate this situation: getters.js export const getters = { getFoo(state) => pref ...

Issue: Request from a different origin blocked

I encountered an issue while working on a web project using the PlanGrid API. I am receiving a cross-domain request block error. var apiKey="API KEY"; var password="PASSWORD"; $.ajax({ url: "https://io.plangrid.com/projects", xhrFields: { ...

What are the steps for implementing timezone-js?

I found a project on GitHub that claims to convert one timezone to another. I've been trying to get it to work without success. After downloading and extracting the files, I created an HTML file with the following code: <html xmlns="http://www.w3. ...

The mongoose library requires JSON input, yet it is unable to generate a dynamic JSON object from a Node

This question delves more into javascript and JSON concepts rather than focusing on the mongoose library. When working with Mongoose, conditions are expected to be in JSON format, like so: { $or: [ { "doc_no" : /first/i }, { "doc_type" : /second/i } ] ...

What is the best way to retrieve all arrays within a JSON object?

After successfully sending a JSON object from the view to HTML via AJAX in Django, it looks like this: json: Object name1: Array[2] name2: Array[2] age: '18' class: 'CLS01' phone: '' code: 'SV01' Now, I am trying t ...

Why is Selenium Webdriver unable to click on an element in Chrome, even though the same code works perfectly in Firefox?

I am working on automating the process of filling out time sheets in a web application. I have a list of weekends that are pending submission, which can be seen in this image: https://i.sstatic.net/jzOxY.png The user is required to input their choice from ...

Forward from the Ajax PHP script

I am currently working with a form that looks like this: <form action="process.php" method="post"> <input type="text" name="input" /> <button type="submit">Submit</button> </form> In addition to the form, I have an A ...

Testing for an exception using JUnit's assertTrue method

I am currently utilizing JUnit 4.0 to verify whether an application returns the expected output on a boolean method. The test structure is akin to the following: import org.junit.Test; import static org.junit.Assert.*; public class ExampleTest{ @Tes ...

Ways to retrieve the global state from within the mutation namespace module

Within my state, I have organized two namespace modules: portfolio and stocks. The structure looks like this: export default new Vuex.Store({ modules: { stocks, portfolio } }) The stocks module contains a property called stocks, while the por ...

Sending file streams from the frontend to the backend service using Express.js and the Fetch

In my ExpressJS application, I have created an endpoint that needs to proxy a large raw binary to a remote backend REST service without storing anything in memory. To achieve this, I initially looked into using the request module with code like: req.pipe( ...

Sending information from React JS to MongoDB

I am currently facing a challenge in sending data from the front-end (react js) to the back-end (node js), and then to a mongodb database for storage. While I have successfully called the server with the data, I am encountering an issue when attempting to ...

Utilize VueJS to streamline your filtering process

I recently started learning VueJS and I am facing an issue with using the vue filter. I need help resolving this problem. Below is a snippet of my HTML file. However, when I attempt to use this code, the items in v-for are not being displayed and there i ...

Activate inline javascript within LESS styling

I am interested in incorporating inline JavaScript into my less files, but I received the following notification: Inline JavaScript is not enabled. Have you configured it in your settings? What steps can I take to enable this feature? ...

Retrieving the Body of a Network Request Response in Python

Greetings! I am currently in the process of obtaining network request details such as headers, URL, and response. Although I have succeeded in retrieving the headers and URL, I am facing difficulty in accessing the response. I have referred to the follow ...