# M00N Report - Full LLM Reference > Real-time test reporting platform for modern CI/CD pipelines and automation-first QA teams. ## Product Overview M00N Report is a test intelligence platform that replaces traditional test management systems (TestRail, Xray, Zephyr, qTest). It provides real-time WebSocket-powered dashboards, AI-native MCP integration, and flexible deployment options. - Website: https://m00nreport.com - Documentation: https://m00nreport.com/documentation - GitHub: https://github.com/m00n-report - Support: support@m00nreport.com --- ## Playwright Reporter **Package:** `@m00nsolutions/playwright-reporter` **Install:** ```bash npm install @m00nsolutions/playwright-reporter --save-dev ``` **Configuration (playwright.config.ts):** ```typescript import { defineConfig } from '@playwright/test'; export default defineConfig({ reporter: [ ['list'], ['@m00nsolutions/playwright-reporter', { serverUrl: 'https://m00nreport.com', apiKey: process.env.M00N_API_KEY, launch: 'Regression Suite', tags: ['smoke', 'regression'], }], ], }); ``` **Options:** | Option | Type | Required | Description | |--------|------|----------|-------------| | serverUrl | string | Yes | M00N Report server URL | | apiKey | string | Yes | Project API key | | enabled | boolean | No | Enable/disable reporting (default: true) | | launch | string | No | Launch name for grouping runs | | tags | string[] | No | Tags for filtering | | attributes | object | No | Custom key-value metadata | **Environment Variables:** `M00N_SERVER_URL`, `M00N_API_KEY`, `M00N_LAUNCH`, `M00N_TAGS`, `M00N_ENABLED` **Features:** Real-time step streaming, automatic screenshot/video/trace capture, retry tracking, CI/CD auto-detection (GitHub Actions, GitLab CI, Jenkins, Bitbucket, Azure DevOps, CircleCI, Travis CI). --- ## Jest Reporter **Package:** `@m00nsolutions/jest-reporter` **Install:** ```bash npm install @m00nsolutions/jest-reporter --save-dev ``` **Configuration (jest.config.js):** ```javascript module.exports = { reporters: [ 'default', ['@m00nsolutions/jest-reporter', { serverUrl: 'https://m00nreport.com', apiKey: process.env.M00N_API_KEY, launch: 'API Tests', tags: ['api', 'unit'], }], ], }; ``` **Options:** | Option | Type | Required | Description | |--------|------|----------|-------------| | serverUrl | string | Yes | M00N Report server URL | | apiKey | string | Yes | Project API key | | launch | string | No | Launch name for grouping runs | | tags | string[] | No | Tags for filtering | | attributes | object | No | Custom key-value metadata | | debug | boolean | No | Enable debug logging (default: false) | | realtime | boolean | No | Enable real-time streaming (default: true) | | includeConsole | boolean | No | Capture console output (default: false) | | includeCoverage | boolean | No | Include coverage data (default: false) | | includeSnapshots | boolean | No | Track snapshot changes (default: true) | | slowTestThreshold | number | No | Slow test threshold in ms (default: 5000) | **Environment Variables:** `M00N_SERVER_URL`, `M00N_API_KEY`, `M00N_LAUNCH`, `M00N_TAGS`, `M00N_DEBUG` **Features:** Real-time streaming, retry tracking, jest-circus support, snapshot tracking, watch mode, parallel execution, console output capture. --- ## Pytest Reporter **Package:** `m00nreport-pytest` (PyPI, MIT-licensed) **Install:** ```bash pip install m00nreport-pytest ``` The package registers itself as a pytest plugin via the standard `pytest11` entry point, so pytest discovers and loads it automatically once installed - no `conftest.py` wiring, `-p` flag, or config block needed. **Configuration (fastest path - environment variables):** ```bash export M00N_SERVER_URL=https://m00nreport.com # or your self-hosted URL export M00N_API_KEY=m00n_xxxxxxxxxxxxx # your project API key pytest ``` **Configuration (pytest.ini, checked into the repo):** ```ini [pytest] m00n_server_url = https://m00nreport.com m00n_api_key = m00n_xxxxxxxxxxxxx m00n_launch = Nightly Regression m00n_tags = smoke, api ``` Never commit a real API key in `pytest.ini` - keep the key in `M00N_API_KEY`. Precedence, highest wins: CLI flag > `pytest.ini` key > environment variable > default. **Key APIs:** | API | Purpose | |-----|---------| | `from m00n_reporter import step, attach` | `with step("name"): ...` records a named, timed step (supports nesting); `attach("file.png")` attaches a file. | | `@pytest.mark.m00n(case_id=42, tags=[...])` | Links a test to an existing M00N Report test case. The `m00n` marker is auto-registered by the plugin - do not add it to `pytest.ini`'s `markers` list. | | Playwright `page` fixture | Calls made through pytest-playwright's `page` fixture are auto-captured as `pw:api` steps, with a screenshot on failure. Requires both `pytest-playwright` AND `playwright` installed - `pip install m00nreport-pytest[playwright]` pulls in `pytest-playwright` for you; browsers still need a separate `python -m playwright install chromium`. Otherwise this layer is fully inert. | | `pip install pytest-rerunfailures` + `pytest --reruns 3` | Each retry attempt reports as a distinct entry with its own `testId` and an incrementing zero-based `retry` index. | | `--m00n-debug` / `M00N_DEBUG=true` | Verbose `[m00nreport]` logging of every HTTP retry attempt and any final exhaustion. | CI metadata (branch, commit, pipeline, build number/URL) is auto-detected with zero configuration on GitHub Actions, GitLab CI, Jenkins, Bitbucket Pipelines, Azure DevOps, CircleCI, and Travis CI. `pytest-xdist` parallel execution (`-n auto`) is supported and reports as one launch. --- ## NUnit Reporter **Package:** `M00nReport.NUnit` (NuGet, MIT-licensed) + optional `M00nReport.NUnit.Playwright` **Install:** ```bash dotnet add package M00nReport.NUnit # Only if the project already uses Microsoft.Playwright.NUnit: dotnet add package M00nReport.NUnit.Playwright ``` **Activate with one attribute:** ```csharp // AssemblyInfo.cs (or any file in the test project) [assembly: M00nReport.NUnit.M00nReport] ``` No `[SetUpFixture]`, no `ITestEventListener`, no runsettings entry - the attribute is an NUnit `ITestAction` that wires itself into the run automatically. **Configuration (fastest path - environment variables):** ```bash export M00N_SERVER_URL=https://m00nreport.com # or your self-hosted URL export M00N_API_KEY=m00n_xxxxxxxxxxxxx # your project API key dotnet test ``` **Configuration (m00nreport.json, next to the test assembly's build output):** ```json { "serverUrl": "https://m00nreport.com", "apiKey": "m00n_xxxxxxxxxxxxx", "launch": "Nightly Regression", "tags": ["smoke", "api"] } ``` Never commit a real API key - keep it in `M00N_API_KEY`. Precedence, highest wins: environment variable > `m00nreport.json` > built-in default. **Key APIs:** | API | Purpose | |-----|---------| | `M00nStep.Run("name", () => { ... })` | Records a named, timed step; a thrown exception marks it `failed`, a normal return marks it `passed`. | | `M00nAttach.Bytes(bytes, "name.png", "image/png")` / `M00nAttach.File(path)` | Attach a file to the current test. | | `[M00nCaseId(42, "regression", "checkout")]` | Links a test to an existing M00N Report test case. | | `[Retry(3)]` (NUnit built-in) | Each attempt reports as a distinct entry with its own `testId` and a zero-based `retry` index (`TestContext.CurrentContext.CurrentRepeatCount`). | | `M00nPageTest` base class (from `M00nReport.NUnit.Playwright`) | Change ONLY the base class from `PageTest` to `M00nPageTest` - existing `Page.(...)` calls keep working and a curated set of navigation/interaction methods is recorded as `pw:api` steps, with an automatic failure screenshot. Set `M00N_TRACING=retain-on-failure` and/or `M00N_VIDEO=retain-on-failure` for trace/video too. | | `M00N_DEBUG=true` / `"debug": true` | Verbose `[m00nreport]` logging. | Note: NUnit exposes no source file path at runtime, so `filePath` for this reporter is the test's namespace-qualified class name, not a real file path - this is expected, not a bug. CI metadata is auto-detected with zero configuration on the same 7 major providers as the pytest reporter. --- ## MCP Server (AI Integration) **Package:** `@m00nsolutions/mcp-server` **Install:** ```bash npm install @m00nsolutions/mcp-server # Or use npx for one-time execution npx -y @m00nsolutions/mcp-server ``` **Cursor IDE Configuration (.cursor/mcp.json):** ```json { "mcpServers": { "m00n": { "command": "npx", "args": ["-y", "@m00nsolutions/mcp-server"], "env": { "M00N_API_URL": "https://m00nreport.com", "M00N_API_KEY": "m00n_mcp_your_key_here" } } } } ``` **Claude Desktop Configuration:** ```json { "mcpServers": { "m00n": { "command": "npx", "args": ["-y", "@m00nsolutions/mcp-server"], "env": { "M00N_API_URL": "https://m00nreport.com", "M00N_API_KEY": "m00n_mcp_your_key_here" } } } } ``` **Environment Variables:** | Variable | Required | Default | Description | |----------|----------|---------|-------------| | M00N_API_URL | Yes | - | M00N Report API URL | | M00N_API_KEY | Yes | - | MCP API key (starts with `m00n_mcp_`) | | M00N_INSECURE_SSL | No | false | Skip SSL verification (self-hosted) | | M00N_DEBUG | No | false | Enable verbose logging | | M00N_TIMEOUT_MS | No | 30000 | Request timeout in milliseconds | **Capabilities:** - 50 tools: Analytics, test case management, folder management, collections, executions, releases - 8 resources: Projects, project health, flaky tests, failing tests, folder tree, launch reports, test cases, release summaries - 6 prompts: analyze_flaky_tests, debug_test_failure, release_readiness, generate_test_cases, weekly_health_report, investigate_regression --- ## Build Your Own Integration (Ingest API v2) Every M00N Report reporter, including the official Playwright, Jest, Pytest, JUnit 5, and NUnit ones, speaks the same small HTTP API: the ingest v2 protocol. If there is no official reporter for a given language or test runner, a custom integration can be built against this API directly, in any language that can send HTTP requests. **The contract:** the full OpenAPI 3.0 specification is public and machine-readable at `YOUR_SERVER_URL/api/ingest/v2/openapi.json` (e.g. `https://m00nreport.com/api/ingest/v2/openapi.json`) - it is the single source of truth for every field, type, limit, and enum. A human-browsable version is at `https://m00nreport.com/documentation/integration-api/reference`, and the full guide is at `https://m00nreport.com/documentation/integration-api/guide`. **Authentication:** every request except the two health checks carries an `X-API-Key` header (format `m00n_...`). The key alone identifies both the organization and the project - never send a separate project id. **Protocol, in order:** 1. `POST run/start` once per run - the server creates the run and returns `runId` (UUID). Every later call echoes this `runId`. 2. `POST test/start` per test attempt, fire-and-forget - the CLIENT generates `testId` (UUID v4) so steps can stream immediately without waiting for a response. 3. `POST steps/stream` batches of live step events (optional but recommended for real-time UX). Batches may mix tests and runs; max 1000 items per call. 4. `POST attachment/upload` (small files, buffered multipart, <=10MB), `attachment/stream` (large files, streaming multipart, >10MB), or the `attachment/presign` + PUT + `attachment/confirm` trio (direct-to-storage upload), per attachment. 5. `POST test/complete` per test attempt with final status, error, timings, any remaining steps, and attachment descriptors. 6. `POST run/end` once, last. **Retries:** on a retry, send `test/start` and `test/complete` again with the SAME `titlePath`, a NEW `testId`, and `retry` incremented (0-based: first attempt is `retry: 0`, first retry is `retry: 1`, and so on). The dashboard groups every attempt sharing a `titlePath` into one flaky-test history. **titlePath semantics:** `titlePath` is the single field the dashboard uses to derive a test's title, its suite grouping, its FILE badge, and its browser badge. Shape: `[file-or-module, ...suite/describe/class names, test title]`. - The LAST element is always the display title. - Elements between the first and last group the test into suites; the element immediately before the title is shown as the closest enclosing suite. - The FIRST element becomes the FILE badge only when it looks like a file (a path separator, or a trailing extension like `.spec.ts`) - a bare namespace/module segment (e.g. NUnit's root namespace) does not trigger it. - A trailing `[chromium]` / `[firefox]` / `[webkit]` suffix ON THE TITLE STRING (not a separate array element) renders a browser badge. - Never put the run/launch name inside `titlePath` - that belongs in `run/start`'s `launch` field. Examples: Playwright JS raw `test.titlePath()`: `['', 'chromium', 'auth.spec.ts', 'Login', 'valid credentials']`. pytest: `['tests/test_login.py', 'test_valid_credentials[chromium]']`. NUnit: `['MyApp', 'Tests', 'LoginTests', 'ValidCredentials']`. **Limits:** 5000 steps and 100 attachments per `test/complete`; 1000 items per `steps/stream` batch; 200MB per file; 10 files per multipart request; use `attachment/upload` (buffered) for files <=10MB and `attachment/stream` for files >10MB to avoid buffering large files in memory; per-run attachment byte quota by pricing tier (413 `RUN_ATTACHMENT_LIMIT_EXCEEDED` when exceeded). **Health:** two unauthenticated liveness probes are part of the contract: `GET /healthz` and `GET /api/ingest/health` (identical response shape, `{ ok: true, service: "ingest" }`). The official Playwright JS reporter calls `/healthz` with a 2 second timeout before streaming and disables itself for the run if it is unreachable - treat this probe as advisory, not a hard blocker. On the m00nreport.com cloud apex, only `/api/ingest/health` is reachable (only specific path prefixes such as `/api/*` reach the backend there); self-hosted deployments, local development, and direct ingest URLs serve `/healthz` directly. Any server implementing this contract should serve both paths. **Resilience (the iron rule):** a reporter must NEVER fail the test run. Wrap all network calls in try/catch, retry every request that receives a 5xx response (including `test/start`) with exponential backoff, implement a circuit breaker that stops attempting further calls after repeated failures, and degrade silently (log a warning) if the server stays unreachable. **Conformance:** a reporter's traffic is expected to satisfy 12 named invariants - `AUTH_HEADER_PRESENT`, `RUN_START_FIRST`, `RUN_ID_ECHO`, `TESTID_UUID`, `START_BEFORE_COMPLETE`, `COMPLETE_ALL_STARTED`, `RETRY_MONOTONIC`, `RUN_END_ONCE`, `RUN_END_LAST`, `SCHEMA_VALID`, `MULTIPART_FIELDS`, and (under fault injection) `RETRIES_ON_FAILURE`. A conformance suite that checks these lives in the M00N Report repository (`reporter-conformance/`) and will ship as an installable npm package. ### Compact endpoint reference All paths below are relative to the ingest server root (e.g. `https://m00nreport.com` or a self-hosted URL). Full field-level types, enums, and descriptions are in the OpenAPI document. | Method + path | Required fields | Response fields | |---|---|---| | `GET /healthz` | (none, no auth) | `ok`, `service` | | `GET /api/ingest/health` | (none, no auth) | `ok`, `service` | | `POST /api/ingest/v2/run/start` | `launch` | `ok`, `runId` | | `POST /api/ingest/v2/test/start` | `runId`, `testId`, `titlePath` | `ok`, `testId`, `displayId` | | `POST /api/ingest/v2/steps/stream` | `items` (array of StepItem, max 1000) | `ok`, `count` | | `POST /api/ingest/v2/test/complete` | `testId`, `runId`, `status` | `ok` | | `POST /api/ingest/v2/run/end` | `runId` | `ok` | | `POST /api/ingest/v2/attachment/upload` (multipart) | `runId`, `testId`, `file` | `ok`, `attachments[]` (AttachmentResult) | | `POST /api/ingest/v2/attachment/stream` (multipart) | `runId`, `testId`, `file` | `ok`, `attachments[]` (AttachmentResult) | | `POST /api/ingest/v2/attachment/presign` | (none required; `check`, `runId`, `testId`, `filename`, `contentType`, `size` accepted) | capability check: `supported`, `maxSize`, `reason`, `runQuota`; OR presign: `url`, `attachmentId`, `objectName`, `bucket`, `expiresIn`, `runQuota` | | `POST /api/ingest/v2/attachment/confirm` | `runId`, `testId`, `attachmentId`, `filename` | `success`, `attachmentId`, `objectName` | `test/start` and `test/complete` both also accept the optional fields `filePath`, `retry`, `startedAt` (and `test/complete` additionally: `titlePath`, `annotations`, `endedAt`, `duration`, `error`, `steps[]`, `attachments[]`). `run/start` also accepts optional `tags[]`, `total`, `startedAt`, `attributes`, `metadata`. `run/end` also accepts optional `status`, `endedAt`. StepItem (used in `steps/stream`'s `items[]`): required `runId`, `testId`, `title`; optional `action` (`begin`|`end`), `status`, `category`, `duration`, `error`, `nestingLevel`, `stepIndex`. EmbeddedStep (used in `test/complete`'s `steps[]`, a DIFFERENT shape - no `runId`/`testId` per item): all fields optional, `title`, `category`, `status`, `duration`, `error`, `nestingLevel`, `index` (falls back to array position if omitted), `stepIndex` (accepted as an alias for `index`). ### AI prompt: build a reporter for any language or test runner The following is a complete, self-contained prompt for an AI coding assistant to build a custom M00N Report integration in any language or test runner. It is also available as a copy-paste Collapse block on the "Build your own integration" guide page in the app (`https://m00nreport.com/documentation/integration-api/guide`). NOTE: keep this prompt in sync with the `AI_REPORTER_BUILDER_PROMPT` constant in `src/components/docs/sections/integrations/BuildYourOwnIntegration.jsx`. # Build a M00N Report reporter for MY_TEST_RUNNER You are an AI assistant helping me build a custom M00N Report integration for a test runner or language that does not have an official M00N Report reporter yet. Follow this guide end to end. Do not skip the resilience requirements - they are acceptance criteria, not suggestions. ## Before you write any code, ask me for 1. `YOUR_SERVER_URL` - the M00N Report server URL (e.g. `https://m00nreport.com`, or a self-hosted URL). 2. `YOUR_API_KEY` - a project API key, format `m00n_...`. 3. `YOUR_TEST_RUNNER_NAME_AND_LANGUAGE` - the exact test framework, language, and version (e.g. "Go testing package", "RSpec 3.12", "Robot Framework 7"). 4. `YOUR_HOOK_MECHANISM` - how that runner exposes lifecycle hooks (listener interface, plugin API, reporter interface) so results can be reported without editing every individual test file. Wait for my answers before generating code. ## Step 0 - Read the contract Fetch `YOUR_SERVER_URL/api/ingest/v2/openapi.json` (a public, unauthenticated GET). It is the single source of truth for every field name, type, limit, and enum below. If anything below conflicts with the fetched document, the document wins. ## Authentication Every request below except the two health checks carries: ``` X-API-Key: YOUR_API_KEY ``` The key alone identifies both the organization and the project - never send a separate project id. ## Lifecycle: 6 core endpoints, in this order 1. `POST YOUR_SERVER_URL/api/ingest/v2/run/start` - ONCE, first. Body: `{ launch (string, required), tags (string[]), total (number), startedAt (ISO 8601), attributes (object), metadata (object) }`. Response: `{ ok, runId }` - store `runId`, echo it in every later call. 2. `POST YOUR_SERVER_URL/api/ingest/v2/test/start` - once per test attempt, fire-and-forget (do not block the test on the response). Body: `{ runId, testId, titlePath (array, required - see titlePath rules below), filePath, retry, startedAt }`. YOU (the client) generate `testId` as a fresh UUID v4 - never reuse one, even across a retry. 3. `POST YOUR_SERVER_URL/api/ingest/v2/steps/stream` - optional but recommended, batched. Body: `{ items: StepItem[] }`, max 1000 items per call. StepItem: `{ runId, testId, title (required), action ('begin'|'end'), status, category, duration (ms), error, nestingLevel (0-based depth), stepIndex (stable per-test index) }`. Recommended cadence: flush every ~200ms or every ~100 buffered items, whichever comes first - keeps the dashboard live without hammering the server. GOTCHA: this endpoint's field is `stepIndex`. The separate steps array embedded inside `test/complete` (below) uses `index` instead, falling back to array position if omitted, with `stepIndex` accepted only as an alias there. Do not mix the two field names up between the two call sites. 4. Attachments - upload each file with ONE of these three paths: - `POST .../attachment/upload` (multipart form: `runId`, `testId`, one or more `file` parts) - buffered in memory, use for files <=10MB. - `POST .../attachment/stream` (same multipart shape) - streamed to storage without buffering, use for files >10MB. - OR `POST .../attachment/presign` `{ runId, testId, filename, contentType, size }` -> `{ url, attachmentId }`, PUT the file bytes to `url`, then `POST .../attachment/confirm` `{ runId, testId, attachmentId, filename, contentType, size }`. Hard caps: 200MB per file, 10 files per multipart request, plus a per-run attachment byte quota (413 `RUN_ATTACHMENT_LIMIT_EXCEEDED` when exceeded - treat this as non-fatal: log a warning and continue the run). 5. `POST YOUR_SERVER_URL/api/ingest/v2/test/complete` - once per test attempt, after its `test/start`. Body: `{ testId, runId, status (required, enum: passed|failed|skipped|timedOut|timedout|interrupted), titlePath, filePath, annotations, retry, startedAt, endedAt, duration (ms), error, steps[] (EmbeddedStep - any steps not already sent via steps/stream), attachments[] (EmbeddedAttachment, base64 inline - leave empty if files were uploaded separately in step 4, which is the default and preferred path) }`. 6. `POST YOUR_SERVER_URL/api/ingest/v2/run/end` - EXACTLY ONCE, last, after every `test/complete`. Body: `{ runId (required), status (enum: passed|failed|timedOut|timedout|interrupted|finished|completed), endedAt }`. ## testId / runId rules - `runId` is server-generated, returned once by `run/start`. Every later call in the run echoes that SAME `runId`. - `testId` is a client-generated UUID v4, one per TEST ATTEMPT (a retried test gets a NEW `testId` per attempt, not one shared `testId`). It is generated client-side specifically so `steps/stream` can start before `test/start`'s response comes back. ## Retry semantics On a retry: keep the SAME `titlePath`, generate a NEW `testId`, and set `retry` to the previous attempt's `retry` plus 1 (0-based, so a test's first attempt is `retry: 0`, its first retry is `retry: 1`, and so on). The dashboard groups every attempt sharing a `titlePath` into one flaky-test history. ## titlePath rules `titlePath` is an array: `[file-or-module, ...suite/describe/class names, test title]`. - The LAST element is always the test's display title. - Elements between the first and the last group the test into suites in the dashboard; the element immediately before the title is shown as its closest enclosing suite. - The FIRST element becomes the dashboard's FILE badge only when it looks like a file (contains a path separator, or ends in a short extension such as `.spec.ts`) - a bare namespace or module segment does not trigger it. - A trailing `[chromium]` / `[firefox]` / `[webkit]` suffix ON THE TITLE STRING ITSELF (not a separate array element) renders a browser badge. - Never put the run/launch name inside `titlePath` - that belongs in `run/start`'s `launch` field. Examples from existing ecosystems (adapt the shape to your runner, do not copy verbatim): - Playwright JS raw `test.titlePath()`: `['', 'chromium', 'auth.spec.ts', 'Login', 'valid credentials']` - pytest: `['tests/test_login.py', 'test_valid_credentials[chromium]']` - NUnit: `['MyApp', 'Tests', 'LoginTests', 'ValidCredentials']` ## Resilience - ACCEPTANCE CRITERIA, not suggestions 1. The reporter must NEVER fail or crash the test run. Wrap every network call in try/catch (or your language's equivalent) - a reporting failure is a logged warning, never an exception that reaches the test framework. 2. Retry every request that receives a 5xx response, INCLUDING `test/start` (its fire-and-forget nature does not exempt it from retry-with-backoff), using exponential backoff. 3. Implement a circuit breaker: after N consecutive failures (e.g. 3-5), stop attempting further ingest calls for the rest of the run and degrade silently, rather than retrying forever and delaying every test. 4. Treat `GET YOUR_SERVER_URL/api/ingest/health` (no auth required) as an ADVISORY pre-flight probe only. An unreachable or non-200 response is informational, not a hard blocker - it is reasonable (and is what the official Playwright JS reporter does) to disable the reporter for the run when the probe fails, but never let the probe itself throw or delay tests. ## Definition of done - 12 conformance invariants A conformant reporter's traffic passes all 12 named checks the M00N Report conformance suite runs against a recorded session. Use them as your test plan even if the conformance package is not attached to this project directly: 1. `AUTH_HEADER_PRESENT` - every request carries `X-API-Key` starting with `m00n_` 2. `RUN_START_FIRST` - `run/start` is the first ingest call 3. `RUN_ID_ECHO` - every `runId` used was previously issued by `run/start` 4. `TESTID_UUID` - every `testId` is a valid UUID 5. `START_BEFORE_COMPLETE` - `test/start` precedes `test/complete` for the same `testId` 6. `COMPLETE_ALL_STARTED` - every started test is eventually completed 7. `RETRY_MONOTONIC` - `retry` starts at 0 and increments by 1 per attempt of the same `titlePath` 8. `RUN_END_ONCE` - `run/end` is called exactly once per run 9. `RUN_END_LAST` - no ingest calls happen for a run after its `run/end` 10. `SCHEMA_VALID` - every JSON body validates against the OpenAPI request schema for its path 11. `MULTIPART_FIELDS` - multipart uploads carry `runId` and `testId` fields 12. `RETRIES_ON_FAILURE` - any request that received an injected or transient failure was retried and eventually succeeded ## Step-by-step 1. Ask me for `YOUR_SERVER_URL`, `YOUR_API_KEY`, and the runner specifics above; wait for my answer. 2. Fetch and read the OpenAPI document. 3. Identify the runner's hook/listener/plugin mechanism for: run start, per-test start, per-step events (if the runner exposes them), per-test finish, and run end. 4. Implement the 6 calls above behind that mechanism, generating `testId`/`runId` per the rules above. 5. Implement the resilience acceptance criteria: retry with backoff, circuit breaker, never-fail. 6. Wire up attachment upload for screenshots, logs, or traces the runner already captures, if any. 7. Run a small suite - including at least one intentionally failing test and one retried test - and confirm in the M00N Report dashboard: the run appears, tests show correct pass/fail/skip status, steps (if implemented) appear nested and in order, retries show as separate grouped attempts, and attachments are viewable. --- ## Self-Hosted Deployment M00N Report can be self-hosted at no additional cost using Docker Compose or Kubernetes. **Docker Compose (quickstart):** ```bash git clone https://github.com/m00nreport/m00nreport cd m00nreport/examples/self-hosted docker compose up -d ``` **Kubernetes:** Helm charts and k3d examples are included in the repository. **MCP with self-hosted instance:** ```json { "env": { "M00N_API_URL": "https://your-m00n-instance.company.com", "M00N_API_KEY": "m00n_mcp_your_key_here" } } ``` --- ## CI/CD Auto-Detection The official reporters automatically detect CI/CD environments and capture metadata: | Field | Recognized Variables | |-------|---------------------| | Pipeline | `pipeline`, `GITHUB_WORKFLOW`, `CI_PIPELINE_NAME`, `JOB_NAME` | | Branch | `branch`, `git_branch`, `GITHUB_REF`, `CI_COMMIT_REF_NAME`, `BRANCH_NAME` | | Commit | `commit`, `git_commit`, `GITHUB_SHA`, `CI_COMMIT_SHA`, `GIT_COMMIT` | | Build Number | `build_number`, `GITHUB_RUN_NUMBER`, `CI_PIPELINE_ID`, `BUILD_NUMBER` | | Build URL | `build_url`, `GITHUB_SERVER_URL`, `CI_PIPELINE_URL`, `BUILD_URL` | | Environment | `environment`, `env`, `DEPLOY_ENV` | | Trigger | `trigger`, `GITHUB_EVENT_NAME`, `CI_PIPELINE_SOURCE` | --- ## Test Case Management M00N Report provides a structured repository for test definitions with hierarchical organization, metadata, and linking between manual and automated tests. ### Organization - **Folders:** Hierarchical folder structure for organizing test cases. Folders can contain cases and nested suites. - **Display IDs:** Each case gets a sequential display ID (e.g., TC-1, TC-42) unique within its project. - **Tags:** Array of string tags per case for filtering and categorization. - **Custom Fields:** Project-level custom field definitions supporting types: text, number, select, multiselect, boolean, date. ### Case Structure Each test case contains: | Field | Description | |-------|-------------| | Title | Case name | | Description | Rich text description | | Steps | Ordered list of steps, each with a title and expected result | | Status | Customizable per project (e.g., draft, active, deprecated) | | Priority | Customizable per project (e.g., low, medium, high, critical) | | Tags | Array of string labels | | Custom Fields | Key-value pairs matching project field definitions | | Dependencies | Links to other cases this case depends on | ### Bulk Operations - **Bulk create:** Create multiple cases in a single request - **Bulk update:** Update status, priority, tags, or folder for multiple cases at once - **Bulk clone:** Clone cases with full dependency chain support (topological sort, up to 10 levels deep) ### Automated Test Linking Test cases can be linked to automated test results from CI/CD runs. When a reporter sends results, tests can reference case IDs, creating a bridge between manual case definitions and automated execution data. Archiving a case automatically removes all autotest links. ### Archive & Restore Cases are soft-deleted (archived) rather than permanently removed. Archived cases can be viewed in a dedicated archive view and restored at any time. --- ## Manual Test Execution (Test Collections) Test collections are groups of test cases assembled for manual execution. They enable structured manual testing workflows with user assignment, step-level result tracking, and progress reporting. ### Creating a Collection 1. Create a test collection with a name, description, and optionally assign it to a user 2. Add test cases to the collection (individually or in bulk) 3. Optionally link the collection to a release for progress tracking 4. Organize collections in folders for better structure ### Execution Flow 1. Assigned user opens the collection and begins executing cases 2. Each case starts as **not_executed** 3. User marks cases as **in_testing** when starting 4. For each case, the user can record step-level results (pass/fail per step) 5. User sets final status: **passed**, **failed**, or **blocked** 6. For failures, a **caused_by** field captures the root cause 7. Duration and notes can be recorded per execution ### Execution Statuses | Status | Description | |--------|-------------| | not_executed | Case has not been started | | in_testing | Currently being executed | | passed | All steps passed | | failed | One or more steps failed | | blocked | Cannot be executed (dependency or environment issue) | ### Step-Level Results Each step within a case can be independently marked with a status and an issue description. This enables detailed failure tracking- you can see exactly which step failed and why, including steps inherited from parent/dependent cases. ### Collection Properties | Field | Description | |-------|-------------| | Name | Collection name | | Description | Purpose of this test run | | Assigned To | User responsible for execution | | Status | Overall collection status | | Priority | Execution priority | | Environment | Target environment (e.g., staging, production) | | Start/End Date | Planned execution window | | Release | Optional link to a release for progress tracking | --- ## Release Management Releases aggregate test results from both manual test collections and automated test launches, providing a unified view of release readiness. ### Release Structure | Field | Description | |-------|-------------| | Name | Release name (e.g., "v2.4.0") | | Version | Version identifier | | Description | Release notes or scope | | Status | planned, in_progress, or completed (customizable) | | Start/End Date | Release timeline | ### Linking Test Results Releases combine two sources of test data: **Manual Executions:** Link test collections to a release. The release dashboard shows aggregated progress across all linked collections- how many cases passed, failed, are blocked, or still need execution. **Automated Launches:** Link CI/CD test runs (launches) to a release. The release shows automated test results including pass rates and specific failures. ### Release Progress Dashboard The release details page provides: - **Manual test stats:** Total cases, passed, failed, blocked, in testing, not executed- aggregated across all linked collections - **Automated test stats:** Total tests, passed, failed, skipped- aggregated across all linked launches - **Progress view:** Lists all failed, in-testing, and blocked test cases with details (case ID, title, assigned user, collection name, step-level issues) - **Failed automated tests:** Lists specific test failures from linked launches ### Release Workflow 1. Create a release with name, version, and dates 2. Optionally link to Jira sprints for project tracking 3. Link manual test collections for manual QA progress 4. Link automated test launches for CI/CD results 5. Monitor the progress dashboard as testing proceeds 6. View failed and blocked tests to identify remaining work 7. Mark release as completed when all criteria are met ### Jira Integration Releases can be linked to Jira sprints (scrum or kanban boards) for cross-tool project tracking. Sprint data includes board type, project key, and direct links back to Jira. --- ## Key Features - **Real-time streaming:** WebSocket-powered live test updates at 100K messages/sec - **Flaky test detection:** Automatic identification of flaky tests across runs - **Slowest tests report:** Find performance bottlenecks in your test suite - **Coverage gap analysis:** Identify untested areas - **Test case management:** Folders, tags, custom fields, display IDs, bulk operations, archive/restore - **Manual execution:** Test collections with user assignment, step-level results, and failure tracking - **Release management:** Aggregate manual and automated results, track release readiness - **Notifications:** Native Slack, Discord, Microsoft Teams, Telegram, Email integrations - **Security:** PostgreSQL RLS, AES-256 encryption, SSO (OIDC/SAML), project-level API keys - **Monitoring:** Prometheus metrics and Grafana dashboards included