Skip to content

Commit 49f327c

Browse files
authored
Don't add the first tab by default to the URL params in the explorer (#617)
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
1 parent 41acefb commit 49f327c

File tree

2 files changed

+133
-7
lines changed

2 files changed

+133
-7
lines changed

src/web/scripts/tabs.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const tabButtons = document.querySelectorAll("[data-sourcemeta-ui-tab-target]");
22
const tabViews = document.querySelectorAll("[data-sourcemeta-ui-tab-id]");
33

4-
function selectTab(tab, name) {
4+
function selectTab(tab, name, updateURL) {
55
tabButtons.forEach(element => element.classList.remove("active"));
66
tab.classList.add("active");
77
tabViews.forEach((panel) => {
@@ -12,25 +12,30 @@ function selectTab(tab, name) {
1212
}
1313
});
1414

15-
const url = new URL(window.location);
16-
url.searchParams.set("tab", name);
17-
window.history.replaceState({}, "", url);
15+
if (updateURL) {
16+
const url = new URL(window.location);
17+
url.searchParams.set("tab", name);
18+
window.history.replaceState({}, "", url);
19+
}
1820
}
1921

2022
const initialTab = new URL(window.location).searchParams.get("tab");
2123
if (initialTab) {
2224
tabButtons.forEach((element) => {
2325
if (element.getAttribute("data-sourcemeta-ui-tab-target") === initialTab) {
24-
selectTab(element, initialTab);
26+
selectTab(element, initialTab, true);
2527
}
2628
});
2729
} else if (tabButtons[0]) {
28-
selectTab(tabButtons[0], tabButtons[0].getAttribute("data-sourcemeta-ui-tab-target"));
30+
selectTab(tabButtons[0],
31+
tabButtons[0].getAttribute("data-sourcemeta-ui-tab-target"),
32+
// Don't update the URL for the default one to avoid some unnecessary noise
33+
false);
2934
}
3035

3136
tabButtons.forEach((tab) => {
3237
tab.addEventListener("click", () => {
3338
const targetId = tab.getAttribute("data-sourcemeta-ui-tab-target");
34-
selectTab(tab, targetId);
39+
selectTab(tab, targetId, true);
3540
});
3641
});

test/ui/schema.spec.js

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import { test, expect } from '@playwright/test';
2+
3+
test.describe('Schema Tabs', () => {
4+
test('defaults to examples tab on load without adding query parameter',
5+
async ({ page }) => {
6+
await page.goto('/test/schemas/string');
7+
8+
// The examples tab button should be active
9+
const examplesTab = page.locator(
10+
'[data-sourcemeta-ui-tab-target="examples"]');
11+
await expect(examplesTab).toHaveClass(/active/);
12+
13+
// The examples panel should be visible
14+
const examplesPanel = page.locator(
15+
'[data-sourcemeta-ui-tab-id="examples"]');
16+
await expect(examplesPanel).not.toHaveClass(/d-none/);
17+
18+
// Other panels should be hidden
19+
const dependenciesPanel = page.locator(
20+
'[data-sourcemeta-ui-tab-id="dependencies"]');
21+
await expect(dependenciesPanel).toHaveClass(/d-none/);
22+
const healthPanel = page.locator(
23+
'[data-sourcemeta-ui-tab-id="health"]');
24+
await expect(healthPanel).toHaveClass(/d-none/);
25+
26+
// The URL should NOT have a tab query parameter
27+
expect(page.url()).not.toContain('tab=');
28+
});
29+
30+
test('clicking a tab updates the query parameter and panel visibility',
31+
async ({ page }) => {
32+
await page.goto('/test/schemas/string');
33+
34+
// Wait for the default tab to be active
35+
const examplesTab = page.locator(
36+
'[data-sourcemeta-ui-tab-target="examples"]');
37+
await expect(examplesTab).toHaveClass(/active/);
38+
39+
// Click on the dependencies tab
40+
const dependenciesTab = page.locator(
41+
'[data-sourcemeta-ui-tab-target="dependencies"]');
42+
await dependenciesTab.click();
43+
44+
// Query parameter should update
45+
await expect(page).toHaveURL(/tab=dependencies/);
46+
47+
// The dependencies tab should be active, others not
48+
await expect(dependenciesTab).toHaveClass(/active/);
49+
await expect(examplesTab).not.toHaveClass(/active/);
50+
51+
// The dependencies panel should be visible, others hidden
52+
const dependenciesPanel = page.locator(
53+
'[data-sourcemeta-ui-tab-id="dependencies"]');
54+
await expect(dependenciesPanel).not.toHaveClass(/d-none/);
55+
const examplesPanel = page.locator(
56+
'[data-sourcemeta-ui-tab-id="examples"]');
57+
await expect(examplesPanel).toHaveClass(/d-none/);
58+
59+
// Click on the health tab
60+
const healthTab = page.locator(
61+
'[data-sourcemeta-ui-tab-target="health"]');
62+
await healthTab.click();
63+
64+
await expect(page).toHaveURL(/tab=health/);
65+
await expect(healthTab).toHaveClass(/active/);
66+
await expect(dependenciesTab).not.toHaveClass(/active/);
67+
const healthPanel = page.locator(
68+
'[data-sourcemeta-ui-tab-id="health"]');
69+
await expect(healthPanel).not.toHaveClass(/d-none/);
70+
await expect(dependenciesPanel).toHaveClass(/d-none/);
71+
});
72+
73+
test('clicking back to the first tab also sets the query parameter',
74+
async ({ page }) => {
75+
await page.goto('/test/schemas/string');
76+
77+
const examplesTab = page.locator(
78+
'[data-sourcemeta-ui-tab-target="examples"]');
79+
await expect(examplesTab).toHaveClass(/active/);
80+
81+
// Click away from the default tab
82+
const dependenciesTab = page.locator(
83+
'[data-sourcemeta-ui-tab-target="dependencies"]');
84+
await dependenciesTab.click();
85+
await expect(page).toHaveURL(/tab=dependencies/);
86+
87+
// Click back to examples
88+
await examplesTab.click();
89+
90+
// Now the query parameter should be present
91+
await expect(page).toHaveURL(/tab=examples/);
92+
await expect(examplesTab).toHaveClass(/active/);
93+
await expect(dependenciesTab).not.toHaveClass(/active/);
94+
});
95+
96+
test('navigating with a tab query parameter selects that tab',
97+
async ({ page }) => {
98+
await page.goto('/test/schemas/string?tab=health');
99+
100+
// The health tab should be active
101+
const healthTab = page.locator(
102+
'[data-sourcemeta-ui-tab-target="health"]');
103+
await expect(healthTab).toHaveClass(/active/);
104+
105+
// The health panel should be visible
106+
const healthPanel = page.locator(
107+
'[data-sourcemeta-ui-tab-id="health"]');
108+
await expect(healthPanel).not.toHaveClass(/d-none/);
109+
110+
// The URL should keep the tab parameter
111+
await expect(page).toHaveURL(/tab=health/);
112+
113+
// Other tabs and panels should not be active/visible
114+
const examplesTab = page.locator(
115+
'[data-sourcemeta-ui-tab-target="examples"]');
116+
await expect(examplesTab).not.toHaveClass(/active/);
117+
const examplesPanel = page.locator(
118+
'[data-sourcemeta-ui-tab-id="examples"]');
119+
await expect(examplesPanel).toHaveClass(/d-none/);
120+
});
121+
});

0 commit comments

Comments
 (0)