рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдЕрдкрдЧреНрд░реЗрдб рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж 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 рдпрд╛ рдЗрд╕реА рддрд░рд╣ рдХреА рд╕реЗрдЯрд┐рдВрдЧ рдпрд╣ рд╕рдВрджреЗрд╢ рджреЗрдЧреАред рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЬреЗрд╕реНрдЯ рдкрд╣рд▓реЗ рдЗрди рд╕рдВрджреЗрд╢реЛрдВ рдХреЛ рджрдмрд╛ рд░рд╣рд╛ рдерд╛, рдпрд╛ рдХреНрдпрд╛ред
рдпрд╣ рд╢рд╛рдпрдж рдХреБрдЫ рдРрд╕рд╛ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдареАрдХ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдпрджрд┐ рдЖрдк рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рдЙрди рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдЪрд▓рд╛ рд░рд╣реЗ рдереЗ, рддреЛ рдкрд░реАрдХреНрд╖рдг рдзрд╛рд╡рдХ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЙрдбрд╝ рдЬрд╛рдПрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рдкреГрд╖реНрда рдХреЛ рдПрдХ рдирдП рдпреВрдЖрд░рдПрд▓ рдкрд░ рдиреЗрд╡рд┐рдЧреЗрдЯ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЖрдк рдХрднреА рднреА рдХреЛрдИ рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рджреЗрдЦреЗрдВрдЧреЗ рдкрд░рд┐рдгрд╛рдоред Jsdom рдореЗрдВ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рд╣рдо рдХреЗрд╡рд▓ рдХрдВрд╕реЛрд▓ рдХреЛ рдПрдХ рд╕рдВрджреЗрд╢ рдЖрдЙрдЯрдкреБрдЯ рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ рдЖрдк рдЪрд╛рд╣реЗрдВ рддреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рдЖрдк рдЕрдкрдиреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдФрд░ рдЕрдзрд┐рдХ рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдмреЗрд╣рддрд░ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдареАрдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рд╡реИрд╕реЗ рднреА, рдореИрдВ рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдкрд░ рдФрд░ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЦреБрд▓рд╛ рдЫреЛрдбрд╝ рджреВрдВрдЧрд╛ред
рдЖрдк рдЬреЛ рдХрд╣ рд░рд╣реЗ рд╣реИрдВ рдЙрд╕реЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдЬреЗрд╕реНрдЯ 22 рдЕрдкрдбреЗрдЯ JSDOM 9 рд╕реЗ 11 IIRC рдкрд░ рдЪрд▓рд╛ рдЧрдпрд╛, рдЗрд╕рд▓рд┐рдП 9.x рдореЗрдВ рд╡рд╛рдкрд╕ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛рдлреА рднрд┐рдиреНрди рд╣реЛ рд╕рдХрддрд╛ рд╣реИред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореИрдВ рдЬреЗрдПрд╕рдбреАрдУрдПрдо рдореЗрдВ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЭрдВрдбреЗ рдХреЗ рд╕рд╛рде рдиреЗрд╡рд┐рдЧреЗрд╢рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдкрд╕рдВрдж рдХрд░реВрдВрдЧрд╛ рддрд╛рдХрд┐ рдЗрд╕реЗ рдПрдХ рдЕрд▓рдЧ рдкреЗрдЬ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдиреЛ-рдСрдк рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХреЗ (рдПрдЪрдЯреАрдПрдордПрд▓ 5 рдкреБрд╢рд╕реНрдЯреЗрдЯ рдХреЗ рд╕рдорд╛рди рднрд╛рд╡рдирд╛ рдореЗрдВред) рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдЖрдорддреМрд░ рдкрд░ рдкрд░реАрдХреНрд╖рдг рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдЬрдмрдХрд┐ рд╢рд╛рдпрдж рдПрдХ рд╡рд┐рдЪрд┐рддреНрд░ рдЕрдиреБрд░реЛрдз, рдЗрд╕реЗ рдЕрдХреНрд╕рд░ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рд╣рдореЗрдВ рдРрд╕рд╛ рдзреНрд╡рдЬ рдЬреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреЛ рдЖрдкрдХреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ jsdom рдореЗрдВ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЪрд▓рд╛рдПред рддрдм рдЖрдкрдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рддреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдпрд╣ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рдкреГрд╖реНрда рдкрд░ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдмрдЬрд╛рдп рдЗрд╕рдХреЗ рдХрд┐ рдЖрдкрдХреЗ рдкрд░реАрдХреНрд╖рдг рд╣реЛ рд░рд╣реЗ рдХреНрд░рд┐рдпрд╛ рдХреЛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП) рдФрд░ рдЖрдк рдиреЛрдЯрд┐рд╕ рднреА рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ!
рдЦреИрд░ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдпрд╣ рд╡рд░реНрддрдорд╛рди рдкреГрд╖реНрда рд╕рдВрджрд░реНрдн рдХреЛ рдЙрддрд╛рд░рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдХреБрдЫ рднреА рдЕрд▓рдЧ рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред рдореИрдВ рдЕрднреА рднреА window.location.href
рдЕрдкрдбреЗрдЯ рд╣реЛрдиреЗ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реВрдВ, рдЖрджрд┐ред
@domenic рдореБрдЭреЗ рдПрдХ рд╣реА рд╕рдорд╕реНрдпрд╛ рд╣реИ рдФрд░ рдореИрдВ рд╕реЛрдЪ рд░рд╣рд╛ рдерд╛ рдХрд┐ window.location
рд╕реЗрдЯ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдРрдк рдХреЗ рд╕рд╛рде JSDOM рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдкреНрд░рдХрд╛рд░ рдХрд╛ рд╕рд░реНрд╡реЛрддреНрддрдо рдЕрднреНрдпрд╛рд╕ рд╣реИ рдпрд╛ рдирд╣реАрдВред рдореИрдВ рдЬреЛ рдмрддрд╛ рд╕рдХрддрд╛ рд╣реВрдВ рдЙрд╕рд╕реЗ JSDOM window.location
рд╕реЗрдЯ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╕рдордп рдПрдХ рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХрддрд╛ рд╣реИ рдФрд░ window.location.href
рд╕реЗрдЯ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╕рдордп рдПрдХ рддреНрд░реБрдЯрд┐ рд▓реЙрдЧ рдХрд░рддрд╛ рд╣реИ - рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореИрдВ рдПрдордбреАрдПрди рдкрд░ рдкрдврд╝ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ рджреЛрдиреЛрдВ рд╕рдорд╛рдирд╛рд░реНрдереА рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдХреНрдпрд╛ рдореБрдЭреЗ рд╕реНрдерд╛рди рдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рддрд░реАрдХреЗ рд╕реЗ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреЛ рд╕реНрдЯрдм рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реЛ?
рдорджрдж рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж
рдореБрдЭреЗ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкреНрд░рд╢реНрди рдХрд╛ рдЙрддреНрддрд░ рдкреЛрд╕реНрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдВ
рдореИрдВ рдмрд╕ 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 рдиреЗ рдХрд╣рд╛ рд╣реИ:
рдпрд╣ рд╢рд╛рдпрдж рдХреБрдЫ рдРрд╕рд╛ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдареАрдХ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдпрджрд┐ рдЖрдк рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рдЙрди рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдЪрд▓рд╛ рд░рд╣реЗ рдереЗ, рддреЛ рдкрд░реАрдХреНрд╖рдг рдзрд╛рд╡рдХ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЙрдбрд╝ рдЬрд╛рдПрдЧрд╛ рдЬрдм рдЖрдк рдкреГрд╖реНрда рдХреЛ рдПрдХ рдирдП рдпреВрдЖрд░рдПрд▓ рдкрд░ рдиреЗрд╡рд┐рдЧреЗрдЯ рдХрд░реЗрдВрдЧреЗред
рдЕрднреА рдХреЗ рд▓рд┐рдП рд╣рдо рдЗрд╕рдХреЗ рд╕рд╛рде рд░рд╣рддреЗ рд╣реИрдВ рдФрд░ рд╣рд╛рдБ рд╣рдо рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрдкрдирд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛрдб рдмрджрд▓рддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рдмреБрд░рд╛ рдЕрднреНрдпрд╛рд╕ рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рд╣рдо рд░рд╛рдд рдореЗрдВ рднреА рдЕрдЪреНрдЫреА рдиреАрдВрдж рд▓реЗрддреЗ рд╣реИрдВ!
рд╣реИрдкреНрдкреА рдЯреЗрд╕реНрдЯрд┐рдВрдЧ
@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 (рдФрд░ рдЬреЗрд╕реНрдЯ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ
рдкреБрдирд╢реНрдЪ: рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд https://github.com/facebook/jest/issues/5266
Jsdom 12.2.0 рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рддреНрд░реБрдЯрд┐ рдорд┐рд▓реА:
рд▓реЗрдЦрди рддреНрд░реБрдЯрд┐: рд╕рдВрдкрддреНрддрд┐ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛: рдЕрд╕рд╛рдЗрди рдХрд░реЗрдВ
const assign = sinon.stub(document.location, 'assign')
рдЗрд╕реЗ рдХреИрд╕реЗ рдЬреЛрдбрд╝реЗрдВрдЧреЗ?
@ рдпреВрд░реА-рд╕рдЦрд╛рд░реЛрд╡
Jsdom 12.2.0 рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рддреНрд░реБрдЯрд┐ рдорд┐рд▓реА:
рд▓реЗрдЦрди рддреНрд░реБрдЯрд┐: рд╕рдВрдкрддреНрддрд┐ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛: рдЕрд╕рд╛рдЗрди рдХрд░реЗрдВ
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
рдХреЛрдИ рд╡рд┐рдЪрд╛рд░?
@ рдпреВрд░реА-рд╕рдЦрд╛рд░реЛрд╡ рдореЛрдЪрд╛ рдЪрд▓рд╛рдиреЗ рдХреЗ рд╕рдорд╛рди рд╕рдорд╕реНрдпрд╛ред
рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдореИрдВ 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();
@Hontas 'рд╕рдорд╛рдзрд╛рди рдХрд╛ @zxiest рдХрд╛ рдЬреЗрд╕реНрдЯ рд╕рдВрд╕реНрдХрд░рдг рдореЗрд░реЗ рдХрд╛рдо рдирд╣реАрдВ рдЖрдпрд╛, рд▓реЗрдХрд┐рди рдЗрд╕рдиреЗ рдХрд┐рдпрд╛:
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 рдорд┐рд▓ рд░рд╣рд╛ рд╣реИ: рд╕рдВрдкрддреНрддрд┐ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛: sinon 7.2.3 рдФрд░ jsdom 13.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 рд╡реЗрдмрд╕рд╛рдЗрдЯ рд▓реЛрдб рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдпрд╛ рдХреЛрдИ рд╡реЗрдмрд╕рд╛рдЗрдЯ? рдЖрдк рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХреИрд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ?
@chrisbateman рдХреЗ рдЙрддреНрддрд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдореИрдВ рдЗрд╕реЗ рдЬреЗрд╕реНрдЯ рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдХрд╛рдо рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рд░рд╣рд╛ред рдЬреЛ рдХреЛрдИ рднреА рдЬреЗрд╕реНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реИ, рдЙрд╕рдХреЗ рд▓рд┐рдП рдпрд╣ рдореЗрд░рд╛ рд╕рдорд╛рдзрд╛рди рд╣реИ:
describe('', () => {
const originalLocation = window.location;
beforeEach(() => {
delete window.location;
window.location = {
href: '',
};
});
afterEach(() => {
window.location = originalLocation;
});
it('', () => {
// test here
});
});
рдореИрдВрдиреЗ рдЗрд╕ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд┐рдпрд╛ред рдореИрдВ рд╣реИрд╢ рдпреВрдЖрд░рдПрд▓ рдХреЗ рд▓рд┐рдП рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рди рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛:
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 рдзрдиреНрдпрд╡рд╛рдж, рдЙрд╕ рд╕рдорд╛рдзрд╛рди рдиреЗ рдЕрдЪреНрдЫрд╛ рдХрд╛рдо рдХрд┐рдпрд╛ред
рд╢рд╛рдпрдж рдпрд╣ рдПрдХ рдЕрдЪреНрдЫрд╛ рдЕрднреНрдпрд╛рд╕ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреБрдЫ рдкрд░реАрдХреНрд╖рдг рд╣реИрдВ, рдЬреЛ рд╕реНрдерд╛рди/рд╣реЛрд╕реНрдЯ/рд╣реЛрд╕реНрдЯрдирд╛рдо рдФрд░ рдЕрдиреНрдп рд╕реНрдерд╛рди рдЧреБрдгреЛрдВ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП рдЬреИрд╕рд╛ рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ рд▓реЛрдХреЗрд╢рди рдХрд╛ рдордЬрд╛рдХ рдмрдирд╛рдирд╛ рдФрд░ рдмрд╛рдж рдореЗрдВ рдмрд╣рд╛рд▓ рдХрд░рдирд╛ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░ рдЧрдпрд╛ред
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, });
рдпрд╣ рд╕рд░реНрдХрд▓рд╕реА рдХреА рддрд░рд╣ 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
(рдЬреЛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдирд╣реАрдВ рд╣реИ) рд╣реИ, рдХреЗрд╡рд▓ рдпрд╣ рдорд╛рдпрдиреЗ рд░рдЦрддрд╛ рд╣реИ рдХрд┐ рдХреНрд╡реЗрд░реА рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХреА рдЧрдИ рд╣реИ ( рдпрд╣ рдЧреБрдЬрд░рддрд╛ рд╣реИ)
рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдореБрджреНрджрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╡рд┐рдзрд┐рдпреЛрдВ рдФрд░ рдЧреЗрдЯрд░реНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдореИрдВ рдЬреЛ рдХрд░рддрд╛ рд╣реВрдВ рд╡рд╣ рдореВрд▓ рд░реВрдк рд╕реЗ 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();
рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд┐рдпрд╛, рдзрдиреНрдпрд╡рд╛рдж! рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореБрдЭреЗ рдЬреЗрд╕реНрдЯ рдЯреЗрд╕реНрдЯ() рд╕реЗ 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 рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ :( рд╕рдВрдкрддреНрддрд┐ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдиреЗ/рдмрджрд▓рдиреЗ рдореЗрдВ рдЕрд╕рдорд░реНрде
рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВ рд╕рдордЭрддрд╛ рд╣реВрдВ рдХрд┐ рдЬреЗрд╕реНрдЯ рдиреЗ рдирдП рд╕рдВрд╕реНрдХрд░рдг ("рдЬреЗрд╕реНрдЯ": "^ 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 рдорд┐рдирдЯ рдХрд╛ рд╕рдордп рд▓рдЧрддрд╛ рд╣реИ рдЬрдм рддрдХ рдзрд╛рд╡рдХ рдХрд┐рд╕реА рд╕рдорд╕реНрдпрд╛ рдХреЗ рд╕рд╛рде рдкрд░реАрдХреНрд╖рдг рддрдХ рдирд╣реАрдВ рдкрд╣реБрдВрдЪ рдЬрд╛рддрд╛ред
рдкреБрдирд╢реНрдЪ: рдореЗрд░реЗ рд╡рд░реНрддрдорд╛рди рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ 176 jsdom рд╕рдВрдмрдВрдзрд┐рдд рдкрд░реАрдХреНрд╖рдг рд╣реИрдВ
рдореИрдВ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЬреЗрд╕реНрдЯ 26.0.1
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рдиреАрдЪреЗ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ:
рд╡рд┐рдВрдбреЛ рд╕реНрдерд╛рди рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП window.location.assign(url)
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред
рд▓реЛрдХреЗрд╢рди рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдореЙрдХ рдХрд░реЗрдВ (рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рд╣рдЯрд╛рдирд╛ рдФрд░ рдкреБрдирд░реНрдирд┐рд░реНрдорд╛рдг рдирд╣реАрдВ рдХрд░рдирд╛ рдкрд╣рд▓реЗ рдЕрднреА рднреА рдЬреЗрд╕реНрдЯ рдХреЗ рд╡рд┐рдЦреНрдпрд╛рдд рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХреА рдЧрдИ рддреНрд░реБрдЯрд┐ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд╣реИ рдФрд░ рдкрд╣рд▓реЗ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ, 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 рд╕реЗ рдЕрдкрдЧреНрд░реЗрдб рдХрд┐рдпрд╛ рдФрд░ рдЕрдм рдпрд╣ред
рдХреНрдпрд╛ рдХреЛрдИ рдЕрдЪреНрдЫрд╛ рдХрд╛рд░рдг рд╣реИ рдХрд┐ рд╡рд┐рдВрдбреЛ рдПрдкреАрдЖрдИ рд▓реЙрдХ/рдЬрдореЗ рд╣реБрдП рдереЗ?
рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдиреЗрд╡рд┐рдЧреЗрд╢рди рдХреЛ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣реЗ рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдпрд╣ рдмрд╛рдзрд╛ рд╣реИред
рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рдХреНрдпрд╛ рд╣рдо рдЙрдиреНрд╣реЗрдВ рдлреНрд░реАрдЬ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ? рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рднреА рдЗрддрдиреЗ рд╕рдЦреНрдд рд╣реИрдВ рдЬреЛ рдЖрдкрдХреЛ рд╡рд┐рдВрдбреЛ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреЛ рдмрджрд▓рдиреЗ рд╕реЗ рд░реЛрдХрддреЗ рд╣реИрдВред
рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╕реЗ рднрд┐рдиреНрди рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ jsdom рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ, рддреЛ рдХреГрдкрдпрд╛ рд╕рдорд╕реНрдпрд╛ рдЯреЗрдореНрдкрд▓реЗрдЯ (jsbin рдпрд╛ рд╕рдорд╛рди рджрд┐рдЦрд╛рдиреЗ рд╡рд╛рд▓реЗ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╡реНрдпрд╡рд╣рд╛рд░ рд╕рд╣рд┐рдд) рдХреЗ рдмрд╛рдж рдПрдХ рд╕рдорд╕реНрдпрд╛ рджрд░реНрдЬ рдХрд░реЗрдВред
рдХреНрдпрд╛ рдЬреЗрд╕реНрдЯ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рджреМрд░рд╛рди рдХреЛрдИ рдФрд░ рдЙрд╕реА Error: Not implemented: navigation (except hash changes)
рдореЗрдВ рдЪрд▓ рд░рд╣рд╛ рд╣реИ рдЬреЛ рдПрдХ рдПрдВрдХрд░ рддрддреНрд╡ рдкрд░ href
рд╕рд╛рде рдПрдХ рдХреНрд▓рд┐рдХ рдИрд╡реЗрдВрдЯ рдХреЛ рд╕рдХреНрд░рд┐рдп рдХрд░рддрд╛ рд╣реИ? рдореЗрд░реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдПрдХ рдРрд╕реЗ рдлрд╝рдВрдХреНрд╢рди рдкрд░ рдЬрд╛рд╕реВрд╕реА рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдЬрд┐рд╕реЗ onClick
рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рджрд╛рд╡рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдВрдХрд░ рддрддреНрд╡ рдкрд░ рдХреНрд▓рд┐рдХ рдИрд╡реЗрдВрдЯ рдХреЛ рдЖрдЧ рд▓рдЧрд╛рдирд╛ рд╣реЛрдЧрд╛ред
рдКрдкрд░ рджрд┐рдП рдЧрдП рд╕рдорд╛рдзрд╛рди window.location
рдХрд╛ рдордЬрд╛рдХ рдЙрдбрд╝рд╛рдиреЗ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рдореИрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ window.location.replace
рдпрд╛ window.location.assign
рдХреЙрд▓ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдорджрдж рдирд╣реАрдВ рдХрд░рддреЗ рдЬрд╣рд╛рдВ рдиреЗрд╡рд┐рдЧреЗрд╢рди рдПрдВрдХрд░ рддрддреНрд╡ рд╕реЗ рдЙрддреНрдкрдиреНрди рд╣реЛрддрд╛ рд╣реИ рдХреНрд▓рд┐рдХ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред
рд╕рдорд╛рдзрд╛рди рдкрд░ рдХреЛрдИ рд╡рд┐рдЪрд╛рд░? рдзрдиреНрдпрд╡рд╛рдж!
рдЖрдк рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рдЙрд╕ рдХреЛрдб рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХреИрд╕реЗ рдХрд░реЗрдВрдЧреЗ? рдзреНрдпрд╛рди рд░рдЦреЗрдВ рдХрд┐ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рд▓рд┐рдВрдХ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рдиреЗ рд╕реЗ рдЖрдкрдХрд╛ рдкреВрд░рд╛ рдкреГрд╖реНрда рдЙрдбрд╝ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдХрд┐рд╕реА рднреА рдкрд░реАрдХреНрд╖рд╛ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдлреЗрдВрдХ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рддреЛ рдЗрд╕реЗ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдк рдЬреЛ рдХреБрдЫ рднреА рдХрд░реЗрдВрдЧреЗ, рд╡рд╣ рдХрдВрд╕реЛрд▓ рдкрд░ рдмрд╣реБрдд рдХрдо-рдирд╛рдЯрдХреАрдп рдЪреЗрддрд╛рд╡рдиреА рд╕рдВрджреЗрд╢ jsdom рдЖрдЙрдЯрдкреБрдЯ рдХреЛ рднреА рд░реЛрдХ рджреЗрдЧрд╛ред
рдореЗрд░реА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдиреЗ рдЬреЗрд╕реНрдЯ рдХреЛ 23 рд╕реЗ 26 рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдЕрдкрдЧреНрд░реЗрдб рдХрд┐рдпрд╛ред
рдореБрдЭреЗ location.search
рд╕рдорд╕реНрдпрд╛ рдереАред рд╡рд╣реА рддреНрд░реБрдЯрд┐ Error: Not implemented: navigation
ред
рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдП рдЧрдП рдореЙрдбреНрдпреВрд▓ рдХреЛ рдЦреЛрдЬ рдХреНрд╡реЗрд░реА рдкреИрд░рд╛ рдХреЗ рдорд╛рди рдорд┐рд▓рддреЗ рд╣реИрдВред
рдЕрдЧрд▓рд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд┐рдпрд╛:
beforeAll(() => {
delete window.location;
window.location = new URL('your URL');
})
afterAll(() => {
window.location.search = '';
})
@mattcphillips рдХреНрдпрд╛ рдЖрдкрдиреЗ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдпрд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдХреИрд╕реЗ рдареАрдХ рдХрд┐рдпрд╛ рдЬрд╛рдП? рдХреНрд▓рд┐рдХ рдХрд░рддреЗ рд╕рдордп рдореБрдЭреЗ рднреА рд╕рдорд╕реНрдпрд╛ рд╣реЛ рд░рд╣реА рд╣реИ
@Sabrinovsky рдирд╣реАрдВ, рдореИрдВрдиреЗ рдЕрдкрдиреЗ 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
рдореЗрдВ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:
```
рдЧреНрд▓реЛрдмрд▓.рд╡рд┐рдВрдбреЛ = рдСрдмреНрдЬреЗрдХреНрдЯ.рдХреНрд░рд┐рдПрдЯ (рд╡рд┐рдВрдбреЛ);
Object.defineProperty (рд╡рд┐рдВрдбреЛ, 'рд╕реНрдерд╛рди', {
рдореВрд▓реНрдп: {
...рд╡рд┐рдВрдбреЛ.рд╕реНрдерд╛рди,
},
рд▓рд┐рдЦрдиреЗ рдпреЛрдЧреНрдп: рд╕рдЪ,
});
````
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
рдореБрдЭреЗ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкреНрд░рд╢реНрди рдХрд╛ рдЙрддреНрддрд░ рдкреЛрд╕реНрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдВ
рдореИрдВ рдмрд╕
window.location = url;
рдФрд░window.location.href = url;
рдХреЗ рдЙрдкрдпреЛрдЧреЛрдВ рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддрд╛ рд╣реВрдВрдФрд░ рдлрд┐рд░ рдореЗрд░реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдореИрдВрдиреЗ рдХрд┐рдпрд╛:
рдПрдХ рдЖрдХрд░реНрд╖рдг рдХреА рддрд░рд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ - рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХрд┐рд╕реА рдФрд░ рдХреА рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИ