์๋ ํ์ธ์,
์ญ์ฌ ๊ด๋ฆฌ๊ฐ ์์ ํ์ง ์๋ค๊ณ ๋งํ๊ณ ์ถ์ต๋๋ค.
๋ด ์ธก์ ์ด ํ
์คํธ๋ 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
});
});
๋ค. jsdom์ ์์ ํ ์๋ก์ด ์ฐฝ ๊ฐ์ฒด ์์ฑ์ ํฌํจํ๊ธฐ ๋๋ฌธ์ ์์ง ์ผ๋ฐ์ ์ผ๋ก ํ์์ ์ง์ํ์ง ์์ต๋๋ค. ์ด๊ฒ์ ์ฐ๋ฆฌ๊ฐ ํด๊ฒฐ์ ๋ํด ์๊ฐํ๊ธฐ ์์ํ์ง ์์ ์ด๋ ค์ด ์ฅ๊ธฐ ๋ฌธ์ ์ ๋๋ค.
์ด ๊ฒ์๋ฌผ์ ์ฐพ๊ณ ํ
์คํธ๋ฅผ ์๋์ํค๋ ค๋ ์ฌ๋์ ์ํ ํด๊ฒฐ ๋ฐฉ๋ฒ์ Sinon spy
๋ฅผ ์ฌ์ฉํ๊ณ history.pushState
๋๋ history.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);
}
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ด ๊ฒ์๋ฌผ์ ์ฐพ๊ณ ํ ์คํธ๋ฅผ ์๋์ํค๋ ค๋ ์ฌ๋์ ์ํ ํด๊ฒฐ ๋ฐฉ๋ฒ์ Sinon
spy
๋ฅผ ์ฌ์ฉํ๊ณhistory.pushState
๋๋history.replaceState
๋ฉ์๋๋ฅผ ์กฐ๋กฑํ๋ ๊ฒ์ ๋๋ค.