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