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 }