Running Sahi Scripts from Java

Problem

In an enterprise application, some times the web application may be only a small part of an other wise larger use case. One may be invoking a lot of test Java code for setting up a database, verifying infrastructure, making SOAP calls, copying over files, invoking shell commands and then, eventually verifying the application state via a web interface. In such cases it may make sense to write normal Java code for anything other than web, and then invoke a Sahi script when needed. This brings in a necessity to invoke a Sahi script from Java. The main class for invoking Sahi from Java is in.co.sahi.distributed.DSahiRunner.

Java code invoking DSahiRunner

package in.co.sahi.sample;
import java.util.HashMap;
import in.co.sahi.distributed.DSahiRunner;
import in.co.sahi.distributed.SuiteInfo;

public class SahiScriptLauncher {

	public static void main(String[] args) {
		final String host = "localhost";
		final String port = "9999";
		final String suiteName = "sahitests/integration.sah";
		final String browserType = "firefox";
		String baseURL = "http://sahitest.com/demo/training/";
		String threads = "1";

		SuiteInfo suiteInfo = new SuiteInfo();
		suiteInfo.setHost(host);
		suiteInfo.setPort(port);
		suiteInfo.setStartWith("BROWSER"); // you can pass other modes like, WINDOWS, JAVA, ANDROID, IOS, SAP
		suiteInfo.setThreads(threads);
		suiteInfo.setBaseURL(baseURL);
		suiteInfo.setBrowserType(browserType);
		suiteInfo.setScriptsPathMaster("scripts");
		suiteInfo.setSuitePath(suiteName);

		// use this to set deviceId in suiteInfo
		// suiteInfo.setAndroidDevice("XXXX"); // for Android
		// suiteInfo.setIOSDevice("XXXX"); // for IOS

		// add nodes in suiteInfo for distributed run
		// suiteInfo.addNode("10.10.2.50", "9999");
		// suiteInfo.addNode("10.10.2.53", "9999");

		DSahiRunner dSahiRunner = new DSahiRunner(suiteInfo);
		HashMap<String, Object> variableHashMap = new HashMap<String, Object>();
		variableHashMap.put("$user", "test");
		variableHashMap.put("$pwd", "secret");
		dSahiRunner.setInitJS(variableHashMap);

		String status = dSahiRunner.executeNonDistributed();
		// execute this for distributed run
		// String status = dSahiRunner.execute();

		System.out.println(status);
	}
}


Java code invoking TestRunner

dangerDEPRECATED: Use Java code invoking DSahiRunner instead.
package in.co.sahi.sample;
import java.io.IOException;
import java.util.HashMap;
import net.sf.sahi.test.TestRunner;

public class SahiScriptLauncher {
  public static void main(String[] args) throws IOException, InterruptedException {
    final String suiteName = "scripts/sahitests/integration.sah";
    final String browserType = "firefox";
    String base = "http://sahitest.com/demo/training/";
    String threads = "1";
    TestRunner testRunner = new TestRunner(suiteName, browserType, base, threads);
    HashMap<String, Object> variableHashMap = new HashMap<String, Object>();
    variableHashMap.put("$user", "test");
    variableHashMap.put("$pwd", "secret");
    testRunner.setInitJS(variableHashMap);
    String status = testRunner.execute();
    System.out.println(status);
  }
}
NOTE: The ant-sahi.jar file needs to be added to your classpath. It is located in sahi/lib folder.

The Sahi script being invoked

The script we are invoking is this:
// Test Manager can pass in data to this script via "initJS" parameter.
// initJS will be "eval"ed before a script starts
// Pass String "$user='test';$pwd='secret';" as parameter "initJS"
// Or pass a HashMap of variable name and value as called in above Java code
_setValue(_textbox("user"), $user);
_setValue(_password("password"), $pwd);
_click(_submit("Login"));
_setValue(_textbox("q"), "2");
_setValue(_textbox("q[1]"), "1");
_setValue(_textbox("q[2]"), "1");
_click(_button("Add"));
_click(_cell("Rs.200[1]"));
_assertExists(_textbox("total"));
_assert(_isVisible(_textbox("total")));
_assertEqual("1150", _textbox("total").value);
_click(_button("Logout"));

Passing parameters into Sahi script from Java

Parameters can be passed in as a simple string which contains the Javascript to be executed before a script starts. In the above example. notice how we pass in two variables $user and $pwd from the Java code into Sahi code.

Passing data values from the Script back to Java

This is best done via writing into a file in the Script and then reading the file in Java to obtain the parameters. To write to a file, use "_writeFile":miscellaneous-apis
_writeFile($filePath, $text);
To read it in your Java code, you can write your own custom code to read file contents, or use Sahi's Utils class
String contents = net.sf.sahi.util.Utils.readFileAsString(new File(filePath));
This class is also part of ant-sahi.jar which you would have already added to your classpath to invoke TestRunner.