Skip to content

Commit f563458

Browse files
committed
fix: Collapsed should support All and none
1 parent 34ff60f commit f563458

File tree

5 files changed

+93
-22
lines changed

5 files changed

+93
-22
lines changed

docs/user_guide.rst

+8-5
Original file line numberDiff line numberDiff line change
@@ -248,15 +248,18 @@ Auto Collapsing Table Rows
248248

249249
By default, all rows in the **Results** table will be expanded except those that have :code:`Passed`.
250250

251-
This behavior can be customized either with a query parameter: :code:`?collapsed=Passed,XFailed,Skipped`
252-
or by setting the :code:`render_collapsed` in a configuration file (pytest.ini, setup.cfg, etc).
251+
This behavior can be customized with a query parameter: :code:`?collapsed=Passed,XFailed,Skipped`.
252+
If you want all rows to be collapsed you can pass :code:`?collapsed=All`.
253+
By setting the query parameter to empty string :code:`?collapsed=""` **none** of the rows will be collapsed.
254+
255+
Note that the query parameter is case insensitive, so passing :code:`PASSED` and :code:`passed` has the same effect.
256+
257+
You can also set the collapsed behaviour by setting the :code:`render_collapsed` in a configuration file (pytest.ini, setup.cfg, etc).
253258

254259
.. code-block:: ini
255260
256261
[pytest]
257-
render_collapsed = True
258-
259-
**NOTE:** Setting :code:`render_collapsed` will, unlike the query parameter, affect all statuses.
262+
render_collapsed = FIX THIS
260263
261264
Controlling Test Result Visibility Via Query Params
262265
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

src/pytest_html/scripts/datamanager.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const { getCollapsedCategory } = require('./storage.js')
22

33
class DataManager {
44
setManager(data) {
5-
const collapsedCategories = [...getCollapsedCategory(), 'passed']
5+
const collapsedCategories = [...getCollapsedCategory()]
66
const dataBlob = { ...data, tests: Object.values(data.tests).flat().map((test, index) => ({
77
...test,
88
id: `test_${index}`,

src/pytest_html/scripts/main.js

+1-11
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const { dom, findAll } = require('./dom.js')
33
const { manager } = require('./datamanager.js')
44
const { doSort } = require('./sort.js')
55
const { doFilter } = require('./filter.js')
6-
const { getVisible } = require('./storage.js')
6+
const { getVisible, possibleResults } = require('./storage.js')
77

88
const removeChildren = (node) => {
99
while (node.firstChild) {
@@ -61,16 +61,6 @@ const renderContent = (tests) => {
6161
}
6262

6363
const renderDerived = (tests, collectedItems, isFinished) => {
64-
const possibleResults = [
65-
{ result: 'passed', label: 'Passed' },
66-
{ result: 'skipped', label: 'Skipped' },
67-
{ result: 'failed', label: 'Failed' },
68-
{ result: 'error', label: 'Errors' },
69-
{ result: 'xfailed', label: 'Unexpected failures' },
70-
{ result: 'xpassed', label: 'Unexpected passes' },
71-
{ result: 'rerun', label: 'Reruns' },
72-
]
73-
7464
const currentFilter = getVisible()
7565
possibleResults.forEach(({ result, label }) => {
7666
const count = tests.filter((test) => test.result.toLowerCase() === result).length

src/pytest_html/scripts/storage.js

+29-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
const possibleFilters = ['passed', 'skipped', 'failed', 'error', 'xfailed', 'xpassed', 'rerun']
1+
const possibleResults = [
2+
{ result: 'passed', label: 'Passed' },
3+
{ result: 'skipped', label: 'Skipped' },
4+
{ result: 'failed', label: 'Failed' },
5+
{ result: 'error', label: 'Errors' },
6+
{ result: 'xfailed', label: 'Unexpected failures' },
7+
{ result: 'xpassed', label: 'Unexpected passes' },
8+
{ result: 'rerun', label: 'Reruns' },
9+
]
10+
const possibleFilters = possibleResults.map((item) => item.result)
211

312
const getVisible = () => {
413
const url = new URL(window.location.href)
@@ -50,15 +59,28 @@ const setSort = (type) => {
5059
}
5160

5261
const getCollapsedCategory = () => {
53-
let categotries
62+
let categories
5463
if (typeof window !== 'undefined') {
5564
const url = new URL(window.location.href)
5665
const collapsedItems = new URLSearchParams(url.search).get('collapsed')
57-
categotries = collapsedItems?.split(',') || []
66+
switch (true) {
67+
case collapsedItems === null:
68+
categories = ['passed'];
69+
break;
70+
case collapsedItems?.length === 0 || /^["']{2}$/.test(collapsedItems):
71+
categories = [];
72+
break;
73+
case /^all$/.test(collapsedItems):
74+
categories = [...possibleFilters];
75+
break;
76+
default:
77+
categories = collapsedItems?.split(',').map(item => item.toLowerCase()) || [];
78+
break;
79+
}
5880
} else {
59-
categotries = []
81+
categories = []
6082
}
61-
return categotries
83+
return categories
6284
}
6385

6486
const getSortDirection = () => JSON.parse(sessionStorage.getItem('sortAsc'))
@@ -75,4 +97,6 @@ module.exports = {
7597
setSort,
7698
setSortDirection,
7799
getCollapsedCategory,
100+
possibleFilters,
101+
possibleResults,
78102
}

testing/unittest.js

+54
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,57 @@ describe('utils tests', () => {
156156
})
157157
})
158158
})
159+
160+
describe('Storage tests', () => {
161+
describe('getCollapsedCategory', () => {
162+
let originalWindow
163+
const mockWindow = (queryParam) => {
164+
const mock = {
165+
location: {
166+
href: `https://example.com/page?${queryParam}`
167+
}
168+
}
169+
originalWindow = global.window
170+
global.window = mock
171+
}
172+
after(() => global.window = originalWindow)
173+
174+
it('collapses passed by default', () => {
175+
mockWindow('')
176+
const collapsedItems = storageModule.getCollapsedCategory()
177+
expect(collapsedItems).to.eql(['passed'])
178+
})
179+
180+
it('collapses specified outcomes', () => {
181+
mockWindow('collapsed=failed,error')
182+
const collapsedItems = storageModule.getCollapsedCategory()
183+
expect(collapsedItems).to.eql(['failed', 'error'])
184+
})
185+
186+
it('collapses all', () => {
187+
mockWindow('collapsed=all')
188+
const collapsedItems = storageModule.getCollapsedCategory()
189+
expect(collapsedItems).to.eql(storageModule.possibleFilters)
190+
})
191+
192+
it('handles case insensitive params', () => {
193+
mockWindow('collapsed=fAiLeD,ERROR,passed')
194+
const collapsedItems = storageModule.getCollapsedCategory()
195+
expect(collapsedItems).to.eql(['failed', 'error', 'passed'])
196+
})
197+
198+
const falsy = [
199+
{ param: 'collapsed' },
200+
{ param: 'collapsed=' },
201+
{ param: 'collapsed=""' },
202+
{ param: 'collapsed=\'\'' }
203+
]
204+
falsy.forEach(({param}) => {
205+
it(`collapses none with ${param}`, () => {
206+
mockWindow(param)
207+
const collapsedItems = storageModule.getCollapsedCategory()
208+
expect(collapsedItems).to.be.empty
209+
})
210+
})
211+
})
212+
})

0 commit comments

Comments
 (0)