@Override
    public boolean test() throws Exception {
      ICondition selectionRangeCondition = ConditionHelpers.selectionRange(fSelectionRange);
      if (!selectionRangeCondition.test()) {
        fFailureMessage = selectionRangeCondition.getFailureMessage();
        return false;
      }
      @NonNull
      TmfTimeRange curWindowRange =
          TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange();
      if (!curWindowRange.contains(fVisibleTime)) {
        fFailureMessage =
            "Current window range " + curWindowRange + " does not contain " + fVisibleTime;
        return false;
      }

      if (fView.isDirty()) {
        fFailureMessage = "Time graph is dirty";
        return false;
      }
      return true;
    }
  /** Test tool bar buttons "Follow CPU Forward" and "Follow CPU Backward" */
  @Test
  public void testToolBarFollowCPUForwardBackward() {
    /* change window range to 10 ms */
    TmfTimeRange range =
        new TmfTimeRange(
            START_TIME, START_TIME.normalize(10000000L, ITmfTimestamp.NANOSECOND_SCALE));
    TmfSignalManager.dispatchSignal(new TmfWindowRangeUpdatedSignal(this, range));
    fBot.waitUntil(ConditionHelpers.windowRange(range));

    /* set selection to trace start time */
    TmfSignalManager.dispatchSignal(new TmfSelectionRangeUpdatedSignal(this, START_TIME));
    fBot.waitUntil(ConditionHelpers.selectionRange(new TmfTimeRange(START_TIME, START_TIME)));

    /* select first item */
    final SWTBotTree tree = fViewBot.bot().tree();
    tree.pressShortcut(Keystrokes.HOME);

    /* set focus on time graph */
    final TimeGraphControl timegraph =
        fViewBot.bot().widget(WidgetOfType.widgetOfType(TimeGraphControl.class));
    UIThreadRunnable.syncExec(
        new VoidResult() {
          @Override
          public void run() {
            timegraph.setFocus();
          }
        });

    /* click "Follow CPU Forward" 3 times */
    timeGraphIsReadyCondition(new TmfTimeRange(START_TIME, START_TIME));
    fViewBot.toolbarButton(FOLLOW_CPU_FORWARD).click();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME1, TID1_TIME1));
    fViewBot.toolbarButton(FOLLOW_CPU_FORWARD).click();
    timeGraphIsReadyCondition(new TmfTimeRange(TID2_TIME1, TID2_TIME1));
    fViewBot.toolbarButton(FOLLOW_CPU_FORWARD).click();
    timeGraphIsReadyCondition(new TmfTimeRange(TID2_TIME2, TID2_TIME2));
    fBot.waitUntil(ConditionHelpers.selectionRange(new TmfTimeRange(TID2_TIME2, TID2_TIME2)));
    fBot.waitUntil(ConditionHelpers.treeSelectionContains(tree, 1, "2"));
    assertTrue(
        TmfTraceManager.getInstance()
            .getCurrentTraceContext()
            .getWindowRange()
            .contains(TID2_TIME2));

    /* shift-click "Follow CPU Forward" 3 times */
    fViewBot.toolbarButton(FOLLOW_CPU_FORWARD).click(SWT.SHIFT);
    timeGraphIsReadyCondition(new TmfTimeRange(TID2_TIME2, TID2_TIME3));
    fViewBot.toolbarButton(FOLLOW_CPU_FORWARD).click(SWT.SHIFT);
    timeGraphIsReadyCondition(new TmfTimeRange(TID2_TIME2, TID2_TIME4));
    fViewBot.toolbarButton(FOLLOW_CPU_FORWARD).click(SWT.SHIFT);
    timeGraphIsReadyCondition(new TmfTimeRange(TID2_TIME2, TID2_TIME4));
    fBot.waitUntil(ConditionHelpers.selectionRange(new TmfTimeRange(TID2_TIME2, TID5_TIME1)));
    fBot.waitUntil(ConditionHelpers.treeSelectionContains(tree, 1, "5"));
    assertTrue(
        TmfTraceManager.getInstance()
            .getCurrentTraceContext()
            .getWindowRange()
            .contains(TID5_TIME1));

    /* shift-click "Follow CPU Backward" 4 times */
    fViewBot.toolbarButton(FOLLOW_CPU_BACKWARD).click(SWT.SHIFT);
    timeGraphIsReadyCondition(new TmfTimeRange(TID2_TIME2, TID2_TIME4));
    fViewBot.toolbarButton(FOLLOW_CPU_BACKWARD).click(SWT.SHIFT);
    timeGraphIsReadyCondition(new TmfTimeRange(TID2_TIME2, TID2_TIME3));
    fViewBot.toolbarButton(FOLLOW_CPU_BACKWARD).click(SWT.SHIFT);
    timeGraphIsReadyCondition(new TmfTimeRange(TID2_TIME2, TID2_TIME2));
    fViewBot.toolbarButton(FOLLOW_CPU_BACKWARD).click(SWT.SHIFT);
    timeGraphIsReadyCondition(new TmfTimeRange(TID2_TIME2, TID2_TIME1));
    fBot.waitUntil(ConditionHelpers.selectionRange(new TmfTimeRange(TID2_TIME2, TID2_TIME1)));
    fBot.waitUntil(ConditionHelpers.treeSelectionContains(tree, 1, "2"));
    assertTrue(
        TmfTraceManager.getInstance()
            .getCurrentTraceContext()
            .getWindowRange()
            .contains(TID2_TIME1));

    /* click "Follow CPU Forward" 2 times */
    fViewBot.toolbarButton(FOLLOW_CPU_FORWARD).click();
    timeGraphIsReadyCondition(new TmfTimeRange(TID2_TIME2, TID2_TIME2));
    fViewBot.toolbarButton(FOLLOW_CPU_FORWARD).click();
    timeGraphIsReadyCondition(new TmfTimeRange(TID2_TIME3, TID2_TIME3));
    fBot.waitUntil(ConditionHelpers.selectionRange(new TmfTimeRange(TID2_TIME3, TID2_TIME3)));
    fBot.waitUntil(ConditionHelpers.treeSelectionContains(tree, 1, "2"));
    assertTrue(
        TmfTraceManager.getInstance()
            .getCurrentTraceContext()
            .getWindowRange()
            .contains(TID2_TIME3));

    /* shift-click "Follow CPU Backward" 3 times */
    fViewBot.toolbarButton(FOLLOW_CPU_BACKWARD).click(SWT.SHIFT);
    timeGraphIsReadyCondition(new TmfTimeRange(TID2_TIME3, TID2_TIME2));
    fViewBot.toolbarButton(FOLLOW_CPU_BACKWARD).click(SWT.SHIFT);
    timeGraphIsReadyCondition(new TmfTimeRange(TID2_TIME3, TID2_TIME1));
    fViewBot.toolbarButton(FOLLOW_CPU_BACKWARD).click(SWT.SHIFT);
    timeGraphIsReadyCondition(new TmfTimeRange(TID2_TIME3, TID1_TIME1));
    fBot.waitUntil(ConditionHelpers.selectionRange(new TmfTimeRange(TID2_TIME3, TID1_TIME1)));
    fBot.waitUntil(ConditionHelpers.treeSelectionContains(tree, 1, "1"));
    assertTrue(
        TmfTraceManager.getInstance()
            .getCurrentTraceContext()
            .getWindowRange()
            .contains(TID1_TIME1));

    /* shift-click "Follow CPU Forward" 4 times */
    fViewBot.toolbarButton(FOLLOW_CPU_FORWARD).click(SWT.SHIFT);
    timeGraphIsReadyCondition(new TmfTimeRange(TID2_TIME3, TID2_TIME1));
    fViewBot.toolbarButton(FOLLOW_CPU_FORWARD).click(SWT.SHIFT);
    timeGraphIsReadyCondition(new TmfTimeRange(TID2_TIME3, TID2_TIME2));
    fViewBot.toolbarButton(FOLLOW_CPU_FORWARD).click(SWT.SHIFT);
    timeGraphIsReadyCondition(new TmfTimeRange(TID2_TIME3, TID2_TIME3));
    fViewBot.toolbarButton(FOLLOW_CPU_FORWARD).click(SWT.SHIFT);
    timeGraphIsReadyCondition(new TmfTimeRange(TID2_TIME3, TID2_TIME4));
    fBot.waitUntil(ConditionHelpers.selectionRange(new TmfTimeRange(TID2_TIME3, TID2_TIME4)));
    fBot.waitUntil(ConditionHelpers.treeSelectionContains(tree, 1, "2"));
    assertTrue(
        TmfTraceManager.getInstance()
            .getCurrentTraceContext()
            .getWindowRange()
            .contains(TID2_TIME4));

    /* click "Follow CPU Backward" 5 times */
    fViewBot.toolbarButton(FOLLOW_CPU_BACKWARD).click();
    timeGraphIsReadyCondition(new TmfTimeRange(TID2_TIME3, TID2_TIME3));
    fViewBot.toolbarButton(FOLLOW_CPU_BACKWARD).click();
    timeGraphIsReadyCondition(new TmfTimeRange(TID2_TIME2, TID2_TIME2));
    fViewBot.toolbarButton(FOLLOW_CPU_BACKWARD).click();
    timeGraphIsReadyCondition(new TmfTimeRange(TID2_TIME1, TID2_TIME1));
    fViewBot.toolbarButton(FOLLOW_CPU_BACKWARD).click();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME1, TID1_TIME1));
    fViewBot.toolbarButton(FOLLOW_CPU_BACKWARD).click();
    timeGraphIsReadyCondition(new TmfTimeRange(START_TIME, START_TIME));
    fBot.waitUntil(ConditionHelpers.selectionRange(new TmfTimeRange(START_TIME, START_TIME)));
    assertTrue(
        TmfTraceManager.getInstance()
            .getCurrentTraceContext()
            .getWindowRange()
            .contains(START_TIME));
  }
  private void testNextPreviousEvent(
      Runnable selectNext,
      Runnable shiftSelectNext,
      Runnable selectPrevious,
      Runnable shiftSelectPrevious) {
    /* change window range to 10 ms */
    TmfTimeRange range =
        new TmfTimeRange(
            START_TIME, START_TIME.normalize(10000000L, ITmfTimestamp.NANOSECOND_SCALE));
    TmfSignalManager.dispatchSignal(new TmfWindowRangeUpdatedSignal(this, range));
    fBot.waitUntil(ConditionHelpers.windowRange(range));

    /* set selection to trace start time */
    TmfSignalManager.dispatchSignal(new TmfSelectionRangeUpdatedSignal(this, START_TIME));
    timeGraphIsReadyCondition(new TmfTimeRange(START_TIME, START_TIME));

    /* select first item */
    final SWTBotTree tree = fViewBot.bot().tree();
    tree.pressShortcut(Keystrokes.HOME);

    /* set focus on time graph */
    final TimeGraphControl timegraph =
        fViewBot.bot().widget(WidgetOfType.widgetOfType(TimeGraphControl.class));
    UIThreadRunnable.syncExec(
        new VoidResult() {
          @Override
          public void run() {
            timegraph.setFocus();
          }
        });

    /* click "Select Next Event" 3 times */
    selectNext.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME1, TID1_TIME1));
    selectNext.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME2, TID1_TIME2));
    selectNext.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME3, TID1_TIME3));
    fBot.waitUntil(ConditionHelpers.selectionRange(new TmfTimeRange(TID1_TIME3, TID1_TIME3)));
    assertTrue(
        TmfTraceManager.getInstance()
            .getCurrentTraceContext()
            .getWindowRange()
            .contains(TID1_TIME3));

    /* shift-click "Select Next Event" 3 times */
    shiftSelectNext.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME3, TID1_TIME4));
    shiftSelectNext.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME3, TID1_TIME5));
    shiftSelectNext.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME3, TID1_TIME6));
    fBot.waitUntil(ConditionHelpers.selectionRange(new TmfTimeRange(TID1_TIME3, TID1_TIME6)));
    assertTrue(
        TmfTraceManager.getInstance()
            .getCurrentTraceContext()
            .getWindowRange()
            .contains(TID1_TIME6));

    /* shift-click "Select Previous Event" 4 times */
    shiftSelectPrevious.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME3, TID1_TIME5));
    shiftSelectPrevious.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME3, TID1_TIME4));
    shiftSelectPrevious.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME3, TID1_TIME3));
    shiftSelectPrevious.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME3, TID1_TIME2));
    fBot.waitUntil(ConditionHelpers.selectionRange(new TmfTimeRange(TID1_TIME3, TID1_TIME2)));
    assertTrue(
        TmfTraceManager.getInstance()
            .getCurrentTraceContext()
            .getWindowRange()
            .contains(TID1_TIME2));

    /* click "Select Next Event" 2 times */
    selectNext.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME3, TID1_TIME3));
    selectNext.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME4, TID1_TIME4));
    fBot.waitUntil(ConditionHelpers.selectionRange(new TmfTimeRange(TID1_TIME4, TID1_TIME4)));
    assertTrue(
        TmfTraceManager.getInstance()
            .getCurrentTraceContext()
            .getWindowRange()
            .contains(TID1_TIME4));

    /* shift-click "Select Previous Event" 3 times */
    shiftSelectPrevious.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME4, TID1_TIME3));
    shiftSelectPrevious.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME4, TID1_TIME2));
    shiftSelectPrevious.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME4, TID1_TIME1));
    fBot.waitUntil(ConditionHelpers.selectionRange(new TmfTimeRange(TID1_TIME4, TID1_TIME1)));
    assertTrue(
        TmfTraceManager.getInstance()
            .getCurrentTraceContext()
            .getWindowRange()
            .contains(TID1_TIME1));

    /* shift-click "Select Next Event" 4 times */
    shiftSelectNext.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME4, TID1_TIME2));
    shiftSelectNext.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME4, TID1_TIME3));
    shiftSelectNext.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME4, TID1_TIME4));
    shiftSelectNext.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME4, TID1_TIME5));
    fBot.waitUntil(ConditionHelpers.selectionRange(new TmfTimeRange(TID1_TIME4, TID1_TIME5)));
    assertTrue(
        TmfTraceManager.getInstance()
            .getCurrentTraceContext()
            .getWindowRange()
            .contains(TID1_TIME5));

    /* click "Select Previous Event" 5 times */
    selectPrevious.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME4, TID1_TIME4));
    selectPrevious.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME3, TID1_TIME3));
    selectPrevious.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME2, TID1_TIME2));
    selectPrevious.run();
    timeGraphIsReadyCondition(new TmfTimeRange(TID1_TIME1, TID1_TIME1));
    selectPrevious.run();
    timeGraphIsReadyCondition(new TmfTimeRange(START_TIME, START_TIME));
    fBot.waitUntil(ConditionHelpers.selectionRange(new TmfTimeRange(START_TIME, START_TIME)));
    assertTrue(
        TmfTraceManager.getInstance()
            .getCurrentTraceContext()
            .getWindowRange()
            .contains(START_TIME));
  }