1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.panels.testcase;
14
15 import com.eviware.soapui.SoapUI;
16 import com.eviware.soapui.config.TestStepConfig;
17 import com.eviware.soapui.impl.support.actions.ShowOnlineHelpAction;
18 import com.eviware.soapui.impl.wsdl.actions.testcase.AddNewLoadTestAction;
19 import com.eviware.soapui.impl.wsdl.actions.testcase.TestCaseOptionsAction;
20 import com.eviware.soapui.impl.wsdl.panels.support.MockTestRunContext;
21 import com.eviware.soapui.impl.wsdl.panels.support.MockTestRunner;
22 import com.eviware.soapui.impl.wsdl.panels.support.ProgressBarTestCaseAdapter;
23 import com.eviware.soapui.impl.wsdl.panels.testcase.actions.SetCredentialsAction;
24 import com.eviware.soapui.impl.wsdl.panels.testcase.actions.SetEndpointAction;
25 import com.eviware.soapui.impl.wsdl.panels.teststeps.support.AbstractGroovyEditorModel;
26 import com.eviware.soapui.impl.wsdl.panels.teststeps.support.PropertyHolderTable;
27 import com.eviware.soapui.impl.wsdl.support.HelpUrls;
28 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
29 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner;
30 import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStep;
31 import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestStepFactory;
32 import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestStepRegistry;
33 import com.eviware.soapui.model.ModelItem;
34 import com.eviware.soapui.model.support.TestRunListenerAdapter;
35 import com.eviware.soapui.model.testsuite.*;
36 import com.eviware.soapui.monitor.support.TestMonitorListenerAdapter;
37 import com.eviware.soapui.settings.UISettings;
38 import com.eviware.soapui.support.DocumentListenerAdapter;
39 import com.eviware.soapui.support.StringUtils;
40 import com.eviware.soapui.support.UISupport;
41 import com.eviware.soapui.support.action.swing.SwingActionDelegate;
42 import com.eviware.soapui.support.components.*;
43 import com.eviware.soapui.support.dnd.DropType;
44 import com.eviware.soapui.support.dnd.JListDragAndDropable;
45 import com.eviware.soapui.support.dnd.SoapUIDragAndDropHandler;
46 import com.eviware.soapui.support.swing.ComponentBag;
47 import com.eviware.soapui.support.types.StringToObjectMap;
48 import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
49
50 import javax.swing.*;
51 import javax.swing.text.Document;
52 import java.awt.*;
53 import java.awt.dnd.DnDConstants;
54 import java.awt.dnd.DragSource;
55 import java.awt.event.ActionEvent;
56 import java.text.SimpleDateFormat;
57 import java.util.Date;
58
59 /***
60 * WsdlTestCase desktop panel
61 *
62 * @author Ole.Matzura
63 */
64
65 public class WsdlTestCaseDesktopPanel extends ModelItemDesktopPanel<WsdlTestCase>
66 {
67 private JProgressBar progressBar;
68 private TestStepList testStepList;
69 private InternalTestRunListener testRunListener = new InternalTestRunListener();
70 private JButton runButton;
71 private JButton cancelButton;
72 private TestRunner runner;
73 private JButton setEndpointButton;
74 private JButton setCredentialsButton;
75 private JButton optionsButton;
76 private ComponentBag stateDependantComponents = new ComponentBag();
77 private TestRunLog testCaseLog;
78 private JToggleButton loopButton;
79 @SuppressWarnings( "unused" )
80 private ProgressBarTestCaseAdapter progressBarAdapter;
81 private InternalTestMonitorListener testMonitorListener;
82 public boolean canceled;
83 private JTextArea descriptionArea;
84 private PropertyHolderTable propertiesTable;
85 private GroovyEditorComponent tearDownGroovyEditor;
86 private GroovyEditorComponent setupGroovyEditor;
87 private JInspectorPanel testStepListInspectorPanel;
88 private JButton createLoadTestButton;
89
90 public WsdlTestCaseDesktopPanel( WsdlTestCase testCase )
91 {
92 super( testCase );
93
94 buildUI();
95
96 setPreferredSize( new Dimension( 400, 550 ) );
97 setRunningState();
98
99 testCase.addTestRunListener( testRunListener );
100 progressBarAdapter = new ProgressBarTestCaseAdapter( progressBar, testCase );
101 testMonitorListener = new InternalTestMonitorListener();
102
103 SoapUI.getTestMonitor().addTestMonitorListener( testMonitorListener );
104
105 DragSource dragSource = DragSource.getDefaultDragSource();
106 SoapUIDragAndDropHandler dragAndDropHandler = new SoapUIDragAndDropHandler(
107 new ModelItemListDragAndDropable( getTestStepList().getTestStepList(), testCase ), DropType.BEFORE_AND_AFTER );
108
109 dragSource.createDefaultDragGestureRecognizer( getTestStepList().getTestStepList(), DnDConstants.ACTION_COPY_OR_MOVE,
110 dragAndDropHandler );
111 }
112
113 /***
114 * There are three states: - enabled, no testcases or testschedules running -
115 * enabled, standalone testcase running - disabled, testschedule is running
116 */
117
118 private void setRunningState()
119 {
120 stateDependantComponents.setEnabled( !SoapUI.getTestMonitor().hasRunningLoadTest( getModelItem() ) );
121 }
122
123 private void buildUI()
124 {
125 JPanel panel = new JPanel( new BorderLayout() );
126
127 panel.add( buildToolbar(), BorderLayout.PAGE_START );
128 panel.add( buildRunnerBar(), BorderLayout.CENTER );
129
130 add( panel, BorderLayout.NORTH );
131
132 JInspectorPanel inspectorPanel = JInspectorPanelFactory.build( buildContent() );
133 inspectorPanel.addInspector( new JComponentInspector<JComponent>( buildTestLog(), "TestCase Log", "TestCase Execution Log", true ) );
134 inspectorPanel.setDefaultDividerLocation( 0.7F );
135 inspectorPanel.setCurrentInspector( "TestCase Log" );
136
137 if( StringUtils.hasContent( getModelItem().getDescription() ) && getModelItem().getSettings().getBoolean( UISettings.SHOW_DESCRIPTIONS ) )
138 {
139 testStepListInspectorPanel.setCurrentInspector( "Description" );
140 }
141
142 add( inspectorPanel.getComponent(), BorderLayout.CENTER );
143 }
144
145 protected TestStepList getTestStepList()
146 {
147 return testStepList;
148 }
149
150 private JComponent buildTestLog()
151 {
152 testCaseLog = new TestCaseTestRunLog( getModelItem() );
153 stateDependantComponents.add( testCaseLog );
154 return testCaseLog;
155 }
156
157 private JComponent buildContent()
158 {
159 JTabbedPane tabs = new JTabbedPane( JTabbedPane.TOP );
160 testStepListInspectorPanel = JInspectorPanelFactory.build( buildTestStepList(),
161 SwingConstants.BOTTOM );
162
163 tabs.addTab( "TestSteps", testStepListInspectorPanel.getComponent() );
164
165 addTabs( tabs, testStepListInspectorPanel );
166 tabs.setTabLayoutPolicy( JTabbedPane.SCROLL_TAB_LAYOUT );
167
168 return UISupport.createTabPanel( tabs, true );
169 }
170
171 protected JComponent buildTestStepList()
172 {
173 JPanel p = new JPanel( new BorderLayout() );
174 JXToolBar toolbar = UISupport.createToolbar();
175
176 WsdlTestStepFactory[] factories = WsdlTestStepRegistry.getInstance().getFactories();
177 for( WsdlTestStepFactory factory : factories )
178 {
179 toolbar.addFixed( UISupport.createToolbarButton( new AddWsdlTestStepAction( factory ) ) );
180 }
181
182 p.add( toolbar, BorderLayout.NORTH );
183 testStepList = new TestStepList( getModelItem() );
184 stateDependantComponents.add( testStepList );
185
186 p.add( new JScrollPane( testStepList ), BorderLayout.CENTER );
187
188 return p;
189 }
190
191 protected void addTabs( JTabbedPane tabs, JInspectorPanel inspectorPanel )
192 {
193 inspectorPanel.addInspector( new JFocusableComponentInspector<JPanel>( buildDescriptionPanel(),
194 descriptionArea, "Description", "TestCase Description", true ) );
195 inspectorPanel.addInspector( new JComponentInspector<JComponent>( buildPropertiesPanel(), "Properties", "TestCase level properties", true ) );
196 inspectorPanel.addInspector( new GroovyEditorInspector( buildSetupScriptPanel(), "Setup Script", "Script to run before tunning a TestCase" ) );
197 inspectorPanel.addInspector( new GroovyEditorInspector( buildTearDownScriptPanel(), "TearDown Script", "Script to run after a TestCase Run" ) );
198 }
199
200 protected GroovyEditorComponent buildTearDownScriptPanel()
201 {
202 tearDownGroovyEditor = new GroovyEditorComponent( new TearDownScriptGroovyEditorModel(), null );
203 return tearDownGroovyEditor;
204 }
205
206 protected GroovyEditorComponent buildSetupScriptPanel()
207 {
208 setupGroovyEditor = new GroovyEditorComponent( new SetupScriptGroovyEditorModel(), null );
209 return setupGroovyEditor;
210 }
211
212 protected JComponent buildPropertiesPanel()
213 {
214 JPanel panel = new JPanel( new BorderLayout() );
215 propertiesTable = buildPropertiesTable();
216 panel.add( new JScrollPane( propertiesTable ), BorderLayout.CENTER );
217 return panel;
218 }
219
220 protected PropertyHolderTable buildPropertiesTable()
221 {
222 return new PropertyHolderTable( getModelItem() );
223 }
224
225 private JPanel buildDescriptionPanel()
226 {
227 JPanel panel = new JPanel( new BorderLayout() );
228 descriptionArea = new JUndoableTextArea( getModelItem().getDescription() );
229 descriptionArea.getDocument().addDocumentListener( new DocumentListenerAdapter()
230 {
231 public void update( Document document )
232 {
233 getModelItem().setDescription( descriptionArea.getText() );
234 }
235 } );
236
237 panel.setBorder( BorderFactory.createEmptyBorder( 2, 2, 2, 2 ) );
238 panel.add( new JScrollPane( descriptionArea ), BorderLayout.CENTER );
239 UISupport.addTitledBorder( panel, "TestCase Description" );
240
241 return panel;
242 }
243
244 private Component buildToolbar()
245 {
246 JToolBar toolbar = UISupport.createToolbar();
247
248 runButton = UISupport.createToolbarButton( new RunTestCaseAction() );
249 optionsButton = UISupport.createToolbarButton( SwingActionDelegate.createDelegate(
250 TestCaseOptionsAction.SOAPUI_ACTION_ID, getModelItem(), null, "/options.gif" ) );
251 optionsButton.setText( null );
252 cancelButton = UISupport.createToolbarButton( new CancelRunTestCaseAction(), false );
253
254 loopButton = new JToggleButton( UISupport.createImageIcon( "/loop.gif" ) );
255 loopButton.setPreferredSize( UISupport.getPreferredButtonSize() );
256 loopButton.setToolTipText( "Loop TestCase continuously" );
257
258 setCredentialsButton = UISupport.createToolbarButton( new SetCredentialsAction( getModelItem() ) );
259 setEndpointButton = UISupport.createToolbarButton( new SetEndpointAction( getModelItem() ) );
260
261 stateDependantComponents.add( runButton );
262 stateDependantComponents.add( optionsButton );
263 stateDependantComponents.add( cancelButton );
264 stateDependantComponents.add( setCredentialsButton );
265 stateDependantComponents.add( setEndpointButton );
266
267 createLoadTestButton = UISupport.createToolbarButton( SwingActionDelegate.createDelegate(
268 AddNewLoadTestAction.SOAPUI_ACTION_ID, getModelItem(), null, "/loadtest.gif" ) );
269
270 addToolbarActions( toolbar );
271
272 toolbar.add( Box.createHorizontalGlue() );
273 toolbar.add( UISupport.createToolbarButton( new ShowOnlineHelpAction( HelpUrls.TESTCASEEDITOR_HELP_URL ) ) );
274
275 return toolbar;
276 }
277
278 protected void addToolbarActions( JToolBar toolbar )
279 {
280 toolbar.add( runButton );
281 toolbar.add( cancelButton );
282 toolbar.add( loopButton );
283 toolbar.addSeparator( );
284 toolbar.add( setCredentialsButton );
285 toolbar.add( setEndpointButton );
286 toolbar.addSeparator( );
287 toolbar.add( createLoadTestButton );
288 toolbar.addSeparator( );
289 toolbar.add( optionsButton );
290 }
291
292 private Component buildRunnerBar()
293 {
294 progressBar = new JProgressBar( 0, getModelItem().getTestStepCount() );
295 return UISupport.createProgressBarPanel( progressBar, 10, false );
296 }
297
298 private final class InternalTestMonitorListener extends TestMonitorListenerAdapter
299 {
300 public void loadTestStarted( LoadTestRunner runner )
301 {
302 setRunningState();
303 }
304
305 public void loadTestFinished( LoadTestRunner runner )
306 {
307 setRunningState();
308 }
309 }
310
311 public class InternalTestRunListener extends TestRunListenerAdapter
312 {
313 private SimpleDateFormat dateFormat;
314
315 public InternalTestRunListener()
316 {
317 dateFormat = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss.SSS" );
318 }
319
320 public void beforeRun( TestRunner testRunner, TestRunContext runContext )
321 {
322 if( SoapUI.getTestMonitor().hasRunningLoadTest( getModelItem() ) )
323 return;
324
325 runButton.setEnabled( false );
326 cancelButton.setEnabled( true );
327 testStepList.setEnabled( false );
328 testStepList.setSelectedIndex( -1 );
329 testCaseLog.clear();
330
331 testCaseLog.addText( "Test started at " + dateFormat.format( new Date() ) );
332
333 WsdlTestCaseDesktopPanel.this.beforeRun();
334
335 if( runner == null )
336 runner = testRunner;
337 }
338
339 public void beforeStep( TestRunner testRunner, TestRunContext runContext )
340 {
341 if( SoapUI.getTestMonitor().hasRunningLoadTest( getModelItem() ) )
342 return;
343
344 TestStep testStep = runContext.getCurrentStep();
345 testStepList.setSelectedValue( testStep, true );
346 }
347
348 public void afterRun( TestRunner testRunner, TestRunContext runContext )
349 {
350 if( SoapUI.getTestMonitor().hasRunningLoadTest( getModelItem() ) )
351 return;
352
353 WsdlTestCaseRunner wsdlRunner = (WsdlTestCaseRunner) testRunner;
354
355 if( testRunner.getStatus() == TestRunner.Status.CANCELED )
356 testCaseLog.addText( "TestCase canceled [" + testRunner.getReason() + "], time taken = "
357 + wsdlRunner.getTimeTaken() );
358 else if( testRunner.getStatus() == TestRunner.Status.FAILED )
359 {
360 String msg = wsdlRunner.getReason();
361 if( wsdlRunner.getError() != null )
362 {
363 if( msg != null )
364 msg += ":";
365
366 msg += wsdlRunner.getError();
367 }
368
369 testCaseLog.addText( "TestCase failed [" + msg + "], time taken = "
370 + wsdlRunner.getTimeTaken() );
371 }
372 else
373 testCaseLog.addText( "TestCase finished with status [" + testRunner.getStatus() + "], time taken = " + wsdlRunner.getTimeTaken() );
374
375 runner = null;
376
377 JToggleButton loopButton = (JToggleButton) runContext.getProperty( "loopButton" );
378 if( loopButton != null && loopButton.isSelected() && testRunner.getStatus() == TestRunner.Status.FINISHED )
379 {
380 SwingUtilities.invokeLater( new Runnable()
381 {
382 public void run()
383 {
384 runTestCase();
385 }
386 } );
387 }
388 else
389 {
390 WsdlTestCaseDesktopPanel.this.afterRun();
391 }
392 }
393
394 public void afterStep( TestRunner testRunner, TestRunContext runContext, TestStepResult stepResult )
395 {
396 if( SoapUI.getTestMonitor().hasRunningLoadTest( getModelItem() ) )
397 return;
398
399 testCaseLog.addTestStepResult( stepResult );
400 }
401 }
402
403 protected void runTestCase()
404 {
405 if( canceled )
406 {
407
408 runButton.setEnabled( true );
409 cancelButton.setEnabled( false );
410 testStepList.setEnabled( true );
411 return;
412 }
413
414 StringToObjectMap properties = new StringToObjectMap();
415 properties.put( "loopButton", loopButton );
416 runner = getModelItem().run( properties, true );
417 }
418
419 public class RunTestCaseAction extends AbstractAction
420 {
421 public RunTestCaseAction()
422 {
423 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_testcase.gif" ) );
424 putValue( Action.SHORT_DESCRIPTION, "Runs this testcase" );
425 }
426
427 public void actionPerformed( ActionEvent e )
428 {
429 canceled = false;
430 runTestCase();
431 }
432 }
433
434 public class CancelRunTestCaseAction extends AbstractAction
435 {
436 public CancelRunTestCaseAction()
437 {
438 putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/stop_testcase.gif" ) );
439 putValue( Action.SHORT_DESCRIPTION, "Stops running this testcase" );
440 }
441
442 public void actionPerformed( ActionEvent e )
443 {
444 if( runner != null )
445 runner.cancel( "canceled in UI" );
446
447 canceled = true;
448 }
449 }
450
451 public boolean onClose( boolean canCancel )
452 {
453 if( canCancel )
454 {
455 if( runner != null && runner.getStatus() == TestRunner.Status.RUNNING )
456 {
457 Boolean retval = UISupport.confirmOrCancel( "Cancel running TestCase?", "Cancel Run" );
458
459 if( retval == null )
460 return false;
461 if( retval.booleanValue() )
462 {
463 runner.cancel( null );
464 }
465 }
466 }
467 else
468 {
469 if( runner != null && runner.getStatus() == TestRunner.Status.RUNNING )
470 {
471 runner.cancel( null );
472 }
473 }
474
475 SoapUI.getTestMonitor().removeTestMonitorListener( testMonitorListener );
476 getModelItem().removeTestRunListener( testRunListener );
477 testStepList.release();
478 progressBarAdapter.release();
479 propertiesTable.release();
480
481 setupGroovyEditor.getEditor().release();
482 tearDownGroovyEditor.getEditor().release();
483
484 testCaseLog.release();
485
486 return release();
487 }
488
489 public boolean dependsOn( ModelItem modelItem )
490 {
491 return modelItem == getModelItem() || modelItem == getModelItem().getTestSuite()
492 || modelItem == getModelItem().getTestSuite().getProject();
493 }
494
495 protected void beforeRun()
496 {
497 }
498
499 protected void afterRun()
500 {
501 runButton.setEnabled( true );
502 cancelButton.setEnabled( false );
503 testStepList.setEnabled( true );
504 }
505
506 private class SetupScriptGroovyEditorModel extends AbstractGroovyEditorModel
507 {
508 @Override
509 public Action createRunAction()
510 {
511 return new AbstractAction()
512 {
513
514 public void actionPerformed( ActionEvent e )
515 {
516 try
517 {
518 MockTestRunner mockTestRunner = new MockTestRunner( getModelItem(), SoapUI.ensureGroovyLog() );
519 getModelItem().runSetupScript( new MockTestRunContext( mockTestRunner, null ), mockTestRunner );
520 }
521 catch( Exception e1 )
522 {
523 UISupport.showErrorMessage( e1 );
524 }
525 }
526 };
527 }
528
529 public SetupScriptGroovyEditorModel()
530 {
531 super( new String[]{"log", "context", "testRunner"}, getModelItem().getSettings(), "Setup" );
532 }
533
534 public String getScript()
535 {
536 return getModelItem().getSetupScript();
537 }
538
539 public void setScript( String text )
540 {
541 getModelItem().setSetupScript( text );
542 }
543 }
544
545 private class TearDownScriptGroovyEditorModel extends AbstractGroovyEditorModel
546 {
547 @Override
548 public Action createRunAction()
549 {
550 return new AbstractAction()
551 {
552
553 public void actionPerformed( ActionEvent e )
554 {
555 try
556 {
557 MockTestRunner mockTestRunner = new MockTestRunner( getModelItem(), SoapUI.ensureGroovyLog() );
558 getModelItem().runTearDownScript( new MockTestRunContext( mockTestRunner, null ), mockTestRunner );
559 }
560 catch( Exception e1 )
561 {
562 UISupport.showErrorMessage( e1 );
563 }
564 }
565 };
566 }
567
568 public TearDownScriptGroovyEditorModel()
569 {
570 super( new String[]{"log", "context", "testRunner"}, getModelItem().getSettings(), "TearDown" );
571 }
572
573 public String getScript()
574 {
575 return getModelItem().getTearDownScript();
576 }
577
578 public void setScript( String text )
579 {
580 getModelItem().setTearDownScript( text );
581 }
582 }
583
584 private class AddWsdlTestStepAction extends AbstractAction
585 {
586 private final WsdlTestStepFactory factory;
587
588 public AddWsdlTestStepAction( WsdlTestStepFactory factory )
589 {
590 this.factory = factory;
591 putValue( SMALL_ICON, UISupport.createImageIcon( factory.getTestStepIconPath() ) );
592 putValue( SHORT_DESCRIPTION, "Create a new " + factory.getTestStepName() + " TestStep" );
593 }
594
595 public void actionPerformed( ActionEvent e )
596 {
597 int ix = testStepList.getTestStepList().getSelectedIndex();
598
599 String name = UISupport.prompt( "Specify name for new step", ix == -1 ? "Add Step" : "Insert Step", factory.getTestStepName() );
600 if( name != null )
601 {
602 TestStepConfig newTestStepConfig = factory.createNewTestStep( getModelItem(), name );
603 if( newTestStepConfig != null )
604 {
605 WsdlTestStep testStep = getModelItem().insertTestStep( newTestStepConfig, ix );
606 UISupport.selectAndShow( testStep );
607 }
608 }
609
610 }
611 }
612
613 public static class ModelItemListDragAndDropable extends JListDragAndDropable<JList>
614 {
615 public ModelItemListDragAndDropable( JList list, WsdlTestCase testCase )
616 {
617 super( list, testCase );
618 }
619
620 @Override
621 public ModelItem getModelItemAtRow( int row )
622 {
623 return (ModelItem) getList().getModel().getElementAt( row );
624 }
625
626 @Override
627 public int getModelItemRow( ModelItem modelItem )
628 {
629 ListModel model = getList().getModel();
630
631 for( int c = 0; c < model.getSize(); c++ )
632 {
633 if( model.getElementAt( c ) == modelItem )
634 return c;
635 }
636
637 return -1;
638 }
639
640 public Component getRenderer( ModelItem modelItem )
641 {
642 return getList().getCellRenderer().getListCellRendererComponent( getList(), modelItem,
643 getModelItemRow( modelItem ), true, true );
644 }
645
646 @Override
647 public void setDragInfo( String dropInfo )
648 {
649 super.setDragInfo( dropInfo == null || dropInfo.length() == 0 ? null : dropInfo );
650 }
651 }
652 }