Hallo,
Ich würde sagen, dass die Geschichtsverwaltung nicht vollständig ist.
Dieser Test auf meiner Seite schlägt mit jsdom Version 9.4.1 fehl:
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
});
});
Jawohl. jsdom unterstützt im Allgemeinen noch keine Navigation, da dazu ein völlig neues Fensterobjekt erstellt werden muss. Dies ist ein schwerwiegendes langfristiges Problem, über dessen Lösung wir noch nicht nachgedacht haben.
Eine Problemumgehung für alle, die diesen Beitrag finden und Tests zum Laufen bringen möchten, besteht darin, Sinon spy
zu verwenden und die Methoden history.pushState
oder history.replaceState
zu verspotten.
@ Crobinson42 nicht sicher, ob ich dich verstehe, aber würde das Spotten auch mit dem window.onpopstate helfen?
Hier ist die Problemumgehung, die ich verwende (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);
}
Hilfreichster Kommentar
Eine Problemumgehung für alle, die diesen Beitrag finden und Tests zum Laufen bringen möchten, besteht darin, Sinon
spy
zu verwenden und die Methodenhistory.pushState
oderhistory.replaceState
zu verspotten.