Skip to content

feat(cli): add feature file runner#2706

Open
ScriptedAlchemy wants to merge 4 commits into
mainfrom
feat/cli-feature-runner-poc
Open

feat(cli): add feature file runner#2706
ScriptedAlchemy wants to merge 4 commits into
mainfrom
feat/cli-feature-runner-poc

Conversation

@ScriptedAlchemy

@ScriptedAlchemy ScriptedAlchemy commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Adds a Rstest/Rspack loader so @midscene/cli can run .feature files directly.
  • Parses standard Gherkin with @cucumber/gherkin, expanding Background, Rule, and Scenario Outline/Examples into per-scenario Midscene YAML execution configs.
  • Preserves per-scenario result metadata, summary labels, retry reporting, and keeps existing YAML execution behavior unchanged.

Relationship to core runGherkinScenario

  • Agent.runGherkinScenario() from main is an inline core API for one scenario string.
  • This PR is the CLI file-runner layer: file discovery, Rstest scheduling, Rspack loader transform, per-scenario result files, summaries, retries, and .feature authoring.
  • The two are complementary; this PR does not replace the core API.

Architecture

flowchart TD
  A["User-authored .feature file"] --> B["@midscene/cli file discovery"]
  B --> C["createRstestYamlProject()"]
  C --> D["Pre-enumerate scenarios<br/>(testName, resultFile, caseId)"]
  C --> E["Rstest include: real .feature file"]
  E --> F["Rspack .feature loader"]
  F --> G["@cucumber/gherkin parser<br/>+ compiler"]
  G --> H["Expanded concrete cases<br/>Background, Rule, Examples"]
  H --> I["MidsceneYamlScript<br/>execution config"]
  I --> J["defineYamlCaseTest()"]
  J --> K["Existing YAML player"]
  K --> L["Agent aiAct / aiAssert"]
  L --> M["Result JSON, retry<br/>metadata, summary"]

  N["Existing .yml / .yaml files"] --> O["Existing virtual-module path"]
  O --> J
Loading
sequenceDiagram
  participant User as User
  participant CLI as @midscene/cli
  participant Rstest as Rstest
  participant Loader as Rspack feature loader
  participant Gherkin as @cucumber/gherkin
  participant YAML as YAML player
  participant Agent as Midscene Agent
  participant Summary as Summary writer

  User->>CLI: Run .feature path or config files
  CLI->>CLI: Match .feature, .yml, .yaml
  CLI->>CLI: Precompute scenario metadata
  CLI->>Rstest: Inline config includes real .feature file
  Rstest->>Loader: Transform .feature module
  Loader->>Gherkin: Parse AST and compile pickles
  Gherkin-->>Loader: Expanded concrete scenarios
  Loader->>Rstest: Emit defineYamlCaseTest calls
  Rstest->>YAML: Execute each scenario config
  YAML->>Agent: aiAct for Given / When
  YAML->>Agent: aiAssert for Then
  YAML-->>Summary: Result, report, retry attempts
  Summary-->>User: Per-scenario summary rows
Loading

Test plan

  • npx nx test @midscene/core -- tests/unit-test/run-gherkin-scenario.test.ts tests/unit-test/yaml-doc-usage.test.ts
  • npx nx test @midscene/cli
  • npx nx build @midscene/cli
  • pnpm run lint
  • git diff --check

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 23, 2026

Copy link
Copy Markdown

Deploying midscene with  Cloudflare Pages  Cloudflare Pages

Latest commit: 8202c27
Status: ✅  Deploy successful!
Preview URL: https://d38b0312.midscene.pages.dev
Branch Preview URL: https://feat-cli-feature-runner-poc.midscene.pages.dev

View logs

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b857fa4e70

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

stdio?: 'inherit' | 'pipe';
}

const DEFAULT_FEATURE_LOADER_PATH = join(__dirname, 'feature-loader.js');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Point the default loader at the emitted framework entry

When the packaged CLI runs from the root bundle (dist/lib/index.js), this default resolves to dist/lib/feature-loader.js, but the new rslib entry is emitted as dist/lib/framework/feature-loader.js. In that install path, any .feature file run will fail during Rspack loading unless a test-only featureLoaderPath override is supplied; resolve this the same way as the framework entry or include the framework/ segment.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant