ããã«ã¡ã¯@cpojer ã
ããã¯å®éã«ã¯jsdom@8
ã®åé¡ã§ã... tmpvar / jsdomïŒ1388ãåç
§ããŠãã ããããã ããããã§ããã³çããããã®ã§ãJestã¯jsdomãæãã€ãã解決çããã¹ãŠåãäžããŸãã
以åã¯[email protected]/[email protected]
ã䜿çšããŠã次ã®ãããªãã¹ããäœæã§ããŸããã
jest.autoMockOff()
jest.setMock('../lib/window', window)
jest.mock('cookies-js')
jest.mock('query-string')
jest.mock('superagent')
describe(['@utils/auth - When an AJAX response returns:'
].join('')
, function () {
beforeEach(function () {
window.location.href = 'http://quux.default.com'
var queryString = require('query-string')
queryString.__setMockParseReturns([{
'access_token': '1234foo',
'expires_in': '9999'
}])
})
it(['should set a redirect token and goto platform ',
'when the AJAX request returns 401.'
].join('')
, function () {
var superagent = require('superagent')
superagent.__setMockAjaxResponses([
[null, { 'status': 401 }]
])
var href = window.location.href
var auth = require('../index.js')
auth.login(function (res) {})
var Cookies = require('cookies-js')
var config = require.requireActual('../config')
expect(decodeURIComponent(window.location.href)).toBe([
config.loginUrl,
config.loginServiceLogin,
'?client_id=',
config.clientId,
'&response_type=token',
'&redirect_uri=',
config.clientRedirectUri
].join(''))
expect(Cookies.__getMockCookieData()[config.clientId + '_state_locationAfterLogin']).toBe(escape(href))
})
ãããŠããã®ãã¹ãã¯åæ Œããã§ãããã jsdom@8
以éãããã¯äžå¯èœã«ãªãããããã®ãã¹ãã¯å€±æããŸãã
jsdomã¯ããçš®ã®æ©èœãæ€èšããŠããããã§ãããJestãå©çšå¯èœã«ãªã£ããšãã«ãã®æ©èœã確å®ã«ååŸã§ããããã«ãããã£ãã ãã§ãã
ããªãã¯æ£ããã§ããããã¯ç¢ºãã«jsdomã®åé¡ã§ãã Facebookã§ã¯ããããåé¿ããããã«ããã䜿çšããŠããŸãã
Object.defineProperty(window.location, 'href', {
writable: true,
value: 'some url'
});
ããã¯ç§ãã¡ã«ãšã£ãŠã¯ããŸããããŸãããç§ãã¡ã¯ãŸã å éšçã«jsdom7ã䜿çšããŠããŸãã
Object.defineProperty
ã®ããæ¹ã§åé¡ãªããšæãã®ã§ããããéããŸãã jsdom 8ã§ãããããŸããããªãå Žåã¯ãåéãããŠããã ããŸãã
ãã£ããããããããšããããè©ŠããŠã¿ãŸãã
@cpojer ããã®åé¡ãåéããããã«äœãã¯ãªãã¯ããå¿ èŠãããã®ãââç解ã§ããªãããã§ã...
https://github.com/tmpvar/jsdom#changing -the-url-of-an-existing-jsdom-ã§èª¬æãããŠããããã«ã jest
ç°å¢ã«jsdom.changeUrl(window, url)
ãåŒã³åºãããã®ç°å¢ã¯ãããŸããïŒ [email protected]
ã®ãŠã£ã³ããŠã€ã³ã¹ã¿ã³ã¹ïŒ
å€ããã±ããã§ããããŸã ãã®åé¡ãçºçããŠããå Žåã¯ã代ããã«window.location.assign()
ã䜿çšãå§ããã®ã§ããã¹ãã§ã¯assign
é¢æ°ããã®ããã«ã¢ãã¯ã§ããŸãã
it('will redirect with a bad route', () => {
window.location.assign = jest.fn();
const redirection = shallow(<Redirection />, {
context: {
router: {
location: {
pathname: '/wubbalubbadubdub',
},
},
},
});
expect(window.location.assign).toBeCalledWith(`${CONFIG.APP_LEGACY_ROOT}`);
});
@ th3fallenã«æè¬ããŸãã ã«ãã³ããïŒ
ãšããã§@cpojerç§ã¯5æ1æ¥ã«FBã§éå§ããŸã....; P
è¯ãïŒ
ãã¹ããMocha + Chai + Sinon.jsããJestã«ç§»è¡ããããšããŠããŸãããç¹å®ã®ãã¹ãã®å Žæãå€æŽããæ¹æ³ãããããŸããã
Jest 19.xã¯ã Object.defineProperty
ããªãã¯ã䜿çšããŠå Žæãå€æŽã§ããªãJSDom9.12ã䜿çšããŸãã ãŸããtmpvar / jsdomïŒ1700ã«èšèŒãããŠããçç±ã«ããã jsdom.changeURL()
ã䜿çšã§ããŸããã
@cpojer Jestã®jsdom.changeURL()
ã«ãããã·ã¡ãœãããå®è£
ããã®ã¯ã©ãã§ããïŒ
@okovpashko jsdomãç°å¢ã«å ¬éããããšãèšç»ããŠããŸãïŒ https ïŒ//github.com/facebook/jest/issues/2460
Object.defineProperty
ã¯FBã§åããŠããŸãã
@thymikeeç§ã¯ãã®åé¡ãèŠãŸããããææ¡ã¯æåŠããããšæããŸããã
@cpojerç§ã¯ããªãã®äŸãèªã¿ééãããã®åé¡ã«é¢é£ããä»ã®äŸãšæ··åããŸããã人ã
ã¯Object.defineProperty(window, 'location', {value: 'url'});
ã®äœ¿çšãææ¡ããŸããã ããããšãïŒ
hrefã ãã§ãªãå€æŽããå¿ èŠãããã®ã§ããã®ã¹ã¬ãããèªã人ã«åœ¹ç«ã€å¯èœæ§ã®ããç°¡åãªã¡ãœãããäœæããŸããã
const setURL = (url) => {
const parser = document.createElement('a');
parser.href = url;
['href', 'protocol', 'host', 'hostname', 'origin', 'port', 'pathname', 'search', 'hash'].forEach(prop => {
Object.defineProperty(window.location, prop, {
value: parser[prop],
writable: true,
});
});
};
ãã®ã¹ã¬ãããããã«ãã©ãã°ããŠãè©«ã³ããŸãããææ¡ãããŠããããã«ããã·ã¥æ©èœãã¢ãã¯ã¢ãŠãããŠã¿ãŸãã...
reactRouterReduxMock.push = (url) => {
Object.defineProperty(window.location, 'href', {
writable: true,
value: url
})
})
ããããç§ã¯ãŸã jsdomãšã©ãŒãçºçããŠããã®ã§ãåé¿ã§ããªãããã§ãã
TypeError: Cannot read property '_location' of null
at Window.location (/Users/user/projects/app/client/node_modules/jsdom/lib/jsdom/browser/Window.js:148:79)
at value (/Users/user/projects/app/client/test/integration-tests/initialSetup.js:122:32) //this is the defineProperty line above
ããã¯jsdomãšã©ãŒã ãšæããŸãããããã解決ãã人ã®ããã«ããããåé¿ã§ããå¯èœæ§ã®ããå ±æã§ããã»ããã¢ããã³ã³ããã¹ãã¯ä»ã«ãããŸããïŒ
ããããšã
@ matt-daltonhttpsïŒ//github.com/facebook/jest/issues/890#issuecommentã§ç§ã®ææ¡ãè©ŠããŠãã ãã-295939071ã¯ç§ã«ãšã£ãŠããŸãæ©èœããŸã
@ matt-daltonããªãã®URLã¯äœã§ããïŒ jest-config.json
ã«testURLãèšå®ãããŠããŸããããããšãabout:blank
ãšããŠåæåãããŸããïŒ
@ianlyonsãããpackage.jsonã§ããã«"https://test.com/"
ã®å€ãèšå®ããŸããããã©ã®ãã¹ãblank
ãšããŠè¡šç€ºãããŠããŸããã
@ th3fallenããªããæ£ããç解ããŠããã°ãããã¯ç§ã®ãŠãŒã¹ã±ãŒã¹ã§ã¯ããŸããããªããšæããŸãã å²ãåœãŠãããªã¬ãŒãããã³ã³ããã¹ãå€ãšããŠURLãæž¡ããŸããïŒ åºæ¬çãªçµ±åãã¹ãããŸãšããããšããŠããã®ã§ãã«ãŒã¿ãŒãåæããŒã¿ããŒãã«ã©ã®ããã«å¿çãããã確èªããããšæããŸãã APIå¿çãã¢ãã¯ããåŸãã¢ããªããžãã¯ã䜿çšããŠURLãå€æŽããå¿ èŠããããŸãïŒã€ãŸããèªåã§å€éšããããªã¬ãŒããããªãïŒã
Object.defineProperty
ã¯ãããšãã°window.location.search
ã«äŸåããæ©èœããã¹ãããããã®ããªãã¯ãå®è¡ããŠããããã§ãã ããã¯èšã£ãŠããããã¯window.location.search
ãå€æŽããã®ã§ãä»ã®ãã¹ãã圱é¿ãåããå¯èœæ§ããããŸãã Object.defineProperty
$ãä»ããŠ$ window.location.search
ã«å ããå€æŽããå
ã«æ»ããæ¹æ³ã¯ãããŸããïŒãžã§ã¹ãã¢ãã¯é¢æ°ã«mockReset
é¢æ°ããããããªãã®ã§ããïŒ
@ msholty-fdãã®ã¢ãããŒããè©Šãããšãã§ããŸãïŒ
const origLocation = document.location.href;
let location = origLocation;
beforeAll(() => {
const parser = document.createElement('a');
['href', 'protocol', 'host', 'hostname', 'origin', 'port', 'pathname', 'search', 'hash'].forEach(prop => {
Object.defineProperty(window.location, prop, {
get: function() {
parser.href = location;
return parser[prop];
}
});
});
});
afterEach(() => {
location = origLocation;
});
test('location 1', () => {
location = "https://www.google.com/";
console.log(document.location.href); // https://www.google.com/
});
test('location 2', () => {
console.log(document.location.href); // about:blank
});
Jest22.0.1ã§åäœãåæ¢ããŸãã
Object.defineProperty(window.location, 'href', {
writable: true,
value: 'some url'
});
ãšã©ãŒã¡ãã»ãŒãžïŒ
TypeError: Cannot redefine property: href
at Function.defineProperty (<anonymous>)
ããŒããã©ãããããã人ã
ãreconfigure
ã«é»è©±ã§ããããã«ããå¿
èŠããããããããŸããã https://github.com/tmpvar/jsdom/blob/05a6deb6b91b4e02c53ce240116146e59f7e14d7/README.md#reconfiguring -the-jsdom-with-reconfiguresettings
ãããéããããã®ã§ãããã«é¢é£ããæ°ããåé¡ãéããŸããïŒïŒ5124
@SimenBJestããããä¿®æ£ããå¿
èŠããããšã¯ç¢ºä¿¡ããŠããŸããã JSDOMã¯ã window.location.assign()
ãæå³ãããšããã«æ©èœãã window.location.href
ãªã©ã®åºåãåæ§æã§ããããã«ããå¿
èŠããããŸãã
jsdomã®ããŒã¹URLã®ããã©ã«ãã¯about:blank
$ã§ããããã TypeError: Could not parse "/upgrades/userlogin?hardwareSku=sku1351000490stgvha" as a URL
ãååŸããŸãã
ããŒã¹URLãjsdom
ã«å²ãåœãŠãããšããŸããããæåããã«4æéè²»ãããŸããïŒæ¹æ³ã¯ããã£ãŠããŸãã <base href='your_base_url' />
ãdomã«æ¿å
¥ããã ãã§ãããdomã¯jest
ã«ãã£ãŠäœæãããŸãã
Object.defineProperty
ãœãªã¥ãŒã·ã§ã³ã¯ãå€ãããŒãžã§ã³ã®jsdom
ã§ã®ã¿æ©èœããŸãïŒæ°ããããŒãžã§ã³ã®jsdom
ã§ã¯ 'ããããã£ãšã©ãŒãåå®çŸ©ã§ããŸããïŒã
jsdom
ver> 10ã䜿çšããŠããå Žåã¯ã @ th3fallenãé©åãªãœãªã¥ãŒã·ã§ã³ã§ãã
window.location.assign
ã䜿çšããã®ãæ£ããæ¹æ³ã§ã
about:blank
以å€ã®URLãå¿
èŠãªå Žåã¯ã testURL
æ§æã䜿çšã§ããŸãã
@SimenBããã®è¿ä¿¡ã«æè¬ããŸãã
ãããã$ url
base url
ã«ã€ããŠè©±ããŠããŸããã window.location.href="/login"
ãå®è¡ããã³ãŒããããã jest
ãå®è¡ãããšã jsdom
ã/login
ãæå¹ãªURLã§ã¯ãªãããšã瀺ãäŸå€ãã¹ããŒããŸã
TypeError: Could not parse "/login" as a URL
jsdom
ã®ãœãŒã¹ã³ãŒãã確èªããŸããããããã¯ããŒã¹URLãèšå®ãããŠããªãããã§ãïŒããã¯ãããŒã¹ã¢ãã¬ã¹ãªãã§ãã©ãŠã¶ã®URLããŒã«ã/ loginããšå
¥åããã®ãšåãã§ãïŒã
jsdom
ã䜿çšãããšãéåžžã次ã®æ¹æ³ã§ããŒã¹URLãèšå®ã§ããŸãã
global.jsdom = new JSDOM('<html><head> <base href="base_url" /></head></html>')
ãããã jest
ã¯jsdom
$ãèšå®ããŠããã®ã§ãããã¯ç§ãã¡ã®å¶åŸ¡ã®åã°ãªããã®ã§ãã
---æŽæ°ïŒ jsdom
ãäŸåé¢ä¿ãšããŠæ瀺çã«è¿œå ãã jsdom
ãæåã§æ§æã§ãããšæããŸãã
次ã«ã window.location.href=
ãwindow.location.assign
ã«çœ®ãæããŠã assign
é¢æ°ãã¢ãã¯ãããšãã解決çãèŠã€ããŸããã
@ bochen2014ãã®åé¡ã«ã¯ãæ°ããããŒãžã§ã³ã®jsdomã®äœ¿çšæ¹æ³ã«é¢ãã詳现æ å ±ããããŸãïŒïŒ5124
tl; drïŒ window.location.assign()
ãã¢ãã¯ãããã jest-environment-jsdom-global
ã䜿çšããŠãé£è¡äžã®jsdomãåæ§æã§ããŸãã
ããããšã@ simon360
ããã¯ç§ãããããšã§ã;-)
ç§ã¯jsdom.reconfigure
ã䜿çšããŠããã¹ãã§å¥ã®åæurls
ãèšå®ããŸãããã³ãŒãã§ïŒãã¹ãã§ã¯ãªãïŒURLãå€æŽããå¿
èŠããããšãã¯ãã€ã§ãã window.location.assign
ã䜿çšããŠã¢ãã¯ããŸããã ããã¯ç§ã®ããã«åããã
åãåé¡ãçºçããå¯èœæ§ãããããŸãã¯çºçããå¯èœæ§ããã人ã®ããã«ãjsdomã®URLãèšå®ããŸã
// jest.config.js
module.exorts={
testURL: 'http://localhost:3000',
// or :
testEnvironmentOptions: {
url: "http://localhost:3000/",
referrer: "https://example.com/",
}
}
ããã«ããããã¹ãŠã®ãã¹ãã®URLãèšå®ãããããšã«æ³šæããŠãã ããã
ç¹å®ã®ãã¹ãã§å¥ã®URLãå¿
èŠãªå Žåã¯ã jsdom.reconfigure
apiã䜿çšããŠãã ããã
åäœãã¹ãã³ãŒãïŒã€ãŸããæ¬çªã³ãŒãïŒã®å€ã§ãã®å Žã§URLãå€æŽããå¿
èŠãããå Žåã¯ã window.location.assign
ã䜿çšããŠã¢ãã¯ããå¿
èŠããããŸãã
ä»ã®ãã±ããã«æçš¿ããŸããããããã«æçš¿ããŸãïŒ
Jest21.2.1ã®åªãããœãªã¥ãŒã·ã§ã³ãèŠã€ãããŸãã
ããŠããããŸã§ã®ãšããããããåé¿ããæãç°¡åãªè§£æ±ºçã¯æ¬¡ã®ãšããã§ãã
Jestèšå®ã«ç§»åããŸãïŒããšãã°ãpackage.jsonã䜿çšããŸãïŒã
"jest": {
"testURL": "http://localhost"
}
ããã§ãŠã£ã³ããŠãªããžã§ã¯ãã«ã¢ã¯ã»ã¹ã§ããããã«ãªãããã¹ãäžã«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);
});
ããŸãããã°ãããã¯èª°ããå©ããŸãã
@ petar-prog91圹ã«ç«ã¡ãŸããã ãã ããã¿ã€ããã¹ããããŸãã$ TestURL
testURL
ã§ããå¿
èŠããããŸãã
@BarthesSimpsonéç¥ãæŽæ°ãããã³ã¡ã³ãã«æè¬ããŸãã
ãããæçš¿ããã®ããããŠãã ãããããã¯jestã§ã¯æ©èœããŸãã "ïŒ" ^ 22.4.2 "
ããã«ã¡ã¯ã
ç§ã¯ããããã¹ãã§äœ¿çšããŸãããã°ããŒãã«ç¶æ
ãåé€ããjsdomã䜿çšããŠæ°ããç¶æ
ãäœæããŸã...ïŒ
describe('componentDidMount', () => {
delete global.window
const window = (new JSDOM(``, {url: 'https://example.org/'})).window
global.window = window
describe('When window is defined', () => {
const spy = jest.spyOn(Utils, 'extractTokenFromUrl')
it('should call extract token function with window location', () => {
mount(<Header />)
expect(spy).toHaveBeenCalledWith('https://example.org/')
})
})
})
@UserNT確èªâ TypeError: Cannot redefine property: href
ãæäŸããŸã
@ annemarie35ãæ©èœããªãâ ReferenceError: JSDOM is not defined
ããã誰ããå©ãããã©ããã¯ããããŸããããããã¯ç§ãçŸåšè¡ã£ãŠããããšã§ãã
const redirectTo = (url: string): void => {
if (process.env.NODE_ENV === "test") {
global.jsdom.reconfigure({ url: `${getBaseUrl()}${url}` });
} else {
window.location.replace(url);
}
};
ãªãã€ã¬ã¯ãé¢æ°ãäœæãã代ããã«ããã䜿çšããŸãã ãããã£ãŠãenvã®ãã¹ãã§ã¯ãjsdom.reconfigureurlã«äŸåããŠurléšåãå€æŽããŸãã
ç§ã¯ãã®ããã«äœ¿çšããŸã
export const clientFetchData = (
history: Object,
routes: Object,
store: Object
) => {
const callback = location =>
match({ routes, location }, (error, redirectLocation, renderProps) => {
if (error) {
redirectTo("/500.html");
} else if (redirectLocation) {
redirectTo(redirectLocation.pathname + redirectLocation.search);
} else if (renderProps) {
if (!isEmpty(window.prerenderData)) {
// Delete initial data so that subsequent data fetches can occur
window.prerenderData = undefined;
} else {
// Fetch mandatory data dependencies for 2nd route change onwards
trigger(
FETCH_DATA_HOOK,
renderProps.components,
getDefaultParams(store, renderProps)
);
}
trigger(
UPDATE_HEADER_HOOK,
renderProps.components,
getDefaultParams(store, renderProps)
);
} else {
redirectTo("/404.html");
}
});
history.listen(callback);
callback(history.getCurrentLocation());
};
ãã®åŸãããªãã®ãã¹ãã§ã¯ãããã¯ãã®ããã«ãªãå¯èœæ§ããããŸã
describe("# match route", () => {
it("should navigate to error page", () => {
fetchData.clientFetchData(history, components, store);
reactRouter.match.mock.calls[0][1](true);
expect(window.location.href).toEqual(`${SERVER_URL}/500.html`);
});
it("should redirect to /hello-world.html page", () => {
fetchData.clientFetchData(history, components, store);
reactRouter.match.mock.calls[0][1](undefined, {
pathname: "/hello-world.html",
search: ""
});
expect(window.location.href).toEqual(`${SERVER_URL}/hello-world.html`);
});
...
ç§ã¯ãããããããšã«ãªããŸããïŒ
global.window = new jsdom.JSDOM('', {
url: 'http://www.test.com/test?foo=1&bar=2&fizz=3'
}).window;
JSDOMã»ããã¢ãããã¡ã€ã«ã®å é ã«ããããããŸãã
const { JSDOM } = require('jsdom');
const jsdom = new JSDOM('<!doctype html><html><body><div id="root"></div></body></html>', {
url: "http://test.com"
});
const { window } = jsdom;
function copyProps(src, target) {
const props = Object.getOwnPropertyNames(src)
.filter(prop => typeof target[prop] === 'undefined')
.map(prop => Object.getOwnPropertyDescriptor(src, prop));
Object.defineProperties(target, props);
}
global.document = window.document;
global.window = window;
global.navigator = {
userAgent: 'node.js',
};
global.HTMLElement = window.HTMLElement;
Jest configã§ãtestURLãïŒã httpïŒ// localhost / ããèšå®ããŠä¿®æ£ããŸããïŒææ°ããŒãžã§ã³ã䜿çšããŠããŸãïŒã ããã©ã«ãã§ã¯ã aboutïŒblank ãã§ãããJSDOMãšã©ãŒãçºçããŠããŸããïŒãaboutïŒblankãã®URLãå¥ã®ãã®ã«å€æŽããããšã¯ã§ããŸããïŒã
è³åïŒ
http://jestjs.io/docs/en/configuration#testurl -string
https://github.com/jsdom/jsdom/issues/1372
ãã®æçš¿ã¯éåžžã«åœ¹ã«ç«ã¡ãŸããïŒ https ïŒ//www.ryandoll.com/post/2018/3/29/jest-and-url-mocking
ãJestæ§æã§ã¯ãå¿ ã次ã®ããã«èšå®ããŠãã ããã
"testURL": "https://www.somthing.com/test.html"
次ã«ããã¹ãã®beforeEachïŒïŒã»ã¯ã·ã§ã³ã§ãå¿
èŠã«å¿ããŠãã¹ãå€æŽããŸãã
history.pushStateïŒïŒã
window.history.pushState({}, 'Test Title', '/test.html?query=true');
åºæ¥äžããïŒ ããã§ãäžèšã®ã¹ã¬ããã§ä»ã®äººã瀺åããŠããããã«jsdomæ§æããªãŒããŒã©ã€ãããããšãªãããã¹ãã®ãã¹ãå€æŽã§ããŸãã ãã®ãœãªã¥ãŒã·ã§ã³ãã©ã®ã¹ã¬ããã§èŠã€ãããã¯ããããŸãããããããæçš¿ããéçºè ã«æè¬ããŸãïŒã
@ Mike-Tran You rockïŒ ããã¯å®å šã«æ©èœããã®ã§ããšãŠãç°¡åã§ãã testURLèšå®ã䜿çšããå¿ èŠãããããŸããã§ããã
@ Mike-Tranããã¯ããŸããããŸãïŒ ããããšãããããŸãïŒ ãã ãã testURL
ãbeforeEach
ã¯å¿
èŠãããŸããã§ããã ä»ãããŸããïŒ
window.history.pushState({}, 'Test Title', '/test.html?query=true');
ãããŠä»ãç§ã¯ããObject.defineProperty
ã䜿ãå¿
èŠã¯ãããŸããð
@jcmcnealããããšãããããŸããïŒ ïŒãžã§ã¹ã23.0.0ïŒ
window
ãªããžã§ã¯ããã¢ãã¯ããããšãç®æšã§ããå Žåããããç§ã®ïŒããã»ã©ãšã¬ã¬ã³ãã§ã¯ãããŸããããæ©èœããŸãïŒãœãªã¥ãŒã·ã§ã³ã§ãã
ã€ã³ã¿ãŒãã§ã€ã¹ãäœæããŸãïŒã€ã³ã¿ãŒãã§ã€ã¹ãæ£ããåèªãã©ããã¯ããããŸããããèŠç¹ãç解ããŠããã ããã°å¹žãã§ãïŒã
// window.js
export const { location } = window;
å®éã®ã³ãŒãã§ã¯ã window
ãã€ã³ã¿ãŒãã§ã€ã¹ã¡ãœããã®ã¡ãœãããšäº€æããŸãïŒäŸïŒ win
// myFile.js
import * as win from './window';
export function doSomethingThatRedirectsPage() {
win.location.href = 'google.com';
}
次ã«ãjestãã¹ãã§ã¯ãjsdomãæå¥ãèšããªãããã«ãããããã¢ãã¯ã¢ãŠãããŸãã ããªãããããã䞻匵ããããšãã§ããŸãïŒ
// myFile.test.js
import * as myFile from './myFile';
import * as win from './window';
it('should redirect', () => {
win.location = { href: 'original-url' };
expect(win.location.href).toBe('original-url');
myFile.doSomethingThatRedirectsPage();
expect(win.location.href).toBe('google.com');
});
@ Mike-Tranã@ jcmcnealããããšãïŒ ãã¹ãŠãã¢ã¹ãã¯ããšããŠæ©èœããŸãïŒ
ã¯ã©ã¹SSOtestComponentã¯React.Componentãæ¡åŒµããŸã{
componentDidMount() {
let isSuccess = this.props.location.pathname === '/sso/test/success' ? true : false
window.opener.postMessage({ type: "sso_test", isSuccess,...this.props.location.query}, window.location.origin)
}
onSsoAuthenticate() {
}
componentWillUnmount() {
}
render() {
return (<Loader />);
}
}
module.exports = SSOtestComponent;
ç§ã¯enjymeãšjestã䜿çšããŠãŠããããã¹ãã±ãŒã¹ãäœæããŠããŸããæ¡ä»¶window.location ... plsãã©ã®ããã«äœæãããã§çããåŸãããŸãã
ããã¯ç§ã®ããã«åãã
const location = JSON.stringify(window.location);
delete window.location;
Object.defineProperty(window, 'location', {
value: JSON.parse(location)
});
Object.defineProperty(global.location, 'href', {
value: 'http://localhost/newURL',
configurable: true
});
jestããŒãžã§ã³23.6.0
ããã¯ç§ã®ããã«åããã
delete global.window.location
global.window.location = { href: 'https://test-domain.com.br', ...anyOptions }
@FelipeBohnertPaetzoldããããšã
@FelipeBohnertPaetzoldã«æè¬ããŸãã ã³ãŒãã§location.host
ã䜿çšããŠããã®ã§ãå®å
šãªå Žæãªããžã§ã¯ããå¿
èŠã§ããããšãããã£ãã®ã§ãåå Žæã®ããããã£ãæåã§æž¡ããããã次ã®æ¹ãããŸããããŸããã
delete global.window.location;
global.window.location = new URL("https://www.ediblecode.com/");
ããã¯ããŒã6.13以éã§æ©èœãïŒ URLã¯ã©ã¹ã®ããã¥ã¡ã³ããåç §ïŒãJest24ã䜿çšããŠããããšã«æ³šæããŠãã ããã
ãŸããããã¯çžå¯ŸURLã§ã¯æ©èœããªãããšã«æ³šæããŠãã ãããhttpsïŒ //url.spec.whatwg.org/#example-url-parsingãåç §ããŠãã ããã
ãã®TypeScriptã¯ã Jest24.0.0ãšNode10.15.0ã§æ©èœããŠããŸãã
import { mockWindow } from './testUtils';
mockWindow(window, 'http://localhost');
describe('setup tests', () => {
describe('window.location', () => {
const saveLocation = window.location;
afterAll(() => {
delete window.location;
window.location = saveLocation;
});
it('location.assign assigns a location', () => {
window.location.assign('http://foo.com');
expect(window.location.href).toBe('http://foo.com/');
(window.location.assign as jest.Mock<void, [string]>).mockClear();
});
it('location.replace replaces a location', () => {
window.location.replace('http://bar.com');
expect(window.location.href).toBe('http://bar.com/');
(window.location.replace as jest.Mock<void, [string]>).mockClear();
});
it('location.reload is a spy', () => {
window.location.reload();
expect(window.location.reload).toHaveBeenCalledTimes(1);
(window.location.reload as jest.Mock).mockClear();
});
});
});
interface MockedLocation extends Location {
assign: jest.Mock<void, [string]>;
reload: jest.Mock;
replace: jest.Mock<void, [string]>;
}
interface MockedWindow extends Window {
location: MockedLocation;
}
export function mockWindow(win: Window = window, href = win.location.href) {
const locationMocks: Partial<MockedLocation> = {
assign: jest.fn().mockImplementation(replaceLocation),
reload: jest.fn(),
replace: jest.fn().mockImplementation(replaceLocation),
};
return replaceLocation(href);
function replaceLocation(url: string) {
delete win.location;
// tslint:disable-next-line:no-any
win.location = Object.assign(new URL(url), locationMocks) as any;
return win as MockedWindow;
}
}
import { mockWindow } from './testUtils';
describe('test utils', () => {
describe('mockWindow', () => {
const saveLocation = window.location;
afterAll(() => {
delete window.location;
window.location = saveLocation;
});
it('location.assign assigns a location', () => {
const { assign } = mockWindow().location;
assign('http://foo.com');
expect(window.location.href).toBe('http://foo.com/');
assign.mockClear();
});
it('location.replace replaces a location', () => {
const { replace } = mockWindow().location;
replace('http://bar.com');
expect(window.location.href).toBe('http://bar.com/');
replace.mockClear();
});
it('location.reload is a spy', () => {
const { reload } = mockWindow().location;
reload();
expect(window.location.reload).toHaveBeenCalledTimes(1);
reload.mockClear();
});
});
});
@jedmao
ãããç·ïŒçŽ æŽãããutilïŒ
ç§ã®å Žåã src/setupTests.test.ts
ã§å°ãåé·ã«ãã¹ãããŸããããã¯ãsrc /testUtils.test.tsã§mockWindow
utilããã§ã«å®å
šã«ãã¹ãããŠããããã§ãã ãããã£ãŠã src/setupTests.ts
ã®ãã¹ãã§ã¯ãæ£ããåŒæ°ã䜿çšããŠmockWindow
ãåŒã³åºãã ãã§ååã§ãã
ããããšãïŒ
@ tzvipm @jup-ðã«æè¬ããŸãã @jedmao/storage
ãš@jedmao/location
ããªãªãŒã¹ããŸããããã©ã¡ããJestã«å®å
šã«äŸåããŠããŸããã npmããã±ãŒãžã¯å®å
šã«ãã¹ããããŠãããããè¿œå ã®ãã¹ããèšè¿°ããªããŠããé©åãªã¡ãœãããspyOn
å®è¡ã§ããã¯ãã§ãã
Vueã®äœ¿çšäžã«ãã®ãšã©ãŒãçºçããå Žåã¯ã this.$router.go({...})
this.$router.push({...})
ã䜿çšããŠãã ãã
以äžã®ã³ãŒãã1è¡ç®ã«é
眮ããŸãã
delete global.window.location;
global.window.location = "";
window.locationãå€æŽããŠããã¯ãªãã¯ã€ãã³ãããã£ããã£ã§ããããã«ãªããŸããã
"jest"ïŒ "^ 23.6.0"
ããã¯æ©èœããŸãïŒ
delete window.location;
window.location = Object.assign({}, window.location);
const url = Object.assign({}, new URL('http://google.com'));
Object.keys(url).forEach(prop => (window.location[prop] = url[prop]));
ãŸãã¯ããã«è¯ã...
delete (global as any).window;
(global as any).window = new JSDOM(undefined, { url: 'http://google.com' }).window;
ããªãã¯æ£ããã§ããããã¯ç¢ºãã«jsdomã®åé¡ã§ãã Facebookã§ã¯ããããåé¿ããããã«ããã䜿çšããŠããŸãã
Object.defineProperty(window.location, 'href', { writable: true, value: 'some url' });
ããã¯ç§ãã¡ã«ãšã£ãŠã¯ããŸããããŸãããç§ãã¡ã¯ãŸã å éšçã«jsdom7ã䜿çšããŠããŸãã
Object.defineProperty
ã®ããæ¹ã§åé¡ãªããšæãã®ã§ããããéããŸãã jsdom 8ã§ãããããŸããããªãå Žåã¯ãåéãããŠããã ããŸãã
ãããç§ã¯location.search
ãšlocation.hash
ãæ±ãããã€ãã®é¢æ°ãæã£ãŠããŸãããããŠããªããèšã£ãããã«ç§ã¯ãããdefineProperty
ã§ãã¹ãããããšæããŸãã åäœããŸããïŒ
jest
ãµã€ã¬ã³ãã¢ãŒãããªãã«ãããšã次ã®ããã«ãªããŸãïŒ Error: Not implemented: navigation (except hash changes)
console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29
Error: Not implemented: navigation (except hash changes)
at module.exports (/home/ghlandy/projects/wdph-utils/node_modules/jsdom/lib/jsdom/browser/not-implemented.js:9:17)
at navigateFetch (/home/ghlandy/projects/wdph-utils/node_modules/jsdom/lib/jsdom/living/window/navigation.js:74:3)
at exports.navigate (/home/ghlandy/projects/wdph-utils/node_modules/jsdom/lib/jsdom/living/window/navigation.js:52:3)
at LocationImpl._locationObjectNavigate (/home/ghlandy/projects/wdph-utils/node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:29:5)
at LocationImpl.assign (/home/ghlandy/projects/wdph-utils/node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:213:10)
at Location.assign (/home/ghlandy/projects/wdph-utils/node_modules/jsdom/lib/jsdom/living/generated/Location.js:93:25)
at Object.assign (/home/ghlandy/projects/wdph-utils/src/__tests__/url.test.js:6:14)
at Object.asyncJestLifecycle (/home/ghlandy/projects/wdph-utils/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:53:37)
at resolve (/home/ghlandy/projects/wdph-utils/node_modules/jest-jasmine2/build/queueRunner.js:43:12)
at new Promise (<anonymous>) undefined
ãããŠä»ãç§ã¯èªåã®æ©èœããã¹ãããæ¹æ³ãããããŸããã
誰ã§ããã¹ããå€æŽããæ¹æ³ããããŸãurl
ããªãã¯æ£ããã§ããããã¯ç¢ºãã«jsdomã®åé¡ã§ãã Facebookã§ã¯ããããåé¿ããããã«ããã䜿çšããŠããŸãã
Object.defineProperty(window.location, 'href', { writable: true, value: 'some url' });
ããã¯ç§ãã¡ã«ãšã£ãŠã¯ããŸããããŸãããç§ãã¡ã¯ãŸã å éšçã«jsdom7ã䜿çšããŠããŸãã
Object.defineProperty
ã®ããæ¹ã§åé¡ãªããšæãã®ã§ããããéããŸãã jsdom 8ã§ãããããŸããããªãå Žåã¯ãåéãããŠããã ããŸãããããç§ã¯
location.search
ãšlocation.hash
ãæ±ãããã€ãã®é¢æ°ãæã£ãŠããŸãããããŠããªããèšã£ãããã«ç§ã¯ãããdefineProperty
ã§ãã¹ãããããšæããŸãã åäœããŸããïŒ
jest
ãµã€ã¬ã³ãã¢ãŒãããªãã«ãããšã次ã®ããã«ãªããŸãïŒError: Not implemented: navigation (except hash changes)
console.error node_modules/jsdom/lib/jsdom/virtual-console.js:29 Error: Not implemented: navigation (except hash changes) at module.exports (/home/ghlandy/projects/wdph-utils/node_modules/jsdom/lib/jsdom/browser/not-implemented.js:9:17) at navigateFetch (/home/ghlandy/projects/wdph-utils/node_modules/jsdom/lib/jsdom/living/window/navigation.js:74:3) at exports.navigate (/home/ghlandy/projects/wdph-utils/node_modules/jsdom/lib/jsdom/living/window/navigation.js:52:3) at LocationImpl._locationObjectNavigate (/home/ghlandy/projects/wdph-utils/node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:29:5) at LocationImpl.assign (/home/ghlandy/projects/wdph-utils/node_modules/jsdom/lib/jsdom/living/window/Location-impl.js:213:10) at Location.assign (/home/ghlandy/projects/wdph-utils/node_modules/jsdom/lib/jsdom/living/generated/Location.js:93:25) at Object.assign (/home/ghlandy/projects/wdph-utils/src/__tests__/url.test.js:6:14) at Object.asyncJestLifecycle (/home/ghlandy/projects/wdph-utils/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:53:37) at resolve (/home/ghlandy/projects/wdph-utils/node_modules/jest-jasmine2/build/queueRunner.js:43:12) at new Promise (<anonymous>) undefined
ãããŠä»ãç§ã¯èªåã®æ©èœããã¹ãããæ¹æ³ãããããŸããã
誰ã§ããã¹ããå€æŽããæ¹æ³ããããŸã
url
ãããŠç§ã®ç¶æ³ã§ã¯ã jest.config.js
ãã¡ã€ã«ã®ãã£ãŒã«ãtestURL
ãæ©èœããå¯èœæ§ããããŸãã ããããåãã¹ãã®åã«testURLãå€æŽãããå Žåã¯ã©ããªããŸããã
ãã®æçš¿ã¯éåžžã«åœ¹ã«ç«ã¡ãŸããïŒ https ïŒ//www.ryandoll.com/post/2018/3/29/jest-and-url-mocking
ãJestæ§æã§ã¯ãå¿ ã次ã®ããã«èšå®ããŠãã ããã
"testURL": "https://www.somthing.com/test.html"
次ã«ããã¹ãã®beforeEachïŒïŒã»ã¯ã·ã§ã³ã§ãå¿ èŠã«å¿ããŠãã¹ãå€æŽããŸãã
history.pushStateïŒïŒãwindow.history.pushState({}, 'Test Title', '/test.html?query=true');
åºæ¥äžããïŒ ããã§ãäžèšã®ã¹ã¬ããã§ä»ã®äººã瀺åããŠããããã«jsdomæ§æããªãŒããŒã©ã€ãããããšãªãããã¹ãã®ãã¹ãå€æŽã§ããŸãã ãã®ãœãªã¥ãŒã·ã§ã³ãã©ã®ã¹ã¬ããã§èŠã€ãããã¯ããããŸãããããããæçš¿ããéçºè ã«æè¬ããŸãïŒã
åªãããœãªã¥ãŒã·ã§ã³!!! ã©ããããããšãããããŸããïŒ @ Mike-Tran
ç§ã¯ãã®ãããªçããŠäŸµè¥²çã§ãªã解決çã欲ããã£ãã®ã§ãïŒ
2019幎6æã®æç¹ã§ãããæ©èœãããã«ã¯ã次ã®ããšãè¡ãå¿ èŠããããŸããã
delete global.window.location;
global.window = Object.create(window);
global.window.location = {
port: '123',
protocol: 'http:',
hostname: 'localhost',
};
ç§ã¯ããã䜿ããŸãâŠã
window.history.pushState({}, '', `${url}/`);
ããããç§ã®JSDOMTestWrapperã®äžéšã誰ããå©ããããšãã§ããŸã
/** <strong i="6">@type</strong> {Window} */
this.testWindowObject = Object.create(window);
const wnd = this.testWindowObject;
this.testWindowObject.history = {
state: null,
prev: { /** <strong i="7">@todo</strong> immutable stack with the go(step) method emulation */
state: null,
pathname: null,
search: null,
},
go(step) {
logger.special('history go called', step);
logger.warn('history go has not supported yet');
},
back() {
this.state = this.prev.state;
wnd.location.pathname = this.prev.pathname;
wnd.location.search = this.prev.search;
const eventData = this.state ? { url: this.state.displayURL, newState: this.state, type: 'push' } : null;
wnd.sm.eventsService.triggerEvent(ROUTER_EVENTS.ROUTE_PUSH, eventData);
wnd.sm.urlService.simpleRouteTo(`${ wnd.location.pathname || '' }${ wnd.location.search || '' }`);
logger.special('history back emulated');
},
pushState(state, title, url) {
this.prev.state = Object.assign({}, this.state);
this.prev.pathname = '' + wnd.location.pathname;
this.prev.search = '' + wnd.location.search;
this.state = state;
if (title) wnd.document.title = title;
const [p, s] = url.split('?');
wnd.location.pathname = p;
wnd.location.search = s ? `?${ s }` : '';
logger.special('push state emulated', { state, title, url });
},
replaceState(state, title, url) {
this.prev.state = Object.assign({}, this.state);
this.prev.pathname = '' + wnd.location.pathname;
this.prev.search = '' + wnd.location.search;
this.state = state;
if (title) wnd.document.title = title;
const [p, s] = url.split('?');
wnd.location.pathname = p;
wnd.location.search = s ? `?${ s }` : '';
logger.special('replace state emulated', { state, title, url });
logger.special('test: urlService.getPathName()', wnd.sm.urlService.getPathName());
},
};
this.testWindowObject.innerWidth = WND_WIDTH;
this.testWindowObject.innerHeight = WND_HEIGHT;
this.testWindowObject.fetch = fetchFn;
this.testWindowObject.localStorage = lstMock;
this.testWindowObject.scrollTo = (x, y) => {
/** not implemented yet https://github.com/jsdom/jsdom/issues/1422 */
if (typeof x !== 'number' && (x.left || x.top)) {
y = x.top;
x = x.left;
}
// logger.info(`window.scrollTo(${ x }, ${ y })`);
};
if (fetchFn === JSDOMTestWrapper.FETCH_FN.DEV_MOCK) {
global.Request = RequestMock;
this.testWindowObject.Request = RequestMock;
}
if (href) {
this.testWindowObject.location = Object.assign({}, this.testWindowObject.location, urlapi.parse(href));
}
else {
this.testWindowObject.location = Object.assign({}, this.testWindowObject.location);
}
(function(ELEMENT) {
ELEMENT.matches = ELEMENT.matches || ELEMENT.mozMatchesSelector || ELEMENT.msMatchesSelector || ELEMENT.oMatchesSelector || ELEMENT.webkitMatchesSelector;
ELEMENT.closest = ELEMENT.closest || function closest(selector) {
if (!this) return null;
if (this.matches(selector)) return this;
if (!this.parentElement) {return null}
else return this.parentElement.closest(selector)
};
ELEMENT.getBoundingClientRect = ELEMENT.getBoundingClientRect || (() =>
({ bottom: WND_HEIGHT, height: WND_HEIGHT, left: 0, right: WND_WIDTH, top: 0, width: WND_WIDTH, x: 0, y: 0 }));
}(Element.prototype));
this.testWindowObject.getBoundingClientRect = () =>
({ bottom: WND_HEIGHT, height: WND_HEIGHT, left: 0, right: WND_WIDTH, top: 0, width: WND_WIDTH, x: 0, y: 0 });
this.testWindowObject.__resizeListeners__ = [];
this.testWindowObject.__resizeTriggers__ = {};
this.testWindowObject._detectElementResize = {
removeResizeListener: () => {},
};
this.testWindowObject.matchMedia = jest.fn().mockImplementation(query => {
return {
matches: false,
media: query,
onchange: null,
addListener: jest.fn(),
removeListener: jest.fn(),
};
});
this.rftpr = () => {};
this.mode = mode;
this.renderFirstTimePromise = new Promise((resolve) => {
this.rftpr = resolve;
});
this.marpr = () => {};
this.mobileAppReadyPromise = new Promise((resolve) => {
this.marpr = resolve;
});
if (mode === JSDOMTestWrapper.MODE.MOBILE_APP) {
this.testWindowObject.navigator = Object.assign({}, this.testWindowObject.navigator, {
language: storeKey,
appVersion: '5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Mobile Safari/537.36',
userAgent: 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Mobile Safari/537.36',
vendor: 'Google Inc.',
});
global.intercom = {
registerUnidentifiedUser: jest.fn(),
registerForPush: jest.fn(),
};
}
const XApp = mode ? MobileApp : App;
const app = <XApp window={ this.testWindowObject } rftResolve={ this.rftpr } storeKey={ storeKey } apiHost={ apiVersion } forceMobileDetection={ mode } />;
render(app, this.testWindowObject.document.body);
if (mode === JSDOMTestWrapper.MODE.MOBILE_APP) {
setTimeout(() => {
this.testWindowObject.sm.deviceService.appRestorePathHasInit = this.marpr;
this.testWindowObject.sm.deviceService.fireEvent(this.testWindowObject.document, 'deviceready');
}, 200);
}
ãã®ã¢ãããŒãã¯2019幎9æ27æ¥çŸåšæå¹ã§ãïŒ https ïŒ//stackoverflow.com/a/54034379/1344144
global.window = Object.create(window);
const url = "http://dummy.com";
Object.defineProperty(window, "location", {
value: {
href: url
},
writable: true
});
jsdom
ãæžããªããŠããçŸåšå¥ã®è§£æ±ºçãæ©èœããŸãã
jest.config.js
ã«testURL
ãèšå®ããŠããããšã確èªããŠãã ããã// jest.config.js
'testURL': 'https://someurl.com'
ãã¹ããã¡ã€ã«å ïŒ
window.history.pushState({}, 'Mocked page title', 'www.yoururl.com');
https://www.ryandoll.com/post/2018/3/29/jest-and-url-mockingããåŠã³ãŸããã ã©ã€ã¢ã³ã«æè¬ããŸãïŒ
ç§ã®ããã«åããŠããªãïŒ
TypeErrorïŒå³å¯ã¢ãŒãã§ã¯èš±å¯ãããŠããªãèªã¿åãå°çšããããã£ãžã®å²ãåœãŠ
it("should save hash when history is not found", () => {
const historyBkp = global.window.history;
delete global.window.history;
global.window.history = false;
externalLoader.savePageURL(urlTraining);
expect(window.location.hash).to.be.equal(`#page=${urlTraining}`);
global.window.history = historyBkp;
window.location.hash = "";
});
ç§ã®ããã«åããŠããªãïŒ
TypeErrorïŒå³å¯ã¢ãŒãã§ã¯èš±å¯ãããŠããªãèªã¿åãå°çšããããã£ãžã®å²ãåœãŠ
it("should save hash when history is not found", () => { const historyBkp = global.window.history; delete global.window.history; global.window.history = false; externalLoader.savePageURL(urlTraining); expect(window.location.hash).to.be.equal(`#page=${urlTraining}`); global.window.history = historyBkp; window.location.hash = ""; });
ãããã°ããŒãã«ãã¡ã€ã«ã«è¿œå ããŸãã
global.window.locationãåé€ããŸãã
global.window.location = "";
ãã®ã¢ãããŒãã¯2019幎9æ27æ¥çŸåšæå¹ã§ãïŒ https ïŒ//stackoverflow.com/a/54034379/1344144
global.window = Object.create(window); const url = "http://dummy.com"; Object.defineProperty(window, "location", { value: { href: url }, writable: true });
location.assignã䜿çšããŠåæ§ã®ããšãè©Šã¿ãŠããŸãããããã¯ããæ©èœããŠããªãããã§ãã
ããã¯jest24.9.0ã§ç§ã®ããã«åããŸã
window.history.replaceState({}, 'Test Title', '/test?userName=James&userNumber=007');
ããã¯jest24.9.0ã§ç§ã®ããã«åããŸã
window.history.replaceState({}, 'Test Title', '/test?userName=James&userNumber=007');
ãããæ©èœãããã«ã¯ãpromiseå ã§ã³ãŒããå®è¡ããŠãããããã³ãŒããéåæã«ããå¿ èŠããããŸããã
ã ããä»åããŠããŸãð
vuexã¢ã¯ã·ã§ã³ã§chengeã®å Žæããã¹ãããæ¹æ³ã¯ïŒ
async setForm({ rootState, state, commit, dispatch }, formData) {
....
switch (answ.result.type) {
....
case 'redirect':
console.log(answ.data.url);
window.location = answ.data.url;
console.log({ location: window.location.href });
break;
default:
break;
it('setForm - success, redirect', async done => {
expect(window.location.href).toBe('https://www.google.ru/');
ãšã©ãŒããããŸãïŒ
expect(received).toBe(expected) // Object.is equality
Expected: "https://www.google.ru/"
Received: "http://localhost/"
ããã¯ç§ã®ããã«åãã
const location = JSON.stringify(window.location); delete window.location; Object.defineProperty(window, 'location', { value: JSON.parse(location) }); Object.defineProperty(global.location, 'href', { value: 'http://localhost/newURL', configurable: true });
jestããŒãžã§ã³23.6.0
ã°ããŒãã«ãšã¯äœã§ããïŒ
ã°ããŒãã«ãªå®çŸ©ã¯ã©ãã«ãããŸããïŒ
ããã¯ç§ã®ããã«åããã
delete global.window.location global.window.location = { href: 'https://test-domain.com.br', ...anyOptions }
ããã«ãããå ã®ãã¹ãŠã®æ©èœãåãããã±ãŒã·ã§ã³ãäœæãããŸãããã¢ãã¯å¯èœã§ãã
beforeAll(() => {
const location = window.location
delete global.window.location
global.window.location = Object.assign({}, location)
})
æãåèã«ãªãã³ã¡ã³ã
ããªãã¯æ£ããã§ããããã¯ç¢ºãã«jsdomã®åé¡ã§ãã Facebookã§ã¯ããããåé¿ããããã«ããã䜿çšããŠããŸãã
ããã¯ç§ãã¡ã«ãšã£ãŠã¯ããŸããããŸãããç§ãã¡ã¯ãŸã å éšçã«jsdom7ã䜿çšããŠããŸãã
Object.defineProperty
ã®ããæ¹ã§åé¡ãªããšæãã®ã§ããããéããŸãã jsdom 8ã§ãããããŸããããªãå Žåã¯ãåéãããŠããã ããŸãã