Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 26, 2025

The stencil-lit-migration-v2 agent produced page-object files with TypeScript errors, used arbitrary timeouts instead of Playwright's auto-waiting, and lacked clear guidance for visual regression baseline generation.

Changes

TypeScript-Safe Templates

  • Page Object: Complete template with explicit return types (Promise<void>, Promise<Buffer>), correct base class imports, and this.hydrated.screenshot() usage
  • Stage-Aware Base Class: Use @/playwright-utils/base-page-object at Step 0 (Stencil) with BasePageObject<'atomic-component-name'> type parameter, then switch to @/playwright-utils/lit-base-page-object after Step 4 (Lit migration)
  • Fixture: Type-safe template with proper MyFixtures type parameter and specific page object class imports
  • Validation Section: New section documenting 5 common TypeScript issues with side-by-side bad/good examples

Visual Regression Workflow (Step 0)

Enhanced each substep with explicit commands and validation:

  • 0.1: TypeScript-safe page-object template with waitForVisualStability() and captureScreenshot() methods using Stencil's base-page-object
  • 0.2: TypeScript-safe fixture with correct type annotations
  • 0.3: Visual test cases using test.step() and proper synchronization
  • 0.4: Explicit baseline generation: pnpm exec playwright test component.e2e.ts --grep "Visual" --update-snapshots
  • 0.5: Validation checklist and commit procedure

Step 4: Update Page Object for Lit

Added explicit guidance to update the page-object import after component migration:

  • Change from base-page-object (Stencil - uses hydrated class selector) to lit-base-page-object (Lit - uses tag selector)
  • Remove type parameter when switching to Lit base class

Test Synchronization

Replaced arbitrary timeout guidance with Playwright best practices:

Before:

await component.nextButton.click();
await component.page.waitForTimeout(300); // Dummy timeout

After:

await component.nextButton.click();
await expect(component.currentPage).toContainText('2'); // State-based waiting

Added synchronization guidance to Step 4 (functional E2E tests) and Step 0.3 (visual tests) with explicit bad/good patterns.

Documentation

Original prompt

This section details on the original issue you should resolve

<issue_title>[DXUI Feature]: Improve stencil-lit-migrationV2 agent for visual regression migration, TypeScript compatibility, and spec file logic</issue_title>
<issue_description>### Feature Description

Update the stencil-lit-migrationV2 agent to:

  • Properly handle migration steps for visual regression, including snapshot generation at all phases
  • Improve page-object file generation to ensure TypeScript compatibility and minimize manual fixes
  • Prevent unnecessary dummy timeouts in spec files by implementing correct test synchronization
    This automation will reduce manual intervention and test maintenance, improving the overall migration process for UI components.

User Story

As a DXUI developer migrating Stencil components
I want the migration agent to automate visual regression setup, TypeScript page-object generation, and robust spec file logic
So that migrations require less manual fixing, and automated testing is reliable and efficient.

Implementation Notes

• The agent should validate TypeScript output for generated page-object files to ensure type correctness before commit.
• Replace dummy timeouts in specs with actual synchronization for UI rendering (e.g., wait for DOM events, stable snapshot timing).
• Automatically set up visual regression snapshots at phase 0 and subsequent migration steps with minimal manual edits.
• Reference commits: 08883fd, cfc94ad
• Branch: copilot/migrate-atomic-rating-facet
• Target component: atomic-rating-facet

Jira Ticket

No response</issue_description>

Comments on the Issue (you are @copilot in this section)

Custom agent used: PromptEngineerV1
Autonomous prompt engineering agent for GitHub issues/PRs using advanced reasoning techniques


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

…visual regression, and test synchronization

Co-authored-by: y-lakhdar <12199712+y-lakhdar@users.noreply.github.com>
Copilot AI changed the title [WIP] Update stencil-lit-migrationV2 agent for visual regression docs(agents): enhance stencil-lit-migration-v2 agent with TypeScript safety, proper test synchronization, and visual regression workflow Nov 26, 2025
Copilot AI requested a review from y-lakhdar November 26, 2025 20:21
Copilot finished work on behalf of y-lakhdar November 26, 2025 20:21
…it-base-page-object after migration

Co-authored-by: y-lakhdar <12199712+y-lakhdar@users.noreply.github.com>
Copilot AI requested a review from y-lakhdar November 27, 2025 15:49
Copilot finished work on behalf of y-lakhdar November 27, 2025 15:49
@y-lakhdar y-lakhdar marked this pull request as ready for review November 27, 2025 16:15
@y-lakhdar y-lakhdar requested a review from a team as a code owner November 27, 2025 16:15
Copilot finished reviewing on behalf of y-lakhdar November 27, 2025 16:19
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR significantly enhances the stencil-to-lit-migration-v2 agent documentation to address three critical pain points identified during actual migrations: TypeScript compilation errors in generated page objects, inappropriate use of arbitrary timeouts instead of Playwright's auto-waiting mechanisms, and unclear visual regression baseline generation workflow. The changes transform the agent from high-level guidance into a comprehensive, executable migration playbook with complete code templates, validation checklists, and clear before/after examples.

Key Changes

  • TypeScript-Safe Templates: Complete page object and fixture templates with explicit return types, proper base class imports, and type parameters that pass compilation without manual fixes
  • Visual Regression Workflow Enhancement: Restructured Step 0 into 5 clear substeps (0.1-0.5) with explicit commands for baseline generation and validation
  • Test Synchronization Best Practices: Replaced arbitrary timeout guidance with Playwright auto-waiting patterns using await expect() assertions and state-based synchronization throughout Step 0.3 and Step 4
  • Stage-Aware Base Class Guidance: Clear instructions to use base-page-object (with type parameter) for Stencil components and lit-base-page-object (without type parameter) for Lit components
  • Comprehensive Validation Section: New section documenting 5 common TypeScript issues with side-by-side bad/good examples and a pre-commit validation checklist

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


// Only add page.waitForTimeout() if the component has animations/transitions
// that can't be detected otherwise. Most components don't need this.
// Example: await this.page.waitForTimeout(300); // For fade-in animation
Copy link

Copilot AI Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The comment at line 115-116 suggests that page.waitForTimeout() should only be added "if the component has animations/transitions that can't be detected otherwise." However, line 117 then provides an example with a specific timeout value (300ms). This is misleading because:

  1. The example comment "For fade-in animation" doesn't explain how to determine if this timeout is needed
  2. No guidance is provided on how to detect animations programmatically
  3. The specific 300ms value is arbitrary and might encourage copy-pasting without thought

Consider improving this guidance to either:

  • Remove the example entirely since "most components don't need this" (as stated in line 116)
  • Or provide clearer criteria for when timeouts are truly necessary (e.g., "only if the component uses CSS animations with no DOM state changes to detect")
  • Or add a reference to the waitForVisualStability() usage in tests, which already handles this
Suggested change
// Example: await this.page.waitForTimeout(300); // For fade-in animation

Copilot uses AI. Check for mistakes.
cd packages/atomic
pnpm exec playwright test atomic-component-name.e2e.ts --grep "Visual"
```
All visual tests should PASS (comparing Stencil component against its own baseline).
Copy link

Copilot AI Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The line "All visual tests should PASS (comparing Stencil component against its own baseline)" is misleading. At this point (Step 0.5), the baselines have just been generated with --update-snapshots, so the tests should pass by definition. The statement suggests validating the Stencil component against pre-existing baselines, which is not the case.

Consider clarifying this as: "All visual tests should PASS (the newly generated baselines should match the current Stencil rendering)" or simply "All visual tests should PASS (confirming successful baseline generation)".

Suggested change
All visual tests should PASS (comparing Stencil component against its own baseline).
All visual tests should PASS (confirming successful baseline generation).

Copilot uses AI. Check for mistakes.
Comment on lines +404 to +405
export class ComponentPageObject extends BasePageObject { ... }
```
Copy link

Copilot AI Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The guidance states "Remove type parameter when switching to Lit base class" but the "After" example at line 404 still shows extends BasePageObject { ... }, which could be read as just removing the type parameter content while keeping the angle brackets.

The example is technically correct (no type parameter), but for absolute clarity, consider adding a comment in the "After" example explicitly noting: // Note: No type parameter for Lit base class

Suggested change
export class ComponentPageObject extends BasePageObject { ... }
```

Copilot uses AI. Check for mistakes.
Comment on lines +908 to +923

The base class depends on whether the component is Stencil or Lit:

**At Step 0 (Stencil component - before migration):**
```typescript
// Correct for Stencil - uses hydrated class selector
import {BasePageObject} from '@/playwright-utils/base-page-object';
export class ComponentPageObject extends BasePageObject<'atomic-component-name'> { ... }
```

**After Step 4 (Lit component - after migration):**
```typescript
// Correct for Lit - uses tag selector
import {BasePageObject} from '@/playwright-utils/lit-base-page-object';
export class ComponentPageObject extends BasePageObject { ... }
```
Copy link

Copilot AI Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The title "Issue 3: Wrong BasePageObject Import for Migration Stage" is accurate, but the section doesn't clearly identify what the "error" or "fix" is - it only shows the correct patterns for each stage. Consider restructuring this to:

❌ Error: Using wrong base class for migration stage

// At Step 0 with Stencil component - WRONG
import {BasePageObject} from '@/playwright-utils/lit-base-page-object'; // Don't use lit version yet!

// After Step 4 with Lit component - WRONG
import {BasePageObject} from '@/playwright-utils/base-page-object'; // Still using Stencil version

✅ Fix: (then show the current "At Step 0" and "After Step 4" examples)

This would match the pattern of the other issues which clearly show bad and good examples.

Copilot uses AI. Check for mistakes.
Comment on lines +926 to +937

**Error:**
```typescript
// Using generic name instead of specific class
import {ComponentPageObject} from './page-object';
```

**Fix:**
```typescript
// Use the actual exported class name
import {RatingFacetPageObject} from './page-object';
```
Copy link

Copilot AI Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] In Issue 4's bad example (line 930), the comment says "Using generic name instead of specific class" but the actual import statement import {ComponentPageObject} from './page-object'; is inconsistent with the template provided earlier in the document.

Earlier at line 99, the page-object template defines the class as ComponentNamePageObject, and at line 183, the fixture correctly imports ComponentNamePageObject. However, the bad example uses ComponentPageObject (without "Name").

For consistency across the document, either:

  1. Use ComponentNamePageObject consistently everywhere (including bad examples)
  2. Or clarify that this represents the actual component name pattern (e.g., RatingFacetPageObject, PagerPageObject)

The good example at line 936 correctly uses the actual class name pattern.

Copilot uses AI. Check for mistakes.
// Wait for visible state change that indicates interaction completed
await expect(component.currentPage).toContainText('2');
// OR wait for element to appear/disappear
await expect(component.loadingSpinner).not.toBeVisible();
Copy link

Copilot AI Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The example at line 265 uses await expect(component.loadingSpinner).not.toBeVisible(); as a synchronization pattern. However, there's no loadingSpinner locator defined in the page-object template (lines 99-157), and this specific pattern isn't explained elsewhere in the document.

While this is meant as a generic example, it could be confusing since:

  1. The page-object template doesn't show how to define such locators
  2. The example comments at lines 138-156 show patterns for buttons, links, text, and lists, but not for visibility-based elements like spinners

Consider either:

  • Adding a loadingSpinner example to the page-object template comments
  • Or using an element that's already referenced in the examples (e.g., component.nextButton or component.statusMessage)
Suggested change
await expect(component.loadingSpinner).not.toBeVisible();
await expect(component.statusMessage).toBeVisible();

Copilot uses AI. Check for mistakes.
```bash
# Ensure Stencil component is built
# Step 1: Ensure the Stencil component is built
cd /home/runner/work/ui-kit/ui-kit
Copy link

Copilot AI Nov 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At line 289, the guidance says to cd /home/runner/work/ui-kit/ui-kit which appears to be a CI/GitHub Actions-specific path. This path is not appropriate for local development and will fail for developers running the migration locally.

Consider either:

  1. Using a relative path: cd /home/runner/work/ui-kit/ui-kit → (no cd needed if already at repo root, or just cd ../.. from packages/atomic)
  2. Or making it more generic: "Navigate to the repository root if not already there"
  3. Or removing this line entirely since line 294 already has cd packages/atomic which is the important navigation step

The current instruction will cause confusion for local development workflows.

Suggested change
cd /home/runner/work/ui-kit/ui-kit
# (Navigate to the repository root if not already there)

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[DXUI Feature]: Improve stencil-lit-migrationV2 agent for visual regression migration, TypeScript compatibility, and spec file logic

3 participants