# Regression Test Script Review Hints

## Context
These hints are for reviewing Playwright regression test scripts that perform systematic testing of the Halo QA application's dashboard functionality.

## Regression Test Principles

### 1. Test Naming Convention
✅ **Correct Format:**
```typescript
test('REG-XXX: Clear description of test purpose', async ({ page }) => {
  // Test implementation
});
```
- Use REG- prefix with sequential numbering
- Clear, descriptive test names
- Reference related tests if applicable (e.g., "Delete dashboard created in test 01")

### 2. Extended Wait Times for Stability
✅ **Build Loading Pattern:**
```typescript
// Initial build load after login
await page.waitForTimeout(40000); // Wait for build to load

// Additional wait before main actions
await page.waitForTimeout(20000);

// After major operations (delete/duplicate)
console.log('Waiting 10 seconds for build to reload...');
await page.waitForTimeout(10000);
```

### 3. Comprehensive Test Steps
✅ **Structured Test Execution:**
```typescript
// Step 1: Navigate and Login
await test.step('Navigate and Login to Halo QA', async () => {
  await loginPage.goto();
  await loginPage.login(testEmail, testPassword);
  await dashboardPage.waitForDashboardLoad();
});

// Step 2: Setup/Preparation
await test.step('Prepare test environment', async () => {
  // Setup code
});

// Step 3: Main Test Action
await test.step('Execute primary test action', async () => {
  // Core test logic
});

// Step 4: Verification
await test.step('Verify results', async () => {
  // Assertions
});

// Final Summary
await test.step('Final verification', async () => {
  console.log('\n=== Regression Test Summary ===');
  console.log('Test ID: REG-XXX');
  console.log('Test Name: Test description');
  console.log('Status: PASSED');
  console.log('✅ Summary of what was accomplished');
});
```

### 4. Dashboard Operations Testing

#### Delete Operations
✅ **Loop Pattern for Multiple Deletions:**
```typescript
let deletedCount = 0;
let foundDashboard = true;

while (foundDashboard) {
  const dashboardText = page.getByText('Pattern to Find', { exact: false });
  const dashboardCount = await dashboardText.count();

  if (dashboardCount === 0) {
    foundDashboard = false;
    break;
  }

  // Delete logic
  await dashboardText.first().click();
  // ... deletion steps
  deletedCount++;

  // Navigate back to list
  await dashboardPage.navigateToDashboards();
  await page.waitForTimeout(3000);
}

console.log(`✅ Successfully deleted ${deletedCount} dashboard(s)`);
```

#### Duplicate Operations
✅ **Duplicate Verification Pattern:**
```typescript
// Original dashboard name
const originalDashboardName = 'Test Dashboard';

// After duplication
const duplicateName = `${originalDashboardName} (1)`;

// Verify duplicate exists
const allPageText = await page.locator('body').innerText();
const duplicateFound = allPageText.includes(duplicateName);
expect(duplicateFound).toBeTruthy();
```

#### Favorites Management
✅ **Favorites Workflow:**
```typescript
// Add to favorites
const starButton = page.locator('[data-testid="favourite-button"]');
await starButton.click();

// Confirm addition
const addButton = page.getByRole('button', { name: 'Add', exact: true });
await addButton.click();

// Navigate to favorites
const favoritesLink = page.getByText('Favorites', { exact: true }).first();
await favoritesLink.click();

// Verify presence in favorites
const dashboardInFavorites = page.getByText(dashboardName, { exact: false });
expect(await dashboardInFavorites.isVisible()).toBeTruthy();
```

### 5. Robust Element Selection

#### Fallback Selectors
✅ **Multiple Selector Strategy:**
```typescript
// Primary selector attempt
const deleteOption = page.getByRole('menuitem', { name: 'Delete', exact: true });
const deleteVisible = await deleteOption.isVisible({ timeout: 5000 }).catch(() => false);

if (!deleteVisible) {
  // Fallback to alternative selector
  const alternativeDelete = page.locator('button, [role="menuitem"]')
    .filter({ hasText: /^Delete$/i })
    .first();

  if (await alternativeDelete.isVisible()) {
    await alternativeDelete.click();
  } else {
    // Last resort
    await page.getByText('Delete').filter({ hasNotText: 'Duplicate' }).first().click();
  }
} else {
  await deleteOption.click();
}
```

#### Dashboard List Access
✅ **Conditional Navigation:**
```typescript
// Check if My Dashboards needs to be clicked first
const myDashboardsButton = page.locator('[data-testid="Custom Dashboards"]');
const myDashboardsVisible = await myDashboardsButton.isVisible({ timeout: 3000 }).catch(() => false);

if (myDashboardsVisible) {
  await myDashboardsButton.click();
  console.log('Clicked My Dashboards button');
  await page.waitForTimeout(5000);
}
```

### 6. Debugging and Logging

✅ **Comprehensive Debug Output:**
```typescript
// Debug element search
console.log('Searching for dashboards...');
const selectors = [
  'a[href*="/dashboards/"]',
  '[role="article"]',
  '.MuiCard-root',
  '[class*="dashboard"]'
];

for (const selector of selectors) {
  const count = await page.locator(selector).count();
  if (count > 0) {
    console.log(`Found ${count} elements with selector "${selector}"`);
  }
}

// Log operation progress
console.log(`Deleted dashboard #${deletedCount}`);
console.log(`Total dashboards remaining: ${totalDashboards}`);
```

### 7. Error Handling

✅ **Graceful Failure Handling:**
```typescript
// Use catch for non-critical operations
const elementVisible = await element.isVisible({ timeout: 5000 }).catch(() => false);

if (elementVisible) {
  // Proceed with action
} else {
  console.log('Element not found, using alternative approach');
  // Alternative logic
}
```

### 8. Test Data Management

✅ **Unique Name Generation:**
```typescript
// Generate unique names for test isolation
const uniqueName = await dashboardPage.generateUniqueDashboardName('Test Prefix');

// Track generated names for cleanup
let testDashboardNames: string[] = [];
testDashboardNames.push(uniqueName);

// Cleanup at end of test
for (const name of testDashboardNames) {
  // Delete test dashboards
}
```

## Regression Test Requirements

### Must Have
1. **Test ID Format**: REG-XXX prefix
2. **Extended timeouts**: 40s initial, 10s after major operations
3. **Test steps**: Organized with test.step()
4. **Summary output**: Final verification with test summary
5. **Debug logging**: Comprehensive console output
6. **Error handling**: Graceful fallbacks for UI variations
7. **Page object usage**: Consistent use of page objects
8. **Login flow**: Always through Halo QA login

### Should Have
1. **Related test references**: Mention dependencies on other tests
2. **Cleanup operations**: Remove test data after verification
3. **Multiple verification methods**: Text search, element visibility, counts
4. **Progress tracking**: Count operations performed
5. **Fallback selectors**: Multiple approaches for finding elements

## Common Patterns

### Dashboard Navigation Reset
```typescript
// After operations, reset to dashboard list
await dashboardPage.navigateToDashboards();
await page.waitForTimeout(3000);

// Refresh list if needed
const myDashboardsButton = page.getByRole('button', { name: 'My Dashboards' });
if (await myDashboardsButton.isVisible({ timeout: 3000 }).catch(() => false)) {
  await myDashboardsButton.click();
  await page.waitForTimeout(3000);
}
```

### Confirmation Dialog Handling
```typescript
const confirmButton = page.locator('button:has-text("Confirm"), button:has-text("Yes"), button:has-text("OK")').last();
const confirmVisible = await confirmButton.isVisible({ timeout: 5000 }).catch(() => false);

if (confirmVisible) {
  await confirmButton.click();
  console.log('Confirmed action');
} else {
  console.log('No confirmation dialog, action might be immediate');
}
```

### Text-Based Dashboard Search
```typescript
// Get all text and filter for dashboards
const allPageText = await page.locator('body').innerText();
const dashboardLines = allPageText.split('\n').filter(line =>
  line.includes('Dashboard') || line.includes(searchPattern)
);
console.log('Found dashboards:', dashboardLines);
```

## Review Focus for Regression Tests

1. **Test dependencies**: Check if test relies on other tests' outputs
2. **Cleanup logic**: Verify test data is properly cleaned up
3. **Wait strategies**: Ensure adequate waits for slow builds
4. **Loop termination**: Check while loops have proper exit conditions
5. **Assertion quality**: Verify meaningful assertions beyond execution
6. **Debug output**: Check for helpful console logging
7. **Error recovery**: Verify fallback strategies for UI variations

## Red Flags

1. Missing REG- prefix in test name
2. No extended timeouts for build loading
3. Missing final test summary
4. No fallback selectors for critical operations
5. Hard failures without catch handlers
6. Missing debug output for operations
7. No verification after operations
8. Infinite loops without proper exit conditions
9. No cleanup of test data
10. Direct navigation without checking current state