mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-30 06:12:03 +00:00
fix: improve project-switcher data-testid for uniqueness and special chars
The data-testid generation was using only the sanitized project name which
could produce collisions and didn't handle special characters properly.
Changes:
- Combine stable project.id with sanitized name: project-switcher-{id}-{name}
- Expand sanitization to remove non-alphanumeric chars (except hyphens)
- Collapse multiple hyphens and trim leading/trailing hyphens
- Update E2E tests to use ends-with selector for matching
This ensures test IDs are deterministic, unique, and safe for CSS selectors.
This commit is contained in:
@@ -37,10 +37,28 @@ export function ProjectSwitcherItem({
|
||||
const IconComponent = getIconComponent();
|
||||
const hasCustomIcon = !!project.customIconPath;
|
||||
|
||||
// Create a sanitized project name for test ID:
|
||||
// - Convert to lowercase
|
||||
// - Replace spaces with hyphens
|
||||
// - Remove all non-alphanumeric characters except hyphens
|
||||
// - Collapse multiple hyphens into single hyphen
|
||||
// - Trim leading/trailing hyphens
|
||||
const sanitizedName = project.name
|
||||
.toLowerCase()
|
||||
.replace(/\s+/g, '-')
|
||||
.replace(/[^a-z0-9-]/g, '')
|
||||
.replace(/-+/g, '-')
|
||||
.replace(/^-|-$/g, '');
|
||||
|
||||
// Combine project.id with sanitized name for uniqueness and readability
|
||||
// Format: project-switcher-{id}-{sanitizedName}
|
||||
const testId = `project-switcher-${project.id}-${sanitizedName}`;
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={onClick}
|
||||
onContextMenu={onContextMenu}
|
||||
data-testid={testId}
|
||||
className={cn(
|
||||
'group w-full aspect-square rounded-xl flex items-center justify-center relative overflow-hidden',
|
||||
'transition-all duration-200 ease-out',
|
||||
@@ -60,7 +78,6 @@ export function ProjectSwitcherItem({
|
||||
'hover:scale-105 active:scale-95'
|
||||
)}
|
||||
title={project.name}
|
||||
data-testid={`project-switcher-${project.id}`}
|
||||
>
|
||||
{hasCustomIcon ? (
|
||||
<img
|
||||
|
||||
@@ -131,7 +131,8 @@ test.describe('Feature Manual Review Flow', () => {
|
||||
}
|
||||
|
||||
// Verify we're on the correct project (project switcher button shows project name)
|
||||
await expect(page.getByTestId(`project-switcher-project-${projectName}`)).toBeVisible({
|
||||
// Use ends-with selector since data-testid format is: project-switcher-{id}-{sanitizedName}
|
||||
await expect(page.locator(`[data-testid$="-${projectName}"]`)).toBeVisible({
|
||||
timeout: 10000,
|
||||
});
|
||||
|
||||
|
||||
@@ -78,7 +78,8 @@ test.describe('Project Creation', () => {
|
||||
|
||||
// Wait for project to be set as current and visible on the page
|
||||
// The project name appears in the project switcher button
|
||||
await expect(page.getByTestId(`project-switcher-project-${projectName}`)).toBeVisible({
|
||||
// Use ends-with selector since data-testid format is: project-switcher-{id}-{sanitizedName}
|
||||
await expect(page.locator(`[data-testid$="-${projectName}"]`)).toBeVisible({
|
||||
timeout: 15000,
|
||||
});
|
||||
|
||||
|
||||
@@ -157,8 +157,9 @@ test.describe('Open Project', () => {
|
||||
|
||||
// Wait for a project to be set as current and visible on the page
|
||||
// The project name appears in the project switcher button
|
||||
// Use ends-with selector since data-testid format is: project-switcher-{id}-{sanitizedName}
|
||||
if (targetProjectName) {
|
||||
await expect(page.getByTestId(`project-switcher-project-${targetProjectName}`)).toBeVisible({
|
||||
await expect(page.locator(`[data-testid$="-${targetProjectName}"]`)).toBeVisible({
|
||||
timeout: 15000,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user