How can I programmatically generate keypress events from Javascript code running in Safari? It looks like WebKit is using the DOM level 3 model for creating keyboard events
Use the TextEvent (introduced by DOM3). Since you're looking to generate keypress events, I'm guessing you're working with characters. In the code below, textToInsert is a string, and textarea the element I'm dispatching the event to.
var eventObject = document.createEvent('TextEvent');
eventObject.initTextEvent('textInput',
true,
true,
null,
textToInsert);
textarea.dispatchEvent(eventObject);
This works on Safari 3.1.2 (consequently on Chrome).
Sounds like a very similar (non browser specific) question was asked and answered already:
Trigger a keypress with jQuery...and specify which key was pressed
http://docs.jquery.com/Events/keypress#fn
In other words, you attach a keypress event to some element. Using an element with the ID of "someid", for example:
<script language="text/javascript" src="jquery.js"></script>
<script language="text/javascript">
$(function() {
// add a keypress handler
$("#someid").keypress(function(e){
alert('you just pressed ' + e.which);
});
// imitate the keypress
$("#someid").keypress();
});
</script>
I have had the same problem. I wanted to be able to write a test that when the enter key is pressed on the GUI a line item (li) is added to a list. For then, I needed to "generate" a keypress. Having tried to generate the event, simulate an event, mock out the event (jqMock), here's a very simple solution.
I can continue on with BDDing my code using jsSpec and jQuery code. This test would be a little harder if you used a plugin to manage the keypresses (eg hotkeys jQuery plugin)
Here's what I want to do:
describe 'I need to be able to edit items in a list', {
... [setup code and other tests]
'should create a new item if I press enter': function(){
value_of($('#todo').items().size()).should_be(7)
// be on the last item in the list
task = $('#todo').items().filter(':last').focus()
// press enter
task.__keypress(13)
// check that an item was added
value_of($('#todo').tasks().size()).should_be(8)
},
}
Here's the code that binds the handler. Note with this solution I intercept the event and only pass through the which code - this allows me to pass in the value from the test. That is all I need at the moment. Obviously, if I wanted to intercept more I would need to expand what is passed in (for example, see jquery.hotkeys plugin):
$().items().bind('keypress', function(event){$().__keypress(event.which)})
And here's the handler:
__keypress: function(which){
switch(which)
{
...
case 13: // enter
[my code that creates a new item]
break;
default:
}
},
ps: if anyone is able to mock window.event let me know. I didn't have any luck using jqMock.