blob: 9be4120d2540495c8dab770e4a21cd4c018d205a [file]
//
// 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 { test, expect } from "@playwright/test";
test.describe("Documentation Page - Basic Loading", () => {
test("docs page loads successfully with title", async ({ page }) => {
await page.goto("/docs");
await page.waitForLoadState("networkidle");
// Check URL and title
await expect(page).toHaveURL(/.*docs/);
await expect(page).toHaveTitle(/Preface|HBase/i);
});
test("docs page has visible content", async ({ page }) => {
await page.goto("/docs");
await page.waitForLoadState("networkidle");
// Check for meaningful text content
const bodyText = await page.locator("body").textContent();
expect(bodyText).toBeTruthy();
expect(bodyText!.length).toBeGreaterThan(500);
});
test("docs page has header with Apache HBase link", async ({ page }) => {
await page.goto("/docs");
await page.waitForLoadState("networkidle");
// Check for header link
const headerLink = page.getByRole("link", { name: /Apache HBase/i }).first();
await expect(headerLink).toBeVisible();
});
});
test.describe("Documentation Page - Sidebar Navigation", () => {
test("sidebar is visible and has navigation items", async ({ page }) => {
await page.goto("/docs");
await page.waitForLoadState("networkidle");
// Look for sidebar (aside element)
const sidebar = page.locator("aside").first();
await expect(sidebar).toBeVisible();
// Check sidebar has links
const sidebarLinks = sidebar.locator("a");
const linkCount = await sidebarLinks.count();
expect(linkCount).toBeGreaterThan(5);
});
test("sidebar has multiple navigation links", async ({ page }) => {
await page.goto("/docs");
await page.waitForLoadState("networkidle");
// Verify sidebar has multiple links to different pages
const sidebar = page.locator("aside");
const allLinks = sidebar.locator('a[href^="/docs/"]');
const linkCount = await allLinks.count();
// Should have many navigation links in sidebar
expect(linkCount).toBeGreaterThan(10);
// Verify at least one link is visible
const firstLink = allLinks.first();
await expect(firstLink).toBeVisible();
});
test("sidebar collapse button works", async ({ page }) => {
await page.goto("/docs");
await page.waitForLoadState("networkidle");
// Look for collapse button (use .first() for desktop version)
const collapseButton = page.getByRole("button", { name: /Collapse Sidebar/i }).first();
if ((await collapseButton.count()) > 0) {
await expect(collapseButton).toBeVisible();
// Click to collapse
await collapseButton.click();
await page.waitForTimeout(300);
// The button should still exist (might change text or icon)
expect(true).toBe(true);
}
});
});
test.describe("Documentation Page - Search Functionality", () => {
test("search button is visible on docs page", async ({ page }) => {
await page.goto("/docs");
await page.waitForLoadState("networkidle");
// Look for search button with more flexible matching
const searchButton = page.getByRole("button", { name: /Search/i }).first();
await expect(searchButton).toBeVisible();
});
test("can open search dialog by clicking button", async ({ page }) => {
await page.goto("/docs");
await page.waitForLoadState("networkidle");
// Click search button - look for button containing "Search"
const searchButton = page.getByRole("button", { name: /Search/i }).first();
await searchButton.click();
// Wait for dialog
await page.waitForTimeout(500);
// Verify dialog opened
const searchDialog = page.getByRole("dialog", { name: /Search/i });
await expect(searchDialog).toBeVisible();
});
test("can type in search input", async ({ page }) => {
await page.goto("/docs");
await page.waitForLoadState("networkidle");
// Open search
const searchButton = page.getByRole("button", { name: /Search/i }).first();
await searchButton.click();
await page.waitForTimeout(500);
// Find and type in search input
const searchInput = page.getByRole("textbox", { name: /Search/i });
await expect(searchInput).toBeVisible();
await searchInput.fill("configuration");
await expect(searchInput).toHaveValue("configuration");
});
test("can close search with ESC key", async ({ page }) => {
await page.goto("/docs");
await page.waitForLoadState("networkidle");
// Open search
const searchButton = page.getByRole("button", { name: /Search/i }).first();
await searchButton.click();
await page.waitForTimeout(500);
// Verify dialog is open
const searchDialog = page.getByRole("dialog", { name: /Search/i });
await expect(searchDialog).toBeVisible();
// Press ESC
await page.keyboard.press("Escape");
await page.waitForTimeout(300);
// Dialog should be closed
await expect(searchDialog).not.toBeVisible();
});
test("keyboard shortcut Cmd+K opens search", async ({ page }) => {
await page.goto("/docs");
await page.waitForLoadState("networkidle");
// Press Cmd+K (or Ctrl+K)
await page.keyboard.press(process.platform === "darwin" ? "Meta+k" : "Control+k");
await page.waitForTimeout(500);
// Verify dialog opened
const searchDialog = page.getByRole("dialog", { name: /Search/i });
await expect(searchDialog).toBeVisible();
});
});
test.describe("Documentation Page - Content & Navigation", () => {
test("docs page has headings", async ({ page }) => {
await page.goto("/docs");
await page.waitForLoadState("networkidle");
// Check for headings
const headings = page.locator("h1, h2, h3");
const headingCount = await headings.count();
expect(headingCount).toBeGreaterThan(2);
});
test("can navigate to single-page documentation", async ({ page }) => {
await page.goto("/docs/single-page");
await page.waitForLoadState("networkidle");
// Verify URL
await expect(page).toHaveURL(/.*single-page/);
// Check for content
const bodyText = await page.locator("body").textContent();
expect(bodyText!.length).toBeGreaterThan(5000); // Single page has lots of content
});
test("can navigate to configuration docs", async ({ page }) => {
await page.goto("/docs/configuration");
await page.waitForLoadState("networkidle");
await expect(page).toHaveURL(/.*configuration/);
// Check page has content
const bodyText = await page.locator("body").textContent();
expect(bodyText).toBeTruthy();
});
test("Edit on GitHub link is present", async ({ page }) => {
await page.goto("/docs");
await page.waitForLoadState("networkidle");
// Look for GitHub link
const githubLink = page.getByRole("link", { name: /Edit on GitHub/i });
// Wait a bit for it to appear
await page.waitForTimeout(1000);
if ((await githubLink.count()) > 0) {
await expect(githubLink).toBeVisible();
}
});
});
test.describe("Documentation Page - Mobile Responsiveness", () => {
test("mobile menu button is visible on small screens", async ({ page }) => {
await page.setViewportSize({ width: 375, height: 667 });
await page.goto("/docs");
await page.waitForLoadState("networkidle");
// Look for mobile menu button
const menuButton = page.getByRole("button", { name: /Open Sidebar/i });
await expect(menuButton).toBeVisible();
});
test("can open mobile sidebar", async ({ page }) => {
await page.setViewportSize({ width: 375, height: 667 });
await page.goto("/docs");
await page.waitForLoadState("networkidle");
// Click mobile menu button
const menuButton = page.getByRole("button", { name: /Open Sidebar/i });
await menuButton.click();
await page.waitForTimeout(500);
// Sidebar drawer should appear (check for navigation elements)
const sidebarLinks = page.locator('a[href^="/docs"]');
const linkCount = await sidebarLinks.count();
expect(linkCount).toBeGreaterThan(5);
});
test("search button visible on mobile", async ({ page }) => {
await page.setViewportSize({ width: 375, height: 667 });
await page.goto("/docs");
await page.waitForLoadState("networkidle");
// Look for search button
const searchButton = page.getByRole("button", { name: /Open Search|Search/i }).first();
await expect(searchButton).toBeVisible();
});
});