This is an automated email from the ASF dual-hosted git repository.

anmolnar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/zookeeper.git


The following commit(s) were added to refs/heads/master by this push:
     new 65016cb1b ZOOKEEPER-5067: Remove older docs picker from the docs page
65016cb1b is described below

commit 65016cb1b29f630fa37ff7a3f8cf4a6ab755d26b
Author: Yurii Palamarchuk <[email protected]>
AuthorDate: Wed Jul 15 21:55:15 2026 +0200

    ZOOKEEPER-5067: Remove older docs picker from the docs page
    
    Reviewers: anmolnar
    Author: yuriipalam
    Closes #2422 from yuriipalam/ZOOKEEPER-5067
---
 zookeeper-website/app/pages/_docs/docs/index.tsx   |  6 +-
 .../e2e-tests/older-docs-picker.spec.ts            | 84 ++++++++++------------
 zookeeper-website/scripts/build-site.ts            | 10 +++
 zookeeper-website/unit-tests/build-site.test.ts    | 63 ++++++++++++++++
 4 files changed, 110 insertions(+), 53 deletions(-)

diff --git a/zookeeper-website/app/pages/_docs/docs/index.tsx 
b/zookeeper-website/app/pages/_docs/docs/index.tsx
index 256418539..3ebb1bc84 100644
--- a/zookeeper-website/app/pages/_docs/docs/index.tsx
+++ b/zookeeper-website/app/pages/_docs/docs/index.tsx
@@ -173,11 +173,7 @@ export function DocsPage({ loaderData }: { loaderData: 
DocsLoaderData }) {
   const layoutOptions = baseOptions();
 
   return (
-    <DocsLayout
-      {...layoutOptions}
-      tree={tree as PageTree.Root}
-      sidebar={{ banner: <OlderDocsPicker /> }}
-    >
+    <DocsLayout {...layoutOptions} tree={tree as PageTree.Root}>
       <Content tree={tree as PageTree.Root} />
     </DocsLayout>
   );
diff --git a/zookeeper-website/e2e-tests/older-docs-picker.spec.ts 
b/zookeeper-website/e2e-tests/older-docs-picker.spec.ts
index 2321fadb2..256ee72e8 100644
--- a/zookeeper-website/e2e-tests/older-docs-picker.spec.ts
+++ b/zookeeper-website/e2e-tests/older-docs-picker.spec.ts
@@ -16,8 +16,7 @@
 // limitations under the License.
 //
 
-import { test, expect } from "@playwright/test";
-import { DOCS_ROOT } from "./constants";
+import { test, expect, type Page } from "@playwright/test";
 import {
   getReleasedDocUrl,
   getReleasedDocVersions
@@ -25,33 +24,41 @@ import {
 
 const EXPECTED_VERSIONS = getReleasedDocVersions();
 
-test.describe("Older Docs Picker – sidebar", () => {
-  test.beforeEach(async ({ page }) => {
-    await page.goto(DOCS_ROOT);
-    await page.waitForLoadState("networkidle");
-  });
+async function openOlderDocsMenu(page: Page) {
+  await page
+    .getByRole("button", { name: /^Documentation$/i })
+    .first()
+    .click();
 
-  test("trigger button is visible in the docs sidebar", async ({ page }) => {
-    const trigger = page.getByRole("button", { name: /older docs/i });
-    await expect(trigger).toBeVisible();
-  });
+  const olderDocsTrigger = page.getByRole("menuitem", { name: /^Older docs$/ 
});
+  await expect(olderDocsTrigger).toBeVisible();
+  await olderDocsTrigger.focus();
+  await page.keyboard.press("ArrowRight");
 
-  test("popover is closed by default", async ({ page }) => {
-    await expect(page.getByRole("combobox")).not.toBeVisible();
-  });
+  const list = page.getByRole("listbox");
+  await expect(list).toBeVisible();
+  return list;
+}
 
-  test("clicking the trigger opens a popover with a search input", async ({
-    page
-  }) => {
-    await page.getByRole("button", { name: /older docs/i }).click();
-    await expect(page.getByRole("combobox")).toBeVisible();
+test.describe("Older Docs Picker - landing page navigation", () => {
+  test.beforeEach(async ({ page }) => {
+    await page.goto("/", { waitUntil: "domcontentloaded" });
+    await page.waitForLoadState("load");
   });
 
-  test("popover lists released doc versions", async ({ page }) => {
-    await page.getByRole("button", { name: /older docs/i }).click();
+  test("trigger is visible in the Documentation dropdown", async ({ page }) => 
{
+    await page
+      .getByRole("button", { name: /^Documentation$/i })
+      .first()
+      .click();
+
+    await expect(
+      page.getByRole("menuitem", { name: /^Older docs$/ })
+    ).toBeVisible();
+  });
 
-    const list = page.getByRole("listbox");
-    await expect(list).toBeVisible();
+  test("submenu lists released doc versions", async ({ page }) => {
+    const list = await openOlderDocsMenu(page);
 
     const options = list.getByRole("option");
     await expect(options.first()).toBeVisible();
@@ -59,9 +66,8 @@ test.describe("Older Docs Picker – sidebar", () => {
   });
 
   test("versions are displayed in descending order", async ({ page }) => {
-    await page.getByRole("button", { name: /older docs/i }).click();
-
-    const options = page.getByRole("option");
+    const list = await openOlderDocsMenu(page);
+    const options = list.getByRole("option");
     await expect(options.first()).toBeVisible();
 
     const texts = await options.allTextContents();
@@ -71,9 +77,9 @@ test.describe("Older Docs Picker – sidebar", () => {
   test("each version item links to the correct archive path", async ({
     page
   }) => {
-    await page.getByRole("button", { name: /older docs/i }).click();
+    const list = await openOlderDocsMenu(page);
+    const options = list.getByRole("option");
 
-    const options = page.getByRole("option");
     await expect(options).toHaveCount(EXPECTED_VERSIONS.length);
     for (let i = 0; i < EXPECTED_VERSIONS.length; i++) {
       const href = await options.nth(i).getAttribute("href");
@@ -84,7 +90,7 @@ test.describe("Older Docs Picker – sidebar", () => {
   test("typing in the search box filters the version list", async ({
     page
   }) => {
-    await page.getByRole("button", { name: /older docs/i }).click();
+    await openOlderDocsMenu(page);
 
     const input = page.getByRole("combobox");
     await expect(input).toBeVisible();
@@ -107,7 +113,6 @@ test.describe("Older Docs Picker – sidebar", () => {
     expect(totalBefore).toBe(EXPECTED_VERSIONS.length);
     expect(totalAfter).toBe(expectedMatches);
 
-    // Every remaining option must contain the search term
     for (let i = 0; i < totalAfter; i++) {
       const text = await filtered.nth(i).textContent();
       expect(text).toContain(prefix);
@@ -117,7 +122,7 @@ test.describe("Older Docs Picker – sidebar", () => {
   test("searching for a non-existent version shows 'No versions found'", async 
({
     page
   }) => {
-    await page.getByRole("button", { name: /older docs/i }).click();
+    await openOlderDocsMenu(page);
 
     const input = page.getByRole("combobox");
     await input.fill("99.99.99");
@@ -125,21 +130,4 @@ test.describe("Older Docs Picker – sidebar", () => {
 
     await expect(page.getByText(/no versions found/i)).toBeVisible();
   });
-
-  test("search is cleared when the popover is reopened", async ({ page }) => {
-    const trigger = page.getByRole("button", { name: /older docs/i });
-
-    await trigger.click();
-    const input = page.getByRole("combobox");
-    await input.fill("anything");
-
-    // Close the popover by pressing Escape
-    await page.keyboard.press("Escape");
-    await expect(page.getByRole("combobox")).not.toBeVisible();
-
-    // Reopen
-    await trigger.click();
-    const newInput = page.getByRole("combobox");
-    await expect(newInput).toHaveValue("");
-  });
 });
diff --git a/zookeeper-website/scripts/build-site.ts 
b/zookeeper-website/scripts/build-site.ts
index f046c3cb3..69ebbf6dc 100644
--- a/zookeeper-website/scripts/build-site.ts
+++ b/zookeeper-website/scripts/build-site.ts
@@ -44,6 +44,15 @@ function runCommand(command: string, args: string[], env: 
NodeJS.ProcessEnv) {
   }
 }
 
+export async function pruneLandingRootDocsImages(
+  buildClientDir = BUILD_CLIENT_DIR
+) {
+  await rm(join(buildClientDir, "docs-images"), {
+    recursive: true,
+    force: true
+  });
+}
+
 // Builds the live site as two independent Vite builds that get merged for 
local
 // serving (vite preview / e2e) and for publishing:
 //   1. Current docs (base /doc/r<CURRENT>/) -> build/doc/r<CURRENT>/. Built 
first
@@ -68,6 +77,7 @@ export async function main() {
     ...process.env,
     [DOCS_BUILD_TARGET_ENV]: "landing"
   });
+  await pruneLandingRootDocsImages();
 
   const mergedDocsDir = join(BUILD_CLIENT_DIR, "doc", `r${CURRENT_VERSION}`);
   await rm(mergedDocsDir, { recursive: true, force: true });
diff --git a/zookeeper-website/unit-tests/build-site.test.ts 
b/zookeeper-website/unit-tests/build-site.test.ts
new file mode 100644
index 000000000..f2e86df92
--- /dev/null
+++ b/zookeeper-website/unit-tests/build-site.test.ts
@@ -0,0 +1,63 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+import { afterEach, beforeEach, describe, expect, it } from "vitest";
+import { access, mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
+import { join } from "node:path";
+import { tmpdir } from "node:os";
+import { pruneLandingRootDocsImages } from "../scripts/build-site";
+
+let tempDir: string;
+
+async function pathExists(path: string): Promise<boolean> {
+  try {
+    await access(path);
+    return true;
+  } catch {
+    return false;
+  }
+}
+
+beforeEach(async () => {
+  tempDir = await mkdtemp(join(tmpdir(), "zk-build-site-test-"));
+});
+
+afterEach(async () => {
+  await rm(tempDir, { recursive: true, force: true });
+});
+
+describe("pruneLandingRootDocsImages", () => {
+  it("removes docs images from the landing root without touching merged docs", 
async () => {
+    await mkdir(join(tempDir, "docs-images"), { recursive: true });
+    await writeFile(join(tempDir, "docs-images", "zkservice.jpg"), "");
+    await mkdir(join(tempDir, "doc", "r3.10.0", "docs-images"), {
+      recursive: true
+    });
+    await writeFile(
+      join(tempDir, "doc", "r3.10.0", "docs-images", "zkservice.jpg"),
+      ""
+    );
+
+    await pruneLandingRootDocsImages(tempDir);
+
+    await expect(pathExists(join(tempDir, 
"docs-images"))).resolves.toBe(false);
+    await expect(
+      pathExists(join(tempDir, "doc", "r3.10.0", "docs-images"))
+    ).resolves.toBe(true);
+  });
+});

Reply via email to