Установите location.hash и location.href с помощью JSDom

Я настраиваю некоторые тесты, используя JSDom, где мне нужны глобальные переменные window и document, а также нужно передать другой URL/href для каждого теста. Как установить свойства location.hash и location.href?

global.document = jsdom({url: 'http://localhost?something=not#test', 'html': ''});
global.window = document.defaultView;
console.log(window.location.href); // returns 'about:blank'
console.log(window.location.hash); // returns no value

Я попытался присвоить значения непосредственно window.location.hash с тем же результатом.


person cyberwombat    schedule 25.11.2015    source источник


Ответы (4)


Вы можете установить location.hash, введя строку сразу после # в URL-адресе. Обратитесь к следующему моему коду.

var jsdom = require("jsdom");

jsdom.env({
    url: 'http://localhost?something=not#hash', 'html': '',
    onload: function( window ) {
        console.log(window.location.href); // http://localhost/?something=not#hash
        console.log(window.location.hash); // #hash
    }
});
person aluc    schedule 25.11.2015
comment
Я понимаю, что не совсем правильно сформулировал свой вопрос, поскольку в основном это было связано с тем, что href был пустым. Ваш ответ предполагает, что мне нужен обратный вызов. Есть ли способ обойти это? делать это в моих тестах очень грязно, так как мне нужно менять href для каждого теста. - person cyberwombat; 25.11.2015
comment
@Яшуа, верно! Поскольку загрузка страницы является асинхронной, как указано в руководстве по jsdom в github, рекомендуется использовать config.done, config.onload, config.created. - person aluc; 25.11.2015
comment
В итоге я издевался над своим собственным объектом окна — jsdom был излишним для моих тестов. stackoverflow.com/questions/4792281/ - person cyberwombat; 25.11.2015

Я тоже столкнулся с этой проблемой, но мне не удалось заставить работать решение jsdom.env(...). В итоге я последовал рекомендации здесь и используя функцию jsdom changeURL. Моя тестовая установка выглядела примерно так:

beforeEach(function() {
  // snip...
  jsdom.changeURL(window, 'http://foo/bar')
  // snip...
})
person killthrush    schedule 15.08.2016
comment
это больше не работает: jsdom_1.default.changeURL is not a function - person Moustachiste; 07.03.2019

Многие из этих ответов устарели. Более новые версии jsdom не позволяют перезаписывать данные, как раньше. То, что вы ищете, это вероятно функция reconfigure.

import { JSDOM } from 'jsdom';

const jsdom = new JSDOM();

// ...
jsdom.reconfigure({
  url: 'https://www.test.com/whatever/url/you/want',
});
// ...

Документацию по reconfigure() можно найти здесь.

Прочтите эту статью от 2020 года, чтобы получить дополнительную информацию. .

person Jacob Smith    schedule 15.01.2021

Этот работал на меня.

Object.defineProperty(window.location, 'href', {
  writable: true,
  value: 'some url'
});
person Aliaksandr Sushkevich    schedule 22.02.2018
comment
Этот ответ решил проблему, с которой я пытался протестировать компонент с помощью HashRouter из React Router, который умирал с непрозрачной ошибкой TypeError: Cannot read property 'substr' of undefined при попытке использовать createHashHistory(). undefined был window.location.hash, который JSDom не предоставляет, поэтому определение его таким образом в моем тесте устранило проблему. Надеюсь, это поможет любому, кто столкнулся с той же проблемой. - person Scott Martin; 17.03.2021