pyplaykit 1.19.0__tar.gz → 1.19.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.19.0 → pyplaykit-1.19.2}/CHANGELOG.md +16 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/INIT_COMMAND_EXAMPLES.md +17 -9
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/PKG-INFO +26 -1
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/README.md +25 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/pyplaykit/cli.py +135 -3
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/pyplaykit.egg-info/PKG-INFO +26 -1
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/pyproject.toml +1 -1
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/.github/copilot-instructions.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/.github/prompts/review-execution-plan-and-implement-next-task.prompt.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/.github/prompts/run-unit-tests-and-coverage.prompt.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/.github/prompts/security-audit-and-consolidated-report.prompt.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/CHOOSE_YOUR_STRUCTURE.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/CLAUDE.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/COLUMN_MAPPING_AND_IGNORE_FIELDS_GUIDE.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/COMMANDS_FOR_YOUR_PROJECTS.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/COMMIT_SUMMARY.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/CONTRIBUTING.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/CORRECTED_PROJECT_NAMES.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/DATABASE_IMPLEMENTATION_SUMMARY.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/DELIVERABLES_SUMMARY.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/ENTERPRISE_TEST_STRUCTURE.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/FINAL_PROJECT_SETUP.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/GAP_TRACKER.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/HOW_TO_ACCESS_DOCS.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/KEY_BASED_MATCHING_SOLUTION.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/MANIFEST.in +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/MIGRATION_COMPLETE.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/MIGRATION_PLAN.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/PIP_INSTALL_GUIDE.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/PYPLAYKIT_CLIENT_OVERVIEW.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/QUICK_DB_REFERENCE.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/QUICK_REFERENCE_COMPARISON_FEATURES.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/QUICK_START_QE.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/STRUCTURE_COMPARISON.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/TEST_LOCATION_CHEATSHEET.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/VISUAL_COMPARISON.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/WINDOWS_INSTALL_GUIDE.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/YOUR_PROJECTS_IMPLEMENTATION_GUIDE.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/YOUR_SETUP_SUMMARY.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/bin/README.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/components/__init__.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/components/base_component.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/components/data_table.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/components/form_field.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/components/modal.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/config/config.yaml +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/config/data_comparison_profiles.yaml +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/config/environments.yaml +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/config/projects/customs_modernization.yaml +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/config/projects/dispatcho.yaml +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/config/projects/timelyquote.yaml +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/core/__init__.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/core/base_page.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/core/base_test.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/core/browser_factory.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/core/playwright_manager.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/demo/README.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/demo/functional/database/file_comparison/README.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/demo/functional/database/postgres_src_tgt/README.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/dist_pkg/__init__.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/dist_pkg/distribution.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/API_TESTING_GUIDE.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/CLI_REFERENCE.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/COMPETITIVE_ANALYSIS.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/COVERAGE_IMPROVEMENTS.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/CUSTOMER_SCENARIOS.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/DATABASE_SUPPORT.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/DATA_VALIDATION_GUIDE.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/DELIVERABLES_INDEX.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/EXAMPLE_TESTS_SUMMARY.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/Enterprise-Framework-Assessment-REVISED.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/Enterprise-Readiness-Assessment.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/Example-Tests-Guide.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/Execution-Plan-Backlog-and-Closure-Tracker.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/FRAMEWORK_CONTRIBUTION_GUIDE.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/KT/01_ARCHITECTURE.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/KT/02_DEPLOYMENT_RUNBOOK.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/KT/03_ACCESS_MATRIX.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/KT/04_CLIENT_CONTACT_MATRIX.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/KT/05_OPEN_RISKS_REGISTER.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/KT/06_PENDING_ENHANCEMENTS.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/KT/07_PRODUCT_ROADMAP.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/KT/08_ENVIRONMENT_DETAILS.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/KT/09_OPERATIONAL_SOPS.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/KT/10_ESCALATION_MATRIX.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/KT/11_KT_RECORDINGS_INDEX.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/KT/12_REVERSE_KT_SIGNOFF.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/KT/13_LEADERSHIP_SIGNOFF.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/KT/README.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/MCP_SERVER_DESIGN.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/MULTI_DB_VALIDATION_GUIDE.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/MULTI_PROJECT_STRUCTURE.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/PIP_INSTALL_GUIDE.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/PyPlayKit-Framework-Overview.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/PyPlayKit-Usage-Scenarios.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/QE_VISUAL_GUIDE.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/RESILIENCE_GUIDE.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/RUN_TESTS_QUICK_REFERENCE.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/TEST_ORGANIZATION.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/docs/Usage-Scenarios-Feasibility-Analysis.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/integrations/__init__.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/integrations/adapters.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/mcp_server/__init__.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/mcp_server/_ast_utils.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/mcp_server/_config_utils.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/mcp_server/cli.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/mcp_server/server.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/mcp_server/tools/__init__.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/mcp_server/tools/package_discovery.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/mcp_server/tools/project_introspection.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/mcp_server/tools/project_state.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/orchestration/__init__.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/orchestration/enforcer.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/orchestration/planner.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/pages/__init__.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/pages/dashboard_page.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/pages/login_page.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/pages/orangehrm_login_page.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/pages/saucedemo_inventory_page.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/pages/saucedemo_login_page.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/plugins/__init__.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/plugins/api_plugin.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/plugins/base.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/plugins/data_plugin.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/plugins/registry.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/plugins/security_plugin.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/pyplaykit/PIP_INSTALL_GUIDE.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/pyplaykit/README.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/pyplaykit/__init__.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/pyplaykit/config/__init__.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/pyplaykit/config/config.yaml +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/pyplaykit/config/environments.yaml +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/pyplaykit/plugin.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/pyplaykit/show_docs.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/pyplaykit.egg-info/SOURCES.txt +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/pyplaykit.egg-info/dependency_links.txt +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/pyplaykit.egg-info/entry_points.txt +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/pyplaykit.egg-info/requires.txt +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/pyplaykit.egg-info/top_level.txt +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/resilience/__init__.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/resilience/locator_recovery.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/setup.cfg +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/test_data/api/ecom/auth_payloads.json +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/test_data/api/ecom/product_payloads.json +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/test_data/api_test_data.json +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/test_data/data_validation_test_data.json +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/test_data/login_test_data.json +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/test_data/orangehrm_login_data.json +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/test_data/ui_test_data.json +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/tests/projects/README.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/tests/projects/customs_modernization/README.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/tests/projects/demo/functional/README.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/tests/projects/demo/functional/api/README.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/tests/projects/demo/functional/database/README.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/tests/projects/demo/functional/ui/README.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/tests/projects/demo/integration/README.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/tests/projects/dispatcho/README.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/tests/projects/timelyquote/README.md +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/__init__.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/api_client.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/api_test_helper.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/assertion_helper.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/auth_manager.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/comparison_config_loader.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/data_comparison_report.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/data_comparison_utils.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/data_loader.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/data_source.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/data_validator.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/database_clients.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/db_client.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/db_drivers/__init__.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/db_drivers/db2.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/db_drivers/informix.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/db_drivers/mysql.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/db_drivers/oracle.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/db_drivers/snowflake.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/db_drivers/sqlite.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/db_drivers/sqlserver.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/db_factory.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/db_fixtures.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/db_pool.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/db_validation_helper.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/environment_validator.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/file_reader.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/graphql_client.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/logger.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/observability.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/observability_report.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/response_validator.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/screenshot_helper.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/soap_client.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/tdm.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/transformation_validator.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/ui_db_validator.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/version_checker.py +0 -0
- {pyplaykit-1.19.0 → pyplaykit-1.19.2}/utils/yaml_config_reader.py +0 -0
|
@@ -11,6 +11,22 @@ Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
+
## [1.19.2] — 2026-07-24
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **Excel comparison demos now run out of the box** — `pyplaykit init` ships the eight sample workbooks that `tests/demo/functional/database/test_demo_excel.py` reads (`baseline.xlsx`, `current.xlsx`, `legacy_export.xlsx`, `new_system_export.xlsx`, `baseline_unordered.xlsx`, `current_unordered.xlsx`, `export_v1.xlsx`, `export_v2.xlsx`), generated at scaffold time via the new `_create_demo_excel_files()` (mirroring the bundled SQLite `demo.db`). Previously all four Excel demo tests skipped until the user manually placed files in `test_data/`. Degrades gracefully when `pandas`/`openpyxl` are absent at init time.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## [1.19.1] — 2026-07-24
|
|
23
|
+
|
|
24
|
+
### Documentation
|
|
25
|
+
|
|
26
|
+
- **README** — documented the `pyplaykit observability-report` HTML viewer under Reports and Artifacts → Observability, covering all invocation options (`--reports-dir`, `--output/-o`, `--open`), report contents, and the `summary.json` prerequisite.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
14
30
|
## [1.19.0] — 2026-07-24
|
|
15
31
|
|
|
16
32
|
### Added
|
|
@@ -234,7 +234,7 @@ pytest tests/demo/functional/api/test_demo_api.py
|
|
|
234
234
|
# UI tests (requires Playwright)
|
|
235
235
|
pytest tests/demo/functional/ui/login/test_demo_login.py
|
|
236
236
|
|
|
237
|
-
# Excel tests (
|
|
237
|
+
# Excel tests (run out of the box — sample workbooks ship in test_data/)
|
|
238
238
|
pytest tests/demo/functional/database/test_demo_excel.py
|
|
239
239
|
|
|
240
240
|
# Database tests (configure database in config/environments.yaml)
|
|
@@ -260,14 +260,22 @@ pytest tests/demo/functional/database/test_demo_db.py::test_migration_validation
|
|
|
260
260
|
|
|
261
261
|
### For Excel Tests
|
|
262
262
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
263
|
+
`pyplaykit init` already ships sample workbooks in `test_data/` (requires
|
|
264
|
+
`pandas`/`openpyxl` at init time), so the four Excel demos run and pass out of
|
|
265
|
+
the box:
|
|
266
|
+
|
|
267
|
+
```
|
|
268
|
+
test_data/
|
|
269
|
+
├── baseline.xlsx ├── baseline_unordered.xlsx
|
|
270
|
+
├── current.xlsx ├── current_unordered.xlsx
|
|
271
|
+
├── legacy_export.xlsx ├── export_v1.xlsx
|
|
272
|
+
├── new_system_export.xlsx └── export_v2.xlsx
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
To compare your own data, either replace those files or point the tests at new
|
|
276
|
+
paths:
|
|
277
|
+
|
|
278
|
+
1. Drop your files in `test_data/` (overwrite the samples or use new names).
|
|
271
279
|
|
|
272
280
|
2. Update file paths in tests:
|
|
273
281
|
```python
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyplaykit
|
|
3
|
-
Version: 1.19.
|
|
3
|
+
Version: 1.19.2
|
|
4
4
|
Summary: Enterprise Python + Playwright automation framework
|
|
5
5
|
Author-email: Shan Konduru <shankonduru@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -861,6 +861,31 @@ Each project config includes:
|
|
|
861
861
|
- QA report: `reports/observability/qa_functional_report.json`
|
|
862
862
|
- Leadership report: `reports/observability/leadership_kpi_report.json`
|
|
863
863
|
|
|
864
|
+
**Viewing observability as an HTML report:** the reports above are JSON. To turn
|
|
865
|
+
them into a single, self-contained, styled HTML report with a generation
|
|
866
|
+
date/time stamp, run the `observability-report` CLI command after a pytest run:
|
|
867
|
+
|
|
868
|
+
```bash
|
|
869
|
+
# Default: reads reports/observability/, writes a timestamped HTML file there
|
|
870
|
+
pyplaykit observability-report
|
|
871
|
+
|
|
872
|
+
# Point at a different reports directory
|
|
873
|
+
pyplaykit observability-report --reports-dir path/to/observability
|
|
874
|
+
|
|
875
|
+
# Choose an explicit output file
|
|
876
|
+
pyplaykit observability-report --output reports/observability/latest.html
|
|
877
|
+
|
|
878
|
+
# Generate and open in the default web browser
|
|
879
|
+
pyplaykit observability-report --open
|
|
880
|
+
```
|
|
881
|
+
|
|
882
|
+
The report includes a brand header with the generation timestamp and an overall
|
|
883
|
+
PASSED / ATTENTION-NEEDED status pill, KPI cards (total, passed, failed, skipped,
|
|
884
|
+
pass rate, flaky count, durations, automation coverage), leadership KPI metrics,
|
|
885
|
+
a failed-tests table with failure classification, and a flaky-tests list. It
|
|
886
|
+
requires that a pytest run has already written `summary.json`. See
|
|
887
|
+
[docs/CLI_REFERENCE.md](docs/CLI_REFERENCE.md) for full option details.
|
|
888
|
+
|
|
864
889
|
### Integration Exports
|
|
865
890
|
- Jira export: `reports/integrations/jira_export.json`
|
|
866
891
|
- Test management: `reports/integrations/test_management_export.json`
|
|
@@ -764,6 +764,31 @@ Each project config includes:
|
|
|
764
764
|
- QA report: `reports/observability/qa_functional_report.json`
|
|
765
765
|
- Leadership report: `reports/observability/leadership_kpi_report.json`
|
|
766
766
|
|
|
767
|
+
**Viewing observability as an HTML report:** the reports above are JSON. To turn
|
|
768
|
+
them into a single, self-contained, styled HTML report with a generation
|
|
769
|
+
date/time stamp, run the `observability-report` CLI command after a pytest run:
|
|
770
|
+
|
|
771
|
+
```bash
|
|
772
|
+
# Default: reads reports/observability/, writes a timestamped HTML file there
|
|
773
|
+
pyplaykit observability-report
|
|
774
|
+
|
|
775
|
+
# Point at a different reports directory
|
|
776
|
+
pyplaykit observability-report --reports-dir path/to/observability
|
|
777
|
+
|
|
778
|
+
# Choose an explicit output file
|
|
779
|
+
pyplaykit observability-report --output reports/observability/latest.html
|
|
780
|
+
|
|
781
|
+
# Generate and open in the default web browser
|
|
782
|
+
pyplaykit observability-report --open
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
The report includes a brand header with the generation timestamp and an overall
|
|
786
|
+
PASSED / ATTENTION-NEEDED status pill, KPI cards (total, passed, failed, skipped,
|
|
787
|
+
pass rate, flaky count, durations, automation coverage), leadership KPI metrics,
|
|
788
|
+
a failed-tests table with failure classification, and a flaky-tests list. It
|
|
789
|
+
requires that a pytest run has already written `summary.json`. See
|
|
790
|
+
[docs/CLI_REFERENCE.md](docs/CLI_REFERENCE.md) for full option details.
|
|
791
|
+
|
|
767
792
|
### Integration Exports
|
|
768
793
|
- Jira export: `reports/integrations/jira_export.json`
|
|
769
794
|
- Test management: `reports/integrations/test_management_export.json`
|
|
@@ -140,7 +140,11 @@ _EXAMPLE_EXCEL = '''\
|
|
|
140
140
|
Prerequisites:
|
|
141
141
|
pip install pandas openpyxl
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
These tests run out of the box: ``pyplaykit init`` ships the sample workbooks
|
|
144
|
+
they read (baseline.xlsx, current.xlsx, legacy_export.xlsx, etc.) into
|
|
145
|
+
``test_data/``. Swap in your own files at the same paths to compare real data.
|
|
146
|
+
They skip gracefully only if those workbooks are missing (e.g. pandas/openpyxl
|
|
147
|
+
were not installed when the project was scaffolded).
|
|
144
148
|
|
|
145
149
|
Run:
|
|
146
150
|
pytest tests/demo/functional/database/test_demo_excel.py
|
|
@@ -593,6 +597,130 @@ def _create_demo_sqlite_db(test_data_dir: Path) -> None:
|
|
|
593
597
|
print(f" created {db_path} (SQLite demo database)")
|
|
594
598
|
|
|
595
599
|
|
|
600
|
+
# Employee dataset shared by the Excel comparison demos. Kept in dict form so it
|
|
601
|
+
# maps directly onto DataFrame columns / Excel headers.
|
|
602
|
+
_DEMO_EXCEL_ROWS = [
|
|
603
|
+
{"employee_id": 1, "name": "Alice Johnson", "department": "Engineering", "salary": 95000.00},
|
|
604
|
+
{"employee_id": 2, "name": "Bob Smith", "department": "Sales", "salary": 72000.00},
|
|
605
|
+
{"employee_id": 3, "name": "Carla Diaz", "department": "Marketing", "salary": 68000.50},
|
|
606
|
+
{"employee_id": 4, "name": "Devon Lee", "department": "Engineering", "salary": 88000.00},
|
|
607
|
+
{"employee_id": 5, "name": "Emma Brown", "department": "Finance", "salary": 79000.75},
|
|
608
|
+
]
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
def _create_demo_excel_files(test_data_dir: Path) -> None:
|
|
612
|
+
"""Ship the sample .xlsx workbooks the Excel comparison demos expect.
|
|
613
|
+
|
|
614
|
+
``test_demo_excel.py`` reads eight fixed-path workbooks from ``test_data/``
|
|
615
|
+
and skips when they are absent. Generating them here at ``pyplaykit init``
|
|
616
|
+
time means all four Excel demos run and pass out of the box — the same
|
|
617
|
+
zero-setup guarantee the SQLite database demos already enjoy. Each pair is
|
|
618
|
+
crafted so its specific comparison (identical, column-mapped, unordered,
|
|
619
|
+
metadata-ignored) succeeds. Existing files are left untouched.
|
|
620
|
+
|
|
621
|
+
Degrades gracefully: if pandas/openpyxl are not installed at init time the
|
|
622
|
+
demos simply keep skipping until the user installs them and re-runs init.
|
|
623
|
+
"""
|
|
624
|
+
try:
|
|
625
|
+
import pandas as pd
|
|
626
|
+
except ImportError:
|
|
627
|
+
print(
|
|
628
|
+
" skipped Excel demo workbooks (install 'pandas openpyxl' and "
|
|
629
|
+
"re-run 'pyplaykit init' to generate them)"
|
|
630
|
+
)
|
|
631
|
+
return
|
|
632
|
+
|
|
633
|
+
def write(name: str, rows: list[dict]) -> None:
|
|
634
|
+
path = test_data_dir / name
|
|
635
|
+
if path.exists():
|
|
636
|
+
return
|
|
637
|
+
try:
|
|
638
|
+
pd.DataFrame(rows).to_excel(path, index=False)
|
|
639
|
+
except ImportError:
|
|
640
|
+
# openpyxl missing — pandas raises at write time.
|
|
641
|
+
raise
|
|
642
|
+
print(f" created {path} (Excel demo data)")
|
|
643
|
+
|
|
644
|
+
base = _DEMO_EXCEL_ROWS
|
|
645
|
+
|
|
646
|
+
try:
|
|
647
|
+
# 1. test_excel_files_match — identical business data; the ignored
|
|
648
|
+
# timestamp/run_id columns differ so the demo exercises ignore_fields.
|
|
649
|
+
write("baseline.xlsx", [
|
|
650
|
+
{**r, "timestamp": "2026-01-01T00:00:00", "run_id": "run-001"} for r in base
|
|
651
|
+
])
|
|
652
|
+
write("current.xlsx", [
|
|
653
|
+
{**r, "timestamp": "2026-07-24T09:30:00", "run_id": "run-999"} for r in base
|
|
654
|
+
])
|
|
655
|
+
|
|
656
|
+
# 2. test_excel_with_column_mapping — legacy abbreviated columns vs new
|
|
657
|
+
# system names; identical values once mapped. System timestamps differ
|
|
658
|
+
# and are ignored.
|
|
659
|
+
write("legacy_export.xlsx", [
|
|
660
|
+
{
|
|
661
|
+
"emp_id": r["employee_id"], "emp_name": r["name"],
|
|
662
|
+
"emp_dept": r["department"], "emp_sal": r["salary"],
|
|
663
|
+
"created_at": "2020-01-01", "modified_at": "2020-01-01",
|
|
664
|
+
}
|
|
665
|
+
for r in base
|
|
666
|
+
])
|
|
667
|
+
write("new_system_export.xlsx", [
|
|
668
|
+
{
|
|
669
|
+
"employee_id": r["employee_id"], "name": r["name"],
|
|
670
|
+
"department": r["department"], "salary": r["salary"],
|
|
671
|
+
"created_at": "2026-07-24", "modified_at": "2026-07-24",
|
|
672
|
+
}
|
|
673
|
+
for r in base
|
|
674
|
+
])
|
|
675
|
+
|
|
676
|
+
# 3. test_excel_unordered_data — same rows, shuffled order; matched by the
|
|
677
|
+
# composite key (order_id, line_number). Ignored export metadata differs.
|
|
678
|
+
order_rows = [
|
|
679
|
+
{"order_id": 1001, "line_number": 1, "sku": "A-100", "qty": 2, "amount": 40.00},
|
|
680
|
+
{"order_id": 1001, "line_number": 2, "sku": "B-200", "qty": 1, "amount": 15.50},
|
|
681
|
+
{"order_id": 1002, "line_number": 1, "sku": "C-300", "qty": 5, "amount": 99.99},
|
|
682
|
+
{"order_id": 1003, "line_number": 1, "sku": "D-400", "qty": 3, "amount": 60.00},
|
|
683
|
+
]
|
|
684
|
+
write("baseline_unordered.xlsx", [
|
|
685
|
+
{**r, "export_timestamp": "2026-01-01T00:00:00", "batch_id": "b-001"}
|
|
686
|
+
for r in order_rows
|
|
687
|
+
])
|
|
688
|
+
# Reverse the row order to prove key-based matching, not positional.
|
|
689
|
+
write("current_unordered.xlsx", [
|
|
690
|
+
{**r, "export_timestamp": "2026-07-24T09:30:00", "batch_id": "b-999"}
|
|
691
|
+
for r in reversed(order_rows)
|
|
692
|
+
])
|
|
693
|
+
|
|
694
|
+
# 4. test_excel_ignore_metadata_columns — identical business data keyed by
|
|
695
|
+
# product_id; only the system metadata columns differ (all ignored).
|
|
696
|
+
product_rows = [
|
|
697
|
+
{"product_id": "SKU-1", "product_name": "Widget", "price": 9.99, "in_stock": 120},
|
|
698
|
+
{"product_id": "SKU-2", "product_name": "Gadget", "price": 19.95, "in_stock": 45},
|
|
699
|
+
{"product_id": "SKU-3", "product_name": "Gizmo", "price": 4.50, "in_stock": 300},
|
|
700
|
+
]
|
|
701
|
+
write("export_v1.xlsx", [
|
|
702
|
+
{
|
|
703
|
+
**r, "timestamp": "2026-01-01", "created_at": "2026-01-01",
|
|
704
|
+
"updated_at": "2026-01-01", "created_by": "etl", "modified_by": "etl",
|
|
705
|
+
"row_version": 1, "etl_batch_id": "e-001", "export_id": "x-001",
|
|
706
|
+
}
|
|
707
|
+
for r in product_rows
|
|
708
|
+
])
|
|
709
|
+
write("export_v2.xlsx", [
|
|
710
|
+
{
|
|
711
|
+
**r, "timestamp": "2026-07-24", "created_at": "2026-07-24",
|
|
712
|
+
"updated_at": "2026-07-24", "created_by": "svc", "modified_by": "svc",
|
|
713
|
+
"row_version": 7, "etl_batch_id": "e-999", "export_id": "x-999",
|
|
714
|
+
}
|
|
715
|
+
for r in product_rows
|
|
716
|
+
])
|
|
717
|
+
except ImportError:
|
|
718
|
+
print(
|
|
719
|
+
" skipped Excel demo workbooks (install 'openpyxl' and re-run "
|
|
720
|
+
"'pyplaykit init' to generate them)"
|
|
721
|
+
)
|
|
722
|
+
|
|
723
|
+
|
|
596
724
|
_DEMO_README = '''# Demo Tests
|
|
597
725
|
|
|
598
726
|
Runnable **reference tests** that demonstrate PyPlayKit features. They mirror
|
|
@@ -621,8 +749,9 @@ tests/demo/
|
|
|
621
749
|
- **API** — targets the public https://jsonplaceholder.typicode.com service.
|
|
622
750
|
- **Database** — uses the bundled `test_data/demo.db` SQLite database created
|
|
623
751
|
by `pyplaykit init`. No PostgreSQL/MySQL server required.
|
|
624
|
-
- **Excel** —
|
|
625
|
-
`test_data
|
|
752
|
+
- **Excel** — runs against sample `.xlsx` workbooks that `pyplaykit init` ships
|
|
753
|
+
in `test_data/` (requires `pandas`/`openpyxl`); swap in your own files at the
|
|
754
|
+
same paths to compare real data.
|
|
626
755
|
|
|
627
756
|
## Running the demos
|
|
628
757
|
```bash
|
|
@@ -1455,6 +1584,9 @@ def _create_demo_structure(tests_root: Path, test_data_dir: Path) -> None:
|
|
|
1455
1584
|
# Bundled SQLite demo database that the database demos read from.
|
|
1456
1585
|
_create_demo_sqlite_db(test_data_dir)
|
|
1457
1586
|
|
|
1587
|
+
# Bundled sample workbooks so the Excel comparison demos run out of the box.
|
|
1588
|
+
_create_demo_excel_files(test_data_dir)
|
|
1589
|
+
|
|
1458
1590
|
|
|
1459
1591
|
def _create_functional_structure(functional: Path, tests_root: Path) -> None:
|
|
1460
1592
|
"""Create the ui/api/database functional test tree plus category READMEs."""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyplaykit
|
|
3
|
-
Version: 1.19.
|
|
3
|
+
Version: 1.19.2
|
|
4
4
|
Summary: Enterprise Python + Playwright automation framework
|
|
5
5
|
Author-email: Shan Konduru <shankonduru@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -861,6 +861,31 @@ Each project config includes:
|
|
|
861
861
|
- QA report: `reports/observability/qa_functional_report.json`
|
|
862
862
|
- Leadership report: `reports/observability/leadership_kpi_report.json`
|
|
863
863
|
|
|
864
|
+
**Viewing observability as an HTML report:** the reports above are JSON. To turn
|
|
865
|
+
them into a single, self-contained, styled HTML report with a generation
|
|
866
|
+
date/time stamp, run the `observability-report` CLI command after a pytest run:
|
|
867
|
+
|
|
868
|
+
```bash
|
|
869
|
+
# Default: reads reports/observability/, writes a timestamped HTML file there
|
|
870
|
+
pyplaykit observability-report
|
|
871
|
+
|
|
872
|
+
# Point at a different reports directory
|
|
873
|
+
pyplaykit observability-report --reports-dir path/to/observability
|
|
874
|
+
|
|
875
|
+
# Choose an explicit output file
|
|
876
|
+
pyplaykit observability-report --output reports/observability/latest.html
|
|
877
|
+
|
|
878
|
+
# Generate and open in the default web browser
|
|
879
|
+
pyplaykit observability-report --open
|
|
880
|
+
```
|
|
881
|
+
|
|
882
|
+
The report includes a brand header with the generation timestamp and an overall
|
|
883
|
+
PASSED / ATTENTION-NEEDED status pill, KPI cards (total, passed, failed, skipped,
|
|
884
|
+
pass rate, flaky count, durations, automation coverage), leadership KPI metrics,
|
|
885
|
+
a failed-tests table with failure classification, and a flaky-tests list. It
|
|
886
|
+
requires that a pytest run has already written `summary.json`. See
|
|
887
|
+
[docs/CLI_REFERENCE.md](docs/CLI_REFERENCE.md) for full option details.
|
|
888
|
+
|
|
864
889
|
### Integration Exports
|
|
865
890
|
- Jira export: `reports/integrations/jira_export.json`
|
|
866
891
|
- Test management: `reports/integrations/test_management_export.json`
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|