6.9. HTML2PDF - Hat die dynamische PDF-Erstellung funktioniert?

Ausgangssituation

Eine Webanwendung erzeugt dynamische Webseiten und bietet außerdem die Möglichkeit, den Inhalt der aktuellen Webseite als PDF-Dokument herunterzuladen. Dazu wird die HTML-Seite dynamisch in PDF gerendert.

Problem

Wie kann sichergestellt werden, dass der Inhalt der HTML-Seite und der Inhalt der PDF-Seite übereinstimmen? Es ist ja nicht ausgeschlossen, dass das Rendering-Werkzeug Randbedingungen benötigt, die unbekannt sind und damit eventuell nicht eingehalten werden.

Lösungsansatz

Die HTML-Seite wird mit Selenium angesteuert, der erwartete Text wird mit Selenium ausgelesen und in Variablen gespeichert.

Anschließend wird die PDF-Erstellung über die Webseite angestoßen und das erhaltene PDF-Dokument mit PDFUnit auf genau dieselben Texte überprüft.

Lösung

/**
 * This sample shows how to test an HTML page with Selenium, then let it be rendered 
 * by the server to PDF and verify that content also appears in PDF.
 * 
 * @author Carsten Siedentop, February 2013
 */
public class Html2PDFTest {

  private WebDriver driver;

  @Test
  public void testHtml2PDFRenderer_WikipediaSeleniumEnglish() throws Exception {
    String urlWikipediaSelenium = "http://en.wikipedia.org/wiki/Selenium_%28software%29";
    driver.get(urlWikipediaSelenium);

    String section1  = "History";
    String section2  = "Components";
    String section3  = "The Selenium ecosystem";
    String section4  = "References";
    String section5  = "External links";

    assertLinkPresent(section1);
    assertLinkPresent(section2);
    assertLinkPresent(section3);
    assertLinkPresent(section4);
    assertLinkPresent(section5);
    
    String linkName = "Download as PDF";
    URL url = loadPDF(linkName);
    
    AssertThat.document(url)
              .restrictedTo(ANY_PAGE)
              .hasText()
              .containing(section1,  WhitespaceProcessing.IGNORE)
              .containing(section2,  WhitespaceProcessing.IGNORE)
              .containing(section3,  WhitespaceProcessing.IGNORE)
              .containing(section4,  WhitespaceProcessing.IGNORE)
              .containing(section5,  WhitespaceProcessing.IGNORE)
    ;
  }

  private void assertLinkPresent(String partOfLinkText) {
    driver.findElement(By.xpath("//a[./span = '" + partOfLinkText + "']"));
  }

  private URL loadPDF(String linkName_LoadAsPDF) throws Exception {
    driver.findElement(By.linkText(linkName_LoadAsPDF)).click();
    String title = "Rendering finished - Wikipedia, the free encyclopedia";
    assertEquals(title, driver.getTitle());
    WebElement element = driver.findElement(By.linkText("Download the file"));
    String hrefValue = element.getAttribute("href");
    URL url = new URL(hrefValue); 
    return url;
  }

  @After
  public void tearDown() throws Exception {
    driver.quit();
  }

  @Before
  public void createDriver() throws Exception {
    driver = new HtmlUnitDriver();
  }
  
}