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