Skip to content

Commit 4e1e21c

Browse files
devvaannshabose
authored andcommitted
feat: integ tests for collapse folders feature
1 parent ef9a5b6 commit 4e1e21c

File tree

2 files changed

+335
-0
lines changed

2 files changed

+335
-0
lines changed

test/UnitTestSuite.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ define(function (require, exports, module) {
128128
require("spec/Extn-JSHint-integ-test");
129129
require("spec/Extn-ESLint-integ-test");
130130
require("spec/Extn-CSSColorPreview-integ-test");
131+
require("spec/Extn-CollapseFolders-integ-test");
131132
// extension integration tests
132133
require("spec/Extn-CSSCodeHints-integ-test");
133134
require("spec/Extn-HTMLCodeHints-Lint-integ-test");
Lines changed: 334 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
/*
2+
* GNU AGPL-3.0 License
3+
*
4+
* Copyright (c) 2021 - present core.ai . All rights reserved.
5+
*
6+
* This program is free software: you can redistribute it and/or modify it
7+
* under the terms of the GNU Affero General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
14+
* for more details.
15+
*
16+
* You should have received a copy of the GNU Affero General Public License
17+
* along with this program. If not, see https://opensource.org/licenses/AGPL-3.0.
18+
*
19+
*/
20+
21+
/*global describe, it, expect, beforeAll, afterAll, beforeEach, afterEach, awaitsFor, awaitsForDone */
22+
23+
define(function (require, exports, module) {
24+
const SpecRunnerUtils = require("spec/SpecRunnerUtils");
25+
26+
const testPath = SpecRunnerUtils.getTestPath("/spec/ProjectManager-test-files");
27+
28+
let ProjectManager, // loaded from brackets.test
29+
CommandManager, // loaded from brackets.test
30+
testWindow,
31+
brackets,
32+
$;
33+
34+
describe("integration:CollapseFolders", function () {
35+
beforeAll(async function () {
36+
testWindow = await SpecRunnerUtils.createTestWindowAndRun();
37+
brackets = testWindow.brackets;
38+
ProjectManager = brackets.test.ProjectManager;
39+
CommandManager = brackets.test.CommandManager;
40+
$ = testWindow.$;
41+
42+
await SpecRunnerUtils.loadProjectInTestWindow(testPath);
43+
}, 30000);
44+
45+
afterAll(async function () {
46+
ProjectManager = null;
47+
CommandManager = null;
48+
testWindow = null;
49+
brackets = null;
50+
$ = null;
51+
await SpecRunnerUtils.closeTestWindow();
52+
}, 30000);
53+
54+
afterEach(async function () {
55+
await testWindow.closeAllFiles();
56+
});
57+
58+
it("Should create collapse button in project files header", function () {
59+
const $projectFilesHeader = $("#project-files-header");
60+
const $collapseBtn = $("#collapse-folders");
61+
62+
expect($projectFilesHeader.length).toBe(1);
63+
expect($collapseBtn.length).toBe(1);
64+
expect($collapseBtn.parent()[0]).toBe($projectFilesHeader[0]);
65+
});
66+
67+
it("Should have correct button structure and classes", function () {
68+
const $collapseBtn = $("#collapse-folders");
69+
const $icons = $collapseBtn.find("i.collapse-icon");
70+
71+
expect($collapseBtn.hasClass("btn-alt-quiet")).toBe(true);
72+
expect($collapseBtn.attr("title")).toBe("Collapse All");
73+
expect($icons.length).toBe(2);
74+
expect($icons.eq(0).hasClass("fa-solid")).toBe(true);
75+
expect($icons.eq(0).hasClass("fa-chevron-down")).toBe(true);
76+
expect($icons.eq(1).hasClass("fa-solid")).toBe(true);
77+
expect($icons.eq(1).hasClass("fa-chevron-up")).toBe(true);
78+
});
79+
80+
it("Should show button on sidebar hover", async function () {
81+
const $sidebar = $("#sidebar");
82+
const $collapseBtn = $("#collapse-folders");
83+
84+
// Initially button should not have show class
85+
expect($collapseBtn.hasClass("show")).toBe(false);
86+
87+
// Trigger mouseenter on sidebar
88+
$sidebar.trigger("mouseenter");
89+
90+
await awaitsFor(
91+
function () {
92+
return $collapseBtn.hasClass("show");
93+
},
94+
"Button should show on sidebar hover",
95+
1000
96+
);
97+
98+
expect($collapseBtn.hasClass("show")).toBe(true);
99+
});
100+
101+
it("Should hide button on sidebar mouse leave", async function () {
102+
const $sidebar = $("#sidebar");
103+
const $collapseBtn = $("#collapse-folders");
104+
105+
// First show the button
106+
$sidebar.trigger("mouseenter");
107+
await awaitsFor(
108+
function () {
109+
return $collapseBtn.hasClass("show");
110+
},
111+
"Button should show first",
112+
1000
113+
);
114+
115+
// Then trigger mouseleave
116+
$sidebar.trigger("mouseleave");
117+
118+
await awaitsFor(
119+
function () {
120+
return !$collapseBtn.hasClass("show");
121+
},
122+
"Button should hide on sidebar mouse leave",
123+
1000
124+
);
125+
126+
expect($collapseBtn.hasClass("show")).toBe(false);
127+
});
128+
129+
it("Should have click handler attached", function () {
130+
const $collapseBtn = $("#collapse-folders");
131+
const events = $._data($collapseBtn[0], "events");
132+
133+
expect(events).toBeTruthy();
134+
expect(events.click).toBeTruthy();
135+
expect(events.click.length).toBe(1);
136+
});
137+
138+
function findTreeNode(fullPath) {
139+
const $treeItems = testWindow.$("#project-files-container li");
140+
let $result;
141+
142+
const name = fullPath.split("/").pop();
143+
144+
$treeItems.each(function () {
145+
const $treeNode = testWindow.$(this);
146+
if ($treeNode.children("a").text().trim() === name) {
147+
$result = $treeNode;
148+
return false; // break the loop
149+
}
150+
});
151+
return $result;
152+
}
153+
154+
async function openFolder(folderPath) {
155+
const $treeNode = findTreeNode(folderPath);
156+
expect($treeNode).toBeTruthy();
157+
158+
if (!$treeNode.hasClass("jstree-open")) {
159+
$treeNode.children("a").children("span").click();
160+
161+
await awaitsFor(
162+
function () {
163+
return $treeNode.hasClass("jstree-open");
164+
},
165+
`Open folder ${folderPath}`,
166+
2000
167+
);
168+
}
169+
}
170+
171+
function isFolderOpen(folderPath) {
172+
const $treeNode = findTreeNode(folderPath);
173+
return $treeNode && $treeNode.hasClass("jstree-open");
174+
}
175+
176+
function getOpenFolders() {
177+
const openFolders = [];
178+
testWindow.$("#project-files-container li.jstree-open").each(function () {
179+
const $node = testWindow.$(this);
180+
const folderName = $node.children("a").text().trim();
181+
if (folderName) {
182+
openFolders.push(folderName);
183+
}
184+
});
185+
return openFolders;
186+
}
187+
188+
it("Should collapse all open directories when clicked", async function () {
189+
// First, open some directories
190+
const directoryPath = testPath + "/directory";
191+
192+
await openFolder("directory");
193+
194+
// Verify the directory is open
195+
expect(isFolderOpen("directory")).toBe(true);
196+
197+
// Show the collapse button by hovering over sidebar
198+
const $sidebar = $("#sidebar");
199+
const $collapseBtn = $("#collapse-folders");
200+
$sidebar.trigger("mouseenter");
201+
202+
await awaitsFor(
203+
function () {
204+
return $collapseBtn.hasClass("show");
205+
},
206+
"Button should show",
207+
1000
208+
);
209+
210+
// Click the collapse button
211+
$collapseBtn.trigger("click");
212+
213+
// Wait for directories to close
214+
await awaitsFor(
215+
function () {
216+
return !isFolderOpen("directory");
217+
},
218+
"Directory should be closed after clicking collapse button",
219+
2000
220+
);
221+
222+
// Verify the directory is now closed
223+
expect(isFolderOpen("directory")).toBe(false);
224+
});
225+
226+
it("Should collapse multiple open directories when clicked", async function () {
227+
// Open multiple directories if they exist
228+
await openFolder("directory");
229+
230+
// Verify directories are open
231+
expect(isFolderOpen("directory")).toBe(true);
232+
233+
const initialOpenFolders = getOpenFolders();
234+
expect(initialOpenFolders.length).toBeGreaterThan(0);
235+
236+
// Show the collapse button and click it
237+
const $sidebar = $("#sidebar");
238+
const $collapseBtn = $("#collapse-folders");
239+
$sidebar.trigger("mouseenter");
240+
241+
await awaitsFor(
242+
function () {
243+
return $collapseBtn.hasClass("show");
244+
},
245+
"Button should show",
246+
1000
247+
);
248+
249+
$collapseBtn.trigger("click");
250+
251+
// Wait for all directories to close
252+
await awaitsFor(
253+
function () {
254+
return getOpenFolders().length === 0;
255+
},
256+
"All directories should be closed",
257+
2000
258+
);
259+
260+
// Verify no directories are open
261+
expect(getOpenFolders().length).toBe(0);
262+
});
263+
264+
it("Should handle click when no directories are open", function () {
265+
// Ensure no directories are open initially
266+
const openFolders = getOpenFolders();
267+
expect(openFolders.length).toBe(0);
268+
269+
// Show the collapse button and click it
270+
const $sidebar = $("#sidebar");
271+
const $collapseBtn = $("#collapse-folders");
272+
$sidebar.trigger("mouseenter");
273+
274+
// This should not throw an error
275+
expect(function () {
276+
$collapseBtn.trigger("click");
277+
}).not.toThrow();
278+
279+
// Should still have no open folders
280+
expect(getOpenFolders().length).toBe(0);
281+
});
282+
283+
it("Should work with nested directories", async function () {
284+
// Open a parent directory first
285+
await openFolder("directory");
286+
expect(isFolderOpen("directory")).toBe(true);
287+
288+
// If there are subdirectories, try to open one
289+
// Note: This test assumes the test project has nested directories
290+
const $subdirs = testWindow.$("#project-files-container li.jstree-open li.jstree-closed");
291+
if ($subdirs.length > 0) {
292+
// Open a subdirectory if one exists
293+
$subdirs.first().children("a").children("span").click();
294+
295+
await awaitsFor(
296+
function () {
297+
return $subdirs.first().hasClass("jstree-open");
298+
},
299+
"Open subdirectory",
300+
2000
301+
);
302+
}
303+
304+
const initialOpenCount = getOpenFolders().length;
305+
expect(initialOpenCount).toBeGreaterThan(0);
306+
307+
// Show the collapse button and click it
308+
const $sidebar = $("#sidebar");
309+
const $collapseBtn = $("#collapse-folders");
310+
$sidebar.trigger("mouseenter");
311+
312+
await awaitsFor(
313+
function () {
314+
return $collapseBtn.hasClass("show");
315+
},
316+
"Button should show",
317+
1000
318+
);
319+
320+
$collapseBtn.trigger("click");
321+
322+
// Wait for all directories to close (including nested ones)
323+
await awaitsFor(
324+
function () {
325+
return getOpenFolders().length === 0;
326+
},
327+
"All nested directories should be closed",
328+
2000
329+
);
330+
331+
expect(getOpenFolders().length).toBe(0);
332+
});
333+
});
334+
});

0 commit comments

Comments
 (0)