| 1 14 package org.eclipse.jdt.internal.junit.ui; 15 16 import java.io.BufferedWriter ; 17 import java.io.File ; 18 import java.io.FileWriter ; 19 import java.io.IOException ; 20 import java.text.DateFormat ; 21 import java.text.MessageFormat ; 22 import java.text.NumberFormat ; 23 import java.text.SimpleDateFormat ; 24 import java.util.Date ; 25 import java.util.Iterator ; 26 import java.util.List ; 27 28 import org.eclipse.core.commands.AbstractHandler; 29 import org.eclipse.core.commands.ExecutionEvent; 30 import org.eclipse.core.commands.ExecutionException; 31 import org.eclipse.core.commands.IHandler; 32 33 import org.eclipse.core.runtime.CoreException; 34 import org.eclipse.core.runtime.IProgressMonitor; 35 import org.eclipse.core.runtime.IStatus; 36 import org.eclipse.core.runtime.Status; 37 import org.eclipse.core.runtime.jobs.ILock; 38 import org.eclipse.core.runtime.jobs.Job; 39 40 import org.eclipse.swt.SWT; 41 import org.eclipse.swt.custom.CLabel; 42 import org.eclipse.swt.custom.SashForm; 43 import org.eclipse.swt.custom.ViewForm; 44 import org.eclipse.swt.dnd.Clipboard; 45 import org.eclipse.swt.events.ControlEvent; 46 import org.eclipse.swt.events.ControlListener; 47 import org.eclipse.swt.graphics.Image; 48 import org.eclipse.swt.graphics.Point; 49 import org.eclipse.swt.layout.GridData; 50 import org.eclipse.swt.layout.GridLayout; 51 import org.eclipse.swt.widgets.Composite; 52 import org.eclipse.swt.widgets.Display; 53 import org.eclipse.swt.widgets.FileDialog; 54 import org.eclipse.swt.widgets.Layout; 55 import org.eclipse.swt.widgets.Shell; 56 import org.eclipse.swt.widgets.ToolBar; 57 58 import org.eclipse.jface.action.Action; 59 import org.eclipse.jface.action.IAction; 60 import org.eclipse.jface.action.IMenuListener; 61 import org.eclipse.jface.action.IMenuManager; 62 import org.eclipse.jface.action.IStatusLineManager; 63 import org.eclipse.jface.action.IToolBarManager; 64 import org.eclipse.jface.action.MenuManager; 65 import org.eclipse.jface.action.Separator; 66 import org.eclipse.jface.dialogs.ErrorDialog; 67 import org.eclipse.jface.dialogs.MessageDialog; 68 import org.eclipse.jface.preference.IPreferenceStore; 69 import org.eclipse.jface.resource.ImageDescriptor; 70 71 import org.eclipse.ui.IActionBars; 72 import org.eclipse.ui.IEditorActionBarContributor; 73 import org.eclipse.ui.IEditorPart; 74 import org.eclipse.ui.IMemento; 75 import org.eclipse.ui.IPartListener2; 76 import org.eclipse.ui.IViewPart; 77 import org.eclipse.ui.IViewSite; 78 import org.eclipse.ui.IWorkbenchActionConstants; 79 import org.eclipse.ui.IWorkbenchPage; 80 import org.eclipse.ui.IWorkbenchPart; 81 import org.eclipse.ui.IWorkbenchPartReference; 82 import org.eclipse.ui.IWorkbenchWindow; 83 import org.eclipse.ui.PartInitException; 84 import org.eclipse.ui.PlatformUI; 85 import org.eclipse.ui.actions.ActionFactory; 86 import org.eclipse.ui.handlers.IHandlerActivation; 87 import org.eclipse.ui.handlers.IHandlerService; 88 import org.eclipse.ui.part.EditorActionBarContributor; 89 import org.eclipse.ui.part.ViewPart; 90 import org.eclipse.ui.progress.IWorkbenchSiteProgressService; 91 import org.eclipse.ui.progress.UIJob; 92 93 import org.eclipse.debug.core.ILaunch; 94 import org.eclipse.debug.core.ILaunchConfiguration; 95 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; 96 97 import org.eclipse.debug.ui.DebugUITools; 98 99 import org.eclipse.jdt.core.ElementChangedEvent; 100 import org.eclipse.jdt.core.IElementChangedListener; 101 import org.eclipse.jdt.core.IJavaElement; 102 import org.eclipse.jdt.core.IJavaElementDelta; 103 import org.eclipse.jdt.core.IJavaProject; 104 import org.eclipse.jdt.core.JavaCore; 105 106 import org.eclipse.jdt.internal.ui.viewsupport.ViewHistory; 107 108 import org.eclipse.jdt.junit.model.ITestElement.Result; 109 110 import org.eclipse.jdt.internal.junit.Messages; 111 import org.eclipse.jdt.internal.junit.launcher.ITestKind; 112 import org.eclipse.jdt.internal.junit.launcher.JUnitLaunchConfigurationConstants; 113 import org.eclipse.jdt.internal.junit.launcher.TestKindRegistry; 114 import org.eclipse.jdt.internal.junit.model.ITestRunSessionListener; 115 import org.eclipse.jdt.internal.junit.model.ITestSessionListener; 116 import org.eclipse.jdt.internal.junit.model.JUnitModel; 117 import org.eclipse.jdt.internal.junit.model.TestCaseElement; 118 import org.eclipse.jdt.internal.junit.model.TestElement; 119 import org.eclipse.jdt.internal.junit.model.TestRunSession; 120 121 124 public class TestRunnerViewPart extends ViewPart { 125 126 public static final String NAME= "org.eclipse.jdt.junit.ResultView"; 128 private static final String RERUN_LAST_COMMAND= "org.eclipse.jdt.junit.junitShortcut.rerunLast"; private static final String RERUN_FAILED_FIRST_COMMAND= "org.eclipse.jdt.junit.junitShortcut.rerunFailedFirst"; 131 static final int REFRESH_INTERVAL= 200; 132 133 static final int LAYOUT_FLAT= 0; 134 static final int LAYOUT_HIERARCHICAL= 1; 135 136 139 protected boolean fAutoScroll = true; 140 144 private int fOrientation= VIEW_ORIENTATION_AUTOMATIC; 145 149 private int fCurrentOrientation; 150 153 private int fLayout= LAYOUT_HIERARCHICAL; 154 155 157 protected JUnitProgressBar fProgressBar; 158 protected ProgressImages fProgressImages; 159 protected Image fViewImage; 160 protected CounterPanel fCounterPanel; 161 protected boolean fShowOnErrorOnly= false; 162 protected Clipboard fClipboard; 163 protected volatile String fInfoMessage; 164 165 private FailureTrace fFailureTrace; 166 167 private TestViewer fTestViewer; 168 171 private boolean fIsDisposed= false; 172 173 176 private Action fNextAction; 177 private Action fPreviousAction; 178 179 private StopAction fStopAction; 180 private JUnitCopyAction fCopyAction; 181 182 private Action fRerunLastTestAction; 183 private IHandlerActivation fRerunLastActivation; 184 private Action fRerunFailedFirstAction; 185 private IHandlerActivation fRerunFailedFirstActivation; 186 187 private Action fFailuresOnlyFilterAction; 188 private ScrollLockAction fScrollLockAction; 189 private ToggleOrientationAction[] fToggleOrientationActions; 190 private ShowTestHierarchyAction fShowTestHierarchyAction; 191 private ActivateOnErrorAction fActivateOnErrorAction; 192 private IMenuListener fViewMenuListener; 193 194 private TestRunSession fTestRunSession; 195 private TestSessionListener fTestSessionListener; 196 197 private RunnerViewHistory fViewHistory; 198 private TestRunSessionListener fTestRunSessionListener; 199 200 final Image fStackViewIcon= TestRunnerViewPart.createImage("eview16/stackframe.gif"); final Image fTestRunOKIcon= TestRunnerViewPart.createImage("eview16/junitsucc.gif"); final Image fTestRunFailIcon= TestRunnerViewPart.createImage("eview16/juniterr.gif"); final Image fTestRunOKDirtyIcon= TestRunnerViewPart.createImage("eview16/junitsuccq.gif"); final Image fTestRunFailDirtyIcon= TestRunnerViewPart.createImage("eview16/juniterrq.gif"); 206 final Image fTestIcon= TestRunnerViewPart.createImage("obj16/test.gif"); final Image fTestOkIcon= TestRunnerViewPart.createImage("obj16/testok.gif"); final Image fTestErrorIcon= TestRunnerViewPart.createImage("obj16/testerr.gif"); final Image fTestFailIcon= TestRunnerViewPart.createImage("obj16/testfail.gif"); final Image fTestRunningIcon= TestRunnerViewPart.createImage("obj16/testrun.gif"); final Image fTestIgnoredIcon= TestRunnerViewPart.createImage("obj16/testignored.gif"); 213 final ImageDescriptor fSuiteIconDescriptor= JUnitPlugin.getImageDescriptor("obj16/tsuite.gif"); final ImageDescriptor fSuiteOkIconDescriptor= JUnitPlugin.getImageDescriptor("obj16/tsuiteok.gif"); final ImageDescriptor fSuiteErrorIconDescriptor= JUnitPlugin.getImageDescriptor("obj16/tsuiteerror.gif"); final ImageDescriptor fSuiteFailIconDescriptor= JUnitPlugin.getImageDescriptor("obj16/tsuitefail.gif"); final ImageDescriptor fSuiteRunningIconDescriptor= JUnitPlugin.getImageDescriptor("obj16/tsuiterun.gif"); 219 final Image fSuiteIcon= fSuiteIconDescriptor.createImage(); 220 final Image fSuiteOkIcon= fSuiteOkIconDescriptor.createImage(); 221 final Image fSuiteErrorIcon= fSuiteErrorIconDescriptor.createImage(); 222 final Image fSuiteFailIcon= fSuiteFailIconDescriptor.createImage(); 223 final Image fSuiteRunningIcon= fSuiteRunningIconDescriptor.createImage(); 224 225 static final String TAG_PAGE= "page"; static final String TAG_RATIO= "ratio"; static final String TAG_TRACEFILTER= "tracefilter"; static final String TAG_ORIENTATION= "orientation"; static final String TAG_SCROLL= "scroll"; 234 static final String TAG_LAYOUT= "layout"; 238 static final String TAG_FAILURES_ONLY= "failuresOnly"; 240 static final int VIEW_ORIENTATION_VERTICAL= 0; 242 static final int VIEW_ORIENTATION_HORIZONTAL= 1; 243 static final int VIEW_ORIENTATION_AUTOMATIC= 2; 244 245 private IMemento fMemento; 246 247 Image fOriginalViewImage; 248 IElementChangedListener fDirtyListener; 249 250 251 private SashForm fSashForm; 253 254 private Composite fCounterComposite; 255 private Composite fParent; 256 257 260 private UpdateUIJob fUpdateJob; 261 262 266 private JUnitIsRunningJob fJUnitIsRunningJob; 267 private ILock fJUnitIsRunningLock; 268 public static final Object FAMILY_JUNIT_RUN = new Object (); 269 270 private IPartListener2 fPartListener= new IPartListener2() { 271 public void partActivated(IWorkbenchPartReference ref) { } 272 public void partBroughtToTop(IWorkbenchPartReference ref) { } 273 public void partInputChanged(IWorkbenchPartReference ref) { } 274 public void partClosed(IWorkbenchPartReference ref) { } 275 public void partDeactivated(IWorkbenchPartReference ref) { } 276 public void partOpened(IWorkbenchPartReference ref) { } 277 278 public void partVisible(IWorkbenchPartReference ref) { 279 if (getSite().getId().equals(ref.getId())) { 280 fPartIsVisible= true; 281 } 282 } 283 284 public void partHidden(IWorkbenchPartReference ref) { 285 if (getSite().getId().equals(ref.getId())) { 286 fPartIsVisible= false; 287 } 288 } 289 }; 290 291 protected boolean fPartIsVisible= false; 292 293 294 private class RunnerViewHistory extends ViewHistory { 295 296 public void configureHistoryListAction(IAction action) { 297 action.setText(JUnitMessages.TestRunnerViewPart_history); 298 } 299 300 public void configureHistoryDropDownAction(IAction action) { 301 action.setToolTipText(JUnitMessages.TestRunnerViewPart_test_run_history); 302 JUnitPlugin.setLocalImageDescriptors(action, "history_list.gif"); } 304 305 public Action getClearAction() { 306 return new ClearAction(); 307 } 308 309 public String getHistoryListDialogTitle() { 310 return JUnitMessages.TestRunnerViewPart_test_runs; 311 } 312 313 public String getHistoryListDialogMessage() { 314 return JUnitMessages.TestRunnerViewPart_select_test_run; 315 } 316 317 public Shell getShell() { 318 return fParent.getShell(); 319 } 320 321 public List getHistoryEntries() { 322 return JUnitPlugin.getModel().getTestRunSessions(); 323 } 324 325 public Object getCurrentEntry() { 326 return fTestRunSession; 327 } 328 329 public void setActiveEntry(Object entry) { 330 TestRunSession deactivatedSession= setActiveTestRunSession((TestRunSession) entry); 331 if (deactivatedSession != null) 332 deactivatedSession.swapOut(); 333 } 334 335 public void setHistoryEntries(List remainingEntries, Object activeEntry) { 336 setActiveTestRunSession((TestRunSession) activeEntry); 337 338 List testRunSessions= JUnitPlugin.getModel().getTestRunSessions(); 339 testRunSessions.removeAll(remainingEntries); 340 for (Iterator iter= testRunSessions.iterator(); iter.hasNext();) { 341 JUnitPlugin.getModel().removeTestRunSession((TestRunSession) iter.next()); 342 } 343 for (Iterator iter= remainingEntries.iterator(); iter.hasNext();) { 344 TestRunSession remaining= (TestRunSession) iter.next(); 345 remaining.swapOut(); 346 } 347 } 348 349 public ImageDescriptor getImageDescriptor(Object element) { 350 TestRunSession session= (TestRunSession) element; 351 if (session.isStopped()) 352 return fSuiteIconDescriptor; 353 354 if (session.isRunning()) 355 return fSuiteRunningIconDescriptor; 356 357 Result result= session.getTestResult(true); 358 if (result == Result.OK) 359 return fSuiteOkIconDescriptor; 360 else if (result == Result.ERROR) 361 return fSuiteErrorIconDescriptor; 362 else if (result == Result.FAILURE) 363 return fSuiteFailIconDescriptor; 364 else 365 return fSuiteIconDescriptor; 366 } 367 368 public String getText(Object element) { 369 TestRunSession session= (TestRunSession) element; 370 if (session.getStartTime() == 0) { 371 return session.getTestRunName(); 372 } else { 373 String startTime= DateFormat.getDateTimeInstance().format(new Date (session.getStartTime())); 374 return Messages.format(JUnitMessages.TestRunnerViewPart_testName_startTime, new Object [] { session.getTestRunName(), startTime }); 375 } 376 } 377 378 public void addMenuEntries(MenuManager manager) { 379 manager.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, new ImportTestRunSessionAction(fParent.getShell())); 380 if (fTestRunSession != null) 381 manager.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, new ExportTestRunSessionAction(fParent.getShell(), fTestRunSession)); 382 } 383 384 public String getMaxEntriesMessage() { 385 return JUnitMessages.TestRunnerViewPart_max_remembered; 386 } 387 388 public int getMaxEntries() { 389 IPreferenceStore store= JUnitPlugin.getDefault().getPreferenceStore(); 390 return store.getInt(JUnitPreferencesConstants.MAX_TEST_RUNS); 391 } 392 393 public void setMaxEntries(int maxEntries) { 394 IPreferenceStore store= JUnitPlugin.getDefault().getPreferenceStore(); 395 store.setValue(JUnitPreferencesConstants.MAX_TEST_RUNS, maxEntries); 396 } 397 } 398 399 private static class ImportTestRunSessionAction extends Action { 400 private final Shell fShell; 401 402 public ImportTestRunSessionAction(Shell shell) { 403 super(JUnitMessages.TestRunnerViewPart_ImportTestRunSessionAction_name); 404 fShell= shell; 405 } 406 407 public void run() { 408 FileDialog importDialog= new FileDialog(fShell, SWT.OPEN); 409 importDialog.setText(JUnitMessages.TestRunnerViewPart_ImportTestRunSessionAction_title); 410 importDialog.setFilterExtensions(new String [] {"*.xml", "*.*"}); String path= importDialog.open(); 412 if (path == null) 413 return; 414 415 File file= new File (path); 417 418 try { 419 JUnitModel.importTestRunSession(file); 420 } catch (CoreException e) { 421 JUnitPlugin.log(e); 422 ErrorDialog.openError(fShell, JUnitMessages.TestRunnerViewPart_ImportTestRunSessionAction_error_title, e.getStatus().getMessage(), e.getStatus()); 423 } 424 } 425 } 426 427 private static class ExportTestRunSessionAction extends Action { 428 private final TestRunSession fTestRunSession; 429 private final Shell fShell; 430 431 public ExportTestRunSessionAction(Shell shell, TestRunSession testRunSession) { 432 super(JUnitMessages.TestRunnerViewPart_ExportTestRunSessionAction_name); 433 fShell= shell; 434 fTestRunSession= testRunSession; 435 } 436 437 public void run() { 438 FileDialog exportDialog= new FileDialog(fShell, SWT.SAVE); 439 exportDialog.setText(JUnitMessages.TestRunnerViewPart_ExportTestRunSessionAction_title); 440 exportDialog.setFileName(getFileName()); 441 exportDialog.setFilterExtensions(new String [] {"*.xml", "*.*"}); String path= exportDialog.open(); 443 if (path == null) 444 return; 445 446 File file= new File (path); 448 449 try { 450 JUnitModel.exportTestRunSession(fTestRunSession, file); 451 } catch (CoreException e) { 452 JUnitPlugin.log(e); 453 ErrorDialog.openError(fShell, JUnitMessages.TestRunnerViewPart_ExportTestRunSessionAction_error_title, e.getStatus().getMessage(), e.getStatus()); 454 } 455 } 456 457 private String getFileName() { 458 String testRunName= fTestRunSession.getTestRunName(); 459 long startTime= fTestRunSession.getStartTime(); 460 if (startTime == 0) 461 return testRunName; 462 463 String isoTime= new SimpleDateFormat ("yyyyMMdd-HHmmss").format(new Date (startTime)); return testRunName + " " + isoTime + ".xml"; } 466 } 467 468 private class TestRunSessionListener implements ITestRunSessionListener { 469 public void sessionAdded(TestRunSession testRunSession) { 470 if (getSite().getWorkbenchWindow() == JUnitPlugin.getActiveWorkbenchWindow()) { 471 TestRunSession deactivatedSession= setActiveTestRunSession(testRunSession); 472 if (deactivatedSession != null) 473 deactivatedSession.swapOut(); 474 String testRunName= fTestRunSession.getTestRunName(); 475 String msg; 476 if (testRunSession.getLaunch() != null) { 477 msg= Messages.format(JUnitMessages.TestRunnerViewPart_Launching, new Object []{ testRunName }); 478 } else { 479 msg= testRunName; 480 } 481 setContentDescription(msg); 482 } 483 } 484 public void sessionRemoved(TestRunSession testRunSession) { 485 if (testRunSession.equals(fTestRunSession)) { 486 List testRunSessions= JUnitPlugin.getModel().getTestRunSessions(); 487 TestRunSession deactivatedSession; 488 if (! testRunSessions.isEmpty()) { 489 deactivatedSession= setActiveTestRunSession((TestRunSession) testRunSessions.get(0)); 490 } else { 491 deactivatedSession= setActiveTestRunSession(null); 492 } 493 if (deactivatedSession != null) 494 deactivatedSession.swapOut(); 495 } 496 } 497 } 498 499 private class TestSessionListener implements ITestSessionListener { 500 public void sessionStarted(){ 501 fTestViewer.registerViewersRefresh(); 502 fShowOnErrorOnly= getShowOnErrorOnly(); 503 504 startUpdateJobs(); 505 506 fStopAction.setEnabled(true); 507 fRerunLastTestAction.setEnabled(true); 508 } 509 510 public void sessionEnded(long elapsedTime){ 511 fTestViewer.registerAutoScrollTarget(null); 512 513 String [] keys= {elapsedTimeAsString(elapsedTime)}; 514 String msg= Messages.format(JUnitMessages.TestRunnerViewPart_message_finish, keys); 515 registerInfoMessage(msg); 516 517 postSyncRunnable(new Runnable () { 518 public void run() { 519 if (isDisposed()) 520 return; 521 fStopAction.setEnabled(lastLaunchIsKeptAlive()); 522 updateRerunFailedFirstAction(); 523 processChangesInUI(); 524 if (hasErrorsOrFailures()) { 525 selectFirstFailure(); 526 } 527 if (fDirtyListener == null) { 528 fDirtyListener= new DirtyListener(); 529 JavaCore.addElementChangedListener(fDirtyListener); 530 } 531 warnOfContentChange(); 532 } 533 }); 534 stopUpdateJobs(); 535 } 536 537 public void sessionStopped(final long elapsedTime) { 538 fTestViewer.registerAutoScrollTarget(null); 539 540 registerInfoMessage(JUnitMessages.TestRunnerViewPart_message_stopped); 541 handleStopped(); 542 } 543 544 public void sessionTerminated() { 545 fTestViewer.registerAutoScrollTarget(null); 546 547 registerInfoMessage(JUnitMessages.TestRunnerViewPart_message_terminated); 548 handleStopped(); 549 } 550 551 public void runningBegins() { 552 if (!fShowOnErrorOnly) 553 postShowTestResultsView(); 554 } 555 556 public void testStarted(TestCaseElement testCaseElement) { 557 fTestViewer.registerAutoScrollTarget(testCaseElement); 558 fTestViewer.registerViewerUpdate(testCaseElement); 559 560 String className= testCaseElement.getClassName(); 561 String method= testCaseElement.getTestMethodName(); 562 String status= Messages.format(JUnitMessages.TestRunnerViewPart_message_started, new String [] { className, method }); 563 registerInfoMessage(status); 564 } 565 566 public void testFailed(TestElement testElement, TestElement.Status status, String trace, String expected, String actual) { 567 if (isAutoScroll()) { 568 fTestViewer.registerFailedForAutoScroll(testElement); 569 } 570 fTestViewer.registerViewerUpdate(testElement); 571 572 if (fShowOnErrorOnly && (getErrorsPlusFailures() == 1)) 574 postShowTestResultsView(); 575 576 } 585 586 public void testEnded(TestCaseElement testCaseElement){ 587 fTestViewer.registerViewerUpdate(testCaseElement); 588 } 589 590 public void testReran(TestCaseElement testCaseElement, TestElement.Status status, String trace, String expectedResult, String actualResult) { 591 fTestViewer.registerViewerUpdate(testCaseElement); postSyncProcessChanges(); 593 showFailure(testCaseElement); 594 } 595 596 public void testAdded(TestElement testElement) { 597 fTestViewer.registerTestAdded(testElement); 598 } 599 600 public boolean acceptsSwapToDisk() { 601 return false; 602 } 603 } 604 605 private class UpdateUIJob extends UIJob { 606 private boolean fRunning= true; 607 608 public UpdateUIJob(String name) { 609 super(name); 610 setSystem(true); 611 } 612 public IStatus runInUIThread(IProgressMonitor monitor) { 613 if (!isDisposed()) { 614 processChangesInUI(); 615 } 616 schedule(REFRESH_INTERVAL); 617 return Status.OK_STATUS; 618 } 619 620 public void stop() { 621 fRunning= false; 622 } 623 public boolean shouldSchedule() { 624 return fRunning; 625 } 626 } 627 628 private class JUnitIsRunningJob extends Job { 629 public JUnitIsRunningJob(String name) { 630 super(name); 631 setSystem(true); 632 } 633 public IStatus run(IProgressMonitor monitor) { 634 fJUnitIsRunningLock.acquire(); 636 return Status.OK_STATUS; 637 } 638 public boolean belongsTo(Object family) { 639 return family == TestRunnerViewPart.FAMILY_JUNIT_RUN; 640 } 641 } 642 643 private class ClearAction extends Action { 644 public ClearAction() { 645 setText(JUnitMessages.TestRunnerViewPart_clear_history_label); 646 647 boolean enabled= false; 648 List testRunSessions= JUnitPlugin.getModel().getTestRunSessions(); 649 for (Iterator iter= testRunSessions.iterator(); iter.hasNext();) { 650 TestRunSession testRunSession= (TestRunSession) iter.next(); 651 if (! testRunSession.isRunning()) { 652 enabled= true; 653 break; 654 } 655 } 656 setEnabled(enabled); 657 } 658 659 public void run() { 660 List testRunSessions= getRunningSessions(); 661 Object first= testRunSessions.isEmpty() ? null : testRunSessions.get(0); 662 fViewHistory.setHistoryEntries(testRunSessions, first); 663 } 664 665 private List getRunningSessions() { 666 List testRunSessions= JUnitPlugin.getModel().getTestRunSessions(); 667 for (Iterator iter= testRunSessions.iterator(); iter.hasNext();) { 668 TestRunSession testRunSession= (TestRunSession) iter.next(); 669 if (! testRunSession.isRunning()) { 670 iter.remove(); 671 } 672 } 673 return testRunSessions; 674 } 675 } 676 677 private class StopAction extends Action { 678 public StopAction() { 679 setText(JUnitMessages.TestRunnerViewPart_stopaction_text); 680 setToolTipText(JUnitMessages.TestRunnerViewPart_stopaction_tooltip); 681 JUnitPlugin.setLocalImageDescriptors(this, "stop.gif"); } 683 684 public void run() { 685 stopTest(); 686 setEnabled(fal
|