View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2010 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.testsuite;
14  
15  import java.awt.BorderLayout;
16  import java.awt.Color;
17  import java.awt.Component;
18  import java.awt.Dimension;
19  import java.awt.event.ActionEvent;
20  import java.awt.event.ActionListener;
21  
22  import javax.swing.AbstractAction;
23  import javax.swing.Action;
24  import javax.swing.BorderFactory;
25  import javax.swing.ButtonGroup;
26  import javax.swing.JComponent;
27  import javax.swing.JPanel;
28  import javax.swing.JProgressBar;
29  import javax.swing.JScrollPane;
30  import javax.swing.JTabbedPane;
31  import javax.swing.JTextArea;
32  import javax.swing.JToggleButton;
33  import javax.swing.text.Document;
34  
35  import com.eviware.soapui.impl.support.actions.ShowOnlineHelpAction;
36  import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
37  import com.eviware.soapui.impl.wsdl.actions.testsuite.AddNewTestCaseAction;
38  import com.eviware.soapui.impl.wsdl.panels.support.MockTestSuiteRunner;
39  import com.eviware.soapui.impl.wsdl.panels.testcase.JTestRunLog;
40  import com.eviware.soapui.impl.wsdl.panels.testcase.TestRunLogTestRunListener;
41  import com.eviware.soapui.impl.wsdl.panels.teststeps.support.AbstractGroovyEditorModel;
42  import com.eviware.soapui.impl.wsdl.panels.teststeps.support.PropertyHolderTable;
43  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
44  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestSuiteRunner;
45  import com.eviware.soapui.model.ModelItem;
46  import com.eviware.soapui.model.support.TestSuiteListenerAdapter;
47  import com.eviware.soapui.model.testsuite.TestCase;
48  import com.eviware.soapui.model.testsuite.TestCaseRunner;
49  import com.eviware.soapui.model.testsuite.TestSuiteRunContext;
50  import com.eviware.soapui.model.testsuite.TestSuiteRunListener;
51  import com.eviware.soapui.model.testsuite.TestSuiteRunner;
52  import com.eviware.soapui.model.testsuite.TestSuite.TestSuiteRunType;
53  import com.eviware.soapui.settings.UISettings;
54  import com.eviware.soapui.support.DocumentListenerAdapter;
55  import com.eviware.soapui.support.StringUtils;
56  import com.eviware.soapui.support.UISupport;
57  import com.eviware.soapui.support.action.swing.SwingActionDelegate;
58  import com.eviware.soapui.support.components.GroovyEditorComponent;
59  import com.eviware.soapui.support.components.GroovyEditorInspector;
60  import com.eviware.soapui.support.components.JComponentInspector;
61  import com.eviware.soapui.support.components.JFocusableComponentInspector;
62  import com.eviware.soapui.support.components.JInspectorPanel;
63  import com.eviware.soapui.support.components.JInspectorPanelFactory;
64  import com.eviware.soapui.support.components.JUndoableTextArea;
65  import com.eviware.soapui.support.components.JXToolBar;
66  import com.eviware.soapui.support.types.StringToObjectMap;
67  import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
68  
69  /***
70   * DesktopPanel for WsdlTestSuite
71   * 
72   * @author Ole.Matzura
73   */
74  
75  @SuppressWarnings( "serial" )
76  public class WsdlTestSuiteDesktopPanel extends ModelItemDesktopPanel<WsdlTestSuite>
77  {
78  	private JProgressBar progressBar;
79  	private JTestSuiteTestCaseList testCaseList;
80  	private RunAction runAction = new RunAction();
81  	private CancelAction cancelAction = new CancelAction();
82  	private JToggleButton sequentialButton;
83  	private JToggleButton parallellButton;
84  	private final InternalTestSuiteListener testSuiteListener = new InternalTestSuiteListener();
85  	private final InternalTestSuiteRunListener testSuiteRunListener = new InternalTestSuiteRunListener();
86  	private JTextArea descriptionArea;
87  	private PropertyHolderTable propertiesTable;
88  	private JTestRunLog testRunLog;
89  	private GroovyEditorComponent tearDownGroovyEditor;
90  	private GroovyEditorComponent setupGroovyEditor;
91  	private JInspectorPanel testCaseListInspectorPanel;
92  	private JInspectorPanel inspectorPanel;
93  	private WsdlTestSuiteRunner testSuiteRunner;
94  
95  	public WsdlTestSuiteDesktopPanel( WsdlTestSuite testSuite )
96  	{
97  		super( testSuite );
98  
99  		buildUI();
100 		testSuite.addTestSuiteListener( testSuiteListener );
101 		testSuite.addTestSuiteRunListener( testSuiteRunListener );
102 	}
103 
104 	private void buildUI()
105 	{
106 		add( buildToolbar(), BorderLayout.NORTH );
107 		add( buildContent(), BorderLayout.CENTER );
108 
109 		setPreferredSize( new Dimension( 500, 500 ) );
110 	}
111 
112 	private JComponent buildContent()
113 	{
114 		inspectorPanel = JInspectorPanelFactory.build( buildTabs() );
115 		inspectorPanel.addInspector( new JComponentInspector<JComponent>( buildRunLog(), "TestSuite Log",
116 				"Log of executed TestCases and TestSteps", true ) );
117 
118 		if( StringUtils.hasContent( getModelItem().getDescription() )
119 				&& getModelItem().getSettings().getBoolean( UISettings.SHOW_DESCRIPTIONS ) )
120 		{
121 			testCaseListInspectorPanel.setCurrentInspector( "Description" );
122 		}
123 
124 		return inspectorPanel.getComponent();
125 	}
126 
127 	private JComponent buildRunLog()
128 	{
129 		testRunLog = new JTestRunLog( getModelItem().getSettings() );
130 		return testRunLog;
131 	}
132 
133 	protected JTestSuiteTestCaseList getTestCaseList()
134 	{
135 		return testCaseList;
136 	}
137 
138 	private JComponent buildToolbar()
139 	{
140 		cancelAction.setEnabled( false );
141 		runAction.setEnabled( getModelItem().getTestCaseCount() > 0 );
142 
143 		JXToolBar toolbar = UISupport.createToolbar();
144 
145 		addToolbarActions( toolbar );
146 		toolbar.addGlue();
147 		toolbar.add( UISupport.createToolbarButton( new ShowOnlineHelpAction( HelpUrls.TESTSUITE_HELP_URL ) ) );
148 
149 		progressBar = new JProgressBar( 0, getModelItem().getTestCaseCount() );
150 		JPanel progressPanel = UISupport.createProgressBarPanel( progressBar, 10, false );
151 
152 		JPanel panel = new JPanel( new BorderLayout() );
153 
154 		panel.add( toolbar, BorderLayout.PAGE_START );
155 		panel.add( progressPanel, BorderLayout.CENTER );
156 
157 		return panel;
158 	}
159 
160 	protected void addToolbarActions( JXToolBar toolbar )
161 	{
162 		toolbar.add( UISupport.createToolbarButton( runAction ) );
163 		toolbar.add( UISupport.createToolbarButton( cancelAction ) );
164 
165 		toolbar.addRelatedGap();
166 
167 		ButtonGroup buttonGroup = new ButtonGroup();
168 
169 		sequentialButton = new JToggleButton( UISupport.createImageIcon( "/sequential.gif" ), true );
170 		sequentialButton.setToolTipText( "The selected TestCases are run in sequence" );
171 		sequentialButton.setPreferredSize( UISupport.getPreferredButtonSize() );
172 		sequentialButton.setSelected( getModelItem().getRunType() == TestSuiteRunType.SEQUENTIAL );
173 		sequentialButton.addActionListener( new ActionListener()
174 		{
175 
176 			public void actionPerformed( ActionEvent e )
177 			{
178 				getModelItem().setRunType( TestSuiteRunType.SEQUENTIAL );
179 			}
180 		} );
181 
182 		buttonGroup.add( sequentialButton );
183 
184 		parallellButton = new JToggleButton( UISupport.createImageIcon( "/parallell.gif" ) );
185 		parallellButton.setToolTipText( "The selected TestCases are run in parallel" );
186 		parallellButton.setPreferredSize( UISupport.getPreferredButtonSize() );
187 		parallellButton.setSelected( getModelItem().getRunType() == TestSuiteRunType.PARALLEL );
188 		parallellButton.addActionListener( new ActionListener()
189 		{
190 
191 			public void actionPerformed( ActionEvent e )
192 			{
193 				getModelItem().setRunType( TestSuiteRunType.PARALLEL );
194 			}
195 		} );
196 
197 		buttonGroup.add( parallellButton );
198 
199 		toolbar.addUnrelatedGap();
200 		toolbar.add( sequentialButton );
201 		toolbar.addRelatedGap();
202 		toolbar.add( parallellButton );
203 	}
204 
205 	private JComponent buildTabs()
206 	{
207 		JTabbedPane tabs = new JTabbedPane( JTabbedPane.TOP );
208 		testCaseListInspectorPanel = JInspectorPanelFactory.build( buildTestCaseList( getModelItem() ) );
209 
210 		tabs.addTab( "TestCases", testCaseListInspectorPanel.getComponent() );
211 
212 		addTabs( tabs, testCaseListInspectorPanel );
213 		tabs.setTabLayoutPolicy( JTabbedPane.SCROLL_TAB_LAYOUT );
214 
215 		return UISupport.createTabPanel( tabs, true );
216 	}
217 
218 	protected void addTabs( JTabbedPane tabs, JInspectorPanel inspectorPanel )
219 	{
220 		inspectorPanel.addInspector( new JFocusableComponentInspector<JPanel>( buildDescriptionPanel(), descriptionArea,
221 				"Description", "Description for this TestSuite", true ) );
222 		inspectorPanel.addInspector( new JComponentInspector<JComponent>( buildPropertiesPanel(), "Properties",
223 				"TestSuite level properties", true ) );
224 		inspectorPanel.addInspector( new GroovyEditorInspector( buildSetupScriptPanel(), "Setup Script",
225 				"Script to run before running TestSuite" ) );
226 		inspectorPanel.addInspector( new GroovyEditorInspector( buildTearDownScriptPanel(), "TearDown Script",
227 				"Script to run after running TestSuite" ) );
228 	}
229 
230 	protected GroovyEditorComponent buildTearDownScriptPanel()
231 	{
232 		tearDownGroovyEditor = new GroovyEditorComponent( new TearDownScriptGroovyEditorModel(), null );
233 		return tearDownGroovyEditor;
234 	}
235 
236 	protected GroovyEditorComponent buildSetupScriptPanel()
237 	{
238 		setupGroovyEditor = new GroovyEditorComponent( new SetupScriptGroovyEditorModel(), null );
239 		return setupGroovyEditor;
240 	}
241 
242 	private JComponent buildPropertiesPanel()
243 	{
244 		JPanel panel = new JPanel( new BorderLayout() );
245 		propertiesTable = createPropertyHolderTable();
246 		panel.add( new JScrollPane( propertiesTable ), BorderLayout.CENTER );
247 		return panel;
248 	}
249 
250 	protected PropertyHolderTable createPropertyHolderTable()
251 	{
252 		return new PropertyHolderTable( getModelItem() );
253 	}
254 
255 	private JPanel buildDescriptionPanel()
256 	{
257 		JPanel panel = new JPanel( new BorderLayout() );
258 		descriptionArea = new JUndoableTextArea( getModelItem().getDescription() );
259 		descriptionArea.getDocument().addDocumentListener( new DocumentListenerAdapter()
260 		{
261 			public void update( Document document )
262 			{
263 				getModelItem().setDescription( descriptionArea.getText() );
264 			}
265 		} );
266 
267 		panel.setBorder( BorderFactory.createEmptyBorder( 2, 2, 2, 2 ) );
268 		panel.add( new JScrollPane( descriptionArea ), BorderLayout.CENTER );
269 		UISupport.addTitledBorder( panel, "TestSuite Description" );
270 
271 		return panel;
272 	}
273 
274 	protected JComponent buildTestCaseList( WsdlTestSuite testSuite )
275 	{
276 		testCaseList = new JTestSuiteTestCaseList( testSuite );
277 
278 		JPanel p = new JPanel( new BorderLayout() );
279 
280 		p.add( buildTestCaseListToolbar(), BorderLayout.NORTH );
281 		p.add( new JScrollPane( testCaseList ), BorderLayout.CENTER );
282 
283 		return p;
284 	}
285 
286 	private Component buildTestCaseListToolbar()
287 	{
288 		JXToolBar toolbar = UISupport.createToolbar();
289 		toolbar.add( UISupport.createToolbarButton( SwingActionDelegate.createDelegate(
290 				AddNewTestCaseAction.SOAPUI_ACTION_ID, getModelItem(), null, "/testCase.gif" ) ) );
291 		toolbar.addGlue();
292 		toolbar.add( UISupport.createToolbarButton( new ShowOnlineHelpAction( HelpUrls.TESTSUITEEDITOR_HELP_URL ) ) );
293 		return toolbar;
294 	}
295 
296 	public boolean onClose( boolean canCancel )
297 	{
298 		propertiesTable.release();
299 		inspectorPanel.release();
300 		testCaseListInspectorPanel.release();
301 
302 		setupGroovyEditor.getEditor().release();
303 		tearDownGroovyEditor.getEditor().release();
304 
305 		testRunLog.release();
306 
307 		getModelItem().removeTestSuiteRunListener( testSuiteRunListener );
308 		getModelItem().removeTestSuiteListener( testSuiteListener );
309 
310 		return super.release();
311 	}
312 
313 	public JComponent getComponent()
314 	{
315 		return this;
316 	}
317 
318 	public boolean dependsOn( ModelItem modelItem )
319 	{
320 		return modelItem == getModelItem() || modelItem == getModelItem().getProject();
321 	}
322 
323 	protected void runTestSuite()
324 	{
325 		testSuiteRunner = getModelItem().run( new StringToObjectMap(), true );
326 
327 		// new Thread( testSuiteRunner, getModelItem().getName() +
328 		// " TestSuiteRunner" ).start();
329 	}
330 
331 	protected void beforeRun()
332 	{
333 		runAction.setEnabled( false );
334 		cancelAction.setEnabled( testSuiteRunner != null );
335 		testCaseList.setEnabled( false );
336 		progressBar.setForeground( Color.GREEN.darker() );
337 	}
338 
339 	protected void afterRun( WsdlTestSuiteRunner testSuiteRunner )
340 	{
341 		runAction.setEnabled( true );
342 		cancelAction.setEnabled( false );
343 		testCaseList.setEnabled( true );
344 
345 		progressBar.setString( String.valueOf( testSuiteRunner.getStatus() ) );
346 		progressBar.setForeground( testSuiteRunner.isFailed() ? Color.RED : Color.GREEN.darker() );
347 	}
348 
349 	private final class InternalTestSuiteListener extends TestSuiteListenerAdapter
350 	{
351 		public void testCaseAdded( TestCase testCase )
352 		{
353 			runAction.setEnabled( getModelItem().getTestCaseCount() > 0 );
354 		}
355 
356 		public void testCaseRemoved( TestCase testCase )
357 		{
358 			runAction.setEnabled( getModelItem().getTestCaseCount() > 0 );
359 		}
360 	}
361 
362 	private class RunAction extends AbstractAction
363 	{
364 		public RunAction()
365 		{
366 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_testcase.gif" ) );
367 			putValue( Action.SHORT_DESCRIPTION, "Runs the selected TestCases" );
368 		}
369 
370 		public void actionPerformed( ActionEvent e )
371 		{
372 			runTestSuite();
373 		}
374 	}
375 
376 	private class CancelAction extends AbstractAction
377 	{
378 		public CancelAction()
379 		{
380 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/stop_testcase.gif" ) );
381 			putValue( Action.SHORT_DESCRIPTION, "Cancels ongoing TestCase runs" );
382 		}
383 
384 		public void actionPerformed( ActionEvent e )
385 		{
386 			testSuiteRunner.cancel( "Cancelled from UI" );
387 		}
388 	}
389 
390 	private class SetupScriptGroovyEditorModel extends AbstractGroovyEditorModel
391 	{
392 		public SetupScriptGroovyEditorModel()
393 		{
394 			super( new String[] { "log", "runner", "context", "testSuite" }, WsdlTestSuiteDesktopPanel.this.getModelItem(), "Setup" );
395 		}
396 
397 		public String getScript()
398 		{
399 			return  WsdlTestSuiteDesktopPanel.this.getModelItem().getSetupScript();
400 		}
401 
402 		public void setScript( String text )
403 		{
404 			 WsdlTestSuiteDesktopPanel.this.getModelItem().setSetupScript( text );
405 		}
406 
407 		@Override
408 		public Action createRunAction()
409 		{
410 			return new AbstractAction()
411 			{
412 
413 				public void actionPerformed( ActionEvent e )
414 				{
415 					try
416 					{
417 						MockTestSuiteRunner mockRunner = new MockTestSuiteRunner(  WsdlTestSuiteDesktopPanel.this.getModelItem() );
418 						 WsdlTestSuiteDesktopPanel.this.getModelItem().runSetupScript( ( TestSuiteRunContext )mockRunner.getRunContext(), mockRunner );
419 					}
420 					catch( Exception e1 )
421 					{
422 						UISupport.showErrorMessage( e1 );
423 					}
424 				}
425 			};
426 		}
427 	}
428 
429 	private class TearDownScriptGroovyEditorModel extends AbstractGroovyEditorModel
430 	{
431 		public TearDownScriptGroovyEditorModel()
432 		{
433 			super( new String[] { "log", "runner", "context", "testSuite" },  WsdlTestSuiteDesktopPanel.this.getModelItem(), "TearDown" );
434 		}
435 
436 		public String getScript()
437 		{
438 			return  WsdlTestSuiteDesktopPanel.this.getModelItem().getTearDownScript();
439 		}
440 
441 		public void setScript( String text )
442 		{
443 			 WsdlTestSuiteDesktopPanel.this.getModelItem().setTearDownScript( text );
444 		}
445 
446 		@Override
447 		public Action createRunAction()
448 		{
449 			return new AbstractAction()
450 			{
451 
452 				public void actionPerformed( ActionEvent e )
453 				{
454 					try
455 					{
456 						MockTestSuiteRunner mockRunner = new MockTestSuiteRunner(  WsdlTestSuiteDesktopPanel.this.getModelItem() );
457 						 WsdlTestSuiteDesktopPanel.this.getModelItem().runTearDownScript( ( TestSuiteRunContext )mockRunner.getRunContext(), mockRunner );
458 					}
459 					catch( Exception e1 )
460 					{
461 						UISupport.showErrorMessage( e1 );
462 					}
463 				}
464 			};
465 		}
466 	}
467 
468 	private class InternalTestSuiteRunListener implements TestSuiteRunListener
469 	{
470 		private TestRunLogTestRunListener runLogListener;
471 		private int finishCount;
472 
473 		public void afterRun( TestSuiteRunner testRunner, TestSuiteRunContext runContext )
474 		{
475 			WsdlTestSuiteDesktopPanel.this.afterRun( ( WsdlTestSuiteRunner )testRunner );
476 		}
477 
478 		public void afterTestCase( TestSuiteRunner testRunner, TestSuiteRunContext runContext,
479 				TestCaseRunner testCaseRunner )
480 		{
481 			progressBar.setValue( ++finishCount );
482 
483 			if( getModelItem().getRunType() == TestSuiteRunType.SEQUENTIAL )
484 				testCaseRunner.getTestCase().removeTestRunListener( runLogListener );
485 		}
486 
487 		public void beforeRun( TestSuiteRunner testRunner, TestSuiteRunContext runContext )
488 		{
489 			WsdlTestSuiteDesktopPanel.this.beforeRun();
490 
491 			testCaseList.reset();
492 
493 			progressBar.setMaximum( getModelItem().getTestCaseCount() );
494 			progressBar.setValue( 0 );
495 			progressBar.setString( "" );
496 			finishCount = 0;
497 
498 			if( runLogListener == null )
499 				runLogListener = new TestRunLogTestRunListener( testRunLog, false );
500 
501 			testRunLog.clear();
502 
503 			if( getModelItem().getRunType() == TestSuiteRunType.PARALLEL )
504 				testRunLog.addText( "<log disabled during parallell execution>" );
505 		}
506 
507 		public void beforeTestCase( TestSuiteRunner testRunner, TestSuiteRunContext runContext, TestCase testCase )
508 		{
509 			if( getModelItem().getRunType() == TestSuiteRunType.SEQUENTIAL )
510 			{
511 				progressBar.setString( "Running " + testCase.getName() );
512 				testCase.addTestRunListener( runLogListener );
513 			}
514 			else
515 			{
516 				progressBar.setString( "Starting " + testCase.getName() );
517 			}
518 		}
519 	}
520 }