testConsecutiveErrors() {
    const mm = getModuleManager({'s': []});
    mm.setLoader(createUnsuccessfulLoader(mm, 500));

    // Register an error callback for consecutive failures.
    let firedLoadFailed = false;
    mm.registerCallback(
        ModuleManager.CallbackType.ERROR, (callbackType, id, cause) => {
          assertEquals(
              'Failure cause was not as expected',
              ModuleLoadFailure.Type.CONSECUTIVE_FAILURES, cause.type);
          firedLoadFailed = true;
        });

    mm.preloadModule('s');
    assertFalse('module "s" should not be loaded (0)', mm.isModuleLoaded('s'));

    // Fail twice.
    for (let i = 0; i < 2; i++) {
      clock.tick(5 + mm.getBackOff_());
      assertFalse(
          'module "s" should not be loaded (1)', mm.isModuleLoaded('s'));
      assertFalse('should not fire failed callback (1)', firedLoadFailed);
    }

    // Fail a third time and check that the callback is fired.
    clock.tick(5 + mm.getBackOff_());
    assertFalse('module "s" should not be loaded (2)', mm.isModuleLoaded('s'));
    assertTrue('should have fired failed callback', firedLoadFailed);

    // Check that it doesn't attempt to load the module anymore after it has
    // failed.
    let triedLoad = false;
    mm.setLoader({
      loadModules: function(ids, moduleInfoMap, {onError, onSuccess}) {
        triedLoad = true;
      },
    });

    // Also reset the failed callback flag and make sure it isn't called
    // again.
    firedLoadFailed = false;
    clock.tick(10 + mm.getBackOff_());
    assertFalse('module "s" should not be loaded (3)', mm.isModuleLoaded('s'));
    assertFalse('No more loads should have been tried', triedLoad);
    assertFalse(
        'The load failed callback should be fired only once', firedLoadFailed);
  }
Test consecutive errors in loading modules.
     @suppress {missingProperties} suppression added to enable type checking