Files
galaxy/test/casperjs/modules/tools.js
T

204 lines
8.7 KiB
JavaScript

// =================================================================== module object, exports
/** Creates a new tools module object.
* @exported
*/
exports.create = function createTools( spaceghost ){
return new Tools( spaceghost );
};
/** Tools object constructor.
* @param {SpaceGhost} spaceghost a spaceghost instance
*/
var Tools = function Tools( spaceghost ){
//??: circ ref?
this.options = {};
/** Default amount of ms to wait for upload to finish */
this.options.defaultUploadWait = ( 45 * 1000 );
this.spaceghost = spaceghost;
};
exports.Tools = Tools;
Tools.prototype.toString = function toString(){
return this.spaceghost + '.Tools';
};
// -------------------------------------------------------------------
/* TODO:
move selectors from sg to here
*/
// =================================================================== INTERNAL
var require = patchRequire( require ),
xpath = require( 'casper' ).selectXPath;
// ------------------------------------------------------------------- get avail. tools
// list available tools
//spaceghost.then( function(){
// spaceghost.withFrame( 'galaxy_tools', function(){
// //var availableTools = this.fetchText( 'a.tool-link' );
//
// var availableTools = this.evaluate( function(){
// //var toolTitles = __utils__.findAll( 'div.toolTitle' );
// //return Array.prototype.map.call( toolTitles, function( e ){
// // //return e.innerHtml;
// // return e.textContent || e.innerText;
// //}).join( '\n' );
//
// var toolLinks = __utils__.findAll( 'a.tool-link' );
// return Array.prototype.map.call( toolLinks, function( e ){
// //return e.innerHtml;
// return e.textContent || e.innerText;
// }).join( '\n' );
// });
// this.debug( 'availableTools: ' + availableTools );
// });
//});
/** Parses the hid and name of a new file from the tool execution donemessagelarge
* @param {String} doneMsgText the text extracted from the donemessagelarge after a tool execution
*/
Tools.prototype._parseDoneMessageForTool = function parseDoneMessageForTool( doneMsgText ){
//TODO: test
var executionInfo = {};
var textMatch = doneMsgText.match( /added to the queue:\n\n(\d+)\: (.*)\n/m );
if( textMatch ){
if( textMatch.length > 1 ){
executionInfo.hid = parseInt( textMatch[1], 10 );
}
if( textMatch.length > 2 ){
executionInfo.name = textMatch[2];
}
executionInfo.name = textMatch[2];
}
return executionInfo;
};
// ------------------------------------------------------------------- upload (internal)
/** Tests uploading a file.
* NOTE: this version does NOT throw an error on a bad upload.
* It is meant for testing the upload functionality and, therefore, is marked as private.
* Other tests should use uploadFile
* @param {String} filepath the local filesystem path of the file to upload (absolute (?))
*/
Tools.prototype._uploadFile = function _uploadFile( filepath ){
//TODO: generalize for all tools
var spaceghost = this.spaceghost,
uploadInfo = {};
uploadInfo[ spaceghost.data.selectors.tools.upload.fileInput ] = filepath;
spaceghost.openHomePage( function(){
// load the upload tool form
// (we can apprently click a tool label without expanding the tool container for it)
this.click( xpath( '//a[contains(text(),"Upload File")]' ) );
this.jumpToMain( function(){
this.waitForSelector( 'body' );
});
});
// fill in the form and click execute - wait for reload
spaceghost.withMainPanel( function(){
//?? no wait for page to load?
this.fill( this.data.selectors.tools.general.form, uploadInfo, false );
// the following throws:
// [error] [remote] Failed dispatching clickmouse event on xpath selector: //input[@value="Execute"]:
// PageError: TypeError: 'undefined' is not a function (evaluating '$(spaceghost).formSerialize()')
// ...and yet the upload still seems to work
this.click( xpath( this.data.selectors.tools.general.executeButton_xpath ) );
// wait for main panel, history reload
////NOTE!: assumes tool execution reloads the history panel
this.waitForMultipleNavigation( [ 'tool_runner/upload_async_message' ],
function thenAfterUploadRefreshes(){
// debugging
this.jumpToMain( function(){
var messageInfo = this.elementInfoOrNull( this.data.selectors.messages.all );
this.debug( ( messageInfo )?( messageInfo.attributes['class'] + ':\n' + messageInfo.text )
:( 'NO post upload message' ) );
});
},
function timeoutWaitingForUploadRefreshes( urlsStillWaitingOn ){
throw new this.GalaxyError( 'Upload Error: '
+ 'timeout waiting for upload "' + filepath + '" refreshes: ' + urlsStillWaitingOn );
},
this.tools.options.defaultUploadWait
);
});
};
// =================================================================== API (external)
// ------------------------------------------------------------------- misc
/** get filename from filepath
* @param {String} filepath (POSIX) filepath
* @returns {String} filename part of filepath
*/
Tools.prototype.filenameFromFilepath = function filenameFromFilepath( filepath ){
var lastSepIndex = filepath.lastIndexOf( '/' );
if( lastSepIndex !== -1 ){
return filepath.slice( lastSepIndex + 1 );
}
return filepath;
};
// ------------------------------------------------------------------- upload (conv.)
/** Convenience function for uploading a file.
* callback function will be passed an uploadInfo object in the form:
* filepath: the filepath of the uploaded file
* filename: the filename of the uploaded file
* hid: the hid of the uploaded file hda in the current history
* name: the name of the uploaded file hda
* hdaElement: the hda DOM (casperjs form) element info object (see Casper#getElementInfo)
* @param {String} filepath (POSIX) filepath relative to the script's directory
* @param {Function} callback callback function called after hda moves into ok state (will be passed uploadInfo)
* @param {Integer} timeoutAfterMs milliseconds to wait before timing out (defaults to options.defaultUploadWait)
*/
Tools.prototype.uploadFile = function uploadFile( filepath, callback, timeoutAfterMs ){
timeoutAfterMs = timeoutAfterMs || this.options.defaultUploadWait;
var spaceghost = this.spaceghost,
filename = this.filenameFromFilepath( filepath ),
uploadInfo = {};
spaceghost.info( 'uploading file: ' + filepath + ' (timeout after ' + timeoutAfterMs + ')' );
this._uploadFile( filepath );
// error if an info message wasn't found
spaceghost.withMainPanel( function checkUploadMessage(){
var infoInfo = spaceghost.elementInfoOrNull( this.data.selectors.messages.infolarge );
if( ( infoInfo )
&& ( infoInfo.text.indexOf( this.data.text.upload.success ) !== -1 ) ){
// safe to store these
uploadInfo.filename = filename;
uploadInfo.filepath = filepath;
} else {
// capture any other messages on the page
var otherInfo = spaceghost.elementInfoOrNull( this.data.selectors.messages.all ),
message = ( otherInfo && otherInfo.text )?( otherInfo.text ):( '' );
throw new this.GalaxyError( 'Upload Error: no success message uploading "' + filepath + '": ' + message );
}
});
// the hpanel should refresh and display the uploading file, wait for that to go into the ok state
// throw if uploaded HDA doesn't appear, or it doesn't move to 'ok' after allotted time
//spaceghost.historypanel.waitForHdas()
spaceghost.historypanel.waitForHda( filename,
// success: update the upload info and run callback
function whenInStateFn( newHdaInfo ){
this.info( 'Upload complete: ' + newHdaInfo.text );
uploadInfo.hdaElement = newHdaInfo;
callback.call( spaceghost, uploadInfo );
},
function timeoutFn( newHdaInfo ){
this.warning( 'timeout waiting for upload: ' + filename + ', ' + this.jsonStr( newHdaInfo ) );
throw new spaceghost.GalaxyError( 'Upload Error: timeout waiting for ok state: '
+ '"' + uploadInfo.filepath + '" (waited ' + timeoutAfterMs + ' ms)' );
},
timeoutAfterMs
);
return spaceghost;
};
//TODO: upload via url
//TODO: upload by textarea