framework-compliance-t…
Make a cloud account compliant with a security or industry framework using Prowler Cloud.
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).
Claude Code
$ npx -y skills add prowler-cloud/prowler --skill prowler-test-ui --agent claude-code
Codex
$ npx skills add prowler-cloud/prowler --skill prowler-test-ui -a codex -y
Cursor
$ npx skills add prowler-cloud/prowler --skill prowler-test-ui -a cursor -y
Gemini CLI
$ npx skills add prowler-cloud/prowler --skill prowler-test-ui -a gemini-cli -y
GitHub Copilot
$ npx skills add prowler-cloud/prowler --skill prowler-test-ui -a github-copilot -y
OpenCode
$ npx skills add prowler-cloud/prowler --skill prowler-test-ui -a opencode -y
Windsurf
$ npx skills add prowler-cloud/prowler --skill prowler-test-ui -a windsurf -y
name: prowler-test-ui
description: >
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).
license: Apache-2.0
metadata:
author: prowler-cloud
version: "1.1"
scope: [root, ui]
auto_invoke:
- "Writing Prowler UI E2E tests"
- "Working with Prowler UI test helpers/pages"
allowed-tools: Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task> **Generic Patterns**: For base Playwright patterns (Page Object Model, selectors, helpers), see the `playwright` skill. > This skill covers **Prowler-specific** conventions only.
ui/
├── playwright.base.ts # Shared config (testDir ./tests, expect timeout 20s, CI retries 2)
├── playwright.config.ts # Main projects + webServer (pnpm dev / pnpm start in CI)
├── playwright.registry.config.ts # Registry suite: own fixture API (:4300) and UI servers
└── tests/
├── base-page.ts # abstract BasePage (shared locators/verifications)
├── helpers.ts # makeSuffix, getSession, addAWSProvider, deleteProviderIfExists, TEST_CREDENTIALS...
├── setups/*.auth.setup.ts # Auth setup projects -> playwright/.auth/*.json storage states
└── {page-name}/
├── {page-name}-page.ts # Page Object Model
├── {page-name}.spec.ts # Tests (one spec per feature by default)
└── {page-name}.md # Test documentation (MANDATORY - sync with spec.ts)| Project | Specs | Depends on | |---------|-------|-----------| | `admin.auth.setup` (+ `manage-scans`, `manage-integrations`, `manage-account`, `manage-cloud-providers`, `unlimited-visibility`, `invite-and-manage-users`) | `tests/setups/*.auth.setup.ts` | - | | `sign-in-base`, `auth`, `invitation-accept`, `runtime-config` | `tests/{name}/*.spec.ts` | - (unauthenticated) | | `sign-up` | `sign-up.spec.ts` | - | | `scans`, `providers`, `invitations` | `{name}.spec.ts` | `admin.auth.setup` | | `navigation` | `tests/navigation/*.spec.ts` (Pixel 5, 390x844) | `admin.auth.setup` |
A new test folder needs a new project entry here (and in the `test:e2e*` scripts in `ui/package.json` if it should run by default). `pnpm run test:e2e` runs only `auth, sign-up, providers, invitations, scans, runtime-config, navigation`; `sign-in-base` and `invitation-accept` must be run with `--project`.
Authenticated suites reuse storage state instead of logging in:
test.use({ storageState: "playwright/.auth/admin_user.json" });Data-dependent flows use `test.describe.serial(...)` and the `@serial` tag; clean up first (e.g. `deleteProviderIfExists`) and `test.skip(!process.env.E2E_..., "...")` when required env vars are missing. Credentials and provider identifiers come only from `E2E_*` env vars (see `docs/developer-guide/end2end-testing.mdx`).
---
**⚠️ ALWAYS verify BEFORE completing any E2E task:**
# Verify .md exists for each test folder
ls ui/tests/{feature}/{feature}.md
# Verify test IDs match
grep -oE "@[A-Z-]+-E2E-[0-9]+" ui/tests/{feature}/*.spec.ts | sed 's/.*@//' | sort -u
grep -oE "\`[A-Z-]+-E2E-[0-9]+\`" ui/tests/{feature}/{feature}.md | tr -d '\`' | sort -u> [!IMPORTANT] > ❌ An E2E change is NOT considered complete without updating the corresponding `.md` file.
---
**⚠️ 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.
---
**⚠️ NEVER use `networkidle` - it causes flaky tests!**
| Strategy | Use Case | |----------|----------| | ❌ `networkidle` | NEVER - flaky with polling/WebSockets | | ⚠️ `load` | Only 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---
`BasePage` is `abstract`; extend it and reuse its helpers instead of re-implementing them:
| Member | Purpose | |--------|---------| | `title`, `loadingIndicator`, `themeToggle` | Shared locators | | `goto(url)`, `gotoFresh(url)` (`waitUntil: "commit"`, after clearing cookies), `refresh()`, `goBack()` | Navigation | | `skipFirstRunRedirect()` | Prevents the empty-tenant redirect to the add-provider wizard | | `verifyElementVisible/NotVisible/Text/ContainsText`, `verifyPageTitle`, `verifyNoErrors`, `verifyKeyboardNavigation`, `verifyAriaLabels` | Verifications | | `waitForElement`, `waitForElementToDisappear`, `waitForUrl` | Waits (5s default) |
import { PaProwler is the world’s most widely used Open-Source Cloud Security Platform that automates security and compliance across any cloud environment.
Make a cloud account compliant with a security or industry framework using Prowler Cloud.
Vercel AI SDK patterns for the installed major (ui/package.json: `ai` 6.x, `@ai-sdk/react` 3.x). The skill name is historical;…
Django REST Framework patterns. Trigger: When implementing generic DRF APIs (ViewSets, serializers, routers, permissions,…
Reviews Django migration files for PostgreSQL best practices specific to Prowler. Trigger: When creating migrations, running…
Create and maintain GitHub Agentic Workflows (gh-aw) for Prowler. Trigger: When creating agentic workflows, modifying gh-aw…
Strict JSON:API v1.1 specification compliance. Trigger: When creating or modifying API endpoints, reviewing API responses, or…
Use for authorized security assessment of REST, GraphQL, WebSocket, or SOAP APIs, including discovery, authentication,…
Extract and decrypt Windows DPAPI-protected secrets (Credential Manager, browser logins/cookies, Wi-Fi credentials, KeePass keys)…
Clean and finalize authorized natural-language text intended for readers by auditing suspicious invisible Unicode and rewriting…