Last active
December 17, 2015 16:29
-
-
Save mwcz/5638789 to your computer and use it in GitHub Desktop.
(mostly complete) CasperJS script to configure the Dynamic Navigation section of a GSA, because Google's API doesn't provide that ability...
This file contains 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
(function () { | |
var system = require('system'); | |
var casper = require('casper').create({ | |
clientScripts : [ 'jquery.min.js' ], | |
waitTimeout : 30000, // ms | |
logLevel : 'debug', // info, debug, warning, or error | |
verbose : system.args.indexOf('-v') >= 0 | |
}); | |
var actions; | |
var action_sequences; | |
var GSA_PASSWORD = ''; | |
var GSA_USERNAME = ''; | |
var GSA_URL = ''; | |
//======================= | |
// | |
// Convenience functions | |
// | |
//======================= | |
// Extract function name from a function reference | |
// thanks http://stackoverflow.com/a/15714445/215148 | |
function functionName(fun) { | |
var ret = fun.toString(); | |
ret = ret.substr('function '.length); | |
ret = ret.substr(0, ret.indexOf('(')); | |
return ret; | |
} | |
function exit(returnValue) { | |
casper.exit(returnValue); | |
} | |
//========================================================================== | |
// | |
// Common actions | |
// | |
// These are actions that need to be called by several sequences below. | |
// Any action that needs to be called multiple times during a sequence, or | |
// are used by multiple sequences, should go here. | |
// | |
//========================================================================== | |
actions = {}; | |
actions.login = function login () { | |
casper.start( GSA_URL, function () { | |
this.fill('form[name=login]', { | |
'userName' : GSA_USERNAME, | |
'password' : GSA_PASSWORD | |
}, true); | |
}); | |
}; | |
actions.go_to_dyn_nav = function go_to_dyn_nav () { | |
casper.thenOpen( GSA_URL + '?actionType=dynNav' ); | |
}; | |
actions.get_dnav_configurations = function get_dnav_configurations () { | |
// for each configuration: | |
// click edit: | |
// get the Name | |
// get the Added Front Ends | |
// get Secure Search | |
// if Secure Search: | |
// get Use Fast Auth or Use All Auth | |
// get Use Only Fast Auth or Use All Types Auth | |
// for each Attribute: | |
// fn() get the Attribute's Label, Name, Type, [Range], SortBy, SortOrder | |
casper.then(function () { | |
// Wait for the page contents to be filled in via AJAX | |
this.waitForText( "Existing Configurations", function () { | |
var configurations = ""; | |
casper.page.injectJs("dynamic_nav_data_types.js"); | |
configurations = this.evaluate(function () { | |
var configurations = []; | |
var $edit_buttons; | |
// Find the edit button for each Configuration | |
$edit_buttons = $("#gwt-debug-configs a.gwt-Anchor:contains(Edit)"); | |
$edit_buttons.each(function () { | |
// Get a brand new Configuration object with default values | |
var configuration = DNAV_TYPES.clone( DNAV_TYPES.Configuration ); | |
// view this Configuration | |
$(this).click(); | |
// get the Name | |
configuration.name = $("#gwt-debug-configName").val(); | |
// get the Added Front Ends | |
$("#gwt-debug-addedFes option").each(function () { | |
configuration.added_front_ends.push( $(this).val() ); | |
}); | |
// get Secure Search enabled | |
configuration.enable_secure_search = | |
$("#gwt-debug-enableSecureSearch-input").prop("checked"); | |
// if Secure Search enabled, get the Auth Type | |
if (configuration.enable_secure_search) { | |
configuration.auth_type = | |
DNAV_TYPES.AuthzTypeValueToNameMap[ | |
$("[name=authzType]:checked").prop('id') | |
]; | |
} | |
// Click Edit on each Attribute and harvest their infos | |
$("#gwt-debug-params .gwt-Anchor:contains('Edit')").each(function () { | |
var attribute = DNAV_TYPES.clone( DNAV_TYPES.Attribute ); | |
$(this).click(); | |
attribute.display_label = $('#gwt-debug-label').val(); | |
attribute.attribute_name = $('#gwt-debug-name').val(); | |
attribute.type = DNAV_TYPES.AttributeTypeValueToNameMap[ $('#gwt-debug-type').val() ]; | |
attribute.sort_by = DNAV_TYPES.SortByValueToNameMap[ $("input[name=sortBy]:checked").prop("id") ]; | |
attribute.sort_order = DNAV_TYPES.SortOrderValueToNameMap[ $("input[name=sortOrder]:checked").prop("id") ]; | |
attribute.is_range = $('#gwt-debug-isRange-input').prop("checked"); | |
if (attribute.is_range) { | |
$("#gwt-debug-ranges option").each( function () { | |
// ranges are in the format "1 - 10" | |
var range_obj; | |
var range = $(this).val().split(" - "); // isolate the numbers | |
range_obj = DNAV_TYPES.clone( DNAV_TYPES.Range ); | |
range_obj.low = range[0]; | |
range_obj.high = range[1]; | |
attribute.ranges.push( range_obj ); | |
}); | |
} | |
attribute.is_entity = $("#gwt-debug-entity[aria-hidden=false] option:selected").length > 0; | |
configuration.attributes.push( attribute ); | |
}); | |
configurations.push( configuration ); | |
// Go back to the list of Configurations | |
$("#gwt-debug-configCancel").click(); | |
}); | |
return JSON.stringify(configurations, null, 4 ); | |
}); | |
this.echo(configurations); | |
}); | |
}); | |
}; | |
// Make the confirm() dialog return true every time, just like clicking Ok | |
// automatically | |
actions.always_confirm = function always_confirm () { | |
casper.thenEvaluate(function () { | |
var confirm2 = window.confirm; | |
window.confirm = function (msg) { return true; }; | |
}); | |
}; | |
// Delete the first Dynamic Navigation configuration entry | |
actions.delete_dnav_configuration = function delete_dnav_configuration () { | |
casper.waitWhileVisible( | |
".gux-confirm-panel-message", | |
function then () { | |
this.thenEvaluate(function () { | |
// Click on the first Delete button | |
$("#gwt-debug-configs .gwt-Anchor:contains(Delete)").eq(0).click(); | |
}); | |
} | |
); | |
}; | |
// Delete all Dynamic Navigation configuration entries | |
actions.delete_dnav_configurations = function delete_dnav_configurations () { | |
casper.waitForText( | |
"Existing Configurations", | |
function then () { | |
casper.then(function () { | |
var i; | |
var dnav_count = this.evaluate(function () { | |
return $("#gwt-debug-configs .gwt-Anchor:contains(Delete)").length; | |
}); | |
for (i = 0; i < dnav_count; i += 1) { | |
actions.delete_dnav_configuration(); | |
} | |
}); | |
} | |
); | |
}; | |
actions.add_dnav_frontend = function add_dnav_frontend (fe) { | |
casper.thenEvaluate(function (fe) { | |
(function () { | |
var $front_end = $("#gwt-debug-availableFes option[value="+fe+"]").detach(); | |
$("#gwt-debug-addedFes").append($front_end); | |
}()); | |
}, fe); | |
}; | |
actions.add_dnav_range = function add_dnav_range (range) { | |
casper.waitUntilVisible( | |
"#gwt-debug-addRange", | |
function then() { | |
this.evaluate(function (range) { | |
$("#gwt-debug-rangeLv").val( range.low ); | |
$("#gwt-debug-rangeHv").val( range.high ); | |
}, range); | |
} | |
); | |
casper.thenClick("#gwt-debug-addRange"); | |
}; | |
actions.add_dnav_attribute = function add_dnav_attribute (attribute) { | |
casper.waitUntilVisible( | |
"#gwt-debug-paramAdd", | |
function then () { | |
this.evaluate(function (attribute) { | |
var range_i; | |
// The only difference between Entity attributes and | |
// non-Entity attributes is that Entity attributes' | |
// "Attribute Names" come from a select list. | |
if (attribute.is_entity) { | |
$("#gwt-debug-entityAdd").click(); | |
// select the Attribute Name from the select list | |
$("#gwt-debug-entity option[value="+ | |
DNAV_TYPES.AttributeNameToValueMap[ | |
attribute.attribute_name | |
]+ | |
"]").prop("selected", true); | |
} else { | |
$("#gwt-debug-paramAdd").click(); | |
// Set the plaintext attribute name | |
$("#gwt-debug-name").val( attribute.attribute_name ); | |
} | |
// The rest of these properties are common between both | |
// Entity attributes and non-entity attributes | |
// set display label | |
$("#gwt-debug-label").val( attribute.display_label ); | |
// select the Type from the select list | |
$("#gwt-debug-type option[value="+ | |
DNAV_TYPES.AttributeTypeNameToValueMap[ | |
attribute.type | |
]+ | |
"]").prop("selected", true); | |
// Set SortBy and SortOrder | |
$("#"+ DNAV_TYPES.SortByNameToValueMap[ attribute.sort_by ]).click(); | |
$("#"+ DNAV_TYPES.SortOrderNameToValueMap[ attribute.sort_order ]).click(); | |
}, attribute); | |
// If this attribute has any ranges, add them | |
if (attribute.is_range) { | |
this.thenClick("#gwt-debug-isRange-input"); | |
for (range_i = 0; range_i < attribute.ranges.length; range_i += 1) { | |
actions.add_dnav_range( attribute.ranges[ range_i ] ); | |
} | |
} | |
} | |
); | |
// Save attribute! | |
casper.thenClick("#gwt-debug-paramCreate"); | |
casper.waitUntilVisible("#gwt-debug-paramAdd"); | |
}; | |
actions.add_dnav_configuration = function add_dnav_configuration (configuration) { | |
casper.waitUntilVisible( | |
"#gwt-debug-configAdd", | |
function then () { | |
casper.page.injectJs("dynamic_nav_data_types.js"); | |
casper.echo("GONNA ADD ME A CONFIGURATION GONNA ADD IT TO-DAY"); | |
casper.thenClick("#gwt-debug-configAdd"); | |
} | |
); | |
// When the Create Configuration button appears, fill out the form | |
casper.waitUntilVisible( | |
"#gwt-debug-configCreate", | |
function then() { | |
var front_end_i; | |
var attr_i; | |
this.evaluate(function (configuration) { | |
$('#gwt-debug-configName').val( configuration.name ); | |
// click Secure Search radio button | |
$("#gwt-debug-enableSecureSearch-input").prop("checked",configuration.enable_secure_search); | |
// click Secure Search type | |
$("#"+ DNAV_TYPES.AuthzTypeNameToValueMap[ configuration.auth_type ] ).prop("checked",true); | |
}, configuration); | |
// Move each chosen front end from the Available to the Added column | |
for (front_end_i = 0; front_end_i < configuration.added_front_ends.length; front_end_i += 1) { | |
actions.add_dnav_frontend( configuration.added_front_ends[front_end_i] ); | |
} | |
for (attr_i = 0; attr_i < configuration.attributes.length; attr_i += 1) { | |
actions.add_dnav_attribute( configuration.attributes[attr_i] ); | |
} | |
} | |
); | |
casper.then(function () { | |
this.page.injectJs("dynamic_nav_data_types.js"); | |
}); | |
// Save configuration! | |
casper.thenClick( "#gwt-debug-configCreate" ); | |
}; | |
actions.add_dnav_configurations = function add_dnav_configurations () { | |
// for each configuration passed in: | |
// click Add | |
// enter Name gwt-debug-configName | |
// for each Added Front End: | |
// click on the corresponding Available Front End | |
// if secure search: | |
// click secure search | |
// if fast auth: click fast | |
// if all auth: click all | |
// for each attribute: | |
// if entity: | |
// click Add Entity | |
// choose Attribute Name | |
// else not entity: | |
// click Add | |
// enter Attribute Name | |
// enter display label | |
// choose Type | |
// choose SortBy | |
// choose SortOrder | |
// click Ok | |
// click Create | |
// | |
casper.waitUntilVisible( | |
"#gwt-debug-configAdd", | |
function then () { | |
var configurations = []; | |
var input = system.stdin.read(); | |
var conf_i; | |
if (input.length === 0) { | |
console.error("No Dynamic Navigation configuration was passed in."); | |
exit(1); | |
} | |
try { | |
configurations = JSON.parse( input ); | |
} catch (e) { | |
console.error(e); | |
console.error("Dynamic Navigation configuration could not be parsed by JSON.parse."); | |
exit(1); | |
} | |
for (conf_i = 0; conf_i < configurations.length; conf_i += 1) { | |
actions.add_dnav_configuration( configurations[conf_i] ); | |
} | |
} | |
); | |
}; | |
actions.end_state = function end_state () { | |
// Log out | |
casper.thenEvaluate(function () { | |
$("#TopLinks a:contains(Log Out)").click(); | |
}); | |
}; | |
//=========================================================== | |
// | |
// Action sequences; strings of actions to accomplish a task | |
// | |
// They can be a combination of common actions from above, | |
// or sequence-specific actions. | |
// | |
//=========================================================== | |
action_sequences = {}; | |
// Scrape the current Dynamic Navigation configuration | |
action_sequences.get_dnav_configuration = [ | |
actions.login, | |
actions.go_to_dyn_nav, | |
actions.get_dnav_configurations, | |
actions.end_state | |
]; | |
// Add a Dynamic Navigation configuration | |
action_sequences.add_dnav_configuration = [ | |
actions.login, | |
actions.go_to_dyn_nav, | |
actions.always_confirm, | |
actions.delete_dnav_configurations, | |
actions.add_dnav_configurations, | |
actions.end_state | |
]; | |
//================================ | |
// | |
// Run through an action sequence | |
// | |
//================================ | |
function run_actions (action_sequence) { | |
var step; | |
for (step = 0; step < action_sequence.length; step += 1) { | |
action_sequence[step](); | |
} | |
casper.run(); | |
} | |
function helpText() { | |
var text = [ | |
"NAME", | |
" gsa.js - send scripted commands to a Google Search Appliance", | |
"", | |
"USAGE", | |
" casperjs --ignore-ssl-errors=true gsa.js [OPTIONS]", | |
"", | |
"DESCRIPTION", | |
" help - print this help page", | |
" list - list all the available 'run' commands", | |
" run COMMAND - run a GSA interaction", | |
" -v - verbose mode", | |
"", | |
"RUN COMMANDS", | |
helpCommands(), | |
"", | |
"EXAMPLES", | |
" List all the available COMMANDs to use with the `run` option:", | |
" casperjs --ignore-ssl-errors=true gsa.js list", | |
"", | |
" Get the current Dynamic Navigation configuration from the GSA:", | |
" casperjs --ignore-ssl-errors=true gsa.js run get_dnav_configuration", | |
"", | |
" Save the current configuration and then re-load it:", | |
" casperjs --ignore-ssl-errors=true gsa.js run get_dnav_configuration > dnav.out", | |
" cat dnav.out | casperjs --ignore-ssl-errors=true gsa.js run add_dnav_configuration", | |
"", | |
"NOTES", | |
" 'run' commands can take some time to execute. ", | |
""]; | |
return text.join("\n"); | |
} | |
function helpCommands() { | |
var commands = []; | |
var action_name; | |
for (action_name in action_sequences) { | |
commands.push( " " + action_name ); | |
} | |
return commands.join("\n"); | |
} | |
//============================= | |
// | |
// Finally let's run some code | |
// | |
//============================= | |
switch (system.args[4]) { | |
case 'help': | |
console.log( helpText() ); | |
exit(0); | |
break; | |
case 'list': | |
console.log(helpCommands()); | |
exit(0); | |
break; | |
case 'run': | |
if (system.args[5] in action_sequences) { | |
//var interval_i = 0; | |
//setInterval(function () { | |
//casper.capture(interval_i+".png"); | |
//interval_i += 1; | |
//}, 100 ); | |
run_actions( action_sequences[ system.args[5] ] ); | |
} else { | |
console.error('Invalid command name. Valid command names are:\n' + helpCommands()); | |
exit(1); | |
} | |
break; | |
default: | |
console.log( helpText() ); | |
exit(0); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment