Back to list
amitsingh-007

e2e-test-generation

by amitsingh-007

🔗 A web extension to bypass links along with custom redirections, private bookmarks panel & person tagging panel.

75🍴 12📅 Jan 21, 2026

SKILL.md


name: e2e-test-generation description: Create E2E tests for Chrome extension using Playwright license: MIT compatibility: opencode metadata: audience: developers framework: playwright target: extension

What I do

  • Create Playwright E2E tests for the Chrome extension
  • Use data-testid and getByTestId() as the primary test selector pattern
  • Add semantic selectors (role-based, data-testid) instead of class selectors
  • Add data-testid attributes to components when needed for robust test selectors
  • Define test constants for reusable test data in apps/extension/tests/constants.ts
  • Follow project conventions: test.describe for 2+ tests, exact text matches, no evaluate() for clicks
  • Use project fixtures: import { test, expect } from '../fixtures/bookmark-fixture'
  • Run the generated test file after making changes

When to use me

Use this when you need to create new E2E tests or update existing tests for the Chrome extension.

I will ask clarifying questions if:

  • The feature to test is not clearly defined
  • You need to test across multiple projects (extension vs web app)
  • Test data requirements are unclear

Selector Priority (use in this order)

  1. data-testid with getByTestId() (highest priority - standard for this project)

    bookmarksPage.getByTestId('folder-item-Main');
    bookmarksPage.getByTestId('bookmark-item-React Docs');
    bookmarksPage.getByTestId('person-item-John Doe');
    
    // For dynamic patterns, use locator with ^=
    bookmarksPage.locator('[data-testid^="bookmark-item-"]');
    
  2. Accessible Role Selectors (when data-testid not available)

    bookmarksPage.getByRole('button', { name: 'Add' });
    bookmarksPage.getByRole('dialog', { name: 'Add folder' });
    
  3. Placeholder/Label Selectors

    dialog.getByPlaceholder('Enter folder name');
    bookmarksPage.getByLabel('History');
    
  4. Title/Alt Selectors

    bookmarksPage.getByTitle('Edit Bookmark');
    bookmarksPage.getByAltText('User avatar');
    
  5. Text Content (use sparingly)

    bookmarksPage.getByText('Tagged Persons');
    

Selector Anti-Patterns (NEVER use)

  • Class selectors: [class*="Folder-module__container"], .mantine-HoverCard-dropdown
  • Custom data attributes (other than data-testid): data-folder-name, data-context-id, etc.
  • Regex for simple text: { name: /add/i } → use { name: 'Add' }
  • Positional selectors when specific selection is possible: .first(), .nth()
  • Generic CSS selectors without semantic meaning
  • Generic element selectors: img, div, span (use data-testid instead)
  • .evaluate() for clicks (use direct .click() instead)

When Positional Selectors Are OK

  • Generic UI elements without unique data-testid attributes
  • Tests that need "any" element rather than a specific one
  • Temporary UI elements (tooltips, context menus) where adding data-testid is impractical

Coding Style Guidelines

  • Exact text matches: Use { name: 'Add' } not { name: /add/i }
  • Specific selectors: Target parent div to avoid duplicate elements
  • Test constants: Define constants in apps/extension/tests/constants.ts for reusable data
  • Group tests: Only use test.describe for 2+ tests
  • Clear comments: Explain "why", not "what"

Common Patterns

Opening a dialog:

const addButton = bookmarksPage.getByRole('button', { name: 'Add' });
await addButton.click();
const dialog = bookmarksPage.getByRole('dialog', { name: 'Add folder' });
await expect(dialog).toBeVisible();

Filling a form:

await dialog.getByPlaceholder('Enter folder name').fill('Test Folder');
await dialog.getByRole('button', { name: 'Save' }).click();
await expect(dialog).toBeHidden();

Context menu:

await element.click({ button: 'right' });
const editOption = bookmarksPage.locator(
  '.mantine-contextmenu-item-button-title',
  { hasText: 'Edit' }
);
await editOption.waitFor({ state: 'attached' });
await editOption.evaluate((el) => (el as HTMLElement).click());

Multi-select with keyboard:

await firstItem.click();
await secondItem.click({ modifiers: ['Meta'] }); // Cmd/Ctrl+click

Waiting for navigation:

const [newPage] = await Promise.all([
  context.waitForEvent('page', { timeout: 15_000 }),
  element.dblclick(),
]);
expect(newPage).toBeTruthy();

After Test Creation

Run the generated test file to verify it works:

playwright test apps/extension/tests/specs/<your-test-file>.spec.ts

Checklist Before Committing

  • Tests use getByTestId() with data-testid as primary selector
  • Tests use semantic selectors (roles) when data-testid not available
  • No regex for simple text matches
  • No class-based selectors
  • No custom data attributes (only data-testid)
  • Avoid .evaluate() for clicks (use direct .click())
  • Test constants defined for reusable data
  • data-testid attributes added to components if needed
  • Only use test.describe for 2+ tests
  • Clear, descriptive test names
  • All tests pass locally
  • Tests are deterministic (no flaky behavior)

Score

Total Score

80/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

+10
人気

GitHub Stars 100以上

0/15
最近の活動

1ヶ月以内に更新

+10
フォーク

10回以上フォークされている

+5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

+5

Reviews

💬

Reviews coming soon