/*
 * Copyright 2026, Jaime Terrats.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { existsSync } from 'node:fs';
import { join } from 'node:path';
import { generateQaWorkflows } from '../generators/workflows/qa.js';
import { codebaseContextualization, documentationStandards, generatedPromptsProtocol, interactionPreferences, salesforceReferences, semanticCommits, testCoverageStandards, } from './shared-sections.js';
export const qaProfile = {
    id: 'qa',
    label: 'QA / Test Automation (Playwright)',
    ruleFile: 'qa-standards.mdc',
    extensions: ['ms-playwright.playwright', 'dbaeumer.vscode-eslint', 'esbenp.prettier-vscode'],
    capabilities: ['code-analysis', 'doc-sync', 'prompt-registry', 'declare-points'],
    cursorScope: 'auto-attach',
    globs: ['force-app/**/*_Test.cls', '**/*.spec.ts', '**/*.test.ts', 'playwright.config.*'],
    detect(cwd) {
        return existsSync(join(cwd, 'playwright.config.ts')) || existsSync(join(cwd, 'playwright.config.js'));
    },
    workflows: generateQaWorkflows,
    ruleContent() {
        return [
            '---',
            'description: QA / Test Automation Standards (Playwright)',
            'globs:',
            'alwaysApply: true',
            '---',
            '',
            '# QA / Test Automation Standards (Playwright)',
            '',
            '> Role: QA / Test Automation Engineer — Salesforce Professional Services.',
            '',
            ...codebaseContextualization('existing tests and Page Objects'),
            '',
            '## Consultative Design (CRITICAL)',
            '- **No Ninja Edits.** Always summarize proposed test changes and get explicit agreement before modifying any file.',
            '- Discuss test strategy (which personas, which flows) before implementation.',
            '',
            '## Framework: Playwright',
            '- **Playwright** is the base framework for all end-to-end and UI tests.',
            '- All tests must be runnable via `npx playwright test`.',
            '- Use `playwright.config.ts` for configuration — never hardcode base URLs or credentials.',
            '- Store credentials in environment variables or `.env` files (never committed to git).',
            '',
            '## Page Object Model (MANDATORY)',
            '- Every page or major UI section must have a corresponding **Page Object** class.',
            '- Page Objects encapsulate selectors and actions. Tests must not contain raw selectors.',
            '- Naming: `<PageName>Page.ts` (e.g., `OpportunityPage.ts`, `LoginPage.ts`).',
            '- Selectors priority: `data-testid` > ARIA role > text > CSS. Never use XPath or positional CSS.',
            '',
            '## Test Isolation',
            '- Each test must be fully independent — no shared state between tests.',
            '- Use `beforeEach` / `afterEach` for setup and teardown.',
            '- Never rely on test execution order.',
            '- Use Playwright fixtures for reusable setup (authenticated page, test data, etc.).',
            '',
            '## Persona-to-Data Fixture Mapping',
            '- Every persona in the user story must have a corresponding Playwright **fixture**',
            '  that provisions a logged-in session with the correct Permission Set Group.',
            '- Fixture naming: `<persona>Fixture.ts` (e.g., `fieldRepFixture.ts`, `backOfficeFixture.ts`).',
            "- Fixtures must create or reference test data aligned with the persona's typical workflow.",
            '- Map acceptance criteria actors (Given I am a <Persona>) directly to fixture names.',
            '',
            '## Salesforce CLI Session Authentication',
            '- **Prefer SF CLI sessions over stored credentials.** Running `sf setup-agents local --profile qa`',
            '  scaffolds `src/utils/salesforce-auth.ts` and `src/utils/salesforce-api.ts` — use these in every project.',
            '- `getSalesforceOrgInfo()` calls `sf org display --json` via `execFileSync` (no shell interpolation).',
            '  It never reads cookies from the DOM — the access token comes directly from the CLI.',
            '- `navigateWithCLISession(page, context)` injects the `sid` cookie and navigates to Lightning home.',
            '  Use in `test.beforeEach` for UI tests.',
            '- `useSalesforceCLISession(context)` sets the cookie without navigating. Use in fixtures or API-only tests.',
            '- Control the target org with `SF_TARGET_ORG=<alias>` env var. Default: the CLI default org.',
            '- **CI/CD:** inject `SALESFORCE_INSTANCE_URL` and `SALESFORCE_ACCESS_TOKEN` as secrets.',
            '  The utility functions check these env vars first before calling the SF CLI.',
            '- Never store access tokens in `.env` files committed to git. Never hardcode org URLs.',
            '- See workflow `session-from-cli.md` for full usage patterns (navigation, fixtures, CI).',
            '',
            '## Salesforce-specific',
            '- Log in via **API** (not UI) when possible to speed up test setup.',
            '- Use scratch orgs or dedicated QA sandboxes — never run automation against production.',
            '- Salesforce Lightning renders asynchronously — always use `waitFor` patterns, never `page.waitForTimeout`.',
            '- Test all critical flows under each persona (Admin, Standard User, Field Rep, etc.).',
            '',
            '## Accessibility Testing',
            '- Integrate `@axe-core/playwright` for automated accessibility checks on key pages.',
            '- Assert zero critical WCAG 2.1 violations on every page under test.',
            '',
            '## Assertions',
            "- Use Playwright's built-in `expect` (auto-retrying). Never use `setTimeout` to wait.",
            '- One logical assertion per test step. Group related assertions only when they form a single behavior.',
            '- Test both happy path and key error/edge case scenarios.',
            '',
            '## Observable Assertions (CRITICAL)',
            '- **Tests must validate observable outcomes, not just prove a script ran.** A test that finishes without error is not evidence of correctness.',
            '- Evidence gaps, mocked boundaries, deferred validations, and required follow-up owners must be documented in the test file or evidence record.',
            '',
            '### Web / Playwright',
            '- Assert rendered text, control states (enabled/disabled/checked), navigation (URL, page title), layout-critical states, error messages, loading/recovery states.',
            '- Capture screenshots on failure (`screenshot: "only-on-failure"`). Screenshots count as evidence for visual assertions.',
            '- Never assert only that a button exists — assert what happens after clicking it.',
            '',
            '### API Tests',
            '- Assert response body shape and key fields (not just `status === 200`).',
            '- Assert error shape and message for failure paths.',
            '- Assert persistence: after a POST/PATCH, re-query and verify the record was written correctly.',
            '- Assert state transitions, idempotency on re-submission, permission enforcement (403/401 for unauthorized), and side effects.',
            '',
            '### Integration Tests (Agentforce / External Systems)',
            '- Assert the external side effect via sandbox, mock, contract test, webhook, queue record, or integration log.',
            '- If deferred validation is unavoidable, document: what was not validated, why, the owner, and the follow-up deadline.',
            '',
            '### CLI Tests (setup-agents / sf commands)',
            '- Assert exit code **and** stdout/stderr content.',
            '- Assert generated files exist and contain expected content (not just that the command exited 0).',
            '- Assert workflow events were recorded (e.g., task status, evidence entries).',
            '- Assert negative outputs: running the command twice must not duplicate artifacts.',
            '',
            '### Agentforce DML Validation (CRITICAL)',
            '- Must validate **both** conversational output and persisted Salesforce side effects — no chat-only tests when the agent performs DML.',
            '- Use `SfCliClient.query<T>(soql)` to verify the record was written. Poll max 10 s / 500 ms interval for async DML.',
            '- Tag with `@agent-dml` for selective CI execution.',
            '- Persist `sf data query` JSON output to `test-results/<spec>-<test>-dml.json` as evidence.',
            '',
            '## Reporting',
            '- Generate HTML reports via Playwright reporter: `npx playwright show-report`.',
            '- Always capture screenshots and traces on failure (`screenshot: "only-on-failure"`).',
            '',
            '## Test Plan Management',
            '- Produce a **test plan** for each sprint or release: scope, approach, entry/exit criteria, environment.',
            '- Maintain a **traceability matrix**: User Story → Test Cases → Test Results.',
            '- Test coverage tracking: every acceptance criterion must have at least one corresponding test case.',
            '- Store test plans in `/docs/test-plans/` following documentation standards.',
            '',
            '## Manual & Exploratory Testing',
            '- Use **session-based exploratory testing** for new features: define a charter, time-box the session (60-90 min), document findings.',
            '- Apply heuristics: boundary values, error states, permission variations, multi-browser behavior.',
            '- Manual testing complements automation — automate the stable paths, explore the edges manually.',
            '- Document exploratory session results: charter, duration, bugs found, areas of concern.',
            '',
            '## Defect Lifecycle',
            '- Bug reports must include: title, severity, priority, steps to reproduce, expected vs actual, screenshots/logs.',
            '- Severity matrix: S1 (blocker — system down), S2 (critical — major feature broken), S3 (major — workaround exists), S4 (minor — cosmetic).',
            '- Triage process: QA assigns severity, PM assigns priority, team agrees on sprint assignment.',
            '- Verification: after a fix is deployed, QA re-tests and closes the defect. No auto-close.',
            '',
            '## Performance Testing',
            '- Define performance acceptance criteria: page load time (< 3s), API response time (< 1s), concurrent users.',
            '- Salesforce-specific limits to monitor: API call volume, SOQL queries per transaction, CPU time.',
            '- For load testing: use tools appropriate to the stack (k6, JMeter, Playwright with concurrency).',
            '- Document performance baselines and compare against them in each release.',
            '',
            '## Salesforce API Testing',
            '- **API tests complement UI tests** — use them for: data setup/teardown, verifying backend logic without UI, and testing REST endpoints directly.',
            '- **Authentication in API tests:** use the SF CLI session utility (`getSalesforceOrgInfo()`) to obtain an access token — same pattern as UI tests, no separate auth config needed.',
            '- **REST API calls from tests:** use `axios` or Node.js `fetch` with the access token in the `Authorization: Bearer <token>` header.',
            '- **SOQL via REST API:**',
            '  ```typescript',
            '  const result = await fetch(`${instanceUrl}/services/data/v62.0/query?q=${encodeURIComponent(soql)}`, {',
            '    headers: { Authorization: `Bearer ${accessToken}` }',
            '  });',
            '  ```',
            '- **Composite API for multi-record setup:** use `/services/data/vXX.0/composite` to create related records in a single request — avoids multiple round-trips in `beforeEach`.',
            '- **Bulk data setup via SF CLI:** for large datasets, use `sf data import tree` in a `globalSetup` script rather than individual REST calls.',
            '- **Tooling API:** use for metadata queries (e.g., verify Apex code coverage, check Flow activation status) — endpoint: `/services/data/vXX.0/tooling/query`.',
            '- **Cleanup:** always delete test records in `afterEach`/`afterAll`. Use a unique prefix on test record names (e.g., `TEST_`) to identify and clean up safely.',
            '- **CI/CD:** inject `SALESFORCE_INSTANCE_URL` and `SALESFORCE_ACCESS_TOKEN` as secrets — same env vars used by the UI test auth utility.',
            '- Never run API tests that write data against production. Assert org type before running destructive operations.',
            '',
            '## Salesforce CLI Assertions in Integration Tests',
            '- Use `sf` CLI commands in `globalSetup` / `globalTeardown` scripts to assert org state beyond what the UI exposes.',
            '- **Verify org type before destructive operations** — never run data-clearing scripts against production:',
            '  ```typescript',
            '  const { result } = JSON.parse(execFileSync("sf", ["org","display","--json"]).toString());',
            '  if (result.instanceUrl.includes("salesforce.com") && !result.instanceUrl.includes("sandbox")) throw new Error("Refusing to run against production");',
            '  ```',
            '- **Post-deploy metadata assertions:** after a `sf project deploy start`, verify the component exists:',
            '  ```bash',
            '  sf data query --query "SELECT Id FROM ApexClass WHERE Name = \'MyClass\'" --json',
            '  ```',
            '- **Apex execution for post-deploy scripts:** use `sf apex run` to execute anonymous Apex that seeds test data or validates configuration — faster than REST API calls for complex setups.',
            '- **Flow activation check:** use Tooling API via `sf data query --use-tooling-api` to verify Flow version status before running dependent UI tests.',
            '- Store all CLI assertion helpers in `test/utils/salesforce-cli-assertions.ts` — reuse across test files.',
            '- Never use `execSync` with shell interpolation for CLI calls — always use `execFileSync` with an args array to prevent injection.',
            '',
            '## Regression Suite Management',
            '- Maintain three test tiers: **Smoke** (critical path, < 10 min), **Regression** (feature coverage, < 60 min), **Full** (all tests).',
            '- Smoke runs on every deployment. Regression runs nightly or before release. Full runs before production.',
            '- Review and prune the regression suite quarterly — remove obsolete tests, add coverage for new features.',
            '- Flaky tests must be quarantined and fixed within one sprint — never ignore intermittent failures.',
            '',
            '## Definition of Done (CRITICAL)',
            '- All acceptance criteria verified with evidence — no AC is "implicitly" done.',
            '- Code coverage ≥ 90% for all new/modified Apex classes.',
            '- No linter errors or suppressed warnings.',
            '- No SOQL or DML inside loops.',
            '- Deployment validation passed (`sf project deploy validate`).',
            '- Use `qa-checklist.md` playbook to sign off each story before approving the QA gate.',
            '',
            ...testCoverageStandards(),
            '',
            ...generatedPromptsProtocol(),
            '',
            ...documentationStandards(),
            '',
            ...semanticCommits(),
            '',
            '## Sub-agent Handover',
            '- Pass to sub-agents: the Page Object for the feature under test, the persona being tested,',
            '  the org/environment URL (from env var), and the test data setup approach.',
            '',
            ...salesforceReferences(),
            '',
            ...interactionPreferences(),
        ].join('\n');
    },
};
//# sourceMappingURL=qa.js.map