2

Recently I've started using Robot with Selenium2Library to automate some GUI test cases. One of the application I'm automating is ReviewBoard.

So far I've been able to automate some stuff but having a lot of problem with inputting text into text area. An example would be the description field on reviewboard.

My latest attempt is

:FOR  ${URL}  in  @{URL_LIST}
\  Go To  ${URL}
# Enter team reviewer name and press ok
\  Click Element  xpath=//*[@id="fieldset_reviewers_body"]/tr[2]/td/a/div[@class="rb-icon rb-icon-edit"]
\  Input Text  xpath=//*[@id="fieldset_reviewers_body"]/tr[2]/td/form/input  rbtest_teamreviewer1
\  Press Key  xpath=//*[@id="fieldset_reviewers_body"]/tr[2]/td/form/input  \\9
\  Click Element  xpath=//*[@id="fieldset_reviewers_body"]/tr[2]/td/form/span/input[@class="save"]
# Fill out Testing Done field
\  Click Element  xpath=//*[@id="review_request_main"]/div[2]/label/a/div[@class="rb-icon rb-icon-edit"]
\  Press Key  xpath=//*[@id='review_request_main']/div[2]/div/form/*//textarea  Testing Done
\  Click Element  xpath=//*[@id="review_request_main"]/div[2]/div/form/div[2]/input[@class="save"]

However, I'm receving the exception

ElementNotVisibleException: Message: Element is not currently visible and so may not be interacted with
Stacktrace:
at fxdriver.preconditions.visible (file:///tmp/tmpW24ACY/webdriver-py-profilecopy/extensions/fxdriver@googlecode.com/components/command-processor.js:10092)
at DelayedCommand.prototype.checkPreconditions_ (file:///tmp/tmpW24ACY/webdriver-py-profilecopy/extensions/fxdriver@googlecode.com/components/command-processor.js:12644)
at DelayedCommand.prototype.executeInternal_/h (file:///tmp/tmpW24ACY/webdriver-py-profilecopy/extensions/fxdriver@googlecode.com/components/command-processor.js:12661)
at DelayedCommand.prototype.executeInternal_ (file:///tmp/tmpW24ACY/webdriver-py-profilecopy/extensions/fxdriver@googlecode.com/components/command-processor.js:12666)
at DelayedCommand.prototype.execute/< (file:///tmp/tmpW24ACY/webdriver-py-profilecopy/extensions/fxdriver@googlecode.com/components/command-processor.js:12608)

I've try different ways such as using Input Text instead of Press Key but having similar problem...I don't have any problem when type is input.

Does anyone have any idea how I might be able to solve this?

If you are interested, you can view the demo reviewboard at http://demo.reviewboard.org/r/1502/ with username:guest6317 password:demo

Kevin Yu
  • 85
  • 1
  • 11
  • hi @Kevin Yu - Could you please provide full code you have written here please? – Curious Apr 23 '16 at 22:08
  • Once you click the `rb-icon-edit` the page generates a new CodeMirror editor instance. The correct way to change its value is described here: http://stackoverflow.com/questions/8378678/. But you need to know the name of CodeMirror object. I suggest you ask this from the developers. When you know the object name, run javascript with RobotFramework's `Execute Javascript` instead of `Press Key` – jim Apr 23 '16 at 22:57
  • @Curious I've updated it with full code. Thanks. – Kevin Yu Apr 25 '16 at 16:58
  • Still, these codes are in complete. And you wrote this code using which language? Copy and paste your code in the above question. You can update sensitive data with test data in the code but provide clear code what you have written. – Curious Apr 25 '16 at 18:49

1 Answers1

5

CodeMirror replaces the textarea with its own object. This object has methods for interacting with the widget. However, in the case of reviewboard this object isn't initialized until you click on the textarea. So, the solution is going to look like this:

  1. find and click on the textarea
  2. find the reference to the CodeMirror editor object
  3. use CodeMirror methods to interact with the editor widget

Step 1: clicking on the text area

The first step is to click on the textarea in order to initialize the widget. This can be done easily with the "Click Element" keyword:

click element    id=field_description    

Step 2: get a reference to the editor object

The reviewboard developers probably have a reference to the object, so you could ask them for the name of the variable. However, we can create our own variable for testing purposes. CodeMirror adds a CodeMirror attribute on the div that contains the editor so can use this information to save a reference to a temporary javascript variable:

Execute javascript    
...    _editor = document.querySelectorAll("div.CodeMirror")[0].CodeMirror;

Step 3: interacting with the editor

The CodeMirror editor has many methods for interacting with the contents of the editor. For example, if you want to replace the contents with your own string, you can call the setValue method.

For example, to replace all of the data with "Hello world!" you could do this:

execute javascript    _editor.setValue("Hello world!");

Step 4: putting it all together

Here is a complete test script that replaces the contents of the editor with "Hello world", and then pauses so you can verify that it worked. I tested this on a linux system with chrome and firefox.

*** Variables ***
${ROOT}       http://demo.reviewboard.org
${BROWSER}    chrome
${USERNAME}   guest6317
${PASSWORD}   demo

*** Settings ***
Library         Selenium2Library
Library         Dialogs

Suite Setup     open browser  ${ROOT}    ${BROWSER}
Suite Teardown  close all browsers

*** Test Cases ***
Example
    [Setup]    run keywords   
    ...     Log in
    ...     AND  go to    ${ROOT}/r/1502/    

    click element    id=field_description    
    Execute javascript    
    ...    _editor = document.querySelectorAll("div.CodeMirror")[0].CodeMirror;
    ...    _editor.setValue("Hello world!");

    pause execution    

*** Keywords ***
Log in
    go to    ${ROOT}/account/login
    input text    id=id_username    ${USERNAME}
    input text    id=id_password    ${PASSWORD}    
    submit form
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Marked this as the accepted answer since it's comprehensive and accurate. Eventually what I did before seeing your answer was: Execute Javascript document.getElementsByClassName("CodeMirror")[0].CodeMirror.setValue("hello world"); – Kevin Yu Apr 25 '16 at 21:22
  • I tried everything I could with input text feature but it didn't work no matter where I targeted. Javascript solution works just fine. Thanks! – Shnigi Jun 09 '21 at 12:29