1 package com.tonbeller.tbutils.httpunit; 2 3 import java.io.File ; 4 import java.io.FileOutputStream ; 5 import java.io.FileWriter ; 6 import java.io.IOException ; 7 import java.io.InputStream ; 8 import java.io.OutputStreamWriter ; 9 import java.io.Writer ; 10 import java.net.URL ; 11 import java.util.ArrayList ; 12 import java.util.Arrays ; 13 import java.util.Iterator ; 14 import java.util.List ; 15 16 import javax.xml.transform.OutputKeys ; 17 import javax.xml.transform.Templates ; 18 import javax.xml.transform.Transformer ; 19 import javax.xml.transform.TransformerConfigurationException ; 20 import javax.xml.transform.TransformerException ; 21 import javax.xml.transform.TransformerFactory ; 22 import javax.xml.transform.dom.DOMSource ; 23 import javax.xml.transform.stream.StreamResult ; 24 import javax.xml.transform.stream.StreamSource ; 25 26 import junit.framework.Assert; 27 28 import org.jaxen.JaxenException; 29 import org.jaxen.dom.DOMXPath; 30 import org.pdfbox.ExtractText; 31 import org.w3c.dom.Element ; 32 import org.w3c.dom.Node ; 33 import org.w3c.dom.Text ; 34 import org.xml.sax.SAXException ; 35 36 import com.meterware.httpunit.HTMLElementPredicate; 37 import com.meterware.httpunit.SubmitButton; 38 import com.meterware.httpunit.TableCell; 39 import com.meterware.httpunit.WebConversation; 40 import com.meterware.httpunit.WebForm; 41 import com.meterware.httpunit.WebLink; 42 import com.meterware.httpunit.WebResponse; 43 import com.meterware.httpunit.WebTable; 44 import com.tonbeller.tbutils.httpunit.FileDiff.FileDiffHandler; 45 46 51 52 public class HttpUnitUtils { 53 54 private DOMXPath xpSubmit; 55 private DOMXPath xpAnchor; 56 private DOMXPath xpRadio; 57 private DOMXPath xpCheckbox; 58 private DOMXPath xpSelect; 59 private DOMXPath xpOption; 60 private DOMXPath xpTextInput; 61 private DOMXPath xpTextArea; 62 private DOMXPath xpPassword; 63 64 WebConversation wc; 65 boolean recordMode; 66 67 XmlDiff xmlDiff; 68 FileDiff fileDiff; 69 70 String htmlLogFileEncoding = "utf-8"; 71 72 77 public HttpUnitUtils(WebConversation wc) throws JaxenException { 78 this.wc = wc; 79 xpSubmit = new DOMXPath(".//input[@type='submit'] | .//input[@type='image']"); 80 xpAnchor = new DOMXPath(".//a[@href]"); 81 xpCheckbox = new DOMXPath(".//input[@type='checkbox']"); 82 xpRadio = new DOMXPath(".//input[@type='radio']"); 83 xpSelect = new DOMXPath(".//select"); 84 xpOption = new DOMXPath(".//option"); 85 xpTextInput = new DOMXPath(".//input[@type='text']"); 86 xpTextArea = new DOMXPath(".//textarea"); 87 xpPassword = new DOMXPath(".//input[@type='password']"); 88 89 recordMode = "true".equals(System.getProperty("httpunit.recordmode")); 90 xmlDiff = new XmlDiff(true); 91 } 92 93 public Node getCellNode(String tableID, int row, int col) throws SAXException { 94 WebTable table = wc.getCurrentPage().getTableWithID(tableID); 95 Assert.assertNotNull(table); 96 TableCell cell = table.getTableCell(row, col); 97 Assert.assertNotNull(cell); 98 return cell.getDOM(); 100 } 101 102 public Element getNth(Node root, DOMXPath xpath, int nth) throws JaxenException, SAXException { 103 if (root == null) 104 root = wc.getCurrentPage().getDOM(); 105 106 List list = xpath.selectNodes(root); 107 Assert.assertTrue("getNth: " + list.size() + ">" + nth, list.size() > nth); 108 return (Element ) list.get(nth); 109 } 110 111 public WebForm getForm(String formID) throws SAXException { 112 WebResponse wr = wc.getCurrentPage(); 113 if (formID == null) 114 return wr.getForms()[0]; 115 WebForm[] wfs = wr.getForms(); 116 WebForm wf = wr.getFormWithID(formID); 117 Assert.assertNotNull("form " + formID + " not found on page", wf); 118 return wf; 119 } 120 121 void addParameterValue(String formID, String name, String value) throws SAXException { 122 WebForm wf = getForm(formID); 123 String [] values = wf.getParameterValues(name); 124 if (values == null) 125 values = new String [0]; 126 List list = new ArrayList (Arrays.asList(values)); 127 if (!list.contains(value)) { 128 list.add(value); 129 values = (String []) list.toArray(values); 130 wf.setParameter(name, values); 131 } 132 } 133 134 void removeParameterValue(String formID, String name, String value) throws SAXException { 135 WebForm wf = getForm(formID); 136 String [] values = wf.getParameterValues(name); 137 if (values == null) 138 values = new String [0]; 139 List list = new ArrayList (Arrays.asList(values)); 140 if (list.contains(value)) { 141 list.remove(value); 142 if (list.size() == 0) 143 wf.removeParameter(name); 144 else { 145 values = (String []) list.toArray(values); 146 wf.setParameter(name, values); 147 } 148 } 149 } 150 151 152 153 156 public WebResponse submitCell(String formID, String tableID, int row, int col, int nth) 157 throws JaxenException, IOException , SAXException { 158 Node root = getCellNode(tableID, row, col); 159 return submitXPath(formID, root, xpSubmit, nth); 160 } 161 162 165 public WebResponse submitXPath(String formID, DOMXPath xpath, int nth) throws JaxenException, 166 IOException , SAXException { 167 return submitXPath(formID, wc.getCurrentPage().getDOM(), xpath, nth); 168 } 169 170 173 public WebResponse submitXPath(String formID, String xpath, int nth) throws JaxenException, 174 IOException , SAXException { 175 DOMXPath dx = new DOMXPath(xpath); 176 return submitXPath(formID, wc.getCurrentPage().getDOM(), dx, nth); 177 } 178 179 182 public WebResponse submitXPath(String formID, Node root, DOMXPath xpath, int nth) 183 throws JaxenException, IOException , SAXException { 184 Element button = getNth(root, xpath, nth); 185 String name = button.getAttribute("name"); 186 WebForm wf = getForm(formID); 187 SubmitButton sb = wf.getSubmitButton(name); 188 return wf.submit(sb); 189 } 190 191 public WebResponse submitButton(String formID, String buttonName) throws IOException , 192 SAXException { 193 WebForm wf = getForm(formID); 194 SubmitButton sb = wf.getSubmitButton(buttonName); 195 return wf.submit(sb); 196 } 197 198 201 public void submitByNamePart(String formId, String namePart) throws JaxenException, IOException , 202 SAXException { 203 submitXPath(formId, "//input[contains(@name,'" + namePart + "')]", 0); 204 } 205 206 209 public void submitByValuePart(String formId, String valuePart) throws JaxenException, 210 IOException , SAXException { 211 submitXPath(formId, "//input[contains(@value,'" + valuePart + "')]", 0); 212 } 213 214 215 216 private HTMLElementPredicate matchLink = new HTMLElementPredicate() { 217 public boolean matchesCriteria(Object a, Object href) { 218 Node node = ((WebLink) a).getDOMSubtree(); 219 Element e = (Element ) node; 220 return e.getAttribute("href").equals(href); 221 } 222 }; 223 224 227 public WebResponse followCell(String tableID, int row, int col, int nth) throws JaxenException, 228 IOException , SAXException { 229 return followXPath(getCellNode(tableID, row, col), xpAnchor, nth); 230 } 231 232 235 public WebResponse followXPath(DOMXPath xpath, int nth) throws JaxenException, IOException , 236 SAXException { 237 return followXPath(wc.getCurrentPage().getDOM(), xpath, nth); 238 } 239 240 243 public WebResponse followXPath(Node root, DOMXPath xpath, int nth) throws JaxenException, 244 IOException , SAXException { 245 Element anchor = (Element ) getNth(root, xpath, nth); 246 String href = anchor.getAttribute("href"); 247 WebResponse wr = wc.getCurrentPage(); 248 WebLink link = wr.getFirstMatchingLink(matchLink, href); 249 return link.click(); 250 } 251 252 public WebResponse followXPath(String xpath, int i) throws JaxenException, IOException , 253 SAXException { 254 return followXPath(new DOMXPath(xpath), i); 255 } 256 257 258 259 272 public void setCheckBox(String formID, String tableID, int row, int col, int nth, boolean checked) 273 throws JaxenException, SAXException { 274 Element cb = (Element ) getNth(getCellNode(tableID, row, col), xpCheckbox, nth); 275 String name = cb.getAttribute("name"); 276 String value = cb.getAttribute("value"); 277 if (checked) 278 addParameterValue(formID, name, value); 279 else 280 this.removeParameterValue(formID, name, value); 281 } 282 283 public void assertChecked(String formID, String tableID, int row, int col, int nth, 284 boolean checked) throws JaxenException, SAXException { 285 Element cb = (Element ) getNth(getCellNode(tableID, row, col), xpCheckbox, nth); 286 String name = cb.getAttribute("name"); 287 String value = cb.getAttribute("value"); 288 WebForm wf = getForm(formID); 289 String [] values = wf.getParameterValues(name); 290 List valueList = Arrays.asList(values); 291 if (checked) 292 Assert.assertTrue(valueList.contains(value)); 293 else 294 Assert.assertFalse(valueList.contains(value)); 295 } 296 297 310 public void setRadioButton(String formID, String tableID, int row, int col, int nth) 311 throws JaxenException, SAXException { 312 Element cb = (Element ) getNth(getCellNode(tableID, row, col), xpRadio, nth); 313 String name = cb.getAttribute("name"); 314 String value = cb.getAttribute("value"); 315 WebForm wf = getForm(formID); 316 wf.setParameter(name, value); 318 } 319 320 321 322 339 public void setSelect1(String formID, String tableID, int row, int col, int nth, int optind) 340 throws JaxenException, SAXException { 341 Element select = (Element ) getNth(getCellNode(tableID, row, col), xpSelect, nth); 342 String name = select.getAttribute("name"); 343 List options = xpOption.selectNodes(select); 344 Element option = (Element ) options.get(optind); 345 String value = option.getAttribute("value"); 346 WebForm wf = getForm(formID); 347 wf.setParameter(name, value); 349 } 350 351 public void setSelect1(String formID, String tableID, int row, int col, int nth, String optText) 352 throws JaxenException, SAXException { 353 Element select = (Element ) getNth(getCellNode(tableID, row, col), xpSelect, nth); 354 String name = select.getAttribute("name"); 355 List options = xpOption.selectNodes(select); 356 357 for (Iterator it = options.iterator(); it.hasNext();) { 358 Element option = (Element ) it.next(); 359 Text text = (Text) option.getChildNodes().item(0); 360 if (optText.equals(text.getData())) { 361 WebForm wf = getForm(formID); 362 wf.setParameter(name, option.getAttribute("value")); 364 return; 365 } 366 } 367 throw new IllegalArgumentException ("Option \"" + optText + "\" not found"); 368 } 369 370 387 public void setTextInput(String formID, String tableID, int row, int col, int nth, String value) 388 throws JaxenException, SAXException { 389 Element input = (Element ) getNth(getCellNode(tableID, row, col), xpTextInput, nth); 390 String name = input.getAttribute("name"); 391 WebForm wf = getForm(formID); 392 wf.setParameter(name, value); 393 } 394 395 412 public void setPassword(String formID, String tableID, int row, int col, int nth, String value) 413 throws JaxenException, SAXException { 414 Element input = (Element ) getNth(getCellNode(tableID, row, col), xpPassword, nth); 415 String name = input.getAttribute("name"); 416 WebForm wf = getForm(formID); 417 wf.setParameter(name, value); 418 } 419 420 424 public void setTextArea(String formID, String tableID, int row, int col, int nth, String value) 425 throws JaxenException, SAXException { 426 Element input = (Element ) getNth(getCellNode(tableID, row, col), xpTextArea, nth); 427 String name = input.getAttribute("name"); 428 WebForm wf = getForm(formID); 429 wf.setParameter(name, value); 430 } 431 432 433 434 private File getDir(String name) { 435 String path = System.getProperty("httpunit.dir") + name; 436 File dir = new File (path); 437 dir.mkdirs(); 438 return dir; 439 } 440 441 private void createParentDir(File f) { 442 File dir = f.getParentFile(); 443 dir.mkdirs(); 444 } 445 446 449 public File getLogDir() { 450 return getDir("/log"); 451 } 452 453 456 public File getRefDir() { 457 return getDir("/ref"); 458 } 459 460 467 public void saveHTML(String fileName) throws IOException { 468 saveTextFile(fileName + ".html", htmlLogFileEncoding); 469 } 470 471 private void saveTextFile(String fileName, String encoding) throws IOException { 472 File f = new File (getLogDir(), fileName); 473 createParentDir(f); 474 FileOutputStream fos = new FileOutputStream (f); 475 OutputStreamWriter osw = new OutputStreamWriter (fos, encoding); 476 try { 477 osw.write(wc.getCurrentPage().getText()); 478 } finally { 479 osw.close(); 480 } 481 } 482 483 488 public void saveTextFile(String fileName) throws IOException { 489 File f = new File (getLogDir(), fileName); 490 createParentDir(f); 491 Writer w = new FileWriter (f); 492 w.write(wc.getCurrentPage().getText()); 493 w.close(); 494 } 495 496 501 public void saveBinFile(String fileName) throws IOException { 502 File f = new File (getLogDir(), fileName); 503 createParentDir(f); 504 FileOutputStream out = null; 505 try { 506 out = new FileOutputStream (f); 507 508 InputStream in = null; 509 try { 510 in = wc.getCurrentPage().getInputStream(); 511 int c; 512 while ((c = in.read()) >= 0) 513 out.write(c); 514 515 } finally { 516 if (in != null) 517 in.close(); 518 } 519 } finally { 520 if (out != null) 521 out.close(); 522 } 523 } 524 525 536 public void saveXML(String fileName, String xslName, String id, Node root) 537 throws TransformerException { 538 Transformer trans = getTransformer(xslName); 539 trans.setParameter("id", id); 540 File f = new File (getLogDir(), fileName + ".xml"); 541 createParentDir(f); 542 trans.transform(new DOMSource (root), new StreamResult (f)); 543 } 544 545 548 public void saveXML(String fileName, Node root) throws TransformerException { 549 TransformerFactory tf = TransformerFactory.newInstance(); 550 Transformer trans = tf.newTransformer(); 551 trans.setOutputProperty(OutputKeys.ENCODING, "iso-8859-1"); 552 trans.setOutputProperty(OutputKeys.INDENT, "yes"); 553 trans.setOutputProperty(OutputKeys.METHOD, "xml"); 554 File f = new File (getLogDir(), fileName + ".xml"); 555 createParentDir(f); 556 trans.transform(new DOMSource (root), new StreamResult (f)); 557 } 558 559 public void check(String fileName, String xslName, String nodeId) throws IOException , 560 JaxenException, SAXException , TransformerException { 561 saveHTML(fileName); 562 saveXML(fileName, xslName, nodeId, wc.getCurrentPage().getDOM()); 563 Assert.assertTrue(fileName, equalsXML(fileName)); 564 } 565 566 571 public boolean equalsXML(String fileName) { 572 if (isRecordMode()) 573 return true; 574 File f1 = new File (getRefDir(), fileName + ".xml"); 575 File f2 = new File (getLogDir(), fileName + ".xml"); 576 return xmlDiff.equals(f1, f2); 577 } 578 579 584 public boolean equalsFile(String fileName) throws IOException { 585 return equalsFile(fileName, null); 586 } 587 588 591 public boolean equalsPdfFile(String fileName, FileDiffHandler handler) throws Exception { 592 if (isRecordMode()) 593 return true; 594 if (!fileName.endsWith(".pdf")) 595 throw new RuntimeException ("Error: pdf file name expected " + fileName); 596 597 String textName = fileName.substring(0, fileName.length() - 4) + ".txt"; 598 File pdfFile = new File (getLogDir(), fileName); 599 File textFile = new File (getLogDir(), textName); 600 601 ExtractText.main(new String [] { pdfFile.getAbsolutePath(), textFile.getAbsolutePath()}); 602 603 return equalsFile(textName, handler); 604 } 605 606 611 public boolean equalsFile(String fileName, FileDiffHandler handler) throws IOException { 612 if (isRecordMode()) 613 return true; 614 File f1 = new File (getRefDir(), fileName); 615 File f2 = new File (getLogDir(), fileName); 616 FileDiff fileDiff = new FileDiff(); 617 return fileDiff.equalsFiles(f1, f2, handler); 618 } 619 620 private Transformer getTransformer(String name) throws TransformerConfigurationException { 621 TransformerFactory tf = TransformerFactory.newInstance(); 622 URL url = this.getClass().getResource(name); 623 Templates templates = tf.newTemplates(new StreamSource (url.toExternalForm())); 624 return templates.newTransformer(); 625 } 626 627 630 public boolean isRecordMode() { 631 return recordMode; 632 } 633 634 637 public void setRecordMode(boolean b) { 638 recordMode = b; 639 } 640 641 public WebConversation setWc(WebConversation wc) { 642 WebConversation oldWc = wc; 643 this.wc = wc; 644 return oldWc; 645 } 646 647 650 public String getFragmentIdentifier() { 651 String url = wc.getCurrentPage().getURL().toExternalForm(); 652 int pos = url.indexOf('#'); 653 if (pos < 0) 654 return null; 655 return url.substring(pos + 1); 656 } 657 658 public XmlDiff getXmlDiff() { 659 return xmlDiff; 660 } 661 662 public String getHtmlLogFileEncoding() { 663 return htmlLogFileEncoding; 664 } 665 666 public void setHtmlLogFileEncoding(String htmlLogFileEncoding) { 667 this.htmlLogFileEncoding = htmlLogFileEncoding; 668 } 669 } | Popular Tags |