1
2
3
4
5
6
7
8
9
10
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.awt.event.MouseAdapter;
20 import java.awt.event.MouseEvent;
21 import java.beans.PropertyChangeEvent;
22 import java.beans.PropertyChangeListener;
23 import java.text.SimpleDateFormat;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Date;
27 import java.util.List;
28
29 import javax.swing.AbstractAction;
30 import javax.swing.AbstractListModel;
31 import javax.swing.Action;
32 import javax.swing.BorderFactory;
33 import javax.swing.JButton;
34 import javax.swing.JComponent;
35 import javax.swing.JInternalFrame;
36 import javax.swing.JLabel;
37 import javax.swing.JList;
38 import javax.swing.JMenu;
39 import javax.swing.JOptionPane;
40 import javax.swing.JPanel;
41 import javax.swing.JPopupMenu;
42 import javax.swing.JProgressBar;
43 import javax.swing.JScrollPane;
44 import javax.swing.JSplitPane;
45 import javax.swing.JTabbedPane;
46 import javax.swing.ListCellRenderer;
47 import javax.swing.ListSelectionModel;
48 import javax.swing.event.PopupMenuEvent;
49 import javax.swing.event.PopupMenuListener;
50
51 import com.eviware.soapui.SoapUI;
52 import com.eviware.soapui.impl.wsdl.WsdlTestCase;
53 import com.eviware.soapui.impl.wsdl.WsdlTestStep;
54 import com.eviware.soapui.impl.wsdl.panels.testcase.actions.SetCredentialsAction;
55 import com.eviware.soapui.impl.wsdl.panels.testcase.actions.SetEndpointAction;
56 import com.eviware.soapui.impl.wsdl.teststeps.WsdlAssertion;
57 import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequest;
58 import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStep;
59 import com.eviware.soapui.model.DesktopPanel;
60 import com.eviware.soapui.model.ModelItem;
61 import com.eviware.soapui.model.support.TestRunListenerAdapter;
62 import com.eviware.soapui.model.support.TestSuiteListenerAdapter;
63 import com.eviware.soapui.model.testsuite.TestRunner;
64 import com.eviware.soapui.model.testsuite.TestStep;
65 import com.eviware.soapui.support.UISupport;
66 import com.jgoodies.forms.builder.ButtonBarBuilder;
67
68 /***
69 * WsdlTestCase desktop panel
70 *
71 * @author Ole.Matzura
72 */
73
74 public class WsdlTestCaseDesktopPanel extends JPanel implements DesktopPanel
75 {
76 private JTabbedPane tabbedPane;
77 final WsdlTestCase testCase;
78 private JProgressBar progressBar;
79 private TestStepListModel testStepListModel;
80 private JList testStepList;
81 private JList testLogList;
82 private LogListModel logListModel;
83 private InternalTestRunListener testRunListener = new InternalTestRunListener();
84 private JButton runButton;
85 private JPopupMenu testListPopup;
86 private MoveStepDownAction moveStepDownAction;
87 private MoveStepUpAction moveStepUpAction;
88 private JButton cancelButton;
89 private TestRunner runner;
90 private JButton setEndpointButton;
91 private JMenu insertStepMenu;
92 private JButton setCredentialsButton;
93
94 public WsdlTestCaseDesktopPanel(WsdlTestCase testCase)
95 {
96 super(new BorderLayout());
97 this.testCase = testCase;
98
99 testCase.addTestRunListener( testRunListener );
100 buildUI();
101 setPreferredSize( new Dimension( 250, 500 ));
102 }
103
104 private void buildUI()
105 {
106 JPanel panel = new JPanel( new BorderLayout() );
107
108 panel.add( buildToolbar(), BorderLayout.PAGE_START );
109 panel.add( buildRunnerBar(), BorderLayout.CENTER );
110
111 add( panel, BorderLayout.NORTH );
112
113 JSplitPane splitPane = UISupport.createVerticalSplit();
114 JScrollPane scrollPane = new JScrollPane( buildTestStepList() );
115 scrollPane.setBorder( BorderFactory.createTitledBorder( BorderFactory.createEmptyBorder(), "Test Steps"));
116 splitPane.setTopComponent( scrollPane);
117 splitPane.setBottomComponent( buildTestLog() );
118 splitPane.setDividerLocation( 0.5 );
119 splitPane.setDividerLocation( 200 );
120
121 add( splitPane, BorderLayout.CENTER );
122 add( new JLabel( "--"), BorderLayout.PAGE_END );
123 }
124
125 private Component buildTestLog()
126 {
127 logListModel = new LogListModel();
128 testLogList = new JList( logListModel );
129 testLogList.setCellRenderer( new TestLogCellRenderer() );
130
131 JScrollPane scrollPane = new JScrollPane( testLogList );
132 scrollPane.setBorder( BorderFactory.createTitledBorder( BorderFactory.createEmptyBorder(), "Test Log"));
133 return scrollPane;
134 }
135
136 private Component buildTestStepList()
137 {
138 testStepListModel = new TestStepListModel();
139 testStepList = new JList( testStepListModel );
140 testStepList.setCellRenderer( new TestStepCellRenderer() );
141 testStepList.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
142
143 testStepList.addMouseListener( new StepListMouseListener() );
144 testListPopup = new JPopupMenu();
145
146 testListPopup.addSeparator();
147 insertStepMenu = new JMenu( "Insert step");
148 insertStepMenu.add( new InsertTransferValuesStepAction() );
149
150 testListPopup.add( insertStepMenu );
151 testListPopup.addSeparator();
152 moveStepDownAction = new MoveStepDownAction();
153 testListPopup.add( moveStepDownAction );
154 moveStepUpAction = new MoveStepUpAction();
155 testListPopup.add( moveStepUpAction );
156
157 testListPopup.addPopupMenuListener( new StepListPopupMenuListener(testCase));
158 testStepList.setComponentPopupMenu( testListPopup );
159
160 return testStepList;
161 }
162
163 private Component buildToolbar()
164 {
165 ButtonBarBuilder builder = new ButtonBarBuilder();
166 runButton = new JButton( new RunTestCaseAction());
167 runButton.setPreferredSize( new Dimension(24, 24 ));
168 cancelButton = new JButton( new CancelRunTestCaseAction() );
169 cancelButton.setPreferredSize( new Dimension(24, 24 ));
170 cancelButton.setEnabled( false );
171 setCredentialsButton = new JButton( new SetCredentialsAction( testCase ));
172 setCredentialsButton.setPreferredSize( new Dimension(24, 24 ));
173 setEndpointButton = new JButton( new SetEndpointAction( testCase ));
174 setEndpointButton.setPreferredSize( new Dimension(24, 24 ));
175
176 builder.addFixed( runButton );
177 builder.addRelatedGap();
178 builder.addFixed( cancelButton );
179 builder.addGlue();
180 builder.addFixed( setCredentialsButton );
181 builder.addRelatedGap();
182 builder.addFixed( setEndpointButton );
183
184 builder.setBorder( BorderFactory.createEmptyBorder( 5, 5, 5, 5 ));
185
186 return builder.getPanel();
187 }
188
189 private Component buildRunnerBar()
190 {
191 progressBar = new JProgressBar( 0, testCase.getTestStepCount() );
192 progressBar.setValue( 0 );
193 progressBar.setStringPainted( true );
194 progressBar.setBorder( BorderFactory.createEmptyBorder( 10, 10, 10, 10 ));
195
196 return progressBar;
197 }
198
199 private final class StepListPopupMenuListener implements PopupMenuListener
200 {
201 private StepListPopupMenuListener(WsdlTestCase case1)
202 {
203 super();
204 }
205
206 public void popupMenuWillBecomeVisible(PopupMenuEvent e)
207 {
208 while( testListPopup.getComponentCount() > 5 )
209 testListPopup.remove( 0 );
210
211 int ix = testStepList.getSelectedIndex();
212
213 if( ix == -1 )
214 {
215 insertStepMenu.setEnabled( false );
216 moveStepDownAction.setEnabled( false );
217 moveStepUpAction.setEnabled( false );
218 return;
219 }
220
221 insertStepMenu.setEnabled( true );
222 moveStepUpAction.setEnabled( ix > 0 );
223 moveStepDownAction.setEnabled( ix > -1 && ix < testCase.getTestStepCount()-1 );
224
225 TestStep testStep = (TestStep) testCase.getTestStepAt( ix );
226 Action[] actions = testStep.getActions();
227
228 for (int i = 0; i < actions.length; i++)
229 {
230 testListPopup.insert( actions[i],i );
231 }
232 }
233
234 public void popupMenuWillBecomeInvisible(PopupMenuEvent e)
235 {
236
237
238 }
239
240 public void popupMenuCanceled(PopupMenuEvent e)
241 {
242
243
244 }
245 }
246
247 private final class StepListMouseListener extends MouseAdapter
248 {
249 public void mouseClicked(MouseEvent e)
250 {
251 if( e.getClickCount() < 2 ) return;
252 ModelItem modelItem = (ModelItem) testStepList.getSelectedValue();
253 if( modelItem == null ) return;
254
255 JInternalFrame frame = SoapUI.getInstance().showTab( testCase );
256
257 JInternalFrame requestFrame = SoapUI.getInstance().showTab( modelItem );
258 if( requestFrame != null )
259 {
260 requestFrame.reshape(frame.getX() + frame.getWidth(), frame.getY(),
261 requestFrame.getWidth(), requestFrame.getHeight());
262 }
263 }
264 }
265
266 private class TestStepCellRenderer extends JLabel implements ListCellRenderer
267 {
268 public Component getListCellRendererComponent(
269 JList list,
270 Object value,
271 int index,
272 boolean isSelected,
273 boolean cellHasFocus)
274 {
275 WsdlTestStep testStep = (WsdlTestStep) value;
276 setText( testStep.getName() );
277
278 setIcon( testStep.getIcon() );
279
280 if (isSelected)
281 {
282 setBackground(list.getSelectionBackground());
283 setForeground(list.getSelectionForeground());
284 }
285 else
286 {
287 setBackground(list.getBackground());
288 setForeground(list.getForeground());
289 }
290
291 setEnabled(list.isEnabled());
292 setFont(list.getFont());
293 setOpaque(true);
294 setBorder( BorderFactory.createEmptyBorder(3, 3, 3, 3));
295
296
297 return this;
298 }
299 }
300
301 private class TestStepListModel extends AbstractListModel implements PropertyChangeListener
302 {
303 private TestStepListTestSuiteListener testStepListTestSuiteListener = new TestStepListTestSuiteListener();
304
305 public TestStepListModel()
306 {
307 for( int c = 0; c < getSize(); c++ )
308 testCase.getTestStepAt( c ).addPropertyChangeListener( this );
309
310 testCase.getTestSuite().addTestSuiteListener( testStepListTestSuiteListener );
311 }
312
313 public int getSize()
314 {
315 return testCase.getTestStepCount();
316 }
317
318 public Object getElementAt(int index)
319 {
320 return testCase.getTestStepAt( index );
321 }
322
323 public void propertyChange(PropertyChangeEvent arg0)
324 {
325 int ix = testCase.getIndexOfTestStep( (TestStep)arg0.getSource() );
326 if( ix == -1 ) return;
327
328 fireContentsChanged( this, ix, ix );
329 }
330
331 public void release()
332 {
333 testCase.getTestSuite().removeTestSuiteListener( testStepListTestSuiteListener );
334
335 for( int c = 0; c < getSize(); c++ )
336 testCase.getTestStepAt( c ).removePropertyChangeListener( this );
337 }
338
339 private class TestStepListTestSuiteListener extends TestSuiteListenerAdapter
340 {
341 public void testStepAdded(TestStep testStep, int ix)
342 {
343 testStep.addPropertyChangeListener( TestStepListModel.this );
344 fireIntervalAdded( TestStepListModel.this, ix, ix );
345 }
346
347 public void testStepRemoved(TestStep testStep, int ix)
348 {
349 testStep.removePropertyChangeListener( TestStepListModel.this );
350 fireIntervalRemoved( TestStepListModel.this, ix, ix );
351 }
352 }
353 }
354
355 public class InternalTestRunListener extends TestRunListenerAdapter
356 {
357 private long stepStart;
358 private long testStartTime;
359 private SimpleDateFormat dateFormat;
360
361 public InternalTestRunListener()
362 {
363 dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
364 }
365
366 public boolean beforeRun(TestRunner testRunner)
367 {
368 runButton.setEnabled( false );
369 cancelButton.setEnabled( true );
370 testStepList.setEnabled( false );
371 testStepList.setSelectedIndex( -1 );
372 progressBar.getModel().setMaximum( testRunner.getTestCase().getTestStepCount() );
373 logListModel.clear();
374
375 for( int c = 0; c < testCase.getTestStepCount(); c++ )
376 {
377 testCase.getTestStepAt( c ).prepare( testRunner );
378 }
379
380 testStartTime = System.currentTimeMillis();
381 logListModel.addText( "Test started at " + dateFormat.format( new Date( testStartTime )) );
382 return true;
383 }
384
385 public boolean beforeStep(TestRunner testRunner)
386 {
387 TestStep testStep = testRunner.getCurrentStep();
388 testStepList.setSelectedValue( testStep, true );
389 progressBar.setString( testStep.getName() );
390 progressBar.setValue( testRunner.getCurrentStepIndex() );
391
392 stepStart = System.currentTimeMillis();
393 return true;
394 }
395
396 public void afterRun(TestRunner testRunner)
397 {
398 long endTime = System.currentTimeMillis();
399
400 progressBar.setValue( testRunner.getCurrentStepIndex() );
401 runButton.setEnabled( true );
402 cancelButton.setEnabled( false );
403 testStepList.setEnabled( true );
404
405 if( testRunner.getStatus() == TestRunner.Status.CANCELED )
406 logListModel.addText( "Test canceled, time taken = " + (endTime-testStartTime));
407 else
408 logListModel.addText( "Test finished, time taken = " + (endTime-testStartTime));
409 runner = null;
410 }
411
412 public boolean afterStep(TestRunner testRunner)
413 {
414 TestStep testStep = testRunner.getCurrentStep();
415 logListModel.addTestStep( "Step " + (1+testRunner.getCurrentStepIndex()) + " : " +
416 testStep.getName() + " took " + (System.currentTimeMillis()-stepStart) + " ms", testStep );
417
418 if( testStep instanceof WsdlTestRequestStep )
419 {
420 WsdlTestRequest testRequest = ((WsdlTestRequestStep)testStep).getTestRequest();
421 for( int c = 0; c < testRequest.getAssertionCount(); c++ )
422 {
423 WsdlAssertion assertion = testRequest.getAssertionAt( c );
424 if( assertion.getStatus() == WsdlAssertion.AssertionStatus.FAILED )
425 {
426 logListModel.addAssertion( assertion );
427 }
428 }
429 }
430
431 return true;
432 }
433 }
434
435 private class LogListModel extends AbstractListModel
436 {
437 private List<Object> items = new ArrayList<Object>();
438
439 public void addText( String msg )
440 {
441 items.add( msg );
442 fireIntervalAdded( this, items.size()-1, items.size() );
443 }
444
445 public void addTestStep( String msg, TestStep testStep )
446 {
447 items.add( new TestStepLogItem( testStep, msg ));
448 fireIntervalAdded( this, items.size()-1, items.size() );
449 }
450
451 public void addAssertion( WsdlAssertion assertion )
452 {
453 int sz = items.size();
454 items.add( assertion );
455 items.addAll( Arrays.asList(assertion.getErrors()) );
456
457 fireIntervalAdded( this, sz, items.size() );
458 }
459
460 public void clear()
461 {
462 int sz = getSize();
463 items.clear();
464 fireIntervalRemoved( this, 0, sz );
465 }
466
467 public int getSize()
468 {
469 return items.size();
470 }
471
472 public Object getElementAt(int arg0)
473 {
474 return items.get( arg0 );
475 }}
476
477 private class TestLogCellRenderer extends JLabel implements ListCellRenderer
478 {
479 public Component getListCellRendererComponent(
480 JList list,
481 Object value,
482 int index,
483 boolean isSelected,
484 boolean cellHasFocus)
485 {
486 setIcon( null );
487
488 if( value instanceof String )
489 {
490 setText( value.toString() );
491 }
492 else if( value instanceof WsdlAssertion )
493 {
494 WsdlAssertion assertion = (WsdlAssertion) value;
495 setIcon( assertion.getIcon() );
496 setText( assertion.getName() + "; " + assertion.getStatus().toString() );
497 }
498 else if( value instanceof AssertionError )
499 {
500 setText( " -> " + ((AssertionError)value).toString() );
501 }
502 else if( value instanceof TestStepLogItem )
503 {
504 TestStepLogItem logItem = (TestStepLogItem) value;
505 setIcon( null );
506 setText( logItem.getMsg() );
507 }
508
509 if (isSelected)
510 {
511 setBackground(list.getSelectionBackground());
512 setForeground(list.getSelectionForeground());
513 }
514 else
515 {
516 setBackground(list.getBackground());
517 setForeground(list.getForeground());
518 }
519
520 setEnabled(list.isEnabled());
521 setFont(list.getFont());
522 setOpaque(true);
523 setBorder( BorderFactory.createEmptyBorder(3, 3, 3, 3));
524
525
526 return this;
527 }
528 }
529
530 private class TestStepLogItem
531 {
532 private final TestStep testStep;
533 private final String msg;
534
535 public TestStepLogItem( TestStep testStep, String msg )
536 {
537 this.testStep = testStep;
538 this.msg = msg;
539 }
540
541 public String getMsg()
542 {
543 return msg;
544 }
545
546 public TestStep getTestStep()
547 {
548 return testStep;
549 }
550 }
551
552 private class MoveStepDownAction extends AbstractAction
553 {
554 public MoveStepDownAction()
555 {
556 super( "Move down" );
557 }
558
559 public void actionPerformed(ActionEvent e)
560 {
561 int ix = testStepList.getSelectedIndex();
562 if( ix == -1 || ix >= testCase.getTestStepCount()-1 ) return;
563
564 testCase.moveStep( ix, 1 );
565 }
566 }
567
568 private class MoveStepUpAction extends AbstractAction
569 {
570 public MoveStepUpAction()
571 {
572 super( "Move up" );
573 }
574
575 public void actionPerformed(ActionEvent e)
576 {
577 int ix = testStepList.getSelectedIndex();
578 if( ix < 1 ) return;
579
580 testCase.moveStep( ix, -1 );
581 }
582 }
583
584 public class RunTestCaseAction extends AbstractAction
585 {
586 public RunTestCaseAction()
587 {
588 putValue( Action.SMALL_ICON, SoapUI.createImageIcon( "/run_testcase.gif"));
589 putValue( Action.SHORT_DESCRIPTION, "Runs this testcase" );
590 }
591
592 public void actionPerformed(ActionEvent e)
593 {
594 runner = testCase.run();
595 }
596 }
597
598 public class CancelRunTestCaseAction extends AbstractAction
599 {
600 public CancelRunTestCaseAction()
601 {
602 putValue( Action.SMALL_ICON, SoapUI.createImageIcon( "/stop_testcase.gif"));
603 putValue( Action.SHORT_DESCRIPTION, "Stops running this testcase" );
604 }
605
606 public void actionPerformed(ActionEvent e)
607 {
608 if( runner != null )
609 runner.cancel();
610 }
611 }
612
613 public class InsertTransferValuesStepAction extends AbstractAction
614 {
615 public InsertTransferValuesStepAction()
616 {
617 super( "Transfer Reponse->Request values" );
618 }
619
620 public void actionPerformed(ActionEvent e)
621 {
622 int ix = testStepList.getSelectedIndex();
623 testCase.addTransferResponseValuesStep( ix );
624 }
625
626 }
627
628 public ModelItem getModelItem()
629 {
630 return testCase;
631 }
632
633 public boolean onClose()
634 {
635 if( runner != null && runner.getStatus() == TestRunner.Status.RUNNING )
636 {
637 int retval = JOptionPane.showConfirmDialog( UISupport.getMainFrame(), "Cancel running TestCase?",
638 "Cancel Run", JOptionPane.YES_NO_CANCEL_OPTION );
639
640 if( retval == JOptionPane.CANCEL_OPTION) return false;
641 if( retval == JOptionPane.YES_OPTION )
642 {
643 runner.cancel();
644 }
645 }
646
647 testCase.removeTestRunListener( testRunListener );
648 testStepListModel.release();
649
650 return true;
651 }
652
653 public JComponent getComponent()
654 {
655 return this;
656 }
657 }