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.project;
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.ButtonGroup;
25  import javax.swing.JComponent;
26  import javax.swing.JPanel;
27  import javax.swing.JProgressBar;
28  import javax.swing.JScrollPane;
29  import javax.swing.JTabbedPane;
30  import javax.swing.JToggleButton;
31  
32  import com.eviware.soapui.impl.support.actions.ShowOnlineHelpAction;
33  import com.eviware.soapui.impl.wsdl.WsdlProject;
34  import com.eviware.soapui.impl.wsdl.actions.project.AddNewTestSuiteAction;
35  import com.eviware.soapui.impl.wsdl.panels.support.MockProjectRunner;
36  import com.eviware.soapui.impl.wsdl.panels.testcase.JTestRunLog;
37  import com.eviware.soapui.impl.wsdl.panels.teststeps.support.AbstractGroovyEditorModel;
38  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
39  import com.eviware.soapui.impl.wsdl.testcase.WsdlProjectRunner;
40  import com.eviware.soapui.model.support.ProjectListenerAdapter;
41  import com.eviware.soapui.model.testsuite.ProjectRunContext;
42  import com.eviware.soapui.model.testsuite.ProjectRunListener;
43  import com.eviware.soapui.model.testsuite.ProjectRunner;
44  import com.eviware.soapui.model.testsuite.TestSuite;
45  import com.eviware.soapui.model.testsuite.TestSuiteRunner;
46  import com.eviware.soapui.model.testsuite.TestSuite.TestSuiteRunType;
47  import com.eviware.soapui.support.UISupport;
48  import com.eviware.soapui.support.action.swing.SwingActionDelegate;
49  import com.eviware.soapui.support.components.GroovyEditorComponent;
50  import com.eviware.soapui.support.components.GroovyEditorInspector;
51  import com.eviware.soapui.support.components.JComponentInspector;
52  import com.eviware.soapui.support.components.JInspectorPanel;
53  import com.eviware.soapui.support.components.JInspectorPanelFactory;
54  import com.eviware.soapui.support.components.JXToolBar;
55  import com.eviware.soapui.support.types.StringToObjectMap;
56  
57  public class WsdlProjectTestSuitesTabPanel extends JPanel
58  {
59  	private final WsdlProject project;
60  	private JProgressBar progressBar;
61  	private JProjectTestSuiteList testSuiteList;
62  	private RunAction runAction = new RunAction();
63  	private CancelAction cancelAction = new CancelAction();
64  	private JToggleButton sequentialButton;
65  	private JToggleButton parallellButton;
66  	private final InternalProjectListener testSuiteListener = new InternalProjectListener();
67  	private final InternalTestSuiteRunListener testSuiteRunListener = new InternalTestSuiteRunListener();
68  	private JTestRunLog testRunLog;
69  	private GroovyEditorComponent tearDownGroovyEditor;
70  	private GroovyEditorComponent setupGroovyEditor;
71  	private JInspectorPanel testSuiteListInspectorPanel;
72  	private JInspectorPanel inspectorPanel;
73  	private WsdlProjectRunner projectRunner;
74  
75  	public WsdlProjectTestSuitesTabPanel( WsdlProject project )
76  	{
77  		super( new BorderLayout() );
78  		this.project = project;
79  
80  		buildUI();
81  		project.addProjectRunListener( testSuiteRunListener );
82  		project.addProjectListener( testSuiteListener );
83  	}
84  
85  	public WsdlProject getProject()
86  	{
87  		return project;
88  	}
89  
90  	private void buildUI()
91  	{
92  		add( buildToolbar(), BorderLayout.NORTH );
93  		add( buildContent(), BorderLayout.CENTER );
94  
95  		setPreferredSize( new Dimension( 500, 500 ) );
96  	}
97  
98  	private JComponent buildContent()
99  	{
100 		inspectorPanel = JInspectorPanelFactory.build( buildTabs() );
101 		addInspectors( inspectorPanel );
102 
103 		return inspectorPanel.getComponent();
104 	}
105 
106 	protected void addInspectors( JInspectorPanel inspectorPanel )
107 	{
108 		inspectorPanel.addInspector( new JComponentInspector<JComponent>( buildRunLog(), "TestSuite Log",
109 				"Log of executed TestSuites, TestCases and TestSteps", true ) );
110 	}
111 
112 	private JComponent buildRunLog()
113 	{
114 		testRunLog = new JTestRunLog( project.getSettings() );
115 		return testRunLog;
116 	}
117 
118 	protected JProjectTestSuiteList getTestSuiteList()
119 	{
120 		return testSuiteList;
121 	}
122 
123 	private JComponent buildToolbar()
124 	{
125 		cancelAction.setEnabled( false );
126 		runAction.setEnabled( project.getTestSuiteCount() > 0 );
127 
128 		JXToolBar toolbar = UISupport.createToolbar();
129 
130 		addToolbarActions( toolbar );
131 		toolbar.addGlue();
132 		toolbar.add( UISupport.createToolbarButton( new ShowOnlineHelpAction( HelpUrls.TESTSUITE_HELP_URL ) ) );
133 
134 		progressBar = new JProgressBar( 0, project.getTestSuiteCount() );
135 		JPanel progressPanel = UISupport.createProgressBarPanel( progressBar, 10, false );
136 
137 		JPanel panel = new JPanel( new BorderLayout() );
138 
139 		panel.add( toolbar, BorderLayout.PAGE_START );
140 		panel.add( progressPanel, BorderLayout.CENTER );
141 
142 		return panel;
143 	}
144 
145 	protected void addToolbarActions( JXToolBar toolbar )
146 	{
147 		toolbar.add( UISupport.createToolbarButton( runAction ) );
148 		toolbar.add( UISupport.createToolbarButton( cancelAction ) );
149 
150 		toolbar.addRelatedGap();
151 
152 		ButtonGroup buttonGroup = new ButtonGroup();
153 
154 		sequentialButton = new JToggleButton( UISupport.createImageIcon( "/sequential.gif" ), true );
155 		sequentialButton.setToolTipText( "The selected TestCases are run in sequence" );
156 		sequentialButton.setPreferredSize( UISupport.getPreferredButtonSize() );
157 		sequentialButton.setSelected( project.getRunType() == TestSuiteRunType.SEQUENTIAL );
158 		sequentialButton.addActionListener( new ActionListener()
159 		{
160 			public void actionPerformed( ActionEvent e )
161 			{
162 				project.setRunType( TestSuiteRunType.SEQUENTIAL );
163 			}
164 		} );
165 
166 		buttonGroup.add( sequentialButton );
167 
168 		parallellButton = new JToggleButton( UISupport.createImageIcon( "/parallell.gif" ) );
169 		parallellButton.setToolTipText( "The selected TestCases are run in parallel" );
170 		parallellButton.setPreferredSize( UISupport.getPreferredButtonSize() );
171 		parallellButton.setSelected( project.getRunType() == TestSuiteRunType.PARALLEL );
172 		parallellButton.addActionListener( new ActionListener()
173 		{
174 
175 			public void actionPerformed( ActionEvent e )
176 			{
177 				project.setRunType( TestSuiteRunType.PARALLEL );
178 			}
179 		} );
180 
181 		buttonGroup.add( parallellButton );
182 
183 		toolbar.addUnrelatedGap();
184 		toolbar.add( sequentialButton );
185 		toolbar.addRelatedGap();
186 		toolbar.add( parallellButton );
187 	}
188 
189 	private JComponent buildTabs()
190 	{
191 		JTabbedPane tabs = new JTabbedPane( JTabbedPane.TOP );
192 		testSuiteListInspectorPanel = JInspectorPanelFactory.build( buildTestSuiteList( project ) );
193 
194 		tabs.addTab( "TestSuites", testSuiteListInspectorPanel.getComponent() );
195 
196 		addTabs( tabs, testSuiteListInspectorPanel );
197 		tabs.setTabLayoutPolicy( JTabbedPane.SCROLL_TAB_LAYOUT );
198 
199 		return UISupport.createTabPanel( tabs, true );
200 	}
201 
202 	protected void addTabs( JTabbedPane tabs, JInspectorPanel inspectorPanel )
203 	{
204 		inspectorPanel.addInspector( new GroovyEditorInspector( buildSetupScriptPanel(), "Setup Script",
205 				"Script to run before running TestSuites" ) );
206 		inspectorPanel.addInspector( new GroovyEditorInspector( buildTearDownScriptPanel(), "TearDown Script",
207 				"Script to run after running TestSuites" ) );
208 	}
209 
210 	protected GroovyEditorComponent buildTearDownScriptPanel()
211 	{
212 		tearDownGroovyEditor = new GroovyEditorComponent( new TearDownScriptGroovyEditorModel(), null );
213 		return tearDownGroovyEditor;
214 	}
215 
216 	protected GroovyEditorComponent buildSetupScriptPanel()
217 	{
218 		setupGroovyEditor = new GroovyEditorComponent( new SetupScriptGroovyEditorModel(), null );
219 		return setupGroovyEditor;
220 	}
221 
222 	protected JComponent buildTestSuiteList( WsdlProject testSuite )
223 	{
224 		testSuiteList = new JProjectTestSuiteList( testSuite );
225 
226 		JPanel p = new JPanel( new BorderLayout() );
227 
228 		p.add( buildTestCaseListToolbar(), BorderLayout.NORTH );
229 		p.add( new JScrollPane( testSuiteList ), BorderLayout.CENTER );
230 
231 		return p;
232 	}
233 
234 	private Component buildTestCaseListToolbar()
235 	{
236 		JXToolBar toolbar = UISupport.createToolbar();
237 		toolbar.add( UISupport.createToolbarButton( SwingActionDelegate.createDelegate(
238 				AddNewTestSuiteAction.SOAPUI_ACTION_ID, project, null, "/testSuite.gif" ) ) );
239 		toolbar.addGlue();
240 		toolbar.add( UISupport.createToolbarButton( new ShowOnlineHelpAction( HelpUrls.TESTSUITELIST_HELP_URL ) ) );
241 		return toolbar;
242 	}
243 
244 	public void release()
245 	{
246 		inspectorPanel.release();
247 		testSuiteListInspectorPanel.release();
248 
249 		setupGroovyEditor.release();
250 		tearDownGroovyEditor.release();
251 
252 		testRunLog.release();
253 		project.removeProjectRunListener( testSuiteRunListener );
254 		project.removeProjectListener( testSuiteListener );
255 	}
256 
257 	protected void runProject()
258 	{
259 		projectRunner = project.run( new StringToObjectMap(), true );
260 	}
261 
262 	protected void beforeRun()
263 	{
264 		runAction.setEnabled( false );
265 		cancelAction.setEnabled( true );
266 		testSuiteList.setEnabled( false );
267 		progressBar.setForeground( Color.GREEN.darker() );
268 	}
269 
270 	protected void afterRun()
271 	{
272 		runAction.setEnabled( true );
273 		cancelAction.setEnabled( false );
274 		testSuiteList.setEnabled( true );
275 
276 		progressBar.setString( projectRunner.getStatus().toString() );
277 		progressBar.setForeground( projectRunner.isFailed() ? Color.RED : Color.GREEN.darker() );
278 	}
279 
280 	private final class InternalProjectListener extends ProjectListenerAdapter
281 	{
282 		public void testSuiteAdded( TestSuite testSuite )
283 		{
284 			runAction.setEnabled( project.getTestSuiteCount() > 0 );
285 		}
286 
287 		public void testSuiteRemoved( TestSuite testSuite )
288 		{
289 			runAction.setEnabled( project.getTestSuiteCount() > 0 );
290 		}
291 	}
292 
293 	private class RunAction extends AbstractAction
294 	{
295 		public RunAction()
296 		{
297 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_testcase.gif" ) );
298 			putValue( Action.SHORT_DESCRIPTION, "Runs the selected TestCases" );
299 		}
300 
301 		public void actionPerformed( ActionEvent e )
302 		{
303 			runProject();
304 		}
305 	}
306 
307 	private class CancelAction extends AbstractAction
308 	{
309 		public CancelAction()
310 		{
311 			putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/stop_testcase.gif" ) );
312 			putValue( Action.SHORT_DESCRIPTION, "Cancels ongoing TestCase runs" );
313 		}
314 
315 		public void actionPerformed( ActionEvent e )
316 		{
317 			projectRunner.cancel( "Cancelled from UI" );
318 		}
319 	}
320 
321 	private class SetupScriptGroovyEditorModel extends AbstractGroovyEditorModel
322 	{
323 		public SetupScriptGroovyEditorModel()
324 		{
325 			super( new String[] { "log", "runner", "context", "project" }, project, "Setup" );
326 		}
327 
328 		public String getScript()
329 		{
330 			return project.getBeforeRunScript();
331 		}
332 
333 		public void setScript( String text )
334 		{
335 			project.setBeforeRunScript( text );
336 		}
337 
338 		@Override
339 		public Action createRunAction()
340 		{
341 			return new AbstractAction()
342 			{
343 
344 				public void actionPerformed( ActionEvent e )
345 				{
346 					try
347 					{
348 						MockProjectRunner runner = new MockProjectRunner( project );
349 						project.runBeforeRunScript( ( ProjectRunContext )runner.getRunContext(), runner );
350 					}
351 					catch( Exception e1 )
352 					{
353 						UISupport.showErrorMessage( e1 );
354 					}
355 				}
356 			};
357 		}
358 	}
359 
360 	private class TearDownScriptGroovyEditorModel extends AbstractGroovyEditorModel
361 	{
362 		public TearDownScriptGroovyEditorModel()
363 		{
364 			super( new String[] { "log", "runner", "context", "project" }, project, "TearDown" );
365 		}
366 
367 		public String getScript()
368 		{
369 			return project.getAfterRunScript();
370 		}
371 
372 		public void setScript( String text )
373 		{
374 			project.setAfterRunScript( text );
375 		}
376 
377 		@Override
378 		public Action createRunAction()
379 		{
380 			return new AbstractAction()
381 			{
382 
383 				public void actionPerformed( ActionEvent e )
384 				{
385 					try
386 					{
387 						MockProjectRunner runner = new MockProjectRunner( project );
388 						project.runAfterRunScript( ( ProjectRunContext )runner.getRunContext(), runner );
389 					}
390 					catch( Exception e1 )
391 					{
392 						UISupport.showErrorMessage( e1 );
393 					}
394 				}
395 			};
396 		}
397 	}
398 
399 	private class InternalTestSuiteRunListener implements ProjectRunListener
400 	{
401 		private TestRunLogTestSuiteRunListener runLogListener;
402 		private int finishCount;
403 
404 		public void afterRun( ProjectRunner testScenarioRunner, ProjectRunContext runContext )
405 		{
406 			if( testScenarioRunner != projectRunner )
407 				return;
408 
409 			WsdlProjectTestSuitesTabPanel.this.afterRun();
410 		}
411 
412 		public void afterTestSuite( ProjectRunner testScenarioRunner, ProjectRunContext runContext,
413 				TestSuiteRunner testRunner )
414 		{
415 			if( testScenarioRunner != projectRunner )
416 				return;
417 			
418 			progressBar.setValue( ++finishCount );
419 
420 			if( project.getRunType() == TestSuiteRunType.SEQUENTIAL )
421 				testRunner.getTestSuite().removeTestSuiteRunListener( runLogListener );
422 		}
423 
424 		public void beforeRun( ProjectRunner testScenarioRunner, ProjectRunContext runContext )
425 		{
426 			if( testScenarioRunner != projectRunner )
427 				return;
428 
429 			WsdlProjectTestSuitesTabPanel.this.beforeRun();
430 
431 			testSuiteList.reset();
432 
433 			progressBar.setMaximum( project.getTestSuiteCount() );
434 			progressBar.setValue( 0 );
435 			progressBar.setString( "" );
436 			finishCount = 0;
437 
438 			if( runLogListener == null )
439 				runLogListener = new TestRunLogTestSuiteRunListener( testRunLog, false );
440 
441 			testRunLog.clear();
442 
443 			if( project.getRunType() == TestSuiteRunType.PARALLEL )
444 				testRunLog.addText( "<log disabled during parallell execution>" );
445 		}
446 
447 		public void beforeTestSuite( ProjectRunner testScenarioRunner, ProjectRunContext runContext,
448 				TestSuite testRunnable )
449 		{
450 			if( testScenarioRunner != projectRunner )
451 				return;
452 
453 			progressBar.setString( "Running " + testRunnable.getName() );
454 
455 			if( project.getRunType() == TestSuiteRunType.SEQUENTIAL )
456 				testRunnable.addTestSuiteRunListener( runLogListener );
457 		}
458 	}
459 }