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
22 import javax.swing.AbstractAction;
23 import javax.swing.Action;
24 import javax.swing.BorderFactory;
25 import javax.swing.ButtonGroup;
26 import javax.swing.JComponent;
27 import javax.swing.JPanel;
28 import javax.swing.JProgressBar;
29 import javax.swing.JScrollPane;
30 import javax.swing.JTabbedPane;
31 import javax.swing.JTextArea;
32 import javax.swing.JToggleButton;
33 import javax.swing.text.Document;
34
35 import com.eviware.soapui.SoapUI;
36 import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
37 import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
38 import com.eviware.soapui.impl.wsdl.actions.testsuite.AddNewTestCaseAction;
39 import com.eviware.soapui.impl.wsdl.panels.testcase.TestRunLog;
40 import com.eviware.soapui.impl.wsdl.panels.testcase.TestRunLog.TestRunLogTestRunListener;
41 import com.eviware.soapui.impl.wsdl.panels.teststeps.support.AbstractGroovyEditorModel;
42 import com.eviware.soapui.impl.wsdl.panels.teststeps.support.PropertyHolderTable;
43 import com.eviware.soapui.impl.wsdl.support.HelpUrls;
44 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestScenario;
45 import com.eviware.soapui.model.ModelItem;
46 import com.eviware.soapui.model.propertyexpansion.DefaultPropertyExpansionContext;
47 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContext;
48 import com.eviware.soapui.model.support.TestSuiteListenerAdapter;
49 import com.eviware.soapui.model.testsuite.TestCase;
50 import com.eviware.soapui.model.testsuite.TestRunner;
51 import com.eviware.soapui.model.testsuite.TestSuite.TestSuiteRunType;
52 import com.eviware.soapui.support.DocumentListenerAdapter;
53 import com.eviware.soapui.support.UISupport;
54 import com.eviware.soapui.support.action.swing.SwingActionDelegate;
55 import com.eviware.soapui.support.components.GroovyEditorComponent;
56 import com.eviware.soapui.support.components.GroovyEditorInspector;
57 import com.eviware.soapui.support.components.JComponentInspector;
58 import com.eviware.soapui.support.components.JFocusableComponentInspector;
59 import com.eviware.soapui.support.components.JInspectorPanel;
60 import com.eviware.soapui.support.components.JUndoableTextArea;
61 import com.eviware.soapui.support.components.JXToolBar;
62 import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
63
64 /***
65 * DesktopPanel for WsdlTestSuite
66 *
67 * @author Ole.Matzura
68 */
69
70 @SuppressWarnings("serial")
71 public class WsdlTestSuiteDesktopPanel extends ModelItemDesktopPanel<WsdlTestSuite>
72 {
73 private final WsdlTestSuite testSuite;
74 private JProgressBar progressBar;
75 private JTestSuiteTestCaseList testCaseList;
76 private RunAction runAction = new RunAction();
77 private CancelAction cancelAction = new CancelAction();
78 private TestSuiteRunner testSuiteRunner = new TestSuiteRunner();
79 private JToggleButton sequentialButton;
80 private JToggleButton parallellButton;
81 private final InternalTestSuiteListener testSuiteListener = new InternalTestSuiteListener();
82 private JTextArea descriptionArea;
83 private boolean failedTests;
84 private PropertyHolderTable propertiesTable;
85 private TestRunLog testRunLog;
86 private GroovyEditorComponent tearDownGroovyEditor;
87 private GroovyEditorComponent setupGroovyEditor;
88
89 public WsdlTestSuiteDesktopPanel(WsdlTestSuite testSuite)
90 {
91 super( testSuite );
92 this.testSuite = testSuite;
93
94 buildUI();
95 testSuite.addTestSuiteListener( testSuiteListener );
96 }
97
98 private void buildUI()
99 {
100 add( buildToolbar(), BorderLayout.NORTH );
101 add( buildContent(), BorderLayout.CENTER );
102
103 setPreferredSize( new Dimension( 500, 500 ));
104 }
105
106 private JComponent buildContent()
107 {
108 JInspectorPanel inspectorPanel = new JInspectorPanel( buildTabs() );
109 inspectorPanel.addInspector( new JComponentInspector( buildRunLog(), "TestSuite Log",
110 "Log of executed TestCases and TestSteps", true ));
111
112 return inspectorPanel;
113 }
114
115 private JComponent buildRunLog()
116 {
117 testRunLog = new TestRunLog( getModelItem().getSettings() );
118 return testRunLog;
119 }
120
121 protected JTestSuiteTestCaseList getTestCaseList()
122 {
123 return testCaseList;
124 }
125
126 @Override
127 public void addNotify()
128 {
129 super.addNotify();
130 testSuite.addTestSuiteListener( testSuiteListener );
131 }
132
133 @Override
134 public void removeNotify()
135 {
136 super.removeNotify();
137 testSuite.removeTestSuiteListener( testSuiteListener );
138 }
139
140 private JComponent buildToolbar()
141 {
142 cancelAction.setEnabled( false );
143 runAction.setEnabled( testSuite.getTestCaseCount() > 0 );
144
145 JXToolBar toolbar = UISupport.createToolbar();
146
147 addToolbarActions( toolbar );
148 toolbar.addGlue();
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 protected void addToolbarActions( JXToolBar toolbar )
163 {
164 toolbar.add( UISupport.createToolbarButton( runAction ));
165 toolbar.add( UISupport.createToolbarButton( cancelAction ));
166
167 toolbar.addRelatedGap();
168
169 ButtonGroup buttonGroup = new ButtonGroup();
170
171 sequentialButton = new JToggleButton( UISupport.createImageIcon( "/sequential.gif" ), true );
172 sequentialButton.setToolTipText( "The selected TestCases are run in sequence" );
173 sequentialButton.setPreferredSize( UISupport.getPreferredButtonSize());
174 sequentialButton.setSelected( testSuite.getRunType() == TestSuiteRunType.SEQUENTIAL );
175 sequentialButton.addActionListener( new ActionListener() {
176
177 public void actionPerformed(ActionEvent e)
178 {
179 testSuite.setRunType( TestSuiteRunType.SEQUENTIAL );
180 }} );
181
182 buttonGroup.add( sequentialButton );
183
184 parallellButton = new JToggleButton( UISupport.createImageIcon( "/parallell.gif" ));
185 parallellButton.setToolTipText( "The selected TestCases are run in parallel" );
186 parallellButton.setPreferredSize( UISupport.getPreferredButtonSize());
187 parallellButton.setSelected( testSuite.getRunType() == TestSuiteRunType.PARALLEL );
188 parallellButton.addActionListener( new ActionListener() {
189
190 public void actionPerformed(ActionEvent e)
191 {
192 testSuite.setRunType( TestSuiteRunType.PARALLEL );
193 }} );
194
195 buttonGroup.add( parallellButton );
196
197 toolbar.addUnrelatedGap();
198 toolbar.add( sequentialButton );
199 toolbar.addRelatedGap();
200 toolbar.add( parallellButton );
201 }
202
203 private JComponent buildTabs()
204 {
205 JTabbedPane tabs = new JTabbedPane( JTabbedPane.TOP );
206 JInspectorPanel inspectorPanel = new JInspectorPanel( buildTestCaseList( testSuite ) );
207
208 tabs.addTab( "TestCases", inspectorPanel );
209
210 addTabs( tabs, inspectorPanel );
211 tabs.setTabLayoutPolicy( JTabbedPane.SCROLL_TAB_LAYOUT );
212
213 return UISupport.createTabPanel( tabs, true );
214 }
215
216 protected void addTabs( JTabbedPane tabs, JInspectorPanel inspectorPanel )
217 {
218 inspectorPanel.addInspector( new JFocusableComponentInspector<JPanel>( buildDescriptionPanel(),
219 descriptionArea, "Description", "Description for this TestSuite", true ));
220
221 inspectorPanel.addInspector( new JComponentInspector( buildPropertiesPanel(), "Properties", "TestSuite level properties", true ) );
222 inspectorPanel.addInspector( new GroovyEditorInspector( buildSetupScriptPanel(), "Setup Script", "Script to run before running TestSuite") );
223 inspectorPanel.addInspector( new GroovyEditorInspector( buildTearDownScriptPanel(), "TearDown Script", "Script to run after running TestSuite" ) );
224 }
225
226 protected GroovyEditorComponent buildTearDownScriptPanel()
227 {
228 tearDownGroovyEditor = new GroovyEditorComponent( new TearDownScriptGroovyEditorModel(), null );
229 return tearDownGroovyEditor;
230 }
231
232 protected GroovyEditorComponent buildSetupScriptPanel()
233 {
234 setupGroovyEditor = new GroovyEditorComponent( new SetupScriptGroovyEditorModel(), null );
235 return setupGroovyEditor;
236 }
237
238 private JComponent buildPropertiesPanel()
239 {
240 JPanel panel = new JPanel( new BorderLayout() );
241 propertiesTable = createPropertyHolderTable();
242 panel.add( new JScrollPane( propertiesTable ), BorderLayout.CENTER );
243 return panel;
244 }
245
246 protected PropertyHolderTable createPropertyHolderTable()
247 {
248 return new PropertyHolderTable( getModelItem() );
249 }
250
251 private JPanel buildDescriptionPanel()
252 {
253 JPanel panel = new JPanel( new BorderLayout() );
254 descriptionArea = new JUndoableTextArea( testSuite.getDescription() );
255 descriptionArea.getDocument().addDocumentListener( new DocumentListenerAdapter()
256 {
257 public void update(Document document)
258 {
259 testSuite.setDescription( descriptionArea.getText() );
260 }} );
261
262 panel.setBorder( BorderFactory.createEmptyBorder( 2, 2, 2, 2));
263 panel.add( new JScrollPane( descriptionArea ), BorderLayout.CENTER );
264 UISupport.addTitledBorder( panel, "TestSuite Description" );
265
266 return panel;
267 }
268
269 protected JComponent buildTestCaseList(WsdlTestSuite testSuite)
270 {
271 testCaseList = new JTestSuiteTestCaseList( testSuite );
272
273 JPanel p = new JPanel( new BorderLayout() );
274
275 p.add( buildTestCaseListToolbar(), BorderLayout.NORTH );
276 p.add( new JScrollPane( testCaseList), BorderLayout.CENTER );
277
278 return p;
279 }
280
281 private Component buildTestCaseListToolbar()
282 {
283 JXToolBar toolbar = UISupport.createToolbar();
284 toolbar.add( UISupport.createToolbarButton(
285 SwingActionDelegate.createDelegate( AddNewTestCaseAction.SOAPUI_ACTION_ID, testSuite, null, "/testCase.gif" )));
286
287 return toolbar;
288 }
289
290 public boolean onClose( boolean canCancel )
291 {
292 propertiesTable.release();
293
294 setupGroovyEditor.getEditor().release();
295 tearDownGroovyEditor.getEditor().release();
296
297 testRunLog.release();
298
299 return super.release();
300 }
301
302 public JComponent getComponent()
303 {
304 return this;
305 }
306
307 public boolean dependsOn(ModelItem modelItem)
308 {
309 return modelItem == testSuite || modelItem == testSuite.getProject();
310 }
311
312 protected void runTestSuite()
313 {
314 new Thread( testSuiteRunner, testSuite.getName() + " TestSuiteRunner" ).start();
315 }
316
317 protected void beforeRun()
318 {
319 runAction.setEnabled( false );
320 cancelAction.setEnabled( true );
321 testCaseList.setEnabled( false );
322
323 failedTests = false;
324 }
325
326 protected void afterRun()
327 {
328 runAction.setEnabled( true );
329 cancelAction.setEnabled( false );
330 testCaseList.setEnabled( true );
331
332 progressBar.setString( failedTests ? "Failed" : "Passed" );
333 progressBar.setForeground( failedTests ? Color.RED : Color.GREEN.darker() );
334 }
335
336 private final class InternalTestSuiteListener extends TestSuiteListenerAdapter
337 {
338 public void testCaseAdded(TestCase testCase)
339 {
340 runAction.setEnabled( testSuite.getTestCaseCount() > 0 );
341 }
342
343 public void testCaseRemoved(TestCase testCase)
344 {
345 runAction.setEnabled( testSuite.getTestCaseCount() > 0 );
346 }
347 }
348
349 private class RunAction extends AbstractAction
350 {
351 public RunAction()
352 {
353 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_testcase.gif" ));
354 putValue( Action.SHORT_DESCRIPTION, "Runs the selected TestCases" );
355 }
356
357 public void actionPerformed(ActionEvent e)
358 {
359 runTestSuite();
360 }
361 }
362
363 private class CancelAction extends AbstractAction
364 {
365 public CancelAction()
366 {
367 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/stop_testcase.gif" ));
368 putValue( Action.SHORT_DESCRIPTION, "Cancels ongoing TestCase runs" );
369 }
370
371 public void actionPerformed(ActionEvent e)
372 {
373 testSuiteRunner.cancel();
374 }
375 }
376
377 /***
378 * Runs the selected testsuites..
379 *
380 * @author Ole.Matzura
381 */
382
383 public class TestSuiteRunner extends WsdlTestScenario
384 {
385 private PropertyExpansionContext context;
386 private TestRunLogTestRunListener runLogListener;
387
388 public TestSuiteRunner()
389 {
390 super( TestSuiteRunType.SEQUENTIAL );
391 }
392
393 public void run()
394 {
395 removeAllTestCases();
396
397 testCaseList.reset();
398
399 for( TestCase testCase : testSuite.getTestCaseList() )
400 {
401 if( !testCase.isDisabled() )
402 addTestCase( testCase );
403 }
404
405 super.run();
406 }
407
408 public void beforeRun()
409 {
410 super.beforeRun();
411
412 WsdlTestSuiteDesktopPanel.this.beforeRun();
413
414 progressBar.setMaximum( getTestCaseCount() );
415 progressBar.setValue( 0 );
416 progressBar.setString( "" );
417
418 if( runLogListener == null )
419 runLogListener = new TestRunLog.TestRunLogTestRunListener( testRunLog, false );
420
421 testRunLog.clear();
422
423 if( getRunType() == TestSuiteRunType.PARALLEL )
424 testRunLog.addText( "<log disabled during parallell execution>" );
425
426 context = new DefaultPropertyExpansionContext( testSuite );
427 try
428 {
429 testSuite.runSetupScript( context );
430 }
431 catch( Exception e )
432 {
433 SoapUI.logError( e );
434 }
435 }
436
437 @Override
438 protected void afterTestCase( TestCase testCase, TestRunner runner )
439 {
440 super.afterTestCase( testCase, runner );
441 progressBar.setValue( getTestCaseList().indexOf( testCase )+1 );
442 if( runner.getStatus() == TestRunner.Status.FAILED )
443 failedTests = true;
444
445 if( getRunType() == TestSuiteRunType.SEQUENTIAL )
446 testCase.removeTestRunListener( runLogListener );
447 }
448
449 @Override
450 protected void beforeTestCase( TestCase testCase )
451 {
452 super.beforeTestCase( testCase );
453 progressBar.setString( "Running " + testCase.getName() );
454
455 if( getRunType() == TestSuiteRunType.SEQUENTIAL )
456 testCase.addTestRunListener( runLogListener );
457 }
458
459 protected void afterRun()
460 {
461 try
462 {
463 testSuite.runTearDownScript( context );
464 }
465 catch( Exception e )
466 {
467 SoapUI.logError( e );
468 }
469 finally
470 {
471 WsdlTestSuiteDesktopPanel.this.afterRun();
472 }
473 }
474 }
475
476 private class SetupScriptGroovyEditorModel extends AbstractGroovyEditorModel
477 {
478 public SetupScriptGroovyEditorModel()
479 {
480 super( new String[] {"log", "context", "testSuite" }, getModelItem().getSettings(), "Setup" );
481 }
482
483 public String getScript()
484 {
485 return getModelItem().getSetupScript();
486 }
487
488 public void setScript( String text )
489 {
490 getModelItem().setSetupScript( text );
491 }
492
493 @Override
494 public Action createRunAction()
495 {
496 return new AbstractAction(){
497
498 public void actionPerformed( ActionEvent e )
499 {
500 try
501 {
502 getModelItem().runSetupScript( null );
503 }
504 catch( Exception e1 )
505 {
506 UISupport.showErrorMessage( e1 );
507 }
508 }};
509 }
510 }
511
512 private class TearDownScriptGroovyEditorModel extends AbstractGroovyEditorModel
513 {
514 public TearDownScriptGroovyEditorModel()
515 {
516 super( new String[] {"log", "context", "testSuite" }, getModelItem().getSettings(), "TearDown" );
517 }
518
519 public String getScript()
520 {
521 return getModelItem().getTearDownScript();
522 }
523
524 public void setScript( String text )
525 {
526 getModelItem().setTearDownScript( text );
527 }
528
529 @Override
530 public Action createRunAction()
531 {
532 return new AbstractAction(){
533
534 public void actionPerformed( ActionEvent e )
535 {
536 try
537 {
538 getModelItem().runTearDownScript( null );
539 }
540 catch( Exception e1 )
541 {
542 UISupport.showErrorMessage( e1 );
543 }
544 }};
545 }
546 }
547 }