Skip to content

Instantly share code, notes, and snippets.

@mayankgupta
Created July 11, 2011 00:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mayankgupta/058a6f6273ce0767ed1f to your computer and use it in GitHub Desktop.
Save mayankgupta/058a6f6273ce0767ed1f to your computer and use it in GitHub Desktop.
Selenium RC And JUnit ADL 1.2 Test Script
/*******************************************************************************
**
** Filename: lmsrtefunctions.js
**
** File Description: This file contains several javascript variable definitions
** and functions that are used commonly by all of the SCO HTML
** files in the LMS Runtime Environment Conformance Test. It
** is intended to be included in each SCO HTML file.
**
** Author: ADL Technical Team
**
** Contract Number:
** Company Name: Concurrent Technologies Corporation
**
**
** Design Issues: None
** Implementation Issues: None
** Known Problems: None
** Side Effects: None
**
** References:
**
**
***************************************************************************
**
** Advanced Distributed Learning Co-Laboratory (ADL Co-Lab) grants you
** ("Licensee") a non-exclusive, royalty free, license to use, modify and
** redistribute this software in source and binary code form, provided that
** i) this copyright notice and license appear on all copies of the software;
** and ii) Licensee does not utilize the software in a manner which is
** disparaging to ADL Co-Lab.
**
** This software is provided "AS IS," without a warranty of any kind. ALL
** EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
** ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
** OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. ADL Co-Lab AND ITS LICENSORS
** SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
** USING, MODIFYING OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO
** EVENT WILL ADL Co-Lab OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE,
** PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
** INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE
** THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE
** SOFTWARE, EVEN IF ADL Co-Lab HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
** DAMAGES.
**
** Date Changed Author Reason for Changes
** ------------ ---------------- -------------------------------------------
**
** 07/11/2001 Jeff Falls PT 966: Course 1/SCOs 5 and 6 reported "red"
** failure messages for optional data model
** elements returning a "404" Not Implemented
** string. These are now reported as "yellow"
** warning message if the data model element is
** optional. Otherwise, it is a mandatory
** element and the "red" failure message is
** reported.
**
** 08/27/2001 J. Falls Changed "can not" to "cannot".
**
** 10/5/2001 Bill Capone PT 1217, 1232 and 1233: Added the Functions
** convertTotalTime(), timeCompare(),
** charInBag(), charInString(),
** stripInitialWhitespace(),
** stripEndWhitespace(), stripEdges() and
** nameCompare().
**
** 10/19/2001 Bill Capone Changed "that the" to "than the".
**
** 10/23/2001 Bill Capone The description for doLMSSetValue states
** that it returns a boolean. Modified that
** function to actually return the boolean as
** that boolean was needed in SCO's 6 & 7.
**
** 10/30/2001 Bill Capone Added the functions stripWhitespace and
** stripCharsInBag.
**
** 10/31/2001 Bill Capone Removed the function doLMSSetErroneousValue
** as it was never called.
**
** 11/13/2001 Bill Capone Added the function doLMSSetValueNoPrint.
**
** 11/14/2001 Bill Capone Modified doLMSGetValue.
**
** 11/27/2001 Jeff Falls Changed testGetValue to allow for returning
** an error code of 201 or 401
**
** 11/27/2001 Jeff Falls Changes testSetValue to fail if a mandatory
** element returns a 201, 401, or 404 on an
** invalid value.
**
** 11/27/2001 Jeff Falls Added a check to make sure a "," exists to
** split on in nameCompare()
**
** 12/06/2001 Bill Capone Removed extraneous alert window in
** testSetValue(). Updated error code in
** in testSetValue(). Modified stripEdges():
** changed theField.value to theField.
**
** 1/28/2002 S. Thropp General format updates. Added code to aid
** in writing the log information to a separate
** file.
**
** 02/11/2002 Bill Capone Rewrote nameCompare() function. Removed the
** following, now unneeded, functions:
** charInBag, charInString,
** stripInitialWhitespace, stripEndWhitespace,
** stripEdges.
**
** 05/15/2002 Bill Capone While researching PT1976 found an error in
** in testGetValue() and testSetValue().
** Changed _WARNING to _FAILED.
**
*******************************************************************************/
// Define exception/error codes
var _NoError = 0;
var _GeneralException = "101";
var _InvalidArgumentError = "201";
var _ElementCannotHaveChildren = "202";
var _ElementIsNotAnArray = "203";
var _NotInitialized = "301";
var _NotImplementedError = "401";
var _InvalidSetValue = "402";
var _ElementIsReadOnly = "403";
var _ElementIsWriteOnly = "404";
var _IncorrectDataType = "405";
var errorMatrix = new Array(12);
errorMatrix[0] = new Array("0", "No error");
errorMatrix[1] = new Array("101", "General Exception");
errorMatrix[2] = new Array("201", "Invalid argument error");
errorMatrix[3] = new Array("202", "Element cannot have children");
errorMatrix[4] = new Array("203", "Element not an array - Cannot have count");
errorMatrix[5] = new Array("301", "Not initialized");
errorMatrix[6] = new Array("401", "Not implemented error");
errorMatrix[7] = new Array("402", "Invalid set value, element is a keyword");
errorMatrix[8] = new Array("403", "Element is read only");
errorMatrix[9] = new Array("404", "Element is write only");
errorMatrix[10] = new Array("405", "Incorrect Data Type");
errorMatrix[11] = new Array("", "");
// page scoped variable definitions
var apiHandle = null;
var API = null;
var findAPITries = 0;
// Data Model Conformance State values
var someOptional = false;
var allOptional = true;
var allMandatory = true;
var _Debug = false; // set this to false to turn debugging off
// to get rid of those annoying alert boxes.
//define the log message type constants
var _INFO = 0; // 0 = informational (diagnostic, trace, etc.)
var _WARNING = 1; // 1 = warning
var _PASSED = 2; // 2 = conformance check passed
var _FAILED = 3; // 3 = conformance check failure
var _TERMINATE = 4; // 4 = test suite termination due to nonconformance or error
var _CONFORMANT = 5; // 5 = subject is found to be conformant
var _OTHER = 9; // other
var _NEWSCO = 6; // 6 = used to indicate that a new sco was launched
// local variable definitions
// we'll track the status of the test using a state variable called scoStatus
// This is set by each SCO as it progresses through the test.
var scoStatus = null;
/*******************************************************************************
**
** Function: writeLogEntry(type, msg)
** Inputs: type - must be one of the following (constants defined above:
** _INFO - informational (diagnostic, trace, etc.)
** _WARNING - warning
** _PASSED - conformance check passed
** _FAILED - conformance check failure
** _TERMINATE - terminating due to nonconformance or error
** _CONFORMANT - subject is conformant
** _OTHER - display no icon and use default font.
** msg - string containing log message
**
** Return: None
**
** Description: This function displays a test suite log message. Note: the
** LogWriterApplet must be present in the HTML file that this script is
** included in and be identified by the logWriter object id.
**
*******************************************************************************/
function writeLogEntry(type, msg)
{
lmsRTEApplet.writeLogEntry(type, msg);
}
/******************************************************************************
**
** Function getAPIHandle()
** Inputs: None
** Return: value contained by APIHandle
**
** Description:
** Returns the handle to API object if it was previously set,
** otherwise it returns null
**
*******************************************************************************/
function getAPIHandle()
{
if (apiHandle == null)
{
apiHandle = getAPI();
if(apiHandle == null)
{
writeLogEntry(_FAILED, "Unable to locate LMS's API Adapter - Test Failed");
lmsRTEApplet.setAPIConformant(false);
terminateTest();
}
}
return apiHandle;
}
/*******************************************************************************
**
** Function: setAPIHandle(api)
** Inputs: api (may be null)
** Return: None
**
** Description: This function sets the apiHandle variable. The function
** looks through the window hierarchy for a variable called API
** and sets the apiHandle to this object.
**
*******************************************************************************/
function setAPIHandle(api)
{
if (_Debug)
{
alert("in setAPIHandle()");
}
if (api == null)
{
apiHandle = getAPI();
if (apiHandle == null)
{
handleAPINotFound();
}
}
else
{
apiHandle = api;
}
}
/*******************************************************************************
**
** Function: doLMSInitialize()
** Inputs: None
** Return: CMIBoolean true if the initialization was successful, or
** CMIBoolean false if the initialization failed.
**
** Description:
** Initialize communication with LMS by calling the LMSInitialize
** function which will be implemented by the LMS.
**
*******************************************************************************/
function doLMSInitialize()
{
writeLogEntry(_INFO, "Attempting to call LMSInitialize function");
var api = getAPIHandle();
if (api == null)
{
alert("Unable to locate the LMS's API Implementation.\nLMSInitialize was not successful.");
return "false";
}
var result = api.LMSInitialize("");
result = result.toString();
if((result != "true") && (result != "false"))
{
lmsRTEApplet.setApiConformant(false);
logMsg = "LMSInitialize did not return a CMIBoolean value.";
logMsg += "LMSInitialize returned: ""+result+"".";
writeLogEntry(_FAILED, logMsg);
terminateTest();
return;
}
if (result != "true")
{
var err = errorHandler();
writeLogEntry(_FAILED, "LMSInitialize failed");
lmsRTEApplet.setApiConformant(false);
terminateTest();
}
else
{
writeLogEntry(_PASSED, "LMSInitialize completed successfully");
}
return result;
}
/*******************************************************************************
**
** Function doLMSFinish()
** Inputs: None
** Return: CMIBoolean true if successful
** CMIBoolean false if failed.
**
** Description:
** Close communication with LMS by calling the LMSFinish
** function which will be implemented by the LMS
**
*******************************************************************************/
function doLMSFinish()
{
writeLogEntry(_INFO, "Attempting to call LMSFinish function");
var api = getAPIHandle();
if (api == null)
{
alert("Unable to locate the LMS's API Implementation.\nLMSFinish was not successful.");
return "false";
}
else
{
// call the LMSFinish function that should be implemented by the API
var result = api.LMSFinish("");
if (result.toString() != "true")
{
var err = errorHandler();
}
}
if (result == "false")
{
writeLogEntry(_FAILED, "LMSFinish Failed");
lmsRTEApplet.setApiConformant(false);
terminateTest();
}
else
{
scoStatus = "completed";
writeLogEntry(_PASSED, "LMSFinish completed successfully");
}
return result.toString();
}
/*******************************************************************************
**
** Function terminateTest()
** Inputs: None
** Return: None
**
** Description:
** This function terminates the current test when a non-conformance
** condition is encountered.
**
*******************************************************************************/
function terminateTest()
{
writeLogEntry(_TERMINATE, "The Test Subject LMS is non conformant");
teststatus.innerText = "Status: This SCO Test Terminated. Please view the log for details.";
scoStatus = "terminated";
lmsRTEApplet.setCurrentSCOStatus("terminated");
lmsRTEApplet.setSessionCompleted(true);
}
/*******************************************************************************
**
** Function handleAPINotFound()
** Inputs: None
** Return: None
**
** Description:
** This function is called when the API object is not found, or is null when a
** non-null value is expected. It logs an appropriate error and terminates the
** current test.
**
*******************************************************************************/
function handleAPINotFound()
{
writeLogEntry(_FAILED, "Unable to locate the LMS API object");
lmsRTEApplet.setApiConformant(false);
terminateTest();
}
/*******************************************************************************
**
** Function isOptionalDMElement(dmElemName)
** Inputs: dmElemName - string representing the cmi data model defined category
** or element (e.g. cmi.core.student_id)
** Return: false -> is a mandatory element
** true -> is an optional element
**
** Description:
** Determines if a data model element is mandatory or optional.
**
*******************************************************************************/
function isOptionalDMElement(dmElemName)
{
var man;
if ( dmElemName == "cmi.core._children" ||
dmElemName == "cmi.core.student_id" ||
dmElemName == "cmi.core.student_name" ||
dmElemName == "cmi.core.lesson_location" ||
dmElemName == "cmi.core.credit" ||
dmElemName == "cmi.core.lesson_status" ||
dmElemName == "cmi.core.entry" ||
dmElemName == "cmi.core.total_time" ||
dmElemName == "cmi.core.exit" ||
dmElemName == "cmi.core.session_time" ||
dmElemName == "cmi.suspend_data" ||
dmElemName == "cmi.launch_data" )
{
man = false;
}
else //it is an optional element
{
man = true;
}
return man;
}
/*******************************************************************************
**
** Function doLMSGetValue(name)
** Inputs: name - string representing the cmi data model defined category or
** element (e.g. cmi.core.student_id)
** Return: The value presently assigned by the LMS to the cmi data model
** element defined by the element or category identified by the name
** input value.
**
** Description:
** Wraps the call to the LMS LMSGetValue method
**
*******************************************************************************/
function doLMSGetValue(name)
{
var isOptional = isOptionalDMElement(name);
var logMsg = "LMSGetValue(" + name + ")";
var api = getAPIHandle();
if (api == null)
{
alert("Unable to locate the LMS's API Implementation.\nLMSGetValue was not successful.");
return "";
}
else
{
var value = api.LMSGetValue(name);
var errCode = api.LMSGetLastError().toString();
if (errCode != _NoError)
{
//display the warning or failure
if ( isOptional )
{
logMsg += " for <b>Optional</b> element resulted in the " +
"following error: " + doLMSGetErrorString(errCode);
writeLogEntry(_WARNING, logMsg);
return "";
}
else
{
logMsg += " for <b>Mandatory</b> element resulted in the " +
"following error: " + doLMSGetErrorString(errCode);
writeLogEntry(_FAILED, logMsg);
return "";
}
}
// Special cases with Empty String
else if (((name == "cmi.launch_data") ||
(name == "cmi.student_data.max_time_allowed") ||
(name == "cmi.student_data.mastery_score") ||
(name == "cmi.student_data.time_limit_action"))
&& (value == ""))
{
logMsg += " returned";
logMsg += ": " + value;
writeLogEntry(_PASSED, logMsg);
return value.toString();
}
else
{
logMsg += " returned";
if ( lmsRTEApplet.verifyElementType(name, value) != "true")
{
logMsg += " a value that is NOT of the correct datatype: ";
logMsg += "&quot;" + value + "&quot;";
writeLogEntry(_FAILED, logMsg);
return "";
}
else
{
logMsg += " a value that is of the correct datatype: " + value;
writeLogEntry(_PASSED, logMsg);
return value.toString();
}
}
}
}
/*******************************************************************************
**
** Function doLMSSetValue(name, value)
** Inputs: name -string representing the data model defined category or element
** value -the value that the named element or category will be assigned
** Return: CMIBoolean true if successful
** CMIBoolean false if failed.
**
** Description:
** Wraps the call to the LMS LMSSetValue function
**
*******************************************************************************/
function doLMSSetValue(name, value)
{
var logMsg = "LMSSetValue(" +name+ ", &quot;"+ value+"&quot;)";
var api = getAPIHandle();
if (api == null)
{
alert("Unable to locate the LMS's API Implementation.\nLMSSetValue was not successful.");
return false;
}
else
{
var result = api.LMSSetValue(name, value);
if (result.toString() != "true")
{
//If item is Optional and Not Implemented you will get a failed.
var errCode = api.LMSGetLastError();
logMsg += " resulted in the following error: ";
logMsg += apiHandle.LMSGetErrorString(errCode);
writeLogEntry(_FAILED, logMsg);
return false;
}
else
{
logMsg += " succeeded";
writeLogEntry(_PASSED, logMsg);
return true;
}
}
return;
}
/*******************************************************************************
**
** Function doLMSCommit()
** Inputs: None
** Return: None
**
** Description:
** Call the LMSCommit function
**
*******************************************************************************/
function doLMSCommit()
{
writeLogEntry(_INFO, "Attempting to call LMSCommit function");
var api = getAPIHandle();
if (api == null)
{
// if this happens - the test will already be terminating...
alert("Unable to locate the LMS's API Implementation.\nLMSCommit was not successful.");
return "false";
}
else
{
var result = api.LMSCommit("");
if (result != "true")
{
var err = errorHandler();
writeLogEntry(_FAILED, "LMSCommit Failed");
lmsRTEApplet.setApiConformant(false);
terminateTest();
}
else
{
writeLogEntry(_PASSED, "LMSCommit completed successfully");
}
}
return result.toString();
}
/*******************************************************************************
**
** Function doLMSGetLastError()
** Inputs: None
** Return: The error code that was set by the last LMS function call
**
** Description:
** Call the LMSGetLastError function
**
*******************************************************************************/
function doLMSGetLastError()
{
var api = getAPIHandle();
if (api == null)
{
alert("Unable to locate the LMS's API Implementation.\nLMSGetLastError was not successful.");
//since we can't get the error code from the LMS, return a general error
return _GeneralError;
}
return api.LMSGetLastError().toString();
}
/*******************************************************************************
**
** Function doLMSGetErrorString(errorCode)
** Inputs: errorCode - Error Code
** Return: The textual description that corresponds to the input error code
**
** Description:
** Call the LMSGetErrorString function
**
********************************************************************************/
function doLMSGetErrorString(errorCode)
{
var api = getAPIHandle();
if (api == null)
{
lmsRTEApplet.setApiConformant(false);
alert("Unable to locate the LMS's API Implementation.\nLMSGetErrorString was not successful.");
}
var errorString = api.LMSGetErrorString(errorCode).toString();
// validate that the error string is valid for the error code...
if(validateErrorString(errorCode, errorString) != true)
{
// generate a warning - not a strict conformance requirement...
var msg = "The LMS returned an invalid error string for error code: ";
msg += errorCode;
msg += "<BR>The LMS returned:<BR> ";
if(errorString == "")
{
errorString = "<i><blank></i>";
}
msg += errorString;
msg += "<BR>The LMS should have returned:<BR> ";
msg += getCorrectErrorString(errorCode);
writeLogEntry(_WARNING, msg);
}
return errorString;
}
/*******************************************************************************
**
** Function getCorrectErrorCode(errorCode)
** Inputs: errorCode - Error Code String
** Return: Error String corresponding to the errorCode if found, otherwise ""
**
** Description:
** Returns the Error String corresponding to the errorCode if found, otherwise,
** if the code is invalid, an empty string ("") is returned.
**
********************************************************************************/
function getCorrectErrorString(errorCode)
{
for(emIdx=0;emIdx<11;emIdx++)
{
if(errorMatrix[emIdx][0] == errorCode)
{
return errorMatrix[emIdx][1];
}
}
return "";
}
/*******************************************************************************
**
** Function validateErrorCode(errorCode)
** Inputs: errorCode - Error Code String to validate
** Return: true if code is valid, otherwise false
**
** Description:
** Determine if the errorCode parameter is a valid API Error Code
**
********************************************************************************/
function validateErrorCode(errorCode)
{
for(emIdx=0;emIdx<11;emIdx++)
{
if(errorMatrix[emIdx][0] == errorCode)
{
return true;
}
}
return false;
}
/*******************************************************************************
**
** Function validateErrorString(errorCode, errorString)
** Inputs: errorCode - Error Code String to use for validating error string
** errorString - Error String to validate
** Return: true if errorString is valid, otherwise false
**
** Description:
** Determine if the errorCode parameter is a valid API Error Code
**
********************************************************************************/
function validateErrorString(errorCode, errorString)
{
for(emIdx=0;emIdx<12;emIdx++)
{
if(errorMatrix[emIdx][0] == errorCode)
{
if(errorString.toLowerCase() == errorMatrix[emIdx][1].toLowerCase())
{
return true;
}
}
}
return false;
}
/*******************************************************************************
**
** Function doLMSGetDiagnostic(errorCode)
** Inputs: errorCode - Error Code(integer format), or null
** Return: The vendor specific textual description that corresponds to the
** input error code
**
** Description:
** Call the LMSGetDiagnostic function
**
*******************************************************************************/
function doLMSGetDiagnostic(errorCode)
{
var api = getAPIHandle();
if (api == null)
{
alert("Unable to locate the LMS's API Implementation.\nLMSGetDiagnostic was not successful.");
lmsRTEApplet.setApiConformant(false);
}
return api.LMSGetDiagnostic(errorCode).toString();
}
/*******************************************************************************
**
** Function errorHandler()
** Inputs: None
** Return: The current value of the LMS Error Code
**
** Description:
** Determines if an error was encountered by the previous API call
** and if so, displays a message to the user. If the error code
** has associated text it is displayed.
**
** Side Effects: Displays an alert window with the appropriate error information
**
*******************************************************************************/
function errorHandler()
{
if (_Debug)
{
alert("in errorHandler()");
}
// check for errors caused by or from the LMS
// Note: apiHandle should never be null at this point, but check to be sure
if (apiHandle != null)
{
var errCode = apiHandle.LMSGetLastError();
if (errCode != _NoError)
{
// an error was encountered so display the error description
var errDescription = apiHandle.LMSGetErrorString(errCode);
errDescription += "<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Diagnostic: ";
errDescription += apiHandle.LMSGetDiagnostic(errCode);
writeLogEntry(_FAILED, "The following error was encountered: " + errDescription);
}
return errCode;
}
else
{
writeLogEntry( _OTHER, "Unable to determine LMS Error Code. API is unexpectedly null. Terminating Test.");
terminateTest();
return _GeneralException;
}
}
/*******************************************************************************
**
** Function findAPI(win)
** Inputs: win - a Window Object
** Return: If an API object is found, it's returned, otherwise null is returned
**
** Description:
** This function looks for an object named API in parent and opener windows
**
*******************************************************************************/
function findAPI(win)
{
while ((win.API == null) && (win.parent != null) && (win.parent != win))
{
findAPITries++;
// Note: 500 is a number that comes from the new IEEE API standard.
// See rational in ticket number 3547
if (findAPITries > 500)
{
alert("Error finding API -- too deeply nested.");
return null;
}
win = win.parent;
}
return win.API;
}
/*******************************************************************************
**
** Function getAPI()
** Inputs: none
** Return: If an API object is found, it's returned, otherwise null is returned
**
** Description:
** This function looks for an object named API, first in the current window's
** frame hierarchy and then, if necessary, in the current window's opener window
** hierarchy (if there is an opener window).
**
*******************************************************************************/
function getAPI()
{
var theAPI = findAPI(window);
if ((theAPI == null) && (window.opener != null) && (typeof(window.opener) != "undefined"))
{
theAPI = findAPI(window.opener);
}
if (theAPI == null)
{
alert("Unable to find an API adapter");
}
return theAPI
}
/*******************************************************************************
**
** Function isLaunchedInOrder()
** Inputs: course - indicates the course number
** sco - indicates the sco number
** Return: boolean - false if the SCO was launched out of sequence
** true if the SCO was launched in sequence
**
** Description: This function determines if an SCO was launched in the order
** specified by the seq input value
*******************************************************************************/
function isLaunchedInOrder(course, sco)
{
if (_Debug)
{
alert("in isLaunchedInOrder - sco is" + sco);
}
var counter;
if(course == 1)
{
counter = lmsRTEApplet.getCourseOneCurrentSCOIndex();
}
else
{
counter = lmsRTEApplet.getCourseTwoCurrentSCOIndex();
}
counter++;
if (_Debug)
{
alert("just got sequence counter - incremented counter is now: " + counter);
}
if (counter+1 != sco)
{
//alert("This SCO was launched out of sequence!");
return false;
}
else
{
if(course == 1)
{
lmsRTEApplet.setCourseOneCurrentSCOIndex(counter);
}
else
{
lmsRTEApplet.setCourseTwoCurrentSCOIndex(counter);
}
return true;
}
}
/*******************************************************************************
**
** Function testLaunch(course, sco)
** Inputs: course - number of test course(1 or 2)
** sco - test sco number (e.g. 1, 2, etc.)
** Return: None
**
** Description: This function determines if an SCO was launched correctly
*******************************************************************************/
function testLaunch(course, sco)
{
if (_Debug)
{
alert("in testLaunch()");
}
if ( (course==1) && (sco==1) )
{
writeLogEntry(_NEWSCO, "*****************************");
writeLogEntry(_NEWSCO, " Executing Course 1 ");
writeLogEntry(_NEWSCO, "*****************************");
writeLogEntry(_NEWSCO, "");
}
else if ( (course==2) && (sco==1) )
{
writeLogEntry(_NEWSCO, "*****************************");
writeLogEntry(_NEWSCO, " Executing Course 2 ");
writeLogEntry(_NEWSCO, "*****************************");
writeLogEntry(_NEWSCO, "");
}
// Verify Launch Test Criteria
// If we get to this point, assume that the SCO has been launched by the LMS.
// the LMS was able to launch at least one SCO...
lmsRTEApplet.setLaunchConformant(true);
writeLogEntry(_NEWSCO, "*****************************");
writeLogEntry(_NEWSCO, " Testing SCO 0"+sco+" ");
writeLogEntry(_NEWSCO, "*****************************");
writeLogEntry(_NEWSCO, "");
var scolink = "c" + course + "s" + sco;
writeLogEntry(_OTHER, "");
writeLogEntry(_INFO, "<a name=\""+scolink+"\">*****************************");
writeLogEntry(_INFO, " SCO 0"+sco+" has been launched.");
writeLogEntry(_INFO, "*****************************</a>");
// Is this SCO launched in the specified test sequence?
writeLogEntry(_INFO, "Validating SCO launch sequence.");
if (isLaunchedInOrder(course, sco) != true)
{
// The SCO was launched in the wrong order
var launchMessage = "This SCO was not launched in the correct sequence.\n";
launchMessage += "Click OK if the SCO was launched automatically by the LMS.\n";
launchMessage += "Click Cancel if the SCO was launched by the user.";
/*if (confirm(launchMessage))
{
writeLogEntry(_FAILED, "The LMS did not launch the SCO in the appropriate sequence.");
lmsRTEApplet.setAPIConformant(false);
}
else
{*/
// must have been operator error?
writeLogEntry(_FAILED, "The operator did not launch the SCO in the appropriate sequence.");
lmsRTEApplet.setAPIConformant(false);
//}
}
else
{
writeLogEntry(_PASSED, "The SCO has been launched in the appropriate sequence.");
}
lmsRTEApplet.setCurrentSCO(course, sco-1);
}
/*******************************************************************************
**
** Function getCMIDateToday()
** Inputs: None
** Return: Current Date in CMIDate format
**
** Description:
** This function returns the current date in CMIDate format
**
*******************************************************************************/
function getCMIDateToday()
{
if(_Debug)
{
alert("In getCMIDateToday()");
}
var todayDate = new Date();
var theMonth = todayDate.getMonth();
theMonth++; // the month is zero based
if(theMonth < 10)
{
theMonth = "0" + theMonth;
}
var theDay = todayDate.getDate();
if(theDay < 10)
{
theDay = "0" + theDay;
}
var cmiDateToday = todayDate.getYear() + "/";
cmiDateToday += theMonth + "/";
cmiDateToday += theDay;
if(_Debug)
{
alert("Today's CMI Date is: "+ cmiDateToday);
}
return cmiDateToday;
}
/******************************************************************************
** Function testGetValue(name)
** Inputs: name - string representing the cmi data model defined category or
** element (e.g. cmi.core.student_id)
** index - indicates the index into the Data Model matrix to be tested
** Return: The value presently assigned by the LMS to the cmi data model
** element defined by the element or category identified by the name
** input value.
**
** Description:
** Wraps the call to the LMS LMSGetValue method.
**
******************************************************************************/
function testGetValue(name, index)
{
if(_Debug)
{
alert("in testGetValue() - name is: "+ name);
}
// handle only the readable data model elements
if(dataModelMatrix[index][1] == _W)
{
return "";
}
var logMsg = "LMSGetValue(" + name + ") ";
var value;
// assume element is not implemented correctly
dataModelMatrix[index][4] = false;
value = apiHandle.LMSGetValue(name);
err = apiHandle.LMSGetLastError();
// If the error code is something other than 0 - No Error
// Then check to see if this is a Conformance Failure
if(err != _NoError)
{
// LMS returned something other than 0 - No Error, this indicates
// an error was encountered
// If the error returned is 401 - Not Implemented or 201 - Invalid
// argument error
if (( err == _NotImplementedError) || ( err == _InvalidArgumentError))
{
// Check to see if the element being tested is mandatoy
if(dataModelMatrix[index][2] == true)
{
// Data Model element being tested is mandatory and the LMS
// did not handle the LMSGetValue() request correctly
logMsg += " for <b>Mandatory</b> element resulted in the " +
"following error: " + doLMSGetErrorString(err);
allMandatory = false;
writeLogEntry(_FAILED, logMsg);
}
else
{
// Data Model element being tested is optional and the LMS
// handle the LMSGetValue() request correctly
logMsg += " for <b>Optional</b> element resulted in the " +
"following error: " + doLMSGetErrorString(err);
allOptional = false;
writeLogEntry(_WARNING, logMsg);
}
}
else
{
// log the error
logMsg += " resulted in the following error: ";
logMsg += doLMSGetErrorString(err).toString();
writeLogEntry(_FAILED, logMsg);
return;
}
return "";
}
else
{
// a value was returned with no error - so verify the return type
logMsg += "returned";
// Special cases with Empty String
if ( ( (name == "cmi.launch_data") ||
(name == "cmi.student_data.max_time_allowed") ||
(name == "cmi.student_data.mastery_score") ||
(name == "cmi.student_data.time_limit_action") ) &&
(value == "") )
{
logMsg += ": &quot;" + value.toString() + "&quot;";
if(dataModelMatrix[index][2] != true)
{
someOptional = true;
}
// element is implemented correctly
dataModelMatrix[index][4] = true;
writeLogEntry(_PASSED, logMsg);
return value.toString();
}
else
{
// The LMS handled the call to LMSGetValue() correctly. Verify
// that the value returned by the LMS is appropriate data type
// and meets the requirements defined in the SCORM
if(lmsRTEApplet.verifyElementType(name, value) != "true")
{
// Value returned by the LMS is not the correct data type
logMsg += " a value that is NOT of the correct datatype: ";
logMsg += "&quot;" + value.toString() + "&quot;";
writeLogEntry(_FAILED, logMsg);
// If the Data Model element is mandatory
if(dataModelMatrix[index][2] == true)
{
// Set the flag that all mandatory data model elements
// were not handled correctly
allMandatory = false;
}
else
{
// Set the flag that all optional data model elements
// were not handled correctly
allOptional = false;
}
return "";
}
else
{
// LMS returned a valid value that meets the requirements
// defined in the SCORM
logMsg += ": &quot;" + value.toString() + "&quot;";
// Data model element is optional set flag indicating that
// some optional elements were implemented correctly
if(dataModelMatrix[index][2] != true)
{
someOptional = true;
}
// element is implemented correctly
dataModelMatrix[index][4] = true;
writeLogEntry(_PASSED, logMsg);
return value.toString();
}
}
}
}
/*******************************************************************************
** Function testSetValue(name, value)
** Inputs: name - string representing the cmi data model defined category or element
** value - the value that the named element or category will be assigned
** Return: None
**
** Description:
** Wraps the call to the LMS LMSSetValue method
**
*******************************************************************************/
function testSetValue(name, value, index)
{
// handle only the writeable data model elements
if(dataModelMatrix[index][1] == _R)
{
return;
}
var logMsg = "LMSSetValue(" +name+ ", &quot;"+ value+"&quot;)";
// Ask the LMS to set the data model element with the value provided
var result = apiHandle.LMSSetValue(name, value);
// If the LMSSetValue() failed determine whether or not the LMS
// handled the call correctly
if(result != "true")
{
// Get the API error code
var err = apiHandle.LMSGetLastError();
// Check the error code
if(err != _NoError)
{
// Error code was not 0 - No error (which it should not be
// since a "false" was returned by the LMS.
if((err == _NotImplementedError) ||
(err == _InvalidArgumentError))
{
// Error code was set to 401 - Not implemented or 201 - Invalid
// argument error
// Check to determine if the data model element is mandatory
if(dataModelMatrix[index][2] == true)
{
// Element was mandatory and the LMS did not handle the
// LMSSetValue() correctly
logMsg += " for <b>Mandatory</b> element resulted in the " +
"following error: " + doLMSGetErrorString(err);
allMandatory = false;
writeLogEntry(_FAILED, logMsg);
}
else
{
// Element was optional and was not handled by the LMS. Set
// the all optional flag to false to indicate that the LMS
// does not handle all optional elements
logMsg += " for <b>Optional</b> element resulted in the " +
"following error: " + doLMSGetErrorString(err);
allOptional = false;
writeLogEntry(_WARNING, logMsg);
}
return;
}
else
{
// log the error
logMsg += " resulted in the following error: ";
logMsg += doLMSGetErrorString(err).toString();
writeLogEntry(_FAILED, logMsg);
return;
}
}
}
else
{
// LMSSetValue() all was handled correctly by the LMS
// Check to see if the element is optional
if(dataModelMatrix[index][2] != true)
{
// Set a flag to indicate that some of the optional data model
// elements were handled correctly
someOptional = true;
}
}
// element is implemented correctly
dataModelMatrix[index][4] = true;
logMsg += " succeeded";
writeLogEntry(_PASSED, logMsg);
return;
}
/*******************************************************************************
** Function compareReadWriteValues(readVal, index)
** Inputs: readVal - value read from the LMS
** index - dataModelMatrix index of element
** Outputs: none
**
** Description: Determines if the value passed back from the LMS is the same
** as the value previously set by the SCO.
*******************************************************************************/
function compareReadWriteValues(readVal, index)
{
// check - only if the element is implemented correctly
if(dataModelMatrix[index][4] == true)
{
if(dataModelMatrix[index][3] != readVal)
{
var logMsg = "The LMS returned a value that is different than the ";
logMsg += "previously set value for ";
if(dataModelMatrix[index][2] == true) // mandatory element
{
logMsg += " <b>Mandatory</b> element ";
allMandatory = false;
}
else // optional element
{
logMsg += " <b>Optional</b> element ";
allOptional = false;
}
logMsg += dataModelMatrix[index][0];
logMsg += "<br>Expected value: &quot;" + dataModelMatrix[index][3];
logMsg += "&quot;<br>LMS Returned: &quot;" + readVal;
logMsg += "&quot;";
writeLogEntry(_FAILED, logMsg);
}
}
return;
}
/*******************************************************************************
** Function setDMStatus()
** Inputs: none
** Outputs: none
**
** Description:
** Persists the data model conformance state values after a SCO is done testing
** data model elements
*******************************************************************************/
function setDMStatus()
{
if(someOptional == true)
{
lmsRTEApplet.setDMSomeOptional(true);
}
if(allOptional == false)
{
lmsRTEApplet.setDMAllOptional(false);
}
if(allMandatory == false)
{
lmsRTEApplet.setDMMandatory(false);
}
}
/*******************************************************************************
**
** Function convertTotalTime(course, sco)
** Inputs: totalTime - value of cmi.core.total_time in the calling fuction
** Return: value in Milliseconds
**
** Description: Convert totalTime to seconds, with the tenths and hundreds of
** inputted seconds returned as the decimal portion of the return.
*******************************************************************************/
function convertTotalTime(totalTime)
{
var lTotalTime = 0.0;
var numArray;
var hourVal, minVal, secVal;
numArray = totalTime.split(":");
hourVal = parseFloat(numArray[0]);
hourVal *= 3600; //3600 equals 60 times 60 (hours times minutes)
minVal = parseFloat(numArray[1]);
minVal *= 60;
secVal = parseFloat(numArray[2]);
lTotalTime = hourVal + minVal + secVal;
return lTotalTime;
}
/*******************************************************************************
**
** Function timeCompare(course, sco)
** Inputs: time1 - Value of first time to compare
** time2 - Value to compare against time1
** Return: Boolean value: True - They are equal
** False - They are NOT equal
**
** Description: Compare time1 against time2
*******************************************************************************/
function timeCompare(time1, time2)
{
var convertedTime1, convertedTime2;
convertedTime1 = convertTotalTime(time1);
convertedTime2 = convertTotalTime(time2);
if (convertedTime1 == convertedTime2)
{
return true;
}
else
{
return false;
}
}
/*******************************************************************************
**
** Function stripCharsInBag(s, bag)
** Inputs: s - String to check
** bag - character that you're checking to see if it exists
** Return: String without any of the characters passed in as argument 'bag'
**
** Description: Strips the character 'bag' from the string.
*******************************************************************************/
function stripCharsInBag (s, bag)
{
var i;
var returnString = "";
for (i = 0; i < s.length; i++)
{
var c = s.charAt(i);
if (bag.indexOf(c) == -1) returnString += c;
}
return returnString;
}
/*******************************************************************************
**
** Function stripWhitespace (s)
** Inputs: s - String that you wish to strip the whitepsace from.
** Return: String without any whitespace
**
** Description: By calling stripCharsInBag with the argument 'whitespace' this
** function strips any whitespace from the string.
*******************************************************************************/
function stripWhitespace (s)
{
var whitespace = " \t\n\r";
return stripCharsInBag (s, whitespace)
}
/*******************************************************************************
**
** Function nameCompare(course, sco)
** Inputs: name1 - Value of first name to compare
** name2 - Value to compare against name1
** Return: Boolean value: True - They are equal
** False - They are NOT equal
**
** Description: Compare name1 against name2. It is expected that the format
** of the name is lastname,firstname.
*******************************************************************************/
function nameCompare(name1, name2)
{
var nameArray1, nameArray2;
//Various whitespace characters
var re = /[ \t\r\n]*/g;
if ( name1.indexOf(",") == -1 )
{
return false;
}
//After the .split the [0] element will contain the Last Name of the Student
//and the [1] element will contain the First Name of the Student
nameArray1 = name1.split(",");
nameArray2 = name2.split(",");
//Remove whitespace characters
nameArray1[0] = nameArray1[0].replace(re,"");
nameArray1[1] = nameArray1[1].replace(re,"");
nameArray2[0] = nameArray2[0].replace(re,"");
nameArray2[1] = nameArray2[1].replace(re,"");
//If both first names match AND both last names match return true
if ((nameArray1[0].toUpperCase() == nameArray2[0].toUpperCase()) &&
(nameArray1[1].toUpperCase() == nameArray2[1].toUpperCase()))
{
return true;
}
else
{
return false;
}
}
/*******************************************************************************
**
** Function doLMSSetValueNoPrint(name, value)
** Inputs: name -string representing the data model defined category or element
** value -the value that the named element or category will be assigned
** Return: CMIBoolean true if successful
** CMIBoolean false if failed.
**
** Description:
** Wraps the call to the LMS LMSSetValue function. Unlike doLMSSetValue, this
** function does not print a message to the log.
**
*******************************************************************************/
function doLMSSetValueNoPrint(name, value)
{
var api = getAPIHandle();
if (api == null)
{
alert("Unable to locate the LMS's API Implementation.\nLMSSetValue was not successful.");
return false;
}
else
{
var result = api.LMSSetValue(name, value);
if (result.toString() != "true")
{
return false;
}
else
{
return true;
}
}
}
/*******************************************************************************
**
** Function: doLMSInitializeTest()
** Inputs: None
** Return: CMIBoolean true if the initialization was successful, or
** CMIBoolean false if the initialization failed.
**
** Description:
** Same as the doLMSInitialize() function, but is called only the first
** time LMSInitialize is invoked - determines if the method exists and, if not,
** catches the exception and reports that as an error.
** Initialize communication with LMS by calling the LMSInitialize
** function which will be implemented by the LMS.
**
*******************************************************************************/
function doLMSInitializeTest()
{
writeLogEntry(_INFO, "Attempting to call LMSInitialize function");
var api = getAPIHandle();
if (api == null)
{
alert("Unable to locate the LMS's API Implementation.\nLMSInitialize was not successful.");
return "false";
}
var result = "";
var passed = true;
try
{
result = api.LMSInitialize("");
}
catch(e)
{
passed = false;
}
if (passed == true)
{
writeLogEntry(_PASSED, "LMSInitialize found.");
}
else
{
writeLogEntry(_FAILED, "LMSInitialize NOT found.");
lmsRTEApplet.setApiConformant(false);
terminateTest();
}
result = result.toString();
if((result != "true") && (result != "false"))
{
lmsRTEApplet.setApiConformant(false);
logMsg = "LMSInitialize did not return a CMIBoolean value.";
logMsg += "LMSInitialize returned: &quot;"+result+"&quot;.";
writeLogEntry(_FAILED, logMsg);
terminateTest();
return;
}
if (result != "true")
{
var err = errorHandler();
writeLogEntry(_FAILED, "LMSInitialize failed");
lmsRTEApplet.setApiConformant(false);
terminateTest();
}
else
{
writeLogEntry(_PASSED, "LMSInitialize completed successfully");
}
return result;
}
/*******************************************************************************
**
** Function doLMSFinishTest()
** Inputs: None
** Return: CMIBoolean true if successful
** CMIBoolean false if failed.
**
** Description:
** Same as the doLMSFinish() function, but is called only the first
** time LMSFinish is invoked - determines if the method exists and, if not,
** catches the exception and reports that as an error.
** Close communication with LMS by calling the LMSFinish
** function which will be implemented by the LMS
**
*******************************************************************************/
function doLMSFinishTest()
{
writeLogEntry(_INFO, "Attempting to call LMSFinish function");
var api = getAPIHandle();
if (api == null)
{
alert("Unable to locate the LMS's API Implementation.\nLMSFinish was not successful.");
return "false";
}
else
{
// call the LMSFinish function that should be implemented by the API
var result = "";
var passed = true;
try
{
result = api.LMSFinish("");
}
catch(e)
{
passed = false;
}
if (passed == true)
{
writeLogEntry(_PASSED, "LMSFinish found.");
}
else
{
writeLogEntry(_FAILED, "LMSFinish NOT found.");
lmsRTEApplet.setApiConformant(false);
terminateTest();
}
if (result.toString() != "true")
{
var err = errorHandler();
}
}
if (result == "false")
{
writeLogEntry(_FAILED, "LMSFinish Failed");
lmsRTEApplet.setApiConformant(false);
terminateTest();
}
else
{
scoStatus = "completed";
writeLogEntry(_PASSED, "LMSFinish completed successfully");
}
return result.toString();
}
/******************************************************************************
** Function testGetValueTest(name)
** Inputs: name - string representing the cmi data model defined category or
** element (e.g. cmi.core.student_id)
** index - indicates the index into the Data Model matrix to be tested
** Return: The value presently assigned by the LMS to the cmi data model
** element defined by the element or category identified by the name
** input value.
**
** Description:
** Same as the testGetValue() function, but is called only the first
** time LMSGetValue is invoked - determines if the method exists and, if not,
** catches the exception and reports that as an error.
** Wraps the call to the LMS LMSGetValue method.
**
******************************************************************************/
function testGetValueTest(name, index)
{
if(_Debug)
{
alert("in testGetValue() - name is: "+ name);
}
// handle only the readable data model elements
if(dataModelMatrix[index][1] == _W)
{
return "";
}
var logMsg = "LMSGetValue(" + name + ") ";
var value;
// assume element is not implemented correctly
dataModelMatrix[index][4] = false;
var value = "";
var passed = true;
try
{
value = apiHandle.LMSGetValue(name);
}
catch(e)
{
passed = false;
}
if (passed == true)
{
writeLogEntry(_PASSED, "LMSGetValue found.");
}
else
{
writeLogEntry(_FAILED, "LMSGetValue NOT found.");
lmsRTEApplet.setApiConformant(false);
terminateTest();
}
err = apiHandle.LMSGetLastError();
// If the error code is something other than 0 - No Error
// Then check to see if this is a Conformance Failure
if(err != _NoError)
{
// LMS returned something other than 0 - No Error, this indicates
// an error was encountered
// If the error returned is 401 - Not Implemented or 201 - Invalid
// argument error
if (( err == _NotImplementedError) || ( err == _InvalidArgumentError))
{
// Check to see if the element being tested is mandatoy
if(dataModelMatrix[index][2] == true)
{
// Data Model element being tested is mandatory and the LMS
// did not handle the LMSGetValue() request correctly
logMsg += " for <b>Mandatory</b> element resulted in the " +
"following error: " + doLMSGetErrorString(err);
allMandatory = false;
writeLogEntry(_FAILED, logMsg);
}
else
{
// Data Model element being tested is optional and the LMS
// handle the LMSGetValue() request correctly
logMsg += " for <b>Optional</b> element resulted in the " +
"following error: " + doLMSGetErrorString(err);
allOptional = false;
writeLogEntry(_WARNING, logMsg);
}
}
else
{
// log the error
logMsg += " resulted in the following error: ";
logMsg += doLMSGetErrorString(err).toString();
writeLogEntry(_FAILED, logMsg);
return;
}
return "";
}
else
{
// a value was returned with no error - so verify the return type
logMsg += "returned";
// Special cases with Empty String
if ( ( (name == "cmi.launch_data") ||
(name == "cmi.student_data.max_time_allowed") ||
(name == "cmi.student_data.mastery_score") ||
(name == "cmi.student_data.time_limit_action") ) &&
(value == "") )
{
logMsg += ": &quot;" + value.toString() + "&quot;";
if(dataModelMatrix[index][2] != true)
{
someOptional = true;
}
// element is implemented correctly
dataModelMatrix[index][4] = true;
writeLogEntry(_PASSED, logMsg);
return value.toString();
}
else
{
// The LMS handled the call to LMSGetValue() correctly. Verify
// that the value returned by the LMS is appropriate data type
// and meets the requirements defined in the SCORM
if(lmsRTEApplet.verifyElementType(name, value) != "true")
{
// Value returned by the LMS is not the correct data type
logMsg += " a value that is NOT of the correct datatype: ";
logMsg += "&quot;" + value.toString() + "&quot;";
writeLogEntry(_FAILED, logMsg);
// If the Data Model element is mandatory
if(dataModelMatrix[index][2] == true)
{
// Set the flag that all mandatory data model elements
// were not handled correctly
allMandatory = false;
}
else
{
// Set the flag that all optional data model elements
// were not handled correctly
allOptional = false;
}
return "";
}
else
{
// LMS returned a valid value that meets the requirements
// defined in the SCORM
logMsg += ": &quot;" + value.toString() + "&quot;";
// Data model element is optional set flag indicating that
// some optional elements were implemented correctly
if(dataModelMatrix[index][2] != true)
{
someOptional = true;
}
// element is implemented correctly
dataModelMatrix[index][4] = true;
writeLogEntry(_PASSED, logMsg);
return value.toString();
}
}
}
}
/*******************************************************************************
** Function testSetValueTest(name, value)
** Inputs: name - string representing the cmi data model defined category or element
** value - the value that the named element or category will be assigned
** Return: None
**
** Description:
** Same as the testSetValue() function, but is called only the first
** time LMSSetValue is invoked - determines if the method exists and, if not,
** catches the exception and reports that as an error.
** Wraps the call to the LMS LMSSetValue method
**
*******************************************************************************/
function testSetValueTest(name, value, index)
{
// handle only the writeable data model elements
if(dataModelMatrix[index][1] == _R)
{
return;
}
var logMsg = "LMSSetValue(" +name+ ", &quot;"+ value+"&quot;)";
var result = "";
var passed = true;
try
{
// Ask the LMS to set the data model element with the value provided
result = apiHandle.LMSSetValue(name, value);
}
catch(e)
{
passed = false;
}
if (passed == true)
{
writeLogEntry(_PASSED, "LMSSetValue found.");
}
else
{
writeLogEntry(_FAILED, "LMSSetValue NOT found.");
lmsRTEApplet.setApiConformant(false);
terminateTest();
}
// If the LMSSetValue() failed determine whether or not the LMS
// handled the call correctly
if(result.toString() != "true")
{
// Get the API error code
var err = apiHandle.LMSGetLastError();
// Check the error code
if(err != _NoError)
{
// Error code was not 0 - No error (which it should not be
// since a "false" was returned by the LMS.
if((err == _NotImplementedError) ||
(err == _InvalidArgumentError))
{
// Error code was set to 401 - Not implemented or 201 - Invalid
// argument error
// Check to determine if the data model element is mandatory
if(dataModelMatrix[index][2] == true)
{
// Element was mandatory and the LMS did not handle the
// LMSSetValue() correctly
logMsg += " for <b>Mandatory</b> element resulted in the " +
"following error: " + doLMSGetErrorString(err);
allMandatory = false;
writeLogEntry(_FAILED, logMsg);
}
else
{
// Element was optional and was not handled by the LMS. Set
// the all optional flag to false to indicate that the LMS
// does not handle all optional elements
logMsg += " for <b>Optional</b> element resulted in the " +
"following error: " + doLMSGetErrorString(err);
allOptional = false;
writeLogEntry(_WARNING, logMsg);
}
return;
}
else
{
// log the error
logMsg += " resulted in the following error: ";
logMsg += doLMSGetErrorString(err).toString();
writeLogEntry(_FAILED, logMsg);
return;
}
}
}
else
{
// LMSSetValue() all was handled correctly by the LMS
// Check to see if the element is optional
if(dataModelMatrix[index][2] != true)
{
// Set a flag to indicate that some of the optional data model
// elements were handled correctly
someOptional = true;
}
}
// element is implemented correctly
dataModelMatrix[index][4] = true;
logMsg += " succeeded";
writeLogEntry(_PASSED, logMsg);
return;
}
/*******************************************************************************
**
** Function doLMSCommitTest()
** Inputs: None
** Return: None
**
** Description:
** Same as the doLMSCommit() function, but is called only the first
** time LMSCommit is invoked - determines if the method exists and, if not,
** catches the exception and reports that as an error.
** Call the LMSCommit function
**
*******************************************************************************/
function doLMSCommitTest()
{
writeLogEntry(_INFO, "Attempting to call LMSCommit function");
var api = getAPIHandle();
if (api == null)
{
// if this happens - the test will already be terminating...
alert("Unable to locate the LMS's API Implementation.\nLMSCommit was not successful.");
return "false";
}
else
{
var result = "";
var passed = true;
try
{
result = api.LMSCommit("");
}
catch(e)
{
passed = false;
}
if (passed == true)
{
writeLogEntry(_PASSED, "LMSCommit found.");
}
else
{
writeLogEntry(_FAILED, "LMSCommit NOT found.");
lmsRTEApplet.setApiConformant(false);
terminateTest();
}
if (result != "true")
{
var err = errorHandler();
writeLogEntry(_FAILED, "LMSCommit Failed");
lmsRTEApplet.setApiConformant(false);
terminateTest();
}
else
{
writeLogEntry(_PASSED, "LMSCommit completed successfully");
}
}
return result.toString();
}
/*******************************************************************************
**
** Function doLMSGetLastErrorTest()
** Inputs: None
** Return: The error code that was set by the last LMS function call
**
** Description:
** Same as the doLMSGetLastError() function, but is called only the first
** time LMSGetLastError is invoked - determines if the method exists and, if
** not,catches the exception and reports that as an error.
** Call the LMSGetLastError function
**
*******************************************************************************/
function doLMSGetLastErrorTest()
{
var api = getAPIHandle();
if (api == null)
{
alert("Unable to locate the LMS's API Implementation.\nLMSGetLastError was not successful.");
//since we can't get the error code from the LMS, return a general error
return _GeneralError;
}
var errorCode = "";
var passed = true;
try
{
errorCode = api.LMSGetLastError();
}
catch(e)
{
passed = false;
}
if (passed == true)
{
writeLogEntry(_PASSED, "LMSGetLastError found.");
}
else
{
writeLogEntry(_FAILED, "LMSGetLastError NOT found.");
lmsRTEApplet.setApiConformant(false);
terminateTest();
}
return errorCode.toString();
}
/*******************************************************************************
**
** Function doLMSGetErrorStringTest(errorCode)
** Inputs: errorCode - Error Code
** Return: The textual description that corresponds to the input error code
**
** Description:
** Same as the doLMSGetErrorString() function, but is called only the first
** time LMSGetErrorString is invoked - determines if the method exists and, if\
** not, catches the exception and reports that as an error.
** Call the LMSGetErrorString function
**
********************************************************************************/
function doLMSGetErrorStringTest(errorCode)
{
var api = getAPIHandle();
if (api == null)
{
lmsRTEApplet.setApiConformant(false);
alert("Unable to locate the LMS's API Implementation.\nLMSGetErrorString was not successful.");
}
var errorString = "";
var passed = true;
try
{
errorString = api.LMSGetErrorString(errorCode).toString();
}
catch(e)
{
passed = false;
}
if (passed == true)
{
writeLogEntry(_PASSED, "LMSGetErrorString found.");
}
else
{
writeLogEntry(_FAILED, "LMSGetErrorString NOT found.");
lmsRTEApplet.setApiConformant(false);
terminateTest();
}
// validate that the error string is valid for the error code...
if(validateErrorString(errorCode, errorString) != true)
{
// generate a warning - not a strict conformance requirement...
var msg = "The LMS returned an invalid error string for error code: ";
msg += errorCode;
msg += "<BR>The LMS returned:<BR> ";
if(errorString == "")
{
errorString = "<i><blank></i>";
}
msg += errorString;
msg += "<BR>The LMS should have returned:<BR> ";
msg += getCorrectErrorString(errorCode);
writeLogEntry(_WARNING, msg);
}
return errorString;
}
/*******************************************************************************
**
** Function doLMSGetDiagnosticTest(errorCode)
** Inputs: errorCode - Error Code(integer format), or null
** Return: The vendor specific textual description that corresponds to the
** input error code
**
** Description:
** Same as the the doLMSGetDiagnostic() function, but is called only the first
** time LMSGetDiagnostic is invoked - determines if the method exists and, if
** not,catches the exception and reports that as an error.
** Call the LMSGetDiagnostic function
**
*******************************************************************************/
function doLMSGetDiagnosticTest(errorCode)
{
var api = getAPIHandle();
if (api == null)
{
alert("Unable to locate the LMS's API Implementation.\nLMSGetDiagnostic was not successful.");
lmsRTEApplet.setApiConformant(false);
}
var result = "";
var passed = true;
try
{
result = api.LMSGetDiagnostic(errorCode);
}
catch(e)
{
passed = false;
}
if (passed == true)
{
writeLogEntry(_PASSED, "LMSGetDiagnostic found.");
}
else
{
writeLogEntry(_FAILED, "LMSGetDiagnostic NOT found.");
lmsRTEApplet.setApiConformant(false);
terminateTest();
}
return result.toString();
}
<?php
/*
* This file is continuously made an AJAX call.
* It reads the test status from the temporary file
* saved in the data root and prints its contents.
*/
require_once("../../config.php");
$myFile = $CFG->dataroot.'/temp/scormtesting/scormtestStatus.txt';
$fh = fopen($myFile, 'r');
$output = "";
while(!feof($fh)) {
$temp = fgets($fh);
$temp = trim($temp, '"');
$temp = explode('.', $temp);
if($temp[0] && $temp[1]){
$output .= '<div id="SCO'.$temp[0].'">'.$temp[1].'</div> <br />';
}
}
echo $output;
?>
<!doctype html public "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
<html>
<script language="JAVASCRIPT">
/*******************************************************************************
** Filename: sco04.htm
**
** File Description: ADL SCORM Test Course I - SCO 04 - Tests the LMS's:
** Launch Conformance
** API implementation Conformance - specifically ability of LMS
** to save/persist data model state across "sessions".
**
**
** Author: CTC ADL Project Team
**
** Contract Number:
** Company Name: CTC
**
** Module/Package Name:
** Module/Package Description:
**
** Design Issues:
** Implementation Issues:
**
** Known Problems:
** Side Effects:
**
** References: ADL SCORM
**
**
/*******************************************************************************
**
** The Advanced Distributed Learning Co-Laboratory (ADL Co-Lab) grants you
** ("Licensee") a non-exclusive, royalty free, license to use, modify and
** redistribute this software in source and binary code form, provided that
** i) this copyright notice and license appear on all copies of the software;
** and ii) Licensee does not utilize the software in a manner which is
** disparaging to ADL Co-Lab.
**
** This software is provided "AS IS," without a warranty of any kind. ALL
** EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
** IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-
** INFRINGEMENT, ARE HEREBY EXCLUDED. ADL Co-Lab AND ITS LICENSORS SHALL NOT BE
** LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
** OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL ADL Co-Lab
** OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
** DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES,
** HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE
** USE OF OR INABILITY TO USE SOFTWARE, EVEN IF ADL Co-Lab HAS BEEN ADVISED OF
** THE POSSIBILITY OF SUCH DAMAGES.
**
**
** Date Changed Author Reason for Changes
** ------------ ---------------- -------------------------------------------
** 05/17/2001 S.Thropp PT 874: Removed the <param name = codebase
** from the applet
**
** 07/03/2001 Jeff Falls PT 964: Modified to be entered 3 times vice
** the previous 2 times. A set to
** cmi.core.session_time is called in the first
** two entries. In the third entry,
** cmi.core.total_time is checked for the
** accumulation of this time.
**
** 10/5/2001 Bill Capone PT 1217 & 1233: Added calls to newly created
** function timeCompare().
**
** 11/27/2001 Jeff Falls Fixed the test for correct use of "credit"
** and "no-credit"
**
** 01/09/2002 Bill Capone Check cmi.core.entry after setting
** cmi.core.exit to something other than
** "suspend". This is to satisfy Version 1.2
** Conformance Requirements 1.7.2.
**
** 01/16/2002 Bill Capone Removed code that satisfied LMS Requirements
** 1.6.6 as that code was causing the Test
** Suite to NOT re-enter sco04.
**
** 03/07/2002 Bill Capone PT 1763: Changed the set for lesson_status
** from failed to completed. Change occurred
** in visit==2 in performTest().
**
/*******************************************************************************/
</script>
<head>
<meta http-equiv="expires" content="Tue, 20 Aug 1999 01:00:00 GMT">
<meta http-equiv="Pragma" content="no-cache">
<script language=JAVASCRIPT src="lmsrtefunctions.js"></script>
<script language=JAVASCRIPT>
// Define data model related variables and constants
var visit = 0;
/*******************************************************************************
**
** Function performTest()
** Inputs: None
** Return: None
**
** Description:
** This function is the main test driver for this SCO.
**
*******************************************************************************/
function performTest()
{
var prevSCO = lmsRTEApplet.getCourseOneCurrentSCOIndex();
// Used to get the cmi.core.total_time and compare
var time;
lmsRTEApplet.setCurrentSCO(1, 3); // fourth SCO of course I
// Is this the first or second time in here?
visit = lmsRTEApplet.getCurrentSCOLaunchCount();
if(_Debug)
{
alert("previous visits to this sco: "+visit);
}
// Display some status indicator that lets us know which entry into
// this SCO the test suite thinks this is...
if(visit == 0)
{
writeLogEntry(_NEWSCO, "");
writeLogEntry(_NEWSCO, "*****************************");
writeLogEntry(_NEWSCO, " Testing SCO 04 ");
writeLogEntry(_NEWSCO, "*****************************");
// first time launch of this SCO...
writeLogEntry(_OTHER, "");
writeLogEntry(_INFO, "<a name=\"c1s4\">*****************************");
writeLogEntry(_INFO, " SCO 04 has been launched.");
writeLogEntry(_INFO, "*****************************</a>");
writeLogEntry(_INFO, "Validating SCO launch sequence.");
// Previous SCO should be SCO 3 (index 2)
if(prevSCO != 2)
{
// The SCO was launched in the wrong order
var launchMessage = "This SCO was not launched in the correct sequence.\n";
launchMessage += "Click OK if the SCO was launched automatically by the LMS.\n";
launchMessage += "Click Cancel if the SCO was launched by the user.";
//if(confirm(launchMessage))
//{
writeLogEntry(_FAILED, "The LMS did not launch the SCO in the appropriate sequence.");
lmsRTEApplet.setApiConformant(false);
//}
/*else
{
// must have been operator error?
writeLogEntry(_FAILED, "The operator did not launch the SCO in the appropriate sequence.");
lmsRTEApplet.setApiConformant(false);
}*/
}
else
{
writeLogEntry(_PASSED, "The SCO has been launched in the appropriate sequence.");
}
// Set up the API for the SCO to start communication
setAPIHandle(null);
// setAPIHandle() may have set the overall SCO status to terminated, if
// so end the test and return
if(scoStatus == "terminated")
{
return;
}
// Initialize the SCO communication
var result = doLMSInitialize();
// doLMSInitialize() may have set the overall SCO status to terminated, if
// so end the test and return
if(scoStatus == "terminated")
{
return;
}
// Get the cmi.core.entry. Test to make sure that the LMS set the
// cmi.core.entry to ab-initio. This is the first time in the SCO
result = doLMSGetValue("cmi.core.entry");
if(result != "ab-initio")
{
writeLogEntry(_FAILED, "Expected cmi.core.entry value of &quot;ab-initio&quot;");
allMandatory = false;
}
// Set some data model values that will be used to verify persistence
result = doLMSSetValue("cmi.core.lesson_location", "#paragraph3");
result = doLMSSetValue("cmi.core.lesson_status", "incomplete");
result = doLMSSetValue( "cmi.core.exit", "logout" );
result = doLMSSetValue("cmi.core.session_time", "03:01:39.52");
result = doLMSSetValue("cmi.suspend_data", "A=1,B=2,C=3");
setDMStatus();
var resultCommit = "";
// Ask the LMS to persist all data
resultCommit = doLMSCommit();
teststatus.innerText = "Status: Step 1 of SCO Test Completed. Please Log out and re-login to the LMS.";
visit++;
lmsRTEApplet.setCurrentSCOLaunchCount(visit);
//alert("Part I of this test SCO is complete. Please log out of the LMS, then return to this SCO to complete the test.");
var resultFinish = "";
// Invoke the LMSFinish()
resultFinish = doLMSFinish();
}
else if(visit == 1)
{
// second entry into this SCO...
teststatus.innerText = "Status: (Step 2) Testing in progress...";
writeLogEntry(_OTHER, "");
writeLogEntry(_OTHER, "");
writeLogEntry(_INFO, "This appears to be the second entry into SCO04");
setAPIHandle(null);
if(scoStatus == "terminated")
{
return;
}
var result = doLMSInitialize();
if(scoStatus == "terminated")
{
return;
}
// get previously set element values to determine if the values match
// thereby indicating whether or not the LMS can save data element values
// across user (student) sessions...
writeLogEntry( _INFO, "Testing to determine LMS ability to save state for mandatory items across sessions");
var loc = doLMSGetValue("cmi.core.lesson_location");
if(loc != "#paragraph3")
{
writeLogEntry(_FAILED, "cmi.core.lesson_location value does not match previously set value");
allMandatory = false;
writeLogEntry(_FAILED, "Assuming that LMSCommit and/or LMSFinish call in step 1 of this SCO did not persist the value");
lmsRTEApplet.setApiConformant(false);
}
else
{
writeLogEntry(_PASSED, "cmi.core.lesson_location value matches previously set value");
}
var suspendData = doLMSGetValue("cmi.suspend_data");
if(suspendData != "A=1,B=2,C=3")
{
writeLogEntry(_FAILED, "cmi.suspend_data value does not match previously set value");
allMandatory = false;
writeLogEntry(_FAILED, "Assuming that LMSCommit and/or LMSFinish call in step 1 of this SCO did not persist the value");
lmsRTEApplet.setApiConformant(false);
}
else
{
writeLogEntry(_PASSED, "cmi.suspend_data value matches previously set value");
}
time = doLMSGetValue("cmi.core.total_time");
var expectedTime = "03:01:39.52";
if (timeCompare(time, expectedTime) == true)
{
writeLogEntry( _PASSED, "cmi.core.total_time returned correctly");
}
else
{
writeLogEntry( _FAILED, "Expected cmi.core.total_time of &quot;03:01:39.52&quot;");
allMandatory = false;
}
result = doLMSSetValue("cmi.core.lesson_status", "incomplete");
result = doLMSSetValue( "cmi.core.exit", "suspend" );
doLMSSetValue("cmi.core.session_time", "00:12:48.22");
result = doLMSGetValue("cmi.core.entry");
if(result != "")
{
writeLogEntry(_FAILED, "Expected cmi.core.entry value of &quot;&quot;");
allMandatory = false;
}
setDMStatus();
var resultCommit = "";
resultCommit = doLMSCommit();
teststatus.innerText = "Status: Step 2 of SCO Test Completed. Please Log out and re-login to the LMS.";
visit ++;
lmsRTEApplet.setCurrentSCOLaunchCount(visit);
//alert("Part 2 of this test SCO is complete. Please log out of the LMS, then return to this SCO to complete the test.");
var resultFinish = "";
resultFinish = doLMSFinish();
}
else if(visit == 2)
{
teststatus.innerText = "Status: (Step 3) Testing in progress...";
writeLogEntry(_OTHER, "");
writeLogEntry(_OTHER, "");
writeLogEntry(_INFO, "This appears to be the third entry into SCO04");
setAPIHandle(null);
if(scoStatus == "terminated")
{
return;
}
var result = doLMSInitialize();
if(scoStatus == "terminated")
{
return;
}
// get previously set element values to determine if the values match
// thereby indicating whether or not the LMS can save data element values
// across user (student) sessions...
writeLogEntry( _INFO, "Testing to determine LMS ability to save state for mandatory items across sessions");
time = doLMSGetValue("cmi.core.total_time");
var expectedTime = "03:14:27.74";
if (timeCompare(time, expectedTime))
{
writeLogEntry( _PASSED, "cmi.core.total_time returned correctly");
}
else
{
writeLogEntry( _FAILED, "Expected cmi.core.total_time of &quot;03:14:27.74&quot;");
allMandatory = false;
}
var credit = doLMSGetValue("cmi.core.credit");
doLMSSetValue("cmi.core.lesson_status", "completed");
if(credit == "credit")
{
doLMSSetValue("cmi.core.score.raw", "25");
}
else if (credit == "no-credit")
{
writeLogEntry(_WARNING, "The instructions specified that this test course should be taken for &quot;credit&quot;");
}
else
{
writeLogEntry(_FAILED, "cmi.core.credit must be set to either credit or no-credit");
allMandatory = false;
}
doLMSSetValue("cmi.core.exit", "" );
setDMStatus();
var resultCommit = "";
resultCommit = doLMSCommit();
lmsRTEApplet.setCurrentSCOStatus("completed");
teststatus.innerText = "Status: Step 3 Complete. This SCO Test Completed.";
visit ++;
lmsRTEApplet.setCurrentSCOLaunchCount(visit);
//alert("Completing testing. Please launch the next SCO.");
var resultFinish = "";
resultFinish = doLMSFinish();
}
else
{
writeLogEntry(_FAILED, "The SCO launch sequence could not be determined");
lmsRTEApplet.setApiConformant(false);
terminateTest();
}
}
</script>
<title>ADL SCORM Version 1.2 LMS Run-Time Environment Test - Course I - SCO #04</title>
</head>
<body onload="performTest();">
<object classid=clsid:8AD9C840-044E-11D1-b3e9-00805F499D93
codebase="http://java.sun.com/products/plugin/1.3/jinstall-13-win32.cab#Version=1,3,0,0"
height="1" width="1" id=lmsRTEApplet>
<param name="name" value="lmsRTEApplet">
<param name="code" value="org/adl/testsuite/rte/lms/LMSRTEApplet.class">
<param name="type" value="application/x-java-applet;version=1.3">
<param name="mayscript" value="true">
<param name="scriptable" value="true">
<param name="archive" value="LMSTestCourse.jar">
</object>
<p align="left">
<font color="#353889" size="5">
ADL SCORM&reg; Version 1.2 LMS Run-Time Environment Test<br /><br />
ADL SCORM Test Course I - SCO #04<br />
<br />
<br />
<div id=teststatus>
<strong>Status:&nbsp;&nbsp;Testing in progress...</strong>
</div>
</font>
<br />
<hr color="#353889">
<br />
<p>
</p>
<p>
Please view the ADL test suite log for detailed progress and status information
for this test.
</p>
<p>
This test may take several minutes to complete. Please be patient!
</p>
<p>
This SCO has three parts. The user is required to exit the course and log out of
the LMS after part one and two are completed, and then log back in and resume
the course. Depending upon the functionality of the LMS, this SCO may or may
not be unloaded automatically upon conclusion of the testing performed by the
SCO. When the SCO completes, the status indicator (above) will change. If the
LMS does not automatically control navigation and sequencing of SCOs, then
please exit the LMS after steps 1 and 2 are completed. After Step 3 is
completed, please go to SCO 05.
</p>
<p>
This Sharable Content Object (SCO) tests the Learning Management System for
conformance with the Runtime Environment Guidelines as described in the SCORM.
The purpose of this SCO is to determine if the LMS has the ability to save data
model element values across user sessions and make the values available upon
student re-entry. Specifically, this SCO performs the following:
</p>
<br />
<hr color="#353889">
<br />
<p align="left">
<em><strong>Upon First Entry</strong>: </em>
</p>
<ol>
<ol>
<li>
<div align="left">
Validates that this SCO was launched in the appropriate sequence (fourth)
</div>
</li>
<li>
<div align="left">
Locates the LMS's API implementation
</div>
</li>
<li>
<div align="left">
Calls the LMSInitialize function
</div>
</li>
<li>
<div align="left">
Verifies expected initial values for the following data model elements:
</div>
</li>
<ul>
<li>"cmi.core.entry"</li>
</ul>
<li>
<div align="left">
Automatically sets the following values to these data elements:
</div>
</li>
<ul>
<li>
<div align="left">
LMSSetValue("cmi.core.lesson_location", "#paragraph3");
</div>
</li>
<li>
<div align="left">
LMSSetValue("cmi.core.lesson_status", "incomplete");
</div>
</li>
<li>
<div align="left">
LMSSetValue("cmi.core.exit", "logout");
</div>
</li>
<li>
<div align="left">
LMSSetValue("cmi.core.session_time", "03:01:39.52");
</div>
</li>
<li>
<div align="left">
LMSSetValue("cmi.core.suspend_data", "A=1,B=2,C=3");
</div>
</li>
</ul>
<li>
<div align="left">
Calls the LMSCommit function
</div>
</li>
<li>
<div align="left">
Calls the LMSFinish function
</div>
</li>
</ol>
</ol>
<br />
<hr color="#353889">
<br />
<p align="left">
<strong><em>Upon Second Entry: </em></strong>
</p>
<ol style="MARGIN-RIGHT: 0px">
<ol>
<li>
<div align="left">
Locates the LMS's API implementation
</div>
</li>
<li>
<div align="left">
Calls the LMSInitialize function
</div>
</li>
<li>
<div align="left">
Calls the LMSGetValue function for the following previously set
data model elements and compares them with the expected values:
</div>
</li>
<ul>
<li>"cmi.core.lesson_location"</li>
<li>"cmi.suspend_data"</li>
<li>"cmi.core.total_time"</li>
<li>"cmi.core.lesson_status"</li>
<li>"cmi.core.entry"</li>
</ul>
<li>
<div align="left">
Automatically sets the following values to these data model elements
</div>
</li>
<ul>
<li>LMSSetValue("cmi.core.lesson_status", "incomplete")</li>
<li>LMSSetValue("cmi.core.exit", "logout")</li>
<li>LMSSetValue("cmi.core.session_time", "00:12:48.22")</li>
</ul>
<li>
<div align="left">
Calls the LMSCommit function
</div>
</li>
<li>
<div align="left">
Calls the LMSFinish function
</div>
</li>
</ol>
</ol>
<br />
<hr color="#353889">
<br />
<p align="left">
<strong><em>Upon Third Entry: </em></strong>
</p>
<ol style="MARGIN-RIGHT: 0px">
<ol>
<li>
<div align="left">
Locates the LMS's API implementation
</div>
</li>
<li>
<div align="left">
Calls the LMSInitialize function
</div>
</li>
<li>
<div align="left">
Calls the LMSGetValue function for the following previously set
data model elements and compares them with the expected values:
</div>
</li>
<ul>
<li>"cmi.core.total_time"</li>
<li>"cmi.core.credit"</li>
</ul>
<li>
<div align="left">
May set one or more of the following values to these data model elements:
</div>
</li>
<ul>
<li>LMSSetValue("cmi.core.lesson_status", "completed")</li>
<li>LMSSetValue("cmi.core.score.raw", "25")</li>
<li>LMSSetValue("cmi.core.exit", "")</li>
</ul>
<li>
<div align="left">
Calls the LMSCommit function
</div>
</li>
<li>
<div align="left">
Calls the LMSFinish function
</div>
</li>
</ol>
</ol>
<br />
<hr color="#353889">
</body>
</html>
import java.io.IOException;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;
public class scormADL12 {
private InternetExplorerDriver driver;
private Wait<WebDriver> wait;
private int currentSCO = 1;
@Before
public void setUp() {
driver = new InternetExplorerDriver();
wait = new WebDriverWait(driver, 60);
}
//Open TestSuite and Moodle site
public void testSetup() throws IOException {
String testSuiteURL = System.getProperty("testSuiteURL");
String moodleURL = System.getProperty("moodleURL");
if (testSuiteURL == null) {
throw new IOException("ADL SCORM 1.2 Test Suite URL not specified");
}
if (moodleURL == null) {
throw new IOException("Moodle Test Site URL not specified");
}
driver.get(testSuiteURL);
driver.switchTo().frame("instructions");
driver.findElement(By.id("pname")).sendKeys("Moodle");
driver.findElement(By.id("pversion")).sendKeys("2011033003");
driver.findElement(By.id("pvname")).sendKeys("MoodleHQ");
driver.findElement(By.id("continue01")).click();
//((JavascriptExecutor) driver).executeScript("window.open('"+moodleURL+"', 'moodleWindow');");
((JavascriptExecutor) driver).executeScript("window.open('"+moodleURL+"', 'moodleWindow');");
driver.switchTo().window("moodleWindow");
}
// Login into ADL SCORM Test Course
public void loginCourse(int course) {
driver.findElement(By.linkText("ADL SCORM Test 1.2")).click();
wait.until(presenceOfElementLocated(By.id("username")));
driver.findElement(By.id("username")).clear();
driver.findElement(By.id("password")).clear();
if (course != 2) {
driver.findElement(By.id("username")).sendKeys("joestudent");
driver.findElement(By.id("password")).sendKeys("password");
} else {
driver.findElement(By.id("username")).sendKeys("marylearner");
driver.findElement(By.id("password")).sendKeys("password");
}
driver.findElement(By.id("loginbtn")).click();
wait.until(presenceOfElementLocated(By.xpath("//span[text()='ADL SCORM Test Course I']")));
if (course != 1) {
driver.findElement(By.xpath("//span[text()='ADL SCORM Test Course II']")).click();
} else {
driver.findElement(By.xpath("//span[text()='ADL SCORM Test Course I']")).click();
}
}
// Test all SCOes
public void testSCO (char mode, int course, int scoLeft) {
wait.until(presenceOfElementLocated(By.id("n")));
String url = driver.getCurrentUrl();
if (mode == 'b') {
driver.findElement(By.id("b")).click();
} else {
driver.findElement(By.id("n")).click();
}
driver.findElement(By.xpath("//input[@value='Enter']")).click();
wait.until(presenceOfElementLocated(By.id("ygtvcontentel2")));
System.out.println("SCO Loaded. Testing ...");
driver.switchTo().frame("scorm_object");
if ((course == 1 && currentSCO != 4) || (course == 2 && currentSCO != 2)) {
wait.until(presenceOfElementLocated(By.xpath("//*[contains(.,'Status: This SCO Test Completed.')]")));
} else if ((course == 1 && currentSCO == 4) || (course == 2 && currentSCO == 2)) {
//for both course 1 and course 2
if (scoLeft !=0){
wait.until(presenceOfElementLocated(By.xpath("//*[contains(.,'Please Log out and re-login to the LMS.')]")));
return;
} else {
wait.until(presenceOfElementLocated(By.xpath("//*[contains(.,'Status: This SCO Test Completed.')]")));
}
}
System.out.println(driver.findElement(By.id("teststatus")).getText());
currentSCO++;
driver.get(url);
}
/*
public void proceedToNextSCO () throws InterruptedException {
currentSCO += 1;
driver.switchTo().window("moodleWindow");
//driver.findElement(By.id("ygtvlabelel"+currentSCO)).click();
//selenium.click("ygtvlabelel"+currentSCO);
System.out.println("Proceeding to SCO -"+currentSCO);
wait.until(presenceOfElementLocated(By.id("ygtvlabelel3")));
System.out.println("Testing SCO "+currentSCO+" ...");
driver.findElement(By.id("ygtvlabelel"+(currentSCO+1))).click();
//((JavascriptExecutor) driver).executeScript("window.location.reload();");
//selenium.waitForPageToLoad("30000");
}
public void checkSCOStatus(String line) throws InterruptedException, IOException {
boolean status = line.contains("\"Status "+currentSCO+": SCO "+currentSCO+" Test completed\"");
if(!status) {
throw new IOException ("Failed at SCO: "+currentSCO);
} else {
//Thread thisThread = Thread.currentThread();
//thisThread.sleep(10000);
proceedToNextSCO();
}
}
public void readSCOStatus () throws InterruptedException {
System.out.println("Reading SCO "+currentSCO+" Status ..");
//open status window the first time only
if(currentSCO == 1) {
//((JavascriptExecutor) driver).executeScript("window.open('"+moodleURL+"/mod/scorm/testReport.php', 'scormStatus');");
//((JavascriptExecutor) driver).executeScript("window.open('http://www.mayank.com/moodle-6b14adf/mod/scorm/testReport.php?readStatus=1', 'scormStatus');");
}
//driver.switchTo().window("scormStatus");
//wait.until(presenceOfElementLocated(By.id("SCO"+currentSCO)));
System.out.println("Testing of SCO "+currentSCO+" completed");
proceedToNextSCO();
//Wait on initial testing for file to be created.
/*if(currentSCO == 1) {
Thread.sleep(10000);
}
String line = null;
int currentLineNo = 0;
int slept = 0;
BufferedReader in = null;
try {
//Thread thisThread = Thread.currentThread();
//thisThread.sleep(10000);
in = new BufferedReader (new FileReader("C:\\xampp\\moodledata-6b14adf\\temp\\scormtesting\\scormtestStatus.txt"));
//read till required line
while(currentLineNo < currentSCO-1) {
if (in.readLine() == null) {
//thisThread.sleep(10000);
slept = 1;
continue;
}
currentLineNo++;
slept = 0;
}
//read until required line
while(currentLineNo <= (currentSCO-1)) {
line = in.readLine();
if (line == null && slept != 100) {
//thisThread.sleep(10000);
slept++;
continue;
}
currentLineNo++;
slept = 0;
System.out.println(line);
}
checkSCOStatus(line);
} catch (IOException ex) {
System.out.println("Problem in status file.\n" + ex.getMessage());
} finally {
try { if (in!=null) in.close(); } catch(IOException ignore) {}
}
}*/
public void logoutLogin(int course) {
driver.switchTo().window("moodleWindow");
driver.findElement(By.linkText("Logout")).click();
loginCourse(course);
}
public void testCourse(int course) {
if (course == 1) {
while(currentSCO <= 9) {
System.out.println("Testing SCO #"+currentSCO);
if(currentSCO != 4) {
testSCO('n', 1, 0);
} else {
//Testing Part I of SCO #4
testSCO('n', 1, 1);
logoutLogin(1);
//Testing Part II of SCO #4
testSCO('n', 1, 1);
//Logout IInd Time.
logoutLogin(1);
//SCO 4 should be completed with this.
testSCO('n', 1, 0);
}
// it is not an infinite loop.
}
} else {
currentSCO = 1;
while(currentSCO <= 3) {
System.out.println("Testing SCO #"+currentSCO);
if(currentSCO != 2) {
testSCO('b', 2, 0);
} else {
testSCO('n', 2, 1);
logoutLogin(2);
// SCO 2 should be completed with this.
testSCO('n', 2, 0);
}
}
currentSCO = 1;
}
}
/*public void executeADL12Tests(int course) throws InterruptedException {
if (course != 2) {
testCourse1();
} else {
testCourse2();
}
}*/
@Test
public void executeADL12Tests() throws IOException {
testSetup();
System.out.println("Testing Course I ...");
loginCourse(1);
testCourse(1);
System.out.println("Course I Test Completed. Testing Course II ...");
logoutLogin(2);
testCourse(2);
}
@After
public void tearDown() {
driver.close();
//selenium.stop();
}
// Explicit Wait for element function
public ExpectedCondition<WebElement> presenceOfElementLocated(final By locator) {
return new ExpectedCondition<WebElement>() {
public WebElement apply(WebDriver webDriver) {
return webDriver.findElement(locator);
}
};
}
// Explicit wait for element with text
public WebElement waitElementWithTextPresent(final By locator, final String text) {
return new WebDriverWait(driver, 30).until(new ExpectedCondition<WebElement>() {
@Override
public WebElement apply(WebDriver d) {
WebElement e = d.findElement(locator);
String elementText = e.getText();
if (elementText != null && elementText.contains(text)) {
return e;
} else {
return null;
}
}
});
}
/*public void main (String args[]) {
testSetup(args[0], args[1]);
testExecutor()
}*/
}
<?php
/* * This file is not required now.
* It was used to write the status temporarily to the dataroot.
* Also, it was being used to display the test status from the file
* saved in the data root.
*/
require_once("../../config.php");
if($_GET['readStatus']) {
?>
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"> </script>
<script type="text/javascript">
$(document).ready(function(){
setInterval(function() {
$.post('<?php echo $CFG->wwwroot."/mod/scorm/readStatus.php";?>', function(data){
$("#testStatus").html(data);
});
}, 2000);
});
</script>
</head>
<body>
<div id="testStatus"> </div>
</body>
</html>
<?php
} elseif($_POST['test_status']) {
$teststatus = trim($_POST['test_status']);
$teststatus .= "\r\n";
$filelocation = $CFG->dataroot.'/temp/scormtesting/scormtestStatus.txt';
if(!empty($teststatus) && strpos($teststatus, "Status")) {
if (!strpos($teststatus, "SCO 1")) {
$fh = fopen($filelocation, 'a+');
} else {
$fh = fopen($filelocation, 'w+');
}
fwrite($fh, $teststatus);
fclose($fh);
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment