diff --git a/src/pytest_html/scripts/datamanager.js b/src/pytest_html/scripts/datamanager.js
index 7d6e7cef..58344972 100644
--- a/src/pytest_html/scripts/datamanager.js
+++ b/src/pytest_html/scripts/datamanager.js
@@ -1,13 +1,17 @@
+const { getCollapsedCategory } = require('./storage.js')
+
class DataManager {
setManager(data) {
+ const collapsedCategories = getCollapsedCategory()
const dataBlob = { ...data, tests: data.tests.map((test, index) => ({
...test,
id: `test_${index}`,
- collapsed: false,
+ collapsed: collapsedCategories.includes(test.outcome.toLowerCase()),
})) }
this.data = { ...dataBlob }
this.renderData = { ...dataBlob }
}
+
get allData() {
return { ...this.data }
}
diff --git a/src/pytest_html/scripts/filter.js b/src/pytest_html/scripts/filter.js
index bfb994eb..4c2ccac7 100644
--- a/src/pytest_html/scripts/filter.js
+++ b/src/pytest_html/scripts/filter.js
@@ -2,26 +2,23 @@ const { manager } = require('./datamanager.js')
const storageModule = require('./storage.js')
const getFilteredSubSet = (filter) =>
- manager.allData.tests.filter(({ outcome }) => !filter.includes(outcome.toLowerCase()))
+ manager.allData.tests.filter(({ outcome }) => filter.includes(outcome.toLowerCase()))
const doInitFilter = () => {
- const currentFilter = storageModule.getFilter()
+ const currentFilter = storageModule.getVisible()
const filteredSubset = getFilteredSubSet(currentFilter)
manager.setRender(filteredSubset)
}
-const doFilter = (type, apply) => {
- const currentFilter = storageModule.getFilter()
- if (!apply) {
- currentFilter.push(type)
+const doFilter = (type, show) => {
+ if (show) {
+ storageModule.showCategory(type)
} else {
- const index = currentFilter.indexOf(type)
- if (index > -1) {
- currentFilter.splice(index, 1)
- }
+ storageModule.hideCategory(type)
}
- storageModule.setFilter(currentFilter)
+ const currentFilter = storageModule.getVisible()
+
if (currentFilter.length) {
const filteredSubset = getFilteredSubSet(currentFilter)
manager.setRender(filteredSubset)
diff --git a/src/pytest_html/scripts/main.js b/src/pytest_html/scripts/main.js
index 23898611..c4d1787c 100644
--- a/src/pytest_html/scripts/main.js
+++ b/src/pytest_html/scripts/main.js
@@ -3,7 +3,7 @@ const { dom, findAll } = require('./dom.js')
const { manager } = require('./datamanager.js')
const { doSort } = require('./sort.js')
const { doFilter } = require('./filter.js')
-const { getFilter } = require('./storage.js')
+const { getVisible } = require('./storage.js')
const removeChildren = (node) => {
while (node.firstChild) {
@@ -74,14 +74,14 @@ const renderDerived = (tests, collectedItems, isFinished) => {
{ outcome: 'rerun', label: 'Reruns' },
]
- const currentFilter = getFilter()
+ const currentFilter = getVisible()
possibleOutcomes.forEach(({ outcome, label }) => {
const count = renderSet.filter((test) => test.outcome.toLowerCase() === outcome).length
const input = document.querySelector(`input[data-test-result="${outcome}"]`)
document.querySelector(`.${outcome}`).innerText = `${count} ${label}`
input.disabled = !count
- input.checked = !currentFilter.includes(outcome)
+ input.checked = currentFilter.includes(outcome)
})
const numberOfTests = renderSet.filter(({ outcome }) =>
diff --git a/src/pytest_html/scripts/storage.js b/src/pytest_html/scripts/storage.js
index 794806e3..c7f5fff1 100644
--- a/src/pytest_html/scripts/storage.js
+++ b/src/pytest_html/scripts/storage.js
@@ -1,22 +1,71 @@
-const getFilter = () => [...new Set(JSON.parse(sessionStorage.getItem('filter')))]
+const possibleFiltes = ['passed', 'skipped', 'failed', 'error', 'xfailed', 'xpassed', 'rerun']
+
+const getVisible = () => {
+ const url = new URL(window.location.href)
+ const settings = new URLSearchParams(url.search).get('visible') || ''
+ const toret = settings ?
+ [...new Set(settings.split(',').filter((filter) => possibleFiltes.includes(filter)))] : possibleFiltes
+
+ return toret
+}
+const hideCategory = (categoryToHide) => {
+ const url = new URL(window.location.href)
+ const visibleParams = new URLSearchParams(url.search).get('visible')
+ const currentVisible = visibleParams ? visibleParams.split(',') : [...possibleFiltes]
+ const settings = [...new Set(currentVisible)].filter((f) => f !== categoryToHide).join(',')
+
+ url.searchParams.set('visible', settings)
+ history.pushState({}, null, unescape(url.href))
+}
+
+const showCategory = (categoryToShow) => {
+ const url = new URL(window.location.href)
+ const currentVisible = new URLSearchParams(url.search).get('visible')?.split(',') || [...possibleFiltes]
+ const settings = [...new Set([categoryToShow, ...currentVisible])]
+ const noFilter = possibleFiltes.length === settings.length || !settings.length
+
+ noFilter ? url.searchParams.delete('visible') : url.searchParams.set('visible', settings.join(','))
+ history.pushState({}, null, unescape(url.href))
+}
const setFilter = (currentFilter) => {
- sessionStorage.setItem('filter', JSON.stringify(currentFilter))
+ if (!possibleFiltes.includes(currentFilter)) {
+ return
+ }
+ const url = new URL(window.location.href)
+ const settings = [currentFilter, ...new Set(new URLSearchParams(url.search).get('filter').split(','))]
+
+ url.searchParams.set('filter', settings)
+ history.pushState({}, null, unescape(url.href))
}
-const getSort = () => sessionStorage.getItem('sort')
-const setSort = (type) => sessionStorage.setItem('sort', type)
+const getSort = () => {
+ const url = new URL(window.location.href)
+ return new URLSearchParams(url.search).get('sort') || 'outcome'
+}
+const setSort = (type) => {
+ const url = new URL(window.location.href)
+ url.searchParams.set('sort', type)
+ history.pushState({}, null, unescape(url.href))
+}
+
+const getCollapsedCategory = () => {
+ const url = new URL(window.location.href)
+ const collapsedItems = new URLSearchParams(url.search).get('collapsed')
+ return collapsedItems?.split(',') || []
+}
const getSortDirection = () => JSON.parse(sessionStorage.getItem('sortAsc'))
-const setSortDirection = (ascending) => {
- sessionStorage.setItem('sortAsc', ascending)
-}
+const setSortDirection = (ascending) => sessionStorage.setItem('sortAsc', ascending)
module.exports = {
- getFilter,
+ getVisible,
setFilter,
+ hideCategory,
+ showCategory,
getSort,
getSortDirection,
setSort,
setSortDirection,
+ getCollapsedCategory,
}
diff --git a/testing/unittest.js b/testing/unittest.js
index 0429fdb8..67f19b35 100644
--- a/testing/unittest.js
+++ b/testing/unittest.js
@@ -45,7 +45,7 @@ describe('Filter tests', () => {
after(() => dataModule.manager.setManager({ tests: [] }))
describe('doInitFilter', () => {
it('has no stored filters', () => {
- getFilterMock = sinon.stub(storageModule, 'getFilter').returns([])
+ getFilterMock = sinon.stub(storageModule, 'getVisible').returns([])
managerSpy = sinon.spy(dataModule.manager, 'setRender')
doInitFilter()
@@ -55,7 +55,7 @@ describe('Filter tests', () => {
])
})
it('exclude passed', () => {
- getFilterMock = sinon.stub(storageModule, 'getFilter').returns(['passed'])
+ getFilterMock = sinon.stub(storageModule, 'getVisible').returns(['passed'])
managerSpy = sinon.spy(dataModule.manager, 'setRender')
doInitFilter()
@@ -67,7 +67,7 @@ describe('Filter tests', () => {
let setFilterMock
afterEach(() => setFilterMock.restore())
it('removes a filter', () => {
- getFilterMock = sinon.stub(storageModule, 'getFilter').returns(['passed'])
+ getFilterMock = sinon.stub(storageModule, 'getVisible').returns(['passed'])
setFilterMock = sinon.stub(storageModule, 'setFilter')
managerSpy = sinon.spy(dataModule.manager, 'setRender')
@@ -78,7 +78,7 @@ describe('Filter tests', () => {
])
})
it('applies a filter', () => {
- getFilterMock = sinon.stub(storageModule, 'getFilter').returns([])
+ getFilterMock = sinon.stub(storageModule, 'getVisible').returns([])
setFilterMock = sinon.stub(storageModule, 'setFilter')
managerSpy = sinon.spy(dataModule.manager, 'setRender')