Last active
August 29, 2015 13:56
-
-
Save lovasoa/9151431 to your computer and use it in GitHub Desktop.
Automatic form fill, random form fill, and all kind of nice things with forms. Can be used for mass user account generation on a web site, for instance.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
exports.url = "http://test.com"; //URL of the first page of the form | |
exports.fillRules = [ //Each element is a new page in the form | |
{// First page | |
// Keys must be CSS selectors | |
// Values indicate how to fill the selected element | |
"#inputid" : "constant string value", | |
"#inputid2" : ["this", "that"], // One value will be picked at random | |
"input[type='password']" : {"type":"randomstr", "length":8}, // A string of random characters | |
"input.numberinput" : {"type":"randomint", "min":8, "max":18}, // A random integer between 8 and 18 | |
}, | |
{ // If submitting the form at the given url leads to a second form page, this second form can be filled too | |
"#email" : {"type":"composedstr", "parts":[{"select":"#name","attr":"innerHTML"}, '@', {'choice':['gmail.com', 'yahoo.co.uk']}]}, | |
} | |
]; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/***************** | |
Formfill | |
Description: fill forms through a headless browser. Works on multi-page forms. | |
Author: @lovasoa | |
License: GPLv2 | |
******************/ | |
var system = require("system"); | |
var filldata = require("./filldata"); | |
var nbrFills = 1; | |
if (system.args.length > 1) { | |
nbrFills = parseInt(system.args[1]); | |
console.log("I will fill it "+nbrFills+' times'); | |
} | |
var page = new WebPage(); | |
page.onConsoleMessage = function() { | |
console.log('Page says: '); | |
console.log.apply(console, arguments); | |
}; | |
page.viewportSize = { | |
width: 800, | |
height: 800 | |
}; | |
page.addVariable = function (name, value) { | |
var strname = JSON.stringify(name); | |
var strval = JSON.stringify(value); | |
if (typeof value === "function") strval = value.toString(); | |
var fun = eval("(function(){return (window["+strname+"]="+strval+")})"); | |
return this.evaluate(fun); | |
} | |
function fillPage () { | |
function randomInt(min, max) { | |
return Math.floor(min + (max-min+1)*Math.random()); | |
} | |
function randomStr(len) { | |
var arr = Array(len); | |
for (var i=0; i<len; i++) { | |
arr[i] = String.fromCharCode(randomInt(97, 122)); // 97:'a' 122:'z' | |
} | |
return arr.join(''); | |
} | |
for (var selector in formfiller_phantom_data) { | |
var target = document.querySelector(selector); | |
var replinfo = formfiller_phantom_data[selector]; | |
if (Array.isArray(replinfo)) { | |
var repl = replinfo[randomInt(0, replinfo.length-1)]; | |
} else if (typeof replinfo === "object") { | |
switch (replinfo.type) { | |
case "randomstr": | |
// String of random characters | |
repl = randomStr(replinfo.length || randomInt(5,100)); | |
break; | |
case "randomint": | |
repl = randomInt(replinfo.min||0, replinfo.max||100); | |
break; | |
case "randomselect": | |
// Only applicable if target is a select element. Chooses a random option | |
var min = replinfo.min || 0; | |
var max = (typeof replinfo.max === "number") ? replinfo.max : target.options.length-1; | |
repl = target.options.item(randomInt(min, max)).value; | |
break; | |
case "randomemail": | |
repl = randomStr(randomInt(6,20))+"@gmail.com"; | |
break; | |
case "composedstr": | |
repl = ''; | |
for (var i=0;i<replinfo.parts.length;i++) { | |
var p = replinfo.parts[i]; | |
if (typeof p === "string") { | |
repl += replinfo.parts[i]; | |
} else { | |
if (p.select) { | |
repl += document.querySelector(p.select)[p.attr||"value"]; | |
} else if (p.randint) { | |
repl += randomInt(p.randint[0], p.randint[1]); | |
} else if (p.choice) { | |
repl += p.choice[randomInt(0,p.choice.length-1)]; | |
} | |
} | |
} | |
break; | |
case "attributes": | |
for (a in replinfo) { | |
if (a != "type") target[a] = replinfo[a]; | |
} | |
repl = null; | |
break; | |
default: | |
console.log("Invalid replinfo type"); | |
} | |
} else if (typeof replinfo === "function") { | |
repl = replinfo(target); | |
} else { | |
repl = replinfo; | |
} | |
if (repl !== null) target.value = repl; | |
} | |
//Validate the form of the last target found | |
target.form.submit(); | |
} | |
var i=0, inter; | |
function fillOnce() { | |
i++; | |
if (i > nbrFills) { | |
phantom.exit(); | |
} | |
clearInterval(inter); | |
page.open(filldata.url, function() { | |
var curPage = -1; | |
var curUrl = ''; | |
inter = setInterval(function(){ | |
if ( !page.loading && curUrl != page.frameUrl ) { | |
curUrl = page.frameUrl; | |
curPage ++; | |
if (curPage === filldata.fillRules.length) { | |
page.zoomFactor = 0.4; | |
page.render("capture-finale-"+i+".pdf"); | |
page.clearCookies(); | |
fillOnce(); | |
return; | |
} | |
console.log("Filling " + page.frameUrl); | |
page.addVariable("formfiller_phantom_data", filldata.fillRules[curPage]); | |
page.evaluate(fillPage); | |
}; | |
}, 50); | |
}); | |
} | |
fillOnce(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment