public Command executeStep(Element stepRow) throws Exception {
   Command command = new Command();
   NodeList stepFields = stepRow.getElementsByTagName("td");
   String cmd = stepFields.item(0).getTextContent().trim();
   command.cmd = cmd;
   ArrayList<String> argList = new ArrayList<String>();
   if (stepFields.getLength() == 1) {
     // skip comments
     command.result = "OK";
     return command;
   }
   for (int i = 1; i < stepFields.getLength(); i++) {
     String content = stepFields.item(i).getTextContent();
     content = content.replaceAll(" +", " ");
     content = content.replace('\u00A0', ' ');
     content = content.trim();
     argList.add(content);
   }
   String args[] = argList.toArray(new String[0]);
   command.args = args;
   if (this.verbose) {
     System.out.println(cmd + " " + Arrays.asList(args));
   }
   try {
     command.result = this.commandProcessor.doCommand(cmd, args);
     command.error = false;
   } catch (Exception e) {
     command.result = e.getMessage();
     command.error = true;
   }
   command.failure = command.error && !cmd.startsWith("verify");
   if (this.verbose) {
     System.out.println(command.result);
   }
   return command;
 }
  public boolean runSuite(String filename) throws Exception {
    if (this.verbose) {
      System.out.println(
          "Running test suite "
              + filename
              + " against "
              + this.host
              + ":"
              + this.port
              + " with "
              + this.browser);
    }
    TestSuite suite = new TestSuite();
    long start = System.currentTimeMillis();
    suite.numTestPasses = 0;
    suite.file = new File(filename);
    File suiteDirectory = suite.file.getParentFile();
    this.document = parseDocument(filename);
    Element table = (Element) this.document.getElementsByTagName("table").item(0);
    NodeList tableRows = table.getElementsByTagName("tr");
    Element tableNameRow = (Element) tableRows.item(0);
    suite.name = tableNameRow.getTextContent();
    suite.result = true;
    suite.tests = new Test[tableRows.getLength() - 1];
    for (int i = 1; i < tableRows.getLength(); i++) {
      Element tableRow = (Element) tableRows.item(i);
      Element cell = (Element) tableRow.getElementsByTagName("td").item(0);
      Element link = (Element) cell.getElementsByTagName("a").item(0);
      Test test = new Test();
      test.label = link.getTextContent();
      test.file = new File(suiteDirectory, link.getAttribute("href"));

      SeleniumHtmlClient subclient = new SeleniumHtmlClient();
      subclient.setHost(this.host);
      subclient.setPort(this.port);
      subclient.setBrowser(this.browser);
      // subclient.setResultsWriter(this.resultsWriter);
      subclient.setBaseUrl(this.baseUrl);
      subclient.setVerbose(this.verbose);
      subclient.runTest(test);
      if (test.result) {
        suite.numTestPasses++;
      }
      suite.result &= test.result;
      suite.tests[i - 1] = test;
    }
    long end = System.currentTimeMillis();

    suite.totalTime = (end - start) / 1000;

    if (this.resultsWriter != null) {
      this.resultsWriter.write("<html><head>\n");
      this.resultsWriter.write("<style type='text/css'>\n");
      this.resultsWriter.write(
          "body, table {font-family: Verdana, Arial, sans-serif;font-size: 12;}\n");
      this.resultsWriter.write("table {border-collapse: collapse;border: 1px solid #ccc;}\n");
      this.resultsWriter.write("th, td {padding-left: 0.3em;padding-right: 0.3em;}\n");
      this.resultsWriter.write("a {text-decoration: none;}\n");
      this.resultsWriter.write(".title {font-style: italic;}");
      this.resultsWriter.write(".selected {background-color: #ffffcc;}\n");
      this.resultsWriter.write(".status_done {background-color: #eeffee;}\n");
      this.resultsWriter.write(".status_passed {background-color: #ccffcc;}\n");
      this.resultsWriter.write(".status_failed {background-color: #ffcccc;}\n");
      this.resultsWriter.write(
          ".breakpoint {background-color: #cccccc;border: 1px solid black;}\n");
      this.resultsWriter.write("</style>\n");
      this.resultsWriter.write("<title>" + suite.name + "</title>\n");
      this.resultsWriter.write("</head><body>\n");
      this.resultsWriter.write("<h1>Test suite results </h1>\n\n");
      this.resultsWriter.write("<table>\n");
      this.resultsWriter.write(
          "<tr>\n<td>result:</td>\n<td>" + (suite.result ? "passed" : "failed") + "</td>\n</tr>\n");
      this.resultsWriter.write(
          "<tr>\n<td>totalTime:</td>\n<td>" + suite.totalTime + "</td>\n</tr>\n");
      this.resultsWriter.write(
          "<tr>\n<td>numTestTotal:</td>\n<td>" + suite.tests.length + "</td>\n</tr>\n");
      this.resultsWriter.write(
          "<tr>\n<td>numTestPasses:</td>\n<td>" + suite.numTestPasses + "</td>\n</tr>\n");
      int numTestFailures = suite.tests.length - suite.numTestPasses;
      this.resultsWriter.write(
          "<tr>\n<td>numTestFailures:</td>\n<td>" + numTestFailures + "</td>\n</tr>\n");
      this.resultsWriter.write("<tr>\n<td>numCommandPasses:</td>\n<td>0</td>\n</tr>\n");
      this.resultsWriter.write("<tr>\n<td>numCommandFailures:</td>\n<td>0</td>\n</tr>\n");
      this.resultsWriter.write("<tr>\n<td>numCommandErrors:</td>\n<td>0</td>\n</tr>\n");
      this.resultsWriter.write("<tr>\n<td>Selenium Version:</td>\n<td>2.24</td>\n</tr>\n");
      this.resultsWriter.write("<tr>\n<td>Selenium Revision:</td>\n<td>.1</td>\n</tr>\n");

      // test suite
      this.resultsWriter.write("<tr>\n<td>\n");
      this.resultsWriter.write(
          "<table id=\"suiteTable\" class=\"selenium\" border=\"1\" cellpadding=\"1\" cellspacing=\"1\"><tbody>\n");
      this.resultsWriter.write(
          "<tr class=\"title "
              + (suite.result ? "status_passed" : "status_failed")
              + "\"><td><b>Test Suite</b></td></tr>\n");

      int i = 0;
      for (Test test : suite.tests) {
        this.resultsWriter.write(
            "<tr class=\""
                + (test.result ? "status_passed" : "status_failed")
                + "\"><td><a href=\"#testresult"
                + i
                + "\">"
                + test.name
                + "</a></td></tr>");
        i++;
      }
      this.resultsWriter.write(
          "</tbody></table>\n</td>\n<td>&nbsp;</td>\n</tr>\n</table>\n<table>");
      int j = 0;
      for (Test test : suite.tests) {
        this.resultsWriter.write(
            "<tr><td><a name=\"testresult" + j + "\">" + test.file + "</a><br/><div>\n");
        this.resultsWriter.write("<table border=\"1\" cellpadding=\"1\" cellspacing=\"1\">\n");
        this.resultsWriter.write(
            "<thead>\n<tr class=\"title "
                + (test.result ? "status_passed" : "status_failed")
                + "\"><td rowspan=\"1\" colspan=\"3\">"
                + test.name
                + "</td></tr>");
        this.resultsWriter.write("</thead><tbody>\n");
        for (Command command : test.commands) {
          boolean result = command.result.startsWith("OK");
          boolean isAssert = command.cmd.startsWith("assert") || command.cmd.startsWith("verify");
          ;
          if (!isAssert) {
            this.resultsWriter.write(
                "<tr class=\"" + (result ? "status_done" : "") + "\">\n<td>\n");
          } else {
            this.resultsWriter.write(
                "<tr class=\"" + (result ? "status_passed" : "status_failed") + "\">\n<td>\n");
          }
          this.resultsWriter.write(command.cmd);
          this.resultsWriter.write("</td>\n");
          if (command.args != null) {
            for (String arg : Arrays.asList(command.args)) {
              this.resultsWriter.write("<td>" + arg + "</td>\n");
            }
          }
        }
        this.resultsWriter.write("</tr>\n");
        this.resultsWriter.write("</tbody></table>\n");
        this.resultsWriter.write("</div></td>\n<td>&nbsp;</td>\n</tr>");

        j++;
      }

      int k = 0;
      for (Test test : suite.tests) {

        k++;
      }

      this.resultsWriter.write("</tbody></table>\n</td><td>&nbsp;</td>\n</tr>\n</table>\n");
      this.resultsWriter.write("</body></html>");
    }
    return suite.result;
  }