pyplaykit 1.20.0__tar.gz → 1.20.2__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.
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/CHANGELOG.md +20 -0
- {pyplaykit-1.20.0/pyplaykit.egg-info → pyplaykit-1.20.2}/PKG-INFO +17 -1
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/README.md +16 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/core/base_page.py +9 -2
- pyplaykit-1.20.2/docs/ARCHITECTURE.md +457 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2/pyplaykit.egg-info}/PKG-INFO +17 -1
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pyplaykit.egg-info/SOURCES.txt +1 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pyproject.toml +1 -1
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/.github/copilot-instructions.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/.github/prompts/review-execution-plan-and-implement-next-task.prompt.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/.github/prompts/run-unit-tests-and-coverage.prompt.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/.github/prompts/security-audit-and-consolidated-report.prompt.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/CHOOSE_YOUR_STRUCTURE.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/CLAUDE.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/COLUMN_MAPPING_AND_IGNORE_FIELDS_GUIDE.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/COMMANDS_FOR_YOUR_PROJECTS.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/COMMIT_SUMMARY.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/CONTRIBUTING.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/CORRECTED_PROJECT_NAMES.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/DATABASE_IMPLEMENTATION_SUMMARY.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/DELIVERABLES_SUMMARY.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/ENTERPRISE_TEST_STRUCTURE.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/FINAL_PROJECT_SETUP.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/GAP_TRACKER.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/HOW_TO_ACCESS_DOCS.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/INIT_COMMAND_EXAMPLES.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/KEY_BASED_MATCHING_SOLUTION.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/MANIFEST.in +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/MIGRATION_COMPLETE.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/MIGRATION_PLAN.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/PIP_INSTALL_GUIDE.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/PYPLAYKIT_CLIENT_OVERVIEW.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/QUICK_DB_REFERENCE.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/QUICK_REFERENCE_COMPARISON_FEATURES.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/QUICK_START_QE.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/STRUCTURE_COMPARISON.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/TEST_LOCATION_CHEATSHEET.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/VISUAL_COMPARISON.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/WINDOWS_INSTALL_GUIDE.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/YOUR_PROJECTS_IMPLEMENTATION_GUIDE.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/YOUR_SETUP_SUMMARY.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/bin/README.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/components/__init__.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/components/base_component.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/components/data_table.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/components/form_field.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/components/modal.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/config/config.yaml +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/config/data_comparison_profiles.yaml +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/config/environments.yaml +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/config/projects/customs_modernization.yaml +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/config/projects/dispatcho.yaml +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/config/projects/timelyquote.yaml +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/core/__init__.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/core/base_test.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/core/browser_factory.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/core/playwright_manager.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/demo/README.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/demo/functional/database/file_comparison/README.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/demo/functional/database/postgres_src_tgt/README.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/dist_pkg/__init__.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/dist_pkg/distribution.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/API_TESTING_GUIDE.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/CLI_REFERENCE.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/COMPETITIVE_ANALYSIS.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/COVERAGE_IMPROVEMENTS.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/CUSTOMER_SCENARIOS.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/DATABASE_SUPPORT.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/DATA_VALIDATION_GUIDE.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/DELIVERABLES_INDEX.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/EXAMPLE_TESTS_SUMMARY.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/Enterprise-Framework-Assessment-REVISED.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/Enterprise-Readiness-Assessment.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/Example-Tests-Guide.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/Execution-Plan-Backlog-and-Closure-Tracker.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/FRAMEWORK_CONTRIBUTION_GUIDE.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/KT/01_ARCHITECTURE.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/KT/02_DEPLOYMENT_RUNBOOK.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/KT/03_ACCESS_MATRIX.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/KT/04_CLIENT_CONTACT_MATRIX.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/KT/05_OPEN_RISKS_REGISTER.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/KT/06_PENDING_ENHANCEMENTS.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/KT/07_PRODUCT_ROADMAP.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/KT/08_ENVIRONMENT_DETAILS.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/KT/09_OPERATIONAL_SOPS.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/KT/10_ESCALATION_MATRIX.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/KT/11_KT_RECORDINGS_INDEX.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/KT/12_REVERSE_KT_SIGNOFF.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/KT/13_LEADERSHIP_SIGNOFF.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/KT/README.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/MCP_SERVER_DESIGN.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/MULTI_DB_VALIDATION_GUIDE.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/MULTI_PROJECT_STRUCTURE.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/PIP_INSTALL_GUIDE.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/PyPlayKit-Framework-Overview.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/PyPlayKit-Usage-Scenarios.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/QE_VISUAL_GUIDE.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/RESILIENCE_GUIDE.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/RUN_TESTS_QUICK_REFERENCE.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/TEST_ORGANIZATION.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/docs/Usage-Scenarios-Feasibility-Analysis.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/integrations/__init__.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/integrations/adapters.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/mcp_server/__init__.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/mcp_server/_ast_utils.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/mcp_server/_config_utils.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/mcp_server/cli.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/mcp_server/server.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/mcp_server/tools/__init__.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/mcp_server/tools/package_discovery.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/mcp_server/tools/project_introspection.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/mcp_server/tools/project_state.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/orchestration/__init__.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/orchestration/enforcer.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/orchestration/planner.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pages/__init__.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pages/dashboard_page.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pages/login_page.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pages/orangehrm_login_page.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pages/saucedemo_inventory_page.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pages/saucedemo_login_page.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/plugins/__init__.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/plugins/api_plugin.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/plugins/base.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/plugins/data_plugin.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/plugins/registry.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/plugins/security_plugin.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pyplaykit/PIP_INSTALL_GUIDE.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pyplaykit/README.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pyplaykit/__init__.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pyplaykit/cli.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pyplaykit/config/__init__.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pyplaykit/config/config.yaml +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pyplaykit/config/environments.yaml +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pyplaykit/config/projects/customs_modernization.yaml +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pyplaykit/config/projects/dispatcho.yaml +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pyplaykit/config/projects/timelyquote.yaml +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pyplaykit/plugin.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pyplaykit/show_docs.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pyplaykit.egg-info/dependency_links.txt +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pyplaykit.egg-info/entry_points.txt +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pyplaykit.egg-info/requires.txt +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/pyplaykit.egg-info/top_level.txt +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/resilience/__init__.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/resilience/locator_recovery.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/setup.cfg +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/test_data/api/ecom/auth_payloads.json +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/test_data/api/ecom/product_payloads.json +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/test_data/api_test_data.json +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/test_data/data_validation_test_data.json +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/test_data/login_test_data.json +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/test_data/orangehrm_login_data.json +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/test_data/ui_test_data.json +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/tests/projects/README.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/tests/projects/customs_modernization/README.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/tests/projects/demo/functional/README.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/tests/projects/demo/functional/api/README.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/tests/projects/demo/functional/database/README.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/tests/projects/demo/functional/ui/README.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/tests/projects/demo/integration/README.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/tests/projects/dispatcho/README.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/tests/projects/timelyquote/README.md +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/__init__.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/api_client.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/api_test_helper.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/assertion_helper.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/auth_manager.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/comparison_config_loader.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/data_comparison_report.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/data_comparison_utils.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/data_loader.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/data_source.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/data_validator.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/database_clients.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/db_client.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/db_drivers/__init__.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/db_drivers/db2.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/db_drivers/informix.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/db_drivers/mysql.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/db_drivers/oracle.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/db_drivers/snowflake.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/db_drivers/sqlite.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/db_drivers/sqlserver.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/db_factory.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/db_fixtures.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/db_pool.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/db_validation_helper.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/environment_validator.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/file_reader.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/graphql_client.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/logger.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/observability.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/observability_report.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/project_config.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/response_validator.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/screenshot_helper.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/soap_client.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/tdm.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/transformation_validator.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/ui_db_validator.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/version_checker.py +0 -0
- {pyplaykit-1.20.0 → pyplaykit-1.20.2}/utils/yaml_config_reader.py +0 -0
|
@@ -11,6 +11,26 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
+
## [1.20.2] — 2026-08-19
|
|
15
|
+
|
|
16
|
+
### Documentation
|
|
17
|
+
|
|
18
|
+
- **Comprehensive architecture documentation** — added `docs/ARCHITECTURE.md`, a living multi-view reference with 9 Mermaid diagrams (layered overview, runtime fixture lifecycle, test/page/resilience flow, config & multi-project resolution, DB stack & data-comparison, plugins/orchestration/observability/integrations, MCP server, security posture, repository map).
|
|
19
|
+
- **Regenerated architecture SVGs to match the current implementation** — `docs/diagrams/architecture_overview.svg` now shows the real 9-layer dependency stack plus the plugins/orchestration/resilience cross-cutting layers, the MCP read-only sidecar, and a security & governance rail; dropped the unsupported "Mobile/Desktop" target. `docs/diagrams/data_comparison_flow.svg` was re-laid-out to remove overlapping boxes/labels and corrected to the real `ComparisonProfile` fields.
|
|
20
|
+
- **New security posture diagram** — `docs/diagrams/security_posture.svg` documents defense-in-depth: runtime secrets/masking/auth controls plus the bandit / pip-audit / gitleaks CI scanning pipeline (with `security_plugin.py` shown honestly as a stub/extension point).
|
|
21
|
+
- **Fixed SVG rendering** — escaped raw `&` characters that caused `xmlParseEntityRef` parse errors when opening the SVGs in a browser.
|
|
22
|
+
- **README diagram embeds for PyPI** — added inline PNG previews (rendered via new `scripts/svg_to_png.py`) that display on the PyPI page and link to the crisp SVG sources.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## [1.20.1] — 2026-08-17
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- **`BasePage.wait_for_url_contains()` no longer raises `value must be a string or regular expression`** — it previously called `expect(page).to_have_url(lambda url: url_part in url)`, but Playwright's `to_have_url()` only accepts a string or regex, not a predicate. It now uses Playwright's native `page.wait_for_url(f"**{url_part}**")` glob pattern, which matches the partial path regardless of scheme, host, or trailing query string.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
14
34
|
## [1.20.0] — 2026-08-14
|
|
15
35
|
|
|
16
36
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyplaykit
|
|
3
|
-
Version: 1.20.
|
|
3
|
+
Version: 1.20.2
|
|
4
4
|
Summary: Enterprise Python + Playwright automation framework
|
|
5
5
|
Author-email: Shan Konduru <shankonduru@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -207,6 +207,22 @@ tests/
|
|
|
207
207
|
8. **Resilience Layer** (`resilience/`) - Self-healing locator resolution
|
|
208
208
|
9. **Integration Layer** (`integrations/`) - Jira and test management adapters
|
|
209
209
|
|
|
210
|
+
### Architecture Diagrams
|
|
211
|
+
|
|
212
|
+
**Architecture Overview** — the full layered dependency stack, cross-cutting layers (plugins, orchestration, resilience), the MCP read-only sidecar, and the security & governance rail:
|
|
213
|
+
|
|
214
|
+
[](https://github.com/ShanKonduru/pyplaykit/blob/master/docs/diagrams/architecture_overview.svg)
|
|
215
|
+
|
|
216
|
+
**Data Comparison Flow** — config-driven Excel / CSV / DB comparison: sources → loader → comparison engine → result + HTML report:
|
|
217
|
+
|
|
218
|
+
[](https://github.com/ShanKonduru/pyplaykit/blob/master/docs/diagrams/data_comparison_flow.svg)
|
|
219
|
+
|
|
220
|
+
**Security Posture** — defense-in-depth: runtime secrets/masking/auth controls plus the bandit / pip-audit / gitleaks CI scanning pipeline:
|
|
221
|
+
|
|
222
|
+
[](https://github.com/ShanKonduru/pyplaykit/blob/master/docs/diagrams/security_posture.svg)
|
|
223
|
+
|
|
224
|
+
> Each image is a PNG (renders inline on PyPI and GitHub) and links to the crisp, zoomable **SVG** source. See also the **[Full Architecture Reference](https://github.com/ShanKonduru/pyplaykit/blob/master/docs/ARCHITECTURE.md)** — 9 Mermaid views covering layers, runtime lifecycle, config resolution, data engineering, plugins/observability, MCP, and security. Regenerate PNGs after editing an SVG with `python scripts/svg_to_png.py`.
|
|
225
|
+
|
|
210
226
|
---
|
|
211
227
|
|
|
212
228
|
## Project Structure
|
|
@@ -110,6 +110,22 @@ tests/
|
|
|
110
110
|
8. **Resilience Layer** (`resilience/`) - Self-healing locator resolution
|
|
111
111
|
9. **Integration Layer** (`integrations/`) - Jira and test management adapters
|
|
112
112
|
|
|
113
|
+
### Architecture Diagrams
|
|
114
|
+
|
|
115
|
+
**Architecture Overview** — the full layered dependency stack, cross-cutting layers (plugins, orchestration, resilience), the MCP read-only sidecar, and the security & governance rail:
|
|
116
|
+
|
|
117
|
+
[](https://github.com/ShanKonduru/pyplaykit/blob/master/docs/diagrams/architecture_overview.svg)
|
|
118
|
+
|
|
119
|
+
**Data Comparison Flow** — config-driven Excel / CSV / DB comparison: sources → loader → comparison engine → result + HTML report:
|
|
120
|
+
|
|
121
|
+
[](https://github.com/ShanKonduru/pyplaykit/blob/master/docs/diagrams/data_comparison_flow.svg)
|
|
122
|
+
|
|
123
|
+
**Security Posture** — defense-in-depth: runtime secrets/masking/auth controls plus the bandit / pip-audit / gitleaks CI scanning pipeline:
|
|
124
|
+
|
|
125
|
+
[](https://github.com/ShanKonduru/pyplaykit/blob/master/docs/diagrams/security_posture.svg)
|
|
126
|
+
|
|
127
|
+
> Each image is a PNG (renders inline on PyPI and GitHub) and links to the crisp, zoomable **SVG** source. See also the **[Full Architecture Reference](https://github.com/ShanKonduru/pyplaykit/blob/master/docs/ARCHITECTURE.md)** — 9 Mermaid views covering layers, runtime lifecycle, config resolution, data engineering, plugins/observability, MCP, and security. Regenerate PNGs after editing an SVG with `python scripts/svg_to_png.py`.
|
|
128
|
+
|
|
113
129
|
---
|
|
114
130
|
|
|
115
131
|
## Project Structure
|
|
@@ -23,8 +23,15 @@ class BasePage:
|
|
|
23
23
|
self.page.goto(url, wait_until="domcontentloaded")
|
|
24
24
|
|
|
25
25
|
def wait_for_url_contains(self, url_part: str) -> None:
|
|
26
|
-
"""Wait until current page URL contains
|
|
27
|
-
|
|
26
|
+
"""Wait until the current page URL contains ``url_part``.
|
|
27
|
+
|
|
28
|
+
Uses Playwright's native :meth:`Page.wait_for_url` with a glob pattern.
|
|
29
|
+
``to_have_url`` only accepts a string or regex — passing a predicate
|
|
30
|
+
raises ``value must be a string or regular expression`` — so we wrap
|
|
31
|
+
``url_part`` in ``**`` wildcards to match any surrounding URL segments
|
|
32
|
+
(scheme, host, trailing query string, etc.).
|
|
33
|
+
"""
|
|
34
|
+
self.page.wait_for_url(f"**{url_part}**")
|
|
28
35
|
|
|
29
36
|
def wait_for_visible(
|
|
30
37
|
self,
|
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
# PyPlayKit — Architecture
|
|
2
|
+
|
|
3
|
+
> Comprehensive architecture reference for the PyPlayKit enterprise test‑automation framework.
|
|
4
|
+
> Diagrams are authored in [Mermaid](https://mermaid.js.org/) and render natively on GitHub.
|
|
5
|
+
> Keep this file in sync with the code — it is the living architecture document.
|
|
6
|
+
|
|
7
|
+
**Contents**
|
|
8
|
+
|
|
9
|
+
1. [Layered Architecture Overview](#1-layered-architecture-overview)
|
|
10
|
+
2. [Runtime Fixture Lifecycle](#2-runtime-fixture-lifecycle)
|
|
11
|
+
3. [Test → Page → Resilience Execution Flow](#3-test--page--resilience-execution-flow)
|
|
12
|
+
4. [Configuration & Multi‑Project Resolution](#4-configuration--multi-project-resolution)
|
|
13
|
+
5. [Data Engineering: DB Stack & Data Comparison](#5-data-engineering-db-stack--data-comparison)
|
|
14
|
+
6. [Plugins, Orchestration, Observability & Integrations](#6-plugins-orchestration-observability--integrations)
|
|
15
|
+
7. [MCP Server & CLI](#7-mcp-server--cli)
|
|
16
|
+
8. [Security Posture](#8-security-posture)
|
|
17
|
+
9. [Repository Map](#9-repository-map)
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 1. Layered Architecture Overview
|
|
22
|
+
|
|
23
|
+
The framework enforces a strict layered architecture. Higher layers depend downward only;
|
|
24
|
+
cross‑cutting concerns (plugins, resilience, observability, integrations) attach to the core flow.
|
|
25
|
+
|
|
26
|
+
```mermaid
|
|
27
|
+
flowchart TB
|
|
28
|
+
subgraph AUT["Applications Under Test"]
|
|
29
|
+
direction LR
|
|
30
|
+
SD["SauceDemo"]
|
|
31
|
+
OHRM["OrangeHRM"]
|
|
32
|
+
PROJ["Multi-project apps<br/>(customers_modernization,<br/>dispatcho, timelyquote)"]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
subgraph TEST["1 · Test Layer — tests/"]
|
|
36
|
+
direction LR
|
|
37
|
+
TF["functional / integration"]
|
|
38
|
+
TP["projects/*"]
|
|
39
|
+
TU["unit/*"]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
subgraph PAGE["2 · Page Object & Component Layer — pages/ · components/"]
|
|
43
|
+
direction LR
|
|
44
|
+
PO["Page Objects<br/>login, dashboard, inventory…"]
|
|
45
|
+
COMP["Reusable Components<br/>data_table, form_field, modal"]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
subgraph CORE["3 · Core Engine Layer — core/"]
|
|
49
|
+
direction LR
|
|
50
|
+
PM["PlaywrightManager<br/>(session)"]
|
|
51
|
+
BF["BrowserFactory<br/>(per test)"]
|
|
52
|
+
BP["BasePage / BaseTest"]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
subgraph UTIL["4 · Utilities Layer — utils/"]
|
|
56
|
+
direction LR
|
|
57
|
+
UAPI["API/GraphQL/SOAP clients"]
|
|
58
|
+
UDB["DB stack + comparison"]
|
|
59
|
+
UDATA["data_loader · tdm · validators"]
|
|
60
|
+
UOBS["logger · observability · screenshots"]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
subgraph CONF["5 · Configuration Layer — config/"]
|
|
64
|
+
direction LR
|
|
65
|
+
CY["config.yaml"]
|
|
66
|
+
CE["environments.yaml"]
|
|
67
|
+
CP["projects/* · comparison_profiles"]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
subgraph XCUT["Cross-Cutting Layers"]
|
|
71
|
+
direction LR
|
|
72
|
+
PLUG["6 · Plugins<br/>plugins/"]
|
|
73
|
+
ORCH["7 · Orchestration<br/>orchestration/"]
|
|
74
|
+
RES["8 · Resilience<br/>resilience/"]
|
|
75
|
+
INTG["9 · Integrations<br/>integrations/"]
|
|
76
|
+
MCP["MCP Server<br/>mcp_server/"]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
AUT --> TEST
|
|
80
|
+
TEST --> PAGE
|
|
81
|
+
PAGE --> CORE
|
|
82
|
+
PAGE --> COMP
|
|
83
|
+
CORE --> UTIL
|
|
84
|
+
TEST --> UTIL
|
|
85
|
+
UTIL --> CONF
|
|
86
|
+
CORE --> CONF
|
|
87
|
+
|
|
88
|
+
PLUG -. hooks .-> TEST
|
|
89
|
+
ORCH -. suite planning .-> TEST
|
|
90
|
+
RES -. self-healing .-> CORE
|
|
91
|
+
INTG -. export .-> UOBS
|
|
92
|
+
MCP -. read-only introspection .-> CONF
|
|
93
|
+
MCP -. read-only introspection .-> TEST
|
|
94
|
+
|
|
95
|
+
classDef aut fill:#fef3c7,stroke:#d97706,color:#78350f;
|
|
96
|
+
classDef test fill:#dbeafe,stroke:#2563eb,color:#1e3a8a;
|
|
97
|
+
classDef page fill:#e0e7ff,stroke:#4f46e5,color:#312e81;
|
|
98
|
+
classDef core fill:#dcfce7,stroke:#16a34a,color:#14532d;
|
|
99
|
+
classDef util fill:#f1f5f9,stroke:#475569,color:#0f172a;
|
|
100
|
+
classDef conf fill:#fae8ff,stroke:#a21caf,color:#701a75;
|
|
101
|
+
classDef xcut fill:#ffe4e6,stroke:#e11d48,color:#881337;
|
|
102
|
+
class SD,OHRM,PROJ aut;
|
|
103
|
+
class TF,TP,TU test;
|
|
104
|
+
class PO,COMP page;
|
|
105
|
+
class PM,BF,BP core;
|
|
106
|
+
class UAPI,UDB,UDATA,UOBS util;
|
|
107
|
+
class CY,CE,CP conf;
|
|
108
|
+
class PLUG,ORCH,RES,INTG,MCP xcut;
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## 2. Runtime Fixture Lifecycle
|
|
114
|
+
|
|
115
|
+
`conftest.py` wires the entire runtime. This sequence shows session start → per‑test execution → session teardown,
|
|
116
|
+
including how the plugin registry and observability tracker are stashed on the pytest `config` object.
|
|
117
|
+
|
|
118
|
+
```mermaid
|
|
119
|
+
sequenceDiagram
|
|
120
|
+
autonumber
|
|
121
|
+
participant CLI as pytest CLI<br/>(--pyplaykit-*)
|
|
122
|
+
participant CF as conftest.py
|
|
123
|
+
participant RO as runtime_options
|
|
124
|
+
participant PR as PluginRegistry
|
|
125
|
+
participant OT as ObservabilityTracker
|
|
126
|
+
participant PM as PlaywrightManager
|
|
127
|
+
participant T as Test Function
|
|
128
|
+
participant BF as BrowserFactory
|
|
129
|
+
participant PG as Page Object
|
|
130
|
+
|
|
131
|
+
Note over CLI,CF: Session start (session-scoped fixtures)
|
|
132
|
+
CLI->>CF: pytest_addoption / collection
|
|
133
|
+
CF->>RO: resolve config + CLI overrides<br/>(env, browser, base_url, tdm_policy,<br/>resilience_policy)
|
|
134
|
+
CF->>PR: build & on_session_start()
|
|
135
|
+
CF->>OT: create tracker (setattr on config)
|
|
136
|
+
CF->>PM: launch Playwright runtime
|
|
137
|
+
|
|
138
|
+
loop Each test
|
|
139
|
+
Note over CF,PG: Function-scoped fixtures
|
|
140
|
+
CF->>BF: create browser (per test)
|
|
141
|
+
BF->>BF: new isolated context
|
|
142
|
+
BF->>PG: new page
|
|
143
|
+
CF->>T: inject page, runtime_options,<br/>db_client, auth_token, logger…
|
|
144
|
+
T->>PG: high-level page actions
|
|
145
|
+
PG-->>T: results / assertions
|
|
146
|
+
CF->>CF: pytest_runtest_makereport
|
|
147
|
+
CF->>OT: record outcome + classify failure
|
|
148
|
+
CF->>PR: on_test_result(hook)
|
|
149
|
+
alt failure
|
|
150
|
+
CF->>CF: capture_artifacts_on_failure<br/>(screenshot / video)
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
Note over CF,OT: Session teardown
|
|
155
|
+
CF->>PR: on_session_finish()
|
|
156
|
+
CF->>OT: write observability + KPI + persona reports
|
|
157
|
+
CF->>PM: stop Playwright
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## 3. Test → Page → Resilience Execution Flow
|
|
163
|
+
|
|
164
|
+
How a test action flows through `BasePage` into Playwright, with the optional self‑healing locator path
|
|
165
|
+
(disabled by default; enabled via `resilience.enabled`).
|
|
166
|
+
|
|
167
|
+
```mermaid
|
|
168
|
+
flowchart TB
|
|
169
|
+
T["Test calls page method<br/>e.g. login_page.login(user, pass)"] --> BP["BasePage action<br/>click / fill / text / wait_for_visible"]
|
|
170
|
+
BP --> POL{"resilience_policy<br/>enabled?"}
|
|
171
|
+
|
|
172
|
+
POL -- No --> DIRECT["Direct Playwright locator<br/>page.locator(selector)"]
|
|
173
|
+
POL -- Yes --> RES["resolve_visible_locator()"]
|
|
174
|
+
|
|
175
|
+
RES --> P1["Try primary selector"]
|
|
176
|
+
P1 --> OK1{"visible?"}
|
|
177
|
+
OK1 -- Yes --> DONE["Return locator<br/>confidence = 1.0"]
|
|
178
|
+
OK1 -- No --> FB["Iterate fallback_selectors<br/>(confidence decays per hop)"]
|
|
179
|
+
FB --> RETRY["DOM retry loop<br/>(dom_retry_count)"]
|
|
180
|
+
RETRY --> OK2{"resolved?"}
|
|
181
|
+
OK2 -- Yes --> AUDIT["Write recovery_audit.jsonl<br/>+ decayed confidence"]
|
|
182
|
+
OK2 -- No --> FAIL["Raise / timeout"]
|
|
183
|
+
AUDIT --> DONE
|
|
184
|
+
|
|
185
|
+
DIRECT --> ACT["Perform action"]
|
|
186
|
+
DONE --> ACT
|
|
187
|
+
ACT --> ASSERT["Assertions via<br/>utils/assertion_helper"]
|
|
188
|
+
|
|
189
|
+
classDef start fill:#dbeafe,stroke:#2563eb;
|
|
190
|
+
classDef res fill:#ffe4e6,stroke:#e11d48;
|
|
191
|
+
classDef ok fill:#dcfce7,stroke:#16a34a;
|
|
192
|
+
class T,BP start;
|
|
193
|
+
class RES,P1,FB,RETRY,AUDIT res;
|
|
194
|
+
class DONE,ACT,ASSERT ok;
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## 4. Configuration & Multi‑Project Resolution
|
|
200
|
+
|
|
201
|
+
Config is layered and CLI‑overridable. Multi‑project support lets one framework instance target
|
|
202
|
+
several applications, each with its own pages, test data, and environment config.
|
|
203
|
+
|
|
204
|
+
```mermaid
|
|
205
|
+
flowchart LR
|
|
206
|
+
subgraph SRC["Config Sources (lowest → highest precedence)"]
|
|
207
|
+
direction TB
|
|
208
|
+
D["config/config.yaml<br/>framework defaults"]
|
|
209
|
+
E["config/environments.yaml<br/>per-env URLs & settings"]
|
|
210
|
+
P["config/projects/*<br/>per-project overrides"]
|
|
211
|
+
ENV["Environment variables<br/>${PYPLAYKIT_*} credentials"]
|
|
212
|
+
CLI["CLI flags<br/>--pyplaykit-env / -browser /<br/>-base-url / -headed"]
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
D --> RO["runtime_options fixture<br/>(resolved config)"]
|
|
216
|
+
E --> RO
|
|
217
|
+
P --> RO
|
|
218
|
+
ENV --> RO
|
|
219
|
+
CLI --> RO
|
|
220
|
+
|
|
221
|
+
RO --> CR["ConfigReader<br/>(env-aware .get())"]
|
|
222
|
+
RO --> Test["Tests & Pages"]
|
|
223
|
+
|
|
224
|
+
subgraph PROJECTS["Multi-Project Fan-out"]
|
|
225
|
+
direction TB
|
|
226
|
+
PGD["pages/{customers_modernization,<br/>dispatcho, timelyquote}"]
|
|
227
|
+
TDD["test_data/{...}"]
|
|
228
|
+
TPD["tests/projects/*"]
|
|
229
|
+
end
|
|
230
|
+
CR --> PROJECTS
|
|
231
|
+
|
|
232
|
+
classDef src fill:#fae8ff,stroke:#a21caf;
|
|
233
|
+
class D,E,P,ENV,CLI src;
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## 5. Data Engineering: DB Stack & Data Comparison
|
|
239
|
+
|
|
240
|
+
PyPlayKit ships a multi‑engine database stack plus a data‑comparison engine used for
|
|
241
|
+
data‑migration / ETL validation (Excel ↔ CSV ↔ DB in any direction), driven by declarative profiles.
|
|
242
|
+
|
|
243
|
+
### 5a. Database stack
|
|
244
|
+
|
|
245
|
+
```mermaid
|
|
246
|
+
flowchart TB
|
|
247
|
+
FIX["db_pool / db_client fixtures<br/>(conftest.py)"] --> POOL["DbConnectionPool<br/>utils/db_pool.py"]
|
|
248
|
+
POOL --> FACT["DbClientFactory<br/>utils/db_factory.py"]
|
|
249
|
+
FACT --> DRV["utils/db_drivers/*<br/>(lazy-imported)"]
|
|
250
|
+
|
|
251
|
+
DRV --> PG["postgresql · psycopg2"]
|
|
252
|
+
DRV --> SL["sqlite · stdlib"]
|
|
253
|
+
DRV --> MY["mysql"]
|
|
254
|
+
DRV --> MS["sqlserver · pyodbc"]
|
|
255
|
+
DRV --> OR["oracle"]
|
|
256
|
+
DRV --> D2["db2"]
|
|
257
|
+
DRV --> IN["informix"]
|
|
258
|
+
DRV --> SN["snowflake"]
|
|
259
|
+
|
|
260
|
+
FIX --> TX["db_transaction / db_seed / db_clean<br/>(test data lifecycle)"]
|
|
261
|
+
|
|
262
|
+
classDef db fill:#dcfce7,stroke:#16a34a;
|
|
263
|
+
class PG,SL,MY,MS,OR,D2,IN,SN db;
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### 5b. Data comparison & validation flow
|
|
267
|
+
|
|
268
|
+
```mermaid
|
|
269
|
+
flowchart LR
|
|
270
|
+
subgraph SOURCES["Data Sources — utils/data_source.py"]
|
|
271
|
+
XL["Excel"]
|
|
272
|
+
CSV["CSV"]
|
|
273
|
+
DB["Database"]
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
PROF["Comparison Profile<br/>config/data_comparison_profiles.yaml<br/>→ comparison_config_loader"] --> CMP
|
|
277
|
+
|
|
278
|
+
subgraph CMP["data_comparison_utils.py"]
|
|
279
|
+
direction TB
|
|
280
|
+
MAP["_apply_column_mapping"]
|
|
281
|
+
KEY["_build_row_key (key columns)"]
|
|
282
|
+
COMPARE["compare_* (excel/csv/db,<br/>any direction) → ComparisonResult"]
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
SOURCES --> CMP
|
|
286
|
+
MAP --> KEY --> COMPARE
|
|
287
|
+
|
|
288
|
+
COMPARE --> TV["TransformationValidator<br/>ColumnSpec / RowRule / PairRule"]
|
|
289
|
+
COMPARE --> UIDB["UIDbValidator<br/>(UI ↔ DB reconciliation)"]
|
|
290
|
+
COMPARE --> RPT["data_comparison_report<br/>+ tolerances → HTML/JSON report"]
|
|
291
|
+
|
|
292
|
+
classDef s fill:#fef3c7,stroke:#d97706;
|
|
293
|
+
class XL,CSV,DB s;
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## 6. Plugins, Orchestration, Observability & Integrations
|
|
299
|
+
|
|
300
|
+
The cross‑cutting layers that wrap the test session. All are config‑gated and disabled by default.
|
|
301
|
+
|
|
302
|
+
```mermaid
|
|
303
|
+
flowchart TB
|
|
304
|
+
subgraph PLUGINS["Plugin Layer — plugins/"]
|
|
305
|
+
REG["PluginRegistry<br/>BUILTIN_PLUGIN_FACTORIES"]
|
|
306
|
+
API["api_plugin"]
|
|
307
|
+
DATA["data_plugin"]
|
|
308
|
+
SEC["security_plugin"]
|
|
309
|
+
REG --> API & DATA & SEC
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
subgraph HOOKS["Lifecycle Hooks (FrameworkPlugin)"]
|
|
313
|
+
H1["on_session_start"]
|
|
314
|
+
H2["on_test_result"]
|
|
315
|
+
H3["on_session_finish"]
|
|
316
|
+
end
|
|
317
|
+
REG --> HOOKS
|
|
318
|
+
|
|
319
|
+
subgraph ORCH["Orchestration — orchestration/"]
|
|
320
|
+
PLAN["planner.build_orchestration_plan()<br/>dependency graph + cycle detection"]
|
|
321
|
+
ENF["enforcer<br/>stage-based execution constraints"]
|
|
322
|
+
PLAN --> ENF
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
subgraph OBS["Observability — utils/observability*"]
|
|
326
|
+
TRK["ObservabilityTracker<br/>outcomes · duration · failure class"]
|
|
327
|
+
FLAKY["flaky detection"]
|
|
328
|
+
PERS["persona reports:<br/>engineering / qa / leadership"]
|
|
329
|
+
TRK --> FLAKY --> PERS
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
subgraph INTG["Integrations — integrations/adapters.py"]
|
|
333
|
+
JIRA["Jira adapter"]
|
|
334
|
+
TMS["Test management adapter"]
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
HOOKS --> TRK
|
|
338
|
+
PERS --> INTG
|
|
339
|
+
PERS --> REPORTS["reports/observability/*.json"]
|
|
340
|
+
JIRA & TMS --> IEXP["reports/integrations/*.json"]
|
|
341
|
+
|
|
342
|
+
classDef p fill:#ffe4e6,stroke:#e11d48;
|
|
343
|
+
class REG,API,DATA,SEC,PLAN,ENF,TRK,FLAKY,PERS,JIRA,TMS p;
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## 7. MCP Server & CLI
|
|
349
|
+
|
|
350
|
+
`mcp_server/` exposes 11 read‑only introspection tools over the Model Context Protocol for AI assistants,
|
|
351
|
+
each also available as a `pyplaykit-mcp` CLI subcommand. Tools are grouped into three categories.
|
|
352
|
+
|
|
353
|
+
```mermaid
|
|
354
|
+
flowchart LR
|
|
355
|
+
AI["AI Assistant<br/>(Claude / Copilot)"] -->|MCP| SRV["mcp_server/server.py"]
|
|
356
|
+
TERM["Terminal / AI IDE"] -->|subcommand| CLIe["mcp_server/cli.py"]
|
|
357
|
+
SRV --> TOOLS
|
|
358
|
+
CLIe --> TOOLS
|
|
359
|
+
|
|
360
|
+
subgraph TOOLS["mcp_server/tools/"]
|
|
361
|
+
direction TB
|
|
362
|
+
subgraph PD["package_discovery"]
|
|
363
|
+
T1["list_utilities"]
|
|
364
|
+
T2["get_module_api"]
|
|
365
|
+
T3["search_methods"]
|
|
366
|
+
T4["get_base_page_api"]
|
|
367
|
+
end
|
|
368
|
+
subgraph PI["project_introspection"]
|
|
369
|
+
T5["summarize_project"]
|
|
370
|
+
T6["list_tests"]
|
|
371
|
+
T7["list_pages"]
|
|
372
|
+
end
|
|
373
|
+
subgraph PS["project_state"]
|
|
374
|
+
T8["get_test_results"]
|
|
375
|
+
T9["get_config"]
|
|
376
|
+
T10["check_environment_readiness"]
|
|
377
|
+
T11["get_comparison_profiles"]
|
|
378
|
+
end
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
PD -. reads .-> CODE["source + AST<br/>(_ast_utils)"]
|
|
382
|
+
PI -. reads .-> PROJ["pages / tests"]
|
|
383
|
+
PS -. reads .-> STATE["config · reports ·<br/>live HTTP check"]
|
|
384
|
+
|
|
385
|
+
classDef mcp fill:#e0e7ff,stroke:#4f46e5;
|
|
386
|
+
class T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 mcp;
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
391
|
+
## 8. Security Posture
|
|
392
|
+
|
|
393
|
+
Security is **cross-cutting** — it is not a single module but a set of controls that touch config, runtime,
|
|
394
|
+
and CI. See also the rendered diagram: [`docs/diagrams/security_posture.svg`](diagrams/security_posture.svg).
|
|
395
|
+
|
|
396
|
+
```mermaid
|
|
397
|
+
flowchart TB
|
|
398
|
+
subgraph RUNTIME["Runtime security — every test session"]
|
|
399
|
+
direction LR
|
|
400
|
+
SEC["1 · Secrets & Config<br/>env-var creds only ·<br/>${ENV_VAR} placeholders ·<br/>no hardcoded secrets"]
|
|
401
|
+
DP["2 · Data Protection<br/>tdm.mask_value/mask_record<br/>(full · partial) · masking_rules ·<br/>deterministic synthetic data"]
|
|
402
|
+
AUTH["3 · Authentication<br/>AuthTokenManager · Bearer<br/>lazy fetch + cache ·<br/>401 auto-refresh"]
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
subgraph CI["Static & supply-chain scanning — CI / on-demand"]
|
|
406
|
+
direction LR
|
|
407
|
+
BANDIT["bandit — Python SAST"]
|
|
408
|
+
AUDIT["pip-audit — dependency CVEs"]
|
|
409
|
+
LEAKS["gitleaks — secrets (dir + git history)"]
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
RUN["scripts/run_security_reports.{sh,bat}<br/>(self-bootstrapping venv)"] --> CI
|
|
413
|
+
BANDIT & AUDIT & LEAKS --> RPT["Consolidated HTML + per-tool json<br/>reports/secutiry_reports/"]
|
|
414
|
+
RPT --> GATE["Triage & gate:<br/>remediate / suppress ·<br/>block release on high severity"]
|
|
415
|
+
|
|
416
|
+
EXT["plugins/security_plugin.py<br/>(lifecycle-hook stub — extension point)"] -. wire via PluginRegistry .-> RUNTIME
|
|
417
|
+
|
|
418
|
+
classDef sec fill:#fef2f2,stroke:#dc2626,color:#7f1d1d;
|
|
419
|
+
classDef scan fill:#fee2e2,stroke:#b91c1c,color:#7f1d1d;
|
|
420
|
+
class SEC,DP,AUTH sec;
|
|
421
|
+
class BANDIT,AUDIT,LEAKS scan;
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
> **Honest scope note:** `plugins/security_plugin.py` is currently a registered *extension point* (a stub),
|
|
425
|
+
> not a working scanner. The active scanning is the bandit / pip-audit / gitleaks pipeline above. DAST,
|
|
426
|
+
> auth fuzzing, and in-run security assertions are not implemented — wire them through the plugin hook if needed.
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
## 9. Repository Map
|
|
431
|
+
|
|
432
|
+
```mermaid
|
|
433
|
+
flowchart LR
|
|
434
|
+
ROOT["pyplaykit/"] --> C["core/ — Playwright lifecycle, BasePage/BaseTest"]
|
|
435
|
+
ROOT --> PG["pages/ — page objects (+ per-project subdirs)"]
|
|
436
|
+
ROOT --> CO["components/ — reusable UI components"]
|
|
437
|
+
ROOT --> U["utils/ — clients, DB stack, comparison, tdm, observability"]
|
|
438
|
+
ROOT --> CFG["config/ — config.yaml, environments.yaml, projects/, profiles"]
|
|
439
|
+
ROOT --> PL["plugins/ — registry + api/data/security plugins"]
|
|
440
|
+
ROOT --> OR["orchestration/ — planner + enforcer"]
|
|
441
|
+
ROOT --> RE["resilience/ — locator_recovery"]
|
|
442
|
+
ROOT --> IN["integrations/ — Jira / TMS adapters"]
|
|
443
|
+
ROOT --> MC["mcp_server/ — server, cli, tools/"]
|
|
444
|
+
ROOT --> TE["tests/ — functional, integration, projects, unit"]
|
|
445
|
+
ROOT --> TD["test_data/ — fixtures (+ per-project subdirs)"]
|
|
446
|
+
ROOT --> DO["docs/ — guides + diagrams/"]
|
|
447
|
+
ROOT --> RP["reports/ — coverage, observability, screenshots, videos"]
|
|
448
|
+
ROOT --> CT["conftest.py — fixture wiring & pytest hooks"]
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
---
|
|
452
|
+
|
|
453
|
+
### Diagram maintenance
|
|
454
|
+
|
|
455
|
+
- **Source of truth:** this file. When you add a layer, plugin, driver, or MCP tool, update the relevant diagram here.
|
|
456
|
+
- **Rendering:** GitHub, VS Code (Mermaid preview), and most IDEs render these blocks inline.
|
|
457
|
+
- **Legacy SVGs:** `docs/diagrams/architecture_overview.svg` and `docs/diagrams/data_comparison_flow.svg` remain for slide/README embedding.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyplaykit
|
|
3
|
-
Version: 1.20.
|
|
3
|
+
Version: 1.20.2
|
|
4
4
|
Summary: Enterprise Python + Playwright automation framework
|
|
5
5
|
Author-email: Shan Konduru <shankonduru@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -207,6 +207,22 @@ tests/
|
|
|
207
207
|
8. **Resilience Layer** (`resilience/`) - Self-healing locator resolution
|
|
208
208
|
9. **Integration Layer** (`integrations/`) - Jira and test management adapters
|
|
209
209
|
|
|
210
|
+
### Architecture Diagrams
|
|
211
|
+
|
|
212
|
+
**Architecture Overview** — the full layered dependency stack, cross-cutting layers (plugins, orchestration, resilience), the MCP read-only sidecar, and the security & governance rail:
|
|
213
|
+
|
|
214
|
+
[](https://github.com/ShanKonduru/pyplaykit/blob/master/docs/diagrams/architecture_overview.svg)
|
|
215
|
+
|
|
216
|
+
**Data Comparison Flow** — config-driven Excel / CSV / DB comparison: sources → loader → comparison engine → result + HTML report:
|
|
217
|
+
|
|
218
|
+
[](https://github.com/ShanKonduru/pyplaykit/blob/master/docs/diagrams/data_comparison_flow.svg)
|
|
219
|
+
|
|
220
|
+
**Security Posture** — defense-in-depth: runtime secrets/masking/auth controls plus the bandit / pip-audit / gitleaks CI scanning pipeline:
|
|
221
|
+
|
|
222
|
+
[](https://github.com/ShanKonduru/pyplaykit/blob/master/docs/diagrams/security_posture.svg)
|
|
223
|
+
|
|
224
|
+
> Each image is a PNG (renders inline on PyPI and GitHub) and links to the crisp, zoomable **SVG** source. See also the **[Full Architecture Reference](https://github.com/ShanKonduru/pyplaykit/blob/master/docs/ARCHITECTURE.md)** — 9 Mermaid views covering layers, runtime lifecycle, config resolution, data engineering, plugins/observability, MCP, and security. Regenerate PNGs after editing an SVG with `python scripts/svg_to_png.py`.
|
|
225
|
+
|
|
210
226
|
---
|
|
211
227
|
|
|
212
228
|
## Project Structure
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|