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.TESTSUITEEDITOR_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
273 return toolbar;
274 }
275
276 public boolean onClose( boolean canCancel )
277 {
278 propertiesTable.release();
279
280 setupGroovyEditor.getEditor().release();
281 tearDownGroovyEditor.getEditor().release();
282
283 testRunLog.release();
284
285 return super.release();
286 }
287
288 public JComponent getComponent()
289 {
290 return this;
291 }
292
293 public boolean dependsOn(ModelItem modelItem)
294 {
295 return modelItem == getModelItem() || modelItem == getModelItem().getProject();
296 }
297
298 protected void runTestSuite()
299 {
300 new Thread( testSuiteRunner, getModelItem().getName() + " TestSuiteRunner" ).start();
301 }
302
303 protected void beforeRun()
304 {
305 runAction.setEnabled( false );
306 cancelAction.setEnabled( true );
307 testCaseList.setEnabled( false );
308 progressBar.setForeground( Color.GREEN.darker() );
309
310 failedTests = false;
311 }
312
313 protected void afterRun()
314 {
315 runAction.setEnabled( true );
316 cancelAction.setEnabled( false );
317 testCaseList.setEnabled( true );
318
319 progressBar.setString( failedTests ? "Failed" : testSuiteRunner.isCanceled() ? "Canceled" : "Passed" );
320 progressBar.setForeground( failedTests ? Color.RED : Color.GREEN.darker() );
321 }
322
323 private final class InternalTestSuiteListener extends TestSuiteListenerAdapter
324 {
325 public void testCaseAdded(TestCase testCase)
326 {
327 runAction.setEnabled( getModelItem().getTestCaseCount() > 0 );
328 }
329
330 public void testCaseRemoved(TestCase testCase)
331 {
332 runAction.setEnabled( getModelItem().getTestCaseCount() > 0 );
333 }
334 }
335
336 private class RunAction extends AbstractAction
337 {
338 public RunAction()
339 {
340 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_testcase.gif" ));
341 putValue( Action.SHORT_DESCRIPTION, "Runs the selected TestCases" );
342 }
343
344 public void actionPerformed(ActionEvent e)
345 {
346 runTestSuite();
347 }
348 }
349
350 private class CancelAction extends AbstractAction
351 {
352 public CancelAction()
353 {
354 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/stop_testcase.gif" ));
355 putValue( Action.SHORT_DESCRIPTION, "Cancels ongoing TestCase runs" );
356 }
357
358 public void actionPerformed(ActionEvent e)
359 {
360 testSuiteRunner.cancel();
361 }
362 }
363
364 /***
365 * Runs the selected testsuites..
366 *
367 * @author Ole.Matzura
368 */
369
370 public class TestSuiteRunner extends WsdlTestScenario
371 {
372 private TestRunLogTestRunListener runLogListener;
373 private int finishCount;
374
375 public TestSuiteRunner()
376 {
377 super( TestSuiteRunType.SEQUENTIAL );
378 }
379
380 public void run()
381 {
382 setRunType( getModelItem().getRunType() );
383
384 removeAllTestCases();
385
386 testCaseList.reset();
387
388 for( TestCase testCase : getModelItem().getTestCaseList() )
389 {
390 if( !testCase.isDisabled() )
391 addTestCase( testCase );
392 }
393
394 super.run();
395 }
396
397 protected PropertyExpansionContext createContext()
398 {
399 return new DefaultPropertyExpansionContext( getModelItem() );
400 }
401
402 public void beforeRun( PropertyExpansionContext context )
403 {
404 super.beforeRun( context );
405
406 WsdlTestSuiteDesktopPanel.this.beforeRun();
407
408 progressBar.setMaximum( getTestCaseCount() );
409 progressBar.setValue( 0 );
410 progressBar.setString( "" );
411 finishCount = 0;
412
413 if( runLogListener == null )
414 runLogListener = new TestRunLog.TestRunLogTestRunListener( testRunLog, false );
415
416 testRunLog.clear();
417
418 if( getRunType() == TestSuiteRunType.PARALLEL )
419 testRunLog.addText( "<log disabled during parallell execution>" );
420
421 context = new DefaultPropertyExpansionContext( getModelItem() );
422 try
423 {
424 getModelItem().runSetupScript( context );
425 }
426 catch( Exception e )
427 {
428 SoapUI.logError( e );
429 }
430 }
431
432 @Override
433 protected void afterTestCase( TestCase testCase, TestRunner runner )
434 {
435 super.afterTestCase( testCase, runner );
436 progressBar.setValue( ++finishCount );
437 if( runner.getStatus() == TestRunner.Status.FAILED )
438 failedTests = true;
439
440 if( getRunType() == TestSuiteRunType.SEQUENTIAL )
441 testCase.removeTestRunListener( runLogListener );
442 }
443
444 @Override
445 protected void beforeTestCase( TestCase testCase )
446 {
447 super.beforeTestCase( testCase );
448 progressBar.setString( "Running " + testCase.getName() );
449
450 if( getRunType() == TestSuiteRunType.SEQUENTIAL )
451 testCase.addTestRunListener( runLogListener );
452 }
453
454 protected void afterRun(PropertyExpansionContext context)
455 {
456 super.afterRun( context );
457
458 try
459 {
460 getModelItem().runTearDownScript( context );
461 }
462 catch( Exception e )
463 {
464 SoapUI.logError( e );
465 }
466 finally
467 {
468 WsdlTestSuiteDesktopPanel.this.afterRun();
469 }
470 }
471 }
472
473 private class SetupScriptGroovyEditorModel extends AbstractGroovyEditorModel
474 {
475 public SetupScriptGroovyEditorModel()
476 {
477 super( new String[] {"log", "context", "testSuite" }, getModelItem().getSettings(), "Setup" );
478 }
479
480 public String getScript()
481 {
482 return getModelItem().getSetupScript();
483 }
484
485 public void setScript( String text )
486 {
487 getModelItem().setSetupScript( text );
488 }
489
490 @Override
491 public Action createRunAction()
492 {
493 return new AbstractAction(){
494
495 public void actionPerformed( ActionEvent e )
496 {
497 try
498 {
499 getModelItem().runSetupScript( null );
500 }
501 catch( Exception e1 )
502 {
503 UISupport.showErrorMessage( e1 );
504 }
505 }};
506 }
507 }
508
509 private class TearDownScriptGroovyEditorModel extends AbstractGroovyEditorModel
510 {
511 public TearDownScriptGroovyEditorModel()
512 {
513 super( new String[] {"log", "context", "testSuite" }, getModelItem().getSettings(), "TearDown" );
514 }
515
516 public String getScript()
517 {
518 return getModelItem().getTearDownScript();
519 }
520
521 public void setScript( String text )
522 {
523 getModelItem().setTearDownScript( text );
524 }
525
526 @Override
527 public Action createRunAction()
528 {
529 return new AbstractAction(){
530
531 public void actionPerformed( ActionEvent e )
532 {
533 try
534 {
535 getModelItem().runTearDownScript( null );
536 }
537 catch( Exception e1 )
538 {
539 UISupport.showErrorMessage( e1 );
540 }
541 }};
542 }
543 }
544 }