Skip to content

Commit 4c57ed5

Browse files
authored
Tests: Refactor sidebar test (#451)
1 parent 35db953 commit 4c57ed5

File tree

5 files changed

+83
-81
lines changed

5 files changed

+83
-81
lines changed

assets/js/product-selector.js

Lines changed: 0 additions & 22 deletions
This file was deleted.

layouts/partials/scripts.html

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,6 @@
6060

6161
{{ end }}
6262

63-
<!-- Load Product Selector javascript -->
64-
{{ $jsProductSelector := resources.Get "js/product-selector.js" | minify | fingerprint "sha512" }}
65-
<script src="{{ $jsProductSelector.RelPermalink }}" type="text/javascript" integrity="{{ $jsProductSelector.Data.Integrity }}"></script>
66-
6763
<!-- Load Sidebar v2 javascript -->
6864
{{ $jsSidebarV2 := resources.Get "js/sidebar-v2.js" | minify | fingerprint "sha512" }}
6965
<script src="{{ $jsSidebarV2.RelPermalink }}" type="text/javascript" integrity="{{ $jsSidebarV2.Data.Integrity }}"></script>

layouts/partials/sidebar-list.html

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
aria-controls="{{ $sectionID }}"
2424
>
2525
<span class="sidebar__toggle-text">{{ $p.LinkTitle }}</span>
26-
<span class="sidebar__chevron {{ if $shouldExpand }}sidebar__chevron--open{{ end }}">
26+
<span class="sidebar__chevron {{ if $shouldExpand }}sidebar__chevron--open{{ end }}" data-testid="sidebar__chevron">
2727
{{ partial "lucide" (dict "context" . "icon" "chevron-right") }}
2828
</span>
2929
</button>
@@ -38,6 +38,7 @@
3838
<a
3939
href="{{ $p.Permalink }}"
4040
class="sidebar__link {{ if $onPage }}sidebar__link--current{{ end }}"
41+
data-testid="sidebar__link"
4142
{{ if $onPage }}aria-current="page"{{ end }}
4243
>
4344
Overview
@@ -62,12 +63,13 @@
6263
{{ if $pageHasTOC }}
6364
<button
6465
class="sidebar__toggle sidebar__link sidebar__link--current"
66+
data-testid="sidebar__section__toggle"
6567
aria-expanded="true"
6668
aria-controls="{{ $tocID }}"
6769
id="{{ $linkID }}"
6870
>
6971
<span>{{ $p.LinkTitle }} {{ partial "commercial-feature.html" $p }}</span>
70-
<span class="sidebar__chevron sidebar__chevron--open">
72+
<span class="sidebar__chevron sidebar__chevron--open" data-testid="sidebar__chevron">
7173
{{ partial "lucide" (dict "context" . "icon" "chevron-right") }}
7274
</span>
7375
</button>
@@ -86,6 +88,7 @@
8688
id="{{ $linkID }}"
8789
class="sidebar__link {{ if $onPage }}sidebar__link--current{{ end }}"
8890
{{ if $onPage }}aria-current="page"{{ end }}
91+
data-testid="sidebar__link"
8992
>
9093
<span>{{ $p.LinkTitle }} {{ partial "commercial-feature.html" $p }}</span>
9194
</a>

layouts/partials/sidebar-v2.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,15 @@
5151
{{ partial "lucide" (dict "context" . "icon" "chevron-right") }}
5252
</span>
5353
</summary>
54-
<div class="product-selector__content">
54+
<div class="product-selector__content" data-testid="product-selector__content">
5555
{{ with index .Site.Data "product-selector" }}
5656
{{ $groups := . }}
5757
{{ range $group := $groups }}
5858
<h3 class="product-selector__product-group">{{ $group.productGroup }}</h3>
5959
<ul>
6060
{{ $products := sort $group.products "productOrder" }}
6161
{{ range $product := $products }}
62-
<li class="product-selector__product">
62+
<li class="product-selector__product" data-testid="product-selector__product">
6363
<a
6464
href="{{ absURL $product.url }}"
6565
aria-label="{{ $product.title }} documentation"

tests/src/sidebar.spec.js

Lines changed: 76 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,94 @@
11
import { expect, test } from '@playwright/test';
22
import { handleConsentPopup, runSmokeTestOnPage, waitFor } from './utils';
33

4-
async function openPage(page, sidebarPage) {
5-
// Find all toggles
6-
let currentElement = sidebarPage;
7-
const toggles = [];
8-
9-
while (currentElement) {
10-
const parentElement = await currentElement.locator('..');
11-
const isSuperParent = await parentElement.evaluate(
12-
(el) => el.getAttribute('data-testid') === 'sidebar__content'
13-
);
14-
if (isSuperParent) break;
15-
16-
const parentElementClass = await parentElement.getAttribute('class');
17-
if (parentElementClass === 'sidebar__section') {
18-
const toggle = parentElement.getByTestId('sidebar__section__toggle');
19-
if ((await toggle.count()) > 0) {
20-
toggles.unshift(toggle.first());
21-
}
22-
}
23-
24-
currentElement = parentElement;
25-
}
26-
27-
// Click all toggles found top-down
28-
for (const toggle of toggles) {
29-
const isCollapsed =
30-
(await toggle.first().getAttribute('aria-expanded')) === 'false';
31-
if (isCollapsed) {
32-
await toggle.first().click();
33-
}
34-
}
35-
36-
// Click on the page
37-
await sidebarPage.click();
38-
const content = page.getByTestId('content');
39-
await content.waitFor();
40-
}
41-
424
test.describe('Smoke test for sidebar', () => {
435
// Slow test
446
test.setTimeout(100_000);
457

468
test.beforeEach(async ({ page }) => {
479
await page.goto('/test-product/');
4810
await page.waitForLoadState('load');
11+
await waitFor(async () => await handleConsentPopup(page));
4912
});
5013

5114
test('sidebar renders', async ({ page }) => {
52-
await expect(
53-
await page.getByTestId('sidebar__header').count()
54-
).toBeTruthy();
55-
await expect(
56-
await page.getByTestId('sidebar__content').count()
57-
).toBeTruthy();
15+
await expect(page.getByTestId('sidebar__header')).toBeVisible();
16+
await expect(page.getByTestId('product-selector')).toBeVisible();
17+
await expect(page.getByTestId('sidebar__content')).toBeVisible();
5818
});
5919

60-
test('each section page on sidebar renders', async ({ page }) => {
61-
/* Click on each link */
62-
const sidebarPages = await page.getByTestId('sidebar__page').all();
63-
for (const sidebarPage of sidebarPages) {
64-
await waitFor(async () => await handleConsentPopup(page));
65-
await openPage(page, sidebarPage);
66-
await runSmokeTestOnPage(page);
20+
test('product selector renders when clicked', async ({ page }) => {
21+
// Click on product selector
22+
const productSelector = page.getByTestId('product-selector');
23+
await productSelector.click();
24+
25+
// Ensure the product selector has items visible
26+
const productSelectorContent = productSelector.getByTestId(
27+
'product-selector__content'
28+
);
29+
const products = await productSelectorContent
30+
.getByTestId('product-selector__product')
31+
.all();
32+
33+
expect(products.length).toBeGreaterThan(0);
34+
for (const product of products) {
35+
await expect(product).toBeVisible();
6736
}
6837
});
38+
39+
test('clicking on a link', async ({ page }) => {
40+
// Greedy logic assumes there is at least one link without having to open a dropdown.
41+
42+
// Fetch only visible links (aka ones not nested in a dropdown)
43+
const sidebarContent = page.getByTestId('sidebar__content');
44+
const pages = await sidebarContent.getByTestId('sidebar__page').all();
45+
const visibleResults = await Promise.all(
46+
pages.map(async (page) => await page.isVisible())
47+
);
48+
const visiblePages = pages.filter((_, index) => visibleResults[index]);
49+
expect(visiblePages.length).toBeGreaterThan(0);
50+
51+
// Click on link
52+
const firstPage = visiblePages.at(0);
53+
await firstPage.click();
54+
await waitFor(async () => await handleConsentPopup(page));
55+
const content = page.getByTestId('content');
56+
await content.waitFor();
57+
58+
// Run smoke test to validate page is not 404
59+
await runSmokeTestOnPage(page);
60+
});
61+
62+
test('clicking on a dropdown', async ({ page }) => {
63+
// Greedy logic assumes there is at least one dropdown at the first level.
64+
65+
// Fetch only visible dropdowns (aka ones not nested in a dropdown)
66+
const sidebarContent = page.getByTestId('sidebar__content');
67+
const dropdowns = await sidebarContent
68+
.getByTestId('sidebar__section__toggle')
69+
.all();
70+
const visibleResults = await Promise.all(
71+
dropdowns.map(async (dropdown) => await dropdown.isVisible())
72+
);
73+
const visibleDropdowns = dropdowns.filter(
74+
(_, index) => visibleResults[index]
75+
);
76+
77+
// Since it is not guaranteed there will be any links under a dropdown, we should check the chevron changes.
78+
// Also this should not check if links work. That is the job of the 'clicking on a link' test.
79+
const firstDropdown = visibleDropdowns.at(0);
80+
const chevron = (
81+
await firstDropdown.getByTestId('sidebar__chevron').all()
82+
).at(0);
83+
const openClassName = 'sidebar__chevron--open';
84+
expect(await chevron.getAttribute('class')).not.toContain(openClassName);
85+
86+
// Open the dropdown
87+
await firstDropdown.click();
88+
expect(await chevron.getAttribute('class')).toContain(openClassName);
89+
90+
// Close the dropdown
91+
await firstDropdown.click();
92+
expect(await chevron.getAttribute('class')).not.toContain(openClassName);
93+
});
6994
});

0 commit comments

Comments
 (0)