View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2009 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  
79  	public WsdlRunTestCaseStepDesktopPanel( WsdlRunTestCaseTestStep modelItem )
80  	{
81  		super( modelItem );
82  
83  		project = getModelItem().getTestCase().getTestSuite().getProject();
84  
85  		getModelItem().addPropertyChangeListener( WsdlRunTestCaseTestStep.TARGET_TESTCASE, this );
86  		WsdlTestCase targetTestCase = getModelItem().getTargetTestCase();
87  		if( targetTestCase != null )
88  		{
89  			targetTestCase.addPropertyChangeListener( WsdlTestCase.NAME_PROPERTY, this );
90  			targetTestCase.getTestSuite().addPropertyChangeListener( WsdlTestCase.NAME_PROPERTY, this );
91  		}
92  
93  		buildUI();
94  		setEnabledState();
95  
96  		if( modelItem.getTargetTestCase() == null )
97  		{
98  			SwingUtilities.invokeLater( new Runnable()
99  			{
100 
101 				public void run()
102 				{
103 					optionsAction.actionPerformed( null );
104 				}
105 			} );
106 		}
107 
108 		setPreferredSize( new Dimension( 400, 600 ) );
109 	}
110 
111 	private void setEnabledState()
112 	{
113 		runAction.setEnabled( getModelItem().getTargetTestCase() != null );
114 		openTestCaseAction.setEnabled( getModelItem().getTargetTestCase() != null );
115 	}
116 
117 	private void buildUI()
118 	{
119 		add( buildToolbar(), BorderLayout.NORTH );
120 		add( buildContent(), BorderLayout.CENTER );
121 	}
122 
123 	private Component buildContent()
124 	{
125 		inspectorPanel = JInspectorPanelFactory.build( createPropertiesTable() );
126 
127 		inspectorPanel.addInspector( new JComponentInspector<JComponent>( buildLog(), "TestCase Log",
128 				"log output from testcase run", true ) );
129 
130 		return inspectorPanel.getComponent();
131 	}
132 
133 	private JComponent buildLog()
134 	{
135 		testRunLog = new JTestRunLog( getModelItem().getSettings() );
136 		return testRunLog;
137 	}
138 
139 	protected JComponent createPropertiesTable()
140 	{
141 		PropertyHolderTable propertyHolderTable = new PropertyHolderTable( getModelItem() );
142 
143 		titledBorder = BorderFactory.createTitledBorder( createTitleForBorder() );
144 		propertyHolderTable.setBorder( titledBorder );
145 
146 		return propertyHolderTable;
147 	}
148 
149 	private String createTitleForBorder()
150 	{
151 		WsdlTestCase targetTestCase = getModelItem().getTargetTestCase();
152 		return "TestCase ["
153 				+ ( targetTestCase == null ? "- none selected -" : targetTestCase.getTestSuite().getName() + ":"
154 						+ targetTestCase.getName() ) + "] Run Properties";
155 	}
156 
157 	private Component buildToolbar()
158 	{
159 		JXToolBar toolbar = UISupport.createToolbar();
160 
161 		toolbar.add( UISupport.createToolbarButton( runAction = new RunAction() ) );
162 		toolbar.add( UISupport.createToolbarButton( cancelAction = new CancelRunTestCaseAction(), false ) );
163 		toolbar.add( UISupport.createToolbarButton( optionsAction = new OptionsAction() ) );
164 		toolbar.add( UISupport.createToolbarButton( openTestCaseAction = new OpenTestCaseAction() ) );
165 
166 		toolbar.addGlue();
167 		toolbar.add( UISupport.createToolbarButton( new ShowOnlineHelpAction( HelpUrls.RUNTESTCASESTEP_HELP_URL ) ) );
168 
169 		return toolbar;
170 	}
171 
172 	@Override
173 	public boolean dependsOn( ModelItem modelItem )
174 	{
175 		WsdlRunTestCaseTestStep callStep = getModelItem();
176 
177 		return modelItem == callStep || modelItem == callStep.getTestCase()
178 				|| modelItem == callStep.getTestCase().getTestSuite()
179 				|| modelItem == callStep.getTestCase().getTestSuite().getProject();
180 	}
181 
182 	public boolean onClose( boolean canCancel )
183 	{
184 		getModelItem().removePropertyChangeListener( WsdlRunTestCaseTestStep.TARGET_TESTCASE, this );
185 
186 		WsdlTestCase targetTestCase = getModelItem().getTargetTestCase();
187 		if( targetTestCase != null )
188 		{
189 			targetTestCase.removePropertyChangeListener( WsdlTestCase.NAME_PROPERTY, this );
190 			targetTestCase.getTestSuite().removePropertyChangeListener( WsdlTestCase.NAME_PROPERTY, this );
191 		}
192 
193 		testRunLog.release();
194 		if( optionsDialog != null )
195 		{
196 			optionsDialog.release();
197 			optionsDialog = null;
198 		}
199 
200 		inspectorPanel.release();
201 
202 		return release();
203 	}
204 
205 	private class RunAction extends AbstractAction
206 	{
207 		public RunAction()
208 		{
209 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_testcase.gif" ) );
210 			putValue( Action.SHORT_DESCRIPTION, "Runs the selected TestCases" );
211 		}
212 
213 		public void actionPerformed( ActionEvent e )
214 		{
215 			runAction.setEnabled( false );
216 			cancelAction.setEnabled( true );
217 
218 			new Thread( new Runnable()
219 			{
220 
221 				public void run()
222 				{
223 					WsdlRunTestCaseTestStep testStep = getModelItem();
224 					InternalTestRunListener testRunListener = new InternalTestRunListener();
225 					testStep.addTestRunListener( testRunListener );
226 
227 					try
228 					{
229 						testRunLog.clear();
230 						MockTestRunner mockTestRunner = new MockTestRunner( testStep.getTestCase(), SoapUI.ensureGroovyLog() );
231 						WsdlTestStepResult result = ( WsdlTestStepResult )testStep.run( mockTestRunner,
232 								new MockTestRunContext( mockTestRunner, testStep ) );
233 
234 						Throwable er = result.getError();
235 						if( er != null )
236 						{
237 							UISupport.showErrorMessage( er.toString() );
238 						}
239 					}
240 					catch( Throwable t )
241 					{
242 						UISupport.showErrorMessage( t );
243 					}
244 					finally
245 					{
246 						testStep.removeTestRunListener( testRunListener );
247 						runAction.setEnabled( true );
248 						cancelAction.setEnabled( false );
249 					}
250 				}
251 			} ).start();
252 		}
253 	}
254 
255 	private class OpenTestCaseAction extends AbstractAction
256 	{
257 		public OpenTestCaseAction()
258 		{
259 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/testCase.gif" ) );
260 			putValue( Action.SHORT_DESCRIPTION, "Opens the target TestCases editor" );
261 		}
262 
263 		public void actionPerformed( ActionEvent e )
264 		{
265 			WsdlTestCase targetTestCase = getModelItem().getTargetTestCase();
266 			if( targetTestCase == null )
267 				UISupport.showErrorMessage( "No target TestCase selected" );
268 			else
269 				UISupport.showDesktopPanel( targetTestCase );
270 		}
271 	}
272 
273 	private class OptionsAction extends AbstractAction
274 	{
275 		public OptionsAction()
276 		{
277 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/options.gif" ) );
278 			putValue( Action.SHORT_DESCRIPTION, "Sets Options" );
279 		}
280 
281 		public void actionPerformed( ActionEvent e )
282 		{
283 			if( optionsDialog == null )
284 			{
285 				optionsDialog = ADialogBuilder.buildDialog( OptionsForm.class );
286 				optionsDialog.getFormField( OptionsForm.TESTSUITE ).addFormFieldListener( new XFormFieldListener()
287 				{
288 
289 					public void valueChanged( XFormField sourceField, String newValue, String oldValue )
290 					{
291 						List<TestCase> testCaseList = project.getTestSuiteByName( newValue ).getTestCaseList();
292 						testCaseList.remove( getModelItem().getTestCase() );
293 						optionsDialog.setOptions( OptionsForm.TESTCASE, ModelSupport.getNames( testCaseList ) );
294 
295 						if( testCaseList.size() > 0 )
296 						{
297 							WsdlTestCase testCase = project.getTestSuiteByName( newValue ).getTestCaseAt( 0 );
298 							optionsDialog.setOptions( OptionsForm.RETURN_PROPERTIES, testCase.getPropertyNames() );
299 							( ( XFormMultiSelectList )optionsDialog.getFormField( OptionsForm.RETURN_PROPERTIES ) )
300 									.setSelectedOptions( getModelItem().getReturnProperties().toStringArray() );
301 						}
302 					}
303 				} );
304 				optionsDialog.getFormField( OptionsForm.TESTCASE ).addFormFieldListener( new XFormFieldListener()
305 				{
306 
307 					public void valueChanged( XFormField sourceField, String newValue, String oldValue )
308 					{
309 						WsdlTestSuite testSuite = project
310 								.getTestSuiteByName( optionsDialog.getValue( OptionsForm.TESTSUITE ) );
311 						WsdlTestCase testCase = testSuite.getTestCaseByName( newValue );
312 						optionsDialog.setOptions( OptionsForm.RETURN_PROPERTIES, testCase.getPropertyNames() );
313 						( ( XFormMultiSelectList )optionsDialog.getFormField( OptionsForm.RETURN_PROPERTIES ) )
314 								.setSelectedOptions( getModelItem().getReturnProperties().toStringArray() );
315 					}
316 				} );
317 			}
318 
319 			WsdlTestCase targetTestCase = getModelItem().getTargetTestCase();
320 
321 			optionsDialog.setOptions( OptionsForm.TESTSUITE, ModelSupport.getNames( project.getTestSuiteList() ) );
322 			if( targetTestCase != null )
323 			{
324 				optionsDialog.setValue( OptionsForm.TESTSUITE, targetTestCase.getTestSuite().getName() );
325 
326 				List<TestCase> testCaseList = targetTestCase.getTestSuite().getTestCaseList();
327 				testCaseList.remove( getModelItem().getTestCase() );
328 
329 				optionsDialog.setOptions( OptionsForm.TESTCASE, ModelSupport.getNames( testCaseList ) );
330 				optionsDialog.setValue( OptionsForm.TESTCASE, targetTestCase.getName() );
331 
332 				optionsDialog.setOptions( OptionsForm.RETURN_PROPERTIES, targetTestCase.getPropertyNames() );
333 				( ( XFormMultiSelectList )optionsDialog.getFormField( OptionsForm.RETURN_PROPERTIES ) )
334 						.setSelectedOptions( getModelItem().getReturnProperties().toStringArray() );
335 			}
336 			else
337 			{
338 				if( project.getTestSuiteCount() == 0 )
339 				{
340 					optionsDialog.setOptions( OptionsForm.TESTCASE, new String[0] );
341 					optionsDialog.setOptions( OptionsForm.RETURN_PROPERTIES, new String[0] );
342 				}
343 				else
344 				{
345 					List<TestCase> testCaseList = project.getTestSuiteAt( 0 ).getTestCaseList();
346 					testCaseList.remove( getModelItem().getTestCase() );
347 					optionsDialog.setOptions( OptionsForm.TESTCASE, ModelSupport.getNames( testCaseList ) );
348 
349 					if( testCaseList.isEmpty() )
350 						optionsDialog.setOptions( OptionsForm.RETURN_PROPERTIES, new String[0] );
351 					else
352 						optionsDialog.setOptions( OptionsForm.RETURN_PROPERTIES, testCaseList.get( 0 ).getPropertyNames() );
353 				}
354 			}
355 
356 			optionsDialog
357 					.setValue(
358 							OptionsForm.RUN_MODE,
359 							getModelItem().getRunMode() == RunTestCaseRunModeTypeConfig.PARALLELL ? OptionsForm.CREATE_ISOLATED_COPY_FOR_EACH_RUN
360 									: OptionsForm.RUN_PRIMARY_TEST_CASE );
361 
362 			if( optionsDialog.show() )
363 			{
364 				WsdlTestSuite testSuite = project.getTestSuiteByName( optionsDialog.getValue( OptionsForm.TESTSUITE ) );
365 				getModelItem().setTargetTestCase(
366 						testSuite == null ? null : testSuite
367 								.getTestCaseByName( optionsDialog.getValue( OptionsForm.TESTCASE ) ) );
368 				getModelItem().setReturnProperties(
369 						new StringList(
370 								( ( XFormMultiSelectList )optionsDialog.getFormField( OptionsForm.RETURN_PROPERTIES ) )
371 										.getSelectedOptions() ) );
372 				getModelItem().setRunMode(
373 						optionsDialog.getValueIndex( OptionsForm.RUN_MODE ) == 0 ? RunTestCaseRunModeTypeConfig.PARALLELL
374 								: RunTestCaseRunModeTypeConfig.SINGLETON_AND_FAIL );
375 
376 				titledBorder.setTitle( createTitleForBorder() );
377 			}
378 		}
379 	}
380 
381 	@AForm( name = "Run TestCase Options", description = "Set options for the Run TestCase Step below" )
382 	private static interface OptionsForm
383 	{
384 		public static final String RUN_PRIMARY_TEST_CASE = "Run primary TestCase (fail if already running)";
385 		public static final String CREATE_ISOLATED_COPY_FOR_EACH_RUN = "Create isolated copy for each run (Thread-Safe)";
386 		public static final String RUN_SYNCHRONIZED_TESTCASE = "Run primary TestCase (wait for running to finish, Thread-Safe)";
387 
388 		@AField( name = "Target TestCase", description = "Selects the TestCase to run", type = AFieldType.ENUMERATION )
389 		public static final String TESTCASE = "Target TestCase";
390 
391 		@AField( name = "Target TestSuite", description = "Selects the containing TestSuite to run", type = AFieldType.ENUMERATION )
392 		public static final String TESTSUITE = "Target TestSuite";
393 
394 		@AField( name = "Return Properties", description = "Selects the properties that are return values", type = AFieldType.MULTILIST )
395 		public static final String RETURN_PROPERTIES = "Return Properties";
396 
397 		@AField( name = "Run Mode", description = "Sets how to run the target TestCase", type = AFieldType.RADIOGROUP, values = {
398 				CREATE_ISOLATED_COPY_FOR_EACH_RUN, RUN_PRIMARY_TEST_CASE, RUN_SYNCHRONIZED_TESTCASE } )
399 		public static final String RUN_MODE = "Run Mode";
400 	}
401 
402 	public void propertyChange( PropertyChangeEvent evt )
403 	{
404 		super.propertyChange( evt );
405 
406 		if( evt.getPropertyName().equals( WsdlRunTestCaseTestStep.TARGET_TESTCASE ) )
407 		{
408 			WsdlTestCase targetTestCase = ( WsdlTestCase )evt.getOldValue();
409 			if( targetTestCase != null )
410 			{
411 				targetTestCase.removePropertyChangeListener( WsdlTestCase.NAME_PROPERTY, this );
412 				targetTestCase.getTestSuite().removePropertyChangeListener( WsdlTestCase.NAME_PROPERTY, this );
413 			}
414 
415 			targetTestCase = ( WsdlTestCase )evt.getNewValue();
416 			if( targetTestCase != null )
417 			{
418 				targetTestCase.addPropertyChangeListener( WsdlTestCase.NAME_PROPERTY, this );
419 				targetTestCase.getTestSuite().addPropertyChangeListener( WsdlTestCase.NAME_PROPERTY, this );
420 			}
421 		}
422 
423 		setEnabledState();
424 		titledBorder.setTitle( createTitleForBorder() );
425 		repaint();
426 	}
427 
428 	public class InternalTestRunListener extends TestRunLogTestRunListener
429 	{
430 		public InternalTestRunListener()
431 		{
432 			super( testRunLog, true );
433 		}
434 
435 		public void beforeRun( TestCaseRunner testRunner, TestCaseRunContext runContext )
436 		{
437 			runAction.setEnabled( false );
438 			cancelAction.setEnabled( true );
439 		}
440 
441 		public void afterRun( TestCaseRunner testRunner, TestCaseRunContext runContext )
442 		{
443 			runAction.setEnabled( true );
444 			cancelAction.setEnabled( false );
445 		}
446 	}
447 
448 	public class CancelRunTestCaseAction extends AbstractAction
449 	{
450 		public CancelRunTestCaseAction()
451 		{
452 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/stop_testcase.gif" ) );
453 			putValue( Action.SHORT_DESCRIPTION, "Stops running this testcase" );
454 		}
455 
456 		public void actionPerformed( ActionEvent e )
457 		{
458 			WsdlTestCaseRunner testCaseRunner = getModelItem().getTestCaseRunner();
459 			if( testCaseRunner != null )
460 				testCaseRunner.cancel( "Canceled from RunTestCase UI" );
461 		}
462 	}
463 }