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