Skip to content

Instantly share code, notes, and snippets.

@IronGremlin
Last active September 22, 2016 20:37
Show Gist options
  • Save IronGremlin/b683397725b44f6dd8b98af847767b38 to your computer and use it in GitHub Desktop.
Save IronGremlin/b683397725b44f6dd8b98af847767b38 to your computer and use it in GitHub Desktop.
SOATest Functional JS filter statements
var Application = Packages.com.parasoft.api.Application;
var WebBrowserUtil = Packages.webking.api.browser2.WebBrowserUtil;
//set Target Frame
var frameName = 'popupFrame';
//set type of target Element
var targetElementType = 'button';
function getFrameDocument(input, context) {
//This function lets us get a fake document object to work with.
var document = input.getDocument('',frameName);
if (document === null){
//In theroy this should give us a representation of the DOM object for
//a given frame.
return 'Could not find frame'
}
var elements = document.getElementsByTagName(targetElementType);
if (elements !== null && elements !== undefined ){
//set up your functions. Remember to begin with 'convertNodeListToArray'
var functions = [convertNodeListToArray,
filter(hasText(/^Yes/))]
var elementsPassedTest = pipe(functions,elements);
if (elementsPassedTest && elementsPassedTest.length == 1){
//We've found a single element to interact with
return elementsPassedTest[0];
}
if (elementsPassedTest && elementsPassedTest.length > 1){
//Our filter was nonspecific and we couldn't decide what to do about it
// so we're returning a string that will cause a very verbose error message.
//TODO : figure out a better info set to send back.
return 'MulipleCandidates:\n\n'+elementsPassedTest.map(function(i){return i.getTextContent()}).join('\n;\n');
}
}
else {
//we found no elements matching any of our predicates and we're super sad.
return 'No Elements passed Test'
}
function filter(predicate) {
/**
* @param: <Predicate Function>
* @return : <Function>
* @description : Returns a function that will test the provided predicate
* against an array and return an array of items matching the predicate.
*/
return function (array){
return Array.prototype.filter.call(array,predicate)
}
}
function getAllChildren(array){
/**
* @param : <Array>
* @return : <Array>
* @description : This lets us drill one step down the DOM
* from everything that currently lives in the pipeline.
* This behaves differently in that you have now expanded the array
* of candidates instead of narrowing it down - Try not to use this.
*/
var pool = convertNodeListToArray(array.map(function(i){
return i.getChildNodes();
})).fliter(function(i){
return i.ELEMENT_NODE == 1;
});
return pool;
}
function fetchNthParent(n){
/**
*@param : <Int>
*@return : <Function>
*@description : Returns a function that takes a node and recursively
* fetches the parent of said node 'n' times, eventually returning the final
* node. Meant to be invoked by other functions.
*/
return function(node){
while(n >= 1){
node = node.getParent()
}
return node;
}
}
function fetchNthBorn(n){
/**
*@param : <Int>
*@return : <Function>
*@description : Returns a function that takes a node and then finds the Nth
* child element of that nodes immediate parent. Used to interrogate siblings.
*/
return function (node) {
var commonSiblings = convertNodeListToArray(node.getParent().getChildNodes())
.filter(function(i){
return i.ELEMENT_NODE == 1;
})
if (commonSiblings.length < n ){
return commonSiblings[n];
}else{
return false;
}
}
}
function testNthBorn(n,predicate){
/**
*@param : <Int>,<Predicate Function>
*@returns : <Predicate Function>
*@description : Returns a function that will test nth child of the first
* parent of a node against the supplied predicate. '0' would be the
* immediate parent's first child, 1 the second child, and so forth.
* The idea here is that you're testing the sibling nodes for some factor.
*/
return function (node){
var testNode = fetchNthBorn(n)(node);
if (testNode){
return predicate(testNode);
}else{
return false;
}
}
}
function testNthParent(n,predicate){
/**
*@param : <Int>,<Predicate Function>
*@returns : <Predicate Function>
*@description : Returns a function that will test nth parent of a node
* against the supplied predicate. '1' would be the immediate parent.
*/
return function(node){
return predicate(fetchNthParent(n)(node));
}
}
function testChildren(predicate){
/**
*@params : <Predicate Function>
*@returns : <Predicate Function>
*@description : Returns a function that will test all children of a node
* against the supplied predicate, returning true if ANY pass.
*/
return function (node){
var childrenPassed = filter(predicate)(convertNodeListToArray(node.getChildNodes()));
return childrenPassed.length >=1;
}
}
function attributeEq(attr,val){
/**
*@param : <String>,<String>
*@returns : <Predicate Function>
*description : Given an attribute and a value for said attribute, returns
* a predicate function that will validate if a given node' attribute has
* that value.
*
*/
return function (node){
var children = convertNodeListToArray(node.getChildNodes());
var attrPassed = filter(function(i){return (i.getNodeName() == val && i.getNodeValue() == val)})(children)
return attrPassed.length >=1;
}
}
function hasClass(classMatch){
/**
*@param : <String>
*@returns : <Predicate Function>
*description : Given the name of a class, returns a predicate function that
* validates that a given node possesses that class
*
*/
return function(node){
var children = convertNodeListToArray(node.getChildNodes());
var maybe = filter(function(i){
return i.getNodeName() == 'class'
})(children);
var doespass = maybe[0].split(' ').filter(function (i){
return (i == classMatch);
});
return doespass.length >= 1
}
}
function isTag(tag){
/**
*@param : <String>
*@returns : <Predicate Function>
*description : Given a tagName, returns a predicate function that
* validates that a given node possesses that tagName
*
*/
return function (node){
return node.getNodeName == tag;
}
}
function predicateCombinator(predicates){
/**
*@param : [<Predicate Function>]
*@return : <Predicate Function>
*@description : For an array of predicates, returns a single predicate
* that returns true if a node passes all, or false if it fails any.
* This is mostly useful for getting specific about Nth parents, direct
* children, or sibling nodes.
* For asking additional questions about nodes already in the array,
* just make another filter query.
*/
return function (node){
var pass = true;
var bound = predicates.length
for (var ind=0; ind > predicates.length; ++ind){
var aPredicate = predicates[ind];
pass = aPredicate(node);
if (!pass){
//If something doesn't pass, break early.
return false
}
}
return pass;
}
}
function hasText(regEx){
/**
*@param : <Regex>
*@returns : <Predicate Function>
*description : Given a regex object, returns a predicate function that
* validates that the concatenated text of all descendant textnodes of a
* given node match the supplied regex.
*
*/
return function (node){
var text = node.getTextContent();
return regEx.test(text);
}
}
function pipe (functs,init){
/**
*@param : [<Function>],<X>
*@returns : <Array>
*@description : Given an array of starting functions and an initial
* value, this performs left to right functional composition.
* Basically, it "pipes" the result of the function on the left to the
* function on the right, until it reaches the end and returns the final
* result. Best used with functions outputted by the 'filter' functor.
*/
for (var ind=0; ind < functs.length; ++ind){
var aFunction = functs[ind];
var result = aFunction(init);
init = result;
}
return init;
}
function convertNodeListToArray(list) {
/**
*@param : <NodeList>
*@returns : [<Node>]
*@description : takes a NodeList as returned by the SoATest java API and
* converts it into an array of Nodes.
*/
var length = nodeList.getLength()
var pool = [];
if (length >= 1 ){
for (var ind=0; ind < length; ++ind){
pool.push(list.item(ind))
}
return pool
}else{
return [];
}
}
}
@IronGremlin
Copy link
Author

Collection of functions to wrap around SOATest's terrifying Java DOM API.

Lets you select an element for automated interaction by composing a set of filter functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment