/******************************************************************************* * Copyright (c) 2016 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributor: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.freemarker.ui.bot.test.editor; import static org.junit.Assert.fail; import java.io.BufferedReader; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.util.List; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.Platform; import org.jboss.reddeer.common.logging.Logger; import org.jboss.reddeer.common.matcher.RegexMatcher; import org.jboss.reddeer.common.platform.RunningPlatform; import org.jboss.reddeer.common.wait.TimePeriod; import org.jboss.reddeer.common.wait.WaitUntil; import org.jboss.reddeer.common.wait.WaitWhile; import org.jboss.reddeer.core.condition.JobIsRunning; import org.jboss.reddeer.core.condition.ShellWithTextIsAvailable; import org.jboss.reddeer.core.matcher.WithTextMatcher; import org.jboss.reddeer.eclipse.condition.ConsoleHasText; import org.jboss.reddeer.eclipse.core.resources.Project; import org.jboss.reddeer.eclipse.core.resources.ProjectItem; import org.jboss.reddeer.eclipse.jdt.ui.ProjectExplorer; import org.jboss.reddeer.eclipse.jdt.ui.packageexplorer.PackageExplorer; import org.jboss.reddeer.eclipse.ui.console.ConsoleView; import org.jboss.reddeer.eclipse.ui.perspectives.JavaPerspective; import org.jboss.reddeer.eclipse.ui.views.log.LogMessage; import org.jboss.reddeer.eclipse.ui.views.log.LogView; import org.jboss.reddeer.eclipse.ui.wizards.datatransfer.ExternalProjectImportWizardDialog; import org.jboss.reddeer.eclipse.ui.wizards.datatransfer.WizardProjectsImportPage; import org.jboss.reddeer.swt.impl.menu.ContextMenu; import org.jboss.reddeer.workbench.handler.EditorHandler; import org.jboss.reddeer.workbench.ui.dialogs.WorkbenchPreferenceDialog; import org.jboss.tools.freemarker.ui.bot.test.Activator; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; /** * Freemarker test parent * @author Jiri Peterka * */ public abstract class AbstractFreemarkerTest { private static final Logger log = Logger.getLogger(FreeMarkerBaseEditorTest.class); protected static String projectName = "org.jboss.tools.freemarker.testprj"; protected static String parentFolder = "ftl"; @BeforeClass public static void beforeClass() { setFullOutlineView(); } @Before public void setUp() { log.step("Import test project for freemarker test"); importTestProject(); } @After public void after() { removeTestProject(projectName); ConsoleView console = new ConsoleView(); if (console.isOpened()) { console.clearConsole(); console.close(); } } /** * Sets Freemarker to full outline view mode */ public static void setFullOutlineView() { JavaPerspective p = new JavaPerspective(); p.open(); EditorHandler.getInstance().closeAll(false); new WaitWhile(new JobIsRunning()); JavaPerspective jp = new JavaPerspective(); jp.open(); WorkbenchPreferenceDialog dlg = new WorkbenchPreferenceDialog(); dlg.open(); dlg.select("FreeMarker"); log.step("Set Freemarker outline level to full level on freemarker preference page"); FreemarkerPreferencePage page = new FreemarkerPreferencePage(); page.setOutlineLevelOfDetail(OutlineLevelOfDetail.FULL); dlg.ok(); } /** * Imports freemarker test project */ public static void importTestProject() { ExternalProjectImportWizardDialog wizard = new ExternalProjectImportWizardDialog(); wizard.open(); String rpath = getResourceAbsolutePath( Activator.PLUGIN_ID, "resources/prj"); String wpath = getWorkspaceAbsolutePath(); File rfile = new File(rpath); File wfile = new File(wpath); try { copyFilesBinaryRecursively(rfile, wfile, null); } catch (IOException e) { fail("Unable to copy freemarker test project"); } WizardProjectsImportPage firstPage = new WizardProjectsImportPage(); firstPage.setRootDirectory(wpath); firstPage.selectAllProjects(); firstPage.copyProjectsIntoWorkspace(false); wizard.finish(); } /** * Check error log for errors */ public void checkErrorLog() { LogView el = new LogView(); el.open(); List<LogMessage> errorMessages = el.getErrorMessages(); for (LogMessage lm : errorMessages) { log.info(lm.getMessage()); } } /** * Read test file to string * @param filePath file path * @return content of the file * @throws IOException */ public String readTextFileToString(String filePath) throws IOException { BufferedReader br = null; try { br = new BufferedReader(new FileReader(filePath)); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { StringBuilder sb = new StringBuilder(); String line = br.readLine(); while (line != null) { sb.append(line); line = br.readLine(); if (line != null) sb.append("\n"); } String everything = sb.toString(); return everything; } finally { br.close(); } } /** * Provide bundle resource absolute path * @param pluginId - plugin id * @param path - resource relative path * @return resource absolute path */ public static String getResourceAbsolutePath(String pluginId, String... path) { // Construct path StringBuilder builder = new StringBuilder(); for (String fragment : path) { builder.append("/" + fragment); } String filePath = ""; try { filePath = FileLocator.toFileURL( Platform.getBundle(pluginId).getEntry("/")).getFile() + "resources" + builder.toString(); File file = new File(filePath); if (!file.isFile()) { filePath = FileLocator.toFileURL( Platform.getBundle(pluginId).getEntry("/")).getFile() + builder.toString(); } } catch (IOException ex) { String message = filePath + " resource file not found"; //log.error(message); fail(message); } return filePath; } /** * Gets workspace absolute path * @return current workspace absolute path */ public static String getWorkspaceAbsolutePath() { IWorkspace workspace = ResourcesPlugin.getWorkspace(); String path = workspace.getRoot().getLocation().toFile().getAbsolutePath(); return path; } /** * Recursively copies files and subdirectories from fromLocation to * toLocation using FileFilter fileFliter * * @param fromLocation * @param toLocation * @param fileFilter * @throws IOException */ public static void copyFilesBinaryRecursively(File fromLocation, File toLocation, FileFilter fileFilter) throws IOException { if (fromLocation.exists()) { for (File fileToCopy : fromLocation.listFiles(fileFilter)) { if (fileToCopy.isDirectory()) { File newToDir = new File(toLocation, fileToCopy.getName()); newToDir.mkdir(); copyFilesBinaryRecursively(fileToCopy, newToDir, fileFilter); } else { copyFilesBinary(fileToCopy, toLocation); } } } } /** * Remove freemarker test project */ public static void removeTestProject(String prj) { ProjectExplorer pe = new ProjectExplorer(); pe.open(); if (pe.containsProject(prj)) { pe.getProject(prj).delete(true); } } /** * Copies binary file originalFile to location toLocation * * @param originalFile * @param toLocation * @throws IOException */ public static void copyFilesBinary(File originalFile, File toLocation) throws IOException { FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream(originalFile); fos = new FileOutputStream(new File(toLocation, originalFile.getName())); byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = fis.read(buffer)) != -1) { fos.write(buffer, 0, bytesRead); // write } } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { // do nothing } } if (fos != null) { try { fos.flush(); fos.close(); } catch (IOException e) { // do nothing } } } } /** * Emtpy Error Log View */ public void emptyErrorLog() { LogView elv = new LogView(); elv.open(); elv.deleteLog(); new WaitWhile(new JobIsRunning()); } /** * Checks whether executed freemarker template is resulting correct output * @param outputIsInFile boolean value that distinguishes if expected output is in String or will * be read from file * * @param output expected output source (file or String) * @param alternateOutput alternate output string * @param runFile java file to be run as Java Application */ protected void checkFreemMarkerOutput(boolean outputIsInFile, String output, String alternateOutput, String... runFile) { String outputExpected = ""; if (outputIsInFile) { String outputFilepath = getResourceAbsolutePath( Activator.PLUGIN_ID, output); outputExpected = readOutputFromFile(outputFilepath); } else { outputExpected = output; } runJavaFile(runFile); new WaitUntil(new ConsoleHasText(outputExpected), TimePeriod.NORMAL, false); ConsoleView cv = new ConsoleView(); cv.open(); String consoleText = cv.getConsoleText(); if (!consoleText.equals(outputExpected)) { } // workaround for slightly different format on Windows compareConsoleToOutput(consoleText, outputExpected, alternateOutput); } /** * If given alternate expected result, checks whether we are running on Windows platform, * if yes, it checks whether console output contains alternate output. Otherwise it tries if * expected output and resulting console output are equal, using String equals method. * Otherwise it checks whether trimmed console output is equal to trimmed expected output. * * @param console String content of console that will be compared * @param output Expected output represented by String * @param alternateOutput Alternate output used for Windows platform */ private void compareConsoleToOutput(String console, String output, String alternateOutput) { if (RunningPlatform.isWindows() && alternateOutput != null && alternateOutput.length() > 0) { log.info("Testing alternative output for windows platform: \n" + alternateOutput); output = alternateOutput.replaceAll("(\\r|\\n|\\r\\n)+", System.lineSeparator()); console = console.replaceAll("(\\r|\\n|\\r\\n)+", System.lineSeparator()); } checkOutput(console, output); } /** * Compares two test outputs and reports error if text objects does not match * after calling equals, equals (with trimmed text) and contains with trimmed methods * @param consoleText text obtained from console * @param expectedText */ private void checkOutput(String consoleText, String expectedText) { if (consoleText.equals(expectedText)) { log.info("Console text corresponds to expected output"); } else if (consoleText.trim().equals(expectedText.trim())) { log.info("Console text corresponds to expected output after trimming"); } else if (consoleText.trim().contains(expectedText.trim())) { log.info("Console text contains expected output after trimming"); } else { log.error("Console text doesn't correspond with expected text"); log.dump("Console text:\n" + consoleText); log.dump("Expected text:\n" + expectedText); fail("Console text does not corresponds to the expected output"); } } /** * Returns content of a file as a String * * @param absolutePath absolute file path * @return Content of given file specified by absolute path as a String */ private String readOutputFromFile(String absolutePath) { String outputExpected = ""; try { outputExpected = readTextFileToString(absolutePath); log.info("------------------------------------------"); log.info(outputExpected); log.info("------------------------------------------"); } catch (IOException e) { log.error(e.getMessage()); new RuntimeException("Unable to read from resource"); } return outputExpected; } /** * Tries to run given file path in Project explorer as a Java Application * * @param javaFilePath File path specified as a array of strings */ @SuppressWarnings("unchecked") private void runJavaFile(String... javaFilePath) { PackageExplorer explorer = new PackageExplorer(); Project project = explorer.getProject(projectName); ProjectItem item = project.getProjectItem(javaFilePath); item.select(); WithTextMatcher regex = new WithTextMatcher(new RegexMatcher(".*Java Application.*")); new ContextMenu(new WithTextMatcher("Run As"), regex).select(); new WaitUntil(new ShellWithTextIsAvailable("Progress Information"), TimePeriod.NORMAL, false); new WaitWhile(new ShellWithTextIsAvailable("Progress Information")); new WaitWhile(new JobIsRunning()); } }