54

I have a long string to test and sendKeys() takes too long. When I tried to set the value of the text the program crashes. I know the Selenium sendKeys() is the best way to test the actual user input, but for my application it takes too much time. So I am trying to avoid it.

Is there a way to set the value right away?

See this quick example:

var webdriver = require('selenium-webdriver');

var driver = new webdriver.Builder().
   withCapabilities(webdriver.Capabilities.chrome()).
      build();

driver.get('http://www.google.com');

// find the search input field on google.com
inputField = driver.findElement(webdriver.By.name('q'));

var longstring = "test"; // not really long for the sake of this quick example

// this works but is slow
inputField.sendKeys(longstring);

// no error but no values set
inputField.value = longstring;

// Output: TypeError: Object [object Object] has no method 'setAttributes'

inputField.setAttributes("value", longstring);
Ripon Al Wasim
  • 34,088
  • 37
  • 146
  • 165
F. Rakes
  • 1,277
  • 2
  • 16
  • 25
  • Indeed the alternative to `sendKeys` would be to set the value of the `input` DOM element directly. However, you show only fragment of how you try to do it and you don't explain how the program "crashes" exactly. ("Crashes" is not precise at all.) – Louis Aug 30 '14 at 15:01
  • Sorry, I updated the Error message in the edit. – F. Rakes Aug 30 '14 at 15:05
  • Your code is still showing only *fragments* of how you do it. You don't show how `input` gets a value. You do show how `inputField` gets a value but not `input`, which is a different variable. – Louis Aug 30 '14 at 15:12
  • That was unfortunately a typo. It should be `inputField` throughout. With `.value = longstring` the program executes fine, but doesn't actually set the value. – F. Rakes Aug 30 '14 at 15:19
  • Similar for Python: [Set attribute of an element using webdriver](http://sqa.stackexchange.com/q/3387/2840) at SQA – kenorb May 23 '15 at 19:56

9 Answers9

59

Try to set the element's value using the executeScript method of JavascriptExecutor:

WebDriver driver = new FirefoxDriver();
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("document.getElementById('elementID').setAttribute('value', 'new value for element')");
Ripon Al Wasim
  • 34,088
  • 37
  • 146
  • 165
Andrey Egorov
  • 1,213
  • 1
  • 12
  • 9
  • I get the same error as when I try to do `.value = longstring` Error: `ElementNotVisibleError: element not visible` – F. Rakes Aug 30 '14 at 15:39
  • Could you please add sample of your html? Because for google this code work excellent. Possibly problem with your element on page (it's hidden i think) – Andrey Egorov Aug 30 '14 at 16:03
  • I'm actually using this example to test it with google. Could you put your code that worked for you here, please? – F. Rakes Aug 30 '14 at 16:22
  • here you are. `driver.executeScript("document.getElementById('gbqfq').setAttribute('value','Selenium Web Driver')");` – Andrey Egorov Aug 31 '14 at 02:12
  • Indeed it works, I tried `getElementById` and used `q` which was the name of the inputfield instead of the real id. Thanks. – F. Rakes Aug 31 '14 at 02:36
  • 5
    In Python Selenium it's execute_script – Chris Hawkes Jul 10 '15 at 12:38
  • this is so beautiful, works on stubborn modern JS forms, and makes me love you like tapirs love twigs python `driver.execute_script("document.getElementById('an_id').setAttribute('value', 'my_username_or_w/e')")` – codyc4321 Feb 27 '16 at 02:10
  • Seems to work but doesn't for file input fields. Even though calling getAttribute("value") on the element returns the string I used in setAttribute("xxx"), the file input field still thinks that no file has been selected. Either that or the change event hasn't been fired... – ndtreviv Jun 02 '16 at 10:31
  • Can I see the solution in Ruby please? – Amanda Cavallaro Oct 20 '16 at 20:13
  • It is worth to remaind that JS code could be checked in browser console before executing from webdriver. – SkorpEN Aug 28 '18 at 14:08
  • For me when used new lines `(\n)` this worked **webdriver.executeScript(`document.getElementsByClassName('CLASS').innerHTML=\`${text}\``;** – Gal Bracha Feb 24 '20 at 11:55
12

Thanks to Andrey Egorov, in my case with python setAttribute not working, but I found I can set the property directly,

Try this code:

driver.execute_script("document.getElementById('q').value='value here'")
iamsankalp89
  • 4,242
  • 2
  • 12
  • 35
Larry Song
  • 854
  • 8
  • 11
10

Extending from the correct answer of Andrey-Egorov using .executeScript() to conclude my own question example:

inputField = driver.findElement(webdriver.By.id('gbqfq'));
driver.executeScript("arguments[0].setAttribute('value', '" + longstring +"')", inputField);
F. Rakes
  • 1,277
  • 2
  • 16
  • 25
  • 11
    Yeah, this also will work. But also can be modified, to be more simplier: `driver.executeScript("arguments[0].setAttribute('value', arguments[1])", inputField, longstring);` – Andrey Egorov Aug 31 '14 at 04:00
  • 2
    `driver.executeScript("arguments[0].value = '" + longstring + "'", inputField)` is another possible improvement that also works with textAreas (I've only tested in Chrome, though) – Johannes Brodwall Aug 25 '15 at 20:11
  • A slight modification to the above 2 ideas because at least in my context I was trying to set a textarea and it complained about the syntax. This is in protractor: browser.executeScript("arguments[0].value=arguments[1].toString()", inputField, longstring); I also found that to make the field update, it helped to then inputField.sendKeys(" "), where in my context the extra space was harmless. – Jeremy Kahan Mar 08 '18 at 06:20
3

An alternative way of sending a large number of repeating characters to a text field (for instance to test the maximum number of characters the field will allow) is to type a few characters and then repeatedly copy and paste them:

inputField.sendKeys('0123456789');
for(int i = 0; i < 100; i++) {
    inputField.sendKeys(Key.chord(Key.CONTROL, 'a'));
    inputField.sendKeys(Key.chord(Key.CONTROL, 'c'));
    for(int i = 0; i < 10; i++) {
        inputField.sendKeys(Key.chord(Key.CONTROL, 'v'));
    }
}

Unfortunately pressing CTRL doesn't seem to work for IE unless REQUIRE_WINDOW_FOCUS is enabled (which can cause other issues), but it works fine for Firefox and Chrome.

Dave
  • 739
  • 9
  • 19
2

Thanks to Andrey-Egorov and this answer, I've managed to do it in C#

IWebDriver driver = new ChromeDriver();
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
string value = (string)js.ExecuteScript("document.getElementById('elementID').setAttribute('value', 'new value for element')");
Leojet
  • 61
  • 1
  • 8
  • What's new in your answer in comparison with previous answers? – Stepan Novikov Oct 19 '17 at 21:05
  • 1
    @Stepan - not much, but none of the answers were in C# which is what I was looking for but couldn't find it anywhere. So here it is. It could help someone like me in the future. – Leojet Oct 23 '17 at 15:56
2

In a nutshell, this is the code which works for me :)

WebDriver driver;
WebElement element;
String value;

JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("arguments[0].value='"+ value +"';", element);
harmider
  • 304
  • 4
  • 14
1

If you want to use some variable, you may use this way:

String value= "your value";
driver.execute_script("document.getElementById('q').value=' "+value+" ' ");
Das_Geek
  • 2,284
  • 7
  • 16
  • 24
0
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("document.querySelector('attributeValue').value='new value'");
Zoe
  • 23,712
  • 16
  • 99
  • 132
Rakesh
  • 1
  • 3
    Hello! While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value. – Valentino Apr 26 '19 at 16:42
0

Thanks guys, here's how I've managed to do this in Java

public static void sendKeysJavascript(By element, String keysToSend) {
    WebElement el = driver.findElement(element);
    JavascriptExecutor ex = (JavascriptExecutor) driver;
    ex.executeScript("arguments[0].value='"+ keysToSend +"';", el);
}
Gustavo
  • 1
  • 1