2

我们已经为我们的 Angular 应用程序启动并运行了业力测试套件。铬的所有测试都是绿色的。现在我必须修复一个在 IE 11 上失败的测试。我得到的异常如下:

TypeError: Object doesn't support this action
       at createEventWithKeycode (http://localhost:9876/_karma_webpack_/main.bundle.js:3574:5)
       at Anonymous function (http://localhost:9876/_karma_webpack_/main.bundle.js:3115:13)
       at Anonymous function (http://localhost:9876/_karma_webpack_/vendor.bundle.js:74994:17)
       at ZoneDelegate.prototype.invoke (http://localhost:9876/_karma_webpack_/polyfills.bundle.js:10531:13)
       at ProxyZoneSpec.prototype.onInvoke (http://localhost:9876/_karma_webpack_/vendor.bundle.js:26806:13)
       at ZoneDelegate.prototype.invoke (http://localhost:9876/_karma_webpack_/polyfills.bundle.js:10531:13)
       at Zone.prototype.run (http://localhost:9876/_karma_webpack_/polyfills.bundle.js:10283:17)
       at Anonymous function (http://localhost:9876/_karma_webpack_/vendor.bundle.js:26503:13)

我的理解是,测试用例是在 angulars TestBed 类的帮助下创建一个用于测试的角度组件。使用一些神奇的代码,我们获取输入组件本身并在其上运行 keydown 事件:

inputComponent.onKeyDownInput(event);

但是当我在 IE 中运行代码时,当我尝试使用以下代码创建事件对象时,异常已经发生:

const event = new KeyboardEvent('keydown', {         //This triggers the exception
    bubbles: true,
    cancelable: true,
    shiftKey: true
  });

KeyboardEvent 对象在类型文件 lib.es6.d.ts 中定义:

declare var KeyboardEvent: {
    prototype: KeyboardEvent;
    new(typeArg: string, eventInitDict?: KeyboardEventInit): KeyboardEvent;
    readonly DOM_KEY_LOCATION_JOYSTICK: number;
    readonly DOM_KEY_LOCATION_LEFT: number;
    readonly DOM_KEY_LOCATION_MOBILE: number;
    readonly DOM_KEY_LOCATION_NUMPAD: number;
    readonly DOM_KEY_LOCATION_RIGHT: number;
    readonly DOM_KEY_LOCATION_STANDARD: number;
}

有人可以说明这个问题吗?请记住,一切都在使用 chrome - 只有 IE 不正常!

4

1 回答 1

2

如果有人遇到这个,我可以让下面的工作

function createKeyEvent(
    key: Key|number = null, options: {type: 'keyup'|'keydown'|'input', bubbles?: boolean, cancelable?: boolean} = {
      type: 'keyup',
      bubbles: true,
      cancelable: true
    }): KeyboardEvent {
  let eventInitDict: any = {bubbles: options.bubbles, cancelable: options.cancelable};
  if (key) {
    eventInitDict.key = String.fromCharCode(key);
  }
  if (key === Key.Shift) {
    eventInitDict.shiftKey = true;
    key = null;
  }
  let event;
  if (isBrowser(['ie10', 'ie11'])) {
    event = document.createEvent('KeyboardEvent') as KeyboardEvent;
    event.initKeyboardEvent(options.type, options.cancelable, options.bubbles, window, key, 0, 0, 0, 0);
  } else {
    event = new KeyboardEvent(options.type, eventInitDict)
  }
  if (key) {
    Object.defineProperties(event, {which: {get: () => key}});
    Object.defineProperties(event, {keyCode: {get: () => key}});
  }

  return event;
}

编辑:添加有关 Key 对象的信息

export enum Key {
  Backspace = 8,
  Tab = 9,
  Enter = 13,
  Shift = 16,
  Escape = 27,
  Space = 32,
  End = 35,
  Home = 36,
  ArrowLeft = 37,
  ArrowUp = 38,
  ArrowRight = 39,
  ArrowDown = 40
}

编辑#2:添加isBrowser功能

export type Browser = 'ie9'|'ie10'|'ie11'|'ie'|'edge'|'chrome'|'safari'|'firefox';

export function getBrowser(ua = window.navigator.userAgent) {
  let browser = 'unknown';

  // IE < 11
  const msie = ua.indexOf('MSIE ');
  if (msie > 0) {
    return 'ie' + parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
  }

  // IE 11
  if (ua.indexOf('Trident/') > 0) {
    let rv = ua.indexOf('rv:');
    return 'ie' + parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
  }

  // Edge
  if (ua.indexOf('Edge/') > 0) {
    return 'edge';
  }

  // Chrome
  if (ua.indexOf('Chrome/') > 0) {
    return 'chrome';
  }

  // Safari
  if (ua.indexOf('Safari/') > 0) {
    return 'safari';
  }

  // Firefox
  if (ua.indexOf('Firefox/') > 0) {
    return 'firefox';
  }

  if (browser === 'unknown') {
    throw new Error('Browser detection failed for: ' + ua);
  }
}

export function isBrowser(browsers: Browser|Browser[], ua = window.navigator.userAgent) {
  let browsersStr = Array.isArray(browsers) ? (browsers as Browser[]).map(x => x.toString()) : [browsers.toString()];
  let browser = getBrowser(ua);

  if (browsersStr.indexOf('ie') > -1 && browser.startsWith('ie')) {
    return true;
  } else {
    return browsersStr.indexOf(browser) > -1;
  }
}
于 2019-01-12T07:35:26.700 回答