Last Updated: February 25, 2016
·
2.638K
· alexindigo

typeKey() for modern browsers (w/ jQuery)

With new versions of Firefox Selenium's typeKey method stopped working,
and most people had downgrade back to Firefox 7.

Especially in our case where we need to test weird autocomplete plugin with lazy loaded components.

So I decided to create temporally workaround until we get new version of Selenium.

Since we're using jQuery everywhere, it was pretty easy just solution – just to call all keyboard related triggers in a loop.

Here is function:

function typeKey(glob, field, sequence, callback)
{
 var nextChar = 0;

 // make glob optional
 if (!callback && (typeof glob == 'string' || glob.jquery))
 {
 callback = sequence;
 sequence = field;
 field = glob;
 glob = window;
 }

 if (!callback) callback = function(){};

 // --- start with actual stuff

 // jquerytize field
 if (typeof field == 'string') field = glob.jQuery(field);

 // make it an array
 sequence = sequence.split('');

 // trigger the whole thing
 setTimeout(function()
 {
 // focus
 field.focus();
 // and start looping
 looping();
 }, 0);

 // --- subroutines

 // do looping
 function looping()
 {
 // check if we done
 if (!sequence[nextChar]) return callback(null);

 // type and continue looping
 type(field, sequence[nextChar], looping);
 // increment pointer
 nextChar++;
 }

 // do typing
 function type($field, char, cb)
 {
 var nextEvent = 0
 , fireSquad =
 [
 // 1. keydown
 function() { $field.trigger(keyEvent('keydown', char)); },
 // 2. enter char
 function() { $field.val($field.val() + char); },
 // 3. keyup
 function() { $field.trigger(keyEvent('keyup', char)); },
 // 4. keypress
 function() { $field.trigger(keyEvent('keypress', char)); },
 // 5. done – callback
 function() { if (typeof callback == 'function') cb(); }
 ]
 ;

 // start firing events in 300ms
 setTimeout(fire, 300);

 // -- sub-subroutines
 function fire()
 {
 fireSquad[nextEvent]();
 nextEvent++;
 // look for next and fire on next tick
 if (fireSquad[nextEvent]) setTimeout(fire, 0);
 }
 }

 // create keyEvent
 function keyEvent(event, key)
 {
 var code = key.charCodeAt(0);
 return glob.jQuery.Event(event, {which: code, keyCode: code});
 }
};

And that's how you use it:

typeKey('#search_location', 'Palo Alto, CA');

There are two optional params:

– callback, which get called after last character is typed.

– glob, window object, used when called from Selenium.

typeKey([window], field_obj_or_selector, sequence, [callback]);

1 Response
Add your response

Cheers! :)

over 1 year ago ·