/*
* SoapUI, Copyright (C) 2004-2016 SmartBear Software
*
* Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent
* versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://ec.europa.eu/idabc/eupl
*
* Unless required by applicable law or agreed to in writing, software distributed under the Licence is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the Licence for the specific language governing permissions and limitations
* under the Licence.
*/
package com.eviware.soapui.impl.wsdl.panels.testsuite;
import com.eviware.soapui.SoapUI;
import com.eviware.soapui.analytics.Analytics;
import com.eviware.soapui.analytics.SoapUIActions;
import com.eviware.soapui.impl.support.actions.ShowOnlineHelpAction;
import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
import com.eviware.soapui.impl.wsdl.actions.testsuite.AddNewTestCaseAction;
import com.eviware.soapui.impl.wsdl.panels.support.MockTestSuiteRunner;
import com.eviware.soapui.impl.wsdl.panels.testcase.JTestRunLog;
import com.eviware.soapui.impl.wsdl.panels.testcase.TestRunLogTestRunListener;
import com.eviware.soapui.impl.wsdl.panels.teststeps.support.AbstractGroovyEditorModel;
import com.eviware.soapui.impl.wsdl.panels.teststeps.support.PropertyHolderTable;
import com.eviware.soapui.impl.wsdl.support.HelpUrls;
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestSuiteRunner;
import com.eviware.soapui.model.ModelItem;
import com.eviware.soapui.model.support.TestSuiteListenerAdapter;
import com.eviware.soapui.model.testsuite.TestCase;
import com.eviware.soapui.model.testsuite.TestCaseRunner;
import com.eviware.soapui.model.testsuite.TestSuite.TestSuiteRunType;
import com.eviware.soapui.model.testsuite.TestSuiteRunContext;
import com.eviware.soapui.model.testsuite.TestSuiteRunListener;
import com.eviware.soapui.model.testsuite.TestSuiteRunner;
import com.eviware.soapui.settings.UISettings;
import com.eviware.soapui.support.DocumentListenerAdapter;
import com.eviware.soapui.support.StringUtils;
import com.eviware.soapui.support.UISupport;
import com.eviware.soapui.support.action.swing.SwingActionDelegate;
import com.eviware.soapui.support.components.GroovyEditorComponent;
import com.eviware.soapui.support.components.GroovyEditorInspector;
import com.eviware.soapui.support.components.JComponentInspector;
import com.eviware.soapui.support.components.JFocusableComponentInspector;
import com.eviware.soapui.support.components.JInspectorPanel;
import com.eviware.soapui.support.components.JInspectorPanelFactory;
import com.eviware.soapui.support.components.JUndoableTextArea;
import com.eviware.soapui.support.components.JXToolBar;
import com.eviware.soapui.support.types.StringToObjectMap;
import com.eviware.soapui.ui.support.KeySensitiveModelItemDesktopPanel;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JToggleButton;
import javax.swing.text.Document;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* DesktopPanel for WsdlTestSuite
*
* @author Ole.Matzura
*/
@SuppressWarnings("serial")
public class WsdlTestSuiteDesktopPanel extends KeySensitiveModelItemDesktopPanel<WsdlTestSuite> {
private JProgressBar progressBar;
private JTestSuiteTestCaseList testCaseList;
private RunAction runAction = new RunAction();
private CancelAction cancelAction = new CancelAction();
private JToggleButton sequentialButton;
private JToggleButton parallellButton;
private final InternalTestSuiteListener testSuiteListener = new InternalTestSuiteListener();
private final InternalTestSuiteRunListener testSuiteRunListener = new InternalTestSuiteRunListener();
private JTextArea descriptionArea;
private PropertyHolderTable propertiesTable;
private JTestRunLog testRunLog;
private GroovyEditorComponent tearDownGroovyEditor;
private GroovyEditorComponent setupGroovyEditor;
private JInspectorPanel testCaseListInspectorPanel;
private JInspectorPanel inspectorPanel;
private WsdlTestSuiteRunner testSuiteRunner;
public WsdlTestSuiteDesktopPanel(WsdlTestSuite testSuite) {
super(testSuite);
buildUI();
testSuite.addTestSuiteListener(testSuiteListener);
testSuite.addTestSuiteRunListener(testSuiteRunListener);
}
private void buildUI() {
add(buildToolbar(), BorderLayout.NORTH);
add(buildContent(), BorderLayout.CENTER);
setPreferredSize(new Dimension(500, 500));
}
private JComponent buildContent() {
inspectorPanel = JInspectorPanelFactory.build(buildTabs());
inspectorPanel.addInspector(new JComponentInspector<JComponent>(buildRunLog(), "TestSuite Log",
"Log of executed TestCases and TestSteps", true));
if (StringUtils.hasContent(getModelItem().getDescription())
&& getModelItem().getSettings().getBoolean(UISettings.SHOW_DESCRIPTIONS)) {
testCaseListInspectorPanel.setCurrentInspector("Description");
}
return inspectorPanel.getComponent();
}
private JComponent buildRunLog() {
testRunLog = new JTestRunLog(getModelItem().getSettings());
return testRunLog;
}
protected JTestSuiteTestCaseList getTestCaseList() {
return testCaseList;
}
private JComponent buildToolbar() {
cancelAction.setEnabled(false);
runAction.setEnabled(getModelItem().getTestCaseCount() > 0);
JXToolBar toolbar = UISupport.createToolbar();
addToolbarActions(toolbar);
toolbar.addGlue();
toolbar.add(UISupport.createToolbarButton(new ShowOnlineHelpAction(HelpUrls.TESTSUITE_HELP_URL)));
progressBar = new JProgressBar(0, getModelItem().getTestCaseCount());
JPanel progressPanel = UISupport.createProgressBarPanel(progressBar, 10, false);
JPanel panel = new JPanel(new BorderLayout());
panel.add(toolbar, BorderLayout.PAGE_START);
panel.add(progressPanel, BorderLayout.CENTER);
return panel;
}
protected void addToolbarActions(JXToolBar toolbar) {
toolbar.add(UISupport.createToolbarButton(runAction));
toolbar.add(UISupport.createToolbarButton(cancelAction));
ButtonGroup buttonGroup = new ButtonGroup();
sequentialButton = new JToggleButton(UISupport.createImageIcon("/sequential.gif"), true);
sequentialButton.setToolTipText("The selected TestCases are run in sequence");
sequentialButton.setPreferredSize(UISupport.getPreferredButtonSize());
sequentialButton.setSelected(getModelItem().getRunType() == TestSuiteRunType.SEQUENTIAL);
sequentialButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
getModelItem().setRunType(TestSuiteRunType.SEQUENTIAL);
}
});
buttonGroup.add(sequentialButton);
parallellButton = new JToggleButton(UISupport.createImageIcon("/parallell.gif"));
parallellButton.setToolTipText("The selected TestCases are run in parallel");
parallellButton.setPreferredSize(UISupport.getPreferredButtonSize());
parallellButton.setSelected(getModelItem().getRunType() == TestSuiteRunType.PARALLEL);
parallellButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
getModelItem().setRunType(TestSuiteRunType.PARALLEL);
}
});
buttonGroup.add(parallellButton);
toolbar.add(sequentialButton);
toolbar.add(parallellButton);
}
private JComponent buildTabs() {
JTabbedPane tabs = new JTabbedPane(JTabbedPane.TOP);
testCaseListInspectorPanel = JInspectorPanelFactory.build(buildTestCaseList(getModelItem()));
tabs.addTab("TestCases", testCaseListInspectorPanel.getComponent());
addTabs(tabs, testCaseListInspectorPanel);
tabs.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
return UISupport.createTabPanel(tabs, true);
}
protected void addTabs(JTabbedPane tabs, JInspectorPanel inspectorPanel) {
inspectorPanel.addInspector(new JFocusableComponentInspector<JPanel>(buildDescriptionPanel(), descriptionArea,
"Description", "Description for this TestSuite", true));
inspectorPanel.addInspector(new JComponentInspector<JComponent>(buildPropertiesPanel(), "Properties",
"TestSuite level properties", true));
inspectorPanel.addInspector(new GroovyEditorInspector(buildSetupScriptPanel(), "Setup Script",
"Script to run before running the TestSuite"));
inspectorPanel.addInspector(new GroovyEditorInspector(buildTearDownScriptPanel(), "TearDown Script",
"Script to run after running the TestSuite"));
}
protected GroovyEditorComponent buildTearDownScriptPanel() {
tearDownGroovyEditor = new GroovyEditorComponent(new TearDownScriptGroovyEditorModel(), null);
return tearDownGroovyEditor;
}
protected GroovyEditorComponent buildSetupScriptPanel() {
setupGroovyEditor = new GroovyEditorComponent(new SetupScriptGroovyEditorModel(), null);
return setupGroovyEditor;
}
private JComponent buildPropertiesPanel() {
JPanel panel = new JPanel(new BorderLayout());
propertiesTable = createPropertyHolderTable();
panel.add(propertiesTable, BorderLayout.CENTER);
return panel;
}
protected PropertyHolderTable createPropertyHolderTable() {
return new PropertyHolderTable(getModelItem());
}
private JPanel buildDescriptionPanel() {
JPanel panel = new JPanel(new BorderLayout());
descriptionArea = new JUndoableTextArea(getModelItem().getDescription());
descriptionArea.getDocument().addDocumentListener(new DocumentListenerAdapter() {
public void update(Document document) {
getModelItem().setDescription(descriptionArea.getText());
}
});
panel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
panel.add(new JScrollPane(descriptionArea), BorderLayout.CENTER);
UISupport.addTitledBorder(panel, "TestSuite Description");
return panel;
}
protected JComponent buildTestCaseList(WsdlTestSuite testSuite) {
testCaseList = new JTestSuiteTestCaseList(testSuite);
JPanel p = new JPanel(new BorderLayout());
p.add(buildTestCaseListToolbar(), BorderLayout.NORTH);
p.add(new JScrollPane(testCaseList), BorderLayout.CENTER);
return p;
}
private Component buildTestCaseListToolbar() {
JXToolBar toolbar = UISupport.createToolbar();
toolbar.add(UISupport.createToolbarButton(SwingActionDelegate.createDelegate(
AddNewTestCaseAction.SOAPUI_ACTION_ID, getModelItem(), null, "/testcase.png")));
toolbar.addGlue();
toolbar.add(UISupport.createToolbarButton(new ShowOnlineHelpAction(HelpUrls.TESTSUITEEDITOR_HELP_URL)));
return toolbar;
}
public boolean onClose(boolean canCancel) {
propertiesTable.release();
inspectorPanel.release();
testCaseListInspectorPanel.release();
setupGroovyEditor.getEditor().release();
tearDownGroovyEditor.getEditor().release();
testRunLog.release();
getModelItem().removeTestSuiteRunListener(testSuiteRunListener);
getModelItem().removeTestSuiteListener(testSuiteListener);
return super.release();
}
public JComponent getComponent() {
return this;
}
public boolean dependsOn(ModelItem modelItem) {
return modelItem == getModelItem() || modelItem == getModelItem().getProject();
}
protected void runTestSuite() {
testSuiteRunner = getModelItem().run(new StringToObjectMap(), true);
}
protected void beforeRun() {
runAction.setEnabled(false);
cancelAction.setEnabled(testSuiteRunner != null);
testCaseList.setEnabled(false);
progressBar.setForeground(Color.GREEN.darker());
}
protected void afterRun(WsdlTestSuiteRunner testSuiteRunner) {
runAction.setEnabled(true);
cancelAction.setEnabled(false);
testCaseList.setEnabled(true);
progressBar.setString(String.valueOf(testSuiteRunner.getStatus()));
progressBar.setForeground(testSuiteRunner.isFailed() ? Color.RED : Color.GREEN.darker());
}
private final class InternalTestSuiteListener extends TestSuiteListenerAdapter {
public void testCaseAdded(TestCase testCase) {
runAction.setEnabled(getModelItem().getTestCaseCount() > 0);
}
public void testCaseRemoved(TestCase testCase) {
runAction.setEnabled(getModelItem().getTestCaseCount() > 0);
}
}
private class RunAction extends AbstractAction {
public RunAction() {
putValue(Action.SMALL_ICON, UISupport.createImageIcon("/run.png"));
putValue(Action.SHORT_DESCRIPTION, "Runs the selected TestCases");
}
public void actionPerformed(ActionEvent e) {
runTestSuite();
Analytics.trackAction(SoapUIActions.RUN_TEST_SUITE.getActionName(), "RunType", getModelItem().getRunType().name());
}
}
private class CancelAction extends AbstractAction {
public CancelAction() {
putValue(Action.SMALL_ICON, UISupport.createImageIcon("/stop.png"));
putValue(Action.SHORT_DESCRIPTION, "Cancels ongoing TestCase runs");
}
public void actionPerformed(ActionEvent e) {
testSuiteRunner.cancel("Cancelled from UI");
}
}
private class SetupScriptGroovyEditorModel extends AbstractGroovyEditorModel {
public SetupScriptGroovyEditorModel() {
super(new String[]{"log", "runner", "context", "testSuite"},
WsdlTestSuiteDesktopPanel.this.getModelItem(), "Setup");
}
public String getScript() {
return WsdlTestSuiteDesktopPanel.this.getModelItem().getSetupScript();
}
public void setScript(String text) {
WsdlTestSuiteDesktopPanel.this.getModelItem().setSetupScript(text);
}
@Override
public Action createRunAction() {
return new AbstractAction() {
public void actionPerformed(ActionEvent e) {
try {
MockTestSuiteRunner mockRunner = new MockTestSuiteRunner(
WsdlTestSuiteDesktopPanel.this.getModelItem());
WsdlTestSuiteDesktopPanel.this.getModelItem().runSetupScript(
(TestSuiteRunContext) mockRunner.getRunContext(), mockRunner);
} catch (Exception e1) {
UISupport.showErrorMessage(e1);
}
}
};
}
}
private class TearDownScriptGroovyEditorModel extends AbstractGroovyEditorModel {
public TearDownScriptGroovyEditorModel() {
super(new String[]{"log", "runner", "context", "testSuite"},
WsdlTestSuiteDesktopPanel.this.getModelItem(), "TearDown");
}
public String getScript() {
return WsdlTestSuiteDesktopPanel.this.getModelItem().getTearDownScript();
}
public void setScript(String text) {
WsdlTestSuiteDesktopPanel.this.getModelItem().setTearDownScript(text);
}
@Override
public Action createRunAction() {
return new AbstractAction() {
public void actionPerformed(ActionEvent e) {
try {
MockTestSuiteRunner mockRunner = new MockTestSuiteRunner(
WsdlTestSuiteDesktopPanel.this.getModelItem());
WsdlTestSuiteDesktopPanel.this.getModelItem().runTearDownScript(
(TestSuiteRunContext) mockRunner.getRunContext(), mockRunner);
} catch (Exception e1) {
UISupport.showErrorMessage(e1);
}
}
};
}
}
private class InternalTestSuiteRunListener implements TestSuiteRunListener {
private TestRunLogTestRunListener runLogListener;
private int finishCount;
public void afterRun(TestSuiteRunner testRunner, TestSuiteRunContext runContext) {
WsdlTestSuiteDesktopPanel.this.afterRun((WsdlTestSuiteRunner) testRunner);
}
public void afterTestCase(TestSuiteRunner testRunner, TestSuiteRunContext runContext,
TestCaseRunner testCaseRunner) {
progressBar.setValue(++finishCount);
if (getModelItem().getRunType() == TestSuiteRunType.SEQUENTIAL) {
testCaseRunner.getTestCase().removeTestRunListener(runLogListener);
}
}
public void beforeRun(TestSuiteRunner testRunner, TestSuiteRunContext runContext) {
WsdlTestSuiteDesktopPanel.this.beforeRun();
testCaseList.reset();
progressBar.setMaximum(getModelItem().getTestCaseCount());
progressBar.setValue(0);
progressBar.setString("");
finishCount = 0;
if (runLogListener == null) {
runLogListener = new TestRunLogTestRunListener(testRunLog, false);
}
testRunLog.clear();
if (getModelItem().getRunType() == TestSuiteRunType.PARALLEL) {
testRunLog.addText("<log disabled during parallell execution>");
}
}
public void beforeTestCase(TestSuiteRunner testRunner, TestSuiteRunContext runContext, TestCase testCase) {
if (getModelItem().getRunType() == TestSuiteRunType.SEQUENTIAL) {
progressBar.setString("Running " + testCase.getName());
testCase.addTestRunListener(runLogListener);
} else {
progressBar.setString("Starting " + testCase.getName());
}
}
}
public WsdlTestSuiteRunner getTestSuiteRunner() {
return testSuiteRunner;
}
@Override
protected void renameModelItem() {
SoapUI.getActionRegistry().performAction("RenameTestSuiteAction", getModelItem(), null);
}
@Override
protected void cloneModelItem() {
SoapUI.getActionRegistry().performAction("CloneTestSuiteAction", getModelItem(), null);
}
}