@Inject public JFunkWebDriverEventListener( final Configuration config, @ModuleArchiveDir final Provider<File> moduleArchiveDirProvider, final Provider<DumpFileCreator> dumpFileCreatorProvider) { this.config = config; this.moduleArchiveDirProvider = moduleArchiveDirProvider; this.dumpFileCreatorProvider = dumpFileCreatorProvider; this.saveOutputMap = new EnumMap<>(SaveOutput.class); for (SaveOutput saveOutput : SaveOutput.values()) { // active flag for every output type saveOutputMap.put( saveOutput, config.getBoolean( JFunkConstants.ARCHIVE_INCLUDE + saveOutput.getIdentifier(), saveOutput.isActiveByDefault())); } }
/** * Saves the currently displayed browser window. The page title is used for the filename - * preceded by some identifying information (thread, counter). Pages of the same type are * collected inside the same subdirectory. The subdirectory uses {@link * SaveOutput#getIdentifier()} for its name. If an alert is present, saving is not supported and * thus skipped. * * @param action the event which triggered to save the page. Will be included in the filename. * @param triggeredBy the object which triggered the event (e.g. a button or a link) */ protected void savePage(final WebDriver driver, final String action, final String triggeredBy) { try { // this updates the driver's window handles, so a subsequent call to // getWindowHandle() fails if the window no longer exists driver.getWindowHandles(); driver.getWindowHandle(); } catch (NoSuchWindowException ex) { // Window is already closed. Saving the page could cause problems, e. g. // ChromeDriver ould hang. return; } File moduleArchiveDir = moduleArchiveDirProvider.get(); if (moduleArchiveDir == null) { return; } if (config.getBoolean(JFunkConstants.ARCHIVE_DO_NOT_SAVE_WHEN_ALERT, false)) { try { // Saving the page does not work if an alert is present driver.switchTo().alert(); log.trace("Cannot save page. Alert is present."); return; } catch (NoAlertPresentException ex) { // ignore } catch (UnsupportedOperationException ex) { // ignore // HtmlUnit does not support alerts } catch (Exception ex) { // ignore } } for (SaveOutput saveOutput : SaveOutput.values()) { boolean saveSwitch = saveOutputMap.get(saveOutput); if (!saveSwitch) { // Saving is disabled by property continue; } File f = null; try { f = dumpFileCreatorProvider .get() .createDumpFile( new File(moduleArchiveDir, saveOutput.getIdentifier()), saveOutput.getExtension(), driver.getCurrentUrl(), action); if (f == null) { return; } switch (saveOutput) { case HTML: StringBuilder html = new StringBuilder(); html.append("<!-- Requested URL: "); html.append(driver.getCurrentUrl()); html.append(" -->"); html.append(IOUtils.LINE_SEPARATOR); html.append(driver.getPageSource()); writeStringToFile(f, html.toString(), "UTF-8"); copyFile(f, new File(moduleArchiveDir, JFunkConstants.LASTPAGE_HTML)); log.trace( "Saving page: filename={}, action={}, trigger={}, response={}", f.getName(), action, triggeredBy, driver.getCurrentUrl()); break; case PNG: if (driver instanceof TakesScreenshot) { File tmpFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE); if (tmpFile != null) { copyFile(tmpFile, f); log.trace( "Saving page: filename={}, action={}, trigger={}, response={}", f.getName(), action, triggeredBy, driver.getCurrentUrl()); deleteQuietly(tmpFile); } } break; case HTML_VALIDATION: /* * JFunkWebDriver.getPageSource() doesn't return the complete page source * e.g. DOCTYPE is missing. Therefore we are using a more complicated way to * retrieve the "real" page source. However, this only works when using * HtmlUnitDriver. */ if (WebDriverUtils.isHtmlUnitDriver(driver)) { String content = ((HtmlPage) WebDriverUtils.getHtmlUnitDriverWebClient(driver) .getCurrentWindow() .getEnclosedPage()) .getWebResponse() .getContentAsString(); writeStringToFile(f, content, "UTF-8"); HtmlValidatorUtil.validateHtml(f.getParentFile(), config, f); } break; default: throw new IllegalStateException("unknown enum constant"); } } catch (Exception ex) { log.error("Could not save file: {}. {}", f, ex.getMessage()); return; } } }