{"action":"created","issue":{"url":"https://api.github.com/repos/jsdom/jsdom/issues/2391","repository_url":"https://api.github.com/repos/jsdom/jsdom","labels_url":"https://api.github.com/repos/jsdom/jsdom/issues/2391/labels{/name}","comments_url":"https://api.github.com/repos/jsdom/jsdom/issues/2391/comments","events_url":"https://api.github.com/repos/jsdom/jsdom/issues/2391/events","html_url":"https://github.com/jsdom/jsdom/issues/2391","id":369193100,"node_id":"MDU6SXNzdWUzNjkxOTMxMDA=","number":2391,"title":"[FEATURE] toggle document.hidden in jsdom","user":{"login":"dotnetCarpenter","id":43763,"node_id":"MDQ6VXNlcjQzNzYz","avatar_url":"https://avatars2.githubusercontent.com/u/43763?v=4","gravatar_id":"","url":"https://api.github.com/users/dotnetCarpenter","html_url":"https://github.com/dotnetCarpenter","followers_url":"https://api.github.com/users/dotnetCarpenter/followers","following_url":"https://api.github.com/users/dotnetCarpenter/following{/other_user}","gists_url":"https://api.github.com/users/dotnetCarpenter/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnetCarpenter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnetCarpenter/subscriptions","organizations_url":"https://api.github.com/users/dotnetCarpenter/orgs","repos_url":"https://api.github.com/users/dotnetCarpenter/repos","events_url":"https://api.github.com/users/dotnetCarpenter/events{/privacy}","received_events_url":"https://api.github.com/users/dotnetCarpenter/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":7,"created_at":"2018-10-11T16:02:24Z","updated_at":"2018-10-11T19:22:09Z","closed_at":null,"author_association":"NONE","body":"### Basic info:\r\n\r\n- **Node.js version:** 8.12.0\r\n- **jsdom version:** 12.2.0\r\n\r\nI need to test code that set a timestamp value depending on `document.hidden`.\r\njsdom toggles the value depending on `pretendToBeVisual` as [documented in the jsdom README](https://github.com/jsdom/jsdom#pretending-to-be-a-visual-browser).\r\n\r\nI am using [jest](https://github.com/facebook/jest/) which uses jsdom.\r\n\r\n### Minimal reproduction case\r\n\r\nI need a way to toggle `document.hidden` in jsdom in order to test code that has different code paths depending on the value.\r\n\r\nTo test the following function `getTimeDuration`:\r\n```js\r\n/**\r\n * First call starts a timer and returns a function\r\n * that when called will give the elapsed time in\r\n * milisecond, while subtracting \"hidden\" time.\r\n * @returns {function} Calling this function will return the elapsed time.\r\n */\r\nexport default function getTimeDuration () {\r\n  const startTimestamp = Date.now()\r\n  let hiddenTimeDelta = 0\r\n  let hiddenTimeStart = 0\r\n\r\n  document.addEventListener('visibilitychange', trackHiddenTime)\r\n\r\n  function trackHiddenTime () {\r\n    if (document.hidden) {\r\n      hiddenTimeStart = Date.now()\r\n    } else {\r\n      hiddenTimeDelta += (Date.now() - hiddenTimeStart)\r\n    }\r\n  }\r\n\r\n  return () => {\r\n    document.removeEventListener('visibilitychange', trackHiddenTime)\r\n\r\n    return (Date.now() - hiddenTimeDelta) - startTimestamp\r\n  }\r\n}\r\n```\r\nWe could write the following test code:\r\n```js\r\ntest('visibilitychange duration used by PayloadTiming', () => {\r\n  // jestDateMock.advanceTo(0) is\r\n  // needed due to issue: https://github.com/hustcc/jest-date-mock/issues/15\r\n  jestDateMock.advanceTo(0)\r\n\r\n  const timer = getTimeDuration()\r\n\r\n  jestDateMock.advanceBy(10) // visible state\r\n\r\n  jsdom.pretendToBeVisual = false // hidden state\r\n  document.dispatchEvent(new Event('visibilitychange'))\r\n  jestDateMock.advanceBy(10)\r\n  \r\n  jsdom.pretendToBeVisual = true // visible state\r\n  document.dispatchEvent(new Event('visibilitychange'))\r\n  jestDateMock.advanceBy(10)\r\n\r\n  expect(timer()).toBe(20)\r\n  jestDateMock.clear()\r\n})\r\n```\r\n\r\nRef: https://github.com/facebook/jest/issues/7142"},"comment":{"url":"https://api.github.com/repos/jsdom/jsdom/issues/comments/429086024","html_url":"https://github.com/jsdom/jsdom/issues/2391#issuecomment-429086024","issue_url":"https://api.github.com/repos/jsdom/jsdom/issues/2391","id":429086024,"node_id":"MDEyOklzc3VlQ29tbWVudDQyOTA4NjAyNA==","user":{"login":"dotnetCarpenter","id":43763,"node_id":"MDQ6VXNlcjQzNzYz","avatar_url":"https://avatars2.githubusercontent.com/u/43763?v=4","gravatar_id":"","url":"https://api.github.com/users/dotnetCarpenter","html_url":"https://github.com/dotnetCarpenter","followers_url":"https://api.github.com/users/dotnetCarpenter/followers","following_url":"https://api.github.com/users/dotnetCarpenter/following{/other_user}","gists_url":"https://api.github.com/users/dotnetCarpenter/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnetCarpenter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnetCarpenter/subscriptions","organizations_url":"https://api.github.com/users/dotnetCarpenter/orgs","repos_url":"https://api.github.com/users/dotnetCarpenter/repos","events_url":"https://api.github.com/users/dotnetCarpenter/events{/privacy}","received_events_url":"https://api.github.com/users/dotnetCarpenter/received_events","type":"User","site_admin":false},"created_at":"2018-10-11T19:22:09Z","updated_at":"2018-10-11T19:22:09Z","author_association":"NONE","body":"Looking through your source code, that does not seem to solve the issue but I'll give it a go.\r\n\r\nIf not, I have an initial patch ready in a minute."}}
{"actor":{"display_login":"dotnetCarpenter"}}