3

I need to instantly fill a textarea with a very long string for testing purposes.

set/send_keys simulates typing and is too slow for Sauce Labs causing time outs.

Is there a way to instantly fill a textarea in Capybara?

danksim
  • 555
  • 3
  • 7
  • 24

2 Answers2

4

The only way to instantly do it would be using execute_script to set the value via JS

element = find('textarea') # however you locate the element
execute_script('arguments[0].value = arguments[1]', element, text_to_set)

Note: this won't trigger all the events a user would generate when inputting into the textarea

Thomas Walpole
  • 42,399
  • 5
  • 53
  • 67
3

TL;DR: Use Javascript/JQuery (.val() function) to set the field's value via the .execute_script()/.evaluate_script() function. It will automatically send the full string. You have more details bellow.

Example:

def execute_script(script)
  browser.execute(function() { 
    $('<yourSelectorHere>').val("blablabla"); 
  })
  nil
end

Selenium team decided a LOOOONG way back to make it work this way, because it will actually simulate the real way a user would fill that input/textarea/field/etc.

Note: I wrote the command in WebdriverIO, but now have updated to Capybara as well.


Indeed, using the .setValue()/.set(), or the .keys()/.send_keys() methods will issue a POST action on the target element (presumably an <input>) in the form of an array of characters. See example:

Command: browser.setValue('input[connectqa-input="rename-device"]','stackoverflowstackoverflowstack');

Output:

> browser.setValue('input[connectqa-input="rename-device"]','stackoverflowstackoverflowstack')
{ state: 'pending' }
> [21:52:25]  COMMAND   POST     "/wd/hub/session/3d830ffd-21c6-4e5f-a6b3-4f8a03821991/elements"
[21:52:25]  DATA                {"using":"css selector","value":"input[connectqa-input=\"rename-device\"]"}
[21:52:25]  RESULT              [{"ELEMENT":"6"}]
[21:52:25]  COMMAND     POST     "/wd/hub/session/3d830ffd-21c6-4e5f-a6b3-4f8a03821991/element/6/clear"
[21:52:25]  DATA                {}
[21:52:25]  COMMAND     POST     "/wd/hub/session/3d830ffd-21c6-4e5f-a6b3-4f8a03821991/element/6/value"
[21:52:25]  DATA                {"value":["s","t","a","c","k","o","v","e","r","f","(21 more items)"],"text":"stackoverflowstackoverflowstack"}

One quick and easy way to escape this is to go ahead and abuse the .val() JQuery function via the .execute()/.executeScript() methods:

Command: browser.execute(function() { $('input[connectqa-input="rename-device"]').val("dwadawdawdawdawdawdwadawawdadawdawdaw"); }) (WebdriverIO)

For Capybara syntax, see this question. It covers both .execute_script() & .evaluate_script(). (I don't want to mooch-off their views). Also you should document on the methods before-hand here.

Output:

> [21:59:38]  COMMAND   POST     "/wd/hub/session/3d830ffd-21c6-4e5f-a6b3-4f8a03821991/execute"
[21:59:38]  DATA                {"script":"return (function () { $('input[connectqa-input=\"rename-device\"]').val(\"dwadawdawdawdawdawdwadawawdadawdawdaw\"); }).apply(null, arguments)","args":[]}

Hope it helped!

iamdanchiv
  • 3,828
  • 4
  • 32
  • 40
  • 1
    @dinky from `conEmu`, or `GitBash` console. I was similating via `WebdriverIO`. I've setup a test-case with some inputs and stopped in debug more (`.debug()`). Due to the fact all drivers (`chromedriver`, `geckodriver`, etc) are implementing the [Selenium W3C](https://www.w3.org/TR/webdriver/) standard, it should work the same on every framework that integrates with said drivers. – iamdanchiv May 25 '17 at 20:09
  • I got this: `> browser VM3737:1 Uncaught ReferenceError: browser is not defined at :1:1` from the chrome console – danksim May 25 '17 at 20:10
  • 1
    @dinky then update your question with your driver instantiation/declaration. Some snippet of code would help us pin-point the issue. – iamdanchiv May 25 '17 at 20:11