diff --git a/core/modules/simpletest/simpletest.css b/core/modules/simpletest/simpletest.css
index 86bd04b..793e357 100644
--- a/core/modules/simpletest/simpletest.css
+++ b/core/modules/simpletest/simpletest.css
@@ -87,3 +87,74 @@ a.simpletest-collapse:hover {
   position: relative;
   z-index: 1000;
 }
+
+.assertion-navigation {
+  position: fixed;
+  border: 3px double #FFACAC;
+  border-right-width: 0;
+  border-radius: 10px 0 0 10px;
+  width: 44px;
+  opacity: 0.7;
+  right: 0px;
+  top: 50%;
+  margin-top: -25px;
+}
+
+#previous-fail,
+#next-fail {
+  background-color: #FFACAC;
+  opacity:0.7;
+  height: 20px;
+  width: 20px;
+  margin: 5px;
+  border-radius: 5px;
+  padding: 5px;
+  cursor: pointer;
+  border: 2px solid transparent;
+  transition: background-color 1s;
+  -moz-transition: background-color 1s;
+  -webkit-transition: background-color 1s;
+  -o-transition: background-color 1s;
+}
+#previous-fail div,
+#next-fail div {
+  width: 0;
+  height: 0;
+  border-left: 7px solid transparent;
+  border-right: 7px solid transparent;
+  margin: 3px;
+}
+#previous-fail:hover,
+#next-fail:hover {
+  background-color: #F44646;
+}
+#previous-fail:active,
+#next-fail:active {
+  opacity: 1;
+}
+#previous-fail div {
+  border-bottom: 16px solid #E00;
+}
+#next-fail div {
+  border-top: 16px solid #E00;
+}
+#previous-fail:hover div,
+#next-fail:hover div {
+  border-top-color: #FFF;
+  border-bottom-color: #FFF;
+  transition:  border-top-color 1s, border-bottom-color;
+  -moz-transition:  border-top-color 1s, border-bottom-color;
+  -webkit-transition:  border-top-color 1s, border-bottom-color;
+  -o-transition:  border-top-color 1s, border-bottom-color;
+}
+
+.disabled,
+.disabled:active,
+.disabled:hover {
+  opacity:0.7 !important;
+  background-color: #FFACAC !important;
+}
+.disabled:active div,
+.disabled div {
+  border-color: transparent !important;
+}
diff --git a/core/modules/simpletest/simpletest.js b/core/modules/simpletest/simpletest.js
index 7048966..7b9dea8 100644
--- a/core/modules/simpletest/simpletest.js
+++ b/core/modules/simpletest/simpletest.js
@@ -99,4 +99,59 @@ Drupal.behaviors.simpleTestSelectAll = {
   }
 };
 
+/**
+ * Scrolling between fail messages.
+ */
+Drupal.behaviors.simpleTestScrollFails = {
+  attach: function (context, settings) {
+
+    if (settings.simpletest) {
+      var fails = settings.simpletest.fails;
+    }
+    else {
+      return;
+    }
+
+    $('body').append('<div class="assertion-navigation"><div id="previous-fail"><div></div></div><div id="next-fail"><div></div></div></div>');
+    var currentFail = -1;
+
+    var disableScroll = function() {
+      $('.assertion-navigation .disabled').removeClass('disabled');
+      if (!fails[currentFail - 1]) {
+        $('#previous-fail').addClass('disabled')
+      }
+      if (!fails[currentFail + 1]) {
+        $('#next-fail').addClass('disabled')
+      }
+    };
+
+    var scroll = function() {
+      // Use sticky table header position as offset.
+      var offset = $('.sticky-header').css('top');
+      var message = $("#message-" + fails[currentFail]);
+      offset = offset ? parseInt(offset) : 100;
+      $('html, body').animate({scrollTop: message.offset().top - offset - 25}, 500);
+      message.effect("highlight", {color:'red'}, 1000);
+      disableScroll();
+    };
+
+    disableScroll();
+
+    $("#next-fail").click(function() {
+      if (fails[currentFail + 1]) {
+        currentFail++;
+        scroll();
+      }
+    });
+
+    $("#previous-fail").click(function() {
+      if (fails[currentFail - 1]) {
+        currentFail--;
+        scroll();
+      }
+    });
+
+  }
+};
+
 })(jQuery);
diff --git a/core/modules/simpletest/simpletest.pages.inc b/core/modules/simpletest/simpletest.pages.inc
index 4fb908d..ed6ac4b 100644
--- a/core/modules/simpletest/simpletest.pages.inc
+++ b/core/modules/simpletest/simpletest.pages.inc
@@ -216,7 +216,7 @@ function simpletest_result_form($form, &$form_state, $test_id) {
   }
 
   // Load all classes and include CSS.
-  drupal_add_css(drupal_get_path('module', 'simpletest') . '/simpletest.css');
+  $form['#attached']['library'][] = array('simpletest', 'drupal.simpletest');
 
   // Keep track of which test cases passed or failed.
   $filter = array(
@@ -241,7 +241,7 @@ function simpletest_result_form($form, &$form_state, $test_id) {
 
   // Cycle through each test group.
   $header = array(t('Message'), t('Group'), t('Filename'), t('Line'), t('Function'), array('colspan' => 2, 'data' => t('Status')));
-  $form['result']['results'] = array();
+  $form['result']['results'] = $fails = array();
   foreach ($results as $group => $assertions) {
     // Create group details with summary information.
     $info = call_user_func(array($group, 'getInfo'));
@@ -268,7 +268,10 @@ function simpletest_result_form($form, &$form_state, $test_id) {
       if ($assertion->message_group == 'Debug') {
         $class = 'simpletest-debug';
       }
-      $rows[] = array('data' => $row, 'class' => array($class));
+      $rows[] = array('data' => $row, 'class' => array($class), 'id' => 'message-' . $assertion->message_id);
+      if ($assertion->status == 'fail') {
+        $fails[] = $assertion->message_id;
+      }
 
       $group_summary['#' . $assertion->status]++;
       $form['result']['summary']['#' . $assertion->status]++;
@@ -331,10 +334,17 @@ function simpletest_result_form($form, &$form_state, $test_id) {
     '#href' => 'admin/config/development/testing',
   );
 
+  $form['#attached']['js'][] = array(
+    'data' => array('simpletest' => array('fails' => $fails)),
+    'type' => 'setting',
+  );
+  $form['#attached']['library'][] = array('system', 'jquery.effects.highlight');
+
   if (is_numeric($test_id)) {
     simpletest_clean_results_table($test_id);
   }
 
+
   return $form;
 }
 
