prowler-test-ui

0
0
Source

E2E testing patterns for Prowler UI (Playwright). Trigger: When writing Playwright E2E tests under ui/tests in the Prowler UI (Prowler-specific base page/helpers, tags, flows).

Install

mkdir -p .claude/skills/prowler-test-ui && curl -L -o skill.zip "https://mcp.directory/api/skills/download/7233" && unzip -o skill.zip -d .claude/skills/prowler-test-ui && rm skill.zip

Installs to .claude/skills/prowler-test-ui

About this skill

Generic Patterns: For base Playwright patterns (Page Object Model, selectors, helpers), see the playwright skill. This skill covers Prowler-specific conventions only.

Prowler UI Test Structure

ui/tests/
├── base-page.ts              # Prowler-specific base page
├── helpers.ts                # Prowler test utilities
└── {page-name}/
    ├── {page-name}-page.ts   # Page Object Model
    ├── {page-name}.spec.ts   # ALL tests (single file per feature)
    └── {page-name}.md        # Test documentation (MANDATORY - sync with spec.ts)

MANDATORY Checklist (Create or Modify Tests)

⚠️ ALWAYS verify BEFORE completing any E2E task:

When CREATING new tests:

  • {page-name}-page.ts - Page Object created/updated
  • {page-name}.spec.ts - Tests added with correct tags (@TEST-ID)
  • {page-name}.md - Documentation created with ALL test cases
  • Test IDs in .md match tags in .spec.ts

When MODIFYING existing tests:

  • {page-name}.md MUST be updated if:
    • Test cases were added/removed
    • Test flow changed (steps)
    • Preconditions or expected results changed
    • Tags or priorities changed
  • Test IDs synchronized between .md and .spec.ts

Quick validation:

# Verify .md exists for each test folder
ls ui/tests/{feature}/{feature}.md

# Verify test IDs match
grep -o "@[A-Z]*-E2E-[0-9]*" ui/tests/{feature}/{feature}.spec.ts | sort -u
grep -o "\`[A-Z]*-E2E-[0-9]*\`" ui/tests/{feature}/{feature}.md | sort -u

❌ An E2E change is NOT considered complete without updating the corresponding .md file


MCP Workflow - CRITICAL

⚠️ MANDATORY: If Playwright MCP tools are available, ALWAYS use them BEFORE creating tests.

  1. Navigate to target page
  2. Take snapshot to see actual DOM structure
  3. Interact with forms/elements to verify real flow
  4. Document actual selectors from snapshots
  5. Only then write test code

Why: Prevents tests based on assumptions. Real exploration = stable tests.


Wait Strategies (CRITICAL)

⚠️ NEVER use networkidle - it causes flaky tests!

StrategyUse Case
networkidleNEVER - flaky with polling/WebSockets
⚠️ loadOnly when absolutely necessary
expect(element).toBeVisible()PREFERRED - wait for specific UI state
page.waitForURL()Wait for navigation
pageObject.verifyPageLoaded()BEST - encapsulated verification

GOOD:

await homePage.verifyPageLoaded();
await expect(page).toHaveURL("/dashboard");
await expect(page.getByRole("heading", { name: "Overview" })).toBeVisible();

BAD:

await page.waitForLoadState("networkidle"); // ❌ FLAKY
await page.waitForTimeout(2000);            // ❌ ARBITRARY WAIT

Prowler Base Page

import { Page, Locator, expect } from "@playwright/test";

export class BasePage {
  constructor(protected page: Page) {}

  async goto(path: string): Promise<void> {
    await this.page.goto(path);
    // Child classes should override verifyPageLoaded() to wait for specific elements
  }

  // Override in child classes to wait for page-specific elements
  async verifyPageLoaded(): Promise<void> {
    await expect(this.page.locator("main")).toBeVisible();
  }

  // Prowler-specific: notification handling
  async waitForNotification(): Promise<Locator> {
    const notification = this.page.locator('[role="status"]');
    await notification.waitFor({ state: "visible" });
    return notification;
  }

  async verifyNotificationMessage(message: string): Promise<void> {
    const notification = await this.waitForNotification();
    await expect(notification).toContainText(message);
  }
}

Page Navigation Verification Pattern

⚠️ URL assertions belong in Page Objects, NOT in tests!

When verifying redirects or page navigation, create dedicated methods in the target Page Object:

// ✅ GOOD - In SignInPage
async verifyOnSignInPage(): Promise<void> {
  await expect(this.page).toHaveURL(/\/sign-in/);
  await expect(this.pageTitle).toBeVisible();
}

// ✅ GOOD - In test
await homePage.goto();  // Try to access protected route
await signInPage.verifyOnSignInPage();  // Verify redirect

// ❌ BAD - Direct assertions in test
await homePage.goto();
await expect(page).toHaveURL(/\/sign-in/);  // Should be in Page Object
await expect(page.getByText("Sign in")).toBeVisible();

Naming convention: verifyOn{PageName}Page() for redirect verification methods.


Prowler-Specific Pages

Providers Page

import { BasePage } from "../base-page";

export class ProvidersPage extends BasePage {
  readonly addButton = this.page.getByRole("button", { name: "Add Provider" });
  readonly providerTable = this.page.getByRole("table");

  async goto(): Promise<void> {
    await super.goto("/providers");
  }

  async addProvider(type: string, alias: string): Promise<void> {
    await this.addButton.click();
    await this.page.getByLabel("Provider Type").selectOption(type);
    await this.page.getByLabel("Alias").fill(alias);
    await this.page.getByRole("button", { name: "Create" }).click();
  }
}

Scans Page

export class ScansPage extends BasePage {
  readonly newScanButton = this.page.getByRole("button", { name: "New Scan" });
  readonly scanTable = this.page.getByRole("table");

  async goto(): Promise<void> {
    await super.goto("/scans");
  }

  async startScan(providerAlias: string): Promise<void> {
    await this.newScanButton.click();
    await this.page.getByRole("combobox", { name: "Provider" }).click();
    await this.page.getByRole("option", { name: providerAlias }).click();
    await this.page.getByRole("button", { name: "Start Scan" }).click();
  }
}

Test Tags for Prowler

test("Provider CRUD operations",
  { tag: ["@critical", "@e2e", "@providers", "@PROV-E2E-001"] },
  async ({ page }) => {
    // ...
  }
);
CategoryTags
Priority@critical, @high, @medium, @low
Type@e2e, @smoke, @regression
Feature@providers, @scans, @findings, @compliance, @signin, @signup
Test ID@PROV-E2E-001, @SCAN-E2E-002

Prowler Test Documentation Template

Keep under 60 lines. Focus on flow, preconditions, expected results only.

### E2E Tests: {Feature Name}

**Suite ID:** `{SUITE-ID}`
**Feature:** {Feature description}

---

## Test Case: `{TEST-ID}` - {Test case title}

**Priority:** `{critical|high|medium|low}`
**Tags:** @e2e, @{feature-name}

**Preconditions:**
- {Prerequisites}

### Flow Steps:
1. {Step}
2. {Step}

### Expected Result:
- {Outcome}

### Key Verification Points:
- {Assertion}

Commands

cd ui && pnpm run test:e2e                              # All tests
cd ui && pnpm run test:e2e tests/providers/             # Specific folder
cd ui && pnpm run test:e2e --grep "provider"            # By pattern
cd ui && pnpm run test:e2e:ui                           # With UI
cd ui && pnpm run test:e2e:debug                        # Debug mode
cd ui && pnpm run test:e2e:headed                       # See browser
cd ui && pnpm run test:e2e:report                       # Generate report

Resources

  • Documentation: See references/ for links to local developer guide

django-drf

prowler-cloud

Django REST Framework patterns. Trigger: When implementing generic DRF APIs (ViewSets, serializers, routers, permissions, filtersets). For Prowler API specifics (RLS/RBAC/Providers), also use prowler-api.

55

zod-4

prowler-cloud

Zod 4 schema validation patterns. Trigger: When creating or updating Zod v4 schemas for validation/parsing (forms, request payloads, adapters), including v3 -> v4 migration patterns.

474

prowler-pr

prowler-cloud

Creates Pull Requests for Prowler following the project template and conventions. Trigger: When working on pull request requirements or creation (PR template sections, PR title Conventional Commits check, changelog gate/no-changelog label), or when inspecting PR-related GitHub workflows like conventional-commit.yml, pr-check-changelog.yml, pr-conflict-checker.yml, labeler.yml, or CODEOWNERS.

00

prowler-ci

prowler-cloud

Helps with Prowler repository CI and PR gates (GitHub Actions workflows). Trigger: When investigating CI checks failing on a PR, PR title validation, changelog gate/no-changelog label, conflict marker checks, secret scanning, CODEOWNERS/labeler automation, or anything under .github/workflows.

00

prowler-ui

prowler-cloud

Prowler UI-specific patterns. For generic patterns, see: typescript, react-19, nextjs-15, tailwind-4. Trigger: When working inside ui/ on Prowler-specific conventions (shadcn vs HeroUI legacy, folder placement, actions/adapters, shared types/hooks/lib).

00

prowler-commit

prowler-cloud

Creates professional git commits following conventional-commits format. Trigger: When creating commits, after completing code changes, when user asks to commit.

10

You might also like

flutter-development

aj-geddes

Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.

9521,094

drawio-diagrams-enhanced

jgtolentino

Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.

846846

ui-ux-pro-max

nextlevelbuilder

"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."

570697

godot

bfollington

This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.

548492

nano-banana-pro

garg-aayush

Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.

672464

fastapi-templates

wshobson

Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.

512280

Stay ahead of the MCP ecosystem

Get weekly updates on new skills and servers.