Question

I'm working on an app that combines Ember with jquery-terminal to help users learn. I apologise for the long question up front!

I love to work in a TDD style, but am struggling to get this working.

What I want to do is simulate user input into jquery-terminal and assert that the correct response is displayed in the terminal. I've dug through the source code and perhaps I'm missing something, but I can't seem to find a place to add the user input. The terminal ends up outputting this:-

<div id="terminal" class="terminal">
  <div class="terminal-output"></div>
  <div class="cmd" style="width: 100%;">
    <span class="prompt">TryRuby:&gt;&nbsp;</span>
    <span></span>
    <span class="cursor blink">&nbsp;</span>
    <span></span>
    <textarea class="clipboard"></textarea>
  </div>
</div>

The text entered by the user is rendered in the first unnamed span, but inserting text here does not make it available to jquery-terminal on submit I get the same response as if it were blank.

What I want to simulate is this (pseudocode)

test('user enters help and submits', function() {
  var input = $('#terminal') // find the right node / place to bind is my problem
  input.text = 'help'
  keyEvent(input, 'keydown', 13) // simulate hitting enter
  var match = /next: move to the next lesson/
  ok(match.test($('.terminal-output'), 'Expected to find "next: move to the next lesson"')
})

Now it all works perfectly if I visit the page and manually type in, but I want this done programatically.

Any suggestions would be welcome!

Was it helpful?

Solution

Here is the code that will enter text and press enter:

terminal.insert("Hello");
var e = $.Event("keydown");
e.ctrlKey = false;
e.which = e.keyCode = 13;
$(document.documentElement || window).trigger(e);

instead of terminal::insert you can also simulate entering text using jQuery events:

function enter(text) {
    var e;
    var $root = $(document.documentElement || window);
    for (var i=0; i<text.length; ++i) {
        e = $.Event("keypress");
        e.which = text.charCodeAt(i);
        $root.trigger(e);
    }
}

NOTE: The code that bind keypress and keydown is in cmd plugin at the end:

$(document.documentElement || window).bind('keypress.cmd', function(e) {

    ...

}).bind('keydown.cmd', keydown_event);

keydown_event is main function that process all short cuts and keypress is to enter text.

If you want to test what's inside terminal last echo text will be in:

 terminal.find('.terminal-output div:last').html()

and the line before that will be prompt + text you enter (I should add specific class for those lines).

Also if you want to handle terminal formatting you will need to look at the rules of formatting in $.terminal.format function, it create span for each formatting with inline style, class and attributes. Testing for html instead of text will give you better results I think. The line with prompt will not have formatting as spans they appear as text.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top