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.testcase;
14  
15  import com.eviware.soapui.SoapUI;
16  import com.eviware.soapui.config.LoadTestConfig;
17  import com.eviware.soapui.config.TestCaseConfig;
18  import com.eviware.soapui.config.TestStepConfig;
19  import com.eviware.soapui.impl.wsdl.AbstractTestPropertyHolderWsdlModelItem;
20  import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
21  import com.eviware.soapui.impl.wsdl.loadtest.LoadTestAssertion;
22  import com.eviware.soapui.impl.wsdl.loadtest.WsdlLoadTest;
23  import com.eviware.soapui.impl.wsdl.loadtest.assertions.TestStepStatusAssertion;
24  import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStep;
25  import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestStepFactory;
26  import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestStepRegistry;
27  import com.eviware.soapui.model.ModelItem;
28  import com.eviware.soapui.model.testsuite.*;
29  import com.eviware.soapui.support.StringUtils;
30  import com.eviware.soapui.support.UISupport;
31  import com.eviware.soapui.support.action.swing.ActionList;
32  import com.eviware.soapui.support.action.swing.DefaultActionList;
33  import com.eviware.soapui.support.resolver.ResolveDialog;
34  import com.eviware.soapui.support.scripting.SoapUIScriptEngine;
35  import com.eviware.soapui.support.scripting.SoapUIScriptEngineRegistry;
36  import com.eviware.soapui.support.types.StringToObjectMap;
37  import org.apache.log4j.Logger;
38  
39  import java.io.File;
40  import java.io.IOException;
41  import java.util.*;
42  
43  /***
44   * TestCase implementation for WSDL projects
45   * 
46   * @author Ole.Matzura
47   */
48  
49  public class WsdlTestCase extends AbstractTestPropertyHolderWsdlModelItem<TestCaseConfig> implements TestCase
50  {
51  	private final static Logger logger = Logger.getLogger( WsdlTestCase.class );
52  	public final static String KEEP_SESSION_PROPERTY = WsdlTestCase.class.getName() + "@keepSession";
53  	public final static String FAIL_ON_ERROR_PROPERTY = WsdlTestCase.class.getName() + "@failOnError";
54  	public final static String FAIL_ON_ERRORS_PROPERTY = WsdlTestCase.class.getName() + "@failOnErrors";
55  	public final static String DISCARD_OK_RESULTS = WsdlTestCase.class.getName() + "@discardOkResults";
56  	public final static String SETUP_SCRIPT_PROPERTY = WsdlTestCase.class.getName() + "@setupScript";
57  	public final static String TEARDOWN_SCRIPT_PROPERTY = WsdlTestCase.class.getName() + "@tearDownScript";
58  	public static final String TIMEOUT_PROPERTY = WsdlTestCase.class.getName() + "@timeout";
59  	public static final String SEARCH_PROPERTIES_PROPERTY = WsdlTestCase.class.getName() + "@searchProperties";
60  
61  	private final WsdlTestSuite testSuite;
62  	private List<WsdlTestStep> testSteps = new ArrayList<WsdlTestStep>();
63  	private List<WsdlLoadTest> loadTests = new ArrayList<WsdlLoadTest>();
64  	private Set<TestRunListener> testRunListeners = new HashSet<TestRunListener>();
65  	private DefaultActionList createActions;
66  	private final boolean forLoadTest;
67  	private SoapUIScriptEngine setupScriptEngine;
68  	private SoapUIScriptEngine tearDownScriptEngine;
69  
70  	public WsdlTestCase( WsdlTestSuite testSuite, TestCaseConfig config, boolean forLoadTest )
71  	{
72  		super( config, testSuite, "/testCase.gif" );
73  
74  		this.testSuite = testSuite;
75  		this.forLoadTest = forLoadTest;
76  
77  		List<TestStepConfig> testStepConfigs = config.getTestStepList();
78  		for( TestStepConfig tsc : testStepConfigs )
79  		{
80  			WsdlTestStep testStep = createTestStepFromConfig( tsc );
81  			if( testStep != null )
82  			{
83  				ensureUniqueName( testStep );
84  				testSteps.add( testStep );
85  			}
86  		}
87  
88  		if( !forLoadTest )
89  		{
90  			List<LoadTestConfig> loadTestConfigs = config.getLoadTestList();
91  			for( LoadTestConfig tsc : loadTestConfigs )
92  			{
93  				WsdlLoadTest loadTest = new WsdlLoadTest( this, tsc );
94  				loadTests.add( loadTest );
95  			}
96  		}
97  
98  		// init default configs
99  		if( !config.isSetFailOnError() )
100 			config.setFailOnError( true );
101 
102 		if( !config.isSetFailTestCaseOnErrors() )
103 			config.setFailTestCaseOnErrors( true );
104 
105 		if( !config.isSetKeepSession() )
106 			config.setKeepSession( false );
107 
108 		if( !config.isSetMaxResults() )
109 			config.setMaxResults( 0 );
110 
111 		for( TestRunListener listener : SoapUI.getListenerRegistry().getListeners( TestRunListener.class ) )
112 		{
113 			addTestRunListener( listener );
114 		}
115 
116 		if( !getConfig().isSetProperties() )
117 			getConfig().addNewProperties();
118 
119 		setPropertiesConfig( getConfig().getProperties() );
120 
121 //		for( TestStep step : testSteps )
122 //		{
123 //			WsdlTestStep testStep = ( WsdlTestStep ) step;
124 //			try
125 //			{
126 //				testStep.afterLoad();
127 //			}
128 //			catch( Exception e )
129 //			{
130 //				e.printStackTrace();
131 //			}
132 //		}
133 	}
134 
135 	public boolean getKeepSession()
136 	{
137 		return getConfig().getKeepSession();
138 	}
139 
140 	public void setKeepSession( boolean keepSession )
141 	{
142 		boolean old = getKeepSession();
143 		if( old != keepSession )
144 		{
145 			getConfig().setKeepSession( keepSession );
146 			notifyPropertyChanged( KEEP_SESSION_PROPERTY, old, keepSession );
147 		}
148 	}
149 
150 	public void setSetupScript( String script )
151 	{
152 		String oldScript = getSetupScript();
153 
154 		if( !getConfig().isSetSetupScript() )
155 			getConfig().addNewSetupScript();
156 
157 		getConfig().getSetupScript().setStringValue( script );
158 		if( setupScriptEngine != null )
159 			setupScriptEngine.setScript( script );
160 
161 		notifyPropertyChanged( SETUP_SCRIPT_PROPERTY, oldScript, script );
162 	}
163 
164 	public String getSetupScript()
165 	{
166 		return getConfig().isSetSetupScript() ? getConfig().getSetupScript().getStringValue() : null;
167 	}
168 
169 	public void setTearDownScript( String script )
170 	{
171 		String oldScript = getTearDownScript();
172 
173 		if( !getConfig().isSetTearDownScript() )
174 			getConfig().addNewTearDownScript();
175 
176 		getConfig().getTearDownScript().setStringValue( script );
177 		if( tearDownScriptEngine != null )
178 			tearDownScriptEngine.setScript( script );
179 
180 		notifyPropertyChanged( TEARDOWN_SCRIPT_PROPERTY, oldScript, script );
181 	}
182 
183 	public String getTearDownScript()
184 	{
185 		return getConfig().isSetTearDownScript() ? getConfig().getTearDownScript().getStringValue() : null;
186 	}
187 
188 	public boolean getFailOnError()
189 	{
190 		return getConfig().getFailOnError();
191 	}
192 
193 	public boolean getFailTestCaseOnErrors()
194 	{
195 		return getConfig().getFailTestCaseOnErrors();
196 	}
197 
198 	public void setFailOnError( boolean failOnError )
199 	{
200 		boolean old = getFailOnError();
201 		if( old != failOnError )
202 		{
203 			getConfig().setFailOnError( failOnError );
204 			notifyPropertyChanged( FAIL_ON_ERROR_PROPERTY, old, failOnError );
205 		}
206 	}
207 
208 	public void setFailTestCaseOnErrors( boolean failTestCaseOnErrors )
209 	{
210 		boolean old = getFailTestCaseOnErrors();
211 		if( old != failTestCaseOnErrors )
212 		{
213 			getConfig().setFailTestCaseOnErrors( failTestCaseOnErrors );
214 			notifyPropertyChanged( FAIL_ON_ERRORS_PROPERTY, old, failTestCaseOnErrors );
215 		}
216 	}
217 
218 	public boolean getSearchProperties()
219 	{
220 		return getConfig().getSearchProperties();
221 	}
222 
223 	public void setSearchProperties( boolean searchProperties )
224 	{
225 		boolean old = getSearchProperties();
226 		if( old != searchProperties )
227 		{
228 			getConfig().setSearchProperties( searchProperties );
229 			notifyPropertyChanged( SEARCH_PROPERTIES_PROPERTY, old, searchProperties );
230 		}
231 	}
232 
233 	public boolean getDiscardOkResults()
234 	{
235 		return getConfig().getDiscardOkResults();
236 	}
237 
238 	public void setDiscardOkResults( boolean discardOkResults )
239 	{
240 		boolean old = getDiscardOkResults();
241 		if( old != discardOkResults )
242 		{
243 			getConfig().setDiscardOkResults( discardOkResults );
244 			notifyPropertyChanged( DISCARD_OK_RESULTS, old, discardOkResults );
245 		}
246 	}
247 
248 	public int getMaxResults()
249 	{
250 		return getConfig().getMaxResults();
251 	}
252 
253 	public void setMaxResults( int maxResults )
254 	{
255 		int old = getMaxResults();
256 		if( old != maxResults )
257 		{
258 			getConfig().setMaxResults( maxResults );
259 			notifyPropertyChanged( "maxResults", old, maxResults );
260 		}
261 	}
262 
263 	
264 	private WsdlTestStep createTestStepFromConfig( TestStepConfig tsc )
265 	{
266 		WsdlTestStepFactory factory = WsdlTestStepRegistry.getInstance().getFactory( tsc.getType() );
267 		if( factory != null )
268 		{
269 			WsdlTestStep testStep = factory.buildTestStep( this, tsc, forLoadTest );
270 			return testStep;
271 		}
272 		else
273 		{
274 			logger.error( "Failed to create test step for [" + tsc.getName() + "]" );
275 			return null;
276 		}
277 	}
278 
279 	private boolean ensureUniqueName( WsdlTestStep testStep )
280 	{
281 		String name = testStep.getName();
282 		while( name == null || getTestStepByName( name ) != null )
283 		{
284 			if( name == null )
285 				name = testStep.getName();
286 			else
287 			{
288 				int cnt = 0;
289 
290 				while( getTestStepByName( name ) != null )
291 				{
292 					cnt++;
293 					name = testStep.getName() + " " + cnt;
294 				}
295 
296 				if( cnt == 0 )
297 					break;
298 			}
299 
300 			name = UISupport.prompt( "TestStep name must be unique, please specify new name for step\n" + "["
301 						+ testStep.getName() + "] in TestCase [" + getTestSuite().getProject().getName() + "->"
302 						+ getTestSuite().getName() + "->" + getName() + "]", "Change TestStep name", name );
303 
304 			if( name == null )
305 				return false;
306 		}
307 
308 		if( !name.equals( testStep.getName() ) )
309 			testStep.setName( name );
310 
311 		return true;
312 	}
313 
314 	public WsdlLoadTest addNewLoadTest( String name )
315 	{
316 		WsdlLoadTest loadTest = new WsdlLoadTest( this, getConfig().addNewLoadTest() );
317 		loadTest.setStartDelay( 0 );
318 		loadTest.setName( name );
319 		loadTests.add( loadTest );
320 
321 		loadTest.addAssertion( TestStepStatusAssertion.STEP_STATUS_TYPE, LoadTestAssertion.ANY_TEST_STEP, false );
322 
323 		( getTestSuite() ).fireLoadTestAdded( loadTest );
324 
325 		return loadTest;
326 	}
327 
328 	public void removeLoadTest( WsdlLoadTest loadTest )
329 	{
330 		int ix = loadTests.indexOf( loadTest );
331 
332 		loadTests.remove( ix );
333 
334 		try
335 		{
336 			( getTestSuite() ).fireLoadTestRemoved( loadTest );
337 		}
338 		finally
339 		{
340 			loadTest.release();
341 			getConfig().removeLoadTest( ix );
342 		}
343 	}
344 
345 	public WsdlTestSuite getTestSuite()
346 	{
347 		return testSuite;
348 	}
349 
350 	public WsdlTestStep cloneStep( WsdlTestStep testStep, String name )
351 	{
352 		return testStep.clone( this, name );
353 	}
354 
355 	public WsdlTestStep getTestStepAt( int index )
356 	{
357 		return testSteps.get( index );
358 	}
359 
360 	public int getTestStepCount()
361 	{
362 		return testSteps.size();
363 	}
364 
365 	public WsdlLoadTest getLoadTestAt( int index )
366 	{
367 		return loadTests.get( index );
368 	}
369 
370 	public LoadTest getLoadTestByName( String loadTestName )
371 	{
372 		return ( LoadTest ) getWsdlModelItemByName( loadTests, loadTestName );
373 	}
374 
375 	public int getLoadTestCount()
376 	{
377 		return loadTests.size();
378 	}
379 
380 	public WsdlTestStep addTestStep( TestStepConfig stepConfig )
381 	{
382 		return insertTestStep( stepConfig, -1 );
383 	}
384 
385 	public WsdlTestStep addTestStep( String type, String name )
386 	{
387 		TestStepConfig newStepConfig = WsdlTestStepRegistry.getInstance().getFactory( type ).createNewTestStep( this,
388 					name );
389 		if( newStepConfig != null )
390 		{
391 			return addTestStep( newStepConfig );
392 		}
393 		else
394 			return null;
395 	}
396 
397 	public WsdlTestStep insertTestStep( String type, String name, int index )
398 	{
399 		TestStepConfig newStepConfig = WsdlTestStepRegistry.getInstance().getFactory( type ).createNewTestStep( this,
400 					name );
401 		if( newStepConfig != null )
402 		{
403 			return insertTestStep( newStepConfig, index );
404 		}
405 		else
406 			return null;
407 	}
408 
409 	public WsdlTestStep importTestStep( WsdlTestStep testStep, String name, int index, boolean createCopy )
410 	{
411 		testStep.beforeSave();
412 		TestStepConfig newStepConfig = ( TestStepConfig ) testStep.getConfig().copy();
413 		newStepConfig.setName( name );
414 		if( createCopy && newStepConfig.isSetId() )
415 			newStepConfig.unsetId();
416 
417       WsdlTestStep result = insertTestStep( newStepConfig, index );
418       resolveTestCase();
419       return result;
420 	}
421 
422    private void resolveTestCase()
423    {
424       ResolveDialog resolver = new ResolveDialog( "Validate TestCase", "Checks TestCase for inconsistencies", null );
425       resolver.setShowOkMessage( false );
426       resolver.resolve( this );
427    }
428 
429 	public WsdlTestStep[] importTestSteps( WsdlTestStep[] testSteps, int index, boolean createCopies )
430 	{
431 		TestStepConfig[] newStepConfigs = new TestStepConfig[testSteps.length];
432 
433 		for( int c = 0; c < testSteps.length; c++ )
434 		{
435 			testSteps[c].beforeSave();
436 			newStepConfigs[c] = ( TestStepConfig ) testSteps[c].getConfig().copy();
437 			if( createCopies && newStepConfigs[c].isSetId() )
438 				newStepConfigs[c].unsetId();
439 		}
440 
441       WsdlTestStep[] result = insertTestSteps( newStepConfigs, index );
442       resolveTestCase();
443       return result;
444 	}
445 
446 	public WsdlTestStep insertTestStep( TestStepConfig stepConfig, int ix )
447 	{
448 		TestStepConfig newStepConfig = ix == -1 ? getConfig().addNewTestStep() : getConfig().insertNewTestStep( ix );
449 		newStepConfig.set( stepConfig );
450 		WsdlTestStep testStep = createTestStepFromConfig( newStepConfig );
451 
452 		if( !ensureUniqueName( testStep ) )
453 			return null;
454 
455 		if( ix == -1 )
456 			testSteps.add( testStep );
457 		else
458 			testSteps.add( ix, testStep );
459 
460 		testStep.afterLoad();
461 
462 		if( getTestSuite() != null )
463 			( getTestSuite() ).fireTestStepAdded( testStep, ix == -1 ? testSteps.size() - 1 : ix );
464 
465 		return testStep;
466 	}
467 
468 	public WsdlTestStep[] insertTestSteps( TestStepConfig[] stepConfig, int ix )
469 	{
470 		WsdlTestStep[] result = new WsdlTestStep[stepConfig.length];
471 
472 		for( int c = 0; c < stepConfig.length; c++ )
473 		{
474 			TestStepConfig newStepConfig = ix == -1 ? getConfig().addNewTestStep() : getConfig()
475 						.insertNewTestStep( ix + c );
476 			newStepConfig.set( stepConfig[c] );
477 			WsdlTestStep testStep = createTestStepFromConfig( newStepConfig );
478 
479 			if( !ensureUniqueName( testStep ) )
480 				return null;
481 
482 			if( ix == -1 )
483 				testSteps.add( testStep );
484 			else
485 				testSteps.add( ix + c, testStep );
486 
487 			result[c] = testStep;
488 		}
489 
490 		for( int c = 0; c < result.length; c++ )
491 		{
492 			result[c].afterLoad();
493 
494 			if( getTestSuite() != null )
495 				( getTestSuite() ).fireTestStepAdded( result[c], getIndexOfTestStep( result[c] ) );
496 		}
497 
498 		return result;
499 	}
500 
501 	public void removeTestStep( WsdlTestStep testStep )
502 	{
503 		int ix = testSteps.indexOf( testStep );
504 		if( ix == -1 )
505 		{
506 			logger.error( "TestStep [" + testStep.getName() + "] passed to removeTestStep in testCase [" + getName()
507 						+ "] not found" );
508 			return;
509 		}
510 
511 		testSteps.remove( ix );
512 
513 		try
514 		{
515 			( getTestSuite() ).fireTestStepRemoved( testStep, ix );
516 		}
517 		finally
518 		{
519 			testStep.release();
520 
521 			for( int c = 0; c < getConfig().sizeOfTestStepArray(); c++ )
522 			{
523 				if( testStep.getConfig() == getConfig().getTestStepArray( c ) )
524 				{
525 					getConfig().removeTestStep( c );
526 					break;
527 				}
528 			}
529 		}
530 	}
531 
532 	public WsdlTestCaseRunner run( StringToObjectMap properties, boolean async )
533 	{
534 		WsdlTestCaseRunner runner = new WsdlTestCaseRunner( this, properties );
535 		runner.start( async );
536 		return runner;
537 	}
538 
539 	public void addTestRunListener( TestRunListener listener )
540 	{
541 		if( listener == null )
542 			throw new RuntimeException( "listener must not be null" );
543 
544 		testRunListeners.add( listener );
545 	}
546 
547 	public void removeTestRunListener( TestRunListener listener )
548 	{
549 		testRunListeners.remove( listener );
550 	}
551 
552 	public TestRunListener[] getTestRunListeners()
553 	{
554 		return testRunListeners.toArray( new TestRunListener[testRunListeners.size()] );
555 	}
556 
557 	public Map<String, TestStep> getTestSteps()
558 	{
559 		Map<String, TestStep> result = new HashMap<String, TestStep>();
560 		for( TestStep testStep : testSteps )
561 			result.put( testStep.getName(), testStep );
562 
563 		return result;
564 	}
565 
566 	public Map<String, LoadTest> getLoadTests()
567 	{
568 		Map<String, LoadTest> result = new HashMap<String, LoadTest>();
569 		for( LoadTest loadTest : loadTests )
570 			result.put( loadTest.getName(), loadTest );
571 
572 		return result;
573 	}
574 
575 	public int getIndexOfTestStep( TestStep step )
576 	{
577 		return testSteps.indexOf( step );
578 	}
579 
580 	/***
581 	 * Moves a step by the specified offset, a bit awkward since xmlbeans doesn't
582 	 * support reordering of arrays, we need to create copies of the contained
583 	 * XmlObjects
584 	 * 
585 	 * @param ix
586 	 * @param offset
587 	 */
588 
589 	public void moveTestStep( int ix, int offset )
590 	{
591 		if( offset == 0 )
592 			return;
593 		WsdlTestStep step = testSteps.get( ix );
594 
595 		if( ix + offset >= testSteps.size() )
596 			offset = testSteps.size() - ix - 1;
597 
598 		testSteps.remove( ix );
599 		testSteps.add( ix + offset, step );
600 
601 		TestStepConfig[] configs = new TestStepConfig[testSteps.size()];
602 
603 		TestCaseConfig conf = getConfig();
604 		for( int c = 0; c < testSteps.size(); c++ )
605 		{
606 			if( offset > 0 )
607 			{
608 				if( c < ix )
609 					configs[c] = ( TestStepConfig ) conf.getTestStepArray( c ).copy();
610 				else if( c < ( ix + offset ) )
611 					configs[c] = ( TestStepConfig ) conf.getTestStepArray( c + 1 ).copy();
612 				else if( c == ix + offset )
613 					configs[c] = ( TestStepConfig ) conf.getTestStepArray( ix ).copy();
614 				else
615 					configs[c] = ( TestStepConfig ) conf.getTestStepArray( c ).copy();
616 			}
617 			else
618 			{
619 				if( c < ix + offset )
620 					configs[c] = ( TestStepConfig ) conf.getTestStepArray( c ).copy();
621 				else if( c == ix + offset )
622 					configs[c] = ( TestStepConfig ) conf.getTestStepArray( ix ).copy();
623 				else if( c <= ix )
624 					configs[c] = ( TestStepConfig ) conf.getTestStepArray( c - 1 ).copy();
625 				else
626 					configs[c] = ( TestStepConfig ) conf.getTestStepArray( c ).copy();
627 			}
628 		}
629 
630 		conf.setTestStepArray( configs );
631 		for( int c = 0; c < configs.length; c++ )
632 		{
633 			( testSteps.get( c ) ).resetConfigOnMove( conf.getTestStepArray( c ) );
634 		}
635 
636 		( getTestSuite() ).fireTestStepMoved( step, ix, offset );
637 	}
638 
639 	public int getIndexOfLoadTest( LoadTest loadTest )
640 	{
641 		return loadTests.indexOf( loadTest );
642 	}
643 
644 	public int getTestStepIndexByName( String stepName )
645 	{
646 		for( int c = 0; c < testSteps.size(); c++ )
647 		{
648 			if( testSteps.get( c ).getName().equals( stepName ) )
649 				return c;
650 		}
651 
652 		return -1;
653 	}
654 
655 	public TestStep findPreviousStepOfType( TestStep referenceStep, Class<? extends TestStep> stepClass )
656 	{
657 		int currentStepIndex = getIndexOfTestStep( referenceStep );
658 		int ix = currentStepIndex - 1;
659 		while( ix >= 0 && !getTestStepAt( ix ).getClass().equals( stepClass ) )
660 		{
661 			ix--;
662 		}
663 
664 		return ix < 0 ? null : getTestStepAt( ix );
665 	}
666 
667 	public TestStep findNextStepOfType( TestStep referenceStep, Class<? extends TestStep> stepClass )
668 	{
669 		int currentStepIndex = getIndexOfTestStep( referenceStep );
670 		int ix = currentStepIndex + 1;
671 		while( ix < getTestStepCount() && !getTestStepAt( ix ).getClass().equals( stepClass ) )
672 		{
673 			ix++;
674 		}
675 
676 		return ix >= getTestStepCount() ? null : getTestStepAt( ix );
677 	}
678 
679 	public List<TestStep> getTestStepList()
680 	{
681 		List<TestStep> result = new ArrayList<TestStep>();
682 		for( TestStep step : testSteps )
683 			result.add( step );
684 
685 		return result;
686 	}
687 
688 	@SuppressWarnings( "unchecked" )
689 	public <T extends TestStep> List<T> getTestStepsOfType( Class<T> stepType )
690 	{
691 		List<T> result = new ArrayList<T>();
692 		for( TestStep step : testSteps )
693 			if( step.getClass().isAssignableFrom( stepType ) )
694 				result.add( ( T ) step );
695 
696 		return result;
697 	}
698 
699 	public WsdlTestStep getTestStepByName( String stepName )
700 	{
701 		return ( WsdlTestStep ) getWsdlModelItemByName( testSteps, stepName );
702 	}
703 
704 	public WsdlLoadTest cloneLoadTest( WsdlLoadTest loadTest, String name )
705 	{
706 		loadTest.beforeSave();
707 
708 		LoadTestConfig loadTestConfig = getConfig().addNewLoadTest();
709 		loadTestConfig.set( loadTest.getConfig().copy() );
710 
711 		WsdlLoadTest newLoadTest = new WsdlLoadTest( this, loadTestConfig );
712 		newLoadTest.setName( name );
713 		loadTests.add( newLoadTest );
714 
715 		( getTestSuite() ).fireLoadTestAdded( newLoadTest );
716 
717 		return newLoadTest;
718 	}
719 
720 	@Override
721    public void release()
722 	{
723 		super.release();
724 
725 		for( WsdlTestStep testStep : testSteps )
726 			testStep.release();
727 
728 		for( WsdlLoadTest loadTest : loadTests )
729 			loadTest.release();
730 
731 		testRunListeners.clear();
732 		
733 		if( setupScriptEngine != null )
734 			setupScriptEngine.release();
735 		
736 		if( tearDownScriptEngine != null )
737 			tearDownScriptEngine.release();
738 	}
739 
740 	public ActionList getCreateActions()
741 	{
742 		return createActions;
743 	}
744 
745 	public void resetConfigOnMove( TestCaseConfig testCaseArray )
746 	{
747 		setConfig( testCaseArray );
748 		int mod = 0;
749 
750 		List<TestStepConfig> configs = getConfig().getTestStepList();
751 		for( int c = 0; c < configs.size(); c++ )
752 		{
753 			if( WsdlTestStepRegistry.getInstance().hasFactory( configs.get( c ) ) )
754 			{
755 				( testSteps.get( c - mod ) ).resetConfigOnMove( configs.get( c ) );
756 			}
757 			else
758 				mod++;
759 		}
760 
761 		List<LoadTestConfig> loadTestConfigs = getConfig().getLoadTestList();
762 		for( int c = 0; c < loadTestConfigs.size(); c++ )
763 		{
764 			loadTests.get( c ).resetConfigOnMove( loadTestConfigs.get( c ) );
765 		}
766 	}
767 
768 	@Override
769 	public void beforeSave()
770 	{
771 		for( WsdlTestStep testStep : testSteps )
772 			testStep.beforeSave();
773 
774 		for( WsdlLoadTest loadTest : loadTests )
775 			loadTest.beforeSave();
776 	}
777 
778 	public List<LoadTest> getLoadTestList()
779 	{
780 		List<LoadTest> result = new ArrayList<LoadTest>();
781 		for( LoadTest loadTest : loadTests )
782 			result.add( loadTest );
783 
784 		return result;
785 	}
786 
787 	public Object runSetupScript( TestRunContext runContext, TestRunner runner ) throws Exception
788 	{
789 		String script = getSetupScript();
790 		if( StringUtils.isNullOrEmpty( script ))
791 			return null;
792 		
793 		if( setupScriptEngine == null )
794 		{
795 			setupScriptEngine = SoapUIScriptEngineRegistry.create( SoapUIScriptEngineRegistry.GROOVY_ID, this );
796 			setupScriptEngine.setScript( script );
797 		}
798 		
799 		setupScriptEngine.setVariable( "context", runContext );
800 		setupScriptEngine.setVariable( "testRunner", runner );
801 		setupScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
802 		return setupScriptEngine.run();
803 	}
804 
805 	public Object runTearDownScript( TestRunContext runContext, TestRunner runner ) throws Exception
806 	{
807 		String script = getTearDownScript();
808 		if( StringUtils.isNullOrEmpty( script ))
809 			return null;
810 		
811 		if( tearDownScriptEngine == null )
812 		{
813 			tearDownScriptEngine = SoapUIScriptEngineRegistry.create( SoapUIScriptEngineRegistry.GROOVY_ID, this );
814 			tearDownScriptEngine.setScript( script );
815 		}
816 		
817 		tearDownScriptEngine.setVariable( "context", runContext );
818 		tearDownScriptEngine.setVariable( "testRunner", runner );
819 		tearDownScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
820 		return tearDownScriptEngine.run();
821 	}
822 
823 	public List<? extends ModelItem> getChildren()
824    {
825 		List<ModelItem> result = new ArrayList<ModelItem>();
826 		result.addAll( getTestStepList() );
827 		result.addAll( getLoadTestList() );
828 		return result;
829    }
830 	
831 	@Override
832 	public void setName( String name )
833 	{
834 		String oldLabel = getLabel();
835    	
836 		super.setName( name );
837 		
838 		String label = getLabel();
839 		if( oldLabel != null && !oldLabel.equals( label ))
840 		{
841 			notifyPropertyChanged( LABEL_PROPERTY, oldLabel, label );
842 		}
843 	}
844 
845 	public String getLabel()
846 	{
847 		String name = getName();
848 		if( isDisabled() )
849 			return name + " (disabled)";
850 		else
851 			return name;
852 	}
853 
854 	public boolean isDisabled()
855 	{
856 		return getConfig().getDisabled();
857 	}
858 	
859 	public void setDisabled( boolean disabled )
860 	{
861 		String oldLabel = getLabel();
862 		
863 		boolean oldDisabled = isDisabled();
864 		if( oldDisabled == disabled )
865 			return;
866 		
867 		if( disabled )
868 			getConfig().setDisabled( disabled );
869 		else if( getConfig().isSetDisabled() )
870 			getConfig().unsetDisabled();
871 		
872 		notifyPropertyChanged( DISABLED_PROPERTY, oldDisabled, disabled );
873 		
874 		String label = getLabel();
875 		if( !oldLabel.equals( label ))
876 			notifyPropertyChanged( LABEL_PROPERTY, oldLabel, label );
877 	}
878 	
879 	public long getTimeout()
880 	{
881 		return getConfig().getTimeout();
882 	}
883 	
884 	public void setTimeout( long timeout )
885 	{
886 		long old = getTimeout();
887 		getConfig().setTimeout( timeout );
888 		notifyPropertyChanged( TIMEOUT_PROPERTY, old, timeout );
889 	}
890 
891 	public void exportTestCase(File file)
892 	{
893 		try
894 		{
895 			this.getConfig().newCursor().save(file);
896 		}
897 		catch (IOException e)
898 		{
899 			e.printStackTrace();
900 		}
901 		
902 	}
903 }