Solution to fix your Angular 5 – TestBed bug of XMLHttpRequest cannot load ng:///DynamicTestModule/- 修复 Angular 5- TestBed 以调试测试用例

You may have encountered this error before.

XMLHttpRequest cannot load ng:///DynamicTestModule/******.ngfactory.js. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

Paul here to offer the best solution I’ve figured out today.

// Modify this file node_modules/@angular/core/esm5/testing.js#L1150
// with following content to see the underlying errors
var initComponent = function () {
          try {
            var componentRef = componentFactory.create(Injector.NULL, [], "#" + rootElId, _this._moduleRef);

          } catch (e) {
            console.error(e.stack && e.stack.replace(/http:.*_karma_webpack_\/webpack:/g,'webpack:///.'));
            debugger
          }
            return new ComponentFixture(componentRef, ngZone, autoDetect);
        };

Now the real errors are shown in Chrome Debugger, and it’s tracable by clicking the link in the trace info, in this example, **-list.component.ts, Line#80

Same idea for node_modules/zone.js/dist/zone.js

// file node_modules/zone.js/dist/zone.js, L#657
    api.onUnhandledError = function (e) {
        if (api.showUncaughtError()) {
            var rejection = e && e.rejection;
            var getStack = function(stack) {
              return stack && stack.replace(/http:.*_karma_webpack_\/webpack:/g,'webpack:///.')
            }
            if (e) {
              e.stack = getStack(e.stack)
            }

            if (rejection) {
              rejection.stack = getStack(rejection.stack)
              console.error('Unhandled Promise rejection:', rejection instanceof Error ? rejection.message : rejection, '; Zone:', e.zone.name, '; Task:', e.task && e.task.source, '; Value:', rejection, rejection instanceof Error ? rejection.stack : undefined);
            }
            else {
                console.error(e);
            }
        }
    };

And node_modules/karma/static/debug.js, L#21

  for (var i = 0; i < result.log.length; i++) {
    // Printing error without losing stack trace
    (function (err) {
      setTimeout(function () {
        var getStack = function(stack) {
          return stack && stack.replace(/http:.*_karma_webpack_\/webpack:/g,'webpack:///.')
        }
        if (err) {
          if (err.stack) {
            err.stack = getStack(err.stack)

          } else {
            err = getStack(err)
          }
        }
        window.console.error(err)
      })
    })(result.log[i])
  }

And node_modules/@angular/core/esm5/core.js, L#15050

function callWithDebugContext(action, fn, self, args) {
    var /** @type {?} */ oldAction = _currentAction;
    var /** @type {?} */ oldView = _currentView;
    var /** @type {?} */ oldNodeIndex = _currentNodeIndex;
    try {
        _currentAction = action;
        var /** @type {?} */ result = fn.apply(self, args);
        _currentView = oldView;
        _currentNodeIndex = oldNodeIndex;
        _currentAction = oldAction;
        return result;
    }
    catch (/** @type {?} */ e) {

      var getStack = function(stack) {
        return stack && stack.replace(/http:.*_karma_webpack_\/webpack:/g,'webpack:///.')
      }
      if (e) {
        if (e.stack) {
          e.stack = getStack(e.stack)

        } else {
          e = getStack(e)
        }
      }

        if (isViewDebugError(e) || !_currentView) {
            throw e;
        }
        throw viewWrappedDebugError(e, /** @type {?} */ ((getCurrentDebugContext())));
    }
}

And if you want more precise control, still zone.js, find keyword throw er, replace all with the same idea.

Fix your bug and the error should not be shown again.

And, no need to disable sourcemap anymore.

# ./karma-webstorm.conf.js is the customized karma settings that is used to debug your case, not required
karmaConfig=./karma-webstorm.conf.js
./node_modules/@angular/cli/bin/ng test --config=${karmaConfig} --log-level error

with fit() set for the case of being debugged.

Enjoy.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.