From db9ae4a4f88e121718da0397e3049d7b76e7c3e9 Mon Sep 17 00:00:00 2001 From: Sanket Saikia Date: Mon, 19 Jan 2026 18:04:22 +0530 Subject: [PATCH 1/4] adding localization to nightly jobs Signed-off-by: Sanket Saikia --- .claude/memories/add_extension_metadata.md | 2 +- .claude/memories/ci-e2e-testing.md | 13 +++++++++++++ .cursor/rules/add_extension_metadata.mdc | 4 ++-- .cursor/rules/ci-e2e-testing.mdc | 13 +++++++++++++ .ibm/pipelines/jobs/ocp-nightly.sh | 12 ++++++++++++ .rulesync/rules/add_extension_metadata.md | 8 ++++---- .rulesync/rules/ci-e2e-testing.md | 13 +++++++++++++ docs/e2e-tests/CI.md | 12 ++++++++++++ 8 files changed, 70 insertions(+), 7 deletions(-) diff --git a/.claude/memories/add_extension_metadata.md b/.claude/memories/add_extension_metadata.md index af5ff5da1a..3cc6a54c33 100644 --- a/.claude/memories/add_extension_metadata.md +++ b/.claude/memories/add_extension_metadata.md @@ -92,7 +92,7 @@ Create `catalog-entities/extensions/plugins/{plugin-name}.yaml`: ### Step 4: Validate Files ```bash -# Navigate to marketplace directory +# Navigate to extensions directory cd catalog-entities/extensions # Download schemas to temp directory (ajv doesn't support remote schemas well) diff --git a/.claude/memories/ci-e2e-testing.md b/.claude/memories/ci-e2e-testing.md index 90022de29b..d2d17b1b90 100644 --- a/.claude/memories/ci-e2e-testing.md +++ b/.claude/memories/ci-e2e-testing.md @@ -79,6 +79,7 @@ test.beforeAll(async ({ }, testInfo) => { - `showcase-runtime`: Runtime environment tests - `showcase-sanity-plugins`: Plugin sanity checks - `showcase-upgrade`: Upgrade scenario tests + - `showcase-localization-fr`: French localization tests - `any-test`: Use for debugging when you need to run a specific tests **Note**: All project names are defined in `e2e-tests/playwright/projects.json` as the single source of truth. This file is consumed by: @@ -110,6 +111,14 @@ test.beforeAll(async ({ }, testInfo) => { - Audit logging functionality - Compliance verification +7. **Localization Tests** (`playwright/e2e/localization/`) + - Verify UI displays correctly translated strings + - Currently supports **French (fr)** only + - Runs as part of OCP nightly job (skipped for OSD-GCP) + - Uses `showcase-localization-fr` Playwright project + - Translation files located in `translations/` directory + - Test helper: `e2e-tests/playwright/e2e/localization/locale.ts` + ### Test Execution #### CI/CD Pipeline Execution @@ -155,6 +164,9 @@ yarn showcase-auth-providers # Auth provider tests # Plugin tests yarn showcase-sanity-plugins # Plugin sanity tests +# Localization tests +yarn showcase-localization-fr # French localization tests + # Utility scripts yarn lint:check # Lint checking yarn lint:fix # Lint fixing @@ -496,6 +508,7 @@ The choice of config map depends on the **Playwright test project** being execut - `showcase-runtime` - Runtime environment tests - `showcase-sanity-plugins` - Plugin sanity tests - `showcase-upgrade` - Upgrade scenario tests +- `showcase-localization-fr` - French localization tests - `showcase-auth-providers` - Authentication provider tests (uses special deployment process) #### **app-config-rhdh-rbac.yaml** (RBAC Configuration) diff --git a/.cursor/rules/add_extension_metadata.mdc b/.cursor/rules/add_extension_metadata.mdc index 3d84cafa74..29d93bca8b 100644 --- a/.cursor/rules/add_extension_metadata.mdc +++ b/.cursor/rules/add_extension_metadata.mdc @@ -98,7 +98,7 @@ Create `catalog-entities/extensions/plugins/{plugin-name}.yaml`: ### Step 4: Validate Files ```bash -# Navigate to marketplace directory +# Navigate to extensions directory cd catalog-entities/extensions # Download schemas to temp directory (ajv doesn't support remote schemas well) @@ -141,7 +141,7 @@ git add catalog-entities/extensions/packages/{plugin-name}.yaml git add catalog-entities/extensions/plugins/{plugin-name}.yaml # Commit with descriptive message -git commit -m "feat: add {plugin-name} plugin to RHDH marketplace +git commit -m "feat: add {plugin-name} plugin to RHDH extensions - Added Package entity with OCI URL and version - Added Plugin entity with description and metadata diff --git a/.cursor/rules/ci-e2e-testing.mdc b/.cursor/rules/ci-e2e-testing.mdc index 821ccfbe0c..4840853ad7 100644 --- a/.cursor/rules/ci-e2e-testing.mdc +++ b/.cursor/rules/ci-e2e-testing.mdc @@ -85,6 +85,7 @@ test.beforeAll(async ({ }, testInfo) => { - `showcase-runtime`: Runtime environment tests - `showcase-sanity-plugins`: Plugin sanity checks - `showcase-upgrade`: Upgrade scenario tests + - `showcase-localization-fr`: French localization tests - `any-test`: Use for debugging when you need to run a specific tests **Note**: All project names are defined in `e2e-tests/playwright/projects.json` as the single source of truth. This file is consumed by: @@ -116,6 +117,14 @@ test.beforeAll(async ({ }, testInfo) => { - Audit logging functionality - Compliance verification +7. **Localization Tests** (`playwright/e2e/localization/`) + - Verify UI displays correctly translated strings + - Currently supports **French (fr)** only + - Runs as part of OCP nightly job (skipped for OSD-GCP) + - Uses `showcase-localization-fr` Playwright project + - Translation files located in `translations/` directory + - Test helper: `e2e-tests/playwright/e2e/localization/locale.ts` + ### Test Execution #### CI/CD Pipeline Execution @@ -161,6 +170,9 @@ yarn showcase-auth-providers # Auth provider tests # Plugin tests yarn showcase-sanity-plugins # Plugin sanity tests +# Localization tests +yarn showcase-localization-fr # French localization tests + # Utility scripts yarn lint:check # Lint checking yarn lint:fix # Lint fixing @@ -502,6 +514,7 @@ The choice of config map depends on the **Playwright test project** being execut - `showcase-runtime` - Runtime environment tests - `showcase-sanity-plugins` - Plugin sanity tests - `showcase-upgrade` - Upgrade scenario tests +- `showcase-localization-fr` - French localization tests - `showcase-auth-providers` - Authentication provider tests (uses special deployment process) #### **app-config-rhdh-rbac.yaml** (RBAC Configuration) diff --git a/.ibm/pipelines/jobs/ocp-nightly.sh b/.ibm/pipelines/jobs/ocp-nightly.sh index 2c86dae5c3..ef455815fb 100644 --- a/.ibm/pipelines/jobs/ocp-nightly.sh +++ b/.ibm/pipelines/jobs/ocp-nightly.sh @@ -33,6 +33,11 @@ handle_ocp_nightly() { run_runtime_config_change_tests run_sanity_plugins_check + # Skip localization tests for OSD-GCP jobs + if [[ ! "${JOB_NAME}" =~ osd-gcp ]]; then + run_localization_tests + fi + } run_standard_deployment_tests() { @@ -54,3 +59,10 @@ run_sanity_plugins_check() { initiate_sanity_plugin_checks_deployment "${RELEASE_NAME}" "${NAME_SPACE_SANITY_PLUGINS_CHECK}" "${sanity_plugins_url}" check_and_test "${RELEASE_NAME}" "${NAME_SPACE_SANITY_PLUGINS_CHECK}" "${PW_PROJECT_SHOWCASE_SANITY_PLUGINS}" "${sanity_plugins_url}" } + +run_localization_tests() { + local url="https://${RELEASE_NAME}-developer-hub-${NAME_SPACE}.${K8S_CLUSTER_ROUTER_BASE}" + log::section "Running localization tests" + # French (fr) + check_and_test "${RELEASE_NAME}" "${NAME_SPACE}" "${PW_PROJECT_SHOWCASE_LOCALIZATION_FR}" "${url}" +} diff --git a/.rulesync/rules/add_extension_metadata.md b/.rulesync/rules/add_extension_metadata.md index ad5b7e542a..62ed704601 100644 --- a/.rulesync/rules/add_extension_metadata.md +++ b/.rulesync/rules/add_extension_metadata.md @@ -111,7 +111,7 @@ Create `catalog-entities/extensions/plugins/{plugin-name}.yaml`: ### Step 4: Validate Files ```bash -# Navigate to marketplace directory +# Navigate to extensions directory cd catalog-entities/extensions # Download schemas to temp directory (ajv doesn't support remote schemas well) @@ -150,11 +150,11 @@ Follow the RHDH-local testing instructions in the README: ```bash # Stage changes -git add catalog-entities/marketplace/packages/{plugin-name}.yaml -git add catalog-entities/marketplace/plugins/{plugin-name}.yaml +git add catalog-entities/extensions/packages/{plugin-name}.yaml +git add catalog-entities/extensions/plugins/{plugin-name}.yaml # Commit with descriptive message -git commit -m "feat: add {plugin-name} plugin to RHDH marketplace +git commit -m "feat: add {plugin-name} plugin to RHDH extensions - Added Package entity with OCI URL and version - Added Plugin entity with description and metadata diff --git a/.rulesync/rules/ci-e2e-testing.md b/.rulesync/rules/ci-e2e-testing.md index fbf57fc592..a680eabc55 100644 --- a/.rulesync/rules/ci-e2e-testing.md +++ b/.rulesync/rules/ci-e2e-testing.md @@ -96,6 +96,7 @@ test.beforeAll(async ({ }, testInfo) => { - `showcase-runtime`: Runtime environment tests - `showcase-sanity-plugins`: Plugin sanity checks - `showcase-upgrade`: Upgrade scenario tests + - `showcase-localization-fr`: French localization tests - `any-test`: Use for debugging when you need to run a specific tests **Note**: All project names are defined in `e2e-tests/playwright/projects.json` as the single source of truth. This file is consumed by: @@ -127,6 +128,14 @@ test.beforeAll(async ({ }, testInfo) => { - Audit logging functionality - Compliance verification +7. **Localization Tests** (`playwright/e2e/localization/`) + - Verify UI displays correctly translated strings + - Currently supports **French (fr)** only + - Runs as part of OCP nightly job (skipped for OSD-GCP) + - Uses `showcase-localization-fr` Playwright project + - Translation files located in `translations/` directory + - Test helper: `e2e-tests/playwright/e2e/localization/locale.ts` + ### Test Execution #### CI/CD Pipeline Execution @@ -172,6 +181,9 @@ yarn showcase-auth-providers # Auth provider tests # Plugin tests yarn showcase-sanity-plugins # Plugin sanity tests +# Localization tests +yarn showcase-localization-fr # French localization tests + # Utility scripts yarn lint:check # Lint checking yarn lint:fix # Lint fixing @@ -513,6 +525,7 @@ The choice of config map depends on the **Playwright test project** being execut - `showcase-runtime` - Runtime environment tests - `showcase-sanity-plugins` - Plugin sanity tests - `showcase-upgrade` - Upgrade scenario tests +- `showcase-localization-fr` - French localization tests - `showcase-auth-providers` - Authentication provider tests (uses special deployment process) #### **app-config-rhdh-rbac.yaml** (RBAC Configuration) diff --git a/docs/e2e-tests/CI.md b/docs/e2e-tests/CI.md index 27b1ef86de..cb36000228 100644 --- a/docs/e2e-tests/CI.md +++ b/docs/e2e-tests/CI.md @@ -97,6 +97,18 @@ The nightly job for the `main` branch also runs against three OpenShift Containe > **Note:** The output of the nightly runs, including test results and any relevant notifications, is posted on the Slack channel **`#rhdh-e2e-test-alerts`**. +### Localization Tests + +Localization tests verify that the RHDH UI displays correctly translated strings for supported languages. These tests run as part of the OCP Helm nightly job. + +- **Supported Languages:** Currently only **French (fr)** is tested. Additional languages (Italian, Japanese) may be added in the future. +- **When They Run:** Localization tests run at the end of the OCP nightly job, after standard deployment tests, runtime config tests, and sanity plugin checks. +- **Skip Condition:** Localization tests are **skipped for OSD-GCP jobs** due to environment constraints. +- **Reuses Existing Deployment:** The tests run against the same RHDH instance deployed for standard tests, so no additional deployment is needed. +- **Playwright Project:** `showcase-localization-fr` + +The localization test implementation is in `.ibm/pipelines/jobs/ocp-nightly.sh` (`run_localization_tests()` function). + ### CI Job Definitions #### Nightly Test Job From 683c6aee49d0b116e0065bfcc01f87612b3dc900 Mon Sep 17 00:00:00 2001 From: Sanket Saikia Date: Wed, 21 Jan 2026 10:43:39 +0530 Subject: [PATCH 2/4] changing user settings persistence to browser Signed-off-by: Sanket Saikia --- .ibm/pipelines/resources/config_map/app-config-rhdh.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.ibm/pipelines/resources/config_map/app-config-rhdh.yaml b/.ibm/pipelines/resources/config_map/app-config-rhdh.yaml index fcb19321f8..106a0e0a1a 100644 --- a/.ibm/pipelines/resources/config_map/app-config-rhdh.yaml +++ b/.ibm/pipelines/resources/config_map/app-config-rhdh.yaml @@ -240,6 +240,9 @@ buildInfo: Authentication provider: "Github" RBAC: disabled overrideBuildInfo: true +# Opt-out of database storage for user settings +userSettings: + persistence: browser i18n: locales: - en From edff4e21673b6e05f41e82548a2a7ef932860b5b Mon Sep 17 00:00:00 2001 From: ssaikia Date: Thu, 22 Jan 2026 12:50:28 +0530 Subject: [PATCH 3/4] adding rulesync generated files --- .claude/rules/add_extension_metadata.md | 205 ++++++++ .claude/rules/ci-e2e-testing.md | 545 ++++++++++++++++++++++ .claude/rules/managing-ai-rules.md | 377 +++++++++++++++ .claude/rules/playwright-locators.md | 164 +++++++ .cursor/rules/add_extension_metadata.mdc | 6 +- .rulesync/rules/add_extension_metadata.md | 6 +- 6 files changed, 1297 insertions(+), 6 deletions(-) create mode 100644 .claude/rules/add_extension_metadata.md create mode 100644 .claude/rules/ci-e2e-testing.md create mode 100644 .claude/rules/managing-ai-rules.md create mode 100644 .claude/rules/playwright-locators.md diff --git a/.claude/rules/add_extension_metadata.md b/.claude/rules/add_extension_metadata.md new file mode 100644 index 0000000000..7b30813254 --- /dev/null +++ b/.claude/rules/add_extension_metadata.md @@ -0,0 +1,205 @@ +--- +paths: 'catalog-entities/extensions/**, docs/dynamic-plugins/**' +--- +# RHDH Extensions Catalog - Plugin Metadata Workflow + +This cursor rule provides an automated workflow for adding dynamic plugin metadata to the RHDH Extensions Catalog. + +## Important Documentation + +**Primary Reference**: Read `catalog-entities/extensions/README.md` for: +- Detailed YAML structure and field explanations +- Complete examples (3scale plugin) +- RHDH-local testing setup +- Troubleshooting guide + +This rule focuses on the **workflow automation** and **validation** aspects not covered in the README. + +## Prerequisites + +Before starting, ensure you have: + +1. **Successfully exported plugin** from [RHDH Plugin Export Overlays](https://github.com/redhat-developer/rhdh-plugin-export-overlays) + - OCI URL from build output (e.g., `oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/aws-ecs:pr_1426__0.6.0!aws-ecs`) + - Plugin version and integrity information + +2. **Required tools installed**: + ```bash + # Check if tools are installed + command -v yq &> /dev/null || echo "❌ Install yq (Go version): brew install yq (macOS) or snap install yq (Linux)" + command -v ajv &> /dev/null || echo "❌ Install ajv-cli: npm install -g ajv-cli" + command -v gh &> /dev/null || echo "❌ Install GitHub CLI: brew install gh (macOS)" + ``` + + **Important**: Ensure you have the **Go-based version of yq** (mikefarah/yq), not the Python version (kislyuk/yq). + Verify with: `yq --version` (should show "mikefarah/yq") + +## Interactive Information Gathering + +When adding a plugin, gather the following information: + +### Required Information +1. **Plugin Identification** + - Plugin name (e.g., `aws-ecs`, `todo`) + - NPM package name (e.g., `@aws/amazon-ecs-plugin-for-backstage`) + - Namespace (e.g., `rhdh` for Red Hat maintained, `community` for community plugins) + +2. **Technical Details** + - OCI URL from overlay build + - Plugin version + - Backstage version compatibility + - Role: `frontend-plugin` or `backend-plugin` + +3. **User-Facing Information** + - Title and short description (2-3 lines for tile view) + - Long description (markdown, for expanded view) + - Category (one of: AI, Analytics, CI/CD, Cloud, Compliance, Cost, Developer Tools, Docs, Feature Flags, Kubernetes, Monitoring, Productivity, Reporting, Search, Security, Storage, Supply Chain, Testing) + - Tags (lowercase, kebab-case) + - Support level: `production`, `tech-preview`, or `dev-preview` + +4. **Links** + - Homepage/documentation URL + - Source code repository + - Bug tracker URL + +## Workflow Steps + +### Step 1: Create Feature Branch + +```bash +# Ensure we're on latest main +git fetch origin && git checkout main && git pull origin main + +# Create feature branch +git checkout -b add-{plugin-name}-plugin-metadata +``` + +### Step 2: Tool Verification + +```bash +# Verify required tools +for tool in yq ajv gh; do + command -v $tool &> /dev/null && echo "✓ $tool installed" || echo "❌ $tool missing" +done + +# Verify yq is the Go version +yq --version | grep -q "mikefarah" && echo "✓ yq is Go version (mikefarah/yq)" || echo "❌ Wrong yq version - install mikefarah/yq" +``` + +### Step 3: Create/Edit Plugin Metadata + +Create `catalog-entities/extensions/plugins/{plugin-name}.yaml`: +- Use `catalog-entities/extensions/plugins/3scale.yaml` as a template +- See README for complete field descriptions + +### Step 4: Validate Files + +```bash +# Navigate to extensions directory +cd catalog-entities/extensions + +# Download schemas to temp directory (ajv doesn't support remote schemas well) +mkdir -p /tmp/rhdh-schemas +curl -s "https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/main/workspaces/extensions/json-schema/packages.json" \ + -o /tmp/rhdh-schemas/packages.json +curl -s "https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/main/workspaces/extensions/json-schema/plugins.json" \ + -o /tmp/rhdh-schemas/plugins.json + +# Convert YAML to JSON and validate Package against local schema +echo "Validating packages/{plugin-name}.yaml..." +yq eval packages/{plugin-name}.yaml -o json > /tmp/rhdh-schemas/package-temp.json +ajv validate -s /tmp/rhdh-schemas/packages.json -d /tmp/rhdh-schemas/package-temp.json + +# Convert YAML to JSON and validate Plugin against local schema +echo "Validating plugins/{plugin-name}.yaml..." +yq eval plugins/{plugin-name}.yaml -o json > /tmp/rhdh-schemas/plugin-temp.json +ajv validate -s /tmp/rhdh-schemas/plugins.json -d /tmp/rhdh-schemas/plugin-temp.json + +# Clean up temp files +rm /tmp/rhdh-schemas/package-temp.json /tmp/rhdh-schemas/plugin-temp.json +``` + +**Note**: This uses the Go-based `yq` syntax (`yq eval file.yaml -o json`). If validation fails, check that you have the correct yq version installed. + +### Step 5: Test Locally (Optional) + +Follow the RHDH-local testing instructions in the README: +1. Clone `rhdh-local` repository +2. Mount your local catalog in `compose.yaml` +3. Set `catalog.processingInterval: { seconds: 15 }` in `app-config.yaml` +4. Start with `docker compose up -d` +5. Check http://localhost:7007 → Catalog → Extensions + +### Step 6: Create Pull Request + +```bash +# Stage changes +git add catalog-entities/extensions/packages/{plugin-name}.yaml +git add catalog-entities/extensions/plugins/{plugin-name}.yaml + +# Commit with descriptive message +git commit -m "feat: add {plugin-name} plugin to RHDH extensions + +- Added Package entity with OCI URL and version +- Added Plugin entity with description and metadata + +# Create PR +gh pr create --title "feat: add {plugin-name} plugin to extensions" \ + --body "## Summary +- Added {plugin-name} plugin metadata to Extensions Catalog +- Package: \`{npm-package-name}\` version {version} +- Support level: {support-level} + +## Checklist +- [ ] Package and Plugin YAML files created +- [ ] Schemas validate successfully +- [ ] Tested locally with rhdh-local (if applicable)" +``` + +## Validation Checklist + +Before submitting: +- [ ] Tools installed (`yq` Go version, `ajv-cli`, `gh`) +- [ ] Package YAML validates against schema +- [ ] Plugin YAML validates against schema +- [ ] Namespace consistent between Package and Plugin +- [ ] OCI URL correctly formatted +- [ ] All required fields populated + +## Common Issues + +### Schema Validation Fails +```bash +# Debug by checking JSON conversion (using Go-based yq) +yq eval your-file.yaml -o json | jq '.' + +# Common issues: +# - Missing required fields +# - Wrong field types +# - Invalid enum values (e.g., wrong category) +``` + +### Wrong yq Version +```bash +# Check if you have the Go version +yq --version + +# Should show: yq (https://github.com/mikefarah/yq/) version X.X.X + +# If you have the Python version (kislyuk/yq), uninstall and install Go version: +# macOS: brew install mikefarah/yq/yq +# Linux: snap install yq +``` + +### OCI URL Format +Correct format: `oci://registry/path:tag!package-name` +- Must include `!package-name` suffix +- Tag typically includes PR number and version + +## References + +- [README with detailed documentation](../../catalog-entities/extensions/README.md) +- [Extension Schemas](https://github.com/redhat-developer/rhdh-plugins/tree/main/workspaces/extensions/json-schema) +- [RHDH Local Testing](https://github.com/redhat-developer/rhdh-local) +- [Dynamic Plugins Documentation](https://docs.redhat.com/en/documentation/red_hat_developer_hub) +- [RHDH Plugin Catalog](https://gitlab.cee.redhat.com/rhidp/rhdh-plugin-catalog/-/blob/rhdh-1-rhel-9/catalog-index) (RH VPN Required) diff --git a/.claude/rules/ci-e2e-testing.md b/.claude/rules/ci-e2e-testing.md new file mode 100644 index 0000000000..8c021f8722 --- /dev/null +++ b/.claude/rules/ci-e2e-testing.md @@ -0,0 +1,545 @@ +--- +paths: '.ibm/**, e2e-tests/**, docs/e2e-tests/**' +--- +# RHDH (Red Hat Developer Hub) Repository Context + +This document serves as a comprehensive starting point for LLMs working with the RHDH repository. It provides detailed information about the e2e-tests, testing infrastructure and CI/CD pipeline. + +## Table of Contents + +- [E2E Testing Framework](#e2e-testing-framework) +- [CI/CD Infrastructure](#cicd-infrastructure) +- [Key Dependencies and Common Issues](#key-dependencies-and-common-issues) +- [Documentation References](#documentation-references) + +## E2E Testing Framework + +### Technology Stack +- **Testing Framework**: Playwright with TypeScript +- **Node.js Version**: 22 +- **Package Manager**: Yarn 3.8.7 +- **Test Runner**: Playwright Test +- **Reporting**: HTML, JUnit XML, List reporters + +Current versions for e2e-tests are defined in `e2e-tests/package.json` + +### Test Structure and Organization + +#### Directory Structure +```text +e2e-tests/ +├── playwright/ +│ ├── e2e/ # Main test files +│ │ └── *.spec.ts # General test files +│ ├── utils/ # Test utilities +│ ├── data/ # Test data +│ └── support/ # Test support files +``` + +#### Test File Requirements + +**Component Assignment**: Every test file (`*.spec.ts`) in the `e2e-tests` folder must have a component assigned in the `test.beforeAll` hook using the following syntax: + +```typescript +test.beforeAll(async ({ }, testInfo) => { + testInfo.annotations.push({ + type: "component", + description: "your_value", + }); +}); +``` + +**Purpose**: This component annotation is used for test categorization, reporting, and CI/CD pipeline organization. It helps identify which component or feature area each test file is validating. + +**Examples of Component Values**: +- `"authentication"` - for authentication provider tests +- `"rbac"` - for role-based access control tests +- `"plugins"` - for plugin functionality tests +- `"configuration"` - for configuration validation tests +- `"audit-log"` - for audit logging tests +- `"core"` - for core functionality tests +- `"navigation"` - for navigation and routing tests +- `"api"` - for API endpoint and integration tests +- `"integration"` - for external service integration tests +- `"monitoring"` - for monitoring and observability tests +- `"data-management"` - for data handling and management tests + +**Note**: The component description should be descriptive and consistent across related test files to ensure proper test organization and reporting. + +#### Key Test Categories + +1. **Smoke Tests** (`smoke-test.spec.ts`) + - Basic functionality verification + - Health checks and core features + +2. **Showcase Tests** (defined in `e2e-tests/playwright/projects.json`) + - `showcase`: General functionality tests with base deployment using Helm chart + - `showcase-rbac`: General functionality tests with RBAC-enabled deployment using Helm chart + - `showcase-k8s`: Kubernetes integration tests with base deployment + - `showcase-rbac-k8s`: Kubernetes integration tests with RBAC-enabled deployment + - `showcase-operator`: General functionality tests with base deployment using Operator + - `showcase-operator-rbac`: General functionality tests with RBAC-enabled deployment using Operator + - `showcase-runtime`: Runtime environment tests + - `showcase-sanity-plugins`: Plugin sanity checks + - `showcase-upgrade`: Upgrade scenario tests + - `showcase-localization-fr`: French localization tests + - `any-test`: Use for debugging when you need to run a specific tests + + **Note**: All project names are defined in `e2e-tests/playwright/projects.json` as the single source of truth. This file is consumed by: + - `playwright.config.ts` via TypeScript import (`e2e-tests/playwright/projects.ts`) + - CI/CD scripts via `.ibm/pipelines/playwright-projects.sh` (exports as `$PW_PROJECT_*` variables) + +3. **Authentication Provider Tests** (`showcase-auth-providers`) + - OIDC (Red Hat Backstage Keycloak) + - Microsoft OAuth2 + - GitHub authentication + - LDAP (Active Directory) + +4. **Plugin Tests** (`playwright/e2e/plugins/`) + - RBAC (Role-Based Access Control) + - Kubernetes actions + - Notifications + - Topology + - Quay integration + - Tekton + - Dynamic plugins info + - Adoption insights + - Analytics + +5. **Configuration Tests** (`playwright/e2e/configuration-test/`) + - Config map validation + - Environment-specific configurations + +6. **Audit Log Tests** (`playwright/e2e/audit-log/`) + - Audit logging functionality + - Compliance verification + +7. **Localization Tests** (`playwright/e2e/localization/`) + - Verify UI displays correctly translated strings + - Currently supports **French (fr)** only + - Runs as part of OCP nightly job (skipped for OSD-GCP) + - Uses `showcase-localization-fr` Playwright project + - Translation files located in `translations/` directory + - Test helper: `e2e-tests/playwright/e2e/localization/locale.ts` + +### Test Execution + +#### CI/CD Pipeline Execution + +In the CI/CD pipeline, tests are executed directly using Playwright's `--project` flag via the `run_tests()` function in `.ibm/pipelines/utils.sh`: + +```bash +yarn playwright test --project="${playwright_project}" +``` + +The namespace and Playwright project are decoupled, allowing flexible reuse. The `check_and_test()` and `run_tests()` functions accept an explicit `playwright_project` argument: + +```bash +# Function signatures: +check_and_test "${RELEASE_NAME}" "${NAMESPACE}" "${PLAYWRIGHT_PROJECT}" "${URL}" [max_attempts] [wait_seconds] +run_tests "${RELEASE_NAME}" "${NAMESPACE}" "${PLAYWRIGHT_PROJECT}" "${URL}" +``` + +#### Local Development Scripts + +Available yarn scripts in `e2e-tests/package.json` for local development: + +```bash +# Showcase tests - OpenShift deployments (Helm) +yarn showcase # General showcase tests +yarn showcase-rbac # General showcase tests with RBAC + +# Showcase tests - Kubernetes deployments +yarn showcase-k8s # Kubernetes showcase tests +yarn showcase-rbac-k8s # Kubernetes showcase tests with RBAC + +# Showcase tests - Operator deployments +yarn showcase-operator # Operator showcase tests +yarn showcase-operator-rbac # Operator showcase tests with RBAC + +# Showcase tests - Other scenarios +yarn showcase-runtime # Runtime configuration tests +yarn showcase-upgrade # Upgrade scenario tests + +# Authentication provider tests +yarn showcase-auth-providers # Auth provider tests + +# Plugin tests +yarn showcase-sanity-plugins # Plugin sanity tests + +# Localization tests +yarn showcase-localization-fr # French localization tests + +# Utility scripts +yarn lint:check # Lint checking +yarn lint:fix # Lint fixing +yarn tsc # TypeScript compilation +yarn prettier:check # Prettier checking +yarn prettier:fix # Prettier fixing +``` + +**Note**: The CI pipeline no longer uses yarn script aliases. Instead, it runs Playwright directly with `yarn playwright test --project=`. This decouples the namespace from the test project name, enabling more flexible namespace and test project reuse. + +### Environment Variables + +All the important environment variables are sourced in `.ibm/pipelines/env_variables.sh` +Most of them are populated by secrets from the Vault. + +⚠️ Important Notice +Do not place any secrets directly into a file. +All sensitive information must be stored in the Vault. + +### Test Configuration + +Playwright configuration (`e2e-tests/playwright.config.ts`): +- **Timeout**: 90 seconds global, 10-15 seconds for actions +- **Retries**: 2 on CI, 0 locally +- **Workers**: 3 parallel workers +- **Viewport**: 1920x1080 +- **Video**: Enabled for all tests +- **Screenshots**: Only on failure +- **Trace**: Retain on failure + +### Key Differences: showcase-auth-providers vs Other Showcase Projects + +The `showcase-auth-providers` project has several significant differences from other showcase projects, particularly in deployment and configuration: + +#### **Namespace and Release Management** +- **Other Showcase Projects**: Use standard namespace patterns (`showcase-ci-nightly`, `showcase-rbac-nightly`) +- **showcase-auth-providers**: Uses dedicated namespace `showcase-auth-providers` and release `rhdh-auth-providers` +- **Logging**: Dedicated logs folder: `e2e-tests/auth-providers-logs` + +#### **Test Retry Configuration** +- **Other Showcase Projects**: Typically use 2 retries (CI default) +- **showcase-auth-providers**: Configured with only 1 retry due to the complexity of authentication provider setup and teardown + +#### **Configuration and Deployment Approach** +- **Other Showcase Projects**: Use Bash scripts for configuration and deployment +- **showcase-auth-providers**: Uses TypeScript for configuration and deployment management +- **Configuration Files**: Uses different configuration files compared to other showcase projects: + - `e2e-tests/playwright/e2e/auth-providers/` directory structure with TypeScript test files + - Dedicated values file: `.ibm/pipelines/value_files/values_showcase-auth-providers.yaml` + - TypeScript-based test configuration instead of Bash scripts + - Dynamic RHDH instance management (create, update, restart, delete) + +#### **Required Plugins and Dependencies** +- **Other Showcase Projects**: Standard plugin dependencies +- **showcase-auth-providers**: Requires specific plugins exported to `dynamic-plugins-root`: + - `backstage-community-plugin-catalog-backend-module-keycloak-dynamic` + - `backstage-plugin-catalog-backend-module-github-org-dynamic` + - `backstage-plugin-catalog-backend-module-msgraph-dynamic` + - `backstage-community-plugin-rbac` + +#### **Authentication Provider Coverage** +- **Other Showcase Projects**: Standard authentication testing +- **showcase-auth-providers**: Tests multiple authentication providers: + - OIDC using Red Hat Backstage Keycloak (RHBK) + - Microsoft OAuth2 provider + - GitHub authentication + - LDAP using Active Directory (commented out) + +#### **Test Structure and Files** +- **Other Showcase Projects**: Standard test file patterns +- **showcase-auth-providers**: Dedicated test structure: + - `e2e-tests/playwright/e2e/auth-providers/` directory + - Individual test files: `oidc.spec.ts`, `microsoft.spec.ts`, `github.spec.ts`, `ldap.spec.ts` + - Tests verify: supported resolvers, user/group ingestion, nested groups, session token configuration + +These differences make `showcase-auth-providers` a specialized testing environment focused on validating authentication provider integrations rather than general RHDH functionality testing. + +## CI/CD Infrastructure + +### OpenShift CI Overview + +The RHDH CI/CD pipeline uses **OpenShift CI** with **Prow-based** automation and **ephemeral clusters** for testing. + +Check the readme at `.ibm/pipelines/README.md` + +#### Key Components + +1. **Ephemeral Clusters**: AWS-based clusters in `us-east-2` region +2. **Cluster Management**: Managed via cluster claims +3. **CI Job Types**: OCP, EKS, GKE, AKS environments +4. **Authentication**: Keycloak as default provider +5. **Secrets Management**: Vault-managed secrets + +### Cluster Pools + +Available cluster pools for different OCP versions: + +- **RHDH-4-19-US-EAST-2** + - Usage: OCP v4.19 nightly jobs + - [Cluster Pool Configuration](https://github.com/openshift/release/blob/master/clusters/hosted-mgmt/hive/pools/rhdh/rhdh-ocp-4-19-0-amd64-aws-us-east-2_clusterpool.yaml) + +- **RHDH-4-18-US-EAST-2** + - Usage: OCP v4.18 nightly jobs + - [Cluster Pool Configuration](https://github.com/openshift/release/blob/master/clusters/hosted-mgmt/hive/pools/rhdh/rhdh-ocp-4-18-0-amd64-aws-us-east-2_clusterpool.yaml) + +- **RHDH-4-17-US-EAST-2** + - Usage: PR checks on main branch and OCP v4.17 nightly jobs + - [Cluster Pool Configuration](https://github.com/openshift/release/blob/master/clusters/hosted-mgmt/hive/pools/rhdh/rhdh-ocp-4-17-0-amd64-aws-us-east-2_clusterpool.yaml) + +- **RHDH-4-16-US-EAST-2** + - Usage: OCP v4.16 nightly jobs + - [Cluster Pool Configuration](https://github.com/openshift/release/blob/master/clusters/hosted-mgmt/hive/pools/rhdh/rhdh-ocp-4-16-0-amd64-aws-us-east-2_clusterpool.yaml) + +**Note:** This is subject to change. Use `.ibm/pipelines/README.md` as a source of truth. + +### CI Job Types + +#### Pull Request Tests +- **Trigger**: Automatic for code changes, manual with `/ok-to-test` +- **Environment**: Ephemeral OpenShift cluster +- **Scope**: Both RBAC and non-RBAC namespaces +- **Artifacts**: 6-month retention period + +#### Nightly Tests +- **Schedule**: Automated nightly runs +- **Environments**: Multiple OCP versions, AKS, GKE +- **Reporting**: Slack notifications to `#rhdh-e2e-test-alerts` + +### Test Execution Environment + +#### Local Development +Tests are run directly using Playwright Test with Node.js 22 and Yarn 3.8.7 as specified in the technology stack above. + +#### CI/CD Pipeline Execution +For CI/CD pipeline execution, tests run in a containerized environment using the image `.ibm/images/Dockerfile`. This image is based on `mcr.microsoft.com/playwright` and uses Ubuntu as the base operating system. + +**Note**: Any additional system dependencies required for testing must be installed in this Docker image to ensure CI/CD pipeline compatibility. + +#### Alternative Execution Methods +**Podman Usage**: If you need to prepare the environment or run tests close to how CI/CD pipeline runs them, you can use Podman to run the `.ibm/pipelines/openshift-ci-tests.sh` script inside the Docker image. + +**RHEL/Fedora Systems**: On Playwright unsupported systems such as RHEL or Fedora, running tests inside the containerized environment using Podman is the recommended approach to avoid compatibility issues. + +### Key CI Scripts + +#### Main Orchestration +- **`.ibm/pipelines/openshift-ci-tests.sh`**: Main test orchestration script +- **`.ibm/pipelines/utils.sh`**: Utility functions +- **`.ibm/pipelines/reporting.sh`**: Reporting and notifications +- **`.ibm/pipelines/env_variables.sh`**: Environment variable management +- **`.ibm/pipelines/playwright-projects.sh`**: Loads Playwright project names from `projects.json` as `$PW_PROJECT_*` variables + +#### CI Infrastructure Package Configuration + +The `.ibm/package.json` file defines the CI infrastructure package configuration and development tools: + +**Available Scripts:** +```bash +# Code quality and linting +yarn shellcheck # Shell script linting with severity warnings +yarn prettier:check # Check formatting for shell, markdown, and YAML files +yarn prettier:fix # Fix formatting for shell, markdown, and YAML files +``` + +⚠️ **Important**: Before using any of these scripts, you must first run `yarn install` in the `.ibm` folder to install the required dependencies (prettier, prettier-plugin-sh, shellcheck). + +**Purpose**: This package provides essential tooling for maintaining code quality in the CI infrastructure, ensuring consistent formatting and shell script best practices across the pipeline scripts. + +#### Shell Script Conventions + +**Shell scripts in `.ibm/` folder:** +- **Never use** `set pipefail` or `set -o pipefail` +- Only `.ibm/pipelines/openshift-ci-tests.sh` defines global `set` options; other scripts inherit them +- Functions may temporarily disable/re-enable error handling with `set +e` / `set -e` pattern + +#### Job Handlers +The main script handles different job types: +- `handle_aks_helm`: AKS Helm deployment +- `handle_eks_helm`: EKS Helm deployment +- `handle_gke_helm`: GKE Helm deployment +- `handle_ocp_operator`: OCP Operator deployment +- `handle_ocp_nightly`: OCP nightly tests +- `handle_ocp_pull`: OCP PR tests +- `handle_auth_providers`: Auth provider tests + +#### Special Case: showcase-auth-providers Deployment + +The `showcase-auth-providers` project has a unique deployment workflow that differs significantly from other showcase projects: + +**Handler**: `handle_auth_providers()` function in `.ibm/pipelines/jobs/auth-providers.sh` +**Configuration**: Uses dedicated values file `values_showcase-auth-providers.yaml` with auth provider-specific settings +**Test Execution**: Runs TypeScript-based tests from `e2e-tests/playwright/e2e/auth-providers/` directory + +### Access and Debugging + +#### Cluster Access +For cluster pool admins, use the login script: +```bash +.ibm/pipelines/ocp-cluster-claim-login.sh +``` + +#### Debugging Process +1. Run the login script +2. Provide Prow log URL when prompted +3. Script will forward cluster web console URL and credentials +4. Ephemeral clusters are deleted after CI job termination + +### CI Configuration Files + +- **Job Definitions**: [OpenShift Release Jobs](https://github.com/openshift/release/tree/master/ci-operator/jobs/redhat-developer/rhdh) +- **Configuration**: [OpenShift Release Config](https://github.com/openshift/release/tree/master/ci-operator/config/redhat-developer/rhdh) +- **Step Registry**: [OpenShift Release Steps](https://github.com/openshift/release/tree/master/ci-operator/step-registry/redhat-developer/rhdh) + +### Debugging + +#### Local Debugging +```bash +# Set local development flags +export ISRUNNINGLOCAL=true +export ISRUNNINGLOCALDEBUG=true + +# Run tests locally +yarn playwright test --project showcase-auth-providers --workers 1 +``` + +#### CI Debugging +1. **Access Logs**: Check PR artifacts or CI logs +2. **Cluster Access**: Use cluster claim login script +3. **Environment Variables**: Verify required variables +4. **Test Failures**: Review test reports and screenshots + +#### Common Debugging Tools +- **Playwright Inspector**: `yarn playwright test --debug` +- **Trace Viewer**: `yarn playwright show-trace` +- **Screenshots**: Automatic on failure +- **Video Recording**: Available for all tests + +## Key Dependencies and Common Issues + +### System Dependencies + +#### macOS Requirements +**Important**: macOS users need to use GNU `grep` and GNU `sed` instead of the built-in BSD versions to avoid compatibility issues with scripts and CI/CD pipelines. + +Install using Homebrew: +```bash +brew install grep +brew install gnu-sed +``` + +**Important**: Make sure to set the GNU versions as default to ensure they are used instead of the built-in macOS versions. + +**Note**: The built-in macOS versions of these tools may cause issues when running scripts or tests that expect GNU-compatible behavior. + +### External Services + +#### Required Services +- **GitHub**: Authentication, repository access +- **Keycloak**: Default authentication provider +- **OpenShift**: Primary deployment platform +- **Advanced Cluster Management**: For OCM plugins + +### Internal Components + +#### Core Components +- **Backstage**: Main application framework +- **Dynamic Plugins**: Plugin management system +- **Catalog**: Entity management +- **Scaffolder**: Template system + +### Common Issues and Solutions + +#### Test Failures +1. **Environment Issues**: Verify environment variables +2. **Authentication Problems**: Check credentials and tokens +3. **Resource Constraints**: Check cluster resources + +#### CI Failures +1. **Cluster Issues**: Verify cluster availability +2. **Resource Limits**: Check resource quotas +3. **Network Problems**: Verify connectivity +4. **Configuration Errors**: Review job configuration + +#### Plugin Issues +1. **Loading Failures**: Check plugin configuration +2. **Dependency Conflicts**: Verify package versions +3. **Configuration Errors**: Review plugin config +4. **Build Issues**: Check build process + +## Documentation References + +### Core Documentation +- [E2E Testing CI Documentation](docs/e2e-tests/CI.md) +- [Dynamic Plugins Documentation](docs/dynamic-plugins/index.md) +- [Authentication Providers README](e2e-tests/playwright/e2e/auth-providers/README.md) +- [OpenShift CI Pipeline README](.ibm/pipelines/README.md) + +### Configuration Files +- [Playwright Project Names (Single Source of Truth)](e2e-tests/playwright/projects.json) +- [Playwright Configuration](e2e-tests/playwright.config.ts) +- [Package Configuration](e2e-tests/package.json) +- [Dynamic Plugins Config](dynamic-plugins/package.json) +- [CI Test Script](.ibm/pipelines/openshift-ci-tests.sh) + +### External Resources +- [OpenShift CI Documentation](https://docs.ci.openshift.org/) +- [Playwright Documentation](https://playwright.dev/) +- [Red Hat Developer Hub Documentation](https://redhat-developer.github.io/red-hat-developers-documentation-rhdh/main/) +- [Backstage Documentation](https://backstage.io/docs) +- [Dynamic Plugins Guide](https://github.com/backstage/backstage/tree/master/packages/backend-dynamic-feature-service) + +### Key Scripts and Tools +- [Cluster Login Script](.ibm/pipelines/ocp-cluster-claim-login.sh) +- [Test Reporting Script](.ibm/pipelines/reporting.sh) +- [Environment Variables](.ibm/pipelines/env_variables.sh) +- [Dynamic Plugin Installer](docker/install-dynamic-plugins.py) + +## Test Configuration Files (Config Maps) + +### Overview + +The RHDH e2e testing infrastructure uses two main configuration files located in `.ibm/pipelines/resources/config_map/`: + +1. **`app-config-rhdh.yaml`** - Non-RBAC configuration +2. **`app-config-rhdh-rbac.yaml`** - RBAC-enabled configuration + +### Config Map Usage Pattern + +The choice of config map depends on the **Playwright test project** being executed, as defined in `e2e-tests/playwright.config.ts`: + +#### **app-config-rhdh.yaml** (Non-RBAC Configuration) + +**Used for test projects that exclude RBAC testing:** + +- `smoke-test` - Basic smoke tests +- `showcase` - General functionality tests (explicitly excludes RBAC tests) +- `showcase-k8s` - Kubernetes integration tests (explicitly excludes RBAC tests) +- `showcase-operator` - Operator-based tests (explicitly excludes RBAC tests) +- `showcase-runtime` - Runtime environment tests +- `showcase-sanity-plugins` - Plugin sanity tests +- `showcase-upgrade` - Upgrade scenario tests +- `showcase-localization-fr` - French localization tests +- `showcase-auth-providers` - Authentication provider tests (uses special deployment process) + +#### **app-config-rhdh-rbac.yaml** (RBAC Configuration) + +**Used for test projects that include RBAC testing:** + +- `showcase-rbac` - RBAC-specific tests +- `showcase-rbac-k8s` - Kubernetes + RBAC tests +- `showcase-operator-rbac` - Operator + RBAC tests + +### **CRITICAL RULE: Config Map Selection** + +**When adding new tests:** + +1. **Identify the test project scope:** + - Will the new test/plugin be tested with RBAC? → Use `app-config-rhdh-rbac.yaml` + - Will the new test/plugin be tested without RBAC? → Use `app-config-rhdh.yaml` + +2. **Check the Playwright project configuration:** + - Projects that exclude RBAC tests (using `testIgnore` for RBAC patterns) → Use `app-config-rhdh.yaml` + - Projects that include RBAC tests (using `testMatch` for RBAC patterns) → Use `app-config-rhdh-rbac.yaml` + +### **Special Cases** + +1. **showcase-auth-providers**: Although it uses the non-RBAC config pattern, it has its own specialized deployment process with dedicated values file (`values_showcase-auth-providers.yaml`) and TypeScript-based configuration management. + +### **Configuration Deployment Process** + +The config maps are deployed as Kubernetes ConfigMaps during CI/CD pipeline execution and are mounted into the RHDH pods to provide runtime configuration. The pipeline selects the appropriate config map based on the test project being executed. + +--- diff --git a/.claude/rules/managing-ai-rules.md b/.claude/rules/managing-ai-rules.md new file mode 100644 index 0000000000..780fc60736 --- /dev/null +++ b/.claude/rules/managing-ai-rules.md @@ -0,0 +1,377 @@ +--- +paths: '.rulesync/**, .cursor/**, .claude/**' +--- +# Managing AI Assistant Rules + +This document provides guidelines for creating, importing, and managing AI assistant rules, commands, and configurations. + +## 📁 Directory Structure + +```text +.rulesync/ +├── rules/ # Rule files (.md files with frontmatter) +├── commands/ # Command files (.md files with frontmatter) +└── README.md # Documentation +``` + +## 🤖 Automated Checks + +A GitHub Actions workflow (`.github/workflows/rulesync-check.yaml`) automatically validates that generated files in `.cursor` and `.claude` are in sync with `.rulesync` on: +- All pull requests +- Pushes to main and release branches + +**What it checks:** +- Runs `yarn rulesync:generate` +- Compares generated files with committed files +- Fails if there are differences + +**If the check fails, run the appropriate command based on what you edited:** + +```bash +# If you forgot to generate from .rulesync +yarn rulesync:generate +git add .cursor .claude + +# If you edited .cursor files directly +yarn rulesync:import:cursor +git add .rulesync + +# If you edited .claude files directly +yarn rulesync:import:claude +git add .rulesync + +# Then commit and push +git commit --amend --no-edit +git push --force-with-lease +``` + +## ✨ Creating New Rules + +### Step 1: Create the Rule File + +Create a new markdown file in `.rulesync/rules/`: + +```bash +# Example: Create a new rule for API development +touch .rulesync/rules/api-development.md +``` + +### Step 2: Add Frontmatter + +Every rule file must have YAML frontmatter: + +```yaml +--- +targets: + - '*' # Target all AI assistants +root: false # Context-aware (not always loaded) +description: >- + Brief description of what this rule covers +globs: # File patterns when this rule applies + - src/api/** + - tests/api/** +cursor: # Cursor-specific configuration + alwaysApply: false + description: >- + Brief description of what this rule covers + globs: + - src/api/** + - tests/api/** +claude: # Claude-specific configuration (optional) + description: >- + Brief description of what this rule covers +--- +``` + +### Step 3: Write the Rule Content + +After the frontmatter, write your rule in markdown: + +```markdown +# API Development Guidelines + +## Overview + +This rule provides guidelines for developing APIs in this project. + +## Best Practices + +1. **Use TypeScript** - All API code must be in TypeScript +2. **Validate inputs** - Use zod schemas for validation +3. **Document endpoints** - Include JSDoc comments + +## Examples + +\`\`\`typescript +// Good example +export async function getUser(id: string): Promise { + // Implementation +} +\`\`\` +``` + +### Step 4: Generate Configurations + +After creating or editing the rule: + +```bash +# This happens automatically on commit, but you can run manually: +yarn rulesync:generate + +# Then stage and commit +git add .rulesync/rules/api-development.md .cursor .claude +git commit -m "docs: add API development rule" +``` + +## 📥 Importing Existing Rules + +### Scenario 1: Rules Already Exist in `.cursor` + +If you have existing rules in `.cursor/rules/*.mdc`: + +```bash +# 1. Import all rules from Cursor +yarn rulesync:import:cursor + +# 2. Review the imported files in .rulesync + +# 3. Edit if needed to match the proper format +``` + +### Scenario 2: Rules Already Exist in `.claude` + +If you have existing rules in `.claude/memories/*.md`: + +```bash +# 1. Import all rules from Claude +yarn rulesync:import:claude + +# 2. Review the imported files in .rulesync + +# 3. Edit if needed to match the proper format +``` + +## 🎯 Creating Commands + +Commands are similar to rules but define specific agent commands. + +### Step 1: Create Command File + +```bash +touch .rulesync/commands/analyze-code.md +``` + +### Step 2: Add Frontmatter and Content + +```markdown +--- +description: Analyze code quality and provide suggestions +targets: ["*"] +--- + +# Analyze Code Command + +Execute the following steps: + +1. Read the target files +2. Check for: + - Code smells + - Security issues + - Performance problems +3. Provide actionable suggestions +``` + +## 📋 Frontmatter Field Reference + +### Required Fields + +- **`targets`** - Array of AI assistants to target + - `["*"]` - All assistants + - `["cursor"]` - Cursor only + - `["claudecode"]` - Claude Code only + - `["cursor", "copilot"]` - Multiple specific assistants + +- **`description`** - Brief description of the rule/command + +### Optional Fields + +- **`root`** - Boolean, whether to always load this rule + - `true` - Always loaded (root-level rule) + - `false` - Context-aware (loaded based on globs) + +- **`globs`** - Array of file patterns when to apply this rule + ```yaml + globs: + - "src/**/*.ts" + - "tests/**/*.spec.ts" + ``` + +- **`cursor`** - Cursor-specific configuration + ```yaml + cursor: + alwaysApply: false + description: "Rule description" + globs: + - "path/**" + ``` + +- **`claude`** - Claude-specific configuration + ```yaml + claude: + description: "Rule description" + ``` + +## 🚫 What NOT to Do + +### ❌ Don't Edit Generated Files in `.cursor` and `.claude` Directly + +Instead, edit the source in `.rulesync/` and then regenerate them: + +```bash +yarn rulesync:generate # Regenerate (or commit to auto-generate) +``` + +### ❌ Don't Forget Frontmatter + +Every rule must have proper frontmatter. Without it, rulesync cannot process the file. + +### ❌ Don't Use Absolute Paths in Globs + +```yaml +# BAD +globs: + - /Users/username/project/src/** + +# GOOD - Use relative paths +globs: + - src/** +``` + +## 🔄 Synchronization Workflow + +### Normal Workflow (Recommended) + +```bash +# 1. Edit source files +vim .rulesync/rules/my-rule.md + +# 2. Stage and commit +git add .rulesync/rules/my-rule.md +git commit -m "docs: update my-rule" +# ✨ Auto-generates .cursor/.claude on commit +``` + +### If You Edited .cursor or .claude Directly + +```bash +# 1. Commit your changes (you'll see a notification) +git add .cursor/rules/my-rule.mdc +git commit -m "docs: update rule" + +# 2. You'll see: +# ⚠️ Direct changes to .cursor detected! +# 💡 To sync back to .rulesync, run: +# yarn rulesync:import:cursor +# git add .rulesync + +# 3. Follow the instructions +yarn rulesync:import:cursor +git add .rulesync +git commit --amend --no-edit +``` + +## 📝 Use `.local.md` for Personal Rules + +For personal or machine-specific rules that shouldn't be committed: + +```bash +# Create a local rule +vim .rulesync/rules/my-personal-setup.local.md + +# This will be ignored by git +git status # Won't show the .local.md file +``` + +Local files: +- ✅ `.rulesync/rules/*.local.md` - Ignored +- ✅ `.cursor/rules/*.local.mdc` - Ignored +- ✅ `.claude/**/*.local.md` - Ignored +- ✅ `.claude/settings.local.json` - Ignored + +## 🎓 Examples + +### Example 1: Simple Rule + +```yaml +--- +targets: ["*"] +root: false +description: Use async/await instead of promises +globs: + - "src/**/*.ts" +cursor: + alwaysApply: false +--- + +# Async/Await Guidelines + +Always use async/await instead of raw promises for better readability. +``` + +### Example 2: Cursor-Only Rule + +```yaml +--- +targets: ["cursor"] +root: false +description: Cursor-specific keyboard shortcuts +globs: ["**/*"] +cursor: + alwaysApply: true +--- + +# Cursor Shortcuts + +- Cmd+K - AI chat +- Cmd+L - Inline edit +``` + +### Example 3: Root-Level Rule (Always Loaded) + +```yaml +--- +targets: ["*"] +root: true +description: Project-wide coding standards +--- + +# Coding Standards + +These standards apply to all code in this repository... +``` + +## 🔗 Related Documentation + +- [Rulesync README](../README.md) +- [Rulesync GitHub](https://github.com/dyoshikawa/rulesync) +- [Configuration File](../../rulesync.jsonc) + +## ❓ Troubleshooting + +### Problem: Rules not loading in AI Assistant (Cursor, Claude Code, ...) + +**Solution:** +1. Check frontmatter is valid YAML +2. Run `yarn rulesync:generate` +3. Restart the AI Assistant + +### Problem: Import doesn't work + +**Solution:** +1. Check the files exist in `.cursor` or `.claude` +2. Ensure they have proper format +3. Run with specific target: `yarn rulesync:import:cursor` + +### Problem: Git shows changes after generate + +**Solution:** This is expected! The generated files should be committed along with the source files. diff --git a/.claude/rules/playwright-locators.md b/.claude/rules/playwright-locators.md new file mode 100644 index 0000000000..11ff82d555 --- /dev/null +++ b/.claude/rules/playwright-locators.md @@ -0,0 +1,164 @@ +--- +paths: e2e-tests/** +--- +# Playwright Locator Best Practices + +## Locator Priority (Use in Order) + +1. **`page.getByRole(role, { name })`** - Interactive elements, headings (reflects user perception) +2. **`page.getByLabel(text)`** - Form controls with labels +3. **`page.getByPlaceholder(text)`** - Inputs without labels +4. **`page.getByText(text)`** - Non-interactive content only (avoid for buttons/links - use getByRole instead) +5. **`page.getByAltText(text)`** - Images +6. **`page.getByTitle(text)`** - Elements with title attribute +7. **`page.getByTestId(id)`** - When semantic locators unavailable (uses `data-testid` attribute only) +8. **`page.locator(selector)`** - Avoid CSS/XPath unless necessary + +## Quick Examples + +```typescript +// ✅ GOOD - Semantic locators +await page.getByRole('button', { name: 'Submit' }).click(); +await page.getByLabel('Username').fill('admin'); +await page.getByPlaceholder('Search...').type('test'); +await expect(page.getByText('Welcome')).toBeVisible(); + +// ✅ GOOD - Filtering and chaining +await page.getByRole('row') + .filter({ hasText: 'Guest User' }) + .getByRole('button', { name: 'Edit' }) + .click(); + +// ❌ BAD - Using getByText for interactive elements +await page.getByText('Submit').click(); // Use getByRole('button', { name: 'Submit' }) instead + +// ❌ BAD - Implementation-dependent selectors +await page.locator('.MuiButton-label').click(); +await page.locator('div:nth-child(3)').click(); +await page.locator('//*[@id="form"]/div[2]/input').fill('test'); +``` + +## Anti-Patterns + +- ❌ CSS class selectors (`.MuiButton-label`, `[class*="MuiTableCell"]`, `.MuiDataGrid-*`) +- ❌ Long XPath chains +- ❌ `nth-child` without semantic context +- ❌ Using `force: true` to bypass checks +- ❌ Mixing locator strategies inconsistently +- ❌ Using getByText for buttons or links (use getByRole instead) +- ❌ Targeting dynamically generated text (dynamic status, timestamps) +- ❌ Configuring custom test ID attributes (stick with `data-testid` only) +- ❌ Selecting elements without scoping (may match from wrong card/dialog) + +## Assertions with Auto-Waiting + +Playwright assertions automatically wait and retry (default: 5 seconds) until conditions are met. No manual waits needed. + +```typescript +// ✅ Auto-waiting assertions +await expect(page.getByRole('button', { name: 'Submit' })).toBeVisible(); +await expect(page.getByLabel('Status')).toHaveText('Submitted'); +await expect(page.getByRole('list')).toHaveCount(5); + +// ❌ Unnecessary manual waiting +await page.waitForSelector('.status'); // Don't do this, expect() waits automatically +``` + +**Common assertions**: `toBeVisible()`, `toBeHidden()`, `toBeEnabled()`, `toBeDisabled()`, `toBeChecked()`, `toHaveText()`, `toContainText()`, `toHaveValue()`, `toHaveCount()`, `toHaveAttribute()` + +**Auto-checks before actions**: Visible, Stable (not animating), Enabled, Editable, Receives Events (not obscured) + +## Filtering & Chaining + +```typescript +// Filter by text or child elements +const row = page.getByRole('listitem').filter({ hasText: 'Product 2' }); +const card = page.getByRole('article').filter({ + has: page.getByRole('button', { name: 'Delete' }) +}); + +// Narrow scope with chaining +await page.getByTestId('dialog') + .getByRole('button', { name: 'OK' }) + .click(); + +// Handle alternatives with .or() +const btn = page.getByRole('button', { name: 'New' }); +const dialog = page.getByText('Confirm settings'); +await expect(btn.or(dialog).first()).toBeVisible(); +``` + +## Working with DataGrid Tables + +```typescript +// ✅ GOOD - Use role-based locators for grids +await page.getByRole('grid').getByRole('row').filter({ hasText: 'Guest User' }) + .getByRole('button', { name: 'Edit' }) + .click(); + +await page.getByRole('columnheader', { name: 'Name' }).click(); + +// ✅ GOOD - Filter rows by text content +const userRow = page.getByRole('row').filter({ hasText: 'john@example.com' }); +await expect(userRow).toBeVisible(); + +// ✅ GOOD - Scope within specific container to avoid conflicts +await page.getByTestId('users-card') + .getByRole('grid') + .getByRole('row') + .filter({ hasText: 'Active' }) + .click(); + +// ❌ BAD - MUI class names (brittle, changes frequently) +await page.locator('.MuiDataGrid-row').click(); +await page.locator('.MuiDataGrid-columnHeader').click(); +await page.locator('[class*="MuiDataGrid"]').click(); + +// ❌ BAD - Selecting from wrong context +await page.getByRole('row').first().click(); // Could match row from any grid on page +``` + +## Page Objects + +```typescript +// ✅ Return locators, not elements +class CatalogPage { + constructor(private page: Page) {} + + getSearchInput(): Locator { + return this.page.getByPlaceholder('Search'); + } + + getComponentLink(name: string): Locator { + return this.page.getByRole('link', { name }); + } + + async findComponent(searchTerm: string): Promise { + await this.getSearchInput().fill(searchTerm); + await this.getSearchInput().press('Enter'); + } +} +``` + +## Debugging + +```bash +# Generate locators automatically +yarn playwright codegen http://localhost:7007 + +# Debug tests step-by-step +yarn playwright test --debug + +# Or pause in test +await page.pause(); +``` + +## Resources + +- **Full Guide**: `docs/e2e-tests/playwright-locator-best-practices.md` +- **Official Docs**: https://playwright.dev/docs/locators +- **Best Practices**: https://playwright.dev/docs/best-practices + +## Remember + +Good locators reflect how users interact with your app. Ask: "How would a user or screen reader find this element?" diff --git a/.cursor/rules/add_extension_metadata.mdc b/.cursor/rules/add_extension_metadata.mdc index 29d93bca8b..5f1a28e490 100644 --- a/.cursor/rules/add_extension_metadata.mdc +++ b/.cursor/rules/add_extension_metadata.mdc @@ -103,9 +103,9 @@ cd catalog-entities/extensions # Download schemas to temp directory (ajv doesn't support remote schemas well) mkdir -p /tmp/rhdh-schemas -curl -s "https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/main/workspaces/marketplace/json-schema/packages.json" \ +curl -s "https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/main/workspaces/extensions/json-schema/packages.json" \ -o /tmp/rhdh-schemas/packages.json -curl -s "https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/main/workspaces/marketplace/json-schema/plugins.json" \ +curl -s "https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/main/workspaces/extensions/json-schema/plugins.json" \ -o /tmp/rhdh-schemas/plugins.json # Convert YAML to JSON and validate Package against local schema @@ -147,7 +147,7 @@ git commit -m "feat: add {plugin-name} plugin to RHDH extensions - Added Plugin entity with description and metadata # Create PR -gh pr create --title "feat: add {plugin-name} plugin to marketplace" \ +gh pr create --title "feat: add {plugin-name} plugin to extensions" \ --body "## Summary - Added {plugin-name} plugin metadata to Extensions Catalog - Package: \`{npm-package-name}\` version {version} diff --git a/.rulesync/rules/add_extension_metadata.md b/.rulesync/rules/add_extension_metadata.md index 62ed704601..95bf0d4b38 100644 --- a/.rulesync/rules/add_extension_metadata.md +++ b/.rulesync/rules/add_extension_metadata.md @@ -116,9 +116,9 @@ cd catalog-entities/extensions # Download schemas to temp directory (ajv doesn't support remote schemas well) mkdir -p /tmp/rhdh-schemas -curl -s "https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/main/workspaces/marketplace/json-schema/packages.json" \ +curl -s "https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/main/workspaces/extensions/json-schema/packages.json" \ -o /tmp/rhdh-schemas/packages.json -curl -s "https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/main/workspaces/marketplace/json-schema/plugins.json" \ +curl -s "https://raw.githubusercontent.com/redhat-developer/rhdh-plugins/main/workspaces/extensions/json-schema/plugins.json" \ -o /tmp/rhdh-schemas/plugins.json # Convert YAML to JSON and validate Package against local schema @@ -160,7 +160,7 @@ git commit -m "feat: add {plugin-name} plugin to RHDH extensions - Added Plugin entity with description and metadata # Create PR -gh pr create --title "feat: add {plugin-name} plugin to marketplace" \ +gh pr create --title "feat: add {plugin-name} plugin to extensions" \ --body "## Summary - Added {plugin-name} plugin metadata to Extensions Catalog - Package: \`{npm-package-name}\` version {version} From 8c5467510351f27381d8cae4c4f247d163570059 Mon Sep 17 00:00:00 2001 From: ssaikia Date: Thu, 22 Jan 2026 17:40:23 +0530 Subject: [PATCH 4/4] adding artifact dir --- .ibm/pipelines/jobs/ocp-nightly.sh | 4 ++-- .ibm/pipelines/utils.sh | 27 ++++++++++++++------------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/.ibm/pipelines/jobs/ocp-nightly.sh b/.ibm/pipelines/jobs/ocp-nightly.sh index ef455815fb..7cf04b96d5 100644 --- a/.ibm/pipelines/jobs/ocp-nightly.sh +++ b/.ibm/pipelines/jobs/ocp-nightly.sh @@ -63,6 +63,6 @@ run_sanity_plugins_check() { run_localization_tests() { local url="https://${RELEASE_NAME}-developer-hub-${NAME_SPACE}.${K8S_CLUSTER_ROUTER_BASE}" log::section "Running localization tests" - # French (fr) - check_and_test "${RELEASE_NAME}" "${NAME_SPACE}" "${PW_PROJECT_SHOWCASE_LOCALIZATION_FR}" "${url}" + # French (fr) - uses custom artifacts_dir to avoid overwriting main showcase test artifacts + check_and_test "${RELEASE_NAME}" "${NAME_SPACE}" "${PW_PROJECT_SHOWCASE_LOCALIZATION_FR}" "${url}" "" "" "${PW_PROJECT_SHOWCASE_LOCALIZATION_FR}" } diff --git a/.ibm/pipelines/utils.sh b/.ibm/pipelines/utils.sh index b3a5ed1a7f..5bd2b8224a 100755 --- a/.ibm/pipelines/utils.sh +++ b/.ibm/pipelines/utils.sh @@ -727,7 +727,8 @@ run_tests() { local release_name=$1 local namespace=$2 local playwright_project=$3 - local url="${4:-}" + local url=$4 + local artifacts_dir="${5:-${namespace}}" CURRENT_DEPLOYMENT=$((CURRENT_DEPLOYMENT + 1)) save_status_deployment_namespace $CURRENT_DEPLOYMENT "$namespace" @@ -768,19 +769,18 @@ run_tests() { pkill Xvfb || true - # Use namespace for artifact directory to keep artifacts organized by deployment - mkdir -p "${ARTIFACT_DIR}/${namespace}/test-results" - mkdir -p "${ARTIFACT_DIR}/${namespace}/attachments/screenshots" - cp -a "${e2e_tests_dir}/test-results/"* "${ARTIFACT_DIR}/${namespace}/test-results" || true - cp -a "${e2e_tests_dir}/${JUNIT_RESULTS}" "${ARTIFACT_DIR}/${namespace}/${JUNIT_RESULTS}" || true + mkdir -p "${ARTIFACT_DIR}/${artifacts_dir}/test-results" + mkdir -p "${ARTIFACT_DIR}/${artifacts_dir}/attachments/screenshots" + cp -a "${e2e_tests_dir}/test-results/"* "${ARTIFACT_DIR}/${artifacts_dir}/test-results" || true + cp -a "${e2e_tests_dir}/${JUNIT_RESULTS}" "${ARTIFACT_DIR}/${artifacts_dir}/${JUNIT_RESULTS}" || true if [[ "${CI}" == "true" ]]; then - cp "${ARTIFACT_DIR}/${namespace}/${JUNIT_RESULTS}" "${SHARED_DIR}/junit-results-${namespace}.xml" || true + cp "${ARTIFACT_DIR}/${artifacts_dir}/${JUNIT_RESULTS}" "${SHARED_DIR}/junit-results-${artifacts_dir}.xml" || true fi - cp -a "${e2e_tests_dir}/screenshots/"* "${ARTIFACT_DIR}/${namespace}/attachments/screenshots/" || true + cp -a "${e2e_tests_dir}/screenshots/"* "${ARTIFACT_DIR}/${artifacts_dir}/attachments/screenshots/" || true ansi2html < "/tmp/${LOGFILE}" > "/tmp/${LOGFILE}.html" - cp -a "/tmp/${LOGFILE}.html" "${ARTIFACT_DIR}/${namespace}" || true - cp -a "${e2e_tests_dir}/playwright-report/"* "${ARTIFACT_DIR}/${namespace}" || true + cp -a "/tmp/${LOGFILE}.html" "${ARTIFACT_DIR}/${artifacts_dir}" || true + cp -a "${e2e_tests_dir}/playwright-report/"* "${ARTIFACT_DIR}/${artifacts_dir}" || true echo "Playwright project '${playwright_project}' in namespace '${namespace}' RESULT: ${RESULT}" if [ "${RESULT}" -ne 0 ]; then @@ -1256,13 +1256,14 @@ check_and_test() { local namespace=$2 local playwright_project=$3 local url=$4 - local max_attempts=${5:-30} # Default to 30 if not set - local wait_seconds=${6:-30} # Default to 30 if not set + local max_attempts=${5:-30} # Default to 30 if not set + local wait_seconds=${6:-30} # Default to 30 if not set + local artifacts_dir="${7:-${namespace}}" # Default to namespace if not set if check_backstage_running "${release_name}" "${namespace}" "${url}" "${max_attempts}" "${wait_seconds}"; then echo "Display pods for verification..." oc get pods -n "${namespace}" - run_tests "${release_name}" "${namespace}" "${playwright_project}" "${url}" + run_tests "${release_name}" "${namespace}" "${playwright_project}" "${url}" "${artifacts_dir}" else echo "Backstage is not running. Marking deployment as failed and continuing..." CURRENT_DEPLOYMENT=$((CURRENT_DEPLOYMENT + 1))