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