-
Notifications
You must be signed in to change notification settings - Fork 39
test: add comprehensive Cucumber BDD test suite for Superposition API #914
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
knutties
wants to merge
30
commits into
main
Choose a base branch
from
claude/cucumber-gherkin-tests-CScOB
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
30 commits
Select commit
Hold shift + click to select a range
6229516
feat: add Cucumber/Gherkin BDD tests for Superposition API
claude 0baa29a
feat: add Playwright UI step definitions for Cucumber/Gherkin tests
claude 87e3984
fix: resolve ESM loading, ambiguous steps, and undefined UI steps
claude 2cdcd87
chore: update SDK package-lock.json after install
claude 7783177
fix: resolve cucumber test failures against live server
knutties d1cc1e0
fix: resolve remaining 5 cucumber test failures
knutties 1719662
fix: rewrite UI step definitions to use SDK client for full test cove…
knutties d15c0e5
feat: add real Playwright UI interactions to Cucumber step definitions
knutties 8293bf2
feat: add macOS-aware Monaco editor helper and detail page navigation
knutties 756ac83
feat: convert variable edit & delete steps to Playwright UI interactions
knutties e2d124c
feat: convert secret edit & delete steps to Playwright UI interactions
knutties 24cebec
feat: convert dimension edit/delete/get steps to Playwright UI intera…
knutties 573f59c
feat: convert type template create/edit/delete steps to Playwright UI…
knutties 389fa80
feat: convert workspace edit step to Playwright UI interactions
knutties a48f810
feat: convert experiment ramp/conclude/discard steps to Playwright UI…
knutties bc7c142
feat: convert context delete step to use Playwright UI interaction
knutties 0792691
feat: convert context delete step to Playwright browser interaction
knutties 66eafb9
feat: convert experiment group delete step to Playwright browser inte…
knutties 15b2e8d
feat: add Playwright navigation to function get and publish steps
knutties 60f4058
feat: add Playwright navigation to default config create/update steps
knutties 5432a95
feat: add Playwright navigation to context create/get/update steps
knutties 9489aa8
feat: add Playwright navigation to experiment group create/get/update…
knutties f72405d
feat: add Playwright navigation to experiment, variable, secret, org,…
knutties 467d9a7
feat: add Playwright navigation to function create and update steps
knutties 01f6d11
feat: add Playwright navigation to function create and update steps
knutties 4611e2d
test: add cucumber testing to test target
knutties 842ffdc
fix: resolve CI build failures in cucumber tests
claude 4f7473f
fix: restore UI cucumber tests with Playwright browser install
claude f1b7440
feat: add Playwright to nix devShell with conditional makefile install
claude 0e61bff
fix: resolve UI test failures from WASM hydration timing
claude File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| node_modules/ | ||
| dist/ | ||
| reports/ | ||
| *.lock |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| /** | ||
| * Cucumber profiles for API and UI testing. | ||
| * | ||
| * Both profiles run the SAME Gherkin feature files from features/. | ||
| * The only difference is which step definitions and support files are loaded: | ||
| * | ||
| * npm run test:api → step_definitions/ + support/ (drives the SDK) | ||
| * npm run test:ui → step_definitions_ui/ + support_ui/ (drives Playwright) | ||
| */ | ||
| export default function () { | ||
| return { | ||
| api: { | ||
| import: ["step_definitions/**/*.ts", "support/**/*.ts"], | ||
| format: ["progress", "html:reports/api-report.html"], | ||
| formatOptions: { snippetInterface: "async-await" }, | ||
| }, | ||
| ui: { | ||
| import: ["step_definitions_ui/**/*.ts", "support_ui/**/*.ts"], | ||
| format: ["progress", "html:reports/ui-report.html"], | ||
| formatOptions: { snippetInterface: "async-await" }, | ||
| }, | ||
| }; | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| @api @config @config_retrieval | ||
| Feature: Configuration Retrieval and Versioning | ||
| As a developer | ||
| I want to retrieve configurations and manage versions | ||
| So that I can serve the right config values to my application | ||
|
|
||
| Background: | ||
| Given an organisation and workspace exist | ||
| And a test default config exists for config retrieval | ||
|
|
||
| # ── GetConfig ────────────────────────────────────────────────────── | ||
|
|
||
| Scenario: Get configuration with context | ||
| When I get the config with the test config key prefix | ||
| Then the operation should succeed | ||
| And the response should have a version | ||
|
|
||
| Scenario: Pin workspace to a config version and verify | ||
| Given I know the current config version | ||
| When I pin the workspace to that config version | ||
| And I get the config again | ||
| Then the config version should match the pinned version | ||
| When I unpin the workspace config version | ||
| Then the workspace config version should be unset | ||
|
|
||
| # ── ListVersions ─────────────────────────────────────────────────── | ||
|
|
||
| Scenario: List configuration versions | ||
| When I list config versions with count 10 and page 1 | ||
| Then the operation should succeed |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| @api @context | ||
| Feature: Context Management | ||
| As a configuration administrator | ||
| I want to manage contexts with condition-based overrides | ||
| So that configurations vary based on runtime conditions | ||
|
|
||
| Background: | ||
| Given an organisation and workspace exist | ||
| And dimensions and default configs are set up for context tests | ||
|
|
||
| # ── Create ───────────────────────────────────────────────────────── | ||
|
|
||
| Scenario: Create a context with overrides | ||
| When I create a context with condition "os" equals "android" and override "ctx-config-key" to "android-value" | ||
| Then the operation should succeed | ||
| And the response should have a context ID | ||
|
|
||
| # ── Get ──────────────────────────────────────────────────────────── | ||
|
|
||
| Scenario: Get a context by ID | ||
| Given a context exists with condition "os" equals "ios" and override "ctx-config-key" to "ios-value" | ||
| When I get the context by its ID | ||
| Then the response should include the override for "ctx-config-key" | ||
|
|
||
| # ── List ─────────────────────────────────────────────────────────── | ||
|
|
||
| Scenario: List all contexts | ||
| Given a context exists with condition "os" equals "web" and override "ctx-config-key" to "web-value" | ||
| When I list all contexts | ||
| Then the response should contain a list | ||
| And the list should contain the created context | ||
|
|
||
| # ── Update Override ──────────────────────────────────────────────── | ||
|
|
||
| Scenario: Update a context override | ||
| Given a context exists with condition "os" equals "android" and override "ctx-config-key" to "old-value" | ||
| When I update the context override for "ctx-config-key" to "new-value" | ||
| Then the operation should succeed | ||
|
|
||
| # ── Move Context ─────────────────────────────────────────────────── | ||
|
|
||
| Scenario: Move a context to a different condition | ||
| Given a context exists with condition "os" equals "android" and override "ctx-config-key" to "move-value" | ||
| When I move the context to condition "os" equals "ios" | ||
| Then the operation should succeed | ||
|
|
||
| # ── Delete ───────────────────────────────────────────────────────── | ||
|
|
||
| Scenario: Delete a context | ||
| Given a context exists with condition "os" equals "android" and override "ctx-config-key" to "delete-value" | ||
| When I delete the context | ||
| Then the operation should succeed | ||
|
|
||
| # ── Bulk Operations ──────────────────────────────────────────────── | ||
|
|
||
| Scenario: Perform bulk context operations | ||
| When I perform a bulk operation to create contexts for "os" values "android,ios" | ||
| Then the operation should succeed | ||
|
|
||
| # ── Weight Recompute ─────────────────────────────────────────────── | ||
|
|
||
| Scenario: Recompute context weights | ||
| Given contexts exist for weight recompute | ||
| When I trigger weight recomputation | ||
| Then the operation should succeed |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| @api @config @default_config | ||
| Feature: Default Configuration Management | ||
| As a developer | ||
| I want to manage default configurations with schema validation | ||
| So that my application has well-defined configuration defaults | ||
|
|
||
| Background: | ||
| Given an organisation and workspace exist | ||
| And validation functions are set up | ||
|
|
||
| # ── Create ───────────────────────────────────────────────────────── | ||
|
|
||
| Scenario: Create a valid default config | ||
| When I create a default config with key "test-key" and value: | ||
| | name | Test User | | ||
| | age | 30 | | ||
| And the schema requires "name" as string and "age" as number with minimum 0 | ||
| Then the operation should succeed | ||
|
|
||
| Scenario: Fail to create config with invalid schema type | ||
| When I create a default config with key "test-key-2" and an invalid schema type "invalid-type" | ||
| Then the operation should fail with error matching "Invalid JSON schema" | ||
|
|
||
| Scenario: Fail to create config with empty schema | ||
| When I create a default config with key "test-key-2" and an empty schema | ||
| Then the operation should fail with error matching "Schema cannot be empty" | ||
|
|
||
| Scenario: Fail to create config when value violates schema constraints | ||
| When I create a default config with key "test-key-2" where age is -5 but minimum is 0 | ||
| Then the operation should fail with error matching "value is too small, minimum is 0" | ||
|
|
||
| Scenario: Fail to create config when function validation fails | ||
| When I create a default config with key "test-key-2" using validation function "false_validation" | ||
| Then the operation should fail with error matching "validation failed" | ||
|
|
||
| Scenario: Create config with value_compute function | ||
| When I create a default config with key "test-key-3" using compute function "auto_fn" | ||
| Then the operation should succeed | ||
| And the response should have value_compute_function_name "auto_fn" | ||
|
|
||
| Scenario: Fail to create config with non-existent function | ||
| When I create a default config with key "test-key-2" using validation function "non_existent_function" | ||
| Then the operation should fail with error matching "published code does not exist" | ||
|
|
||
| # ── Update ───────────────────────────────────────────────────────── | ||
|
|
||
| Scenario: Update an existing default config value | ||
| Given a default config exists with key "test-key-upd" and value "Test User" age 30 | ||
| When I update the default config "test-key-upd" with value "Updated User" age 35 | ||
| Then the response value should have name "Updated User" and age 35 | ||
|
|
||
| Scenario: Update schema and value together | ||
| Given a default config exists with key "test-key-upd2" and value "Test User" age 30 | ||
| When I update default config "test-key-upd2" schema to add email field and set value with email "updated@example.com" | ||
| Then the response value should include email "updated@example.com" | ||
|
|
||
| Scenario: Fail to update a non-existent key | ||
| When I update default config "non_existent_key" with a new value | ||
| Then the operation should fail with error matching "No record found" | ||
|
|
||
| Scenario: Fail to update with invalid schema | ||
| Given a default config exists with key "test-key-upd3" and value "Test User" age 30 | ||
| When I update default config "test-key-upd3" schema to an invalid type | ||
| Then the operation should fail with error matching "Invalid JSON schema" | ||
|
|
||
| Scenario: Fail to update when value misses required field | ||
| Given a default config exists with key "test-key-upd4" and requires name and email | ||
| When I update default config "test-key-upd4" value without the required email field | ||
| Then the operation should fail with error matching "required property" | ||
|
|
||
| Scenario: Update config with a validation function | ||
| Given a default config exists with key "test-key-upd5" and value "Test User" age 30 | ||
| When I update default config "test-key-upd5" validation function to "true_function" | ||
| Then the response should have value_validation_function_name "true_function" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| @api @dimension | ||
| Feature: Dimension Management | ||
| As a configuration administrator | ||
| I want to manage dimensions (context keys) | ||
| So that I can define the axes along which configuration varies | ||
|
|
||
| Background: | ||
| Given an organisation and workspace exist | ||
|
|
||
| # ── Create ───────────────────────────────────────────────────────── | ||
|
|
||
| Scenario: Create a string dimension | ||
| When I create a dimension with name "test-dim-str" and schema type "string" | ||
| Then the operation should succeed | ||
| And the response should have dimension name "test-dim-str" | ||
|
|
||
| Scenario: Create an enum dimension | ||
| When I create a dimension with name "test-dim-enum" and enum values "small,big,otherwise" | ||
| Then the operation should succeed | ||
|
|
||
| Scenario: Create a boolean dimension | ||
| When I create a dimension with name "test-dim-bool" and schema type "boolean" | ||
| Then the operation should succeed | ||
|
|
||
| # ── Get ──────────────────────────────────────────────────────────── | ||
|
|
||
| Scenario: Get a dimension by name | ||
| Given a dimension "test-dim-get" exists with schema type "string" | ||
| When I get dimension "test-dim-get" | ||
| Then the response should have dimension name "test-dim-get" | ||
|
|
||
| # ── List ─────────────────────────────────────────────────────────── | ||
|
|
||
| Scenario: List all dimensions | ||
| Given a dimension "test-dim-list" exists with schema type "string" | ||
| When I list all dimensions | ||
| Then the response should contain a list | ||
| And the list should contain dimension "test-dim-list" | ||
|
|
||
| # ── Update ───────────────────────────────────────────────────────── | ||
|
|
||
| Scenario: Update a dimension's description | ||
| Given a dimension "test-dim-upd" exists with schema type "string" | ||
| When I update dimension "test-dim-upd" description to "Updated description" | ||
| Then the operation should succeed | ||
|
|
||
| # ── Delete ───────────────────────────────────────────────────────── | ||
|
|
||
| Scenario: Delete a dimension | ||
| Given a dimension "test-dim-del" exists with schema type "string" | ||
| When I delete dimension "test-dim-del" | ||
| Then the operation should succeed | ||
|
|
||
| # ── Error Cases ──────────────────────────────────────────────────── | ||
|
|
||
| Scenario: Fail to create a dimension with invalid schema | ||
| When I create a dimension with name "test-dim-invalid" and schema type "invalid-type" | ||
| Then the operation should fail |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| @api @experiment | ||
| Feature: Experiment Management | ||
| As a product manager | ||
| I want to manage A/B test experiments | ||
| So that I can test configuration variants with controlled traffic | ||
|
|
||
| Background: | ||
| Given an organisation and workspace exist | ||
| And dimensions and default configs are set up for experiment tests | ||
|
|
||
| # ── Create ───────────────────────────────────────────────────────── | ||
|
|
||
| Scenario: Create an experiment with control and experimental variants | ||
| When I create an experiment with name "exp-test" and context "os" equals "android" | ||
| And the experiment has a control variant with override "exp-config-key" = "control-val" | ||
| And the experiment has an experimental variant with override "exp-config-key" = "experimental-val" | ||
| Then the operation should succeed | ||
| And the response should have experiment status "CREATED" | ||
| And the response should have 2 variants | ||
|
|
||
| # ── Get ──────────────────────────────────────────────────────────── | ||
|
|
||
| Scenario: Get an experiment by ID | ||
| Given an experiment "exp-get" exists with context "os" equals "ios" | ||
| When I get the experiment by its ID | ||
| Then the response should have the experiment name | ||
| And the response should have experiment status "CREATED" | ||
|
|
||
| # ── List ─────────────────────────────────────────────────────────── | ||
|
|
||
| Scenario: List experiments | ||
| Given an experiment "exp-list" exists with context "os" equals "android" | ||
| When I list experiments | ||
| Then the response should contain a list | ||
| And the list should contain the created experiment | ||
|
|
||
| # ── Ramp ─────────────────────────────────────────────────────────── | ||
|
|
||
| Scenario: Ramp an experiment to 50% traffic | ||
| Given an experiment "exp-ramp" exists with context "os" equals "android" | ||
| When I ramp the experiment to 50 percent traffic | ||
| Then the operation should succeed | ||
| And the experiment status should be "INPROGRESS" | ||
|
|
||
| # ── Update Overrides ─────────────────────────────────────────────── | ||
|
|
||
| Scenario: Update experiment variant overrides | ||
| Given an experiment "exp-override" exists with context "os" equals "android" | ||
| When I update the experimental variant override for "exp-config-key" to "updated-val" | ||
| Then the operation should succeed | ||
|
|
||
| # ── Conclude ─────────────────────────────────────────────────────── | ||
|
|
||
| Scenario: Conclude an experiment | ||
| Given an experiment "exp-conclude" exists and is ramped to 50 percent | ||
| When I conclude the experiment with the experimental variant | ||
| Then the experiment status should be "CONCLUDED" | ||
|
|
||
| # ── Discard ──────────────────────────────────────────────────────── | ||
|
|
||
| Scenario: Discard a created experiment | ||
| Given an experiment "exp-discard" exists with context "os" equals "ios" | ||
| When I discard the experiment | ||
| Then the experiment status should be "DISCARDED" | ||
|
|
||
| Scenario: Discard an in-progress experiment | ||
| Given an experiment "exp-discard-prog" exists and is ramped to 50 percent | ||
| When I discard the experiment | ||
| Then the experiment status should be "DISCARDED" |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both profiles write HTML reports under
reports/..., but the config doesn't ensure thereports/directory exists. Depending on the formatter implementation, this can fail the run before any scenarios execute. Createreports/(andreports/screenshots/for UI) as part of setup (e.g., in aBeforeAllhook or a pretest script).