Java tutorial
/******************************************************************************* * Copyright (c) 2005, 2010 Stein K. Skytteren and Christian Schwarz * All rights reserved. This program and the accompanying materials * are 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 * * Contributors: * Stein K. Skytteren and Christian Schwarz - initial API and implementation *******************************************************************************/ package org.cubictest.exporters.selenium.launch; import java.io.File; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.cubictest.common.utils.ErrorHandler; import org.cubictest.common.utils.Logger; import org.cubictest.common.utils.UserInfo; import org.cubictest.export.ICubicTestRunnable; import org.cubictest.exporters.selenium.SeleniumExporterPlugin; import org.cubictest.exporters.selenium.common.BrowserType; import org.cubictest.exporters.selenium.runner.SeleniumRunnerConfiguration; import org.cubictest.exporters.selenium.runner.holders.SeleniumHolder; import org.cubictest.exporters.selenium.ui.CustomStepWizard; import org.cubictest.model.Test; import org.cubictest.persistence.TestPersistance; import org.cubictest.ui.gef.editors.GraphicalTestEditor; import org.cubictest.ui.gef.interfaces.exported.ITestEditor; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.launching.AbstractJavaLaunchConfigurationDelegate; import org.eclipse.jdt.launching.ExecutionArguments; import org.eclipse.jdt.launching.IVMRunner; import org.eclipse.jdt.launching.SocketUtil; import org.eclipse.jdt.launching.VMRunnerConfiguration; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.ide.IDE; public abstract class LaunchConfigurationDelegate extends AbstractJavaLaunchConfigurationDelegate { private static final String CUBICTEST_SELENIUM_RUNNER_CLASS = "org.cubictest.runner.selenium.server.internal.CubicTestRemoteRunnerServer"; private static final String ERROR_INVALID_PROJECT_GOT_TO_BE_A_JAVA_PROJEDT = "Error invalid project, got to be a java project"; private static final String REMOTE_CUBIC_RUNNER_IS_NOT_ON_THE_CLASSPATH = "RemoteCubicRunner is not on the classpath, " + "please add the CubicTest Selenium Library to the path"; private static final String CUBIC_RUNNER_COULD_NOT_FIND_FREE_PORT = "CubicRunner could not find free port"; private static final String CUBIC_UNIT_PORT = "CUBIC_UNIT_PORT"; private static final String SELENIUM_CLIENT_PROXY = "SELENIUM_CLIENT_PROXY"; private int serverPort; private String seleniumHost; private int seleniumPort; private boolean seleniumMultiWindow; private int seleniumClientProxyPort; private Test test; private ITestEditor testEditor; @Override public String getMainTypeName(ILaunchConfiguration configuration) throws CoreException { return CUBICTEST_SELENIUM_RUNNER_CLASS; } public void setTest(Test test) { this.test = test; } public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { if (monitor == null) { monitor = new NullProgressMonitor(); } monitor.beginTask(MessageFormat.format("{0}...", new String[] { configuration.getName() }), 5); // check for cancellation if (monitor.isCanceled()) { return; } try { monitor.subTask("Verifying attributes"); try { preLaunchCheck(configuration, launch, new SubProgressMonitor(monitor, 2)); } catch (CoreException e) { if (e.getStatus().getSeverity() == IStatus.CANCEL) { monitor.setCanceled(true); return; } throw e; } // check for cancellation if (monitor.isCanceled()) { return; } serverPort = evaluatePort(); seleniumClientProxyPort = evaluatePort(); launch.setAttribute(CUBIC_UNIT_PORT, String.valueOf(serverPort)); launch.setAttribute(SELENIUM_CLIENT_PROXY, String.valueOf(seleniumClientProxyPort)); String mainTypeName = verifyMainTypeName(configuration); IVMRunner runner = getVMRunner(configuration, mode); File workingDir = verifyWorkingDirectory(configuration); String workingDirName = null; if (workingDir != null) { workingDirName = workingDir.getAbsolutePath(); } // Environment variables String[] envp = getEnvironment(configuration); ArrayList<Object> vmArguments = new ArrayList<Object>(); ArrayList<Object> programArguments = new ArrayList<Object>(); collectExecutionArguments(configuration, vmArguments, programArguments); // VM-specific attributes Map<?, ?> vmAttributesMap = getVMSpecificAttributesMap(configuration); // Classpath String[] classpath = getClasspath(configuration); // Create VM config VMRunnerConfiguration runConfig = new VMRunnerConfiguration(mainTypeName, classpath); runConfig.setVMArguments((String[]) vmArguments.toArray(new String[vmArguments.size()])); runConfig.setProgramArguments((String[]) programArguments.toArray(new String[programArguments.size()])); runConfig.setEnvironment(envp); runConfig.setWorkingDirectory(workingDirName); runConfig.setVMSpecificAttributesMap(vmAttributesMap); // Bootpath runConfig.setBootClassPath(getBootpath(configuration)); // check for cancellation if (monitor.isCanceled()) { return; } // done the verification phase monitor.worked(1); monitor.subTask("Create source locator description"); // set the default source locator if required setDefaultSourceLocator(launch, configuration); monitor.worked(1); // Launch the configuration - 1 unit of work runner.run(runConfig, launch, monitor); // check for cancellation if (monitor.isCanceled()) { return; } IJavaProject project = getJavaProject(configuration); String fileName = getTestFileName(configuration); final IFile testFile = project.getProject().getFile(fileName); IWorkbench wb = PlatformUI.getWorkbench(); IWorkbenchWindow wbw = wb.getActiveWorkbenchWindow(); if (wbw == null) wbw = wb.getWorkbenchWindows()[0]; IWorkbenchPage ap = wbw.getActivePage(); if (ap == null) ap = wbw.getPages()[0]; final IWorkbenchPage finalAp = ap; wb.getDisplay().syncExec(new Runnable() { public void run() { try { GraphicalTestEditor editor = (GraphicalTestEditor) IDE.openEditor(finalAp, testFile); setTest(editor.getTest()); setTestEditor(editor); editor.getTest().resetStatus(); editor.getTest().refreshAndVerifySubFiles(); } catch (Exception e) { Logger.warn("Error opening test in editor", e); setTest(TestPersistance.loadFromFile(testFile)); } } }); String browser = getBrowser(configuration); boolean useNamespace = useNamespace(configuration); seleniumHost = getSeleniumHost(configuration); seleniumPort = getSeleniumPort(configuration); if (seleniumPort < 0) seleniumPort = evaluatePort(); seleniumMultiWindow = getSeleniumMultiWindow(configuration); // create the parameters: RunnerParameters parameters = new RunnerParameters(); parameters.test = test; parameters.display = wb.getDisplay(); parameters.remoteRunnerClientListenerPort = serverPort; parameters.seleniumClientProxyPort = seleniumClientProxyPort; SeleniumRunnerConfiguration config = new SeleniumRunnerConfiguration(); if (!isSeleniumServerAutoHostAndPort(configuration)) { config.setUseExistingSeleniumServer(seleniumHost, seleniumPort); } config.setBrowser(BrowserType.fromId(browser)); config.setMultiWindow(seleniumMultiWindow); config.setSupportXHtmlNamespaces(useNamespace); config.setHtmlCaptureAndScreenshotsTargetDir(workingDirName); config.setTakeScreenshots(getSeleniumTakeScreenshots(configuration)); config.setCaptureHtml(getSeleniumCaptureHtml(configuration)); verifyPreconditions(parameters, config); final ICubicTestRunnable cubicTestRunnable = getCubicTestRunnable(parameters, config); try { // run! cubicTestRunnable.run(monitor); // show result message wb.getDisplay().syncExec(new Runnable() { public void run() { if (StringUtils.isNotBlank(cubicTestRunnable.getResultMessage())) { final String msg = "Test run finished. " + cubicTestRunnable.getResultMessage(); UserInfo.showInfoDialog(msg); } } }); project.getResource().refreshLocal(IResource.DEPTH_ONE, null); IResource outputFolder = project.getProject() .findMember(SeleniumHolder.HTML_AND_SCREENSHOTS_FOLDER_NAME); if (outputFolder != null) { outputFolder.refreshLocal(IResource.DEPTH_INFINITE, null); } } catch (final Exception e) { wb.getDisplay().syncExec(new Runnable() { public void run() { ErrorHandler.logAndShowErrorDialog("Error when running test", e); } }); } finally { cubicTestRunnable.cleanUp(); } } catch (Exception e) { Logger.error("Error launching test", e); } finally { monitor.done(); } } /** To be overridden by runner implementations. */ protected abstract void verifyPreconditions(RunnerParameters parameters, SeleniumRunnerConfiguration config); /** To be overridden by runner implementations. */ protected abstract ICubicTestRunnable getCubicTestRunnable(RunnerParameters parameters, SeleniumRunnerConfiguration config); private String getBrowser(ILaunchConfiguration configuration) { try { return configuration.getAttribute(SeleniumRunnerTab.CUBIC_TEST_BROWSER, BrowserType.FIREFOX.getId()); } catch (CoreException e) { Logger.error("Error getting property", e); } return BrowserType.FIREFOX.getId(); } public boolean useNamespace(ILaunchConfiguration configuration) { try { return configuration.getAttribute(SeleniumRunnerTab.CUBIC_TEST_NAMESPACE_XPATH, false); } catch (CoreException e) { Logger.error("Error getting property", e); } return false; } private String getTestFileName(ILaunchConfiguration configuration) { try { return configuration.getAttribute(SeleniumRunnerTab.CUBIC_TEST_NAME, ""); } catch (CoreException e) { Logger.error("Error getting property", e); } return null; } private String getSeleniumHost(ILaunchConfiguration configuration) { try { return configuration.getAttribute(SeleniumRunnerTab.CUBIC_TEST_SELENIUM_SERVER_HOST, ""); } catch (CoreException e) { Logger.error("Error getting property", e); } return null; } private int getSeleniumPort(ILaunchConfiguration configuration) { try { return Integer .parseInt(configuration.getAttribute(SeleniumRunnerTab.CUBIC_TEST_SELENIUM_SERVER_PORT, "")); } catch (CoreException e) { Logger.error("Error getting property", e); } catch (Exception e) { Logger.error("Error getting property", e); } return -1; } private boolean getSeleniumMultiWindow(ILaunchConfiguration configuration) { try { return configuration.getAttribute(SeleniumRunnerTab.CUBIC_TEST_SELENIUM_SERVER_MULTI_WINDOW, false); } catch (Exception e) { Logger.error("Error getting property", e); return false; } } private boolean getSeleniumTakeScreenshots(ILaunchConfiguration configuration) { try { return configuration.getAttribute(SeleniumRunnerTab.CUBIC_TEST_SELENIUM_TAKE_SCREENSHOTS, false); } catch (Exception e) { Logger.error("Error getting property", e); return false; } } private boolean getSeleniumCaptureHtml(ILaunchConfiguration configuration) { try { return configuration.getAttribute(SeleniumRunnerTab.CUBIC_TEST_SELENIUM_CAPTURE_HTML, false); } catch (Exception e) { Logger.error("Error getting property", e); return false; } } private boolean isSeleniumServerAutoHostAndPort(ILaunchConfiguration configuration) { try { return configuration.getAttribute(SeleniumRunnerTab.CUBIC_TEST_SELENIUM_SERVER_AUTO_HOST_AND_PORT, true); } catch (Exception e) { Logger.error("Error getting property", e); return false; } } /** * Performs a check on the launch configuration's attributes. If an * attribute contains an invalid value, a {@link CoreException} with the * error is thrown. * * @param configuration * the launch configuration to verify * @param launch * the launch to verify * @param monitor * the progress monitor to use * @throws CoreException * an exception is thrown when the verification fails */ private void preLaunchCheck(ILaunchConfiguration configuration, ILaunch launch, IProgressMonitor monitor) throws CoreException { try { final IJavaProject javaProject = getJavaProject(configuration); if ((javaProject == null) || !javaProject.exists()) { ErrorHandler.logAndShowErrorDialog(ERROR_INVALID_PROJECT_GOT_TO_BE_A_JAVA_PROJEDT); throw new CoreException(new Status(IStatus.ERROR, SeleniumExporterPlugin.PLUGIN_ID, ERROR_INVALID_PROJECT_GOT_TO_BE_A_JAVA_PROJEDT)); } if (javaProject.findType(CUBICTEST_SELENIUM_RUNNER_CLASS) != null) { return; } PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { public void run() { CustomStepWizard.addLibToClasspath(javaProject, new Shell()); } }); if (javaProject.findType(CUBICTEST_SELENIUM_RUNNER_CLASS) != null) { return; } else { PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() { public void run() { ErrorHandler.logAndShowErrorDialog(REMOTE_CUBIC_RUNNER_IS_NOT_ON_THE_CLASSPATH); } }); } throw new CoreException(new Status(IStatus.ERROR, SeleniumExporterPlugin.PLUGIN_ID, REMOTE_CUBIC_RUNNER_IS_NOT_ON_THE_CLASSPATH)); } finally { monitor.done(); } } private int evaluatePort() throws CoreException { int port = SocketUtil.findFreePort(); if (port == -1) { ErrorHandler.logAndShowErrorDialog(CUBIC_RUNNER_COULD_NOT_FIND_FREE_PORT); throw new CoreException(new Status(IStatus.ERROR, SeleniumExporterPlugin.PLUGIN_ID, CUBIC_RUNNER_COULD_NOT_FIND_FREE_PORT)); } return port; } /** * Collects all VM and program arguments. Implementors can modify and add * arguments. * * @param configuration * the configuration to collect the arguments for * @param vmArguments * a {@link List} of {@link String} representing the resulting VM * arguments * @param programArguments * a {@link List} of {@link String} representing the resulting * program arguments * @exception CoreException * if unable to collect the execution arguments */ protected void collectExecutionArguments(ILaunchConfiguration configuration, List<Object>/* String */ vmArguments, List<Object>/* String */ programArguments) throws CoreException { // add program & VM arguments provided by getProgramArguments and // getVMArguments String pgmArgs = getProgramArguments(configuration); String vmArgs = getVMArguments(configuration); ExecutionArguments execArgs = new ExecutionArguments(vmArgs, pgmArgs); vmArguments.addAll(Arrays.asList(execArgs.getVMArgumentsArray())); programArguments.addAll(Arrays.asList(execArgs.getProgramArgumentsArray())); programArguments.add("-port:" + String.valueOf(serverPort)); programArguments.add("-seleniumClientProxyPort:" + String.valueOf(seleniumClientProxyPort)); } private void setTestEditor(ITestEditor testEditor) { this.testEditor = testEditor; } protected ITestEditor getTestEditor() { return testEditor; } }