æè¿jest
ïŒããã¯ã°ã©ãŠã³ãã§jsdomã䜿çšïŒãããŒãžã§ã³21.2.0ãã22.0.6ã«ã¢ããã°ã¬ãŒãããåŸããšã©ãŒãçºçãå§ããŸããïŒ "Error: Not implemented:" navigation
ç§ã®ã³ãŒãã¯window.location
äŸåããŠããããã¹ãã§äœ¿çšããŸãã
beforeEach(() => {
window.location.href = `/ms/submission/?mybib`;
window.location.search = '?mybib';
});
æ°ããããŒãžã§ã³ã®jsdomã䜿çšããŠwindow.location.search
å€ãå®çŸ©ããæ¹æ³ã¯ãããŸããïŒ
ç§ããã®ãšã©ãŒãçºçããŸã
Error: Not implemented: navigation (except hash changes)
at module.exports (...\node_modules\jsdom\lib\jsdom\browser\not-implemented.js:9:17)
at navigateFetch (...\node_modules\jsdom\lib\jsdom\living\window\navigation.js:74:3)
jsdomã¯ããã²ãŒã·ã§ã³ããµããŒãããŠããªããããwindow.location.hrefãªã©ãèšå®ãããšãã®ã¡ãã»ãŒãžã衚瀺ãããŸãã Jestã以åã«ãããã®ã¡ãã»ãŒãžãæå¶ããŠããã®ãããããšãäœãªã®ãã¯ããããŸããã
ããã¯ãããããã¹ãã§ä¿®æ£ããå¿ èŠããããã®ã§ãããã©ãŠã¶ã§ãããã®ãã¹ããå®è¡ããŠããå ŽåãããŒãžãæ°ããURLã«ç§»åãããšããã¹ãã©ã³ããŒãå®å šã«å¹ãé£ã°ããããã¹ãã衚瀺ãããªããªãããã§ããçµæã 代ããã«jsdomã§ã¯ãã³ã³ãœãŒã«ã«ã¡ãã»ãŒãžãåºåããã ãã§ãããå¿ èŠã«å¿ããŠç¡èŠããããšãããã¹ããä¿®æ£ããŠããå€ãã®ç°å¢ã§ããé©åã«æ©èœããããã«ããããšãã§ããŸãã
ãšã«ãããç§ã¯äººã ã®ããã«ããã«é¢ããããã¥ã¡ã³ãããã£ãšè¿œå ãããã®ã§ãããããããšã远跡ããããã«ãã®åé¡ãéãããŸãŸã«ããŠãããŸãã
ããªããèšã£ãŠããããšãå®å šã«ç解ããŠãã ããã æè¿ã®Jest22ã®æŽæ°ã¯JSDOM9ãã11IIRCã«ç§»è¡ããããã9.xã§ã®åäœã¯ããªãç°ãªã£ãŠããå¯èœæ§ããããŸãã
ããã¯ããŠãããå¥ã®ããŒãžãããŒããããšããç¹ã§æäœãè¡ããªãããã«ããããã«ãäœããã®ãã©ã°ã䜿çšããŠJSDOMã«ããã²ãŒã·ã§ã³ãå®è£ ããããšãæãã§ããŸãïŒHTML5ããã·ã¥ã¹ããŒããšåæ§ã®ç²Ÿç¥ã§ïŒãã©ã€ãã©ãªã¯ãã¹ãç®çã§éåžžã«äžè¬çã«äœ¿çšãããŸããããã£ãŠããããã颚å€ãããªèŠæ±ã§ãããé »ç¹ã«äœ¿çšãããŸãã
jsdomãšãã©ãŠã¶ã§ãã¹ããç°ãªãæ¹æ³ã§å®è¡ãããã©ã°ãè¿œå ããå¿ èŠã¯ãªããšæããŸãã ãããããšããã©ãŠã¶ã§ã³ã³ãã³ããå£ããŠïŒããšãã°ããã¹ãã§çºçããŠãããšèŠãªãããã¢ã¯ã·ã§ã³ãå®è¡ãã代ããã«ããŠãŒã¶ãŒãä»ã®ããŒãžã«ãªãã€ã¬ã¯ãããå¯èœæ§ããããŸãïŒãæ°ä»ããªãå¯èœæ§ããããŸãã
ãã®å ŽåãçŸåšã®ããŒãžã³ã³ããã¹ããã¢ã³ããŒãããªãããšãé€ããŠãäœãå€ãããŸããã ç§ã¯ãŸã window.location.href
ãæŽæ°ãããããšãæåŸ
ããŠããŸãã
@domenicåãåé¡ãçºçããŠããŠã window.location
ãèšå®ããã¢ããªã§JSDOMãã»ããã¢ããããããã®äœããã®ãã¹ããã©ã¯ãã£ã¹ããããã©ããçåã«æã£ãŠããŸããã ç§ã®ç¥ãéããJSDOMã¯window.location
ãèšå®ããããšãããšãšã©ãŒãã¹ããŒãã window.location.href
ãèšå®ããããšãããšãšã©ãŒããã°ã«èšé²ããŸãããmdnã§ãã®2ã€ã¯å矩èªã§ããå¿
èŠããããšèªãã§ããŸãã ã¹ã¿ãããããå¥ã®æ¹æ³ã§å ŽæãæŽæ°ããå¿
èŠããããŸããïŒ
å©ããŠãããŠããããšãð
èªåã®è³ªåãžã®åçãæçš¿ãããŠãã ããð
window.location = url;
ãšwindow.location.href = url;
ã®äœ¿çšæ³ãåçŽã«çœ®ãæããŸã
window.location.assign(url);
ãããŠãç§ã®ãã¹ãã§ã¯ã次ã®ããšãè¡ããŸããã
sinon.stub(window.location, 'assign');
expect(window.location.assign).to.have.been.calledWith(url);
é åã®ããã«æ©èœããŸã-ãããä»ã®èª°ãã®å©ãã«ãªãããšãé¡ã£ãŠããŸãð
ããã¯ç®±ããåºããŠããã«æ©èœããã¯ãã ãšããããšã«åæããŸãã FBã§window.location
ãã¢ãã¯ããŸãããããã¯jsdomã®History
å®è£
ãšç«¶åããŸãã
å°ããªããŒã ãšããŠãjsdomã§ããã²ãŒã·ã§ã³ãé©åã«å®è£ ããããã«ç§ãã¡ã«äŸåããŠãããã倧ããªãããžã§ã¯ãããã®å©ãã確ãã«æè¬ããŸãã
èå³ã®ããæ¹ã¯ã httpsïŒ//github.com/jsdom/jsdom/pull/1913ããå§ãããšããã§ãããã
èãããã解決çã¯ãåäœãã¹ãã§window
ãªããžã§ã¯ãã®äŸåæ§æ³šå
¥/ã¢ãã¯ã«äŸåããããšã§ãã
äœãã®ãããªãã®ïŒ
it('can test', () => {
const mockWindow = {location: {href: null}};
fn({window: mockWindow});
expect(mockWindow.href).toEqual('something');
});
ããã¯çæ³çã§ã¯ãããŸãããã @ domenicãèšã£ã
ããã¯ãããããã¹ãã§ä¿®æ£ããå¿ èŠããããã®ã§ãããã©ãŠã¶ã§ãããã®ãã¹ããå®è¡ããŠããå ŽåãããŒãžãæ°ããURLã«ç§»åãããšããã¹ãã©ã³ããŒãå®å šã«å¹ãé£ã°ãããããšãæå³ããŸãã
ä»ã®ãšããç§ãã¡ã¯ãããšäžç·ã«æ®ãããŠããŸãããããŠã¯ããç§ãã¡ã¯æªãç¿æ £ãšèããããŠãããã¹ãã®å®è£ ã³ãŒããå€æŽããŸãããå€ãããç ããŸãïŒ
ããããŒãã¹ã
@hontasã®ãœãªã¥ãŒã·ã§ã³ã圹ç«ã¡ãŸããïŒ
ã³ãŒãã§window.location.assign(Config.BASE_URL);
ã䜿çšããŸããã
ãããŠãããããã¹ãã§ãïŒ
jest.spyOn(window.location, 'assign').mockImplementation( l => {
expect(l).toEqual(Config.BASE_URL);
})
window.location.assign.mockClear();
åãåé¡ã§ããã³ãŒãã§window.location.search = foo;
ããŠããŸãããjsdomïŒããã³jestïŒã䜿çšããŠãã¹ãããããšæããŸãð€
PSïŒ https ïŒ
jsdom 12.2.0ã«ã¢ããããŒãããåŸããšã©ãŒãçºçããŸããïŒ
TypeErrorïŒããããã£ãåå®çŸ©ã§ããŸããïŒå²ãåœãŠ
const assign = sinon.stub(document.location, 'assign')
ãããä¿®æ£ããæ¹æ³ã¯ïŒ
@ yuri-sakharov
jsdom 12.2.0ã«ã¢ããããŒãããåŸããšã©ãŒãçºçããŸããïŒ
TypeErrorïŒããããã£ãåå®çŸ©ã§ããŸããïŒå²ãåœãŠ
const assign = sinon.stub(document.location, 'assign')
ãããä¿®æ£ããæ¹æ³ã¯ïŒ
sinon.stub(document.location, 'assign')
ããå¿ èŠããããŸãïŒ
sinon.stub(window.location, 'assign')
document
ãwindow
ã«çœ®ãæããå¿
èŠããããŸã
ç§ã¯æ¬¡ã®æ©èœãæã£ãŠããŸã
export const isLocalHost = () => Boolean(
window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address.
window.location.hostname === '[::1]' ||
// 127.0.0.1/8 is considered localhost for IPv4.
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
)
);
ãããæ©èœããããšããã¹ãã§ããããã«ããããã«ã hostname
çŽæ¥æ³šå
¥ããŸã
it('#isLocalHost should return true for all the cases of localhost', () => {
window.location.hostname = 'localhost';
expect(isLocalHost()).toBeTruthy();
window.location.hostname = '[::1]';
expect(isLocalHost()).toBeTruthy();
window.location.hostname = '127.0.0.1';
expect(isLocalHost()).toBeTruthy();
// Reset back the hostname to avoid issues with it
window.location.hostname = '';
});
ããããç§ã¯ãã®ãšã©ãŒãçºçããŠããŸãã
jsdom
ãããã²ãŒã·ã§ã³ãå®å
šã«å®è£
ããããšã¯æåŸ
ããŠããŸããããå°ãªããšãããŒãè¿œå ããŠé¢æ°ãã¢ãã¯ããŸãã
ãªããã®ãšã©ãŒãçºçãç¶ããã®ãæ··ä¹±ããŠããŸããå€ãèšå®ã§ããããã«ãããã ãã§ãã
@nickhallph
ããªããæžããããã«ç§ã¯ãããwindow.location
ã«çœ®ãæããŸããããçµæã¯åãã§ãTypeError: Cannot redefine property: assign
äœãæ¡ã¯ïŒ
@ yuri-sakharovãã¢ã«ãå®è¡ããŠããã®ãšåãåé¡ã
決ããŠwindow.location.*
眮ãæã/æŽæ°/ã¢ãã¯ããããäœãããããã§ããããã«ã¯èŠããŸããã ãããåé¿ããå¯äžã®æ¹æ³ã¯ãç¬èªã®ã«ã¹ã¿ã window.location
ã¢ãã¯ãäœæããããã«äŸåããããã«ã³ãŒãããŒã¹å
šäœãå€æŽããããšã§ãã
@hontasã®ãœãªã¥ãŒã·ã§ã³ã圹ç«ã¡ãŸããïŒ
ã³ãŒãã§
window.location.assign(Config.BASE_URL);
ã䜿çšããŸããããããŠãããããã¹ãã§ãïŒ
jest.spyOn(window.location, 'assign').mockImplementation( l => { expect(l).toEqual(Config.BASE_URL); }) window.location.assign.mockClear();
@zxiestã®JestããŒãžã§ã³ã®@hontas 'ãœãªã¥ãŒã·ã§ã³ã¯ç§ã«ã¯æ©èœããŸããã§ããããããã¯æ©èœããŸããïŒ
window.location.assign = jest.fn();
expect(window.location.assign).toHaveBeenCalledWith('https://correct-uri.com');
window.location.assign.mockRestore();
location.assign
ã䜿çšããããã«ã³ãŒããå€æŽããããªãå Žå-ããã¯JSDom 11ããã³13ã§æ©èœããããã§ãïŒãã ããJSDomãå°æ¥ãããå£ãå¯èœæ§ããããŸã...ïŒ
delete window.location;
window.location = {}; // or stub/spy etc.
æåŸã®çãã¯ç§ã«ãšã£ãŠã¯ããŸããããŸãããã replace
ãå®çŸ©ããå¿
èŠããããŸããïŒ
delete window.location
window.location = { replace: jest.fn() }
ããã圹ã«ç«ãŠã°å¹žãã
TypeErrorãçºçããŸãïŒããããã£ãåå®çŸ©ã§ããŸããïŒsinon7.2.3ããã³jsdom13.2.0ã§å²ãåœãŠãŸãã ãªããããäžéšã®äººã«å¹æããããä»ã®äººã«ã¯å¹æããªãã®ãåãããŸãããïŒ
ããã¯ç§ã®ããã«åãããã®ã§ãïŒ
global.window = Object.create(window);
const url = 'http://localhost';
Object.defineProperty(window, 'location', {
value: {
href: url,
},
writable: true,
});
ãããæ©èœãããããã«pushState
ã䜿çšããŸãã
window.history.pushState(
{},
'',
'http://localhost/something/123?order=asc'
);
ããã¯é£ããç¶æ³ã§ãã JSDOMã¯ïŒãã³ãããªã¹ã以å€ã®ïŒããã²ãŒã·ã§ã³ãå®å šã«ã¯ãµããŒãããŠããããJSDOMã§ã¯ããã²ãŒã·ã§ã³ãã¢ãã¯ã¢ãŠãããããšã¯ã§ããŸããã ãã®çµæãæçµçã«ããã²ãŒã·ã§ã³ãããªã¬ãŒããããšãããã¹ããäœæã§ããªããªããŸãã
JSDOMãããã²ãŒãããããšãåŠãã å ŽåïŒãããäœãæå³ããã®ãããããããŸããïŒãé©åãªããŒãžã«ããããšã«ã€ããŠäž»åŒµã§ãããããããŸããã ãã ããç§ã®ãã¹ããŠãŒã¹ã±ãŒã¹ã§ã¯ãããã²ãŒã·ã§ã³ãå®éã«å®è¡ãããã®ã§ã¯ãªããããªã¬ãŒããããšäž»åŒµããæ¹ãã¯ããã«ã¯ãªãŒã³ã§é«éã§ãã ããã¯ãjsdomã䜿çšããŠãã¹ããããšãã«ç§ãæŽå²çã«è¡ã£ãŠããããšã§ãããçŸåšã¯å£ããŠããŸãã
èªåã®è³ªåã«å¯Ÿããåçãæçš¿ãããŠãã ãã
window.location = url;
ãšwindow.location.href = url;
ã®äœ¿çšæ³ãåçŽã«çœ®ãæããŸãwindow.location.assign(url);
ãããŠãç§ã®ãã¹ãã§ã¯ã次ã®ããšãè¡ããŸããã
sinon.stub(window.location, 'assign'); expect(window.location.assign).to.have.been.calledWith(url);
é åã®ããã«æ©èœããŸã-ãããä»ã®èª°ãã®å©ãã«ãªãããšãé¡ã£ãŠããŸã
ã¿ãŒã²ããURLãå¶åŸ¡ã§ããå Žåã¯ããã§ãããGoogleãŸãã¯Instagramã®Webãµã€ããããŒãããŠããå Žåã¯ã©ãã§ããããã ãŸãã¯ä»»æã®ãŠã§ããµã€ãïŒ ãã®åé¡ãã©ã®ããã«è§£æ±ºã§ããŸããïŒ
@chrisbatemanããã®åçã«åºã¥ããŠãç§ã¯ãããJestç°å¢ã§æ©èœãããããšãã§ããŸããã Jestã䜿çšããŠãã人ã®ããã«ãããã«ç§ã®åé¿çããããŸãïŒ
describe('', () => {
const originalLocation = window.location;
beforeEach(() => {
delete window.location;
window.location = {
href: '',
};
});
afterEach(() => {
window.location = originalLocation;
});
it('', () => {
// test here
});
});
ãã®èšå®ã䜿çšããŠãã®åé¡ã解決ããŸããã ããã·ã¥URLã®ãªãã€ã¬ã¯ãããã¹ããããã£ãïŒ
beforeEach(() => {
delete global.window;
global.window = {
location: { replace: jest.fn(url => ({ href: url })) },
};
});
it('should redirect hash url', () => {
window.location.hash = '#/contrat?id=8171675304';
global.window.location.href =
'http://localhost:3000/#/contrat?id=8171675304';
redirectHashUrl();
expect(window.location.replace).toHaveBeenCalled();
});
@chrisbateman @hamzahamidiããããšãããã®ãœãªã¥ãŒã·ã§ã³ã¯ããŸããããŸããã
ãã¶ãããã¯è¯ãç¿æ £ã§ã¯ãããŸããããããã€ãã®ãã¹ããããããããã¯location / host / hostnameãšä»ã®locationããããã£ã«äŸåããŠããŸãã ã ãããç§ãã¡ãæãããã«å ŽæããããããåŸã§åŸ©å ããããšã¯ç§ã®ããã«åããã
const realLocation = window.location;
describe('bla bla', () => {
afterEach(() => {
window.location = realLocation;
});
it('test where I want to use hostname', () => {
delete window.location;
window.location = {
hostname: 'my-url-i-expect.com'
};
// check my function that uses hostname
});
});
ããã¯ç§ã®ããã«åãããã®ã§ãïŒ
global.window = Object.create(window); const url = 'http://localhost'; Object.defineProperty(window, 'location', { value: { href: url, }, writable: true, });
circleciã®ãããªCI
æ©èœããŸãã
@hontasã®ãœãªã¥ãŒã·ã§ã³ã圹ç«ã¡ãŸããïŒ
ã³ãŒãã§
window.location.assign(Config.BASE_URL);
ã䜿çšããŸããããããŠãããããã¹ãã§ãïŒ
jest.spyOn(window.location, 'assign').mockImplementation( l => { expect(l).toEqual(Config.BASE_URL); }) window.location.assign.mockClear();
ãããã§ä»²éãããªãã¯ç§ãäžæ¥æã£ãŠãããŸããïŒ :)
ç§ã®å Žåã¯ãã¯ãšãªæååããã¹ãããŠããŸãããç§ã®ã¹ããã¯ã®äž»é¡ã¯ãã¯ãšãªæååãã®ãã®ã§ããããšãããç§ã¯ããããã€ãã¹ã«ããããªãããç§ã¯ãããã¹ã¿ãã«æºè¶³ããŠããŸãã ç§ã®å Žåãããã¯ããŸããããŸããïŒ
let name = "utm_content"
window.history.pushState({}, 'Test Title', '/test.html?utm_content=abc');
expect(ParseUrlUtils.getParam(name)).toBe("abc")
ããã§ã¯ããŠã£ã³ããŠã®ã¿ã€ãã«ãäœã§ãããã¯é¢ä¿ãªãã /test.html
ïŒããã¯å®éã§ã¯ãããŸããïŒã§ãããã©ãããé¢ä¿ãããŸãããéèŠãªã®ã¯ãã¯ãšãªæååãæ£ãããã§ãããããããšã ãã§ãïŒããã¯åæ Œã§ãïŒ
äŸã®åé¡ã¯ãã¡ãœãããšã²ãã¿ãŒã䜿çšãããŠããªãããšã§ãã ç§ããã£ãŠããããšã¯ãåºæ¬çã«Locationãªããžã§ã¯ããURLãªããžã§ã¯ãã«çœ®ãæããããšã§ãã URLã«ã¯ãå Žæã®ãã¹ãŠã®ããããã£ïŒæ€çŽ¢ããã¹ããããã·ã¥ãªã©ïŒããããŸãã
const realLocation = window.location;
describe('My test', () => {
afterEach(() => {
window.location = realLocation;
});
test('My test func', () => {
// @ts-ignore
delete window.location;
// @ts-ignore
window.location = new URL('http://google.com');
// ...
});
});
ç§ããã®ãšã©ãŒãçºçããŸã
Error: Not implemented: navigation (except hash changes) at module.exports (...\node_modules\jsdom\lib\jsdom\browser\not-implemented.js:9:17) at navigateFetch (...\node_modules\jsdom\lib\jsdom\living\window\navigation.js:74:3)
@hontasã®ãœãªã¥ãŒã·ã§ã³ã圹ç«ã¡ãŸããïŒ
ã³ãŒãã§
window.location.assign(Config.BASE_URL);
ã䜿çšããŸããããããŠãããããã¹ãã§ãïŒ
jest.spyOn(window.location, 'assign').mockImplementation( l => { expect(l).toEqual(Config.BASE_URL); }) window.location.assign.mockClear();
ããã¯ç§ã®ããã«åãããããããšãïŒ ãã ããjest testïŒïŒã®done
åŒæ°ã䜿çšããå¿
èŠããããŸãããããããªããšãæåŸ
å€ãè©äŸ¡ããããã¹ããæ£åžžã«çµäºãããã©ãããããããŸããã
it('should', (done) => { jest.spyOn(window.location, 'assign').mockImplementation( l => { expect(l).toEqual(Config.BASE_URL); done(); }) window.location.assign.mockClear(); }
@hontasã¯ç§ã«ã¯æ©èœããŸãã:(å²ãåœãŠ/眮æããããã£ãæžãæããããšãã§ããŸãã
ãå®è£ ãããŠããŸããïŒããã²ãŒã·ã§ã³ãã¡ãã»ãŒãžãããªã¬ãŒããŠãããã¹ããèŠã€ããæ¹æ³ã¯ãããŸããïŒ ç§ã¯43ã®ãã¹ãã®ã¹ã€ãŒããæã£ãŠããŸã-ãšã©ãŒã¯äžåºŠã ã衚瀺ãããããã¯ããŠã³ããç¶ããŸãã ã©ã®ãã¹ããä¿®æ£ããã°ãããããããŸãã!!! ã¹ã¿ãã¯ãã¬ãŒã¹ã§ã¯ãåå ã¯ããããŸããã
console.error
Error: Not implemented: navigation (except hash changes)
at module.exports (/Users/naresh/projects/mobx-state-router/node_modules/jsdom/lib/jsdom/browser/not-implemented.js:9:17)
at navigateFetch (/Users/naresh/projects/mobx-state-router/node_modules/jsdom/lib/jsdom/living/window/navigation.js:76:3)
at exports.navigate (/Users/naresh/projects/mobx-state-router/node_modules/jsdom/lib/jsdom/living/window/navigation.js:54:3)
at Timeout._onTimeout (/Users/naresh/projects/mobx-state-router/node_modules/jsdom/lib/jsdom/living/nodes/HTMLHyperlinkElementUtils-impl.js:81:7)
at listOnTimeout (internal/timers.js:531:17)
at processTimers (internal/timers.js:475:7) undefined
at VirtualConsole.<anonymous> (node_modules/jsdom/lib/jsdom/virtual-console.js:29:45)
at module.exports (node_modules/jsdom/lib/jsdom/browser/not-implemented.js:12:26)
at navigateFetch (node_modules/jsdom/lib/jsdom/living/window/navigation.js:76:3)
at exports.navigate (node_modules/jsdom/lib/jsdom/living/window/navigation.js:54:3)
at Timeout._onTimeout (node_modules/jsdom/lib/jsdom/living/nodes/HTMLHyperlinkElementUtils-impl.js:81:7)
@hontasã¯ç§ã«ã¯æ©èœããŸãã:(å²ãåœãŠ/眮æããããã£ãæžãæããããšãã§ããŸãã
ç§ãç解ããŠããããã«ãjestã¯æ°ããããŒãžã§ã³ïŒ "jest"ïŒ "^ 26.0.1"ïŒã§äœããå€æŽããã®ã§ãããã¯ä»ããæ©èœããŸãïŒ
// Mock
Object.defineProperty(window, 'location', {
value: {
pathname: '/terminals',
assign: jest.fn(),
},
});
// Then test
expect(window.location.assign).toBeCalledWith('/auth');
ãå®è£ ãããŠããŸããïŒããã²ãŒã·ã§ã³ãã¡ãã»ãŒãžãããªã¬ãŒããŠãããã¹ããèŠã€ããæ¹æ³ã¯ãããŸããïŒ ç§ã¯43ã®ãã¹ãã®ã¹ã€ãŒããæã£ãŠããŸã-ãšã©ãŒã¯äžåºŠã ã衚瀺ãããããã¯ããŠã³ããç¶ããŸãã ã©ã®ãã¹ããä¿®æ£ããã°ãããããããŸãã!!! ã¹ã¿ãã¯ãã¬ãŒã¹ã§ã¯ãåå ã¯ããããŸããã
console.error Error: Not implemented: navigation (except hash changes) at module.exports (/Users/naresh/projects/mobx-state-router/node_modules/jsdom/lib/jsdom/browser/not-implemented.js:9:17) at navigateFetch (/Users/naresh/projects/mobx-state-router/node_modules/jsdom/lib/jsdom/living/window/navigation.js:76:3) at exports.navigate (/Users/naresh/projects/mobx-state-router/node_modules/jsdom/lib/jsdom/living/window/navigation.js:54:3) at Timeout._onTimeout (/Users/naresh/projects/mobx-state-router/node_modules/jsdom/lib/jsdom/living/nodes/HTMLHyperlinkElementUtils-impl.js:81:7) at listOnTimeout (internal/timers.js:531:17) at processTimers (internal/timers.js:475:7) undefined at VirtualConsole.<anonymous> (node_modules/jsdom/lib/jsdom/virtual-console.js:29:45) at module.exports (node_modules/jsdom/lib/jsdom/browser/not-implemented.js:12:26) at navigateFetch (node_modules/jsdom/lib/jsdom/living/window/navigation.js:76:3) at exports.navigate (node_modules/jsdom/lib/jsdom/living/window/navigation.js:54:3) at Timeout._onTimeout (node_modules/jsdom/lib/jsdom/living/nodes/HTMLHyperlinkElementUtils-impl.js:81:7)
ã©ã®ãã¹ãããå®è£ ãããŠããªããšã©ãŒãçºçããããå€æããã®ã¯å°é£ã§ãã
node_modules/jsdom/lib/jsdom/browser/not-implemented.js:12
ã«ãã¬ãŒã¯ãã€ã³ããè¿œå ãããããã°ã»ãã·ã§ã³ãå®è¡ããŠããã¬ãŒã¯ãã€ã³ãã«å°éãããŸã§åŸ
ã¡ãŸãã ããããŠåããŠããã®ã¡ãã»ãŒãžãåãé€ãããã«ã©ã®ãã¹ããæ¹åããå¿
èŠãããããããããŸãã
ã©ã³ããŒãåé¡ã®ãããã¹ãã«å°éãããŸã§ã«2ã3åãããå ŽåããããŸãã
PSïŒç§ã®çŸåšã®ãããžã§ã¯ãã«ã¯ã176ã®jsdomé¢é£ã®ãã¹ãããããŸã
ç§ã¯çŸåšJest 26.0.1
ã䜿çšããŠããŸããã以äžãæ©èœããŸãã
window.location.assign(url)
ã䜿çšããŠããŠã£ã³ããŠã®å Žæãå€æŽããŸãã
次ã®ããã«ãã±ãŒã·ã§ã³ãªããžã§ã¯ããã¢ãã¯ããŸãïŒæåã«ãªããžã§ã¯ããåé€ããŠåæ§ç¯ããªããšãåè¿°ã®ããŒãžã§ã³ã®Jestã§å®è£
ãããŠããªããšã©ãŒãçºçããããšã«æ³šæããŠãã ããããŸãã Object.defineProperty
æ©èœããããšã©ãŒïŒïŒ
delete window.location;
window.location = {
href: '',
hostname: '',
pathname: '',
protocol: '',
assign: jest.fn()
};
expect(window.location.assign).toBeCalledWith(url);
åè«ãç§ãã¡ã«ãããã®çµ¶ãéãªãåââé¡ãå€æŽã®ãã¹ãŠãªãã§ç°¡åã«å Žæãããããããšãèš±ããŠããããæ¬åœã«çŽ æŽãããã§ãããã 以åã¯window.location.assign = jest.fn()
ã ããåé¡ãªã䜿çšããŠããŸããããv24ããã¢ããã°ã¬ãŒãããŸããã
Window APIãããã¯/ããªãŒãºãããæ£åœãªçç±ã¯ãããŸããïŒ
ããããåé¿çã®ããã²ãŒã·ã§ã³ãå®è£
ãããŠããªãããšãè©Šã¿ã人ã
ã«ãšã£ãŠã®éå£ã®ããã§ãã
ããã§ãªããã°ãç§ãã¡ã¯ããããåçµããããšã¯ã§ããŸãããïŒ ãã©ãŠã¶ã§ããããŠã£ã³ããŠãªããžã§ã¯ãã®å€æŽãé²ãã®ã«ããã»ã©å³æ Œã§ã¯ãªããšæããŸãã
jsdomã®åäœããã©ãŠã¶ãšç°ãªãäŸãããå Žåã¯ãåé¡ãã³ãã¬ãŒãã«åŸã£ãŠåé¡ãå ±åããŠãã ããïŒjsbinãŸãã¯åæ§ã®ãã©ãŠã¶ã®åäœã瀺ããã®ãå«ãïŒã
href
ã¢ã³ã«ãŒèŠçŽ ã§ã¯ãªãã¯ã€ãã³ããçºçãããJestãã¹ãäžã«åãError: Not implemented: navigation (except hash changes)
ã«ééãã人ã¯ä»ã«ããŸããïŒ ç§ã®ãã¹ãã§ã¯ã onClick
ãšåŒã°ããé¢æ°ãã¹ãã€ããããã«ã€ããŠã¢ãµãŒã·ã§ã³ãäœæããŠããã®ã§ãã¢ã³ã«ãŒèŠçŽ ã§å®éã«ã¯ãªãã¯ã€ãã³ããçºçãããå¿
èŠããããŸãã
window.location
ã¢ãã¯ã«é¢é£ããäžèšã®è§£æ±ºçã¯ãæ瀺çã«window.location.replace
ãŸãã¯window.location.assign
åŒã³åºããŠããå Žåã«æ©èœããŸãããããã²ãŒã·ã§ã³ãã¢ã³ã«ãŒèŠçŽ ããçºçããŠãããã®å Žåã«ã¯åœ¹ç«ã¡ãŸããã¯ãªãã¯ãããŠããŸãã
ãœãªã¥ãŒã·ã§ã³ã«é¢ããã¢ã€ãã¢ã¯ãããŸããïŒ ããããšãïŒ
ãã®ã³ãŒãããã©ãŠã¶ã§ã©ã®ããã«ãã¹ãããŸããïŒ ãã©ãŠã¶ã§ãªã³ã¯ãã¯ãªãã¯ãããšãããŒãžå šäœãå¹ãé£ã°ããããã¹ãçµæãç Žæ£ãããããšã«æ³šæããŠãã ããã ãããã£ãŠããããé²ãããã«äœãããã«ããŠããjsdomãã³ã³ãœãŒã«ã«åºåããããã»ã©åçã§ã¯ãªãèŠåã¡ãã»ãŒãžãé²ããŸãã
ç§ã®ç¶æ³ã§ã¯ããããžã§ã¯ãã¯Jestã23ãã26ããŒãžã§ã³ã«ã¢ããã°ã¬ãŒãããŸããã
location.search
åé¡ããããŸããã åããšã©ãŒError: Not implemented: navigation
ã
ãã¹ãããã¢ãžã¥ãŒã«ã¯ãæ€çŽ¢ã¯ãšãªãã©ã¡ãŒã¿ã®å€ãååŸããŸãã
次ã®å®è£
ã¯ç§ã®ããã«åããïŒ
beforeAll(() => {
delete window.location;
window.location = new URL('your URL');
})
afterAll(() => {
window.location.search = '';
})
@mattcphillipsãããä¿®æ£ããæ¹æ³ãç解ããŸãããïŒ ã¯ãªãã¯ããŠãåé¡ãçºçããŸã
@Sabrinovskyããããjestæ§æã®setupFiles
ã«ã¹ã¯ãªãããè¿œå ããã ãã§ãjsdomããã²ãŒã·ã§ã³ããã®ã³ã³ãœãŒã«ãšã©ãŒã飲ã¿èŸŒãã§ããã¹ããä¹±éã«ãªããªãããã«ããŸããã äœãããçµåµèã§ããããããã®ãšã©ãŒã¯ãã¹ãã»ããã¢ããã§äºæ³ãããããã«èãããŸããã
ãã¹ãã®åã«å®è¡ããã¹ã¯ãªããã¯æ¬¡ã®ãšããã§ãã
// There should be a single listener which simply prints to the
// console. We will wrap that listener in our own listener.
const listeners = window._virtualConsole.listeners('jsdomError');
const originalListener = listeners && listeners[0];
window._virtualConsole.removeAllListeners('jsdomError');
// Add a new listener to swallow JSDOM errors that orginate from clicks on anchor tags.
window._virtualConsole.addListener('jsdomError', error => {
if (
error.type !== 'not implemented' &&
error.message !== 'Not implemented: navigation (except hash changes)' &&
originalListener
) {
originalListener(error);
}
// swallow error
});
ããã¯ç§ã®ããã«åããã
delete global.window.location
global.window.location = { href: 'https://test.com' }
ããã¯ç§ã®ããã«åãã
delete window.location
window.location = { assign: jest.fn() }
ããªããååŸããå ŽåTypeError: Cannot assign to read only property 'assign' of object '[object Location]'
ãã®åŸãããªãã«ãã®ãããªãã®ã䜿çšããŠã jest.setup.ts
ïŒ
`` `
global.window = Object.createïŒwindowïŒ;
Object.definePropertyïŒwindowã 'location'ã{
䟡å€ïŒ {
... window.locationã
}ã
æžã蟌ã¿å¯èœïŒtrueã
}ïŒ;
ãã
æãåèã«ãªãã³ã¡ã³ã
èªåã®è³ªåãžã®åçãæçš¿ãããŠãã ããð
window.location = url;
ãšwindow.location.href = url;
ã®äœ¿çšæ³ãåçŽã«çœ®ãæããŸããããŠãç§ã®ãã¹ãã§ã¯ã次ã®ããšãè¡ããŸããã
é åã®ããã«æ©èœããŸã-ãããä»ã®èª°ãã®å©ãã«ãªãããšãé¡ã£ãŠããŸãð