blob: a751ccb0887946207926202628337c2a62f76b58 [file] [log] [blame]
/* -*- Mode: java; tab-width: 8 -*-
* Copyright (C) 1997, 1998 Netscape Communications Corporation, All Rights Reserved.
*/
package com.netscape.javascript.qa.liveconnect;
import java.applet.Applet;
import java.io.File;
import java.util.Vector;
import netscape.javascript.*;
//import netscape.security.*;
import com.netscape.javascript.qa.drivers.*;
/**
* LiveConnectTest is the parent class for all LiveConnect test applets.
*
* <p> Subclasses must override the executeTest() and main() methods, and
* provide a constructor. To add test cases, subclasses should use the
* addTestCaseMethod.
*
* <p> Each test class creates JavaScript TestCase objects through LiveConnect,
* and prints results to standard output, just like the JavaScript language
* tests do.
*
* <p> To run a test individually, add the test package to your classpath
* and start the LiveConnected JavaScript shell. Instantiate the test class,
* and call the test's run method. Test results will be written to standard
* out.
*
* <p> To run the test in Navigator, create an HTML page for each test applet.
* Load the page in Navigator. Test results will be written to the Java
* console.
*
* <p> To run the test in the LiveConnect test driver, use the class
* LiveConnectDrv. LiveConnectDrv starts an out of process Liveconnect
* enabled jsshell.exe, and passes the shell the arguments necessary to
* start the test application.
*
* <p> LiveConnectTests write results to the log files, using the static
* methods in com.netscape.javascript.qa.drivers.TestDriver.
*
* After each test file is completed, each applet writes test case failures
* to the test case log, and if the test fails, also writes to the file log.
*
* <p> The applet writes a summary of that file's information to a temporary
* log that is parsed by the driver. The temporary log contains name and
* value pairs of the TestFile properties, which the driver uses to generate
* suite and summary logs.
*
* <p> Running the test suite is very dependent on LiveConnect working.ft
* Not sure whether this is a good thing, or not.
*
* @see LiveConnectTest#addTestCase
* @see com.netscape.javascript.qa.drivers.LiveConnectDrv
* @see com.netscape.javascript.qa.drivers.LiveConnectEnv
* @see com.netscape.javascript.qa.drivers.TestDriver
*
* @author christine@netscape.com
*
*/
public class LiveConnectTest extends Applet implements Runnable {
/**
* Create a new LiveConnectTest.
*/
public LiveConnectTest() {
}
/**
* Main method. Used when running as an application.
*/
public static void main( String[] args ) {
LiveConnectTest test = new LiveConnectTest();
}
public void start() {
run();
}
public void stop() {
}
/**
* Main method when run as an Applet.
*
*/
public void run() {
System.out.println("Running the test." );
setupTestEnvironment();
file.startTime = TestDriver.getCurrentTime();
executeTest();
file.endTime= TestDriver.getCurrentTime();
getResults();
cleanupTestEnvironment();
stop();
}
/**
* Initialize variables, open log files.
*/
public void setupTestEnvironment() {
global = JSObject.getWindow( this );
getEnvironment();
if ( ENVIRONMENT == BROWSER ) {
// PrivilegeManager.enablePrivilege( "UniversalFileAccess" );
// PrivilegeManager.enablePrivilege( "UniversalPropertyRead" );
}
output = getOutputDirectory();
if (LOGGING) {
TestDriver.openLogFiles( output );
templog = getTempLog( output );
}
testdir = getTestDirectory();
file = new TestFile( this.getClass().getName(), testdir.toString() +
this.getClass().toString() );
file.bugnumber = this.BUGNUMBER;
file.description = ( this.getClass().toString() );
}
public void getEnvironment() {
this.ENVIRONMENT = ( global.getMember("version").equals( "undefined"))
? BROWSER
: SHELL;
return;
}
/**
* Create a TestLog object which will be used to write the testclass
* results to a temporary log file. If there is an existing log,
* delete it.
*/
public TestLog getTempLog( File output ) {
String templog = "";
try {
TEMP_LOG_NAME = ((String) global.getMember( "OUTPUT_FILE" )).equals
("undefined")
? TEMP_LOG_NAME
: (String) global.getMember("OUTPUT_FILE");
templog = output.getAbsolutePath() + TEMP_LOG_NAME;
} catch ( Exception e ) {
this.exception = e.toString();
p("Exception deleting existing templog: " + e.toString() );
}
return new TestLog( templog, "" );
}
/**
* Get the OUTPUT_FILE if defined, which is where the temp log is written.
* If the file is not defined, assume we are running in the shell, and do
* not write any output.
*
* XXX change this to match description above.
*
* @see com.netscape.javascript.drivers.LiveConnectDrv
*/
public File getOutputDirectory() {
String o = "";
if ( this.ENVIRONMENT == BROWSER ) {
String outputParam = this.getParameter( "output" );
return new File( getParameter( "output" ) );
} else {
try {
o = (String) global.getMember( "OUTPUT_DIRECTORY" );
if ( ! o.equals( "undefined") ) {
LOGGING = true;
}
} catch ( Exception e ) {
System.err.println( "OUTPUT_DIRECTORY threw: " + e );
e.printStackTrace();
System.exit(1);
}
System.out.println( "Output file is " + o.toString() );
return new File( o.toString() );
}
}
/**
* Get the TEST_DIRECTORY variable, which must be defined in the
* JavaScript helper file.
*
* @see com.netscape.javascript.drivers.LiveConnectDrv
*/
public File getTestDirectory() {
try {
String o = (String) global.getMember( "TEST_DIRECTORY" );
o = o.endsWith( File.separator ) ? o : o + File.separator;
return new File( o.toString() );
} catch ( Exception e ) {
System.err.println( "TEST_DIRECTORY is not defined: " + e );
return new File( "." );
}
}
/**
* Execute the test. Subclasses must implement this method. The
* default implemenation does nothing. This method should instantiate
* TestCases, and add them to the testcase Vector.
*
*/
public void executeTest() {
return;
}
/**
* Add a TestCase to the testcase Vector.
*
* @param description a description of the test case
* @param expect a string representation of the expected result
* @param actual a string representation of the actual result
* @param exception the message in any JavaScript runtime error
* or Java exception that was thrown.
*
*/
public void addTestCase( String description, String expect, String actual,
String exception )
{
String result = ( expect == actual ) ? "true" : "false";
TestCase tc = shouldBeWithErrorCheck( result, this.getClass().getName().toString(),
description, expect, actual, exception );
file.caseVector.addElement( tc );
file.totalCases++;
if ( result == "false" ) {
file.passed = false;
file.casesFailed++;
} else {
file.casesPassed++;
}
return;
}
/**
* Close all logs.
*
*/
public void closeLogs() {
TestDriver.getLog( output, TestDriver.SUMMARY_LOG_NAME ).closeLog();
TestDriver.getLog( output, TestDriver.SUITE_LOG_NAME ).closeLog();
TestDriver.getLog( output, TestDriver.FILE_LOG_NAME ).closeLog();
TestDriver.getLog( output, TestDriver.CASE_LOG_NAME ).closeLog();
templog.closeLog();
templog = null;
}
/**
* Iterate through the testcase Vector. Populate the properties of the
* TestFile object.
*/
public void getResults() {
displayResults();
if (LOGGING) {
writeResultsToCaseLog();
writeResultsToFileLog();
writeResultsToTempLog();
}
}
/**
* Write a summary of the TestCase to standard out.
*
*/
public void displayResults() {
for ( int i = 0; i < file.caseVector.size(); i++ ) {
TestCase tc = (TestCase) file.caseVector.elementAt(i);
p( tc.description +" = "+ tc.actual+
( tc.expect != tc.actual
? " FAILED! expected: " + tc.expect
: " PASSED!" ) );
}
getFailedCases();
}
/**
* If any test cases did not pass, write a summary of the failed cases
* to the CASE_LOG using static TestDriver methods.
*
* @see com.netscape.javascript.qa.drivers.TestDriver#writeCaseResults
*/
public void writeResultsToCaseLog() {
if ( !file.passed ) {
TestDriver.writeCaseResults( file, file.description, output );
}
}
/**
* If the test failed, write a summary of this test to the FILE_LOG. Use
* static TestDriver methods to write to the FILE_LOG.
*
* @see com.netscape.javascript.qa.drivers.TestDriver#writeFileResult
*/
public void writeResultsToFileLog() {
if ( !file.passed ) {
TestDriver.writeFileResult(file, null, output);
}
}
/**
* Write to a file containing the results of this TestFile. The content
* of this file is parsed by the parseResult() method of LiveConnectEnv,
* which maintains information about all files and suites executed. The
* format of the temp log is a list of name value pairs, one per line.
* The temp log is overwritten each time the LiveConnectDrv executes a
* test.
*
* Changes to the format of the templog file will require changes to
* LiveConnectDrv.parseResult.
*
* <pre>
* CLASSNAME LiveConnectTest
* PASSED [true, false]
* LENGTH [number of testcases in this test]
* NO_PASSED [number of testcases that passed]
* NO_FAILED [number of testcases that failed]
* </pre>
*
* XXX may also want to write bugnumber, time completed, etc?. probably
* what this should do is enumerate all the properties of a TestFile object,
* that the driver can parse and treat as though it had a normal TestFile
* object.
*
* @see com.netscape.javascript.qa.drivers.LiveConnectDrv#parseResult
*/
public void writeResultsToTempLog(){
System.out.println( "Writing results to " + templog.toString() );
templog.writeLine( file.description );
templog.writeLine( file.passed + "" );
templog.writeLine( file.caseVector.size() +"" );
templog.writeLine( file.casesPassed + "");
templog.writeLine( file.casesFailed + "");
templog.writeLine( file.bugnumber );
p( file.name );
p( "passed: " + passed );
p( "total cases: " + file.caseVector.size() );
p( "cases passed: " + file.casesPassed );
p( "cases failed: " + file.casesFailed );
p( "bugnumber: " + file.bugnumber );
return;
}
/**
* Close logs, and set the value of the "completed" variable in the
* JavaScript environment so that the driver knows the test has
* finished.
*/
public void cleanupTestEnvironment() {
try {
if ( LOGGING ) {
// templog.closeLog();
}
// global.eval("var completed = true;");
} catch ( Exception e ) {
p( "exception in cleanupTestEnvironment: " + e.toString() );
e.printStackTrace();
}
}
public void p (String s ) {
System.out.println( s );
}
/**
* This dandy little hack from Nix that is used to test things that
* should fail. It runs a method on a JavaScript object, catching any
* exceptions. It returns the detail message from the exception, or
* NO_EXCEPTION if it succeeds. This is from nix.
*
*/
public static String catchException(JSObject self, String method,
Object args[]) {
Object rval;
String msg;
try {
rval = self.call(method, args);
msg = NO_EXCEPTION;
} catch (Throwable e) {
msg = e.getMessage();
}
return msg;
}
public void getFailedCases() {
if ( file.passed ) {
return;
}
p( "********** Failed Test Cases **********" );
for ( int i = 0; i < file.caseVector.size(); i++ ) {
TestCase tc = (TestCase) file.caseVector.elementAt(i);
if ( tc.passed != "true" ) {
p( tc.description +" = "+ tc.actual+
( tc.expect != tc.actual
? " FAILED! expected: " + tc.expect
: " PASSED!"
) +
( tc.reason.length() > 0
? ": " + tc.reason
: ""
)
);
}
}
}
public File output;
public File testdir;
public TestFile file;
public Vector testcase;
public JSObject global;
public boolean passed = true;
public Vector failedVector = new Vector();
public TestLog templog;
public String exception = "";
public String BUGNUMBER = "";
boolean LOGGING = false;
public static String TEMP_LOG_NAME = "result.tmp";
public static final int BROWSER = 1;
public static final int SHELL = 0;
public int ENVIRONMENT;
public static final String NO_EXCEPTION = "Expected exception not thrown.";
public static final String DATA_CLASS = "com.netscape.javascript.qa.liveconnect.DataTypeClass";
}