Form auto-fill bookmarklet
Intro
So here's the thing, we all know we hate forms, the only thing we hate more than forms themselves is actually filling out forms. But the forms are the interface to our web apps, so we cannot do without them. What we would love to do without, but can't, is skip the application testing part where you fill out forms like there's no tomorrow, just to make sure your app is rock solid.
And filling out forms is a pain. So for some time I wanted to get my hands on a little something that can fill out a form, any form, with a click of a button. JavaScript is ideal for such a task and the best sort of a "little something" is probably a bookmarklet. That is how this bookmark was born.
What is it, what it does?
This is a bookmarklet. You go to page that has one or more forms and you click the bookmarklet. It completes the form for you with some random data. The whole thinking was to have a form ready to be submitted and generating as less validation errors as possible. Here are some details:
- All defaults are kept as they are
- All passwords fields are completed with the same password, in case there is a password/password confirmation combo. The default password is "secret"
- If a text field has the string "email" in its name, the auto-generated value would be a random string @ example.org
- If a text field has the string "name" in its name, a name-looking value will be generated.
- All checkboxes will be checked (who knows which one of them might be "Accept terms" or anything else that is required)
- Multi-selects will have a random number of random options selected
Install
Right-click and bookmark or drag to your personal bookmarks toolbar.
Demo
The code
The demo and the code below are "normal" code, with proper indentation and all. The actual bookmark though has to be on one line and as small as possible, so it's pretty much unreadable. Ah, and while the demo will work in IE, the bookmarklet won't, because it's too big for IE. IE allows up to about 500 characters in the URL (or a bookmarklet) while mine is about 2000 "compressed" or 3000 cleaner. So unless I do something heroic in compressing the script, it won't work on IE. No biggie I'd say, since you'll be testing your application and most likely you use Firefox anyway.
The big picture
Using JSON, the class/object is called auto and it has the following interface:
var auto ={ // a list of names that will be used to generate // normal looking names names: "Steve Buscemi Catherine Keener …", // this is where all the random words will come from blurb: "phpBB is a free…", // default password to be used in all password fields password: "secret", // the main function that does all fillerup: function() {}, // helper function, returns randomly selected words // coming from this.blurb getRandomString: function (how_many_words) {}, // helper function, returns randomly selected names // coming from this.names getRandomName: function () {}, // returns this.password getPassword: function () {}, // returns a random int from 0 to count getRand: function (count) {} }
The actual form fill-out is initiated by calling auto.fillerup()
As you can probably guess, the only interesting function is fillerup(), so let me show you what it does.
fillerup()
In case you're wondering, the name of the function comes from a Sting song:
Fill'er up, son, unleaded.
I need a full tank of gas where I'm headed …
The function starts by identifying all the elements candidate to be completed:
var all_inputs = document.getElementsByTagName('input'); var all_selects = document.getElementsByTagName('select'); var all_textareas = document.getElementsByTagName('textarea');
OK, we have our work cut out for us, let's start by looping through the selects:
// selects for (var i = 0, max = all_selects.length; i < max; i++) { var sel = all_selects[i]; // current element if (sel.selectedIndex != -1 && sel.options[sel.selectedIndex].value) { continue; // has a default value, skip it } var howmany = 1; // how many options we'll select if (sel.type == 'select-multiple') { // multiple selects // random number of options will be selected var howmany = 1 + this.getRand(sel.options.length - 1); } for (var j = 0; j < howmany; j++) { var index = this.getRand(sel.options.length - 1); sel.options[index].selected = 'selected'; // @todo - Check if the selected index actually // has a value otherwise try again } }
Then - textareas, they cannot be simpler. We only check if there isn't already a value and if there's none, we get two "paragraphs" of 10 words each.
// textareas for (var i = 0, max = all_textareas.length; i < max; i++) { var ta = all_textareas[i]; if (!ta.value) { ta.value = this.getRandomString(10) + '\n\n' + this.getRandomString(10); } }
Next (and last), come the inputs. They are a bit more complicated as there are too many of them. Here's the overall code with the skipped details for each input type.
// inputs for (var i = 0, max = all_inputs.length; i < max; i++) { var inp = all_inputs[i]; var type = inp.getAttribute('type'); if (!type) { type = 'text'; // default is 'text'' } if (type == 'checkbox') {…} if (type == 'radio') {…} if (type == 'password') {…} if (type == 'text') {…} }
We're absolutely unforgiving when it comes to checkboxes - just check them all, no questions asked, take no prisoners.
if (type == 'checkbox') { // check'em all // who knows which ones are required inp.setAttribute('checked', 'checked'); /* … ooor random check-off if (!inp.getAttribute('checked')) { if (Math.round(Math.random())) { // 0 or 1 inp.setAttribute('checked', 'checked'); } } */ }
Next, do the radios. They are a bit more complicated, because once we have an element, before checking it, we need to verify that there are no other radios with the same name (and in the same form) are already selected and checked.
if (type == 'radio') { var to_update = true; // we assume this radio needs to be checked // but in any event we'll check first var name = inp.name; var input_array = inp.form.elements[inp.name]; for (var j = 0; j < input_array.length; j++) { if (input_array[j].checked) { // match! already has a value to_update = false; continue; } } if (to_update) { // ok, ok, checking the radio // only … randomly var index = this.getRand(input_array.length - 1); input_array[index].setAttribute('checked', 'checked'); } }
Passwords - trivial, just make sure you always set the same password.
if (type == 'password') { if (!inp.value) { inp.value = this.getPassword(); } }
And finally - the text inputs. We try to guess the nature of the text field by its name. Here there's plenty of room for improvement and more guesses.
if (type == 'text') { if (!inp.value) { // try to be smart about some stuff // like email and name if (inp.name.indexOf('name') != -1) { // name inp.value = this.getRandomName() + ' ' + this.getRandomName(); } else if (inp.name.indexOf('email') != -1) { // email address inp.value = this.getRandomString(1) + '@example.org'; } else { inp.value = this.getRandomString(1); } } }
C'est tout
That's it, hope you liked it and start using it
Any comment or suggestions - let me know.
May 16th, 2006 at 2:17 am
Last days I'm occupied in testing an e-commerce script and have to fill in a huge form of about 30 elements. I'd steal your idea to make a javascript that fills that form with not random but my own personal data.
The idea is great. Thanx a lot
May 16th, 2006 at 3:44 am
Great tool you made here! Really appreciate it. We do a lot of online survey's here in the office and testing can really be a pain most specially with the long forms. Thanks!
May 16th, 2006 at 7:43 am
A handy extension is to not only check for fields with the name "email", but also to check for fieldnames such as "url", "website"
The last part of the js code would become:
Regards,
Bram.
May 16th, 2006 at 10:29 am
Thanks for the comments, guys!
Bram, good idea! With the risk of overdesigning the whole thing I'm thinking of adding a little engine, something like an array of criteria ("name", "email", "url", might even be a regexp) and a callback function to be executed when there is a match. This will make the code cleaner - one loop through the criteria as opposed to a lot of if-else-s.
Dead Moroz, for your purpose you can also benefit from the browser's capability to store your personal data and auto-complete, I know the Google toolbar has this feature. So when you hit the form you want to test, first you hit the toolbar's auto complete, it fills out the form with your personal data and then you click my bookmarklet, which fills out the rest of the fields (because your forms may contain all kinds of fields, not necessarily only personal). Just an idea. Balshoe spasiba for your kind words
May 28th, 2006 at 4:27 am
Great idea, indeed. Thanks for sharing!
June 30th, 2006 at 3:07 am
There is also an excelent plugin in Firefox that does this for you… Look add the webdelopers toolbar in Firefox…
August 9th, 2006 at 6:05 pm
Yeah! After hundreds of wasted keystrokes filling in random test data in a form I'm developing, I thought of making a bookmarklet. Luckily for me, you've already made much better than I would have come up with, and I instantly found it. Thanks, it works great!
August 30th, 2006 at 1:31 pm
[…] Form auto-fill bookmarklet […]
August 30th, 2006 at 3:31 pm
[…] Form auto-fillbookmarklet […]
March 15th, 2007 at 5:18 am
Thank you for saving me from endless pain
March 25th, 2007 at 8:46 pm
Thanks for the code. I modified it to check if the element is visible before modifying the element. Here's the visible function
checkvisible: function(element) {
var el = element;
while (document !== el) {
if ('none' == el.style.display) {
return false;
}
el = el.parentNode;
}
return true;
}
April 13th, 2007 at 10:51 pm
Thanks A LOT! This helps a lot with PHP development where we constantly have to check form data!
June 19th, 2007 at 9:30 am
discussion world, the phpBB is the application, Internet hosting master
hosting for and the community master among undefined Written and
Wow! it works! you made my life a lot easier. thanks!
(and now i'll just have to tweak it a bit so it doesnt fill radiobuttons without a value)
June 22nd, 2007 at 5:33 am
I've been toying around with it for a bit now, and i'm definately going to use this a lot!
for my specific needs i'll have to change it a bit, but its a really good start.
i'll post the final result here
June 28th, 2007 at 2:39 am
It is possible to use this bookmarklet from IE, if you save this bookmarklet as an .js file which you host somewhere, and then use an other bookmarklet which dynamicaly loads that external .js file.
This has several advantages:
1/ it works in IE
2/ the external .js can be human-readable, there is no need to compress it to a single line
3/ if you want to change something, you only have to change the external .js, and not all of your bookmarks
the bookmarklet you run could be something like this
[code]
javascript:(function(){var s=document.createElement("script");s.charset="UTF-8";s.src="http://www.somewhere.com/formfiller.js";document.body.appendChild(s)})();
[/code]
I changed the notation of the script a little bit, but i'm not sure that thats mandatory (I'm not used to the JSON notation, so for me it was better to change that a little)
I also implemented a bit of Bramus' suggestions, and added a construction that makes sure that radiobuttons that have the value 'on' (eg the value attribute is ommitted) are ignored.
this is the code i ended up with:
[code]
//Based on: http://www.phpied.com/form-auto-fill-bookmarklet/
var names = 'Steve Buscemi Catherine Keener Dermot Mulroney Danielle Zerneck James LeGros Rica Martens Peter Dinklage Kevin Corrigan Hilary Gilford Robert Wightman Tom Jarmusch Michael Griffiths Matthew Grace Ryan Bowker Francesca DiMauro';
var blurb = 'phpBB is a free, open source Internet community application, with outstanding discussion forums and membership management. Written in the PHP scripting language, and making use of the popular MySQL database, phpBB is a standard among web hosting companies throughout the world, and is one of the most widely-used bulletin board packages in the world. phpBB short-circuits the need for you to be a web development master in order to create and manage massive online communities';
var password = 'secret';
var email = 'casper.de.groot@test.com.invalid';
function fillerup() {
var all_inputs = document.getElementsByTagName('input');
var all_selects = document.getElementsByTagName('select');
var all_textareas = document.getElementsByTagName('textarea');
// selects
for (var i = 0, max = all_selects.length; i
October 3rd, 2007 at 9:02 pm
Its about time someone did this
December 15th, 2007 at 4:37 pm
Great. Now all I have to do is customize it but it will save me a lot of time! Thanks.
December 21st, 2007 at 7:03 am
the code i posted above is incomplete, it didnt fit in the commentfield.
i mailed the author (a long time ago) to add the rest, but i never received an answer.
if you want my version of the code, drop me a line!
phpied [atsign] sperdegroot [dot] nl
December 23rd, 2007 at 10:23 pm
Hi Casper, sorry about that!
Below is the email I received back in June 2007, I only did a few tweaks to help with the highlighting
—
It is possible to use this bookmarklet from IE, if you save this bookmarklet
as an .js file which you host somewhere, and then use an other bookmarklet
which dynamicaly loads that external .js file.
This has several advantages:
1/ it works in IE
2/ the external .js can be human-readable, there is no need to compress it
to a single line
3/ if you want to change something, you only have to change the external
.js, and not all of your bookmarks
the bookmarklet you run could be something like this
I changed the notation of the script a little bit, but i'm not sure that
thats mandatory (I'm not used to the JSON notation, so for me it was better
to change that a little)
I also implemented a bit of Bramus' suggestions, and added a construction
that makes sure that radiobuttons that have the value 'on' (eg the value
attribute is ommitted) are ignored.
this is the code i ended up with:
For me this is going to be a real time saver, so thank you very much for
the great ideas!
December 24th, 2007 at 1:08 am
@Stoyan: no problem! thanks for posting my version of the bookmarklet!
It has been a real time saver for me and my colleagues, i estimate we use it about 8 times a day for testing questionnaires (fill it out completely, and then checking if all items are stored in the database). this is soooo much better than manually clicking about 80 radiobuttons each time! (which i used to do for about one and a half year before i found this… thats about a whole day of randomly clicking questionaires if you add it all up… what a waste!)
In the meanwhile i also added some counter so the bookmarklet gives me an alert with the number of radiobuttons/checkboxes that are checked, and the number of textfields/textarea's that have been filled.
oh.. and when i read back my old code, i now realize that the getEmail() and getRand() are a bit stupid…
i forgot to use the variables i declared at the top of the code… whoops
Regards,
Koesper
April 7th, 2008 at 7:59 am
Hello,
This is really awesome! But I have one little thing I want to do different…
I want to use the script without having to make a bookmark, and without having to put the javascript code/button on the page of the form itself. I tried to make this script working with frames and iframes… (one frame for the javascript code and button, and one frame for the page with the form) …but I did not succeeded. Does anyone knows how to do this? Main thing is: I don't want to adjust (put javascript code in) the pages with the forms.
Greetings,
Vincent
April 19th, 2008 at 2:42 pm
Vincent: that is posible for Firefox with Grease Monkey - http://www.greasespot.net/ - read documentation and you will soon realize, that it is wery simple to implement
April 21st, 2008 at 12:06 pm
hey can u make it so that the email is made the same next time like password is? and also could you make a username field where it enters random usernames? rather than me getting full names in the username box?
April 21st, 2008 at 8:08 pm
Cool! Is this similar to the technique used for http://mashedLife.com