Skip to content

Commit 8ecdcca

Browse files
Add tests for filter bar widget
1 parent 9ad2534 commit 8ecdcca

File tree

3 files changed

+260
-17
lines changed

3 files changed

+260
-17
lines changed
Lines changed: 256 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,170 @@
11
describe('filter-bar', () => {
2-
beforeEach(() => cy.visit('http://localhost:8080/testcases/api/tests/-filter-test/index.html'));
2+
beforeEach(openPage);
33

44
it('properly renders filters extracted from the document', () => {
55
const filterBar = new FilterBarFixture().toggle();
66

7-
const testTable = [
7+
const testTable: TestTable = [
88
['Visibility', ['public', 'protected']],
99
['Keywords', ['no keywords', 'abstract', 'case', 'final', 'sealed']],
1010
['Extension', ['Standard member', 'from tests']],
1111
];
1212

13-
testTable.forEach(([title, filterOptions], index) => {
14-
const group = filterBar.group(index);
13+
testFilterBarOptions(filterBar, testTable);
14+
});
1515

16-
group.title.should('have.text', title);
17-
group.filterOptions.should('deep.equal', filterOptions);
18-
});
16+
it('properly filters the definition list through search box', () => {
17+
const tabs = new TabsFixture();
18+
const filterBar = new FilterBarFixture().toggle();
19+
20+
// type
21+
tabs.definition('publicType').should('be.visible');
22+
// protected type
23+
tabs.definition('protectedType').should('be.visible');
24+
25+
filterBar.input.type('protectedType');
26+
27+
// protected type
28+
tabs.definition('protectedType').should('be.visible');
29+
// type
30+
tabs.definition('publicType').should('not.be.visible');
31+
32+
const testTable: TestTable = [
33+
['Visibility', ['public', 'protected']],
34+
['Keywords', ['no keywords']],
35+
['Extension', ['Standard member']],
36+
];
37+
38+
testFilterBarOptions(filterBar, testTable);
39+
});
40+
41+
it('works with select all / deselect all', () => {
42+
const filterBar = new FilterBarFixture().toggle();
43+
const group = filterBar.group(0);
44+
const batchSelection = filterBar.group(0).batchSelection;
45+
46+
const public = () => group.filterOption('public').then(x => x.isSelected);
47+
const protected = () => group.filterOption('protected').then(x => x.isSelected);
48+
49+
public().should('be.equal', true);
50+
protected().should('be.equal', true);
51+
52+
batchSelection.deselectAll();
53+
54+
public().should('be.equal', false);
55+
protected().should('be.equal', false);
56+
57+
batchSelection.selectAll();
58+
59+
public().should('be.equal', true);
60+
protected().should('be.equal', true);
1961
});
2062

21-
it('filters by && across groups', () => {});
63+
describe('filter configurations', () => {
64+
describe('returns empty list after deselecting', () => {
65+
it(`'public' and 'no keywords'`, () => {
66+
const filterBar = new FilterBarFixture().toggle();
67+
filterBar.group(0).toggleFilter('public');
68+
filterBar.group(1).toggleFilter('no keywords');
69+
70+
new TabsFixture().definitionTypes.should('not.be.visible');
71+
});
72+
73+
it(`'Standard member'`, () => {
74+
new FilterBarFixture().toggle().group(2).toggleFilter('Standard member');
75+
76+
new TabsFixture().definitionTypes.should('not.be.visible');
77+
});
78+
79+
it('all visibility options', () => {
80+
new FilterBarFixture().toggle().group(0).toggleFilter('public', 'protected');
81+
82+
new TabsFixture().definitionTypes.should('not.be.visible');
83+
});
84+
85+
it('all keywords options', () => {
86+
new FilterBarFixture()
87+
.toggle()
88+
.group(1)
89+
.toggleFilter('no keywords', 'abstract', 'case', 'final', 'sealed');
90+
91+
new TabsFixture().definitionTypes.should('not.be.visible');
92+
});
93+
94+
it('all extension options', () => {
95+
new FilterBarFixture().toggle().group(2).toggleFilter('Standard member', 'from tests');
96+
97+
new TabsFixture().definitionTypes.should('not.be.visible');
98+
});
99+
});
100+
101+
describe('returns filtered list after deselecting', () => {
102+
it(`'protected'`, () => {
103+
const tabs = new TabsFixture();
104+
105+
tabs.definition('protected').should('be.visible');
106+
new FilterBarFixture().toggle().group(0).toggleFilter('protected');
107+
tabs.definition('protected').should('not.be.visible');
108+
});
109+
110+
it(`'no keywords', 'case', 'final' and 'sealed'`, () => {
111+
const tabs = new TabsFixture();
112+
113+
// protected object
114+
tabs.definition('ProtectedObject').should('be.visible');
115+
116+
// sealed case class
117+
tabs.definition('D').should('be.visible');
118+
119+
// final case class
120+
tabs.definition('E').should('be.visible');
121+
122+
new FilterBarFixture()
123+
.toggle()
124+
.group(1)
125+
.toggleFilter('no keywords', 'case', 'final', 'sealed');
126+
127+
// protected object
128+
tabs.definition('ProtectedObject').should('not.be.visible');
129+
130+
// sealed abstract class
131+
tabs.definition('B').should('be.visible');
132+
133+
// abstract case class
134+
tabs.definition('C').should('be.visible');
135+
136+
// sealed case class
137+
tabs.definition('D').should('not.be.visible');
138+
139+
// final case class
140+
tabs.definition('E').should('not.be.visible');
141+
});
142+
143+
it(`'no keywords', 'final' and 'sealed'`, () => {
144+
const tabs = new TabsFixture();
145+
146+
// protected object
147+
tabs.definition('ProtectedObject').should('be.visible');
148+
149+
new FilterBarFixture().toggle().group(1).toggleFilter('no keywords', 'final', 'sealed');
150+
151+
// protected object
152+
tabs.definition('ProtectedObject').should('not.be.visible');
153+
154+
// sealed abstract class
155+
tabs.definition('B').should('be.visible');
156+
157+
// abstract case class
158+
tabs.definition('C').should('be.visible');
159+
160+
// sealed case class
161+
tabs.definition('D').should('be.visible');
162+
163+
// final case class
164+
tabs.definition('E').should('be.visible');
165+
});
166+
});
167+
});
22168
});
23169

24170
class FilterBarFixture {
@@ -30,6 +176,10 @@ class FilterBarFixture {
30176
return new FilterBarGroupFixture(at);
31177
}
32178

179+
get input() {
180+
return new FilterInputFixture();
181+
}
182+
33183
toggle() {
34184
this.toggleButton.click();
35185

@@ -44,17 +194,110 @@ class FilterBarGroupFixture {
44194
return cy.findAllByTestId('filterGroup').eq(this.index);
45195
}
46196

47-
private get filterList() {
48-
return this.group.findByTestId('filterGroupList');
197+
private get filterButtons() {
198+
return this.group
199+
.findByTestId('filterGroupList')
200+
.findAllByTestId('filterGroupButton')
201+
.filter(':visible');
49202
}
50203

51204
get title() {
52205
return this.group.findByTestId('filterGroupTitle');
53206
}
54207

208+
get batchSelection() {
209+
return new BatchSelectionFixture(() => this.group);
210+
}
211+
212+
get filterOptionsValues() {
213+
return this.filterOptions.then(options => {
214+
const acc: string[] = [];
215+
options.forEach(o => o.name.then(v => acc.push(v)));
216+
return cy.wrap(acc);
217+
});
218+
}
219+
220+
filterOption(name: string) {
221+
return this.filterButtons
222+
.contains(name)
223+
.then($el => new FilterOptionFixture(() => cy.wrap($el)));
224+
}
225+
55226
get filterOptions() {
56-
return this.filterList
57-
.findAllByTestId('filterGroupButton')
58-
.then($buttons => cy.wrap($buttons.toArray().map(i => i.innerText)));
227+
return (
228+
this.filterButtons
229+
// .filter(':visible')
230+
.then($buttons =>
231+
cy.wrap($buttons.toArray().map(el => new FilterOptionFixture(() => cy.wrap(el)))),
232+
)
233+
);
234+
}
235+
236+
toggleFilter(...names: string[]) {
237+
names.forEach(name => this.filterButtons.contains(name).click());
238+
return this;
239+
}
240+
}
241+
242+
class FilterOptionFixture {
243+
constructor(private readonly root: () => Cypress.Chainable<JQuery<HTMLElement>>) {}
244+
245+
get name() {
246+
return this.root().then($el => $el.text());
247+
}
248+
249+
get isSelected() {
250+
return this.root().then($el => cy.wrap($el.data('selected')));
251+
}
252+
}
253+
254+
class TabsFixture {
255+
get definitionTypes() {
256+
return cy.findAllByTestId('definitionList');
257+
}
258+
259+
definition(name: string) {
260+
return this.definitionTypes.contains(name);
261+
}
262+
}
263+
264+
class FilterInputFixture {
265+
private get input() {
266+
return cy.findByTestId('filterBarInput');
267+
}
268+
269+
type(phrase: string) {
270+
this.input.type(phrase);
271+
}
272+
}
273+
274+
class BatchSelectionFixture {
275+
constructor(private readonly root: () => Cypress.Chainable<JQuery<HTMLElement>>) {}
276+
277+
private get container() {
278+
return this.root().findByTestId('filterGroupBatchToggle');
279+
}
280+
281+
selectAll() {
282+
this.container.findByText('Select All').click();
59283
}
284+
285+
deselectAll() {
286+
this.container.findByText('Deselect All').click();
287+
}
288+
}
289+
290+
function openPage() {
291+
cy.visit('http://localhost:8080/testcases/api/tests/-filter-test/index.html');
292+
}
293+
294+
type TestTable = [string, string[]][];
295+
296+
function testFilterBarOptions(filterBar: FilterBarFixture, testTable: TestTable) {
297+
testTable.forEach(([title, filterOptions], index) => {
298+
const group = filterBar.group(index);
299+
300+
group.title.should('have.text', title);
301+
group.filterOptionsValues.should('deep.equal', filterOptions);
302+
});
60303
}

scala3doc/resources/dotty_res/scripts/components/FilterGroup.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ class FilterGroup extends Component {
9090
<div class="filterGroup" data-test-id="filterGroup">
9191
<div class="groupTitle">
9292
<span data-test-id="filterGroupTitle">${filterKey.substring(1)}</span>
93-
<div class="groupButtonsContainer">
93+
<div class="groupButtonsContainer" data-test-id="filterGroupBatchToggle">
9494
<button class="selectAll" data-key="${filterKey}">Select All</button>
9595
<button class="deselectAll" data-key="${filterKey}">Deselect All</button>
9696
</div>
@@ -103,7 +103,7 @@ class FilterGroup extends Component {
103103
data.selected
104104
)} ${this.isVisible(
105105
data.visible
106-
)}" data-key="${filterKey}" data-value="${key}" data-test-id="filterGroupButton">${key}</button>`
106+
)}" data-key="${filterKey}" data-selected="${data.selected}" data-value="${key}" data-test-id="filterGroupButton">${key}</button>`
107107
)
108108
.join(" ")}
109109
</div>

scala3doc/src/dotty/renderers/ScalaHtmlRenderer.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class ScalaHtmlRenderer(ctx: DokkaContext) extends HtmlRenderer(ctx) {
132132

133133
)
134134

135-
div(cls := "documentableList")(
135+
div(cls := "documentableList", testId := "definitionList")(
136136
if(n.groupName.isEmpty) raw("") else h3(cls := "documentableHeader")(n.groupName.map(renderElement)),
137137
n.elements.flatMap {
138138
case element: DocumentableElement =>
@@ -154,7 +154,7 @@ class ScalaHtmlRenderer(ctx: DokkaContext) extends HtmlRenderer(ctx) {
154154
</svg>
155155
""")
156156
),
157-
input(cls := "filterableInput", placeholder := "Filter all members")
157+
input(cls := "filterableInput", placeholder := "Filter all members", testId := "filterBarInput")
158158
),
159159
div(cls := "filterLowerContainer")()
160160
)

0 commit comments

Comments
 (0)