initial commit after project creation
This commit is contained in:
218
tests/e2e/utils/search-helpers.ts
Normal file
218
tests/e2e/utils/search-helpers.ts
Normal file
@@ -0,0 +1,218 @@
|
||||
import type { Page } from "@playwright/test";
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
export class SearchHelper {
|
||||
constructor(private page: Page) {}
|
||||
|
||||
/**
|
||||
* Navigate to the docs page and wait for it to load
|
||||
*/
|
||||
async navigateToDocs() {
|
||||
await this.page.goto(`${process.env.NEXT_PUBLIC_BASE_PATH ?? ""}/docs`);
|
||||
await this.page.waitForLoadState("networkidle");
|
||||
// Wait for the search input to be available (client component hydration)
|
||||
const searchInput = this.getSearchInput();
|
||||
await searchInput.waitFor({ state: "attached", timeout: 10000 });
|
||||
}
|
||||
|
||||
/**
|
||||
* Find and return the search input field
|
||||
*/
|
||||
getSearchInput() {
|
||||
return this.page.locator('input[placeholder="Search..."]');
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a search with the given term
|
||||
*/
|
||||
async performSearch(searchTerm: string) {
|
||||
const searchInput = this.getSearchInput();
|
||||
// Wait for the search input to be visible and attached to the DOM
|
||||
// This is important because the Search component is a client component that needs to hydrate
|
||||
await searchInput.waitFor({ state: "visible", timeout: 10000 });
|
||||
await searchInput.fill(searchTerm);
|
||||
await searchInput.press("Enter");
|
||||
|
||||
// Wait for search to complete
|
||||
await this.page.waitForTimeout(1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for search results to appear
|
||||
*/
|
||||
async waitForSearchResults() {
|
||||
await this.page.waitForTimeout(1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get search results container
|
||||
*/
|
||||
getSearchResultsContainer() {
|
||||
// Use the data-testid attribute for reliable selection
|
||||
return this.page.locator('[data-testid="search-results-container"]');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get "No Llamas Found" message
|
||||
*/
|
||||
getNoResultsMessage() {
|
||||
// Use the data-testid attribute for reliable selection
|
||||
return this.page.locator('[data-testid="no-results-message"]');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get loading message
|
||||
*/
|
||||
getLoadingMessage() {
|
||||
// Look for the loading message within the search results container
|
||||
return this.page.locator(
|
||||
'[data-testid="search-results-container"] h4:has-text("Mustering all the Llamas")'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all search result links
|
||||
*/
|
||||
getSearchResultLinks() {
|
||||
return this.page.locator('a[href*="/docs"]');
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify search results are visible
|
||||
*/
|
||||
async expectSearchResultsVisible() {
|
||||
const resultsContainer = this.getSearchResultsContainer();
|
||||
const noResultsMessage = this.getNoResultsMessage();
|
||||
|
||||
await expect(resultsContainer.or(noResultsMessage)).toBeVisible();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify search results are not visible
|
||||
*/
|
||||
async expectSearchResultsNotVisible() {
|
||||
const resultsContainer = this.getSearchResultsContainer();
|
||||
await expect(resultsContainer).not.toBeVisible();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify search input is visible
|
||||
*/
|
||||
async expectSearchInputVisible() {
|
||||
const searchInput = this.getSearchInput();
|
||||
await expect(searchInput).toBeVisible();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify search input has the expected value
|
||||
*/
|
||||
async expectSearchInputValue(expectedValue: string) {
|
||||
const searchInput = this.getSearchInput();
|
||||
await expect(searchInput).toHaveValue(expectedValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear search by clicking the copy button
|
||||
*/
|
||||
async clearSearch() {
|
||||
await this.page.click('button:has-text("Copy")');
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify Pagefind files are accessible
|
||||
*/
|
||||
async verifyPagefindFilesAccessible() {
|
||||
const isDev = this.page.url().includes("localhost");
|
||||
|
||||
// Check Pagefind JavaScript file
|
||||
const pagefindJsResponse = await this.page.request.get(
|
||||
isDev
|
||||
? "http://localhost:3000/pagefind/pagefind.js"
|
||||
: `${process.env.BASE_URL}${
|
||||
process.env.NEXT_PUBLIC_BASE_PATH ?? ""
|
||||
}/_next/static/pagefind/pagefind.js`
|
||||
);
|
||||
expect(pagefindJsResponse.status()).toBe(200);
|
||||
|
||||
// Check Pagefind index file
|
||||
const pagefindIndexResponse = await this.page.request.get(
|
||||
isDev
|
||||
? "http://localhost:3000/pagefind/pagefind-ui.js"
|
||||
: `${process.env.BASE_URL}${
|
||||
process.env.NEXT_PUBLIC_BASE_PATH ?? ""
|
||||
}/_next/static/pagefind/pagefind-ui.js`
|
||||
);
|
||||
|
||||
expect(pagefindIndexResponse.status()).toBe(200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Measure search performance
|
||||
*/
|
||||
async measureSearchPerformance(searchTerm: string): Promise<number> {
|
||||
const startTime = Date.now();
|
||||
|
||||
await this.performSearch(searchTerm);
|
||||
|
||||
const endTime = Date.now();
|
||||
return endTime - startTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test search with multiple terms
|
||||
*/
|
||||
async testMultipleSearches(searchTerms: string[]) {
|
||||
for (const term of searchTerms) {
|
||||
await this.performSearch(term);
|
||||
await this.expectSearchResultsVisible();
|
||||
await this.clearSearch();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test search on mobile viewport
|
||||
*/
|
||||
async testMobileSearch() {
|
||||
await this.page.setViewportSize({ width: 375, height: 667 });
|
||||
await this.expectSearchInputVisible();
|
||||
|
||||
await this.performSearch("TinaDocs");
|
||||
await this.expectSearchResultsVisible();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test data for search tests
|
||||
*/
|
||||
export const SEARCH_TEST_DATA = {
|
||||
knownTerms: [
|
||||
"TinaDocs",
|
||||
"documentation",
|
||||
"search",
|
||||
"API",
|
||||
"TinaCMS",
|
||||
"deployment",
|
||||
"theming",
|
||||
"components",
|
||||
],
|
||||
nonExistentTerms: [
|
||||
"xyz123nonexistent",
|
||||
"completelyrandomterm",
|
||||
"shouldnotexist",
|
||||
],
|
||||
specialCharacters: [
|
||||
"@#$%",
|
||||
"test@example.com",
|
||||
"user-name",
|
||||
"file/path",
|
||||
"test&query",
|
||||
"test+query",
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a search helper instance
|
||||
*/
|
||||
export function createSearchHelper(page: Page): SearchHelper {
|
||||
return new SearchHelper(page);
|
||||
}
|
||||
Reference in New Issue
Block a user