1

I have a test web page that alerts if i hit a key in it's input field:

<!doctype html>
<html>
<head>
  <script type="text/javascript" src="jquery-1.9.1.min.js"></script>
  <script>
    $( document ).ready( function() {
      $( '#foo' ).keydown( function() { alert( "debug" ); } );
    });
  </script>
</head>
<body>
  <input id='foo' type='type'/>
</body>
</html>

And i have this chrome extension that modifies input text and fires keydown event:

$( document ).ready( function() {
  window.setTimeout( function() {
    $( '#foo' ).val( "foo" );
    $( '#foo' ).keydown();
  }, 2000 );
});

If i install extension, after 2 seconds (as expected) text is modified - but alert is not displayed, so i can suggest that keydown event is not passed from extension sandbox into page javascript handler. Is it possible to modify my code somehow so extension can emulate keydown that javascript on the page can see? I'm automating a third-party website via chrome extension, and one of the inputs requires keyup to detect value change (the page i'm automating is written badly - but i don't have any control other it's source code).

grigoryvp
  • 40,413
  • 64
  • 174
  • 277

1 Answers1

11

Your code is not working because jQuery's keydown() method does not actually trigger a "real" keydown event. Instead, jQuery looks up the "bound" event handlers in jQuery.cache, and calls the corresponding functions.

Since your content script's jQuery object differs from the page's jQuery object, invoking .keydown() doesn't cause any action.

In your case, I suggest to inject your code in the page, so that your code runs in the same context as the page. Then, calling $('#foo').keydown() will use the page's jQuery object, and result in the expected behaviour.

A general solution, which doesn't depend on any library is to use the KeyboardEvent constructor (defined in DOM4) to trigger the event:

var event = new KeyboardEvent('keydown');
document.querySelector('#foo').dispatchEvent(event);
Community
  • 1
  • 1
Rob W
  • 341,306
  • 83
  • 791
  • 678
  • Thanks a lot. I have little experience with web technology and this aspect of `jQuery` mechanics was unknown to me. – grigoryvp Jun 18 '13 at 16:37
  • I think I'm facing the same limitation (different contexts of jQuery) in a Jasmine Unit Test using jQuery and Karma. Triggering a `KeyboardEvent` solves the problem, but I don't have an idea about how to make jQuery from the unit test running in the same context as the browser... – mediafreakch Nov 19 '15 at 14:45
  • @mediafreakch See the "inject your code" link in my answer. – Rob W Nov 19 '15 at 16:16
  • @RobW Thanks, but finally found out that my problem was related to the fact that I included jQuery twice (karma.conf.js + require() in the unit test itself) – mediafreakch Nov 20 '15 at 08:46