View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2010 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
11   */
12  
13  package com.eviware.soapui.impl.wsdl.panels.teststeps;
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.beans.PropertyChangeEvent;
20  import java.beans.PropertyChangeListener;
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.JComponent;
27  import javax.swing.SwingUtilities;
28  import javax.swing.border.TitledBorder;
29  
30  import com.eviware.soapui.SoapUI;
31  import com.eviware.soapui.config.RunTestCaseRunModeTypeConfig;
32  import com.eviware.soapui.impl.support.actions.ShowOnlineHelpAction;
33  import com.eviware.soapui.impl.wsdl.WsdlProject;
34  import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
35  import com.eviware.soapui.impl.wsdl.panels.support.MockTestRunContext;
36  import com.eviware.soapui.impl.wsdl.panels.support.MockTestRunner;
37  import com.eviware.soapui.impl.wsdl.panels.testcase.JTestRunLog;
38  import com.eviware.soapui.impl.wsdl.panels.testcase.TestRunLogTestRunListener;
39  import com.eviware.soapui.impl.wsdl.panels.teststeps.support.PropertyHolderTable;
40  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
41  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
42  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner;
43  import com.eviware.soapui.impl.wsdl.teststeps.WsdlRunTestCaseTestStep;
44  import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStepResult;
45  import com.eviware.soapui.model.ModelItem;
46  import com.eviware.soapui.model.support.ModelSupport;
47  import com.eviware.soapui.model.testsuite.TestCase;
48  import com.eviware.soapui.model.testsuite.TestCaseRunContext;
49  import com.eviware.soapui.model.testsuite.TestCaseRunner;
50  import com.eviware.soapui.support.UISupport;
51  import com.eviware.soapui.support.components.JComponentInspector;
52  import com.eviware.soapui.support.components.JInspectorPanel;
53  import com.eviware.soapui.support.components.JInspectorPanelFactory;
54  import com.eviware.soapui.support.components.JXToolBar;
55  import com.eviware.soapui.support.types.StringList;
56  import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
57  import com.eviware.x.form.XFormDialog;
58  import com.eviware.x.form.XFormField;
59  import com.eviware.x.form.XFormFieldListener;
60  import com.eviware.x.form.support.ADialogBuilder;
61  import com.eviware.x.form.support.AField;
62  import com.eviware.x.form.support.AForm;
63  import com.eviware.x.form.support.XFormMultiSelectList;
64  import com.eviware.x.form.support.AField.AFieldType;
65  
66  public class WsdlRunTestCaseStepDesktopPanel extends ModelItemDesktopPanel<WsdlRunTestCaseTestStep> implements
67  		PropertyChangeListener
68  {
69  	private WsdlProject project;
70  	private TitledBorder titledBorder;
71  	private OptionsAction optionsAction;
72  	private RunAction runAction;
73  	private OpenTestCaseAction openTestCaseAction;
74  	private JTestRunLog testRunLog;
75  	private CancelRunTestCaseAction cancelAction;
76  	private XFormDialog optionsDialog;
77  	private JInspectorPanel inspectorPanel;
78  	private PropertyHolderTable propertiesTable;
79  
80  	public WsdlRunTestCaseStepDesktopPanel( WsdlRunTestCaseTestStep modelItem )
81  	{
82  		super( modelItem );
83  
84  		project = getModelItem().getTestCase().getTestSuite().getProject();
85  
86  		getModelItem().addPropertyChangeListener( WsdlRunTestCaseTestStep.TARGET_TESTCASE, this );
87  		WsdlTestCase targetTestCase = getModelItem().getTargetTestCase();
88  		if( targetTestCase != null )
89  		{
90  			targetTestCase.addPropertyChangeListener( WsdlTestCase.NAME_PROPERTY, this );
91  			targetTestCase.getTestSuite().addPropertyChangeListener( WsdlTestCase.NAME_PROPERTY, this );
92  		}
93  
94  		buildUI();
95  		setEnabledState();
96  
97  		if( modelItem.getTargetTestCase() == null )
98  		{
99  			SwingUtilities.invokeLater( new Runnable()
100 			{
101 
102 				public void run()
103 				{
104 					optionsAction.actionPerformed( null );
105 				}
106 			} );
107 		}
108 
109 		setPreferredSize( new Dimension( 400, 600 ) );
110 	}
111 
112 	private void setEnabledState()
113 	{
114 		runAction.setEnabled( getModelItem().getTargetTestCase() != null );
115 		openTestCaseAction.setEnabled( getModelItem().getTargetTestCase() != null );
116 	}
117 
118 	private void buildUI()
119 	{
120 		add( buildToolbar(), BorderLayout.NORTH );
121 		add( buildContent(), BorderLayout.CENTER );
122 	}
123 
124 	private Component buildContent()
125 	{
126 		inspectorPanel = JInspectorPanelFactory.build( createPropertiesTable() );
127 
128 		inspectorPanel.addInspector( new JComponentInspector<JComponent>( buildLog(), "TestCase Log",
129 				"log output from testcase run", true ) );
130 
131 		return inspectorPanel.getComponent();
132 	}
133 
134 	private JComponent buildLog()
135 	{
136 		testRunLog = new JTestRunLog( getModelItem().getSettings() );
137 		return testRunLog;
138 	}
139 
140 	protected JComponent createPropertiesTable()
141 	{
142 		propertiesTable = new PropertyHolderTable( getModelItem() );
143 
144 		titledBorder = BorderFactory.createTitledBorder( createTitleForBorder() );
145 		propertiesTable.setBorder( titledBorder );
146 
147 		return propertiesTable;
148 	}
149 
150 	private String createTitleForBorder()
151 	{
152 		WsdlTestCase targetTestCase = getModelItem().getTargetTestCase();
153 		return "TestCase ["
154 				+ ( targetTestCase == null ? "- none selected -" : targetTestCase.getTestSuite().getName() + ":"
155 						+ targetTestCase.getName() ) + "] Run Properties";
156 	}
157 
158 	private Component buildToolbar()
159 	{
160 		JXToolBar toolbar = UISupport.createToolbar();
161 
162 		toolbar.add( UISupport.createToolbarButton( runAction = new RunAction() ) );
163 		toolbar.add( UISupport.createToolbarButton( cancelAction = new CancelRunTestCaseAction(), false ) );
164 		toolbar.add( UISupport.createToolbarButton( optionsAction = new OptionsAction() ) );
165 		toolbar.add( UISupport.createToolbarButton( openTestCaseAction = new OpenTestCaseAction() ) );
166 
167 		toolbar.addGlue();
168 		toolbar.add( UISupport.createToolbarButton( new ShowOnlineHelpAction( HelpUrls.RUNTESTCASESTEP_HELP_URL ) ) );
169 
170 		return toolbar;
171 	}
172 
173 	@Override
174 	public boolean dependsOn( ModelItem modelItem )
175 	{
176 		WsdlRunTestCaseTestStep callStep = getModelItem();
177 
178 		return modelItem == callStep || modelItem == callStep.getTestCase()
179 				|| modelItem == callStep.getTestCase().getTestSuite()
180 				|| modelItem == callStep.getTestCase().getTestSuite().getProject();
181 	}
182 
183 	public boolean onClose( boolean canCancel )
184 	{
185 		getModelItem().removePropertyChangeListener( WsdlRunTestCaseTestStep.TARGET_TESTCASE, this );
186 
187 		WsdlTestCase targetTestCase = getModelItem().getTargetTestCase();
188 		if( targetTestCase != null )
189 		{
190 			targetTestCase.removePropertyChangeListener( WsdlTestCase.NAME_PROPERTY, this );
191 			targetTestCase.getTestSuite().removePropertyChangeListener( WsdlTestCase.NAME_PROPERTY, this );
192 		}
193 
194 		testRunLog.release();
195 		if( optionsDialog != null )
196 		{
197 			optionsDialog.release();
198 			optionsDialog = null;
199 		}
200 
201 		propertiesTable.release();
202 		inspectorPanel.release();
203 
204 		return release();
205 	}
206 
207 	private class RunAction extends AbstractAction
208 	{
209 		public RunAction()
210 		{
211 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_testcase.gif" ) );
212 			putValue( Action.SHORT_DESCRIPTION, "Runs the selected TestCases" );
213 		}
214 
215 		public void actionPerformed( ActionEvent e )
216 		{
217 			runAction.setEnabled( false );
218 			cancelAction.setEnabled( true );
219 
220 			new Thread( new Runnable()
221 			{
222 
223 				public void run()
224 				{
225 					WsdlRunTestCaseTestStep testStep = getModelItem();
226 					InternalTestRunListener testRunListener = new InternalTestRunListener();
227 					testStep.addTestRunListener( testRunListener );
228 
229 					try
230 					{
231 						testRunLog.clear();
232 						MockTestRunner mockTestRunner = new MockTestRunner( testStep.getTestCase(), SoapUI.ensureGroovyLog() );
233 						WsdlTestStepResult result = ( WsdlTestStepResult )testStep.run( mockTestRunner,
234 								new MockTestRunContext( mockTestRunner, testStep ) );
235 
236 						Throwable er = result.getError();
237 						if( er != null )
238 						{
239 							UISupport.showErrorMessage( er.toString() );
240 						}
241 					}
242 					catch( Throwable t )
243 					{
244 						UISupport.showErrorMessage( t );
245 					}
246 					finally
247 					{
248 						testStep.removeTestRunListener( testRunListener );
249 						runAction.setEnabled( true );
250 						cancelAction.setEnabled( false );
251 					}
252 				}
253 			} ).start();
254 		}
255 	}
256 
257 	private class OpenTestCaseAction extends AbstractAction
258 	{
259 		public OpenTestCaseAction()
260 		{
261 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/testCase.gif" ) );
262 			putValue( Action.SHORT_DESCRIPTION, "Opens the target TestCases editor" );
263 		}
264 
265 		public void actionPerformed( ActionEvent e )
266 		{
267 			WsdlTestCase targetTestCase = getModelItem().getTargetTestCase();
268 			if( targetTestCase == null )
269 				UISupport.showErrorMessage( "No target TestCase selected" );
270 			else
271 				UISupport.showDesktopPanel( targetTestCase );
272 		}
273 	}
274 
275 	private class OptionsAction extends AbstractAction
276 	{
277 		public OptionsAction()
278 		{
279 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/options.gif" ) );
280 			putValue( Action.SHORT_DESCRIPTION, "Sets Options" );
281 		}
282 
283 		public void actionPerformed( ActionEvent e )
284 		{
285 			if( optionsDialog == null )
286 			{
287 				optionsDialog = ADialogBuilder.buildDialog( OptionsForm.class );
288 				optionsDialog.getFormField( OptionsForm.TESTSUITE ).addFormFieldListener( new XFormFieldListener()
289 				{
290 
291 					public void valueChanged( XFormField sourceField, String newValue, String oldValue )
292 					{
293 						List<TestCase> testCaseList = project.getTestSuiteByName( newValue ).getTestCaseList();
294 						testCaseList.remove( getModelItem().getTestCase() );
295 						optionsDialog.setOptions( OptionsForm.TESTCASE, ModelSupport.getNames( testCaseList ) );
296 
297 						if( testCaseList.size() > 0 )
298 						{
299 							WsdlTestCase testCase = project.getTestSuiteByName( newValue ).getTestCaseAt( 0 );
300 							optionsDialog.setOptions( OptionsForm.RETURN_PROPERTIES, testCase.getPropertyNames() );
301 							( ( XFormMultiSelectList )optionsDialog.getFormField( OptionsForm.RETURN_PROPERTIES ) )
302 									.setSelectedOptions( getModelItem().getReturnProperties().toStringArray() );
303 						}
304 					}
305 				} );
306 				optionsDialog.getFormField( OptionsForm.TESTCASE ).addFormFieldListener( new XFormFieldListener()
307 				{
308 
309 					public void valueChanged( XFormField sourceField, String newValue, String oldValue )
310 					{
311 						WsdlTestSuite testSuite = project
312 								.getTestSuiteByName( optionsDialog.getValue( OptionsForm.TESTSUITE ) );
313 						WsdlTestCase testCase = testSuite.getTestCaseByName( newValue );
314 						optionsDialog.setOptions( OptionsForm.RETURN_PROPERTIES, testCase.getPropertyNames() );
315 						( ( XFormMultiSelectList )optionsDialog.getFormField( OptionsForm.RETURN_PROPERTIES ) )
316 								.setSelectedOptions( getModelItem().getReturnProperties().toStringArray() );
317 					}
318 				} );
319 			}
320 
321 			WsdlTestCase targetTestCase = getModelItem().getTargetTestCase();
322 
323 			optionsDialog.setOptions( OptionsForm.TESTSUITE, ModelSupport.getNames( project.getTestSuiteList() ) );
324 			if( targetTestCase != null )
325 			{
326 				optionsDialog.setValue( OptionsForm.TESTSUITE, targetTestCase.getTestSuite().getName() );
327 
328 				List<TestCase> testCaseList = targetTestCase.getTestSuite().getTestCaseList();
329 				testCaseList.remove( getModelItem().getTestCase() );
330 
331 				optionsDialog.setOptions( OptionsForm.TESTCASE, ModelSupport.getNames( testCaseList ) );
332 				optionsDialog.setValue( OptionsForm.TESTCASE, targetTestCase.getName() );
333 
334 				optionsDialog.setOptions( OptionsForm.RETURN_PROPERTIES, targetTestCase.getPropertyNames() );
335 				( ( XFormMultiSelectList )optionsDialog.getFormField( OptionsForm.RETURN_PROPERTIES ) )
336 						.setSelectedOptions( getModelItem().getReturnProperties().toStringArray() );
337 			}
338 			else
339 			{
340 				if( project.getTestSuiteCount() == 0 )
341 				{
342 					optionsDialog.setOptions( OptionsForm.TESTCASE, new String[0] );
343 					optionsDialog.setOptions( OptionsForm.RETURN_PROPERTIES, new String[0] );
344 				}
345 				else
346 				{
347 					List<TestCase> testCaseList = project.getTestSuiteAt( 0 ).getTestCaseList();
348 					testCaseList.remove( getModelItem().getTestCase() );
349 					optionsDialog.setOptions( OptionsForm.TESTCASE, ModelSupport.getNames( testCaseList ) );
350 
351 					if( testCaseList.isEmpty() )
352 						optionsDialog.setOptions( OptionsForm.RETURN_PROPERTIES, new String[0] );
353 					else
354 						optionsDialog.setOptions( OptionsForm.RETURN_PROPERTIES, testCaseList.get( 0 ).getPropertyNames() );
355 				}
356 			}
357 
358 			switch( getModelItem().getRunMode().intValue() )
359 			{
360 			case RunTestCaseRunModeTypeConfig.INT_PARALLELL :
361 				optionsDialog.setValue( OptionsForm.RUN_MODE, OptionsForm.CREATE_ISOLATED_COPY_FOR_EACH_RUN );
362 				break;
363 			case RunTestCaseRunModeTypeConfig.INT_SINGLETON_AND_FAIL :
364 				optionsDialog.setValue( OptionsForm.RUN_MODE, OptionsForm.RUN_PRIMARY_TEST_CASE );
365 				break;
366 			case RunTestCaseRunModeTypeConfig.INT_SINGLETON_AND_WAIT :
367 				optionsDialog.setValue( OptionsForm.RUN_MODE, OptionsForm.RUN_SYNCHRONIZED_TESTCASE );
368 				break;
369 			}
370 			
371 			optionsDialog.setBooleanValue( OptionsForm.COPY_HTTP_SESSION, getModelItem().isCopyHttpSession() );
372 			optionsDialog.setBooleanValue( OptionsForm.COPY_LOADTEST_PROPERTIES, getModelItem().isCopyLoadTestProperties() );
373 			optionsDialog.setBooleanValue( OptionsForm.IGNORE_EMPTY_PROPERTIES, getModelItem().isIgnoreEmptyProperties() );
374 
375 			if( optionsDialog.show() )
376 			{
377 				WsdlTestSuite testSuite = project.getTestSuiteByName( optionsDialog.getValue( OptionsForm.TESTSUITE ) );
378 				getModelItem().setTargetTestCase(
379 						testSuite == null ? null : testSuite
380 								.getTestCaseByName( optionsDialog.getValue( OptionsForm.TESTCASE ) ) );
381 				getModelItem().setReturnProperties(
382 						new StringList(
383 								( ( XFormMultiSelectList )optionsDialog.getFormField( OptionsForm.RETURN_PROPERTIES ) )
384 										.getSelectedOptions() ) );
385 
386 				switch( optionsDialog.getValueIndex( OptionsForm.RUN_MODE ) )
387 				{
388 				case 0 :
389 					getModelItem().setRunMode( RunTestCaseRunModeTypeConfig.PARALLELL );
390 					break;
391 				case 1 :
392 					getModelItem().setRunMode( RunTestCaseRunModeTypeConfig.SINGLETON_AND_FAIL );
393 					break;
394 				case 2 :
395 					getModelItem().setRunMode( RunTestCaseRunModeTypeConfig.SINGLETON_AND_WAIT );
396 					break;
397 				}
398 
399 				getModelItem().setCopyHttpSession( optionsDialog.getBooleanValue( OptionsForm.COPY_HTTP_SESSION ) );
400 				getModelItem().setCopyLoadTestProperties( optionsDialog.getBooleanValue( OptionsForm.COPY_LOADTEST_PROPERTIES ) );
401 				getModelItem().setIgnoreEmptyProperties( optionsDialog.getBooleanValue( OptionsForm.IGNORE_EMPTY_PROPERTIES ) );
402 
403 				titledBorder.setTitle( createTitleForBorder() );
404 			}
405 		}
406 	}
407 
408 	@AForm( name = "Run TestCase Options", description = "Set options for the Run TestCase Step below" )
409 	private static interface OptionsForm
410 	{
411 		public static final String RUN_PRIMARY_TEST_CASE = "Run primary TestCase (fail if already running)";
412 		public static final String CREATE_ISOLATED_COPY_FOR_EACH_RUN = "Create isolated copy for each run (Thread-Safe)";
413 		public static final String RUN_SYNCHRONIZED_TESTCASE = "Run primary TestCase (wait for running to finish, Thread-Safe)";
414 
415 		@AField( name = "Target TestCase", description = "Selects the TestCase to run", type = AFieldType.ENUMERATION )
416 		public static final String TESTCASE = "Target TestCase";
417 
418 		@AField( name = "Target TestSuite", description = "Selects the containing TestSuite to run", type = AFieldType.ENUMERATION )
419 		public static final String TESTSUITE = "Target TestSuite";
420 
421 		@AField( name = "Return Properties", description = "Selects the properties that are return values", type = AFieldType.MULTILIST )
422 		public static final String RETURN_PROPERTIES = "Return Properties";
423 
424 		@AField( name = "Run Mode", description = "Sets how to run the target TestCase", type = AFieldType.RADIOGROUP, values = {
425 				CREATE_ISOLATED_COPY_FOR_EACH_RUN, RUN_PRIMARY_TEST_CASE, RUN_SYNCHRONIZED_TESTCASE } )
426 		public static final String RUN_MODE = "Run Mode";
427 		
428 		@AField( name = "Copy LoadTest Properties", description = "Copies LoadTest related properties to target context", type = AFieldType.BOOLEAN )
429 		public static final String COPY_LOADTEST_PROPERTIES = "Copy LoadTest Properties";
430 		
431 		@AField( name = "Copy HTTP Session", description = "Copies LoadTest related properties to target context", type = AFieldType.BOOLEAN )
432 		public static final String COPY_HTTP_SESSION = "Copy HTTP Session";
433 		
434 		@AField( name = "Ignore Empty Properties", description = "Does not set empty TestCase property values", type = AFieldType.BOOLEAN )
435 		public static final String IGNORE_EMPTY_PROPERTIES = "Ignore Empty Properties";
436 	}
437 
438 	public void propertyChange( PropertyChangeEvent evt )
439 	{
440 		super.propertyChange( evt );
441 
442 		if( evt.getPropertyName().equals( WsdlRunTestCaseTestStep.TARGET_TESTCASE ) )
443 		{
444 			WsdlTestCase targetTestCase = ( WsdlTestCase )evt.getOldValue();
445 			if( targetTestCase != null )
446 			{
447 				targetTestCase.removePropertyChangeListener( WsdlTestCase.NAME_PROPERTY, this );
448 				targetTestCase.getTestSuite().removePropertyChangeListener( WsdlTestCase.NAME_PROPERTY, this );
449 			}
450 
451 			targetTestCase = ( WsdlTestCase )evt.getNewValue();
452 			if( targetTestCase != null )
453 			{
454 				targetTestCase.addPropertyChangeListener( WsdlTestCase.NAME_PROPERTY, this );
455 				targetTestCase.getTestSuite().addPropertyChangeListener( WsdlTestCase.NAME_PROPERTY, this );
456 			}
457 		}
458 
459 		setEnabledState();
460 		titledBorder.setTitle( createTitleForBorder() );
461 		repaint();
462 	}
463 
464 	public class InternalTestRunListener extends TestRunLogTestRunListener
465 	{
466 		public InternalTestRunListener()
467 		{
468 			super( testRunLog, true );
469 		}
470 
471 		public void beforeRun( TestCaseRunner testRunner, TestCaseRunContext runContext )
472 		{
473 			runAction.setEnabled( false );
474 			cancelAction.setEnabled( true );
475 		}
476 
477 		public void afterRun( TestCaseRunner testRunner, TestCaseRunContext runContext )
478 		{
479 			runAction.setEnabled( true );
480 			cancelAction.setEnabled( false );
481 		}
482 	}
483 
484 	public class CancelRunTestCaseAction extends AbstractAction
485 	{
486 		public CancelRunTestCaseAction()
487 		{
488 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/stop_testcase.gif" ) );
489 			putValue( Action.SHORT_DESCRIPTION, "Stops running this testcase" );
490 		}
491 
492 		public void actionPerformed( ActionEvent e )
493 		{
494 			WsdlTestCaseRunner testCaseRunner = getModelItem().getTestCaseRunner();
495 			if( testCaseRunner != null )
496 				testCaseRunner.cancel( "Canceled from RunTestCase UI" );
497 		}
498 	}
499 }