View Javadoc

1   /*
2    *  soapUI, copyright (C) 2006 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of the GNU Lesser General Public License as published by the Free Software Foundation; 
6    *  either version 2.1 of the License, or (at your option) any later version.
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.testcase;
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.text.SimpleDateFormat;
20  import java.util.Date;
21  
22  import javax.swing.AbstractAction;
23  import javax.swing.Action;
24  import javax.swing.BorderFactory;
25  import javax.swing.Box;
26  import javax.swing.JButton;
27  import javax.swing.JLabel;
28  import javax.swing.JPanel;
29  import javax.swing.JProgressBar;
30  import javax.swing.JScrollPane;
31  import javax.swing.JSplitPane;
32  import javax.swing.JTabbedPane;
33  import javax.swing.JTextArea;
34  import javax.swing.JToggleButton;
35  import javax.swing.JToolBar;
36  import javax.swing.SwingUtilities;
37  import javax.swing.text.Document;
38  
39  import com.eviware.soapui.SoapUI;
40  import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
41  import com.eviware.soapui.impl.wsdl.actions.testcase.TestCaseOptionsAction;
42  import com.eviware.soapui.impl.wsdl.panels.support.ProgressBarAdapter;
43  import com.eviware.soapui.impl.wsdl.panels.testcase.actions.SetCredentialsAction;
44  import com.eviware.soapui.impl.wsdl.panels.testcase.actions.SetEndpointAction;
45  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
46  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
47  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner;
48  import com.eviware.soapui.model.ModelItem;
49  import com.eviware.soapui.model.support.PropertiesMap;
50  import com.eviware.soapui.model.support.TestRunListenerAdapter;
51  import com.eviware.soapui.model.testsuite.LoadTestRunner;
52  import com.eviware.soapui.model.testsuite.TestRunContext;
53  import com.eviware.soapui.model.testsuite.TestRunner;
54  import com.eviware.soapui.model.testsuite.TestStep;
55  import com.eviware.soapui.model.testsuite.TestStepResult;
56  import com.eviware.soapui.monitor.support.TestMonitorListenerAdapter;
57  import com.eviware.soapui.support.DocumentListenerAdapter;
58  import com.eviware.soapui.support.UISupport;
59  import com.eviware.soapui.support.swing.ComponentBag;
60  import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
61  
62  /***
63   * WsdlTestCase desktop panel
64   * 
65   * @author Ole.Matzura
66   */
67  
68  public class WsdlTestCaseDesktopPanel extends ModelItemDesktopPanel<WsdlTestCase>
69  {
70     private JProgressBar progressBar;
71     private TestStepList testStepList;
72     private InternalTestRunListener testRunListener = new InternalTestRunListener();
73  	private JButton runButton;
74  	private JButton cancelButton;
75     private TestRunner runner;
76  	private JButton setEndpointButton;
77  	private JButton setCredentialsButton;
78  	private JButton optionsButton;
79  	private ComponentBag stateDependantComponents = new ComponentBag();
80  	private TestCaseLog testCaseLog;
81  	private JToggleButton loopButton;
82  	private ProgressBarAdapter progressBarAdapter;
83  	private InternalTestMonitorListener testMonitorListener;
84  	public boolean canceled;
85  	private JTextArea descriptionArea;
86  
87     public WsdlTestCaseDesktopPanel(WsdlTestCase testCase)
88     {
89        super( testCase );
90  
91        buildUI();
92        
93        setPreferredSize( new Dimension( 250, 500 ));
94        setRunningState();
95        
96        testCase.addTestRunListener( testRunListener );
97        progressBarAdapter = new ProgressBarAdapter( progressBar, testCase );
98        testMonitorListener = new InternalTestMonitorListener();
99        
100 		SoapUI.getTestMonitor().addTestMonitorListener( testMonitorListener);
101    }
102 
103    /***
104     * There are three states:
105     * - enabled, no testcases or testschedules running
106     * - enabled, standalone testcase running
107     * - disabled, testschedule is running
108     */
109    
110 	private void setRunningState()
111 	{
112 		stateDependantComponents.setEnabled( !SoapUI.getTestMonitor().hasRunningLoadTest( getModelItem() ) );
113 	}
114 
115 	private void buildUI()
116    {
117 	   JPanel panel = new JPanel( new BorderLayout() );
118 	   
119       panel.add( buildToolbar(), BorderLayout.PAGE_START );
120       panel.add( buildRunnerBar(), BorderLayout.CENTER );
121       
122       add( panel, BorderLayout.NORTH );
123       
124       JSplitPane splitPane = UISupport.createVerticalSplit();
125 		splitPane.setTopComponent( buildTestStepList() );
126       splitPane.setBottomComponent( buildTestLog() );
127       splitPane.setDividerLocation( 0.7 );
128       splitPane.setDividerLocation( 250 );
129 
130       add( splitPane, BorderLayout.CENTER );
131       add( new JLabel( "--"), BorderLayout.PAGE_END );
132    }
133 
134    private Component buildTestLog()
135    {
136    	testCaseLog = new TestCaseLog();
137    	stateDependantComponents.add( testCaseLog );
138 		return testCaseLog;
139    }
140 
141    private Component buildTestStepList()
142    {
143       testStepList = new TestStepList( getModelItem() );
144       stateDependantComponents.add( testStepList );
145       
146       JTabbedPane tabs = new JTabbedPane( JTabbedPane.TOP );
147       tabs.addTab( "Test Steps",  new JScrollPane( testStepList ));
148       tabs.addTab( "Description", buildDescriptionPanel() );
149       
150 //      tabs.addTab( "Data Source", new JPanel() );
151 //      tabs.addTab( "Test Properties", new JPanel() );
152       
153       return UISupport.createTabPanel( tabs, false );
154    }
155 
156    private Component buildDescriptionPanel()
157 	{
158    	JPanel panel = new JPanel( new BorderLayout() );
159    	descriptionArea = new JTextArea( getModelItem().getDescription() );
160    	descriptionArea.getDocument().addDocumentListener( new DocumentListenerAdapter() 
161    	{
162 			public void update(Document document)
163 			{
164 				getModelItem().setDescription( descriptionArea.getText() );
165 			}} );
166    	
167    	panel.setBorder( BorderFactory.createEmptyBorder( 2, 2, 2, 2));
168    	panel.add( new JScrollPane( descriptionArea ), BorderLayout.CENTER );
169    	
170 		return panel;
171 	}
172 
173 	private Component buildToolbar()
174    {
175    	//ButtonBarBuilder builder = new ButtonBarBuilder();
176 		
177 		JToolBar toolbar = UISupport.createToolbar();
178 		
179       runButton = UISupport.createToolbarButton( new RunTestCaseAction());
180       optionsButton = UISupport.createToolbarButton( new TestCaseOptionsAction( getModelItem() ));
181       optionsButton.setText(null);
182       cancelButton = UISupport.createToolbarButton( new CancelRunTestCaseAction(), false );
183       
184       loopButton = new JToggleButton( UISupport.createImageIcon( "/loop.gif" ) );
185       loopButton.setPreferredSize( UISupport.getPreferredButtonSize());
186       loopButton.setToolTipText( "Loop TestCase continuously" );
187       
188       setCredentialsButton = UISupport.createToolbarButton( new SetCredentialsAction( getModelItem() ));
189       setEndpointButton = UISupport.createToolbarButton( new SetEndpointAction( getModelItem() ));
190 
191       stateDependantComponents.add( runButton );
192       stateDependantComponents.add( optionsButton );
193       stateDependantComponents.add( cancelButton );
194       stateDependantComponents.add( setCredentialsButton );
195       stateDependantComponents.add( setEndpointButton );
196       
197       toolbar.add( runButton );
198       toolbar.add( cancelButton );
199       toolbar.add( loopButton );
200       toolbar.add( Box.createHorizontalGlue() );
201       toolbar.add(  setCredentialsButton );
202       toolbar.add(  setEndpointButton );
203       toolbar.add(  optionsButton );
204       toolbar.add(  UISupport.createToolbarButton( new ShowOnlineHelpAction( HelpUrls.TESTCASEEDITOR_HELP_URL )));
205       
206       return toolbar;
207    }
208 
209    private Component buildRunnerBar()
210    {
211       progressBar = new JProgressBar( 0, getModelItem().getTestStepCount() );
212       return UISupport.createProgressBarPanel( progressBar, 10, false );
213    }
214    
215    private final class InternalTestMonitorListener extends TestMonitorListenerAdapter
216 	{
217 		public void loadTestStarted(LoadTestRunner runner)
218 		{
219 			setRunningState();
220 		}
221 
222 		public void loadTestFinished(LoadTestRunner runner)
223 		{
224 			setRunningState();
225 		}
226 	}
227 
228 	public class InternalTestRunListener extends TestRunListenerAdapter 
229    {
230 		private SimpleDateFormat dateFormat;
231 
232 		public InternalTestRunListener()
233 		{
234 			dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
235 		}
236 
237 		public void beforeRun(TestRunner testRunner, TestRunContext runContext) 
238 		{
239 			if( SoapUI.getTestMonitor().hasRunningLoadTest( getModelItem() ) )
240 				return ;
241 			
242 			runButton.setEnabled( false );
243 			cancelButton.setEnabled( true );
244 			testStepList.setEnabled( false );
245 			testStepList.setSelectedIndex( -1 );
246 			testCaseLog.clear();
247 			
248 			testCaseLog.addText( "Test started at " + dateFormat.format( new Date()) );
249 		}
250 
251 		public void beforeStep(TestRunner testRunner, TestRunContext runContext) 
252 		{
253 			if( SoapUI.getTestMonitor().hasRunningLoadTest( getModelItem() ) )
254 				return ;
255 			
256 			TestStep testStep = runContext.getCurrentStep();
257 			testStepList.setSelectedValue( testStep, true );
258 		}
259 		
260 		public void afterRun(TestRunner testRunner, TestRunContext runContext) 
261 		{
262 			if( SoapUI.getTestMonitor().hasRunningLoadTest( getModelItem() ) )
263 				return ;
264 			
265 			WsdlTestCaseRunner wsdlRunner = (WsdlTestCaseRunner) testRunner;
266 			
267 			if( testRunner.getStatus() == TestRunner.Status.CANCELED )
268 				testCaseLog.addText( "Test canceled [" + testRunner.getReason() + "], time taken = " + wsdlRunner.getTimeTaken());
269 			else
270 				testCaseLog.addText( "Test finished, time taken = " + wsdlRunner.getTimeTaken());
271 			
272 			runner = null;
273 			
274 			JToggleButton loopButton = (JToggleButton) runContext.getProperty( "loopButton" );
275 			if( loopButton != null && loopButton.isSelected() && testRunner.getStatus() == TestRunner.Status.FINISHED )
276 			{
277 				SwingUtilities.invokeLater( new Runnable()
278 						{
279 							public void run()
280 							{
281 								runTestCase();
282 							}
283 						});
284 			}
285 			else
286 			{
287 				runButton.setEnabled( true );	
288 				cancelButton.setEnabled( false );
289 				testStepList.setEnabled( true );
290 			}
291 		}
292 
293 		public void afterStep(TestRunner testRunner, TestRunContext runContext, TestStepResult stepResult) 
294 		{
295 			if( SoapUI.getTestMonitor().hasRunningLoadTest( getModelItem() ) )
296 				return ;
297 			
298 			testCaseLog.addTestStepResult( stepResult );
299 		}
300    }
301 
302 	private void runTestCase()
303 	{
304 		if( canceled )
305 		{
306 			// make sure state is correct
307 			runButton.setEnabled( true );	
308 			cancelButton.setEnabled( false );
309 			testStepList.setEnabled( true );
310 			return;
311 		}
312 		
313 		PropertiesMap properties = new PropertiesMap();
314 		properties.put( "loopButton", loopButton );
315 		runner = getModelItem().run( properties, true );
316 	}
317 
318    public class RunTestCaseAction extends AbstractAction
319    {
320 		public RunTestCaseAction()
321       {
322          putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_testcase.gif"));
323          putValue( Action.SHORT_DESCRIPTION, "Runs this testcase" );
324       }
325 
326 		public void actionPerformed(ActionEvent e)
327 		{
328 			canceled = false;
329 			runTestCase();
330 		}
331    }
332 
333    public class CancelRunTestCaseAction extends AbstractAction
334    {
335 		public CancelRunTestCaseAction()
336       {
337          putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/stop_testcase.gif"));
338          putValue( Action.SHORT_DESCRIPTION, "Stops running this testcase" );
339       }
340       
341 		public void actionPerformed(ActionEvent e)
342 		{
343       	if( runner != null )
344       		runner.cancel( "canceled in UI" );
345       	
346       	canceled = true;
347       }
348    }
349    
350   
351 	public boolean onClose( boolean canCancel )
352 	{
353 		if( canCancel )
354 		{
355 			if( runner != null && runner.getStatus() == TestRunner.Status.RUNNING )
356 			{
357 				Boolean retval = UISupport.confirmOrCancel( "Cancel running TestCase?", "Cancel Run" );
358 				
359 				if( retval == null ) return false;
360 				if( retval.booleanValue() )
361 				{
362 					runner.cancel( null );
363 				}
364 			}
365 		}
366 		else
367 		{
368 			if( runner != null && runner.getStatus() == TestRunner.Status.RUNNING )
369 			{
370 				runner.cancel( null );
371 			}
372 		}
373 		
374 		SoapUI.getTestMonitor().removeTestMonitorListener( testMonitorListener );
375 		getModelItem().removeTestRunListener( testRunListener );
376       testStepList.release();
377 
378       return true;
379 	}
380 
381 	public boolean dependsOn(ModelItem modelItem)
382 	{
383 		return modelItem == getModelItem() || modelItem == getModelItem().getTestSuite() ||
384 				modelItem == getModelItem().getTestSuite().getProject();
385 	}
386 
387 	public String getDescription()
388 	{
389 		return "TestCase: [" + getModelItem().getName() + "]";
390 	}
391 }