1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.panels.testsuite;
14
15 import java.awt.BorderLayout;
16 import java.awt.Color;
17 import java.awt.Component;
18 import java.awt.Dimension;
19 import java.awt.event.ActionEvent;
20 import java.awt.event.ActionListener;
21 import java.util.ArrayList;
22 import java.util.List;
23
24 import javax.swing.AbstractAction;
25 import javax.swing.Action;
26 import javax.swing.BorderFactory;
27 import javax.swing.Box;
28 import javax.swing.ButtonGroup;
29 import javax.swing.JComponent;
30 import javax.swing.JPanel;
31 import javax.swing.JProgressBar;
32 import javax.swing.JScrollPane;
33 import javax.swing.JTabbedPane;
34 import javax.swing.JTextArea;
35 import javax.swing.JToggleButton;
36 import javax.swing.text.Document;
37
38 import com.eviware.soapui.SoapUI;
39 import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
40 import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
41 import com.eviware.soapui.impl.wsdl.actions.testsuite.AddNewTestCaseAction;
42 import com.eviware.soapui.impl.wsdl.support.HelpUrls;
43 import com.eviware.soapui.model.ModelItem;
44 import com.eviware.soapui.model.support.PropertiesMap;
45 import com.eviware.soapui.model.support.TestRunListenerAdapter;
46 import com.eviware.soapui.model.support.TestSuiteListenerAdapter;
47 import com.eviware.soapui.model.testsuite.TestCase;
48 import com.eviware.soapui.model.testsuite.TestRunContext;
49 import com.eviware.soapui.model.testsuite.TestRunner;
50 import com.eviware.soapui.model.testsuite.TestSuite.TestSuiteRunType;
51 import com.eviware.soapui.support.DocumentListenerAdapter;
52 import com.eviware.soapui.support.UISupport;
53 import com.eviware.soapui.support.action.swing.SwingActionDelegate;
54 import com.eviware.soapui.support.components.JUndoableTextArea;
55 import com.eviware.soapui.support.components.JXToolBar;
56 import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
57
58 /***
59 * DesktopPanel for WsdlTestSuite
60 *
61 * @author Ole.Matzura
62 */
63
64 @SuppressWarnings("serial")
65 public class WsdlTestSuiteDesktopPanel extends ModelItemDesktopPanel<WsdlTestSuite>
66 {
67 private final WsdlTestSuite testSuite;
68 private JProgressBar progressBar;
69 private JTestCaseList testCaseList;
70 private RunAction runAction = new RunAction();
71 private CancelAction cancelAction = new CancelAction();
72 private TestSuiteRunner testSuiteRunner = new TestSuiteRunner();
73 private JToggleButton sequentialButton;
74 private JToggleButton parallellButton;
75 private final InternalTestSuiteListener testSuiteListener = new InternalTestSuiteListener();
76 private JTextArea descriptionArea;
77 private boolean failedTests;
78
79 public WsdlTestSuiteDesktopPanel(WsdlTestSuite testSuite)
80 {
81 super( testSuite );
82 this.testSuite = testSuite;
83
84 buildUI();
85 testSuite.addTestSuiteListener( testSuiteListener );
86 }
87
88 private void buildUI()
89 {
90 add( buildToolbar(), BorderLayout.NORTH );
91 add( buildContent(), BorderLayout.CENTER );
92
93 setPreferredSize( new Dimension( 300, 400 ));
94 }
95
96 protected JTestCaseList getTestCaseList()
97 {
98 return testCaseList;
99 }
100
101 @Override
102 public void addNotify()
103 {
104 super.addNotify();
105 testSuite.addTestSuiteListener( testSuiteListener );
106 }
107
108 @Override
109 public void removeNotify()
110 {
111 super.removeNotify();
112 testSuite.removeTestSuiteListener( testSuiteListener );
113 }
114
115 private JComponent buildToolbar()
116 {
117 cancelAction.setEnabled( false );
118 runAction.setEnabled( testSuite.getTestCaseCount() > 0 );
119
120 JXToolBar toolbar = UISupport.createToolbar();
121
122 addToolbarActions( toolbar );
123 toolbar.add( Box.createHorizontalGlue() );
124 toolbar.add( UISupport.createToolbarButton( new ShowOnlineHelpAction( HelpUrls.TESTSUITEEDITOR_HELP_URL )));
125
126 progressBar = new JProgressBar( 0, testSuite.getTestCaseCount() );
127 JPanel progressPanel = UISupport.createProgressBarPanel(progressBar, 10, false );
128
129 JPanel panel = new JPanel( new BorderLayout() );
130
131 panel.add( toolbar, BorderLayout.PAGE_START );
132 panel.add( progressPanel, BorderLayout.CENTER );
133
134 return panel;
135 }
136
137 protected void addToolbarActions( JXToolBar toolbar )
138 {
139 toolbar.add( UISupport.createToolbarButton( runAction ));
140 toolbar.add( UISupport.createToolbarButton( cancelAction ));
141
142 toolbar.addRelatedGap();
143 toolbar.add( UISupport.createToolbarButton(
144 SwingActionDelegate.createDelegate( AddNewTestCaseAction.SOAPUI_ACTION_ID, testSuite, null, "/testCase.gif" )));
145
146 ButtonGroup buttonGroup = new ButtonGroup();
147
148 sequentialButton = new JToggleButton( UISupport.createImageIcon( "/sequential.gif" ), true );
149 sequentialButton.setToolTipText( "The selected TestCases are run in sequence" );
150 sequentialButton.setPreferredSize( UISupport.getPreferredButtonSize());
151 sequentialButton.setSelected( testSuite.getRunType() == TestSuiteRunType.SEQUENTIAL );
152 sequentialButton.addActionListener( new ActionListener() {
153
154 public void actionPerformed(ActionEvent e)
155 {
156 testSuite.setRunType( TestSuiteRunType.SEQUENTIAL );
157 }} );
158
159 buttonGroup.add( sequentialButton );
160
161 parallellButton = new JToggleButton( UISupport.createImageIcon( "/parallell.gif" ));
162 parallellButton.setToolTipText( "The selected TestCases are run in parallel" );
163 parallellButton.setPreferredSize( UISupport.getPreferredButtonSize());
164 parallellButton.setSelected( testSuite.getRunType() == TestSuiteRunType.PARALLEL );
165 parallellButton.addActionListener( new ActionListener() {
166
167 public void actionPerformed(ActionEvent e)
168 {
169 testSuite.setRunType( TestSuiteRunType.PARALLEL );
170 }} );
171
172 buttonGroup.add( parallellButton );
173
174 toolbar.addUnrelatedGap();
175 toolbar.add( sequentialButton );
176 toolbar.addRelatedGap();
177 toolbar.add( parallellButton );
178
179 }
180
181 private JComponent buildContent()
182 {
183 JTabbedPane tabs = new JTabbedPane( JTabbedPane.TOP );
184
185 testCaseList = buildTestCaseList( testSuite );
186
187 tabs.addTab( "TestCases", new JScrollPane( testCaseList ));
188 tabs.addTab( "Description", buildDescriptionPanel() );
189
190 return UISupport.createTabPanel( tabs, true );
191 }
192
193 private Component buildDescriptionPanel()
194 {
195 JPanel panel = new JPanel( new BorderLayout() );
196 descriptionArea = new JUndoableTextArea( testSuite.getDescription() );
197 descriptionArea.getDocument().addDocumentListener( new DocumentListenerAdapter()
198 {
199 public void update(Document document)
200 {
201 testSuite.setDescription( descriptionArea.getText() );
202 }} );
203
204 panel.setBorder( BorderFactory.createEmptyBorder( 2, 2, 2, 2));
205 panel.add( new JScrollPane( descriptionArea ), BorderLayout.CENTER );
206
207 return panel;
208 }
209
210 protected JTestCaseList buildTestCaseList(WsdlTestSuite testSuite)
211 {
212 return new JTestCaseList( testSuite );
213 }
214
215 public boolean onClose( boolean canCancel )
216 {
217 super.release();
218 return true;
219 }
220
221 public JComponent getComponent()
222 {
223 return this;
224 }
225
226 public boolean dependsOn(ModelItem modelItem)
227 {
228 return modelItem == testSuite || modelItem == testSuite.getProject();
229 }
230
231 protected void runTestSuite()
232 {
233 new Thread( testSuiteRunner, testSuite.getName() + " TestSuiteRunner" ).start();
234 }
235
236 protected void beforeRun()
237 {
238 runAction.setEnabled( false );
239 cancelAction.setEnabled( true );
240 testCaseList.setEnabled( false );
241
242 failedTests = false;
243 }
244
245 protected void afterRun()
246 {
247 runAction.setEnabled( true );
248 cancelAction.setEnabled( false );
249 testCaseList.setEnabled( true );
250
251 progressBar.setString( failedTests ? "Failed" : "Passed" );
252 progressBar.setForeground( failedTests ? Color.RED : Color.GREEN.darker() );
253 }
254
255 private final class InternalTestSuiteListener extends TestSuiteListenerAdapter
256 {
257 public void testCaseAdded(TestCase testCase)
258 {
259 runAction.setEnabled( testSuite.getTestCaseCount() > 0 );
260 }
261
262 public void testCaseRemoved(TestCase testCase)
263 {
264 runAction.setEnabled( testSuite.getTestCaseCount() > 0 );
265 }
266 }
267
268 private class RunAction extends AbstractAction
269 {
270 public RunAction()
271 {
272 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_testcase.gif" ));
273 putValue( Action.SHORT_DESCRIPTION, "Runs the selected TestCases" );
274 }
275
276 public void actionPerformed(ActionEvent e)
277 {
278 runTestSuite();
279 }
280 }
281
282 private class CancelAction extends AbstractAction
283 {
284 public CancelAction()
285 {
286 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/stop_testcase.gif" ));
287 putValue( Action.SHORT_DESCRIPTION, "Cancels ongoing TestCase runs" );
288 }
289
290 public void actionPerformed(ActionEvent e)
291 {
292 testSuiteRunner.cancel();
293 }
294 }
295
296 /***
297 * Runs the selected testsuites..
298 *
299 * @author Ole.Matzura
300 */
301
302 public class TestSuiteRunner implements Runnable
303 {
304 private boolean canceled;
305 private List<TestRunner> runners = new ArrayList<TestRunner>();
306 private InternalTestRunListener internalTestRunListener = new InternalTestRunListener();
307
308 public void cancel()
309 {
310 canceled = true;
311
312 for( TestRunner runner : runners )
313 {
314 runner.cancel( "Canceled from TestSuite" );
315 }
316 }
317
318 public void run()
319 {
320 canceled = false;
321 beforeRun();
322
323 int[] indices = testCaseList.getSelectedIndices();
324 if( indices.length == 0 )
325 {
326 indices = new int[testSuite.getTestCaseCount()];
327 for( int c = 0; c < indices.length; c++ )
328 indices[c] = c;
329 }
330
331 progressBar.setValue( 0 );
332 progressBar.setString( "" );
333 progressBar.setMaximum( indices.length );
334
335 TestSuiteRunType runType = testSuite.getRunType();
336
337 for( int c = 0; c < indices.length; c++ )
338 {
339 TestCase testCase = (TestCase) testSuite.getTestCaseAt( indices[c] );
340 if( SoapUI.getTestMonitor().hasRunningLoadTest( testCase ))
341 {
342 progressBar.setString( "Skipping " + testCase.getName() );
343 progressBar.setValue( c+1 );
344 continue;
345 }
346
347 if( runType == TestSuiteRunType.PARALLEL )
348 {
349 testCase.addTestRunListener( internalTestRunListener );
350 progressBar.setString( "Starting " + testCase.getName() );
351 }
352 else
353 {
354 progressBar.setString( "Running " + testCase.getName() );
355 }
356
357 TestRunner runner = testCase.run( PropertiesMap.EMPTY_MAP, true );
358 runners.add( runner );
359
360 if( runType == TestSuiteRunType.SEQUENTIAL )
361 {
362 runner.waitUntilFinished();
363 progressBar.setValue( c+1 );
364 runners.remove( runner );
365 }
366
367 if( canceled )
368 break;
369 }
370
371 if( runners.isEmpty() )
372 afterRun();
373 }
374
375 /***
376 * Waits for running tests to finish when running in parallel
377 */
378
379 private class InternalTestRunListener extends TestRunListenerAdapter
380 {
381 public void afterRun(TestRunner testRunner, TestRunContext runContext)
382 {
383 runners.remove( testRunner );
384 testRunner.getTestCase().removeTestRunListener( this );
385
386 progressBar.setValue( progressBar.getValue()+1 );
387
388 if( runners.isEmpty() )
389 WsdlTestSuiteDesktopPanel.this.afterRun();
390
391 if( testRunner.getStatus() == TestRunner.Status.FAILED )
392 failedTests = true;
393 }
394 }
395 }
396 }