John Lehmann
John Lehmann

Reputation: 8225

How to trigger <enter> in an input in Angular scenario test?

I'm writing tests with Angular Scenario test runner. Within a traditional form, I can enter text into an input, but I need to press enter to execute the query and there is no button to click on. Surely there is some easy way to do this, but I do not know what it is.

input('query').enter('foo bar');
// ... now what?

I tried to simulate a keypress with JQuery, but as this answer indicates JQuery is not loaded in the e2e scenarios scope. So I followed his advice (as well as that of this answer) to simulate the keypress:

element('#search_input').query(function(el, done){
    var press = document.createEvent('keypress');
    press.which = 13;
    press.trigger(evt);
    done();
});

But to this Angular replies:

NotSupportedError: DOM Exception 9
Error: The implementation did not support the requested type of object or operation.

Update

I realized that a very easy workaround is to include a hidden submit input in my form:

<input id="search-submit" type="submit" style="display:none;">

Then in the scenario: element('#search-submit').click(); does what is needed.

For a purer solution which doesn't involve modifying the HTML for the sake of testing, @florian-f's answer (as well as this one) provides access to jQuery within the DSL via:

var $ = $window.$;

which can be used there or passed to the callback. However, even with this access when triggering a press of enter I was not able to submit my form in the following manner:

$(selector).trigger($.Event('keypress', { which: 13 }));

This must be another issue all together. But I did find jQuery's submit function to do the trick:

$(#the_form).submit();

Upvotes: 4

Views: 6075

Answers (2)

leemon20
leemon20

Reputation: 1

There is also another possibility to trigger a key event. While your first approach

element('#search_input').query(function(el, done){
    var press = document.createEvent('keypress');
    press.which = 13;
    press.trigger(evt);
    done();
});

will be blocked by angular, this one

element(<selector>).query(function($el, done) {
    var event = new CustomEvent('keyup');

    event.keyCode = 13;
    $el.val(2);
    $el.get(0).dispatchEvent(event);

    done();
});

will pass and trigger a keyup event on the element specified by the selector (keyCode = 13 = Enter Key). See https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent for further information.

Upvotes: 0

Florian F
Florian F

Reputation: 8875

You can access to the app (runner in an iframe) instance of jQuery :

angular.scenario.dsl('appElement', function() {
  return function(selector, fn) {
    return this.addFutureAction('element ' + selector, function($window, $document, done) {
      fn.call(this, $window.angular.element(selector));
      done();
    });
  };
});

Then you can call the trigger method of jQuery in your test :

appElement('yourSelector', function(elm) {
  elm.trigger('enter');//or keypress
});

Upvotes: 3

Related Questions