Заполнение форм при помощи букмарклета
Как и многие веб-разработчики, я посвящаю много времени тестированию пользовательского интерфейса сайтов, над которыми работаю.
Автоматизированное тестирование, конечно, является хорошей помощью в этом процессе, но «болевые точки» в интерфейсе зачастую невозможно выявить иным способом, кроме как использовать сайт. Ещё и ещё раз. Этот процесс может очень быстро надоедать. Особенно заполнение форм.
Я сам попал в такую ситуацию пару месяцев назад, когда мы добавляли британский фунт к поддерживаемым валютам при расчёте в Wufoo.
Для проверки необходимо было заполнить множество полей с именами, адресами, номерами кредиток и всего прочего, что подразумевается в процессе расчёта. Разумеется, значительная часть этих данных не должна была повторяться:

В конце концов, я сделал букмарклет для быстрого заполнения форм тестовыми данными. (Bookmarklet – программа на JavaScript, выполненная в виде закладки в браузере, гибрид английских слов «bookmark» – закладка и «applet» – маленькое приложение. – Прим. перев.)
Я выбрал форму букмарклета, потому что:
- его легко передать пользователю;
- его легко обновить без участия пользователя;
- он запускается на любой платформе без изменений.
Вы можете легко сделать букмарклет, создав новый «загончик» на CodePen и поместив в HTML что-то вроде:
<a href="javascript: **Здесь должен быть ваш JS-код** "></a>
Пользователю достаточно перетащить получившуюся ссылку в область закладок своего браузера. Клик по закладке запустит код на текущей странице.
В этом проекте я полагался на jQuery для придания коду максимальной удобочитаемости и кроссбраузерности. Если кому-то нужна версия на чистом JavaScript, напишите мне комментарий – я постараюсь что-нибудь сообразить.
Для создания случайных данных я использовал замечательную библиотеку Faker. Её JavaScript-реализацию можно взять здесь.
Основа букмарклета
Мы можем поместить весь код прямо в ссылку. Но такой вариант будет неудобно читать и сопровождать. Кроме того, мне хотелось иметь возможность вносить исправления в код, не заставляя пользователей обновлять закладку. Так что лучше оставить в букмарклете ссылку на внешний файл.
Сам букмарклет выглядит так:
<a href="javascript:
(function(d) {
var body = d.getElementsByTagName('body')[0],
script = d.createElement('script');
script.src = '//localhost.com/pathtomyfile.js';
body.appendChild(script);
}(window.document));
">Мой букмарклет</a>
В нём мы подгружаем скрипт в тело страницы и добавляем туда же ссылку на внешний файл JavaScript. Необходимо заметить, что, если букмарклет применяется к тестированию страницы, загружаемой по https, то и внешний JS-файл должен отдаваться по https, иначе браузер выдаст ошибку безопасности.
Вполне возможно, что при разработке букмарклета вы захотите воспользоваться локальным сервером. В таком случае не забудьте заменить адрес в ссылке на адрес реального сервера, когда будете распространять ваш скрипт.
Заполнение полей
Теперь, когда мы закончили с закладкой, загружающей наш скрипт, можно взяться и за сам скрипт.
Сверхважной задачей для нас будет не сломать ничего в странице, над тестированием которой будет работать наш скрипт.
Поэтому мы обернём его в самозапускающуюся анонимную функцию. Это соответствующим образом ограничит область видимости наших функций и переменных:
(function(win, doc, $, undefined) {
'use strict'; // Don't run if jQuery isn't loaded
if (typeof window.jQuery === 'undefined') {
return;
}
// Our code will go here.
}(window, window.document, window.jQuery));
Мне очень нравится функция генератора псевдослучайных чисел, приведённая Крисом Койлером в этой статье. Воспользуемся ей по мере необходимости:
var _rand = function(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
Теперь загрузим FakerJS. Поскольку наш скрипт зависит от jQuery, мы можем использовать его механизм отложенной загрузки при помощи функции $.getScript:
$.getScript('//cdnjs.cloudflare.com/ajax/libs/Faker/0.7.2/MinFaker.js')
.done(function() {
// run our functions from here
})
.fail(function() {
win.console.error('ERROR: FakerJS not loaded!');
});
Теперь, когда доступ к Faker нам обещан, мы можем использовать его методы для генерации разнообразных правдоподобных имён, мест, адресов и других тестовых данных.
Повторное использование сгенерированных данных обеспечит нам следующий конструктор:
var FormData = function(faker) {
this.faker = faker;
this.randomWord = faker.Internet.domainWord();
this.username = 'fake_' + this.randomWord;
this.username += _rand(100,9999);
// set this value to your password specifications
this.password = 'pass1234';
this.name = faker.Name.findName();
this.address1 = faker.Address.streetAddress();
this.city = faker.Address.city();
this.state = faker.random.br_state_abbr();
this.zip = faker.Address.zipCode();
// Chris' actual credit card number
this.cc = '4242 4242 4242 4242';
this.exp1 = _rand(1,12);
this.exp2 = _rand(14,22);
this.cvv = _rand(100,999);
};
Неплохо было бы протестировать также чекбоксы и радиокнопки на нашем сайте, выбирая их в случайном порядке. Для этого нам придётся несколько расширить функциональность нашего конструктора:
// Randomly select dropdown
FormData.prototype.randomizeSelect = function(el) {
var $el = $(el),
len = $el.find('option').length - 1;
$el.children('option')
.prop('selected', false)
.eq( _rand( 1,len + 1 ) )
.prop('selected', true);
};
// Randomly select radio button
FormData.prototype.randomizeRadio = function(radios) {
radios.not('[type="hidden"]');
var len = radios.length;
radios
.prop('checked', false)
.eq( _rand( 0, len - 1 ) )
.prop('checked', true);
};
// Add some lorem text for textareas
FormData.prototype.randomizeParagraph = function(el) {
$(el).val(this.faker.Lorem.sentence(5));
};
// Randomize all checkbox fields
FormData.prototype.randomizeCheckbox = function(el) {
var $el = $(el);
$el.prop('checked', false);
if (_rand( 0,1 ) === 0) {
$el.prop('checked', true);
}
};
FormData.prototype.randomizeEmail = function(el) {
// if we want different emails for all email fields, we can modify this
$(el).val('chriscoyier+' + this.randomWord + '@gmail.com');
};
И наконец, нам нужно сопоставить генерируемые данные с различными полями тестируемых форм. Мы извлечём из нашей страницы все поля форм и заполним их данными в соответствии с их типом и CSS-классом.
В таком виде наш скрипт прекрасно реализует разделение между механизмом генерации данных и механизмом их использования:
var fillForm = function() {
data = new FormData(window.Faker);
$('#name').val(data.name);
$('#username').val(data.username);
$('#cc').val(data.cc);
$('#exp-1').val(data.exp1);
$('#exp-2').val(data.exp2);
$('#cvv').val(data.cvv);
$('#address').val(data.address1);
$('#city').val(data.city);
$('#state').val(data.state);
$('#zip').val(data.zip);
$('#pw').val(data.password);
$('#pw-repeat').val(data.password);
data.randomizeRadio($('[name="radio-choice"]'));
// Randomize all select boxes
$('select').each(function() {
data.randomizeSelect(this);
});
// Randomize all checkboxes
$('input[type="checkbox"').each(function() {
data.randomizeCheckbox(this);
});
// Randomize all textareas
$('textarea').each(function() {
data.randomizeParagraph(this);
});
// Randomize all emails
$('input[type="email"').each(function() {
data.randomizeEmail(this);
});
};
Вы можете отправить форму автоматически, вызвав JavaScript-функцию submit(), либо сделать это вручную. Это лишь вопрос ваших предпочтений:
$('#form').submit();
Заключение
Таким образом, мной был написан простой и быстрый заполнитель форм в виде букмарклета для тестирования одного проекта. Определённо, существует множество способов его улучшить. Однако в условиях нехватки времени этот инструмент был использован как есть, и вполне справился со своей работой.
Если хотите, можете рассмотреть также Inline Copy Editor – ещё один мой букмарклет, код которого я открыл для команды дизайнеров SurveyMonkey.
Надеюсь, моя статья была вам полезна. Дайте знать, если появятся вопросы.