001: package fitnesse.runner;
002:
003: import java.io.ByteArrayInputStream;
004: import java.io.File;
005: import java.io.FileOutputStream;
006: import java.io.IOException;
007: import java.io.InputStream;
008: import java.net.URI;
009: import java.net.URISyntaxException;
010: import java.util.ArrayList;
011: import java.util.List;
012:
013: import org.w3c.tidy.Tidy;
014:
015: import fitnesse.http.Request;
016: import fitnesse.responders.STIQResultResponder;
017: import fitnesse.util.FileUtil;
018:
019: /**Launch STIQ
020: *
021: * Launches IE against an already running fitness instance.
022: *
023: * The runStiq method will not return until a Result is received by the STIQResultReponder.
024: *
025: */
026: public class BrowserLauncher {
027: private static final String RESULT_FILENAME = "stiq-results.xml";
028:
029: private static final String PASSED = "passed";
030:
031: private Process process;
032:
033: private int port;
034:
035: private String suiteName;
036:
037: private String startPage;
038:
039: private String server = "localhost";
040:
041: private String appRoot = "/stiq/runner.html";
042:
043: private String resultDirectoryPathName;
044:
045: public boolean runStiq() throws IOException, URISyntaxException {
046: launchSTIQ();
047: try {
048: while (STIQResultResponder.getResult() == null) {
049: Thread.sleep(1000);
050: }
051: } catch (InterruptedException e) {
052: } finally {
053: process.destroy();
054: }
055: Request request = STIQResultResponder.getResult();
056: writeRequestResult(request, getResultDirectoryPathname());
057: String result = (String) request.getInput("result");
058: return PASSED.equals(result);
059: }
060:
061: private void launchSTIQ() throws IOException, URISyntaxException {
062: URI uri = new URI("http", null, getServer(), getPort(),
063: getAppRoot(), "startPage=" + getStartPage() + "&suite="
064: + getSuiteName() + "&auto=true"
065: + "&resultsUrl=" + getResultUrl(), null);
066: runProcessBuilderStiq(uri);
067: }
068:
069: private void writeRequestResult(Request request,
070: String outputDirectoryPath) throws IOException {
071:
072: makeDir(outputDirectoryPath);
073:
074: Tidy tidy = new Tidy();
075: tidy.setXHTML(true);
076: tidy.setQuiet(true);
077: tidy.setShowWarnings(false);
078: tidy.setWraplen(1024);
079:
080: // TODO: Refactor to use in memory string manipulation rather than file manips...
081: InputStream inputStream = new ByteArrayInputStream(request
082: .getInput("suite").toString().getBytes());
083: File resultFile = new File(outputDirectoryPath, RESULT_FILENAME);
084: FileOutputStream outputStream = new FileOutputStream(resultFile);
085:
086: tidy.parse(inputStream, outputStream);
087: outputStream.close();
088:
089: String resultContent = "";
090: resultFile = new File(outputDirectoryPath, RESULT_FILENAME);
091: try {
092: resultContent = FileUtil.getFileContent(resultFile);
093: } catch (Exception e) {
094: // TODO Auto-generated catch block
095: e.printStackTrace();
096: }
097:
098: // Get rid of the !Doctype and xmlns stuff at the top so our XSL doesn't choke
099: resultContent = "<html><head>"
100: + resultContent.substring(resultContent
101: .indexOf("<title>"));
102: resultContent = resultContent.replace("<html>", "<stiq>");
103: resultContent = resultContent.replace("</html>", "</stiq>");
104: resultContent = resultContent.replace(" ", "");
105: FileUtil
106: .createFile(resultFile.getAbsolutePath(), resultContent);
107: }
108:
109: private void makeDir(String outputDirectoryPath) {
110: File dir = new File(outputDirectoryPath);
111: dir.mkdirs();
112: }
113:
114: private void runProcessBuilderStiq(URI uri) throws IOException {
115: List commands = new ArrayList(2);
116: commands.add(getExecutablePath());
117: commands.add(uri.toURL().toString());
118: ProcessBuilder builder = new ProcessBuilder(commands);
119: builder.redirectErrorStream(true);
120: process = builder.start();
121: }
122:
123: public void setPort(int port) {
124: this .port = port;
125: }
126:
127: private int getPort() {
128: return this .port;
129: }
130:
131: public void setStartPage(String startPage) {
132: this .startPage = startPage;
133: }
134:
135: private String getStartPage() {
136: return this .startPage;
137: }
138:
139: public void setSuiteName(String suiteName) {
140: this .suiteName = suiteName;
141: }
142:
143: private String getSuiteName() {
144: return this .suiteName;
145: }
146:
147: public void setResultDirectoryPathname(String path) {
148: this .resultDirectoryPathName = path;
149: }
150:
151: private String getResultDirectoryPathname() {
152: return resultDirectoryPathName;
153: }
154:
155: private String getExecutablePath() {
156: return "C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE";
157: }
158:
159: private String getResultUrl() {
160: String resultUrl = "/" + STIQResultResponder.STIQ_RESULT_URL;
161: return resultUrl;
162: }
163:
164: public void setAppRoot(String root) {
165: this .appRoot = root;
166: }
167:
168: private String getAppRoot() {
169: return this .appRoot;
170: }
171:
172: private String getServer() {
173: return this.server;
174: }
175: }
|