View Javadoc

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