Com as novas versões do método typeKey do Firefox, o Selenium parou de funcionar
e a maioria das pessoas fez o downgrade para o Firefox 7.
Especialmente em nosso caso, onde precisamos testar o plugin de autocompletar estranho com componentes carregados lentamente.
Portanto, decidi criar uma alternativa temporária até obtermos uma nova versão do Selenium.
Como estamos usando o jQuery em todos os lugares, foi muito fácil apenas uma solução – apenas chamar todos os gatilhos relacionados ao teclado em um loop.
Aqui está a função:
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});
}
};
E é assim que você o usa:
typeKey('#search_location', 'Palo Alto, CA');
Existem dois parâmetros opcionais:
– callback, que é chamado após o último caractere ser digitado.
– glob, objeto de janela, usado quando chamado do Selenium.
typeKey([window], field_obj_or_selector, sequence, [callback]);