tuner-testkit 4.0.2__tar.gz → 4.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tuner_testkit-4.2.0/PKG-INFO +213 -0
- tuner_testkit-4.2.0/README.md +168 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/pyproject.toml +6 -17
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/__init__.py +1 -1
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/action_words/__init__.py +1 -1
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/action_words/__main__.py +1 -1
- tuner_testkit-4.2.0/tuner_testkit/apps/dna/dna_payload/.cursor/agents/bdd-asset-pipeline.md +106 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/assets-knowledge.mdc +15 -10
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/bdd-asset-layering.mdc +2 -2
- tuner_testkit-4.2.0/tuner_testkit/apps/dna/dna_payload/.cursor/rules/bdd-pipeline-gates.mdc +75 -0
- tuner_testkit-4.2.0/tuner_testkit/apps/dna/dna_payload/.cursor/rules/explore-safety.mdc +23 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/index-hygiene.mdc +2 -2
- tuner_testkit-4.2.0/tuner_testkit/apps/dna/dna_payload/.cursor/skills/derive-design-knowledge/SKILL.md +40 -0
- tuner_testkit-4.2.0/tuner_testkit/apps/dna/dna_payload/.cursor/skills/derive-feature-sets/SKILL.md +25 -0
- tuner_testkit-4.2.0/tuner_testkit/apps/dna/dna_payload/.cursor/skills/explore-sut/SKILL.md +45 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/maintain-index/SKILL.md +4 -4
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/run-feature-playwright-mcp/SKILL.md +12 -12
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/AGENTS.md +20 -19
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/MANIFEST.txt +1 -1
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/docs/spec/assets-knowledge-syntax.md +26 -19
- tuner_testkit-4.2.0/tuner_testkit/apps/dna/dna_payload/docs/spec/bdd-run-gherkin-in-playwrightMCP.md +159 -0
- tuner_testkit-4.2.0/tuner_testkit/apps/dna/dna_payload/docs/spec/design-knowledge-syntax.md +102 -0
- tuner_testkit-4.2.0/tuner_testkit/apps/dna/dna_payload/docs/spec/sut-self-learning.md +91 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/init_repo/scaffold.py +4 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/page_test/__main__.py +1 -1
- tuner_testkit-4.2.0/tuner_testkit.egg-info/PKG-INFO +213 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit.egg-info/SOURCES.txt +2 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit.egg-info/requires.txt +4 -16
- tuner_testkit-4.0.2/PKG-INFO +0 -176
- tuner_testkit-4.0.2/README.md +0 -118
- tuner_testkit-4.0.2/tuner_testkit/apps/dna/dna_payload/.cursor/agents/bdd-asset-pipeline.md +0 -102
- tuner_testkit-4.0.2/tuner_testkit/apps/dna/dna_payload/.cursor/rules/bdd-pipeline-gates.mdc +0 -53
- tuner_testkit-4.0.2/tuner_testkit/apps/dna/dna_payload/docs/spec/bdd-run-gherkin-in-playwrightMCP.md +0 -159
- tuner_testkit-4.0.2/tuner_testkit.egg-info/PKG-INFO +0 -176
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/LICENSE +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/setup.cfg +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/action_words/_internal/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/action_words/_internal/api.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/action_words/_internal/db.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/action_words/_internal/generators.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/action_words/_internal/ids.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/action_words/_internal/wait.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/action_words/base.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/action_words/context.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/action_words/plane.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/action_words/registry.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/api_mock/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/api_mock/app.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/api_mock/errors.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/api_mock/router.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/api_mock/spec.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/api_mock/store.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/api_objects/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/api_objects/auth.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/api_objects/recording/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/api_objects/recording/capture.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/api_objects/recording/codegen.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/api_objects/recording/freeze.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/api_objects/recording/mocks.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/api_objects/recording/normalize.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/api_objects/recording/pipeline.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/api_objects/recording/sanitize.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/api_test/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/api_test/client.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/api_test/errors.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/api_test/jsonpath.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/api_test/model.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/_shared/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/_shared/changelog.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/_shared/plane.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/_shared/plane_app.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/_shared/plane_asset.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/_shared/tests/test_plane_asset.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/_shared/tests/test_plane_collect.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/api_recorder/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/api_recorder/__main__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/api_recorder/addon.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/api_recorder/cli.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/api_recorder/playwright_tap.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/api_recorder/tests/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/api_recorder/tests/test_addon.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/__main__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/build.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/cli.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/hooks/sync_registry.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/hooks.json +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/apps-authoring.mdc +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/apps-handover.mdc +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/bdd-stage-layout.mdc +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/commit-convention.mdc +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/packages-db.mdc +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/packages-fake.mdc +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/packages-logging.mdc +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/rules/packages-page-test.mdc +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/create-action-word/SKILL.md +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/create-app/SKILL.md +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/dump-ddl/SKILL.md +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/feature-authoring/SKILL.md +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/feature-review-lint/SKILL.md +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/freeze-api-objects/SKILL.md +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/maintain-behave-steps/SKILL.md +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/maintain-page-objects/SKILL.md +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/release-template/SKILL.md +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/.cursor/skills/reuse-analysis/SKILL.md +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/docs/spec/action-words-syntax.md +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/docs/spec/api-objects-syntax.md +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/docs/spec/apps-authoring-syntax.md +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/docs/spec/behave-gerkin-syntax.md +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/docs/spec/behave-step-definitions.md +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/docs/spec/commit-convention.md +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/docs/spec/page-objects-syntax.md +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/tools/git-hooks/README.md +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/tools/git-hooks/commit-msg +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/tools/git-hooks/pre-push +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/dna_payload/tools/git-hooks/validate_commit_msg.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/paths.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/source.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dna/tests/test_cli.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/dump_ddl.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/index_ai/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/index_ai/__main__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/index_ai/registry.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/index_platform/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/index_platform/__main__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/index_platform/build.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/index_platform/catalog.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/index_platform/plane.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/index_platform/tests/test_catalog.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/init_repo/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/init_repo/__main__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/init_repo/manifest.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/init_repo/stubs/apps/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/init_repo/stubs/behave.ini +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/init_repo/stubs/config/env.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/init_repo/stubs/packages/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/init_repo/stubs/packages/action_words/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/init_repo/stubs/packages/action_words/_internal/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/init_repo/stubs/packages/action_words/_internal/params.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/init_repo/stubs/packages/action_words/models.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/init_repo/stubs/packages/api_objects/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/init_repo/stubs/packages/api_objects/auth.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/init_repo/stubs/packages/api_objects/plane.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/init_repo/stubs/packages/api_objects/recording/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/init_repo/stubs/packages/api_objects/registry.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/init_repo/stubs/packages/page_objects/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/init_repo/stubs/packages/page_objects/plane.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/init_repo/stubs/packages/page_objects/session.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/init_repo/tests/test_scaffold.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/mock_server/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/mock_server/__main__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/mock_server/cli.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/mock_server/plane.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/mock_server/seed.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/page_recorder/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/page_recorder/__main__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/page_recorder/capture.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/page_recorder/cli.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/page_recorder/codegen.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/page_recorder/freeze.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/page_recorder/inject.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/page_recorder/session.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/page_recorder/tests/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/page_recorder/tests/test_capture.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/page_recorder/tests/test_cli.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/page_recorder/tests/test_freeze.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/recorder/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/recorder/__main__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/recorder/cli.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/recorder/tests/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/apps/recorder/tests/test_cli.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/config.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/db/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/db/client.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/db/connection.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/excel/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/excel/workbook.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/fake/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/fake/__main__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/fake/catalog.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/fake/china.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/fake/cli.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/fake/core.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/fake/medical.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/fake/wrappers.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/logging/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/logging/context.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/logging/core.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/logging/helpers.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/logging/hooks.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/logging/scenario_file.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/page_test/__init__.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/page_test/base.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/page_test/driver.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/page_test/errors.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/page_test/harvest.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/page_test/health.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/page_test/locator.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/page_test/model.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/page_test/registry.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/page_test/session.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/page_test/steps.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/page_test/testing.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit/project.py +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit.egg-info/dependency_links.txt +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit.egg-info/entry_points.txt +0 -0
- {tuner_testkit-4.0.2 → tuner_testkit-4.2.0}/tuner_testkit.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tuner-testkit
|
|
3
|
+
Version: 4.2.0
|
|
4
|
+
Summary: Shared test runtime, recorders, and DNA overlay for SUT test repos
|
|
5
|
+
Author: tuner-testkit contributors
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Requires-Python: >=3.12
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: pydantic>=2
|
|
11
|
+
Provides-Extra: db
|
|
12
|
+
Requires-Dist: pymysql>=1.2.0; extra == "db"
|
|
13
|
+
Requires-Dist: pymssql>=2.3.0; extra == "db"
|
|
14
|
+
Requires-Dist: psycopg[binary]>=3.2; extra == "db"
|
|
15
|
+
Requires-Dist: sqlalchemy>=2.0; extra == "db"
|
|
16
|
+
Provides-Extra: api
|
|
17
|
+
Requires-Dist: requests>=2.33.1; extra == "api"
|
|
18
|
+
Provides-Extra: web-ui
|
|
19
|
+
Requires-Dist: playwright>=1.54.0; extra == "web-ui"
|
|
20
|
+
Provides-Extra: phone-ui
|
|
21
|
+
Provides-Extra: excel
|
|
22
|
+
Requires-Dist: openpyxl>=3.1.0; extra == "excel"
|
|
23
|
+
Provides-Extra: fake
|
|
24
|
+
Requires-Dist: faker>=37.0.0; extra == "fake"
|
|
25
|
+
Provides-Extra: mock
|
|
26
|
+
Requires-Dist: fastapi>=0.115.0; extra == "mock"
|
|
27
|
+
Requires-Dist: uvicorn[standard]>=0.32.0; extra == "mock"
|
|
28
|
+
Requires-Dist: httpx>=0.28.0; extra == "mock"
|
|
29
|
+
Provides-Extra: recorder
|
|
30
|
+
Requires-Dist: playwright>=1.54.0; extra == "recorder"
|
|
31
|
+
Requires-Dist: mitmproxy>=11.1.3; extra == "recorder"
|
|
32
|
+
Provides-Extra: test
|
|
33
|
+
Requires-Dist: pytest>=9.0.3; extra == "test"
|
|
34
|
+
Requires-Dist: openpyxl>=3.1.0; extra == "test"
|
|
35
|
+
Requires-Dist: httpx>=0.28.0; extra == "test"
|
|
36
|
+
Provides-Extra: bdd
|
|
37
|
+
Requires-Dist: behave>=1.2.6; extra == "bdd"
|
|
38
|
+
Requires-Dist: playwright>=1.54.0; extra == "bdd"
|
|
39
|
+
Requires-Dist: behave-html-pretty-formatter>=1.16.1; extra == "bdd"
|
|
40
|
+
Provides-Extra: all
|
|
41
|
+
Requires-Dist: tuner-testkit[api,bdd,db,excel,fake,mock,phone-ui,recorder,test,web-ui]; extra == "all"
|
|
42
|
+
Provides-Extra: dev
|
|
43
|
+
Requires-Dist: tuner-testkit[all]; extra == "dev"
|
|
44
|
+
Dynamic: license-file
|
|
45
|
+
|
|
46
|
+
# tuner-testkit
|
|
47
|
+
|
|
48
|
+
发行名 **`tuner-testkit`**,导入名 **`tuner_testkit`**。给被测系统(SUT)测试仓提供公共运行库与 CLI(db / API / Web UI / 录制 / mock),以及 Cursor/git **DNA**(rules、skills、hooks)。
|
|
49
|
+
|
|
50
|
+
业务资产(page/api objects、action words、features)留在**各项目仓**的 `packages/` 与 `tests/`,不进本包。平台发新版本后,下游用 `uv` 按需升级,不必再整树拷贝运行库。
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 标准作业流程
|
|
55
|
+
|
|
56
|
+
### 1. 工具域:只装核心 kit(能 `tuner-init` 即可)
|
|
57
|
+
|
|
58
|
+
`uv tool install` 和业务仓 `.venv` 是两套环境。下游在 **tool 域只装默认 wheel**,用来拿 `tuner-init` / `tuner-dna`;**不要**在 tool 域打开 `[db]` / `[api]` 等 extra。
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
uv tool install tuner-testkit
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
入口命令是 `tuner-init`、`tuner-dna` 等(`tuner-*`),**没有** `tuner-testkit` 这个 script。`tuner-dump-ddl`、`tuner-recorder` 等依赖 extra 的 CLI,请在业务仓用 `uv run …` 跑,走该仓 `.venv`。
|
|
65
|
+
|
|
66
|
+
### 2. 初始化测试仓
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
tuner-init scaffold ../my-sut-tests
|
|
70
|
+
cd ../my-sut-tests
|
|
71
|
+
uv sync
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
`scaffold` 会铺六层目录、写入依赖 `tuner-testkit[db,api]` 的 `pyproject.toml`,并执行一次 `tuner-dna sync`(把 `.cursor/`、`docs/spec/`、`tools/git-hooks/` 放进**项目树**)。可在任意目录运行,不必先有测试仓。不要用 `tuner-testkit init repo`。
|
|
75
|
+
|
|
76
|
+
`uv sync` 把 **db / api 装进业务仓 `.venv`**,不是 tool 域。已有项目仓则在该仓根目录:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
uv add "tuner-testkit[db,api]>=4.0.0"
|
|
80
|
+
uv sync
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Web UI / 合录等按需再加 extra:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
uv add "tuner-testkit[web-ui]"
|
|
87
|
+
uv add "tuner-testkit[recorder]"
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
测 kit 全能力(平台狗食仓等)一次打开全部能力 extra:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
uv add "tuner-testkit[all]"
|
|
94
|
+
uv sync
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 3. 开始写业务
|
|
98
|
+
|
|
99
|
+
在**项目仓**里写,不要改 site-packages 里的 kit:
|
|
100
|
+
|
|
101
|
+
| 你写什么 | 放哪里 |
|
|
102
|
+
| --- | --- |
|
|
103
|
+
| 页面 / 接口资产 | `packages/page_objects/`、`packages/api_objects/` |
|
|
104
|
+
| 业务动作 | `packages/action_words/` |
|
|
105
|
+
| BDD / pytest | `tests/features/`、`tests/pytest/` |
|
|
106
|
+
| 知识(DDL、用例) | `assets/` |
|
|
107
|
+
| 本仓私有工具 | `apps/`(`python -m apps.<name>`) |
|
|
108
|
+
|
|
109
|
+
代码里 `from tuner_testkit.db import …` / `from tuner_testkit.page_test import …`。密钥只放本机 `config/env_local.py` 或环境变量(`TUNER_ENV`、`TUNER_DB_<ALIAS>_*`),**不要提交**。
|
|
110
|
+
|
|
111
|
+
录制产物同样写到项目仓 `packages/`,不会写进 venv。
|
|
112
|
+
|
|
113
|
+
### 4. 获取 PyPI 上的更新
|
|
114
|
+
|
|
115
|
+
平台发新版本后,下游从 [PyPI:tuner-testkit](https://pypi.org/project/tuner-testkit/) 取 wheel,**不要**再拷本仓源码。tool 域和业务仓 `.venv` 是两份安装,**两边都要升**,再铺 DNA。
|
|
116
|
+
|
|
117
|
+
**先看当前装的是哪一版、PyPI 最新是哪一版:**
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
uv tool list # tool 域里的 tuner-testkit
|
|
121
|
+
cd ../my-sut-tests
|
|
122
|
+
uv pip show tuner-testkit # 业务仓 .venv
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
发行说明见 [`docs/changelog/FRAMEWORK.md`](docs/changelog/FRAMEWORK.md) 与该版本的 `docs/changelog/TEMPLATE-*.md`。
|
|
126
|
+
|
|
127
|
+
**① tool 域(只升核心 CLI)**
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
uv tool upgrade tuner-testkit
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
升的是 `tuner-init` / `tuner-dna` 所在环境。这里仍然**不要**加 `[db]` / `[api]`。尚未 `uv tool install` 过则先执行第 1 节。
|
|
134
|
+
|
|
135
|
+
**② 业务仓 `.venv`(升运行库 + extras)**
|
|
136
|
+
|
|
137
|
+
在**项目仓根目录**改依赖并同步 lock。保留你原来打开的 extra(普通仓 `[db,api]`,狗食/全能力仓 `[all]`):
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
# 钉到某一发行版(推荐,和团队 lock 一致)
|
|
141
|
+
uv add "tuner-testkit[db,api]==4.2.0"
|
|
142
|
+
|
|
143
|
+
# 或只抬下限,让解析器选允许范围内的最新
|
|
144
|
+
# uv add "tuner-testkit[db,api]>=4.2.0"
|
|
145
|
+
|
|
146
|
+
uv sync
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
已经写过 `>=4.0.0`、只想把 lock 里的 kit 升到 PyPI 最新:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
uv lock --upgrade-package tuner-testkit
|
|
153
|
+
uv sync
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
只改 `pyproject.toml` 里的版本再 `uv lock` / `uv sync` 也可以。一个 wheel 不能「只升 web-ui、钉死旧 db」。
|
|
157
|
+
|
|
158
|
+
**③ 同步 DNA 并提交**
|
|
159
|
+
|
|
160
|
+
`uv add` / `uv sync` 只更新 site-packages 里的运行库。Cursor 读的是项目树里的 `.cursor/`、`docs/spec/`、`tools/git-hooks/`,必须再铺一层:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
tuner-dna sync
|
|
164
|
+
tuner-dna check
|
|
165
|
+
git add -A && git commit
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
`tuner-dna check` 核对项目树 DNA 是否与**当前 PATH 上那份** kit 一致。建议先 `uv tool upgrade`,再 `sync`,避免 CLI 还是旧包、`.venv` 已是新包。
|
|
169
|
+
|
|
170
|
+
新仓第一次仍用第 2 节的 `tuner-init scaffold`(会写依赖并做一次 `tuner-dna sync`),不是每次发版都重新 scaffold。
|
|
171
|
+
|
|
172
|
+
`[phone-ui]` 为预留空 extra,4.0 未实现。
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## extras
|
|
177
|
+
|
|
178
|
+
| extra | 内容 |
|
|
179
|
+
| --- | --- |
|
|
180
|
+
| (默认 wheel) | `config` / `logging`、`tuner-init`、`tuner-dna`(tool 域只装这个) |
|
|
181
|
+
| `[db]` | MySQL / SQL Server / PostgreSQL(装在业务仓 `.venv`) |
|
|
182
|
+
| `[api]` | `api_test`(HTTP 客户端) |
|
|
183
|
+
| `[web-ui]` | `page_test` + Playwright |
|
|
184
|
+
| `[phone-ui]` | 预留,无实现 |
|
|
185
|
+
| `[recorder]` | 合录 / 仅 UI / mitmproxy 代理 |
|
|
186
|
+
| `[mock]` | 按冻结的 api_objects 回放 |
|
|
187
|
+
| `[excel]` / `[fake]` | 表格 / 假数据 |
|
|
188
|
+
| `[bdd]` / `[test]` | behave / pytest |
|
|
189
|
+
| `[all]` | 元 extra:上述能力 extra 的并集(不含 `[dev]`) |
|
|
190
|
+
| `[dev]` | `tuner-testkit[all]`,给本仓 editable 开发 |
|
|
191
|
+
|
|
192
|
+
CLI 与 `python -m tuner_testkit.…` 等价,例如 `tuner-recorder`、`tuner-page-recorder`、`tuner-api-recorder`、`tuner-mock-server`。依赖 extra 的命令在业务仓用 `uv run tuner-dump-ddl` / `uv run tuner-recorder`。
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## 安全
|
|
197
|
+
|
|
198
|
+
不得把 token、cookie、Authorization、密码、session 写入仓库(含 capture 与 api_objects)。凭证只允许运行时注入。
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## 本仓库(平台源码)
|
|
203
|
+
|
|
204
|
+
克隆后在仓库根目录开发 kit 本身:
|
|
205
|
+
|
|
206
|
+
```powershell
|
|
207
|
+
uv venv
|
|
208
|
+
uv sync --extra all
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
`uv sync --extra dev` 与 `--extra all` 等价(`dev` 只是引用 `[all]`)。
|
|
212
|
+
|
|
213
|
+
4.2.0 发行说明见 [`docs/changelog/TEMPLATE-4.2.0.md`](docs/changelog/TEMPLATE-4.2.0.md);3.x → 4.x 迁移见 [`TEMPLATE-4.0.0.md`](docs/changelog/TEMPLATE-4.0.0.md)。平台能力地图见 [`INDEX.md`](INDEX.md)。
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# tuner-testkit
|
|
2
|
+
|
|
3
|
+
发行名 **`tuner-testkit`**,导入名 **`tuner_testkit`**。给被测系统(SUT)测试仓提供公共运行库与 CLI(db / API / Web UI / 录制 / mock),以及 Cursor/git **DNA**(rules、skills、hooks)。
|
|
4
|
+
|
|
5
|
+
业务资产(page/api objects、action words、features)留在**各项目仓**的 `packages/` 与 `tests/`,不进本包。平台发新版本后,下游用 `uv` 按需升级,不必再整树拷贝运行库。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 标准作业流程
|
|
10
|
+
|
|
11
|
+
### 1. 工具域:只装核心 kit(能 `tuner-init` 即可)
|
|
12
|
+
|
|
13
|
+
`uv tool install` 和业务仓 `.venv` 是两套环境。下游在 **tool 域只装默认 wheel**,用来拿 `tuner-init` / `tuner-dna`;**不要**在 tool 域打开 `[db]` / `[api]` 等 extra。
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
uv tool install tuner-testkit
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
入口命令是 `tuner-init`、`tuner-dna` 等(`tuner-*`),**没有** `tuner-testkit` 这个 script。`tuner-dump-ddl`、`tuner-recorder` 等依赖 extra 的 CLI,请在业务仓用 `uv run …` 跑,走该仓 `.venv`。
|
|
20
|
+
|
|
21
|
+
### 2. 初始化测试仓
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
tuner-init scaffold ../my-sut-tests
|
|
25
|
+
cd ../my-sut-tests
|
|
26
|
+
uv sync
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`scaffold` 会铺六层目录、写入依赖 `tuner-testkit[db,api]` 的 `pyproject.toml`,并执行一次 `tuner-dna sync`(把 `.cursor/`、`docs/spec/`、`tools/git-hooks/` 放进**项目树**)。可在任意目录运行,不必先有测试仓。不要用 `tuner-testkit init repo`。
|
|
30
|
+
|
|
31
|
+
`uv sync` 把 **db / api 装进业务仓 `.venv`**,不是 tool 域。已有项目仓则在该仓根目录:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
uv add "tuner-testkit[db,api]>=4.0.0"
|
|
35
|
+
uv sync
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Web UI / 合录等按需再加 extra:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
uv add "tuner-testkit[web-ui]"
|
|
42
|
+
uv add "tuner-testkit[recorder]"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
测 kit 全能力(平台狗食仓等)一次打开全部能力 extra:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
uv add "tuner-testkit[all]"
|
|
49
|
+
uv sync
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 3. 开始写业务
|
|
53
|
+
|
|
54
|
+
在**项目仓**里写,不要改 site-packages 里的 kit:
|
|
55
|
+
|
|
56
|
+
| 你写什么 | 放哪里 |
|
|
57
|
+
| --- | --- |
|
|
58
|
+
| 页面 / 接口资产 | `packages/page_objects/`、`packages/api_objects/` |
|
|
59
|
+
| 业务动作 | `packages/action_words/` |
|
|
60
|
+
| BDD / pytest | `tests/features/`、`tests/pytest/` |
|
|
61
|
+
| 知识(DDL、用例) | `assets/` |
|
|
62
|
+
| 本仓私有工具 | `apps/`(`python -m apps.<name>`) |
|
|
63
|
+
|
|
64
|
+
代码里 `from tuner_testkit.db import …` / `from tuner_testkit.page_test import …`。密钥只放本机 `config/env_local.py` 或环境变量(`TUNER_ENV`、`TUNER_DB_<ALIAS>_*`),**不要提交**。
|
|
65
|
+
|
|
66
|
+
录制产物同样写到项目仓 `packages/`,不会写进 venv。
|
|
67
|
+
|
|
68
|
+
### 4. 获取 PyPI 上的更新
|
|
69
|
+
|
|
70
|
+
平台发新版本后,下游从 [PyPI:tuner-testkit](https://pypi.org/project/tuner-testkit/) 取 wheel,**不要**再拷本仓源码。tool 域和业务仓 `.venv` 是两份安装,**两边都要升**,再铺 DNA。
|
|
71
|
+
|
|
72
|
+
**先看当前装的是哪一版、PyPI 最新是哪一版:**
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
uv tool list # tool 域里的 tuner-testkit
|
|
76
|
+
cd ../my-sut-tests
|
|
77
|
+
uv pip show tuner-testkit # 业务仓 .venv
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
发行说明见 [`docs/changelog/FRAMEWORK.md`](docs/changelog/FRAMEWORK.md) 与该版本的 `docs/changelog/TEMPLATE-*.md`。
|
|
81
|
+
|
|
82
|
+
**① tool 域(只升核心 CLI)**
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
uv tool upgrade tuner-testkit
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
升的是 `tuner-init` / `tuner-dna` 所在环境。这里仍然**不要**加 `[db]` / `[api]`。尚未 `uv tool install` 过则先执行第 1 节。
|
|
89
|
+
|
|
90
|
+
**② 业务仓 `.venv`(升运行库 + extras)**
|
|
91
|
+
|
|
92
|
+
在**项目仓根目录**改依赖并同步 lock。保留你原来打开的 extra(普通仓 `[db,api]`,狗食/全能力仓 `[all]`):
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# 钉到某一发行版(推荐,和团队 lock 一致)
|
|
96
|
+
uv add "tuner-testkit[db,api]==4.2.0"
|
|
97
|
+
|
|
98
|
+
# 或只抬下限,让解析器选允许范围内的最新
|
|
99
|
+
# uv add "tuner-testkit[db,api]>=4.2.0"
|
|
100
|
+
|
|
101
|
+
uv sync
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
已经写过 `>=4.0.0`、只想把 lock 里的 kit 升到 PyPI 最新:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
uv lock --upgrade-package tuner-testkit
|
|
108
|
+
uv sync
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
只改 `pyproject.toml` 里的版本再 `uv lock` / `uv sync` 也可以。一个 wheel 不能「只升 web-ui、钉死旧 db」。
|
|
112
|
+
|
|
113
|
+
**③ 同步 DNA 并提交**
|
|
114
|
+
|
|
115
|
+
`uv add` / `uv sync` 只更新 site-packages 里的运行库。Cursor 读的是项目树里的 `.cursor/`、`docs/spec/`、`tools/git-hooks/`,必须再铺一层:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
tuner-dna sync
|
|
119
|
+
tuner-dna check
|
|
120
|
+
git add -A && git commit
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
`tuner-dna check` 核对项目树 DNA 是否与**当前 PATH 上那份** kit 一致。建议先 `uv tool upgrade`,再 `sync`,避免 CLI 还是旧包、`.venv` 已是新包。
|
|
124
|
+
|
|
125
|
+
新仓第一次仍用第 2 节的 `tuner-init scaffold`(会写依赖并做一次 `tuner-dna sync`),不是每次发版都重新 scaffold。
|
|
126
|
+
|
|
127
|
+
`[phone-ui]` 为预留空 extra,4.0 未实现。
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## extras
|
|
132
|
+
|
|
133
|
+
| extra | 内容 |
|
|
134
|
+
| --- | --- |
|
|
135
|
+
| (默认 wheel) | `config` / `logging`、`tuner-init`、`tuner-dna`(tool 域只装这个) |
|
|
136
|
+
| `[db]` | MySQL / SQL Server / PostgreSQL(装在业务仓 `.venv`) |
|
|
137
|
+
| `[api]` | `api_test`(HTTP 客户端) |
|
|
138
|
+
| `[web-ui]` | `page_test` + Playwright |
|
|
139
|
+
| `[phone-ui]` | 预留,无实现 |
|
|
140
|
+
| `[recorder]` | 合录 / 仅 UI / mitmproxy 代理 |
|
|
141
|
+
| `[mock]` | 按冻结的 api_objects 回放 |
|
|
142
|
+
| `[excel]` / `[fake]` | 表格 / 假数据 |
|
|
143
|
+
| `[bdd]` / `[test]` | behave / pytest |
|
|
144
|
+
| `[all]` | 元 extra:上述能力 extra 的并集(不含 `[dev]`) |
|
|
145
|
+
| `[dev]` | `tuner-testkit[all]`,给本仓 editable 开发 |
|
|
146
|
+
|
|
147
|
+
CLI 与 `python -m tuner_testkit.…` 等价,例如 `tuner-recorder`、`tuner-page-recorder`、`tuner-api-recorder`、`tuner-mock-server`。依赖 extra 的命令在业务仓用 `uv run tuner-dump-ddl` / `uv run tuner-recorder`。
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## 安全
|
|
152
|
+
|
|
153
|
+
不得把 token、cookie、Authorization、密码、session 写入仓库(含 capture 与 api_objects)。凭证只允许运行时注入。
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## 本仓库(平台源码)
|
|
158
|
+
|
|
159
|
+
克隆后在仓库根目录开发 kit 本身:
|
|
160
|
+
|
|
161
|
+
```powershell
|
|
162
|
+
uv venv
|
|
163
|
+
uv sync --extra all
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
`uv sync --extra dev` 与 `--extra all` 等价(`dev` 只是引用 `[all]`)。
|
|
167
|
+
|
|
168
|
+
4.2.0 发行说明见 [`docs/changelog/TEMPLATE-4.2.0.md`](docs/changelog/TEMPLATE-4.2.0.md);3.x → 4.x 迁移见 [`TEMPLATE-4.0.0.md`](docs/changelog/TEMPLATE-4.0.0.md)。平台能力地图见 [`INDEX.md`](INDEX.md)。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "tuner-testkit"
|
|
3
|
-
version = "4.0
|
|
3
|
+
version = "4.2.0"
|
|
4
4
|
description = "Shared test runtime, recorders, and DNA overlay for SUT test repos"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
|
@@ -51,23 +51,12 @@ bdd = [
|
|
|
51
51
|
"playwright>=1.54.0",
|
|
52
52
|
"behave-html-pretty-formatter>=1.16.1",
|
|
53
53
|
]
|
|
54
|
+
# Union of capability extras (excludes `dev` to avoid a cycle).
|
|
55
|
+
all = [
|
|
56
|
+
"tuner-testkit[db,api,web-ui,phone-ui,excel,fake,mock,recorder,test,bdd]",
|
|
57
|
+
]
|
|
54
58
|
dev = [
|
|
55
|
-
"
|
|
56
|
-
"pymssql>=2.3.0",
|
|
57
|
-
"psycopg[binary]>=3.2",
|
|
58
|
-
"sqlalchemy>=2.0",
|
|
59
|
-
"requests>=2.33.1",
|
|
60
|
-
"pydantic>=2",
|
|
61
|
-
"faker>=37.0.0",
|
|
62
|
-
"openpyxl>=3.1.0",
|
|
63
|
-
"fastapi>=0.115.0",
|
|
64
|
-
"uvicorn[standard]>=0.32.0",
|
|
65
|
-
"httpx>=0.28.0",
|
|
66
|
-
"pytest>=9.0.3",
|
|
67
|
-
"behave>=1.2.6",
|
|
68
|
-
"playwright>=1.54.0",
|
|
69
|
-
"behave-html-pretty-formatter>=1.16.1",
|
|
70
|
-
"mitmproxy>=11.1.3",
|
|
59
|
+
"tuner-testkit[all]",
|
|
71
60
|
]
|
|
72
61
|
|
|
73
62
|
[project.scripts]
|
|
@@ -15,7 +15,7 @@ CLI::
|
|
|
15
15
|
uv run python -m tuner_testkit.action_words list
|
|
16
16
|
uv run python -m tuner_testkit.action_words describe <word_id>
|
|
17
17
|
uv run python -m tuner_testkit.action_words run <word_id> --params '{...}'
|
|
18
|
-
uv run python -m tuner_testkit.action_words catalog --out
|
|
18
|
+
uv run python -m tuner_testkit.action_words catalog --out artifacts/catalogs/action_words_catalog.json
|
|
19
19
|
"""
|
|
20
20
|
from __future__ import annotations
|
|
21
21
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
uv run python -m tuner_testkit.action_words run db_seed.create_example --params "{...}"
|
|
8
8
|
uv run python -m tuner_testkit.action_words run db_seed.create_example --params-file p.json
|
|
9
9
|
uv run python -m tuner_testkit.action_words run db_seed.create_example --example
|
|
10
|
-
uv run python -m tuner_testkit.action_words catalog --out
|
|
10
|
+
uv run python -m tuner_testkit.action_words catalog --out artifacts/catalogs/action_words_catalog.json
|
|
11
11
|
|
|
12
12
|
``run`` 未提供 ``--params`` 时使用 ``{}``(即全部默认值);``--example``
|
|
13
13
|
使用 word 自带的 ``example_params`` 样例运行。
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bdd-asset-pipeline
|
|
3
|
+
version: 2.0.0
|
|
4
|
+
description: Lower-half of SUT self-learning — Feature Sets + design knowledge → Reuse Analysis → Freeze API Objects → Maintain Page Objects → Maintain Steps → behave regression. Use only for behave/BDD automation assets. Do NOT use when the user explicitly requests pytest. Do NOT use this agent as the explore-first entry; start from docs/spec/sut-self-learning.md instead.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# BDD Asset Pipeline Agent (lower half)
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
Coordinate the **lower half** of SUT self-learning once a feature-set entry
|
|
12
|
+
and (when available) design knowledge exist:
|
|
13
|
+
|
|
14
|
+
Feature Set item + `assets/design/**` → (optional MCP re-run) → Reuse vs
|
|
15
|
+
Create → Freeze API Objects → Update Page Objects → Implement Steps →
|
|
16
|
+
Regression run → Report.
|
|
17
|
+
|
|
18
|
+
The **upper half** (explore SUT → capability map + design knowledge) is
|
|
19
|
+
specified in `docs/spec/sut-self-learning.md`. Do not start this agent
|
|
20
|
+
when the task is still "learn the SUT / explore pages" with no feature
|
|
21
|
+
intent yet.
|
|
22
|
+
|
|
23
|
+
## Applicability
|
|
24
|
+
|
|
25
|
+
- **Use this agent** when generating or maintaining `.feature` / behave
|
|
26
|
+
steps / BDD UI·API assets **from** a feature-set entry (and design notes).
|
|
27
|
+
- **Do not use this agent** when the user **explicitly** asks for **pytest**.
|
|
28
|
+
- **Do not use this agent** as the first step of explore-first learning.
|
|
29
|
+
|
|
30
|
+
## Inputs (required)
|
|
31
|
+
|
|
32
|
+
- At least one feature-set entry (a `.feature` to write/update, or a
|
|
33
|
+
scenario intent grounded in `assets/explore/**` / `assets/usecases/**`).
|
|
34
|
+
- Prefer also: matching `assets/design/<app>/<route-slug>.md` so assertions
|
|
35
|
+
know which tables to check and which to skip as `noise`.
|
|
36
|
+
|
|
37
|
+
## Non-negotiable workflow contract (hard gates)
|
|
38
|
+
|
|
39
|
+
Same three gates as `.cursor/rules/bdd-pipeline-gates.mdc` v3:
|
|
40
|
+
|
|
41
|
+
- **Gate 1: Evidence is mandatory** (explore session OR feature run). Cite
|
|
42
|
+
`artifacts/evidence/<run_id>/`. Do not skip MCP just because local
|
|
43
|
+
`sync_playwright` UI steps pass. If MCP is blocked, stop and report.
|
|
44
|
+
- **Gate 2: Freeze is mandatory when capture has eligible routes**.
|
|
45
|
+
- **Gate 3: Run the stages that actually exist** — do not fail a missing
|
|
46
|
+
API/UI stage that was never authored.
|
|
47
|
+
|
|
48
|
+
## Skills to use (in order)
|
|
49
|
+
|
|
50
|
+
1. **Feature authoring / rewrite** — `feature-authoring` → `tests/features/**/*.feature`
|
|
51
|
+
2. **Feature review / lint** — `feature-review-lint`
|
|
52
|
+
3. **Execute scenario & capture evidence** (if no reusable evidence) —
|
|
53
|
+
`run-feature-playwright-mcp` → sanitized `artifacts/evidence/<run_id>/`
|
|
54
|
+
4. **Reuse analysis** — `reuse-analysis`
|
|
55
|
+
5. **Freeze captures into API assets** — `freeze-api-objects`
|
|
56
|
+
6. **Maintain UI assets** — `maintain-page-objects`
|
|
57
|
+
7. **Implement/repair behave steps** — `maintain-behave-steps`
|
|
58
|
+
|
|
59
|
+
Before writing Then-assertions, **read `assets/design/**`**:
|
|
60
|
+
|
|
61
|
+
- Assert `writes` (business tables) via `db_assert` / API extracts.
|
|
62
|
+
- Never assert `noise` tables (audit / operation_log) as business outcomes.
|
|
63
|
+
- Use `correlate` / `identity` to locate rows; do not hardcode scenario ids
|
|
64
|
+
into APIModel asserts.
|
|
65
|
+
|
|
66
|
+
## Cross-cutting constraints (must always hold)
|
|
67
|
+
|
|
68
|
+
- No secrets in repo: tokens/cookies/authorization/session secrets must never be written.
|
|
69
|
+
- Steps do not contain selectors or handcrafted requests.
|
|
70
|
+
- Assertions are stable and observable; no scenario constants inside API Object asserts.
|
|
71
|
+
- API execution is triggered via `APIModel.execute()` after `set_*` / `override_*`.
|
|
72
|
+
- **Binary / form APIs**: `tuner_testkit.api_test` always returns
|
|
73
|
+
`ApiResponse.content` (raw bytes). Use `APIModel.body_format="form"` when
|
|
74
|
+
capture shows `application/x-www-form-urlencoded`. For xlsx/CSV exports,
|
|
75
|
+
freeze a route-aligned asset that asserts HTTP 200 only; parse bodies with
|
|
76
|
+
`tuner_testkit.excel` in steps or `packages/<domain>` — not in
|
|
77
|
+
`packages/api_objects/`.
|
|
78
|
+
|
|
79
|
+
## Repo conventions this agent must enforce
|
|
80
|
+
|
|
81
|
+
### Stage mode (`behave --stage`)
|
|
82
|
+
|
|
83
|
+
- `behave --stage <name>` changes discovery:
|
|
84
|
+
- steps dir becomes `tests/features/<name>_steps/` (top-level `*.py` only)
|
|
85
|
+
- environment file becomes `tests/features/<name>_environment.py` (if present)
|
|
86
|
+
- Therefore `tests/features/ui_steps/` and `tests/features/api_steps/` **must**
|
|
87
|
+
have a top-level loader that imports the actual step modules.
|
|
88
|
+
|
|
89
|
+
### Step file granularity (required)
|
|
90
|
+
|
|
91
|
+
- UI: `tests/features/ui_steps/given.py`, `when.py`, `then.py`
|
|
92
|
+
- API: `tests/features/api_steps/given.py`, `when.py`, `then.py`
|
|
93
|
+
- **Do not** create domain-split step files like `auth_api_then.py`.
|
|
94
|
+
Reuse is achieved by **phrases and functions**, not by multiplying files.
|
|
95
|
+
|
|
96
|
+
## Done criteria
|
|
97
|
+
|
|
98
|
+
- Feature scenarios read well and pass lint rules.
|
|
99
|
+
- Steps are thin and reusable.
|
|
100
|
+
- `packages/api_objects/` and `packages/page_objects/` are the only place
|
|
101
|
+
with implementation details (per layer).
|
|
102
|
+
- Assertions consult design knowledge when it exists.
|
|
103
|
+
- Evidence is on disk under `artifacts/evidence/<run_id>/` (sanitized).
|
|
104
|
+
- `behave --stage ui` succeeds for UI features that exist.
|
|
105
|
+
- `behave --stage api` succeeds for API features that exist (or `--dry-run`
|
|
106
|
+
with documented TODO).
|
|
@@ -2,28 +2,34 @@
|
|
|
2
2
|
description: assets/ is the knowledge base for humans and the LLM; enforce provenance metadata, raw-vs-curated boundaries, and grounding (consult INDEX before generating)
|
|
3
3
|
globs: assets/**
|
|
4
4
|
alwaysApply: false
|
|
5
|
-
version: 1.
|
|
5
|
+
version: 1.1.0
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# assets — 知识层硬约束
|
|
9
9
|
|
|
10
10
|
`assets/` 存放给人和 LLM 阅读、作为生成测试代码/工具依据的知识。完整规范见
|
|
11
11
|
`docs/spec/assets-knowledge-syntax.md`;全局发现入口见根 `INDEX.md`。
|
|
12
|
+
SUT 自学习见 `docs/spec/sut-self-learning.md`;design schema 见
|
|
13
|
+
`docs/spec/design-knowledge-syntax.md`。
|
|
12
14
|
|
|
13
15
|
## Grounding(生成前必读)
|
|
14
16
|
|
|
15
17
|
- **生成任何测试 / action word / api·page object / 工具之前**,先查根 `INDEX.md`
|
|
16
|
-
|
|
17
|
-
`domain-notes
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
(及存在时的 `INDEX.project.md`)检索相关 domain 的知识(真实 DDL 列名、
|
|
19
|
+
`assets/sql`、`usecases` / `domain-notes` / `explore` / `design`),
|
|
20
|
+
**不要凭空臆造**列名、接口字段、业务规则。
|
|
21
|
+
- 缺知识时先回填:`/dump-ddl` 或 `python -m tuner_testkit.apps.dump_ddl`、
|
|
22
|
+
Playwright MCP 探索(落盘 `artifacts/evidence/<run_id>/`)、
|
|
23
|
+
`python -m tuner_testkit.apps.recorder` / `api_recorder`,再进入生成。
|
|
20
24
|
|
|
21
25
|
## 目录与元数据
|
|
22
26
|
|
|
23
27
|
- 目录分类固定:`ddl/<datasource>/`、`sql/`、`usecases/<domain>/`、
|
|
24
|
-
`domain-notes/<domain>/`、`testreport
|
|
28
|
+
`domain-notes/<domain>/`、`explore/<app>/`、`design/<app>/`、`testreport/`
|
|
29
|
+
(新增类别前先改 spec,再改本 rule)。
|
|
25
30
|
- 人工/半自动区文件头必须带元数据:`domain / source / date / version / confidence`
|
|
26
31
|
(Markdown 用 YAML front-matter,SQL 用顶部 `--` 注释)。
|
|
32
|
+
- `explore/` 与 `design/` 还应填 `evidence`(run_id 列表)。
|
|
27
33
|
- `confidence: high` 表示人工核实过——LLM 应优先采信。
|
|
28
34
|
|
|
29
35
|
## raw vs curated
|
|
@@ -33,10 +39,9 @@ version: 1.0.0
|
|
|
33
39
|
|
|
34
40
|
## 变更留痕
|
|
35
41
|
|
|
36
|
-
- 自动区(`ddl/`)更新由工具写 `assets/CHANGELOG.md
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
增量更新根 `INDEX.md`。
|
|
42
|
+
- 自动区(`ddl/`)更新由工具写 `assets/CHANGELOG.md`;人不手改自动区语义。
|
|
43
|
+
- curated 更新 → bump `version` + 正文追加变更说明;随后由 `maintain-index`
|
|
44
|
+
增量更新 `INDEX.md` / `INDEX.project.md`。
|
|
40
45
|
|
|
41
46
|
## 禁止
|
|
42
47
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
description: Enforce layered boundaries between feature/steps/action_words/page_objects/api_objects and tuner_testkit runtime; no selector or request leakage across layers
|
|
3
3
|
globs: **/*.py
|
|
4
4
|
alwaysApply: false
|
|
5
|
-
version: 1.3.
|
|
5
|
+
version: 1.3.1
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Asset Layering — boundary rules per layer
|
|
@@ -40,7 +40,7 @@ Each layer owns one responsibility. Leakage across layers (e.g. selectors in ste
|
|
|
40
40
|
|
|
41
41
|
## Cross-cutting
|
|
42
42
|
|
|
43
|
-
- **No secrets in repo**, ever: `Authorization`, `Cookie`, `Set-Cookie`, `*token*`, `*secret*`, `*password*`, `*session*`. Also applies to captures under `
|
|
43
|
+
- **No secrets in repo**, ever: `Authorization`, `Cookie`, `Set-Cookie`, `*token*`, `*secret*`, `*password*`, `*session*`. Also applies to captures under `artifacts/evidence/`.
|
|
44
44
|
- **Evidence-driven edits**: Page/API object changes must be backed by Playwright MCP snapshots, `tuner-recorder` / `tuner-api-recorder` captures (`python -m tuner_testkit.apps.recorder` / `api_recorder`), or run_summary findings; avoid locator/path guesses.
|
|
45
45
|
- **`tests/**` must not import `apps.*`**. Action words for BDD/pytest stay in
|
|
46
46
|
`tuner_testkit.action_words`. Opt into Plane with `@plane_db_seed` (etc.) from
|