Search code examples
seleniumrobotframeworkcodemirrorreview-board

Robot Selenium - Enter text into CodeMirror text area


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/[email protected]/components/command-processor.js:10092)
at DelayedCommand.prototype.checkPreconditions_ (file:///tmp/tmpW24ACY/webdriver-py-profilecopy/extensions/[email protected]/components/command-processor.js:12644)
at DelayedCommand.prototype.executeInternal_/h (file:///tmp/tmpW24ACY/webdriver-py-profilecopy/extensions/[email protected]/components/command-processor.js:12661)
at DelayedCommand.prototype.executeInternal_ (file:///tmp/tmpW24ACY/webdriver-py-profilecopy/extensions/[email protected]/components/command-processor.js:12666)
at DelayedCommand.prototype.execute/< (file:///tmp/tmpW24ACY/webdriver-py-profilecopy/extensions/[email protected]/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


Solution

  • 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