web-dev-qa-db-ja.com

エラーの修正方法:実装されていません:ナビゲーション(ハッシュの変更を除く)

_window.location.href_を含むファイルの単体テストを実装しています。チェックする必要があります。

私のjestバージョンは_22.0.4_です。ノードバージョン> = 10でテストを実行すると、すべて問題ありません。

しかし、_v8.9.3_で実行すると、このエラーが発生します

_console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29
      Error: Not implemented: navigation (except hash changes)
_

私はそれについて知りません。私は多くのページを検索して、ここで何が起こったのかを理解するための解決策またはこれに関するヒントを見つけました。

[更新]-私はソースコードを詳しく調べましたが、このエラーはjsdomによるものだと思います。

_at module.exports (webapp/node_modules/jsdom/lib/jsdom/browser/not-implemented.js:9:17)
at navigateFetch (webapp/node_modules/jsdom/lib/jsdom/living/window/navigation.js:74:3)
_

navigation.jsファイル

_exports.evaluateJavaScriptURL = (window, urlRecord) => {
  const urlString = whatwgURL.serializeURL(urlRecord);
  const scriptSource = whatwgURL.percentDecode(Buffer.from(urlString)).toString();
  if (window._runScripts === "dangerously") {
    try {
      return window.eval(scriptSource);
    } catch (e) {
      reportException(window, e, urlString);
    }
  }
  return undefined;
};
exports.navigate = (window, newURL, flags) => {
  // This is NOT a spec-compliant implementation of navigation in any way. It implements a few selective steps that
  // are Nice for jsdom users, regarding hash changes and JavaScript URLs. Full navigation support is being worked on
  // and will likely require some additional hooks to be implemented.

  const document = idlUtils.implForWrapper(window._document);
  const currentURL = document._URL;

  if (!flags.reloadTriggered && urlEquals(currentURL, newURL, { excludeFragments: true })) {
    if (newURL.fragment !== currentURL.fragment) {
      navigateToFragment(window, newURL, flags);
    }
    return;
  }

  // NOT IMPLEMENTED: Prompt to unload the active document of browsingContext.

  // NOT IMPLEMENTED: form submission algorithm
  // const navigationType = 'other';

  // NOT IMPLEMENTED: if resource is a response...
  if (newURL.scheme === "javascript") {
    window.setTimeout(() => {
      const result = exports.evaluateJavaScriptURL(window, newURL);
      if (typeof result === "string") {
        notImplemented("string results from 'javascript:' URLs", window);
      }
    }, 0);
    return;
  }
  navigateFetch(window);
};
_

not-implemented.js

_module.exports = function (nameForErrorMessage, window) {
  if (!window) {
    // Do nothing for window-less documents.
    return;
  }

  const error = new Error(`Not implemented: ${nameForErrorMessage}`);
  error.type = "not implemented";

  window._virtualConsole.emit("jsdomError", error);
};
_

これらのファイルにいくつかの奇妙なロジックが見られます。

  1. const scriptSource = whatwgURL.percentDecode(Buffer.from(urlString)).toString();
  2. 次に文字列をチェックしてエラーを返します
10
Hoang Tran Son

単体テストの1つで同様の問題に直面しました。これを解決するために私がやったことは次のとおりです。

  • _window.location.href_をwindow.location.assign(url) OR window.location.replace(url)に置き換えます

  • JSDOMは、実装されていない_window.location.assign_についてstillと文句を言います。

    Error: Not implemented: navigation (except hash changes)

  • 次に、window.assign(url)またはwindow.replace(url)を含む上記のコンポーネント/関数のユニットテストの1つで、次を定義します。

    • sinon.stub(window.location, 'assign');
    • sinon.stub(window.location, 'replace');
    • 必ずsinon _import sinon from 'sinon';_をインポートしてください


うまくいけば、これで私と同じように問題が解決されます。


JSDOMがError: Not implemented: navigation (except hash changes)について不平を言うのは、JSDOMが_window.alert_、_window.location.assign_などのメソッドを実装していないためです。


参照:

14
Mihir Kale

jestのみで機能する代替バージョン:

let assignMock = jest.fn();

delete window.location;
window.location = { assign: assignMock };

afterEach(() => {
  assignMock.mockClear();
});

参照: https://remarkablemark.org/blog/2018/11/17/mock-window-location/

1
blah