Jsdom: 浏览器历史 pushState/onpopstate/window.location 管理不善

创建于 2016-07-17  ·  4评论  ·  资料来源: jsdom/jsdom

你好,

我想说历史管理不完整。
我这边的这个测试在 jsdom 版本 9.4.1 上失败了:

    describe('jsdom history management', () => {
        before(() => {
        // Init DOM with a fake document
        // <base> and uri (initial uri) allow to do pushState in jsdom
            jsdom.env({
                html: `
                 <html>
                     <head>
                         <base href="http://localhost:8080/"></base>
                     </head>
                  </html>
                `,
                url: 'http://localhost:8080/',
                done(err, window) {
                    global.window = window;
                    global.document = window.document;
                    window.console = global.console;
                }
            });
        });

        it('location not updated', () => {
            window.history.pushState({}, 'route1', '/route1');
            assert(window.location.pathname === '/route1'); // this test is OK
            window.history.back();
            assert(window.location.pathname === '/'); // this test fails pathname still with value '/route1'
        });

        it('onpopstate not called', () => {
            window.onpopstate = () => { };
            const spy_onpopstate = sinon.spy(window, 'onpopstate');
            window.history.pushState({}, 'route1', '/route1');
            window.history.back();
            window.history.forward();
            assert(spy_onpopstate.called);// this test fails as well
        });
    });

最有用的评论

对于任何发现这篇文章并希望测试正常工作的人来说,一个解决方法是使用 Sinon spy并模拟history.pushStatehistory.replaceState方法。

所有4条评论

是的。 jsdom 通常还不支持导航,因为这涉及创建一个全新的窗口对象。 这是一个我们尚未开始考虑解决的长期难题。

对于任何发现这篇文章并希望测试正常工作的人来说,一个解决方法是使用 Sinon spy并模拟history.pushStatehistory.replaceState方法。

@crobinson42不确定我是否明白你的意思,但对 window.onpopstate 也有帮助吗?

这是我使用的解决方法(TypeScript):

function firePopstateOnRoute(window: DOMWindow): void {
  const { history } = window;
  const originalBack = history.back;
  const originalForwards = history.forward;

  (history as unknown as {__proto__: History})['__proto__'].back = function patchedBack(this: History, ...args: Parameters<History['back']>): void {
    originalBack.apply(this, args);

    window.dispatchEvent(new PopStateEvent('popstate'));
  };

  (history as unknown as {__proto__: History}).__proto__.forward = function patchedForward(this: History, ...args: Parameters<History['forward']>): void {
    originalForwards.apply(this, args);

    window.dispatchEvent(new PopStateEvent('popstate'));
  };
}

export function mockBrowser(): void {
  const jsdom = new JSDOM('');
  const { window } = jsdom;

  firePopstateOnRoute(window);
}
此页面是否有帮助?
0 / 5 - 0 等级

相关问题

kilianc picture kilianc  ·  4评论

vsemozhetbyt picture vsemozhetbyt  ·  4评论

Progyan1997 picture Progyan1997  ·  3评论

lehni picture lehni  ·  4评论

jhegedus42 picture jhegedus42  ·  4评论