001: /*
002: * soapUI, copyright (C) 2004-2007 eviware.com
003: *
004: * soapUI is free software; you can redistribute it and/or modify it under the
005: * terms of version 2.1 of the GNU Lesser General Public License as published by
006: * the Free Software Foundation.
007: *
008: * soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
009: * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
010: * See the GNU Lesser General Public License for more details at gnu.org.
011: */
012:
013: package com.eviware.soapui.impl.wsdl.panels.testcase;
014:
015: import java.awt.BorderLayout;
016: import java.awt.Component;
017: import java.awt.Dimension;
018: import java.awt.event.ActionEvent;
019: import java.text.SimpleDateFormat;
020: import java.util.Date;
021:
022: import javax.swing.AbstractAction;
023: import javax.swing.Action;
024: import javax.swing.BorderFactory;
025: import javax.swing.Box;
026: import javax.swing.JButton;
027: import javax.swing.JLabel;
028: import javax.swing.JPanel;
029: import javax.swing.JProgressBar;
030: import javax.swing.JScrollPane;
031: import javax.swing.JSplitPane;
032: import javax.swing.JTabbedPane;
033: import javax.swing.JTextArea;
034: import javax.swing.JToggleButton;
035: import javax.swing.JToolBar;
036: import javax.swing.SwingUtilities;
037: import javax.swing.text.Document;
038:
039: import com.eviware.soapui.SoapUI;
040: import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
041: import com.eviware.soapui.impl.wsdl.actions.testcase.TestCaseOptionsAction;
042: import com.eviware.soapui.impl.wsdl.panels.support.ProgressBarAdapter;
043: import com.eviware.soapui.impl.wsdl.panels.testcase.actions.SetCredentialsAction;
044: import com.eviware.soapui.impl.wsdl.panels.testcase.actions.SetEndpointAction;
045: import com.eviware.soapui.impl.wsdl.support.HelpUrls;
046: import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
047: import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner;
048: import com.eviware.soapui.model.ModelItem;
049: import com.eviware.soapui.model.support.PropertiesMap;
050: import com.eviware.soapui.model.support.TestRunListenerAdapter;
051: import com.eviware.soapui.model.testsuite.LoadTestRunner;
052: import com.eviware.soapui.model.testsuite.TestRunContext;
053: import com.eviware.soapui.model.testsuite.TestRunner;
054: import com.eviware.soapui.model.testsuite.TestStep;
055: import com.eviware.soapui.model.testsuite.TestStepResult;
056: import com.eviware.soapui.monitor.support.TestMonitorListenerAdapter;
057: import com.eviware.soapui.support.DocumentListenerAdapter;
058: import com.eviware.soapui.support.UISupport;
059: import com.eviware.soapui.support.action.swing.SwingActionDelegate;
060: import com.eviware.soapui.support.components.JUndoableTextArea;
061: import com.eviware.soapui.support.swing.ComponentBag;
062: import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
063:
064: /**
065: * WsdlTestCase desktop panel
066: *
067: * @author Ole.Matzura
068: */
069:
070: public class WsdlTestCaseDesktopPanel extends
071: ModelItemDesktopPanel<WsdlTestCase> {
072: private JProgressBar progressBar;
073: private TestStepList testStepList;
074: private InternalTestRunListener testRunListener = new InternalTestRunListener();
075: private JButton runButton;
076: private JButton cancelButton;
077: private TestRunner runner;
078: private JButton setEndpointButton;
079: private JButton setCredentialsButton;
080: private JButton optionsButton;
081: private ComponentBag stateDependantComponents = new ComponentBag();
082: private TestCaseLog testCaseLog;
083: private JToggleButton loopButton;
084: @SuppressWarnings("unused")
085: private ProgressBarAdapter progressBarAdapter;
086: private InternalTestMonitorListener testMonitorListener;
087: public boolean canceled;
088: private JTextArea descriptionArea;
089:
090: public WsdlTestCaseDesktopPanel(WsdlTestCase testCase) {
091: super (testCase);
092:
093: buildUI();
094:
095: setPreferredSize(new Dimension(250, 500));
096: setRunningState();
097:
098: testCase.addTestRunListener(testRunListener);
099: progressBarAdapter = new ProgressBarAdapter(progressBar,
100: testCase);
101: testMonitorListener = new InternalTestMonitorListener();
102:
103: SoapUI.getTestMonitor().addTestMonitorListener(
104: testMonitorListener);
105: }
106:
107: /**
108: * There are three states: - enabled, no testcases or testschedules running -
109: * enabled, standalone testcase running - disabled, testschedule is running
110: */
111:
112: private void setRunningState() {
113: stateDependantComponents.setEnabled(!SoapUI.getTestMonitor()
114: .hasRunningLoadTest(getModelItem()));
115: }
116:
117: private void buildUI() {
118: JPanel panel = new JPanel(new BorderLayout());
119:
120: panel.add(buildToolbar(), BorderLayout.PAGE_START);
121: panel.add(buildRunnerBar(), BorderLayout.CENTER);
122:
123: add(panel, BorderLayout.NORTH);
124:
125: JSplitPane splitPane = UISupport.createVerticalSplit();
126: splitPane.setTopComponent(buildTestStepList());
127: splitPane.setBottomComponent(buildTestLog());
128: splitPane.setDividerLocation(0.7);
129: splitPane.setDividerLocation(250);
130:
131: add(splitPane, BorderLayout.CENTER);
132: add(new JLabel("--"), BorderLayout.PAGE_END);
133: }
134:
135: protected TestStepList getTestStepList() {
136: return testStepList;
137: }
138:
139: private Component buildTestLog() {
140: testCaseLog = new TestCaseLog();
141: stateDependantComponents.add(testCaseLog);
142: return testCaseLog;
143: }
144:
145: private Component buildTestStepList() {
146: testStepList = new TestStepList(getModelItem());
147: stateDependantComponents.add(testStepList);
148:
149: JTabbedPane tabs = new JTabbedPane(JTabbedPane.TOP);
150: tabs.addTab("Test Steps", new JScrollPane(testStepList));
151: tabs.addTab("Description", buildDescriptionPanel());
152:
153: // tabs.addTab( "Test Properties", new JPanel() );
154:
155: return UISupport.createTabPanel(tabs, false);
156: }
157:
158: private Component buildDescriptionPanel() {
159: JPanel panel = new JPanel(new BorderLayout());
160: descriptionArea = new JUndoableTextArea(getModelItem()
161: .getDescription());
162: descriptionArea.getDocument().addDocumentListener(
163: new DocumentListenerAdapter() {
164: public void update(Document document) {
165: getModelItem().setDescription(
166: descriptionArea.getText());
167: }
168: });
169:
170: panel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
171: panel
172: .add(new JScrollPane(descriptionArea),
173: BorderLayout.CENTER);
174:
175: return panel;
176: }
177:
178: private Component buildToolbar() {
179: JToolBar toolbar = UISupport.createToolbar();
180:
181: runButton = UISupport
182: .createToolbarButton(new RunTestCaseAction());
183: optionsButton = UISupport
184: .createToolbarButton(SwingActionDelegate
185: .createDelegate(
186: TestCaseOptionsAction.SOAPUI_ACTION_ID,
187: getModelItem(), null, "/options.gif"));
188: optionsButton.setText(null);
189: cancelButton = UISupport.createToolbarButton(
190: new CancelRunTestCaseAction(), false);
191:
192: loopButton = new JToggleButton(UISupport
193: .createImageIcon("/loop.gif"));
194: loopButton.setPreferredSize(UISupport.getPreferredButtonSize());
195: loopButton.setToolTipText("Loop TestCase continuously");
196:
197: setCredentialsButton = UISupport
198: .createToolbarButton(new SetCredentialsAction(
199: getModelItem()));
200: setEndpointButton = UISupport
201: .createToolbarButton(new SetEndpointAction(
202: getModelItem()));
203:
204: stateDependantComponents.add(runButton);
205: stateDependantComponents.add(optionsButton);
206: stateDependantComponents.add(cancelButton);
207: stateDependantComponents.add(setCredentialsButton);
208: stateDependantComponents.add(setEndpointButton);
209:
210: addToolbarActions(toolbar);
211:
212: toolbar.add(Box.createHorizontalGlue());
213: toolbar.add(UISupport
214: .createToolbarButton(new ShowOnlineHelpAction(
215: HelpUrls.TESTCASEEDITOR_HELP_URL)));
216:
217: return toolbar;
218: }
219:
220: protected void addToolbarActions(JToolBar toolbar) {
221: toolbar.add(runButton);
222: toolbar.add(cancelButton);
223: toolbar.add(loopButton);
224: toolbar.add(setCredentialsButton);
225: toolbar.add(setEndpointButton);
226: toolbar.add(optionsButton);
227: }
228:
229: private Component buildRunnerBar() {
230: progressBar = new JProgressBar(0, getModelItem()
231: .getTestStepCount());
232: return UISupport.createProgressBarPanel(progressBar, 10, false);
233: }
234:
235: private final class InternalTestMonitorListener extends
236: TestMonitorListenerAdapter {
237: public void loadTestStarted(LoadTestRunner runner) {
238: setRunningState();
239: }
240:
241: public void loadTestFinished(LoadTestRunner runner) {
242: setRunningState();
243: }
244: }
245:
246: public class InternalTestRunListener extends TestRunListenerAdapter {
247: private SimpleDateFormat dateFormat;
248:
249: public InternalTestRunListener() {
250: dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
251: }
252:
253: public void beforeRun(TestRunner testRunner,
254: TestRunContext runContext) {
255: if (SoapUI.getTestMonitor().hasRunningLoadTest(
256: getModelItem()))
257: return;
258:
259: runButton.setEnabled(false);
260: cancelButton.setEnabled(true);
261: testStepList.setEnabled(false);
262: testStepList.setSelectedIndex(-1);
263: testCaseLog.clear();
264:
265: testCaseLog.addText("Test started at "
266: + dateFormat.format(new Date()));
267: }
268:
269: public void beforeStep(TestRunner testRunner,
270: TestRunContext runContext) {
271: if (SoapUI.getTestMonitor().hasRunningLoadTest(
272: getModelItem()))
273: return;
274:
275: TestStep testStep = runContext.getCurrentStep();
276: testStepList.setSelectedValue(testStep, true);
277: }
278:
279: public void afterRun(TestRunner testRunner,
280: TestRunContext runContext) {
281: if (SoapUI.getTestMonitor().hasRunningLoadTest(
282: getModelItem()))
283: return;
284:
285: WsdlTestCaseRunner wsdlRunner = (WsdlTestCaseRunner) testRunner;
286:
287: if (testRunner.getStatus() == TestRunner.Status.CANCELED)
288: testCaseLog.addText("Test canceled ["
289: + testRunner.getReason() + "], time taken = "
290: + wsdlRunner.getTimeTaken());
291: else if (testRunner.getStatus() == TestRunner.Status.FAILED)
292: testCaseLog.addText("Test failed ["
293: + wsdlRunner.getError() + "], time taken = "
294: + wsdlRunner.getTimeTaken());
295: else
296: testCaseLog.addText("Test finished with status ["
297: + testRunner.getStatus() + "], time taken = "
298: + wsdlRunner.getTimeTaken());
299:
300: runner = null;
301:
302: JToggleButton loopButton = (JToggleButton) runContext
303: .getProperty("loopButton");
304: if (loopButton != null
305: && loopButton.isSelected()
306: && testRunner.getStatus() == TestRunner.Status.FINISHED) {
307: SwingUtilities.invokeLater(new Runnable() {
308: public void run() {
309: runTestCase();
310: }
311: });
312: } else {
313: WsdlTestCaseDesktopPanel.this .afterRun();
314: }
315: }
316:
317: public void afterStep(TestRunner testRunner,
318: TestRunContext runContext, TestStepResult stepResult) {
319: if (SoapUI.getTestMonitor().hasRunningLoadTest(
320: getModelItem()))
321: return;
322:
323: testCaseLog.addTestStepResult(stepResult);
324: }
325: }
326:
327: protected void runTestCase() {
328: if (canceled) {
329: // make sure state is correct
330: runButton.setEnabled(true);
331: cancelButton.setEnabled(false);
332: testStepList.setEnabled(true);
333: return;
334: }
335:
336: PropertiesMap properties = new PropertiesMap();
337: properties.put("loopButton", loopButton);
338: runner = getModelItem().run(properties, true);
339: }
340:
341: public class RunTestCaseAction extends AbstractAction {
342: public RunTestCaseAction() {
343: putValue(Action.SMALL_ICON, UISupport
344: .createImageIcon("/run_testcase.gif"));
345: putValue(Action.SHORT_DESCRIPTION, "Runs this testcase");
346: }
347:
348: public void actionPerformed(ActionEvent e) {
349: canceled = false;
350: runTestCase();
351: }
352: }
353:
354: public class CancelRunTestCaseAction extends AbstractAction {
355: public CancelRunTestCaseAction() {
356: putValue(Action.SMALL_ICON, UISupport
357: .createImageIcon("/stop_testcase.gif"));
358: putValue(Action.SHORT_DESCRIPTION,
359: "Stops running this testcase");
360: }
361:
362: public void actionPerformed(ActionEvent e) {
363: if (runner != null)
364: runner.cancel("canceled in UI");
365:
366: canceled = true;
367: }
368: }
369:
370: public boolean onClose(boolean canCancel) {
371: if (canCancel) {
372: if (runner != null
373: && runner.getStatus() == TestRunner.Status.RUNNING) {
374: Boolean retval = UISupport.confirmOrCancel(
375: "Cancel running TestCase?", "Cancel Run");
376:
377: if (retval == null)
378: return false;
379: if (retval.booleanValue()) {
380: runner.cancel(null);
381: }
382: }
383: } else {
384: if (runner != null
385: && runner.getStatus() == TestRunner.Status.RUNNING) {
386: runner.cancel(null);
387: }
388: }
389:
390: SoapUI.getTestMonitor().removeTestMonitorListener(
391: testMonitorListener);
392: getModelItem().removeTestRunListener(testRunListener);
393: testStepList.release();
394: progressBarAdapter.release();
395:
396: return release();
397: }
398:
399: public boolean dependsOn(ModelItem modelItem) {
400: return modelItem == getModelItem()
401: || modelItem == getModelItem().getTestSuite()
402: || modelItem == getModelItem().getTestSuite()
403: .getProject();
404: }
405:
406: public String getDescription() {
407: return "TestCase: [" + getModelItem().getName() + "]";
408: }
409:
410: protected void afterRun() {
411: runButton.setEnabled(true);
412: cancelButton.setEnabled(false);
413: testStepList.setEnabled(true);
414: }
415: }
|