View Javadoc

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