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 IconComponent = getIconComponent();
|
||||||
const hasCustomIcon = !!project.customIconPath;
|
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 (
|
return (
|
||||||
<button
|
<button
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
onContextMenu={onContextMenu}
|
onContextMenu={onContextMenu}
|
||||||
|
data-testid={testId}
|
||||||
className={cn(
|
className={cn(
|
||||||
'group w-full aspect-square rounded-xl flex items-center justify-center relative overflow-hidden',
|
'group w-full aspect-square rounded-xl flex items-center justify-center relative overflow-hidden',
|
||||||
'transition-all duration-200 ease-out',
|
'transition-all duration-200 ease-out',
|
||||||
@@ -60,7 +78,6 @@ export function ProjectSwitcherItem({
|
|||||||
'hover:scale-105 active:scale-95'
|
'hover:scale-105 active:scale-95'
|
||||||
)}
|
)}
|
||||||
title={project.name}
|
title={project.name}
|
||||||
data-testid={`project-switcher-${project.id}`}
|
|
||||||
>
|
>
|
||||||
{hasCustomIcon ? (
|
{hasCustomIcon ? (
|
||||||
<img
|
<img
|
||||||
|
|||||||
@@ -131,7 +131,8 @@ test.describe('Feature Manual Review Flow', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify we're on the correct project (project switcher button shows project name)
|
// 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,
|
timeout: 10000,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,8 @@ test.describe('Project Creation', () => {
|
|||||||
|
|
||||||
// Wait for project to be set as current and visible on the page
|
// Wait for project to be set as current and visible on the page
|
||||||
// The project name appears in the project switcher button
|
// 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,
|
timeout: 15000,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -157,8 +157,9 @@ test.describe('Open Project', () => {
|
|||||||
|
|
||||||
// Wait for a project to be set as current and visible on the page
|
// Wait for a project to be set as current and visible on the page
|
||||||
// The project name appears in the project switcher button
|
// The project name appears in the project switcher button
|
||||||
|
// Use ends-with selector since data-testid format is: project-switcher-{id}-{sanitizedName}
|
||||||
if (targetProjectName) {
|
if (targetProjectName) {
|
||||||
await expect(page.getByTestId(`project-switcher-project-${targetProjectName}`)).toBeVisible({
|
await expect(page.locator(`[data-testid$="-${targetProjectName}"]`)).toBeVisible({
|
||||||
timeout: 15000,
|
timeout: 15000,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user