View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2008 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 com.eviware.soapui.SoapUI;
16  import com.eviware.soapui.config.RunTestCaseRunModeTypeConfig;
17  import com.eviware.soapui.impl.support.actions.ShowOnlineHelpAction;
18  import com.eviware.soapui.impl.wsdl.WsdlProject;
19  import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
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.testcase.TestRunLog;
23  import com.eviware.soapui.impl.wsdl.panels.testcase.TestRunLog.TestRunLogTestRunListener;
24  import com.eviware.soapui.impl.wsdl.panels.teststeps.support.PropertyHolderTable;
25  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
26  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
27  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner;
28  import com.eviware.soapui.impl.wsdl.teststeps.WsdlRunTestCaseTestStep;
29  import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStepResult;
30  import com.eviware.soapui.model.ModelItem;
31  import com.eviware.soapui.model.support.ModelSupport;
32  import com.eviware.soapui.model.testsuite.TestCase;
33  import com.eviware.soapui.model.testsuite.TestRunContext;
34  import com.eviware.soapui.model.testsuite.TestRunner;
35  import com.eviware.soapui.support.UISupport;
36  import com.eviware.soapui.support.components.JComponentInspector;
37  import com.eviware.soapui.support.components.JInspectorPanel;
38  import com.eviware.soapui.support.components.JInspectorPanelFactory;
39  import com.eviware.soapui.support.components.JXToolBar;
40  import com.eviware.soapui.support.types.StringList;
41  import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
42  import com.eviware.x.form.XFormDialog;
43  import com.eviware.x.form.XFormField;
44  import com.eviware.x.form.XFormFieldListener;
45  import com.eviware.x.form.support.ADialogBuilder;
46  import com.eviware.x.form.support.AField;
47  import com.eviware.x.form.support.AField.AFieldType;
48  import com.eviware.x.form.support.AForm;
49  import com.eviware.x.form.support.XFormMultiSelectList;
50  
51  import javax.swing.*;
52  import javax.swing.border.TitledBorder;
53  import java.awt.*;
54  import java.awt.event.ActionEvent;
55  import java.beans.PropertyChangeEvent;
56  import java.beans.PropertyChangeListener;
57  import java.util.List;
58  
59  public class WsdlRunTestCaseStepDesktopPanel extends ModelItemDesktopPanel<WsdlRunTestCaseTestStep> implements PropertyChangeListener
60  {
61  	private WsdlProject project;
62  	private TitledBorder titledBorder;
63  	private OptionsAction optionsAction;
64  	private RunAction runAction;
65  	private OpenTestCaseAction openTestCaseAction;
66  	private TestRunLog testRunLog;
67  	private CancelRunTestCaseAction cancelAction;
68  	private XFormDialog optionsDialog;
69  
70  	public WsdlRunTestCaseStepDesktopPanel( WsdlRunTestCaseTestStep modelItem )
71  	{
72  		super( modelItem );
73  		
74  		project = getModelItem().getTestCase().getTestSuite().getProject();
75  		
76  		getModelItem().addPropertyChangeListener( WsdlRunTestCaseTestStep.TARGET_TESTCASE, this );
77  		
78  		buildUI();
79  		setEnabledState();
80  		
81  		if( modelItem.getTargetTestCase() == null )
82  		{
83  			SwingUtilities.invokeLater( new Runnable() {
84  	
85  				public void run()
86  				{
87  					optionsAction.actionPerformed( null );
88  				}} );
89  		}
90  		
91  		setPreferredSize( new Dimension( 400, 600 ) );
92  	}
93  
94  	private void setEnabledState()
95  	{
96  		runAction.setEnabled( getModelItem().getTargetTestCase() != null );
97  		openTestCaseAction.setEnabled( getModelItem().getTargetTestCase() != null );
98  	}
99  
100 	private void buildUI()
101 	{
102 		add( buildToolbar(), BorderLayout.NORTH );
103 		add( buildContent(), BorderLayout.CENTER );
104 	}
105 
106 	private Component buildContent()
107 	{
108 		JInspectorPanel inspectorPanel = JInspectorPanelFactory.build( createPropertiesTable() );
109 		
110 		inspectorPanel.addInspector( new JComponentInspector<JComponent>( buildLog(), "TestCase Log", "log output from testcase run", true ) );
111 		
112 		return inspectorPanel.getComponent();
113 	}
114 
115 	private JComponent buildLog()
116 	{
117 		testRunLog = new TestRunLog( getModelItem().getSettings() );
118 		return testRunLog;
119 	}
120 
121 	protected JComponent createPropertiesTable()
122 	{
123 		PropertyHolderTable propertyHolderTable = new PropertyHolderTable( getModelItem() );
124 		
125 		titledBorder = BorderFactory.createTitledBorder( createTitleForBorder() );
126 		propertyHolderTable.setBorder( titledBorder);
127 		
128 		return propertyHolderTable;
129 	}
130 
131 	private String createTitleForBorder()
132 	{
133 		WsdlTestCase targetTestCase = getModelItem().getTargetTestCase();
134 		return "TestCase [" + (targetTestCase == null ? "-none selected-" : targetTestCase.getName() ) + "] Run Properties";
135 	}
136 
137 	private Component buildToolbar()
138 	{
139 		JXToolBar toolbar = UISupport.createToolbar();
140 		
141 		toolbar.add( UISupport.createToolbarButton( runAction = new RunAction() ));
142 		toolbar.add( UISupport.createToolbarButton( cancelAction = new CancelRunTestCaseAction(), false ));
143 		toolbar.add( UISupport.createToolbarButton( optionsAction = new OptionsAction() ));
144 		toolbar.add( UISupport.createToolbarButton( openTestCaseAction = new OpenTestCaseAction() ));
145 		
146 		toolbar.addGlue();
147 		toolbar.add( UISupport.createToolbarButton( new ShowOnlineHelpAction( HelpUrls.RUNTESTCASESTEP_HELP_URL )));
148 		
149 		return toolbar;
150 	}
151 
152 	@Override
153 	public boolean dependsOn( ModelItem modelItem )
154 	{
155 		WsdlRunTestCaseTestStep callStep = getModelItem();
156 		
157 		return modelItem == callStep || modelItem == callStep.getTestCase() ||
158 			modelItem == callStep.getTestCase().getTestSuite() ||
159 			modelItem == callStep.getTestCase().getTestSuite().getProject();
160 	}
161 
162 	public boolean onClose( boolean canCancel )
163 	{
164 		getModelItem().removePropertyChangeListener( WsdlRunTestCaseTestStep.TARGET_TESTCASE, this );
165 		testRunLog.release();
166 		if( optionsDialog != null )
167 		{
168 			optionsDialog.release();
169 			optionsDialog = null;
170 		}
171 		
172 		return release();
173 	}
174 	
175 	private class RunAction extends AbstractAction
176 	{
177 		public RunAction()
178 		{
179 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_testcase.gif" ));
180 			putValue( Action.SHORT_DESCRIPTION, "Runs the selected TestCases" );
181 		}
182 		
183 		public void actionPerformed(ActionEvent e)
184 		{
185 			runAction.setEnabled( false );
186 			cancelAction.setEnabled( true );
187 
188 			new Thread( new Runnable() {
189 
190 				public void run()
191 				{
192 					WsdlRunTestCaseTestStep testStep = getModelItem();
193 					InternalTestRunListener testRunListener = new InternalTestRunListener();
194 					testStep.addTestRunListener( testRunListener );
195 					
196 					try
197 					{
198 						testRunLog.clear();
199 						MockTestRunner mockTestRunner = new MockTestRunner( testStep.getTestCase(), SoapUI.ensureGroovyLog() );
200 						WsdlTestStepResult result = (WsdlTestStepResult) testStep.run( mockTestRunner, 
201 								new MockTestRunContext( mockTestRunner, testStep ) );
202 						
203 						Throwable er = result.getError();
204 						if( er != null )
205 						{
206 							UISupport.showErrorMessage( er.toString() );
207 						}
208 					}
209 					catch( Throwable t )
210 					{
211 						UISupport.showErrorMessage( t );
212 					}
213 					finally 
214 					{
215 						testStep.removeTestRunListener( testRunListener );
216 						runAction.setEnabled( true );
217 						cancelAction.setEnabled( false );
218 					}
219 				}} ).start();
220 		}
221 	}
222 	
223 	private class OpenTestCaseAction extends AbstractAction
224 	{
225 		public OpenTestCaseAction()
226 		{
227 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/testCase.gif" ));
228 			putValue( Action.SHORT_DESCRIPTION, "Opens the target TestCases editor" );
229 		}
230 		
231 		public void actionPerformed(ActionEvent e)
232 		{
233 			WsdlTestCase targetTestCase = getModelItem().getTargetTestCase();
234 			if( targetTestCase == null )
235 				UISupport.showErrorMessage( "No target TestCase selected" );
236 			else
237 				UISupport.showDesktopPanel( targetTestCase );
238 		}
239 	}
240 	
241 	private class OptionsAction extends AbstractAction
242 	{
243 		public OptionsAction()
244 		{
245 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/options.gif" ));
246 			putValue( Action.SHORT_DESCRIPTION, "Sets Options");
247 		}
248 		
249 		public void actionPerformed( ActionEvent e )
250 		{
251 			if( optionsDialog == null )
252 			{
253 				optionsDialog = ADialogBuilder.buildDialog( OptionsForm.class );
254 				optionsDialog.getFormField( OptionsForm.TESTSUITE ).addFormFieldListener( new XFormFieldListener() {
255 
256 					public void valueChanged( XFormField sourceField, String newValue, String oldValue )
257 					{
258 						List<TestCase> testCaseList = project.getTestSuiteByName( newValue ).getTestCaseList();
259 						testCaseList.remove( getModelItem().getTestCase() );
260 						optionsDialog.setOptions( OptionsForm.TESTCASE, ModelSupport.getNames( testCaseList ));
261 						
262 						if( testCaseList.size() > 0 )
263 						{
264 							WsdlTestCase testCase = project.getTestSuiteByName( newValue ).getTestCaseAt( 0 );
265 							optionsDialog.setOptions( OptionsForm.RETURN_PROPERTIES, testCase.getPropertyNames() );
266 							((XFormMultiSelectList)optionsDialog.getFormField( OptionsForm.RETURN_PROPERTIES )).setSelectedOptions( 
267 										getModelItem().getReturnProperties().toStringArray() );
268 						}
269 					}
270 				} );
271 				optionsDialog.getFormField( OptionsForm.TESTCASE ).addFormFieldListener( new XFormFieldListener() {
272 
273 					public void valueChanged( XFormField sourceField, String newValue, String oldValue )
274 					{
275 						WsdlTestSuite testSuite = project.getTestSuiteByName( optionsDialog.getValue( OptionsForm.TESTSUITE  ) );
276 						WsdlTestCase testCase = testSuite.getTestCaseByName( newValue );
277 						optionsDialog.setOptions( OptionsForm.RETURN_PROPERTIES, testCase.getPropertyNames() );
278 						((XFormMultiSelectList)optionsDialog.getFormField( OptionsForm.RETURN_PROPERTIES )).setSelectedOptions( 
279 									getModelItem().getReturnProperties().toStringArray() );
280 					}
281 				} );
282 			}
283 			
284 			WsdlTestCase targetTestCase = getModelItem().getTargetTestCase();
285 			
286 			optionsDialog.setOptions( OptionsForm.TESTSUITE, ModelSupport.getNames( project.getTestSuiteList() ) );
287 			if( targetTestCase != null )
288 			{
289 				optionsDialog.setValue( OptionsForm.TESTSUITE, targetTestCase.getTestSuite().getName() );
290 				
291 				List<TestCase> testCaseList = targetTestCase.getTestSuite().getTestCaseList();
292 				testCaseList.remove( getModelItem().getTestCase() );
293 				
294 				optionsDialog.setOptions( OptionsForm.TESTCASE, ModelSupport.getNames( testCaseList ));
295 				optionsDialog.setValue( OptionsForm.TESTCASE, targetTestCase.getName() );
296 				
297 				optionsDialog.setOptions( OptionsForm.RETURN_PROPERTIES, targetTestCase.getPropertyNames() );
298 				((XFormMultiSelectList)optionsDialog.getFormField( OptionsForm.RETURN_PROPERTIES )).setSelectedOptions( 
299 							getModelItem().getReturnProperties().toStringArray() );
300 			}
301 			else
302 			{
303 				if( project.getTestSuiteCount() == 0 )
304 				{
305 					optionsDialog.setOptions( OptionsForm.TESTCASE, new String[0] );
306 					optionsDialog.setOptions( OptionsForm.RETURN_PROPERTIES, new String[0] );
307 				}
308 				else
309 				{
310 					List<TestCase> testCaseList = project.getTestSuiteAt(0).getTestCaseList();
311 					testCaseList.remove( getModelItem().getTestCase() );
312 					optionsDialog.setOptions( OptionsForm.TESTCASE, ModelSupport.getNames( testCaseList ) );
313 					
314 					if( testCaseList.isEmpty() )
315 						optionsDialog.setOptions( OptionsForm.RETURN_PROPERTIES, new String[0] );
316 					else
317 						optionsDialog.setOptions( OptionsForm.RETURN_PROPERTIES, testCaseList.get( 0 ).getPropertyNames() );
318 				}
319 			}
320 			
321 			optionsDialog.setValue( OptionsForm.RUN_MODE, getModelItem().getRunMode() == RunTestCaseRunModeTypeConfig.PARALLELL ?
322 						OptionsForm.CREATE_ISOLATED_COPY_FOR_EACH_RUN : OptionsForm.RUN_PRIMARY_TEST_CASE );
323 			
324 			if( optionsDialog.show() )
325 			{
326 				WsdlTestSuite testSuite = project.getTestSuiteByName( optionsDialog.getValue( OptionsForm.TESTSUITE ) );
327 				getModelItem().setTargetTestCase( testSuite == null ? null : 
328 					testSuite.getTestCaseByName( optionsDialog.getValue( OptionsForm.TESTCASE ) ));
329 				getModelItem().setReturnProperties( new StringList( 
330 					((XFormMultiSelectList)optionsDialog.getFormField( OptionsForm.RETURN_PROPERTIES )).getSelectedOptions()) );
331 				getModelItem().setRunMode( optionsDialog.getValueIndex( OptionsForm.RUN_MODE ) == 0 ? 
332 							RunTestCaseRunModeTypeConfig.PARALLELL : RunTestCaseRunModeTypeConfig.SINGLETON_AND_FAIL );
333 			}
334 		}
335 	}
336 	
337 	@AForm( name="Run TestCase Options", description="Set options for the Run TestCase Step below" )
338 	private static interface OptionsForm 
339 	{
340 		public static final String RUN_PRIMARY_TEST_CASE = "Run primary TestCase (fail if already running)";
341 		public static final String CREATE_ISOLATED_COPY_FOR_EACH_RUN = "Create isolated copy for each run (Thread-Safe)";
342 
343 		@AField( name="Target TestCase", description="Selects the TestCase to run", type=AFieldType.ENUMERATION)
344 		public static final String TESTCASE = "Target TestCase";
345 
346 		@AField( name="Target TestSuite", description="Selects the containing TestSuite to run", type=AFieldType.ENUMERATION)
347 		public static final String TESTSUITE = "Target TestSuite";
348 
349 		@AField( name="Return Properties", description="Selects the properties that are return values", type=AFieldType.MULTILIST)
350 		public static final String RETURN_PROPERTIES = "Return Properties";
351 		
352 		@AField( name="Run Mode", description="Sets how to run the target TestCase", type=AFieldType.RADIOGROUP, 
353 					values= {CREATE_ISOLATED_COPY_FOR_EACH_RUN, RUN_PRIMARY_TEST_CASE})
354 		public static final String RUN_MODE = "Run Mode";
355 	}
356 
357 	public void propertyChange( PropertyChangeEvent evt )
358 	{
359 		setEnabledState();
360 		titledBorder.setTitle( createTitleForBorder() );
361 		repaint();
362 	}
363 	
364 	public class InternalTestRunListener extends TestRunLogTestRunListener
365 	{
366 		public InternalTestRunListener()
367 		{
368 			super( testRunLog, true );
369 		}
370 
371 		public void beforeRun( TestRunner testRunner, TestRunContext runContext )
372 		{
373 			runAction.setEnabled( false );
374 			cancelAction.setEnabled( true );
375 		}
376 
377 		public void afterRun( TestRunner testRunner, TestRunContext runContext )
378 		{
379 			runAction.setEnabled( true );
380 			cancelAction.setEnabled( false );
381 		}
382 	}
383 	
384 	public class CancelRunTestCaseAction extends AbstractAction
385 	{
386 		public CancelRunTestCaseAction()
387 		{
388 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/stop_testcase.gif" ) );
389 			putValue( Action.SHORT_DESCRIPTION, "Stops running this testcase" );
390 		}
391 
392 		public void actionPerformed( ActionEvent e )
393 		{
394 			 WsdlTestCaseRunner testCaseRunner = getModelItem().getTestCaseRunner();
395 			 if( testCaseRunner != null )
396 				 testCaseRunner.cancel( "Canceled from RunTestCase UI" );
397 		}
398 	}
399 }