Jest: Object.defineProperty рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ window.location рдмрджрд▓рдиреЗ рдореЗрдВ рдЕрд╕рдорд░реНрде

рдХреЛ рдирд┐рд░реНрдорд┐рдд 19 рджрд┐рд╕ре░ 2017  ┬╖  78рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: facebook/jest

рдХреНрдпрд╛ рдЖрдк _feature_ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдпрд╛ _bug_ рдХреА рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ? рдЧрд▓рддреА рд╕реВрдЪрд┐рдд рдХрд░реЗрдВ

рд╡рд░реНрддрдорд╛рди рд╡реНрдпрд╡рд╣рд╛рд░ рдХреНрдпрд╛ рд╣реИ?

рдПрдХ рдкрд░реАрдХреНрд╖рдг рд╕реВрдЯ рдХреЗ рдЕрдВрджрд░ рд╕реЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛:

Object.defineProperty(location, "hostname", {
  value: "example.com",
  writable: true
});

рдирд┐рдореНрди рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХрддрд╛ рд╣реИ:

    TypeError: Cannot redefine property: hostname
        at Function.defineProperty (<anonymous>)

рдЕрдкреЗрдХреНрд╖рд┐рдд рд╡реНрдпрд╡рд╣рд╛рд░ рдХреНрдпрд╛ рд╣реИ?

рдХреЛрдб рдХреЛ рдЕрдкрд╡рд╛рдж рдирд╣реАрдВ рдлреЗрдВрдХрдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ window.location.hostname === "example.com" рдХреЛ рд╕рддреНрдп рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЗрд╕рдХреЗ рд╕реНрд╡рд░реВрдк рд╕реЗ , jsdom рдЕрдм window.location рдХреЛ рдЕрдХреНрд╖рдореНрдп рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ ред рднреАрддрд░ рдореВрд▓реНрдпреЛрдВ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реА рд░рд╛рд╕реНрддрд╛ window.location рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ reconfigure , рд▓реЗрдХрд┐рди (# 2460 рдХреЗ рдЕрдиреБрд╕рд╛рд░) рдЬреЗрд╕реНрдЯ рдХрд╛ рдЦреБрд▓рд╛рд╕рд╛ рдирд╣реАрдВ рдХрд░рддрд╛ jsdom рдкрд░реАрдХреНрд╖рдг рдХреЗ рд╕рд╛рде рдЪрд╛рд░реЛрдВ рдУрд░ рдЦреЗрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЗ рд▓рд┐рдПред

рдХреГрдкрдпрд╛ рдЕрдкрдирд╛ рд╕рдЯреАрдХ рдЬреЗрд╕реНрдЯ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдкреНрд░рджрд╛рди рдХрд░реЗрдВ рдФрд░ рдЕрдкрдиреЗ рдЬреЗрд╕реНрдЯ, рдиреЛрдб рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░реЗрдВ,рдпрд╛рд░реНрди/рдПрдирдкреАрдПрдо рд╕рдВрд╕реНрдХрд░рдг рдФрд░ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдоред

рдЬреЗрд╕реНрдЯ рд╕рдВрд╕реНрдХрд░рдг : 22.0.1
рдиреЛрдб рд╕рдВрд╕реНрдХрд░рдг : 8.6.0
рдпрд╛рд░реНрди рд╕рдВрд╕реНрдХрд░рдг : 1.2.0
рдУрдПрд╕ : рдореИрдХреЛрдЬрд╝ рд╣рд╛рдИ рд╕рд┐рдПрд░рд╛ 10.13.2

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдореИрдВрдиреЗ npm рдкрд░ jest-environment-jsdom-global рдирд╛рдордХ рдПрдХ рдирдпрд╛ рдкреИрдХреЗрдЬ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд┐рдпрд╛ рд╣реИ, рдЬреЛ рдХреБрдЫ рд▓реЛрдЧреЛрдВ рдХреЛ Object.defineProperty рд╕рд╛рде рд╣реЛрдиреЗ рд╡рд╛рд▓реА рд╕рдорд╕реНрдпрд╛рдУрдВ рдореЗрдВ рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рд╕рднреА 78 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдореЗрд░реЗ рдкрд╛рд╕ рдРрд╕рд╛ рд╣реА рдореБрджреНрджрд╛ рд╣реИред рдЖрдк рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛ JSDOEnvironment рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ jsdom рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдЗрд╕ рддрд░рд╣ рдЧреНрд▓реЛрдмрд▓ рдореЗрдВ рдПрдХреНрд╕рдкреЛрдЬрд╝ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

const JSDOMEnvironment = require('jest-environment-jsdom');

module.exports = class CustomizedJSDomEnvironment extends JSDOMEnvironment {
  constructor(config) {
    super(config);
    this.global.jsdom = this.dom;
  }

  teardown() {
    this.global.jsdom = null;
    return super.teardown();
  }
};

рдФрд░ рдлрд┐рд░ рдЖрдк рдЕрдкрдиреЗ рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓реЗ рдореЗрдВ jsdom.reconfigure рдХреЛ рдЕрдкрдиреА рдкрд╕рдВрдж рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ

рдпрд╣ рдПрдХ рдЕрдЪреНрдЫрд╛ рд╕рдорд╛рдзрд╛рди рд╣реИ, рд╕рд╛рдЭрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!

рдЖрдкрдХреЛ super.teardown(); рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдПрдХ рд╡рд╛рджрд╛ рд╣реИ, рдмреАрдЯреАрдбрдмреНрд▓реНрдпреВ

рдмрд┐рд▓реНрдХреБрд▓ рд╕рд╣реА, @oliverzy - рдореИрдВ рдЗрд╕реЗ рдЖрдЬрд╝рдорд╛ рджреВрдВрдЧрд╛ред рдзрдиреНрдпрд╡рд╛рдж!

рдХреНрдпрд╛ рдЗрд╕рдХрд╛ рджрд╕реНрддрд╛рд╡реЗрдЬреАрдХрд░рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдЙрдкрдпреБрдХреНрдд рд╕реНрдерд╛рди рд╣реИ? рдпрд╣ рдПрдХ рдРрд╕рд╛ рдкреНрд░рд╢реНрди рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ рдЬреЛ рдпрдереЛрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЕрдХреНрд╕рд░ рдЙрдарддрд╛ рд╣реИ; рдЙрдореНрдореАрдж рд╣реИ, рднрд╡рд┐рд╖реНрдп рдХреЗ рдореБрджреНрджреЛрдВ рдореЗрдВ рдХрдЯреМрддреА рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ рдЕрдЧрд░ рдЗрд╕реЗ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдореЗрдВ рдПрдХреАрдХреГрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реЛ?

рдпрд╣ рд╕рдорд╛рдзрд╛рди рдХрд╛рдлреА рдХрд╛рдо рдирд╣реАрдВ рдЖрдпрд╛ред

рд╣рдорд╛рд░реА рдкрд░реАрдХреНрд╖рдг рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рдЕрдВрджрд░, рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ global рдХреЛ JSDom рдХреА window рд╡рд╕реНрддреБ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдПрдХ рдкрд░реАрдХреНрд╖рдг рд╕реВрдЯ рдХреЗ рдЕрдВрджрд░, global рд╕рдорд╛рди рд╣реИ window , рд▓реЗрдХрд┐рди рдЙрд╕ рд╡рд░реНрдЧ рдХреЗ рдЕрдВрджрд░ рдЬреЛ JSDOMEnvironment , global рдиреЛрдб рдХреЗ рд╡рд╛рддрд╛рд╡рд░рдг рд╕реЗ рдЖрддрд╛ рд╣реИред

рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдЗрд╕рдХрд╛ рд╣реЛрдирд╛:

describe("test suite", () => {
  it("should not fail", () => {
    global.jsdom.reconfigure({
      url: "https://www.example.com/"
    });
  });
});

рд╡рд┐рдлрд▓ рд░рд╣рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ global.jsdom рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реИред

рдРрд╕рд╛ рдХрд░рдХреЗ рдореИрдВ рдЗрд╕рд╕реЗ рдЙрдмрд░ рдЧрдпрд╛, рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╣реБрдд рдЬреНрдпрд╛рджрд╛ рдкрд░реЗрд╢рд╛рди рдирд╣реАрдВ рд╣реВрдВред

const JSDOMEnvironment = require("jest-environment-jsdom");

module.exports = class JSDOMEnvironmentGlobal extends JSDOMEnvironment {
  constructor(config) {
    super(config);

    this.dom.window.jsdom = this.dom;
  }
};

рдЗрд╕ рд╡рд╛рддрд╛рд╡рд░рдг рдХреЗ рд╕рд╛рде, рдкрд░реАрдХреНрд╖рдг рд╕реВрдЯ рдХреЗ рдЕрдВрджрд░ global.jsdom рдмрд░рд╛рдмрд░ рд╣реИ this.dom , рдФрд░ рдЙрдкрд░реЛрдХреНрдд рдкрд░реАрдХреНрд╖рдг рд╕реВрдЯ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рдореЗрд░реЗ рд▓рд┐рдП, рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ jsdom рдХреЛ рдЕрдкрдиреА window рд╡рд╕реНрддреБ рдХреА рд╕рдВрдкрддреНрддрд┐ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЗрдЯ рдХрд░рдирд╛ рдЕрдВрддрддрдГ рдЕрд▓рдЧ рд╣реЛ рдЬрд╛рдПрдЧрд╛ - рдХреНрдпрд╛ рдРрд╕рд╛ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдХреНрд▓реАрдирд░ рддрд░реАрдХрд╛ рд╣реИ?

рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ global.jsdom рдмрдЬрд╛рдп jsdom рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛ред

@oliverzy рдЗрд╕ рддрд░рд╣?

describe("test suite", () => {
  it("should not fail", () => {
    jsdom.reconfigure({
      url: "https://www.example.com/"
    });
  });
});

рдпрд╣ jsdom is not defined рдлреЗрдВрдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдЧрд▓рдд рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред

@ simon360 рдХреГрдкрдпрд╛ testEnvironment рдХреЛ @oliverzy рдХреЗ рдХреЛрдб рд╕реЗ https://facebook.github.io/jest/docs/en/configuration.html#testenvironment -string

@danielbayerlein рдореЗрд░реЗ рдЬреЗрд╕реНрдЯ рдХреЙрдиреНрдлрд┐рдЧ рдореЗрдВ рдпрд╣ рд╣реИ:

"testEnvironment": "@wel-ui/jest-environment-jsdom-global"

рдЬрд╣рд╛рдВ @wel-ui/jest-environment-jsdom-global рд╣рдорд╛рд░реЗ рдореЛрдиреЛрд░реЗрдкреЛ рдореЗрдВ рдПрдХ рдкреИрдХреЗрдЬ рдХрд╛ рдирд╛рдо рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдкрд░реНрдпрд╛рд╡рд░рдг рдХрд╛ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╕рдорд╛рдзрд╛рди рдЬреЛ jsdom рдХреЛ window рдХрд░рддрд╛ рд╣реИ рд╡рд╣ рдЕрдкреЗрдХреНрд╖рд╛ рдХреЗ рдЕрдиреБрд░реВрдк рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рдмреАрдЯреАрдбрдмреНрд▓реВ, рдХреНрдпрд╛ рдХрд┐рд╕реА рдХреЛ рдкрддрд╛ рд╣реИ рдХрд┐ рдореВрд▓ рд╕рдорд╛рдзрд╛рди рдирдП рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдХреНрдпреЛрдВ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ?
рдпрд╣ рд╡рд╛рд▓рд╛:

Object.defineProperty(location, "hostname", {
  value: "example.com",
  writable: true
});

@modestfake рд╣рдордиреЗ JSDOM@9 рд╕реЗ JSDOM@11 рдореЗрдВ рдЕрдкрдЧреНрд░реЗрдб рдХрд┐рдпрд╛ рд╣реИ, рдореЗрд░рд╛ рдЕрдиреБрдорд╛рди рд╣реИ рдХрд┐ рд╡реЗ рдмрджрд▓ рдЧрдП рд╣реИрдВ рдХрд┐ рдЪрд░ рдХреИрд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ

@SimenB рд╕рдордЭ рдЧрдпрд╛ред рдмрд╕ jsdom reconfigure рд╡рд┐рдзрд┐ рдХрд╛ рд╡рд┐рд╡рд░рдг рдорд┐рд▓рд╛ред

рд╡рд┐рдВрдбреЛ рдкрд░ рд╢реАрд░реНрд╖ рд╕рдВрдкрддреНрддрд┐ рдХреЛ [рдЕрд╡рд┐рд╕реНрдорд░рдгреАрдп] рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдЧреИрд░-рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рд╕рдВрдкрддреНрддрд┐ рд╣реИ рдФрд░ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдСрдмреНрдЬреЗрдХреНрдЯ.рдбрд┐рдлрд╛рдЗрдирдкреНрд░реЙрдкрд░реНрдЯреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЬреЗрдПрд╕рдбреЙрдо рдХреЗ рдЕрдВрджрд░ рдЪрд▓ рд░рд╣реЗ рд╕рд╛рдорд╛рдиреНрдп рдХреЛрдб рджреНрд╡рд╛рд░рд╛ рдУрд╡рд░рд░рд╛рдЗрдб рдпрд╛ рдЫрд╛рдпрд╛рдВрдХрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдореИрдВрдиреЗ рдЗрд╕ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рднрдВрдбрд╛рд░ рдЬреЛрдбрд╝рд╛ред рдХреНрдпрд╛ рдХреЛрдИ рд╕реНрдерд╛рдиреАрдп рд░реВрдк рд╕реЗ рдХреНрд▓реЛрди рдХрд░рдХреЗ рдЗрд╕реЗ рдкреБрди: рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИ?

https://github.com/simon360/test-environment-for-jest

@simon360 рдкреБрди: рдкреЗрд╢ рдХрд┐рдпрд╛ рдЧрдпрд╛
image

@ рд╕рд╛рдЗрдорди 360 рдореИрдВрдиреЗ рдкрд╛рдпрд╛ рд╣реИред рдЖрдк рдирд╣реАрдВ рдЫреВрдЯрд╛ рд╣реИ this рдХреАрд╡рд░реНрдб рдЬрдм рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ global.jsdom :

const JSDOMEnvironment = require("jest-environment-jsdom");

module.exports = class JSDOMEnvironmentGlobal extends JSDOMEnvironment {
  constructor(config) {
    super(config);

    this.global.jsdom = this.dom;
  }

  teardown() {
    this.global.jsdom = null;

    return super.teardown();
  }
};

location.search рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛? рдореИрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдпрд╣ рдХрд┐рд╕реА рднреА рдЙрд▓реНрд▓реЗрдЦ рдирд╣реАрдВ рдорд┐рд▓рд╛ https://github.com/tmpvar/jsdom/blob/05a6deb6b91b4e02c53ce240116146e59f7e14d7/README.md#reconfiguring -рдЗрд╕-jsdom-рд╕рд╛рде-reconfiguresettings

@andrewBalekha рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛?

jsdom.reconfigure({
  url: 'https://www.example.com/endpoint?queryparam1=15&queryparam2=test'
});

рдзрдиреНрдпрд╡рд╛рдж @modestfake - рдЧреВрдВрдЧрд╛ рдЧрд▓рддреА рдХреЗ рд▓рд┐рдП рдЦреЗрдж рд╣реИ!

рдареАрдХ рд╣реИ, рдореИрдВ рдЗрд╕реЗ рдЕрднреА рджреЗрдЦрддрд╛ рд╣реВрдВ - рдЬреЗрд╕реНрдЯ рдкрд░реНрдпрд╛рд╡рд░рдг рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ this.global рдЬреЗрд╕реНрдЯ рдкрд░реАрдХреНрд╖рдг рдлрд╝рд╛рдЗрд▓ рдореЗрдВ global рд░реВрдк рдореЗрдВ рд╕реЗрдЯ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ - рдЗрд╕рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдореЗрд░реА рдорджрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж! рдЕрдЧрд░ рд╡рд╣рд╛рдБ рд╣реИ рдкрд░реНрдпрд╛рдкреНрдд рд░реБрдЪрд┐ рд╣реИ, рдореИрдВ рдЙрд╕ рд░реЗрдкреЛ рдХреА рдорд░рдореНрдордд рд╕рдВрд╕реНрдХрд░рдг рдкреИрдХреЗрдЬ рдФрд░ рдкрд░ рдбрд╛рд▓ рд╕рдХрддрд╛ рд╣реИ npm рдХреЗ рд░реВрдк рдореЗрдВ jest-environment-jsdom-global ред

рд╣рд╛рд▓рд╛рдВрдХрд┐, рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдЬреЗрд╕реНрдЯ рдореЗрдВ рдРрд╕рд╛ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рд╕рд╛рдл рддрд░реАрдХрд╛ рд╣реИред рдпрд╣ window.location рдХреЛ рдмрджрд▓рдиреЗ рдХрд╛ рдХрдо рдШрд░реНрд╖рдг рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ -

рдХреНрдпрд╛ рдХреЛрдИ рдирдпрд╛ рдбреЙрдХрдмреНрд▓реЙрдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЬреИрд╕реЗ @jest-environment ? рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП...

/**
 * @jest-url https://www.example.com/
 */

рдпрд╛, рд╢рд╛рдпрдж JSDom рдХреЛ jest рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдПрдХ рд╡рд┐рд╢реЗрд╖ рднрд╛рдЧ рдкрд░ рдЙрдЬрд╛рдЧрд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ - рдХреБрдЫ рдРрд╕рд╛:

jest.environment.jsdom.reconfigure({
  url: "https://www.example.com/"
});

(рдЬрд┐рд╕реЗ window.top рдмрджрд▓рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХрд╛ рдЕрддрд┐рд░рд┐рдХреНрдд рд▓рд╛рдн рд╣реЛрдЧрд╛)

рд╣рдордиреЗ рдЕрдм #5003 рдХрд╛ рд╡рд┐рд▓рдп рдХрд░ рджрд┐рдпрд╛ рд╣реИред рдЗрд╕реЗ рдбреЙрдХрдмреНрд▓реЙрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдЬреЛрдбрд╝рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рд╕реЗ рд╕рдордЭ рдореЗрдВ рдЖ рд╕рдХрддрд╛ рд╣реИ, рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реИред @cpojer? рд╣рдо testUrl рдХреЛ рднреА рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЙрд╕ рдирдП рд╡рд┐рдХрд▓реНрдк рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдЕрдЧрд░ рд╡рд╣рд╛рдБ рд╣реИ рдкрд░реНрдпрд╛рдкреНрдд рд░реБрдЪрд┐ рд╣реИ, рдореИрдВ рдЙрд╕ рд░реЗрдкреЛ рдХреА рдорд░рдореНрдордд рд╕рдВрд╕реНрдХрд░рдг рдкреИрдХреЗрдЬ рдФрд░ рдкрд░ рдбрд╛рд▓ рд╕рдХрддрд╛ рд╣реИ npm рдХреЗ рд░реВрдк рдореЗрдВ jest-environment-jsdom-global ред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ рдпрд╣ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЖрдкрдХреЛ рдпреВрдЖрд░рдПрд▓ рд╕реЗрдЯ рдХрд░рдиреЗ рд╕реЗ рдЬреНрдпрд╛рджрд╛ рдХреБрдЫ рдХрд░рддрд╛ рд╣реИ - рдпрд╣ рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЗ рд▓рд┐рдП рдкреВрд░реНрдг рдЬреЗрдПрд╕рдбреАрдУрдПрдо рдХрд╛ рдЦреБрд▓рд╛рд╕рд╛ рдХрд░рддрд╛ рд╣реИ

@andrewBalekha Object.defineProperty(location, 'search', { ...options }); рдЙрд╕реА рддреНрд░реБрдЯрд┐ рдХреЛ window.location рд░реВрдк рдореЗрдВ рдлреЗрдВрдХрддрд╛ рд╣реИред рдлрд┐рд░ рднреА рд╕реБрдЭрд╛рд╡ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред

Object.defineProperty(window.location, 'href', {
рд╕реЗрдЯ: newValue => {currentUrl = newValue; },
});
рдореЗрд░реЗ рдкрд╛рд╕ рдкрд┐рдЫрд▓реЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдореЗрдВ рдпрд╣ рдерд╛ рдФрд░ рдЕрдм рддреНрд░реБрдЯрд┐ рдлреЗрдВрдХрддрд╛ рд╣реИред
рдЕрдЧрд░ рдореИрдВ рд▓рд┐рдЦрдиреЗ рдпреЛрдЧреНрдп рдЬреЛрдбрд╝ рджреВрдВ: рд╕рдЪ
рдПрдХ рдФрд░ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХрддрд╛ рд╣реИ рдХрд┐ рдореИрдВ рдПрдХреНрд╕реЗрд╕рд░ рдФрд░ рд▓рд┐рдЦрдиреЗ рдпреЛрдЧреНрдп рджреЛрдиреЛрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛

рдореИрдВрдиреЗ npm рдкрд░ jest-environment-jsdom-global рдирд╛рдордХ рдПрдХ рдирдпрд╛ рдкреИрдХреЗрдЬ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд┐рдпрд╛ рд╣реИ, рдЬреЛ рдХреБрдЫ рд▓реЛрдЧреЛрдВ рдХреЛ Object.defineProperty рд╕рд╛рде рд╣реЛрдиреЗ рд╡рд╛рд▓реА рд╕рдорд╕реНрдпрд╛рдУрдВ рдореЗрдВ рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рдХреНрдпрд╛ рдХрд┐рд╕реА рдХреЗ рдкрд╛рд╕ { writable: true } рд▓рд┐рдП рдХреЛрдИ рд╕рдорд╛рдзрд╛рди рд╣реИ?

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

Object.defineProperty(window.location, 'href', { writable: true })

...

Object.defineProperty(window.location, 'hash', { writable: true })

...

Object.defineProperty(window.location, 'search', { writable: true })

@danielbayerlein рдЗрд╕ рд╕реВрддреНрд░ рдХреЛ рдкрдврд╝реЗрдВред рдЖрдкрдХреЛ рдХрд╕реНрдЯрдо рд╡рд╛рддрд╛рд╡рд░рдг рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдкрд┐рдЫрд▓реЗ рд╕рдВрджреЗрд╢ рдореЗрдВ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде url рд╢рд╛рдорд┐рд▓ рд╣реИ

@modestfake рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рд╣реА рдЗрд╕ рдзрд╛рдЧреЗ рдХреЛ рдкрдврд╝ рд▓рд┐рдпрд╛ рд╣реИ рдФрд░ https://github.com/facebook/jest/issues/5124#issuecomment -352749005 рдареАрдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рдФрд░ рдЙрдкрдпреЛрдЧ рдХрд╛ рдорд╛рдорд▓рд╛ рд╣реИред рдЬреЗрд╕реНрдЯ 21.xx рдХреЗ рд╕рд╛рде рдореИрдВрдиреЗ рдпреВрдЖрд░рдПрд▓ рдХреЗ рдмрд┐рдирд╛ Object.defineProperty(window.location, 'href', { writable: true }) рд╕реЗрдЯ рдХрд┐рдпрд╛ рд╣реИ - рдХреЗрд╡рд▓ { writable: true } ред рдЕрдЧрд░ рдореИрдВ рдпреВрдЖрд░рдПрд▓ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реВрдВ, рддреЛ рдкрд░реАрдХреНрд╖рдг рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИред

@danielbayerlein рдЗрд╕реЗ рд▓рд┐рдЦрдиреЗ рдпреЛрдЧреНрдп рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд╛ рдорд╛рдорд▓рд╛ рдХреНрдпрд╛ рд╣реИ рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕реЗ рдУрд╡рд░рд░рд╛рдЗрдб рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ? рд╢рд╛рдпрдж рдЗрд╕реЗ рд╕рдордЭрдиреЗ рд╕реЗ рдореБрдЭреЗ рд╕рдорд╛рдзрд╛рди рдирд┐рдХрд╛рд▓рдиреЗ рдореЗрдВ рдорджрдж рдорд┐рд▓ рд╕рдХрддреА рд╣реИ

рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рдРрд╕рд╛ рдлрд╝рдВрдХреНрд╢рди рд╣реИ рдЬреЛ рдпреВрдЖрд░рдПрд▓ рдмрджрд▓рддрд╛ рд╣реИред

рд░реВрдЯрд┐рдВрдЧ.рдЬреЗрдПрд╕

...

export function redirectToErrorPage () {
  window.location.href = '/error.html'
}

...

рд░реВрдЯрд┐рдВрдЧ.рдЯреЗрд╕реНрдЯ.рдЬреЗрдПрд╕

test('redirect to the error page', () => {
  ...
  expect(window.location.href).toBe('/error.html')
  ...
})

рдЬреЗрд╕реНрдЯ 21.xx рдХреЗ рд╕рд╛рде рдореИрдВрдиреЗ Object.defineProperty(window.location, 'href', { writable: true })

рдореИрдВ window.location.assign рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХреА рдЕрдиреБрд╢рдВрд╕рд╛ рдХрд░рддрд╛ рд╣реВрдВ, рдЗрд╕ рддрд░рд╣ рдЖрдк рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдордЬрд╝рд╛рдХ рдЙрдбрд╝рд╛ рд╕рдХрддреЗ рд╣реИрдВред

@ рд╕рд╛рдЗрдорди 360 рдПрдХ рдЖрдХрд░реНрд╖рдг рдХреА рддрд░рд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ! рд╢реБрдХреНрд░рд┐рдпрд╛ред рдореИрдВ

рдореИрдВрдиреЗрдВ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛

history.pushState({}, "page 2", "/bar.html");

рд╕рд╛рде рдореЗрдВ testURL рдЬреЗрд╕реНрдЯ рдХреЙрдиреНрдлрд┐рдЧ рдореЗрдВ

рд╕реНрдерд╛рди рднрд╛рдЧ рд╣реА рдПрдХрдорд╛рддреНрд░ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИред рдореИрдВ jsdom рдХреЛ jsdom.reconfigureWindow рдкрд░ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрд▓рдЧ рд╕реЗ рдЖрдпрд╛рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ (рдХреНрдпреЛрдВрдХрд┐ рд╡рд╣ рдлрд╝рдВрдХреНрд╢рди рдЕрдм jsdom рдХреЗ рдирд╡реАрдирддрдо рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИ)ред рдореИрдВ рдХреЛрдб рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдРрд╕рд╛ рдХрд░ рд░рд╣рд╛ рдерд╛ рдЬреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЪрд▓рддрд╛ рд╣реИ рдпрджрд┐ window !== top ред рдЬреЗрд╕реНрдЯ рдХреЗ рдирд╡реАрдирддрдо рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ, рдЬреЛ jsdom рдХреЗ рдирдП рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред

@andyearnshaw jsdom.reconfigure рд╡рд┐рдзрд┐ рдХреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ windowTop рд╕рджрд╕реНрдп рд╣реИред

рдпрджрд┐ рдЖрдк рдКрдкрд░ рд▓рд┐рдВрдХ рдХрд┐рдП рдЧрдП JSDOM рдкрд░рд┐рд╡реЗрд╢ ( jest-environment-jsdom-global ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдЖрдк рдпрд╣ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

jsdom.reconfigure({
  windowTop: YOUR_VALUE
});

рдЕрдкрдиреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдПрдХ рд╢реАрд░реНрд╖ рдореВрд▓реНрдп рдХрд╛ рдордЬрд╛рдХ рдЙрдбрд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдПред

рдореИрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдФрд░ рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдзрдиреНрдпрд╡рд╛рдж!

рдордВрдЧрд▓, 30 рдЬрдирд╡рд░реА 2018, 13:40 simon360 рдкрд░, [email protected] рд▓рд┐рдЦрд╛ рд╣реИ:

@andyearnshaw https://github.com/andyearnshaw jsdom.reconfigure
рд╡рд┐рдзрд┐ рдореЗрдВ рдЗрд╕рдХреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдПрдХ рд╡рд┐рдВрдбреЛрдЯреЙрдк рд╕рджрд╕реНрдп рд╣реИред

рдпрджрд┐ рдЖрдк JSDOM рд╡рд╛рддрд╛рд╡рд░рдг (jest-environment-jsdom-global) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рддреЛ I
рдКрдкрд░ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ, рдЖрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

jsdom.reconfigure({
рд╡рд┐рдВрдбреЛрдЯреЙрдк: Your_VALUE
});

рдЕрдкрдиреЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдПрдХ рд╢реАрд░реНрд╖ рдореВрд▓реНрдп рдХрд╛ рдордЬрд╛рдХ рдЙрдбрд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдПред

-
рдЖрдк рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рд╕реАрдзреЗ рдЙрддреНрддрд░ рджреЗрдВ, рдЗрд╕реЗ GitHub рдкрд░ рджреЗрдЦреЗрдВ
https://github.com/facebook/jest/issues/5124#issuecomment-361595999 , рдпрд╛ рдореНрдпреВрдЯ рдХрд░реЗрдВ
рд╕реВрддреНрд░
https://github.com/notifications/unsubscribe-auth/ABvdEzCLlWtzr0udscL0C6KUxpgXHZRhks5tPxvJgaJpZM4RGN7C
.

window.history.pushState рдФрд░ testUrl рдХрд░рдирд╛ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░ рдЧрдпрд╛

https://github.com/facebook/jest/issues/5124#issuecomment -359411593

рдЗрд╕реЗ рдмрдВрдж рдХрд░рдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдЬреЗрд╕реНрдЯ рдХреА рддрд░рдл рд╕реЗ рдХреЛрдИ рд▓реЗрдирд╛-рджреЗрдирд╛ рдирд╣реАрдВ рд╣реИ, рдФрд░ рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб рдореМрдЬреВрдж рд╣реИрдВ (рдЪрд░реНрдЪрд╛ рдЬрд╛рд░реА рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВ!)

Jsdom v8.5.0 рд╕реЗ v11.6.2 рдореЗрдВ рдЕрдкрдЧреНрд░реЗрдб рдХрд░рдиреЗ рд╕реЗ рдореЗрд░реЗ рд▓рд┐рдП рд╕рдорд╕реНрдпрд╛ рд╣рд▓ рд╣реЛ рдЧрдИред рддреЛ рдореЗрд░реЗ package.json рд╢рд╛рдорд┐рд▓ рд╣реИрдВ:

"jest": "^21.2.1",
"jest-cli": "^21.2.1",
"jsdom": "^11.6.2",

рдЕрдЧрд░ рдореИрдВ рдЬреЗрд╕реНрдЯ рдФрд░ рдЬреЗрд╕реНрдЯ-рдХреНрд▓реА рдХреЛ v22.2.2 рдореЗрдВ рдЕрдкрдЧреНрд░реЗрдб рдХрд░рддрд╛ рд╣реВрдВ рддреЛ рдпрд╣ рдЯреВрдЯ рдЬрд╛рддрд╛ рд╣реИред

@andr-3-w рдХреЛрдИ рд╡рд┐рд╢реЗрд╖ рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдЖрдкрдХреЗ package.json рдореЗрдВ jsdom рдХреНрдпреЛрдВ рд╣реИ? рдпрд╣ рдЬреЗрд╕реНрдЯ рдХреЗ рд╕рд╛рде рдмрдВрдбрд▓ рдореЗрдВ рдЖрддрд╛ рд╣реИред

@SimenB , рдЕрдЪреНрдЫрд╛ рд╕рд╡рд╛рд▓ рд╣реИ, рд╣рдорд╛рд░реЗ package.json jsdom рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред рдзрдиреНрдпрд╡рд╛рдж!

рддреЛ, рд╕реАрдзреЗ jsdom рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдмрд┐рдирд╛, рдпрд╣рд╛рдБ рд╕рдорд╛рдзрд╛рди рд╣реИ рдЬреЛ рдореИрдВ рдЕрдкрдиреЗ рд╕рд╛рдорд╛рди рдХреЗ рд▓рд┐рдП рдЖрдпрд╛ рд╣реВрдБ:

рдЬреЗрд╕реНрдЯ 21.2.1 рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ (рдореИрдВрдиреЗ рдЙрд╕ рдкрд░ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛):

рдЕрдкрдиреА рдЬреЗрд╕реНрдЯ рд╕реЗрдЯрд┐рдВрдЧ рдореЗрдВ рдЬрд╛рдПрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдореИрдВ package.json рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛):

"jest": { "testURL": "http://localhost" }

рдЕрдм рдЖрдк window.location рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдмрджрд▓рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдВрдЧреЗ рдФрд░ рдлрд┐рд░ рдЖрдк рдкрд░реАрдХреНрд╖рдг рдХреЗ рджреМрд░рд╛рди рдЕрдкрдиреА рдкрд╕рдВрдж рдХреЗ рдЕрдиреБрд╕рд╛рд░ URL рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

it('Should set href url to testURL', () => {
    // Here I set href to my needs, opinionated stuff bellow
    const newUrl = 'http://localhost/editor.html/content/raiweb/it/news/2018/02/altered-carbon-best-cyberpunk-tv-series-ever.html';
    Object.defineProperty(window.location, 'href', {
        writable: true,
        value: newUrl
    });

    console.log(window.location.href);
});

it('Should set pathname url to testURL', () => {
    // Here I set href to my needs, opinionated stuff bellow
    const newUrl = '/editor.html/content/raiweb/it/news/2018/02/altered-carbon-best-cyberpunk-tv-series-ever.html';
    Object.defineProperty(window.location, 'pathname', {
        writable: true,
        value: newUrl
    });

    console.log(window.location.pathname);
});

рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рдХрд┐рд╕реА рдХреА рдорджрдж рдХрд░рддрд╛ рд╣реИред

рдЗрд╕реЗ рдкреЛрд╕реНрдЯ рдХрд░рдирд╛ рдмрдВрдж рдХрд░реЛ, рдпрд╣ рдордЬрд╛рдХ рдкрд░ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛": "^22.4.2"

@UserNT рдореИрдВрдиреЗ рдЙрд╕ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдиреЛрдЯ рдХрд┐рдпрд╛ рдЬрд┐рд╕ рдкрд░ рдпрд╣ рдпрд╣рд╛рдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдореИрдВ рдЗрд╕реЗ рдмрдбрд╝реЗ рдкреИрдорд╛рдиреЗ рдкрд░ рдЙрддреНрдкрд╛рджрди рдкрд░реАрдХреНрд╖рдг рд╕реВрдЯ рдкрд░ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВред рдпрджрд┐ рдпрд╣ рдирдП рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдкрд░ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдореБрдЭреЗ рдЦреЗрдж рд╣реИ, рдХреЗрд╡рд▓ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдХреЛрд╕рдиреЗ рдХреЗ рдмрдЬрд╛рдп рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рд╕рдорд╛рдзрд╛рди рдХреЗ рд╕рд╛рде рдЖрдПрдВред

рдХреЗрд╡рд▓ рдкреВрд░реНрдгрддрд╛ рдХреЗ рд▓рд┐рдП, рдЪреВрдВрдХрд┐ рд╕рдорд╛рдзрд╛рди рдЗрд╕ рдзрд╛рдЧреЗ рдХреЗ рдмреАрдЪ рдореЗрдВ рдлрдВрд╕рд╛ рд╣реБрдЖ рд╣реИ...

@ petar-prog91 рдХрд╛ рд╕рдорд╛рдзрд╛рди Jest 21 рдкрд░ рдХрд╛рдо рдХрд░реЗрдЧрд╛, рд▓реЗрдХрд┐рди рдЕрджреНрдпрддрди рдХрд┐рдП рдЧрдП jsdom рд╕рд╛рде Jest 22 рдкрд░ рдирд╣реАрдВред

рдирд╡реАрдирддрдо рдЬреЗрд╕реНрдЯ рдкрд░ рдЪрд▓рдиреЗ рдХреЗ рд▓рд┐рдП, jest-environment-jsdom-global (рдкреВрд░реНрдг рдкреНрд░рдХрдЯреАрдХрд░рдг, рдпрд╣ рдореЗрд░рд╛ рдкреИрдХреЗрдЬ рд╣реИ) рдЬреИрд╕реА рдХрд┐рд╕реА рдЪреАрдЬрд╝ рдХрд╛ рдЙрдкрдпреЛрдЧ jsdom.reconfigure jsdom рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдЙрдЬрд╛рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░реЗрдВ рдФрд░

https://github.com/facebook/jest/issues/5124#issuecomment -359411593 рдореЗрд░реЗ рд▓рд┐рдП рдЬреЗрд╕реНрдЯ 22 рдкрд░ рднреА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ

@ simon360 рдирдорд╕реНрддреЗ, рдЕрдЧрд░ рдореБрдЭреЗ location.href рдХреЗ рд╕реЗрдЯрд░ рдХреЛ рд╣реИрдХ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рддреЛ рдореБрдЭреЗ рдХреНрдпрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП?
рдореЗрд░реЗ рдкрд┐рдЫрд▓реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХреЗ рдХрдИ рдкрд░реАрдХреНрд╖рдг рд╣реИрдВ рдФрд░ рдЕрдм рд╕рднреА рд╡рд┐рдлрд▓ рд╣реЛ рдЧрдП рд╣реИрдВ ...

const setHrefMockFn = jest.fn();
beforeAll(() => {
  Object.defineProperty(location, "href", {
    get: () => "https://xxxxx",
    set: setHrefMockFn
  });
});
it("xxx", () => {
  //...
  expect(setHrefMockFn.mock.calls[0][0]).toBe(xxx);
});

@ рд╕рд╛рдЗрдорди 360 рдХреНрдпрд╛ рдЖрдк рдореБрдЭреЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреЗ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЕрдкрдиреА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рд╕рд╛рде рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдЯреЗрд╕реНрдЯ рдХреЛ рдХреИрд╕реЗ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВ?

beforeAll(() => {
  =======

  Object.defineProperty(window.location, 'href', {
    writable: true
  });
});

@abhijeetNmishra рдХреНрдпрд╛ рдЖрдкрдиреЗ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рджреЗрдЦрд╛ рд╣реИ? рдореБрдЭреЗ рд╡рд┐рд╢реНрд╡рд╛рд╕ рд╣реИ рдХрд┐ рдпрд╣ рдЖрдкрдХреЗ рдкреНрд░рд╢реНрди рдХрд╛ рдЙрддреНрддрд░ рджреЗрдЧрд╛ред

@ simon360 рд╣рд╛рдБ, рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдХреА рдореЗрд░реА рд╕рдордЭ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдЗрд╕рдореЗрдВ рд▓рдЧрднрдЧ рд▓рдЧрддрд╛ рд╣реИ

jsdom.reconfigure({
      url: "https://www.example.com/"
    });

рдЬреЛ рд╡рд┐рд╢реНрд╡ рд╕реНрддрд░ рдкрд░ рдпреВрдЖрд░рдПрд▓ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рддрд╛ рд╣реИ рди рдХрд┐ рдкреНрд░рддрд┐ рдкрд░реАрдХреНрд╖рдгред рдХреГрдкрдпрд╛ рд╕рд╣рд╛рдпрддрд╛ рдХреАрдЬрд┐рдП!

@abhijeetNmisra рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдореБрджреНрджрд╛ рдЪрд░реНрдЪрд╛ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рдЕрдЪреНрдЫреА рдЬрдЧрд╣ рд╣реИред рдХреНрдпрд╛ рдЖрдк jest-environment-jsdom-global рд░рд┐рдкреЛрдЬрд┐рдЯрд░реА рдкрд░ рдПрдХ рдореБрджреНрджрд╛ рдЦреЛрд▓рдирд╛ рдЪрд╛рд╣реЗрдВрдЧреЗ рдЬрд╣рд╛рдВ рд╣рдо рдЗрд╕рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд╛рдо рдХрд░ рд╕рдХреЗрдВ? рдзрдиреНрдпрд╡рд╛рдж!

@SimenB рдиреЗ рдХрд╣рд╛ рдХрд┐ рд╡рд░реНрдХрдЕрд░рд╛рдЙрдВрдб (" jest-environment-jsdom-global ") рдПрдХ рдЕрддреНрдпрдВрдд рдЙрдк-рд╕рдорд╛рдзрд╛рди рдХреА рддрд░рд╣ рд▓рдЧрддрд╛ рд╣реИ рдЬреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдПрдХ рдмрд╣реБрдд рд╣реА рд╕рд╛рдорд╛рдиреНрдп рд╕рдорд╕реНрдпрд╛ рд╣реИред рдЬреЗрд╕реНрдЯ 22 рдореЗрдВ рдЕрдкрдЧреНрд░реЗрдб рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХрд┐рд╕реА рднреА рд╡реНрдпрдХреНрддрд┐ рдХреЛ рдЕрдм рдЙрд╕ рдерд░реНрдб рдкрд╛рд░реНрдЯреА рдкреИрдХреЗрдЬ рдкрд░ рдирд┐рд░реНрднрд░рддрд╛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ рдФрд░ (рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдирдЬрд░рд┐рдП рд╕реЗ) рдЕрдкрдиреЗ рдХреБрдЫ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛ред рдпрд╣ рдЬреЗрд╕реНрдЯ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рдПрдХ рдкреНрд░рддрд┐рдЧрдорди рд╣реИред

рдХреНрдпрд╛ рдЗрд╕рдХрд╛ рдХреЛрдИ рд╕рдорд╛рдзрд╛рди рд╣реИ рдЬрд┐рд╕реЗ рд╣рдо рдбрд┐рдлрд╝реЙрд▓реНрдЯ jest-environment-jsdom ? рдЖрдкрдХреЗ рдорд╛рд░реНрдЧрджрд░реНрд╢рди рд╕реЗ рдЬрдирд╕рдВрдкрд░реНрдХ рдмрдирд╛рдиреЗ рдореЗрдВ рдЦреБрд╢реА рд╣реЛ рд░рд╣реА рд╣реИред

рдпрд╣ рдмрд╣реБрдд рджреБрд░реНрднрд╛рдЧреНрдпрдкреВрд░реНрдг рд╣реИ рдХрд┐ рдХрд┐рд╕реА рдХреЛ рдХреВрджрдирд╛ рдкрдбрд╝рддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЗрддрдиреЗ рд╕рд╛рд░реЗ рд╣реБрдкреНрд╕ рд╕рд┐рд░реНрдл window.location.href рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИрдВред рдореИрдВрдиреЗ рдЕрднреА рдЬреЗрд╕реНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ рд╣реИ рдФрд░ рдореИрдВ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП рдкрд░реАрдХреНрд╖рдг рдврд╛рдВрдЪреЗ рдХреА рдЕрдкрдиреА рдкрд╕рдВрдж рдкрд░ рдкреБрдирд░реНрд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рд╣реВрдВред рдХреНрдпрд╛ рдКрдкрд░ рд╕реБрдЭрд╛рдП рдЧрдП рдмрджрд╕реВрд░рдд рд╣реИрдХреНрд╕ рд╕реЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреЛрдИ рдмреЗрд╣рддрд░ рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рд╣реИ?

@ydogandjiev рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдпреЛрдЧрджрд╛рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░рддреЗ рд╣реИрдВред рдпрд╛рдж рд░рдЦреЗрдВ рдХрд┐ рдпрд╣ рдЦреБрд▓рд╛ рд╕реНрд░реЛрдд рд╣реИ, рдЗрд╕рд▓рд┐рдП "рдЕрд╕реНрд╡реАрдХрд╛рд░реНрдп" рдФрд░ "рд╣рд╛рд╕реНрдпрд╛рд╕реНрдкрдж" рдЬреИрд╕реА рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд┐рд╕реА рдХреА рдорджрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рднреА рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

@ msholty-fd рдЕрдЧрд░ рдореИрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ рддреЛ рдореБрдЭреЗ рдорджрдж рдХрд░рдирд╛ рдЕрдЪреНрдЫрд╛ рд▓рдЧреЗрдЧрд╛ред рдЪреВрдВрдХрд┐ рдореИрдВ рдЕрднреА рдордЬрд╛рдХ рдФрд░ jsdom рдХреЗ рд╕рд╛рде рд╢реБрд░реБрдЖрдд рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдореБрдЭреЗ рдЗрди рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреА рдЧрд╣рд░реА рд╕рдордЭ рд╣реИ рдХрд┐ рдпрд╣ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдЗрд╕ рдЕрдиреБрднрд╡ рдХреЛ рдмреЗрд╣рддрд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдорд╛рд░реНрдЧ рдХреНрдпрд╛ рд╣реИред рдХреНрдпрд╛ рдпрд╣ рдХреБрдЫ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдордЬрд╛рдХ рдпрд╛ jsdom рдореЗрдВ рд╕рдВрдмреЛрдзрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ? рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрди рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдиреЗ рдХрд┐рд╕реА рдмрд┐рдВрджреБ рдкрд░ рдПрдХ рдмрджрд▓рд╛рд╡ рдХрд┐рдпрд╛ рдЬрд┐рд╕рдиреЗ Object.defineProperty рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рддреЛрдбрд╝ рджрд┐рдпрд╛; рдХреНрдпрд╛ рд╡рд╣ рдмрджрд▓рд╛рд╡ рдордЬрд╝рд╛рдХ рдпрд╛ jsdom рдореЗрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛?

рддреЛ рдпрд╣рд╛рдВ рд╕рднреА рд╡рд┐рдХрд▓реНрдк рджрд┐рдП рдЧрдП рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдореИрдВ рд╡рд┐рдВрдбреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд▓рд╛рдЗрдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдмреЗрд╣рддрд░ рдорд╛рдиреВрдВрдЧрд╛ред рд╕реНрдерд╛рди; рдЗрдирдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ:

  1. href рд╕реАрдзреЗ рд╕реЗрдЯ рдХрд░рдирд╛ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ jsdom рд╕рдВрджреЗрд╢ рдХреЗ рд╕рд╛рде рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХрддрд╛ рд╣реИ "рддреНрд░реБрдЯрд┐: рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛: рдиреЗрд╡рд┐рдЧреЗрд╢рди (рд╣реИрд╢ рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рдЫреЛрдбрд╝рдХрд░)":
    window.location.href = "https://www.example.com";
  1. Object.defineProperty рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ JSDOM рдиреЗ рд╡рд┐рдВрдбреЛ рдХреА рд▓реЛрдХреЗрд╢рди рдкреНрд░реЙрдкрд░реНрдЯреА [рдЕрдирдлрд░реНрдЬреЗрдмрд▓] рдмрдирд╛ рджреА рд╣реИ :

    Object.defineProperty(window.location, "href", {
      value: "https://www.example.com",
      configurable: true
    });
    
  2. Jsdom рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рдирд╛ рдФрд░ рдЗрд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЬреЗрд╕реНрдЯ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдЖрд╕рд╛рди рдкрд╣реБрдВрдЪ рдХреЗ рд▓рд┐рдП рдЙрдЬрд╛рдЧрд░ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ:

    import { JSDOM } from "jsdom";
    ...
    const dom = new JSDOM();
    dom.reconfigure({ url: "https://www.example.com" });
    

рд╡рд┐рдХрд▓реНрдк 1 рдпрд╛ 2 рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП jsdom рдХреЛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреА рддрд░рд╣ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рдиреЗ рдХреЗ рдЕрдкрдиреЗ рд╡рд░реНрддрдорд╛рди рд▓рдХреНрд╖реНрдпреЛрдВ рд╕реЗ рдкреАрдЫреЗ рд╣рдЯрдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕рд▓рд┐рдП, рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХрдорд╛рддреНрд░ рд╡рд┐рдХрд▓реНрдк рд╣реИ рдЬреЛ рдЬреЗрд╕реНрдЯ рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ jsdom рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЛ рдкреБрди: рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛ рдЖрд╕рд╛рди рдмрдирд╛рддрд╛ рд╣реИред рдХреНрдпрд╛ рдЙрд╕ рдЙрджрд╛рд╣рд░рдг рдХреЛ рд╕реАрдзреЗ рд╡реИрд╢реНрд╡рд┐рдХ рдордЬрд╝рд╛рдХ рд╡рд╕реНрддреБ рдкрд░ рдмреЗрдирдХрд╛рдм рдХрд░рдирд╛ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ; рдпрд╛рдиреА рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рдХреА рдЕрдиреБрдорддрд┐:

jest.dom.reconfigure({ url: "https://www.example.com" });

рдореБрдЭреЗ рдЕрдм рднреА рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ location.assign('some-url') рдХрд░рдирд╛ location.href = 'some-url' рд╕реЗ рдмреЗрд╣рддрд░ рд╣реИред рдореБрдЭреЗ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рд╕реЗ рдЕрдзрд┐рдХ рд╕реНрдкрд╖реНрдЯ рд▓рдЧрддрд╛ рд╣реИ, рдФрд░ рдЖрдк рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдордЬрд╝рд╛рдХ рдЙрдбрд╝рд╛ рд╕рдХрддреЗ рд╣реИрдВ

@SimenB рдЙрди рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдЬрд╣рд╛рдВ рдХреЛрдб location.href рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реИ, рд╣рд╛рдВ, location.assign() рдмреЗрд╣рддрд░ рд╣реИред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдХрд┐ _reads_ location.href , location.assign() рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдЦрд╛рд╕рдХрд░ рдЬрдм рд╕реЗ JSDOM рдореЗрдВ location.assign() рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

reconfigure рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдкреАрдЫреЗ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рдПрдХ рдХреЛрдб рдкрде рдХреЛ рд╕рдХреНрд░рд┐рдп рдХрд░рдирд╛ рд╣реИ рдЬреЛ рдХреЗрд╡рд▓ рддрднреА рд╕рдХреНрд╖рдо рд╣реЛрддрд╛ рд╣реИ рдЬрдм location.href рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рддрд░реАрдХреЗ рд╕реЗ рдмрдирддрд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреБрдЫ рдХреЛрдб рдерд╛ рдЬреЛ рд╡рд░реНрддрдорд╛рди рдбреЛрдореЗрди рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдмрджрд▓ рдЧрдпрд╛ - рдХреЛрдб рдмрджрдмреВрджрд╛рд░ рд╣реИ, рд╣рд╛рдБ, рд▓реЗрдХрд┐рди рдпрд╣ рднреА рдЖрд╡рд╢реНрдпрдХ рд╣реИ, рдФрд░ рдмрджрдмреВрджрд╛рд░ рдХреЛрдб рдХреЛ рдХрдо рдХрд░рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рдкрд░реАрдХреНрд╖рдг рдЬреБрдбрд╝рдирд╛рд░ рд╣реИ рдЬреЛ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдкрдХрдбрд╝рддрд╛ рд╣реИ рдФрд░ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд░рд╣рддрд╛ рд╣реИ рдЬрдЧрд╣ рдореЗрдВред

рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдПрдВрдЬрд╛рдЗрдо рдФрд░ рдорд╛рдЙрдВрдЯреЗрдб рдШрдЯрдХ рдХреЗ рд╕рд╛рде рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рд╣реИ?

рдЬреЗрд╕реНрдЯ рдХреЛ рдЕрдкрдЧреНрд░реЗрдб рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдиреАрдЪреЗ рджрд┐рдпрд╛ рдЧрдпрд╛ рдЯреЗрд╕реНрдЯ рдкрд╛рд╕ рд╣реБрдЖ:

```
рдпрд╣ ('рдорд╛рд░реНрдЧ рд╕рд╣реА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдорд╛рд░реНрдЧ', () => {

Object.defineProperty(window.location, 'href', {
  writable: true,
  value: 'https://mysuperawesomesite.com/',
});

const component = mount(
  <App {...props} />
);

const link = component.find('.class');

link.simulate('click');

expect(window.location.href).toEqual('https://mysuperawesomesite.com/new');

});

After upgrading Jest and implementing [jest-environment-jsdom-global](https://www.npmjs.com/package/jest-environment-jsdom-global), I tried the following to no avail:

  ```
it('routes to correct route', () => {

    jsdom.reconfigure({
      url: 'https://mysuperawesomesite.com/',
    });

    const component = mount(
      <App {...props} />
    );

    const link = component.find('.class');

    link.simulate('click');

    expect(window.location.href).toEqual('https://mysuperawesomesite.com/new');
  });

(window.location.href рдЕрднреА рднреА ' https://mysuperawesomesite.com/ ' рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ, рдЗрд╕реЗ ('https://mysuperawesomesite.com/new') рдореЗрдВ рдирд╣реАрдВ рдмрджрд▓рд╛ рдЧрдпрд╛ред

рдЗрд╕ рдкрджреНрдзрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рддрддреНрд╡ рдкрд░ рдХреНрд▓рд┐рдХ рдИрд╡реЗрдВрдЯ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рди window.location.href рд╕реЗрдЯ рдХрд░рдХреЗ рд╣реЛрддрд╛ рд╣реИред

рдпрд╣ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЗрд╕рдХрд╛ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рдкрд░реАрдХреНрд╖рдг рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рдП рдпрд╛ рдпрджрд┐ рдкрд░реАрдХреНрд╖рдг рдЬреЛ рдкрд╣рд▓реЗ Object.defineProperty рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рдереЗ, рдЙрдиреНрд╣реЗрдВ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЦрд░рд╛рдм рддрд░реАрдХреЗ рд╕реЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдХрд┐рд╕реА рднреА рд╕рд╣рд╛рдпрддрд╛ рдХреЗ рд▓рд┐рдП рдЕрдЧреНрд░рд┐рдо рдзрдиреНрдпрд╡рд╛рджред

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рд╣рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛

window.location.href = href рдХреЗ рдмрдЬрд╛рдп window.location.assign(url) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдерд╛ред рдЗрд╕рдиреЗ рдореБрдЭреЗ рдЕрд╕рд╛рдЗрди рд╡рд┐рдзрд┐ рдХреЛ рд░реЛрдХрдиреЗ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреА рдХрд┐ рдЗрд╕реЗ рдареАрдХ рд╕реЗ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рдерд╛ рдпрд╛ рдирд╣реАрдВред рдиреАрдЪреЗ рджреЗрдЦреЗрдВ:

it('routes to correct route', () => {
    window.location.assign = jest.fn();

    const component = mount(
      <App {...props} />
    );

    const link = component.find('.class');

    link.simulate('click');

    expect(window.location.assign).toBeCalledWith('https://mysuperawesomesite.com/new');
    window.location.assign.mockRestore();
  });

@SimenB .assign рдФрд░ .href рдмреАрдЪ рдПрдХ рдмрдбрд╝рд╛ рдЕрдВрддрд░ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдк MDN рдкрд░ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдПрдХ рдкреНрд░рдореБрдЦ рдХреНрд░реЙрд╕-рдбреЛрдореЗрди рдкреНрд░рддрд┐рдмрдВрдз рд╣реИред рдореЗрд░реЗ рдХреЛрдб рдореЗрдВ рдореИрдВ рдореВрд▓ рдкреГрд╖реНрда рдХреЛ рдПрдХ рдЖрдИрдлреНрд░реЗрдо рд╕реЗ рд░реАрдбрд╛рдпрд░реЗрдХреНрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдЬрд╣рд╛рдВ рдореЗрд░рд╛ рдХреЛрдб рдЪрд▓ рд░рд╣рд╛ рд╣реИред рд╡реЗ рдХреНрд░реЙрд╕-рдбреЛрдореЗрди рд╣реИрдВред рдФрд░ рдРрд╕рд╛ рдХрд░рдиреЗ рдХрд╛ рдПрдХрдорд╛рддреНрд░ рддрд░реАрдХрд╛ href рдХреЛ рдмрджрд▓рдирд╛ рд╣реИред
рдореБрдЭреЗ рдЕрдЪреНрдЫрд╛ рд▓рдЧреЗрдЧрд╛ рдЕрдЧрд░ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдлрд┐рд░ рд╕реЗ рдЦреЛрд▓рд╛ рдЬрд╛рдП, рдХреНрдпреЛрдВрдХрд┐ рдореБрдЭреЗ рдХреЛрдИ рдореМрдЬреВрджрд╛ рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рджрд┐рдЦ рд░рд╣рд╛ рд╣реИ рдФрд░ рдореБрдЭреЗ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЬреЛ рдЬрд╛рд╣рд┐рд░ рддреМрд░ рдкрд░ рдмреЗрдХрд╛рд░ рд╣реИред

рдореИрдВ @soswow рдЬреИрд╕реА рд╣реА рдирд╛рд╡ рдореЗрдВ рд╣реВрдВред рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдЖрдк рдпреВрдЖрд░рдПрд▓ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рддрдВрддреНрд░ рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдЬрдм рддрдХ рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдмрд╣рд╛рд▓ рдирд╣реАрдВ рд╣реЛ рдЬрд╛рддреА рд╣реИ, рддрдм рддрдХ рдореИрдВ рдХрдИ рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдг рднреА рд╣рдЯрд╛ рд░рд╣рд╛ рд╣реВрдВред

рдореБрдЭреЗ рдЕрдЪреНрдЫрд╛ рд▓рдЧреЗрдЧрд╛ рдЕрдЧрд░ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдлрд┐рд░ рд╕реЗ рдЦреЛрд▓рд╛ рдЬрд╛рдП, рдХреНрдпреЛрдВрдХрд┐ рдореБрдЭреЗ рдХреЛрдИ рдореМрдЬреВрджрд╛ рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рджрд┐рдЦ рд░рд╣рд╛ рд╣реИ рдФрд░ рдореБрдЭреЗ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЬреЛ рдЬрд╛рд╣рд┐рд░ рддреМрд░ рдкрд░ рдмреЗрдХрд╛рд░ рд╣реИред

рд╣рдо рдордЬрд╛рдХ рдХреЗ рдкрдХреНрд╖ рдореЗрдВ рдХреБрдЫ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред рдореБрдЭреЗ рдпрдХреАрди рд╣реИ рдХрд┐ jsdom рдЗрд╕реЗ рд╕рдорд░реНрдерди рджреЗрдиреЗ рд╡рд╛рд▓реЗ рдкреАрдЖрд░ рдХреЛ рдкрд╕рдВрдж рдХрд░реЗрдЧрд╛ред https://github.com/jsdom/jsdom/issues/2112

рдпрд╣рд╛рдБ рдПрдХ рд╕рд░рд▓ рдЙрдкрд╛рдп рд╣реИ рдЬреЛ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

describe('changing location', () => {
  const testURL = location.href;

  beforeEach(() => history.replaceState({}, 'Login', '/login'));
  afterEach(() => history.replaceState({}, 'Home', '/'));

  it('works', () => {
    expect(location.pathname).toBe('/login');
  });
});

@vastus рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдмрддрд╛рдпрд╛ - рд╕рдорд╕реНрдпрд╛ рдХреНрд░реЙрд╕-рдбреЛрдореЗрди рдХреЗ рд╕рд╛рде рд╣реИ ред рдЬрд╣рд╛рдБ рддрдХ рдореБрдЭреЗ рдпрд╛рдж рд╣реИ, history API рдХрд┐рд╕реА рднрд┐рдиреНрди рдбреЛрдореЗрди рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрдЧрд╛ред

рдЪреВрдБрдХрд┐ location рдХреЛ рд╕реАрдзреЗ jsdom window рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ рдУрд╡рд░рд░рд╛рдЗрдб рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдПрдХ рд╕рдВрднрд╛рд╡рд┐рдд рддрд░реАрдХрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдХрд┐рд╕реА рд╡реНрдпреБрддреНрдкрдиреНрди рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд┐рдпрд╛ рдЬрд╛рдП:

global.window = Object.create(window);
Object.defineProperty(window, 'location', {
  value: {
    href: 'http://example.org/'
  }
});

рдореИрдВ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ:

const windowLocation = JSON.stringify(window.location);
delete window.location;
Object.defineProperty(window, 'location', {
  value: JSON.parse(windowLocation)
});

@RubenVerbourgh & annemarie35 . рд╕реЗ рдкреНрд░реЗрд░рд┐рдд

@vastus рдХреЗ рд╕рдорд╛рдзрд╛рди рдХреЗ рдЖрдзрд╛рд░ рдкрд░ location.search рдкрд░реАрдХреНрд╖рдг рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдЬреЛрдбрд╝рдирд╛:

  test('gets passed query param and returns it as a string if it exists', () => {
    history.replaceState({}, 'Test', '/test?customer=123');
    const customerId = getQueryParam('customer');
    expect(customerId).toBe('123');
  });

@RubenVerbourgh рдПрдХ рдЖрдХрд░реНрд╖рдг рдХреА рддрд░рд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рдХреЛрд╢рд┐рд╢ рдХрд░реЛ:

window.history.pushState({}, null, '/pathname?k=v');

@sahalsaad рдХреЗ рд╕рдорд╛рди рд╕рдорд╛рдзрд╛рди:
```рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ
рдХрд╛рд╕реНрдЯ рдкреБрд░рд╛рдирд╛рд╡рд┐рдВрдбреЛ = рд╡рд┐рдВрдбреЛред рд╕реНрдерд╛рди;
рд╡рд┐рдВрдбреЛ рд╣рдЯрд╛рдПрдВред рд╕реНрдерд╛рди;
рдЦрд┐рдбрд╝рдХреАред рд╕реНрдерд╛рди = {
...рдУрд▓реНрдбрд╡рд┐рдВрдбреЛ,
// рдХрд┐рд╕реА рднреА рдХрд╕реНрдЯрдо рдУрд╡рд░рд░рд╛рдЗрдЯ рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░реЗрдВ рдЬреИрд╕реЗ рдХрд┐ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рд┐рдиреЙрди рд╕реНрдЯрдм
рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ: sinon.stub (),
};

// рдЕрдкрдирд╛ рдЬрд╛рджреВ рдХрд░реЛ

рдЦрд┐рдбрд╝рдХреАред рд╕реНрдерд╛рди = рдкреБрд░рд╛рдирд╛рд╡рд┐рдВрдбреЛ;
````

@sahalsaad рдзрдиреНрдпрд╡рд╛рдж! рдореИрдВрдиреЗ window.location.search рдХрд╛ рдордЬрд╝рд╛рдХ рдЙрдбрд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЗ рд╕рдорд╛рдзрд╛рди рдХреА рд╡рд┐рд╡рд┐рдзрддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛:

const location = {
    ...window.location,
    search: queryString,
};
Object.defineProperty(window, 'location', {
    writable: true,
    value: location,
});

рд╢рд╛рдпрдж рдПрдХ рдмреЗрд╣рддрд░ рд╕рдорд╛рдзрд╛рди:

import { URL } from 'whatwg-url';

const location = new URL(window.location.href);
location.assign = jest.fn()
location.replace = jest.fn()
location.reload = jest.fn()

delete window.location
window.location = location

@kdelmonte рджреНрд╡рд╛рд░рд╛ рджрд┐рдП рдЧрдП рд╕рдорд╛рдзрд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдореЗрд░реА рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХрд┐рдпрд╛, рдореБрдЭреЗ window.location.search рдЪрд░ рдХрд╛ рдордЬрд╛рдХ рдЙрдбрд╝рд╛рдирд╛ рдкрдбрд╝рд╛ред рддреЛ рдореИрдВрдиреЗ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рд╣реИ

window.history.pushState({}, null, '?skuId=1234')

рдЪреВрдБрдХрд┐ location рдХреЛ рд╕реАрдзреЗ jsdom window рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ рдУрд╡рд░рд░рд╛рдЗрдб рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдПрдХ рд╕рдВрднрд╛рд╡рд┐рдд рддрд░реАрдХрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдХрд┐рд╕реА рд╡реНрдпреБрддреНрдкрдиреНрди рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд┐рдпрд╛ рдЬрд╛рдП:

global.window = Object.create(window);
Object.defineProperty(window, 'location', {
  value: {
    href: 'http://example.org/'
  }
});

рдЖрдкрдХрд╛ рдЙрддреНрддрд░ рдХреЗрд╡рд▓ рд╡рд╣реА рд╣реИ рдЬреЛ рдореЗрд░реА рд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдзрдиреНрдпрд╡рд╛рдж!

рдЪреВрдБрдХрд┐ location рдХреЛ рд╕реАрдзреЗ jsdom window рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ рдУрд╡рд░рд░рд╛рдЗрдб рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдПрдХ рд╕рдВрднрд╛рд╡рд┐рдд рддрд░реАрдХрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдХрд┐рд╕реА рд╡реНрдпреБрддреНрдкрдиреНрди рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд┐рдпрд╛ рдЬрд╛рдП:

global.window = Object.create(window);
Object.defineProperty(window, 'location', {
  value: {
    href: 'http://example.org/'
  }
});

рдЖрдкрдХрд╛ рдЙрддреНрддрд░ рдХреЗрд╡рд▓ рд╡рд╣реА рд╣реИ рдЬреЛ рдореЗрд░реА рд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдзрдиреНрдпрд╡рд╛рдж!

рдпрд╣ рдЕрдм рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИ

рдЪреВрдБрдХрд┐ location рдХреЛ рд╕реАрдзреЗ jsdom window рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ рдУрд╡рд░рд░рд╛рдЗрдб рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдПрдХ рд╕рдВрднрд╛рд╡рд┐рдд рддрд░реАрдХрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдХрд┐рд╕реА рд╡реНрдпреБрддреНрдкрдиреНрди рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд┐рдпрд╛ рдЬрд╛рдП:

global.window = Object.create(window);
Object.defineProperty(window, 'location', {
  value: {
    href: 'http://example.org/'
  }
});

рдЖрдкрдХрд╛ рдЙрддреНрддрд░ рдХреЗрд╡рд▓ рд╡рд╣реА рд╣реИ рдЬреЛ рдореЗрд░реА рд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдзрдиреНрдпрд╡рд╛рдж!

рдпрд╣ рдЕрдм рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИ

рдореЗрд░реЗ рд▓рд┐рдП рднреА рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛

рдореИрдВрдиреЗ рдЗрд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛:

delete window.location
window.location = {
  href: 'http://example.org/,
}

рдореИрдВ Location рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдирдХрд▓реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ

export class MockLocation extends URL implements Location {
  ancestorOrigins: any = []
  toString = jest.fn().mockImplementation(() => this.toString())
  assign = jest.fn(href => this.href = href)
  replace = jest.fn(href => this.href = href)
  reload = jest.fn()

  constructor(
    url: string = 'http://mock.localhost',
  ) {
    super(url)
  }

  onWindow(window: Window) {
    Object.defineProperty(window, 'location', { 
      writable: true,
      value: this
    });
    return this
  }
}

рдлрд┐рд░ рдореЗрд░реЗ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ

let location: MockLocation

beforeEach(() => {
    location = new MockLocation(MOCK_PARTNER_URL).onWindow(window)
})

рдореИрдВрдиреЗ рдЦреБрдж рдХреЛ рд╣рд░ рд╕рдордп рдЗрд╕ рддрд░рд╣ рдХреА рдореБрд╢реНрдХрд┐рд▓ рд╡рд╕реНрддреБрдУрдВ рдХреЛ рджрдмрд╛рддреЗ рд╣реБрдП рдкрд╛рдпрд╛, рдФрд░ рдПрдХ рд▓рдЪреАрд▓рд╛ рд╕рд╣рд╛рдпрдХ рдХрд╛рд░реНрдп рдмрдирд╛рдпрд╛:

export const safelyStubAndThenCleanup = (target, method, value) => {
  const original = target[method]
  beforeEach(() => {
    Object.defineProperty(target, method, { configurable: true, value })
  })
  afterEach(() => {
    Object.defineProperty(target, method, { configurable: true, value: original })
  })
}

рдФрд░ рдлрд┐рд░ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:

describe('when on /pages', () => {
  safelyStubAndThenCleanup(window, 'location', { pathname: '/pages' })

  it('should do something neat', () => { /* ... */ })
})

рдФрд░ рдЖрдк рдЬреЛ рдЪрд╛рд╣реЗрдВ рд╕реНрдЯрдм рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: pathname , href , рдЖрджрд┐... рдЗрд╕рд╕реЗ рдЖрдкрдХреЛ рд╕рдлрд╛рдИ рдХрд╛ рдЕрддрд┐рд░рд┐рдХреНрдд рдореБрдлреНрдд рд▓рд╛рдн рдорд┐рд▓рддрд╛ рд╣реИред

рдХреБрдВрдЬреА рдпрд╣ рд╣реИ рдХрд┐ рдЖрдк location рд╕рд╛рде рдЧрдбрд╝рдмрдбрд╝ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдирдХрд▓реА рдХреЗ рд╕рд╛рде location рдХреЛ рд╕реНрд╡реИрдк рдХрд░реЗрдВ, рдФрд░ рдлрд┐рд░ рдкрд░реАрдХреНрд╖рдг рдкреВрд░рд╛ рд╣реЛрдиреЗ рдкрд░ рдЗрд╕реЗ рд╡рд╛рдкрд╕ рд░рдЦ рджреЗрдВред

рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВ рдЕрдкрдиреЗ рдбрд┐рдмрдЧрд┐рдВрдЧ рд╕рддреНрд░ рдореЗрдВ рджреЗрдЦ рд╕рдХрддрд╛ рд╣реВрдВ, global.location рдЧреЗрдЯрдЯрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдПрдХ рд╕рд╛рдзрд╛рд░рдг рд╕рдВрдкрддреНрддрд┐ рдирд╣реАрдВ рд╣реИред рдХреНрдпрд╛ рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдирд╛ рд╕реБрд░рдХреНрд╖рд┐рдд рдирд╣реАрдВ рд╣реЛрдЧрд╛?

let originalLocationDescriptor;
beforeAll(() => {
  originalLocationDescriptor = Object.getOwnPropertyDescriptor(global, 'location');
  delete global.location;
  global.location = {};
});
afterAll(() => {
  Object.defineProperty(global, 'location', originalLocationDescriptor);
}):

рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдХрд▓реНрдкрдирд╛ рдХрд░рдирд╛ рдХрдард┐рди рд╣реИ рдХрд┐ рдореИрдВ рдореВрд▓ global.location рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреНрдпреЛрдВ рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛, рдпрд╣ рдереЛрдбрд╝рд╛ рдФрд░ рд╕рд╣реА рд▓рдЧрддрд╛ рд╣реИред
рдФрд░ рдпрд╣ рдХреЛрдб рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдореЗрд░реЗ рд▓рд┐рдП рдареАрдХ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдореИрдВ рдмрд╕ location.pathname рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдЬрд░реВрд░рдд рдкрдбрд╝рдиреЗ рдкрд░ рдЗрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдХреБрдЫ jest.fn() рд╕рд╛рде рдЖрд╕рд╛рдиреА рд╕реЗ рдмрдврд╝рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИ, рдЬреЗрд╕реНрдЯ 26.5 . рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ

function stubLocation(location) {
  beforeEach(() => {
    jest.spyOn(window, "location", "get").mockReturnValue({
      ...window.location,
      ...location,
    });
  });
}

stubLocation({ pathname: "/facebook/jest/issues/5124" });

test("mocks location prop", () => {
  expect(window.location.pathname).toEqual("/facebook/jest/issues/5124");
});

@vastus рдХреЗ рд╕рдорд╛рдзрд╛рди рдХреЗ рдЖрдзрд╛рд░ рдкрд░ location.search рдкрд░реАрдХреНрд╖рдг рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдЬреЛрдбрд╝рдирд╛:

  test('gets passed query param and returns it as a string if it exists', () => {
    history.replaceState({}, 'Test', '/test?customer=123');
    const customerId = getQueryParam('customer');
    expect(customerId).toBe('123');
  });

рдореБрдЭреЗ рдЬреЛ рд╕рдорд╕реНрдпрд╛ рд╣реЛ рд░рд╣реА рдереА, рдЙрд╕рдХреЗ рд▓рд┐рдП рдЗрд╕рдиреЗ рдмрд┐рд▓реНрдХреБрд▓ рдЕрдЪреНрдЫрд╛ рдХрд╛рдо рдХрд┐рдпрд╛

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

benmccormick picture benmccormick  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

samzhang111 picture samzhang111  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

rosiakr picture rosiakr  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

emmby picture emmby  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

Antho2407 picture Antho2407  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ