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