pyplaykit 1.0.0__tar.gz → 1.4.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.
Files changed (90) hide show
  1. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/PKG-INFO +94 -8
  2. pyplaykit-1.0.0/pyplaykit.egg-info/PKG-INFO → pyplaykit-1.4.0/README.md +84 -34
  3. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/pyplaykit/__init__.py +31 -2
  4. pyplaykit-1.0.0/README.md → pyplaykit-1.4.0/pyplaykit.egg-info/PKG-INFO +120 -1
  5. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/pyplaykit.egg-info/SOURCES.txt +4 -0
  6. pyplaykit-1.4.0/pyplaykit.egg-info/requires.txt +14 -0
  7. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/pyproject.toml +10 -7
  8. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/api_client.py +9 -1
  9. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/data_loader.py +42 -1
  10. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/data_source.py +54 -6
  11. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/db_client.py +78 -0
  12. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/db_drivers/db2.py +7 -0
  13. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/db_drivers/mysql.py +7 -0
  14. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/db_drivers/oracle.py +7 -0
  15. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/db_drivers/snowflake.py +7 -0
  16. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/db_drivers/sqlite.py +8 -0
  17. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/db_drivers/sqlserver.py +7 -0
  18. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/db_validation_helper.py +229 -0
  19. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/environment_validator.py +16 -3
  20. pyplaykit-1.4.0/utils/graphql_client.py +257 -0
  21. pyplaykit-1.4.0/utils/soap_client.py +260 -0
  22. pyplaykit-1.4.0/utils/transformation_validator.py +639 -0
  23. pyplaykit-1.4.0/utils/ui_db_validator.py +442 -0
  24. pyplaykit-1.0.0/pyplaykit.egg-info/requires.txt +0 -11
  25. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/MANIFEST.in +0 -0
  26. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/components/__init__.py +0 -0
  27. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/components/base_component.py +0 -0
  28. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/components/data_table.py +0 -0
  29. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/components/form_field.py +0 -0
  30. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/components/modal.py +0 -0
  31. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/config/config.yaml +0 -0
  32. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/config/environments.yaml +0 -0
  33. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/config/projects/customs_modernization.yaml +0 -0
  34. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/config/projects/dispatcho.yaml +0 -0
  35. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/config/projects/timelyquote.yaml +0 -0
  36. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/core/__init__.py +0 -0
  37. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/core/base_page.py +0 -0
  38. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/core/base_test.py +0 -0
  39. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/core/browser_factory.py +0 -0
  40. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/core/playwright_manager.py +0 -0
  41. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/dist_pkg/__init__.py +0 -0
  42. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/dist_pkg/distribution.py +0 -0
  43. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/integrations/__init__.py +0 -0
  44. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/integrations/adapters.py +0 -0
  45. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/orchestration/__init__.py +0 -0
  46. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/orchestration/enforcer.py +0 -0
  47. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/orchestration/planner.py +0 -0
  48. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/pages/__init__.py +0 -0
  49. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/pages/dashboard_page.py +0 -0
  50. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/pages/login_page.py +0 -0
  51. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/pages/orangehrm_login_page.py +0 -0
  52. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/pages/saucedemo_inventory_page.py +0 -0
  53. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/pages/saucedemo_login_page.py +0 -0
  54. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/plugins/__init__.py +0 -0
  55. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/plugins/api_plugin.py +0 -0
  56. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/plugins/base.py +0 -0
  57. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/plugins/data_plugin.py +0 -0
  58. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/plugins/registry.py +0 -0
  59. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/plugins/security_plugin.py +0 -0
  60. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/pyplaykit/cli.py +0 -0
  61. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/pyplaykit/plugin.py +0 -0
  62. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/pyplaykit.egg-info/dependency_links.txt +0 -0
  63. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/pyplaykit.egg-info/entry_points.txt +0 -0
  64. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/pyplaykit.egg-info/top_level.txt +0 -0
  65. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/resilience/__init__.py +0 -0
  66. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/resilience/locator_recovery.py +0 -0
  67. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/setup.cfg +0 -0
  68. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/test_data/api/ecom/auth_payloads.json +0 -0
  69. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/test_data/api/ecom/product_payloads.json +0 -0
  70. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/test_data/api_test_data.json +0 -0
  71. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/test_data/data_validation_test_data.json +0 -0
  72. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/test_data/login_test_data.json +0 -0
  73. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/test_data/orangehrm_login_data.json +0 -0
  74. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/test_data/ui_test_data.json +0 -0
  75. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/__init__.py +0 -0
  76. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/api_test_helper.py +0 -0
  77. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/assertion_helper.py +0 -0
  78. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/auth_manager.py +0 -0
  79. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/data_validator.py +0 -0
  80. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/db_drivers/__init__.py +0 -0
  81. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/db_factory.py +0 -0
  82. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/db_fixtures.py +0 -0
  83. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/db_pool.py +0 -0
  84. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/file_reader.py +0 -0
  85. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/logger.py +0 -0
  86. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/observability.py +0 -0
  87. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/response_validator.py +0 -0
  88. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/screenshot_helper.py +0 -0
  89. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/tdm.py +0 -0
  90. {pyplaykit-1.0.0 → pyplaykit-1.4.0}/utils/yaml_config_reader.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyplaykit
3
- Version: 1.0.0
3
+ Version: 1.4.0
4
4
  Summary: Enterprise Python + Playwright automation framework
5
5
  Author-email: Shan Konduru <shankonduru@gmail.com>
6
6
  License: MIT
@@ -20,16 +20,19 @@ Classifier: Operating System :: OS Independent
20
20
  Requires-Python: >=3.11
21
21
  Description-Content-Type: text/markdown
22
22
  Requires-Dist: playwright==1.54.0
23
- Requires-Dist: pytest==8.4.1
24
- Requires-Dist: pytest-cov==6.2.1
25
- Requires-Dist: pytest-xdist==3.6.1
26
- Requires-Dist: pytest-rerunfailures==15.1
27
- Requires-Dist: pytest-html==4.1.1
28
- Requires-Dist: allure-pytest==2.13.5
23
+ Requires-Dist: pytest==9.1.1
24
+ Requires-Dist: pytest-cov==7.1.0
25
+ Requires-Dist: pytest-xdist==3.8.0
26
+ Requires-Dist: pytest-rerunfailures==16.4
27
+ Requires-Dist: pytest-html==4.2.0
28
+ Requires-Dist: allure-pytest==2.16.0
29
29
  Requires-Dist: PyYAML==6.0.2
30
30
  Requires-Dist: python-dotenv>=1.0.0
31
31
  Requires-Dist: httpx>=0.27.0
32
32
  Requires-Dist: jmespath>=1.0.0
33
+ Requires-Dist: xlrd>=2.0.1
34
+ Requires-Dist: zeep>=4.2.1
35
+ Requires-Dist: gql[httpx]>=3.5.0
33
36
 
34
37
  # PyPlayKit - Enterprise Test Automation Framework
35
38
 
@@ -45,10 +48,11 @@ PyPlayKit is a **multi-project enterprise test automation framework** built with
45
48
  - 🏢 **Multi-Project Support**: Separate test organization for multiple applications
46
49
  - 👥 **Scalable**: Designed for 50-100 QE engineers working simultaneously
47
50
  - 🎯 **Zero Merge Conflicts**: Project-first organization eliminates conflicts
51
+ - 📊 **Data Comparison**: File-to-File, File-to-DB, DB-to-File validation (Excel, CSV, JSON)
48
52
  - 📚 **Comprehensive Documentation**: 8,700+ lines across 15+ guides
49
53
  - 🔧 **Extensible**: Plugin architecture with orchestration support
50
54
  - 🔍 **Self-Healing**: Locator recovery with fallback chains
51
- - 📊 **Observable**: Comprehensive metrics and reporting
55
+ - 📈 **Observable**: Comprehensive metrics and reporting
52
56
 
53
57
  ---
54
58
 
@@ -437,6 +441,82 @@ pytest tests/projects/timelyquote/functional/ui/quotes/test_create_quote.py -v
437
441
 
438
442
  ---
439
443
 
444
+ ## Data Comparison Patterns
445
+
446
+ PyPlayKit provides comprehensive data comparison capabilities using the built-in `DataValidator` utility.
447
+
448
+ ### Prerequisites for Data Comparison
449
+
450
+ ```bash
451
+ # Install data comparison dependencies
452
+ pip install pandas openpyxl
453
+
454
+ # Or use the examples requirements file
455
+ pip install -r examples/requirements.txt
456
+ ```
457
+
458
+ ### Supported Comparison Types
459
+
460
+ | Comparison Type | Use Case | Example |
461
+ |----------------|----------|---------|
462
+ | **File-to-File** | Compare Excel, CSV, JSON files | Validate data export/import |
463
+ | **File-to-Database** | Verify data loads into database | ETL validation |
464
+ | **Database-to-File** | Validate database exports | Report generation testing |
465
+
466
+ ### Quick Example: Excel-to-Excel Comparison
467
+
468
+ ```python
469
+ import pytest
470
+ import pandas as pd
471
+ from pathlib import Path
472
+ from pyplaykit import DataValidator
473
+
474
+ @pytest.mark.data
475
+ def test_compare_excel_files(logger):
476
+ # Read both files
477
+ df1 = pd.read_excel("report_baseline.xlsx")
478
+ df2 = pd.read_excel("report_current.xlsx")
479
+
480
+ records1 = df1.to_dict('records')
481
+ records2 = df2.to_dict('records')
482
+
483
+ # Compare row by row
484
+ for idx, (r1, r2) in enumerate(zip(records1, records2)):
485
+ DataValidator.assert_records_equal(r1, r2)
486
+
487
+ logger.info("✓ Files match!")
488
+ ```
489
+
490
+ ### DataValidator Methods
491
+
492
+ | Method | Purpose |
493
+ |--------|---------|
494
+ | `assert_records_equal()` | Compare two dictionaries exactly |
495
+ | `assert_floats_equal()` | Compare numeric values with tolerance |
496
+ | `assert_strings_equal_normalized()` | Compare strings with normalization |
497
+ | `assert_collection_contains_record()` | Check if record exists in collection |
498
+ | `assert_datetimes_equal()` | Compare datetime values |
499
+
500
+ ### Runnable Examples
501
+
502
+ See **[examples/data_comparison_examples.py](examples/data_comparison_examples.py)** for 8 complete examples:
503
+
504
+ ```bash
505
+ # Run all data comparison examples
506
+ pytest examples/data_comparison_examples.py -v -s
507
+
508
+ # Run specific example
509
+ pytest examples/data_comparison_examples.py::test_excel_to_excel_basic -v -s
510
+ ```
511
+
512
+ ### Full Documentation
513
+
514
+ - **[docs/PIP_INSTALL_GUIDE.md](docs/PIP_INSTALL_GUIDE.md#step-8--data-comparison-patterns)** - Complete patterns guide
515
+ - **[examples/README.md](examples/README.md)** - Examples documentation
516
+ - **[docs/DATA_VALIDATION_GUIDE.md](docs/DATA_VALIDATION_GUIDE.md)** - Advanced validation
517
+
518
+ ---
519
+
440
520
  ## Unit Testing and Coverage
441
521
 
442
522
  ```bash
@@ -506,6 +586,7 @@ Each project config includes:
506
586
  - **[QUICK_START_QE.md](QUICK_START_QE.md)** - Get started in 10 minutes
507
587
  - **[TEST_LOCATION_CHEATSHEET.md](TEST_LOCATION_CHEATSHEET.md)** - One-page reference
508
588
  - **[COMMANDS_FOR_YOUR_PROJECTS.md](COMMANDS_FOR_YOUR_PROJECTS.md)** - Command reference
589
+ - **[docs/PIP_INSTALL_GUIDE.md](docs/PIP_INSTALL_GUIDE.md)** - Pip install guide with data comparison patterns
509
590
 
510
591
  ### Implementation
511
592
  - **[YOUR_PROJECTS_IMPLEMENTATION_GUIDE.md](YOUR_PROJECTS_IMPLEMENTATION_GUIDE.md)** - Step-by-step guide
@@ -517,6 +598,11 @@ Each project config includes:
517
598
  - **[docs/TEST_ORGANIZATION.md](docs/TEST_ORGANIZATION.md)** - Organization strategy
518
599
  - **[docs/QE_VISUAL_GUIDE.md](docs/QE_VISUAL_GUIDE.md)** - Visual guide with diagrams
519
600
 
601
+ ### Data Comparison & Validation
602
+ - **[examples/data_comparison_examples.py](examples/data_comparison_examples.py)** - Runnable examples for Excel, CSV, DB comparison
603
+ - **[examples/README.md](examples/README.md)** - Examples documentation
604
+ - **[docs/DATA_VALIDATION_GUIDE.md](docs/DATA_VALIDATION_GUIDE.md)** - Advanced validation patterns
605
+
520
606
  ### Project Guides
521
607
  - **[tests/projects/timelyquote/README.md](tests/projects/timelyquote/README.md)** - TimelyQuote guide
522
608
  - **[tests/projects/dispatcho/README.md](tests/projects/dispatcho/README.md)** - Dispatcho guide
@@ -1,36 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: pyplaykit
3
- Version: 1.0.0
4
- Summary: Enterprise Python + Playwright automation framework
5
- Author-email: Shan Konduru <shankonduru@gmail.com>
6
- License: MIT
7
- Project-URL: Homepage, https://github.com/ShanKonduru/pyplaykit
8
- Project-URL: Repository, https://github.com/ShanKonduru/pyplaykit
9
- Project-URL: Bug Tracker, https://github.com/ShanKonduru/pyplaykit/issues
10
- Keywords: playwright,pytest,automation,framework,enterprise,testing,page-object-model
11
- Classifier: Programming Language :: Python :: 3
12
- Classifier: Programming Language :: Python :: 3 :: Only
13
- Classifier: Programming Language :: Python :: 3.11
14
- Classifier: Programming Language :: Python :: 3.12
15
- Classifier: Framework :: Pytest
16
- Classifier: Topic :: Software Development :: Testing
17
- Classifier: Intended Audience :: Developers
18
- Classifier: License :: OSI Approved :: MIT License
19
- Classifier: Operating System :: OS Independent
20
- Requires-Python: >=3.11
21
- Description-Content-Type: text/markdown
22
- Requires-Dist: playwright==1.54.0
23
- Requires-Dist: pytest==8.4.1
24
- Requires-Dist: pytest-cov==6.2.1
25
- Requires-Dist: pytest-xdist==3.6.1
26
- Requires-Dist: pytest-rerunfailures==15.1
27
- Requires-Dist: pytest-html==4.1.1
28
- Requires-Dist: allure-pytest==2.13.5
29
- Requires-Dist: PyYAML==6.0.2
30
- Requires-Dist: python-dotenv>=1.0.0
31
- Requires-Dist: httpx>=0.27.0
32
- Requires-Dist: jmespath>=1.0.0
33
-
34
1
  # PyPlayKit - Enterprise Test Automation Framework
35
2
 
36
3
  **Tagline**: A modular, scalable, and CI/CD-ready Python + Playwright framework for enterprise automation supporting multiple projects and 50+ QE engineers.
@@ -45,10 +12,11 @@ PyPlayKit is a **multi-project enterprise test automation framework** built with
45
12
  - 🏢 **Multi-Project Support**: Separate test organization for multiple applications
46
13
  - 👥 **Scalable**: Designed for 50-100 QE engineers working simultaneously
47
14
  - 🎯 **Zero Merge Conflicts**: Project-first organization eliminates conflicts
15
+ - 📊 **Data Comparison**: File-to-File, File-to-DB, DB-to-File validation (Excel, CSV, JSON)
48
16
  - 📚 **Comprehensive Documentation**: 8,700+ lines across 15+ guides
49
17
  - 🔧 **Extensible**: Plugin architecture with orchestration support
50
18
  - 🔍 **Self-Healing**: Locator recovery with fallback chains
51
- - 📊 **Observable**: Comprehensive metrics and reporting
19
+ - 📈 **Observable**: Comprehensive metrics and reporting
52
20
 
53
21
  ---
54
22
 
@@ -437,6 +405,82 @@ pytest tests/projects/timelyquote/functional/ui/quotes/test_create_quote.py -v
437
405
 
438
406
  ---
439
407
 
408
+ ## Data Comparison Patterns
409
+
410
+ PyPlayKit provides comprehensive data comparison capabilities using the built-in `DataValidator` utility.
411
+
412
+ ### Prerequisites for Data Comparison
413
+
414
+ ```bash
415
+ # Install data comparison dependencies
416
+ pip install pandas openpyxl
417
+
418
+ # Or use the examples requirements file
419
+ pip install -r examples/requirements.txt
420
+ ```
421
+
422
+ ### Supported Comparison Types
423
+
424
+ | Comparison Type | Use Case | Example |
425
+ |----------------|----------|---------|
426
+ | **File-to-File** | Compare Excel, CSV, JSON files | Validate data export/import |
427
+ | **File-to-Database** | Verify data loads into database | ETL validation |
428
+ | **Database-to-File** | Validate database exports | Report generation testing |
429
+
430
+ ### Quick Example: Excel-to-Excel Comparison
431
+
432
+ ```python
433
+ import pytest
434
+ import pandas as pd
435
+ from pathlib import Path
436
+ from pyplaykit import DataValidator
437
+
438
+ @pytest.mark.data
439
+ def test_compare_excel_files(logger):
440
+ # Read both files
441
+ df1 = pd.read_excel("report_baseline.xlsx")
442
+ df2 = pd.read_excel("report_current.xlsx")
443
+
444
+ records1 = df1.to_dict('records')
445
+ records2 = df2.to_dict('records')
446
+
447
+ # Compare row by row
448
+ for idx, (r1, r2) in enumerate(zip(records1, records2)):
449
+ DataValidator.assert_records_equal(r1, r2)
450
+
451
+ logger.info("✓ Files match!")
452
+ ```
453
+
454
+ ### DataValidator Methods
455
+
456
+ | Method | Purpose |
457
+ |--------|---------|
458
+ | `assert_records_equal()` | Compare two dictionaries exactly |
459
+ | `assert_floats_equal()` | Compare numeric values with tolerance |
460
+ | `assert_strings_equal_normalized()` | Compare strings with normalization |
461
+ | `assert_collection_contains_record()` | Check if record exists in collection |
462
+ | `assert_datetimes_equal()` | Compare datetime values |
463
+
464
+ ### Runnable Examples
465
+
466
+ See **[examples/data_comparison_examples.py](examples/data_comparison_examples.py)** for 8 complete examples:
467
+
468
+ ```bash
469
+ # Run all data comparison examples
470
+ pytest examples/data_comparison_examples.py -v -s
471
+
472
+ # Run specific example
473
+ pytest examples/data_comparison_examples.py::test_excel_to_excel_basic -v -s
474
+ ```
475
+
476
+ ### Full Documentation
477
+
478
+ - **[docs/PIP_INSTALL_GUIDE.md](docs/PIP_INSTALL_GUIDE.md#step-8--data-comparison-patterns)** - Complete patterns guide
479
+ - **[examples/README.md](examples/README.md)** - Examples documentation
480
+ - **[docs/DATA_VALIDATION_GUIDE.md](docs/DATA_VALIDATION_GUIDE.md)** - Advanced validation
481
+
482
+ ---
483
+
440
484
  ## Unit Testing and Coverage
441
485
 
442
486
  ```bash
@@ -506,6 +550,7 @@ Each project config includes:
506
550
  - **[QUICK_START_QE.md](QUICK_START_QE.md)** - Get started in 10 minutes
507
551
  - **[TEST_LOCATION_CHEATSHEET.md](TEST_LOCATION_CHEATSHEET.md)** - One-page reference
508
552
  - **[COMMANDS_FOR_YOUR_PROJECTS.md](COMMANDS_FOR_YOUR_PROJECTS.md)** - Command reference
553
+ - **[docs/PIP_INSTALL_GUIDE.md](docs/PIP_INSTALL_GUIDE.md)** - Pip install guide with data comparison patterns
509
554
 
510
555
  ### Implementation
511
556
  - **[YOUR_PROJECTS_IMPLEMENTATION_GUIDE.md](YOUR_PROJECTS_IMPLEMENTATION_GUIDE.md)** - Step-by-step guide
@@ -517,6 +562,11 @@ Each project config includes:
517
562
  - **[docs/TEST_ORGANIZATION.md](docs/TEST_ORGANIZATION.md)** - Organization strategy
518
563
  - **[docs/QE_VISUAL_GUIDE.md](docs/QE_VISUAL_GUIDE.md)** - Visual guide with diagrams
519
564
 
565
+ ### Data Comparison & Validation
566
+ - **[examples/data_comparison_examples.py](examples/data_comparison_examples.py)** - Runnable examples for Excel, CSV, DB comparison
567
+ - **[examples/README.md](examples/README.md)** - Examples documentation
568
+ - **[docs/DATA_VALIDATION_GUIDE.md](docs/DATA_VALIDATION_GUIDE.md)** - Advanced validation patterns
569
+
520
570
  ### Project Guides
521
571
  - **[tests/projects/timelyquote/README.md](tests/projects/timelyquote/README.md)** - TimelyQuote guide
522
572
  - **[tests/projects/dispatcho/README.md](tests/projects/dispatcho/README.md)** - Dispatcho guide
@@ -13,27 +13,56 @@ from core.base_page import BasePage
13
13
  from utils.api_client import ApiClient, ApiResponse
14
14
  from utils.auth_manager import AuthTokenManager
15
15
  from utils.data_validator import DataValidator
16
+ from utils.ui_db_validator import UIDbValidator
17
+ from utils.graphql_client import GraphQLClient, GraphQLResponse, GraphQLValidator
18
+ from utils.soap_client import SoapClient, SoapResponse, SoapValidator
16
19
  from utils.db_client import BaseDbClient, DbClient
20
+ from utils.transformation_validator import (
21
+ ColumnSpec,
22
+ PairRule,
23
+ RowRule,
24
+ RuleValidator,
25
+ TransformationValidator,
26
+ Violation,
27
+ )
17
28
  from utils.db_fixtures import DbCleaner, DbSeeder, DbTransaction
29
+ from utils.data_source import ChunkedDbDataSource
18
30
  from utils.logger import get_logger
19
31
  from utils.response_validator import ResponseValidator
20
32
 
21
- __version__ = "1.0.0"
33
+ __version__ = "1.3.0"
22
34
 
23
35
  __all__ = [
24
- # HTTP / API
36
+ # HTTP / API — REST
25
37
  "ApiClient",
26
38
  "ApiResponse",
27
39
  "AuthTokenManager",
28
40
  "ResponseValidator",
41
+ # HTTP / API — GraphQL
42
+ "GraphQLClient",
43
+ "GraphQLResponse",
44
+ "GraphQLValidator",
45
+ # HTTP / API — SOAP
46
+ "SoapClient",
47
+ "SoapResponse",
48
+ "SoapValidator",
29
49
  # Data validation
30
50
  "DataValidator",
51
+ "UIDbValidator",
52
+ # Transformation + rule-based validation
53
+ "ColumnSpec",
54
+ "TransformationValidator",
55
+ "RowRule",
56
+ "PairRule",
57
+ "RuleValidator",
58
+ "Violation",
31
59
  # Database
32
60
  "BaseDbClient",
33
61
  "DbClient",
34
62
  "DbTransaction",
35
63
  "DbSeeder",
36
64
  "DbCleaner",
65
+ "ChunkedDbDataSource",
37
66
  # UI
38
67
  "BasePage",
39
68
  "BaseComponent",
@@ -1,3 +1,39 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyplaykit
3
+ Version: 1.4.0
4
+ Summary: Enterprise Python + Playwright automation framework
5
+ Author-email: Shan Konduru <shankonduru@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/ShanKonduru/pyplaykit
8
+ Project-URL: Repository, https://github.com/ShanKonduru/pyplaykit
9
+ Project-URL: Bug Tracker, https://github.com/ShanKonduru/pyplaykit/issues
10
+ Keywords: playwright,pytest,automation,framework,enterprise,testing,page-object-model
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3 :: Only
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Framework :: Pytest
16
+ Classifier: Topic :: Software Development :: Testing
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: License :: OSI Approved :: MIT License
19
+ Classifier: Operating System :: OS Independent
20
+ Requires-Python: >=3.11
21
+ Description-Content-Type: text/markdown
22
+ Requires-Dist: playwright==1.54.0
23
+ Requires-Dist: pytest==9.1.1
24
+ Requires-Dist: pytest-cov==7.1.0
25
+ Requires-Dist: pytest-xdist==3.8.0
26
+ Requires-Dist: pytest-rerunfailures==16.4
27
+ Requires-Dist: pytest-html==4.2.0
28
+ Requires-Dist: allure-pytest==2.16.0
29
+ Requires-Dist: PyYAML==6.0.2
30
+ Requires-Dist: python-dotenv>=1.0.0
31
+ Requires-Dist: httpx>=0.27.0
32
+ Requires-Dist: jmespath>=1.0.0
33
+ Requires-Dist: xlrd>=2.0.1
34
+ Requires-Dist: zeep>=4.2.1
35
+ Requires-Dist: gql[httpx]>=3.5.0
36
+
1
37
  # PyPlayKit - Enterprise Test Automation Framework
2
38
 
3
39
  **Tagline**: A modular, scalable, and CI/CD-ready Python + Playwright framework for enterprise automation supporting multiple projects and 50+ QE engineers.
@@ -12,10 +48,11 @@ PyPlayKit is a **multi-project enterprise test automation framework** built with
12
48
  - 🏢 **Multi-Project Support**: Separate test organization for multiple applications
13
49
  - 👥 **Scalable**: Designed for 50-100 QE engineers working simultaneously
14
50
  - 🎯 **Zero Merge Conflicts**: Project-first organization eliminates conflicts
51
+ - 📊 **Data Comparison**: File-to-File, File-to-DB, DB-to-File validation (Excel, CSV, JSON)
15
52
  - 📚 **Comprehensive Documentation**: 8,700+ lines across 15+ guides
16
53
  - 🔧 **Extensible**: Plugin architecture with orchestration support
17
54
  - 🔍 **Self-Healing**: Locator recovery with fallback chains
18
- - 📊 **Observable**: Comprehensive metrics and reporting
55
+ - 📈 **Observable**: Comprehensive metrics and reporting
19
56
 
20
57
  ---
21
58
 
@@ -404,6 +441,82 @@ pytest tests/projects/timelyquote/functional/ui/quotes/test_create_quote.py -v
404
441
 
405
442
  ---
406
443
 
444
+ ## Data Comparison Patterns
445
+
446
+ PyPlayKit provides comprehensive data comparison capabilities using the built-in `DataValidator` utility.
447
+
448
+ ### Prerequisites for Data Comparison
449
+
450
+ ```bash
451
+ # Install data comparison dependencies
452
+ pip install pandas openpyxl
453
+
454
+ # Or use the examples requirements file
455
+ pip install -r examples/requirements.txt
456
+ ```
457
+
458
+ ### Supported Comparison Types
459
+
460
+ | Comparison Type | Use Case | Example |
461
+ |----------------|----------|---------|
462
+ | **File-to-File** | Compare Excel, CSV, JSON files | Validate data export/import |
463
+ | **File-to-Database** | Verify data loads into database | ETL validation |
464
+ | **Database-to-File** | Validate database exports | Report generation testing |
465
+
466
+ ### Quick Example: Excel-to-Excel Comparison
467
+
468
+ ```python
469
+ import pytest
470
+ import pandas as pd
471
+ from pathlib import Path
472
+ from pyplaykit import DataValidator
473
+
474
+ @pytest.mark.data
475
+ def test_compare_excel_files(logger):
476
+ # Read both files
477
+ df1 = pd.read_excel("report_baseline.xlsx")
478
+ df2 = pd.read_excel("report_current.xlsx")
479
+
480
+ records1 = df1.to_dict('records')
481
+ records2 = df2.to_dict('records')
482
+
483
+ # Compare row by row
484
+ for idx, (r1, r2) in enumerate(zip(records1, records2)):
485
+ DataValidator.assert_records_equal(r1, r2)
486
+
487
+ logger.info("✓ Files match!")
488
+ ```
489
+
490
+ ### DataValidator Methods
491
+
492
+ | Method | Purpose |
493
+ |--------|---------|
494
+ | `assert_records_equal()` | Compare two dictionaries exactly |
495
+ | `assert_floats_equal()` | Compare numeric values with tolerance |
496
+ | `assert_strings_equal_normalized()` | Compare strings with normalization |
497
+ | `assert_collection_contains_record()` | Check if record exists in collection |
498
+ | `assert_datetimes_equal()` | Compare datetime values |
499
+
500
+ ### Runnable Examples
501
+
502
+ See **[examples/data_comparison_examples.py](examples/data_comparison_examples.py)** for 8 complete examples:
503
+
504
+ ```bash
505
+ # Run all data comparison examples
506
+ pytest examples/data_comparison_examples.py -v -s
507
+
508
+ # Run specific example
509
+ pytest examples/data_comparison_examples.py::test_excel_to_excel_basic -v -s
510
+ ```
511
+
512
+ ### Full Documentation
513
+
514
+ - **[docs/PIP_INSTALL_GUIDE.md](docs/PIP_INSTALL_GUIDE.md#step-8--data-comparison-patterns)** - Complete patterns guide
515
+ - **[examples/README.md](examples/README.md)** - Examples documentation
516
+ - **[docs/DATA_VALIDATION_GUIDE.md](docs/DATA_VALIDATION_GUIDE.md)** - Advanced validation
517
+
518
+ ---
519
+
407
520
  ## Unit Testing and Coverage
408
521
 
409
522
  ```bash
@@ -473,6 +586,7 @@ Each project config includes:
473
586
  - **[QUICK_START_QE.md](QUICK_START_QE.md)** - Get started in 10 minutes
474
587
  - **[TEST_LOCATION_CHEATSHEET.md](TEST_LOCATION_CHEATSHEET.md)** - One-page reference
475
588
  - **[COMMANDS_FOR_YOUR_PROJECTS.md](COMMANDS_FOR_YOUR_PROJECTS.md)** - Command reference
589
+ - **[docs/PIP_INSTALL_GUIDE.md](docs/PIP_INSTALL_GUIDE.md)** - Pip install guide with data comparison patterns
476
590
 
477
591
  ### Implementation
478
592
  - **[YOUR_PROJECTS_IMPLEMENTATION_GUIDE.md](YOUR_PROJECTS_IMPLEMENTATION_GUIDE.md)** - Step-by-step guide
@@ -484,6 +598,11 @@ Each project config includes:
484
598
  - **[docs/TEST_ORGANIZATION.md](docs/TEST_ORGANIZATION.md)** - Organization strategy
485
599
  - **[docs/QE_VISUAL_GUIDE.md](docs/QE_VISUAL_GUIDE.md)** - Visual guide with diagrams
486
600
 
601
+ ### Data Comparison & Validation
602
+ - **[examples/data_comparison_examples.py](examples/data_comparison_examples.py)** - Runnable examples for Excel, CSV, DB comparison
603
+ - **[examples/README.md](examples/README.md)** - Examples documentation
604
+ - **[docs/DATA_VALIDATION_GUIDE.md](docs/DATA_VALIDATION_GUIDE.md)** - Advanced validation patterns
605
+
487
606
  ### Project Guides
488
607
  - **[tests/projects/timelyquote/README.md](tests/projects/timelyquote/README.md)** - TimelyQuote guide
489
608
  - **[tests/projects/dispatcho/README.md](tests/projects/dispatcho/README.md)** - Dispatcho guide
@@ -68,11 +68,15 @@ utils/db_pool.py
68
68
  utils/db_validation_helper.py
69
69
  utils/environment_validator.py
70
70
  utils/file_reader.py
71
+ utils/graphql_client.py
71
72
  utils/logger.py
72
73
  utils/observability.py
73
74
  utils/response_validator.py
74
75
  utils/screenshot_helper.py
76
+ utils/soap_client.py
75
77
  utils/tdm.py
78
+ utils/transformation_validator.py
79
+ utils/ui_db_validator.py
76
80
  utils/yaml_config_reader.py
77
81
  utils/db_drivers/__init__.py
78
82
  utils/db_drivers/db2.py
@@ -0,0 +1,14 @@
1
+ playwright==1.54.0
2
+ pytest==9.1.1
3
+ pytest-cov==7.1.0
4
+ pytest-xdist==3.8.0
5
+ pytest-rerunfailures==16.4
6
+ pytest-html==4.2.0
7
+ allure-pytest==2.16.0
8
+ PyYAML==6.0.2
9
+ python-dotenv>=1.0.0
10
+ httpx>=0.27.0
11
+ jmespath>=1.0.0
12
+ xlrd>=2.0.1
13
+ zeep>=4.2.1
14
+ gql[httpx]>=3.5.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pyplaykit"
7
- version = "1.0.0"
7
+ version = "1.4.0"
8
8
  description = "Enterprise Python + Playwright automation framework"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -27,16 +27,19 @@ classifiers = [
27
27
 
28
28
  dependencies = [
29
29
  "playwright==1.54.0",
30
- "pytest==8.4.1",
31
- "pytest-cov==6.2.1",
32
- "pytest-xdist==3.6.1",
33
- "pytest-rerunfailures==15.1",
34
- "pytest-html==4.1.1",
35
- "allure-pytest==2.13.5",
30
+ "pytest==9.1.1",
31
+ "pytest-cov==7.1.0",
32
+ "pytest-xdist==3.8.0",
33
+ "pytest-rerunfailures==16.4",
34
+ "pytest-html==4.2.0",
35
+ "allure-pytest==2.16.0",
36
36
  "PyYAML==6.0.2",
37
37
  "python-dotenv>=1.0.0",
38
38
  "httpx>=0.27.0",
39
39
  "jmespath>=1.0.0",
40
+ "xlrd>=2.0.1",
41
+ "zeep>=4.2.1",
42
+ "gql[httpx]>=3.5.0",
40
43
  ]
41
44
 
42
45
  [project.scripts]
@@ -1,4 +1,12 @@
1
- """Reusable API client built on httpx for framework-level API testing."""
1
+ """Reusable REST API client built on httpx for framework-level API testing.
2
+
3
+ For GraphQL APIs use ``utils.graphql_client.GraphQLClient``.
4
+ For SOAP / WSDL APIs use ``utils.soap_client.SoapClient``.
5
+
6
+ Not supported:
7
+ - WebSocket connections (use Playwright's page.on("websocket") for browser WS testing)
8
+ - gRPC (requires protobuf compilation — out of scope for this framework)
9
+ """
2
10
 
3
11
  from __future__ import annotations
4
12
 
@@ -1,4 +1,4 @@
1
- """Data loading utilities for JSON, CSV, and Excel (XLSX) with environment placeholder support."""
1
+ """Data loading utilities for JSON, CSV, and Excel (XLSX / XLS) with environment placeholder support."""
2
2
 
3
3
  import csv
4
4
  import json
@@ -75,3 +75,44 @@ def load_xlsx(
75
75
  rows.append(row)
76
76
 
77
77
  return _resolve_env_placeholders(rows)
78
+
79
+
80
+ def load_xls(
81
+ file_path: str,
82
+ sheet_name: str | None = None,
83
+ ) -> list[dict[str, Any]]:
84
+ """Load a legacy Excel (.xls) worksheet and return rows as a list of dicts.
85
+
86
+ Args:
87
+ file_path: Path to the .xls file.
88
+ sheet_name: Worksheet name to load. Defaults to the first sheet.
89
+
90
+ Returns:
91
+ list[dict] where each dict maps column header → cell value.
92
+ Fully blank rows are skipped. Cell values are returned as native Python
93
+ types via xlrd — numeric, text, bool, or None.
94
+
95
+ Environment placeholder resolution is applied to string cell values so that
96
+ ${ENV_VAR} tokens work the same way as in load_json(), load_csv(), and load_xlsx().
97
+ """
98
+ import xlrd # noqa: PLC0415 — lazy import; xlrd is an optional install
99
+
100
+ wb = xlrd.open_workbook(file_path)
101
+ ws = wb.sheet_by_name(sheet_name) if sheet_name else wb.sheet_by_index(0)
102
+
103
+ if ws.nrows == 0:
104
+ return []
105
+
106
+ headers = [
107
+ str(ws.cell_value(0, col)) if ws.cell_value(0, col) != "" else f"col_{col}"
108
+ for col in range(ws.ncols)
109
+ ]
110
+
111
+ rows: list[dict[str, Any]] = []
112
+ for row_idx in range(1, ws.nrows):
113
+ raw = [ws.cell_value(row_idx, col) for col in range(ws.ncols)]
114
+ if all(v == "" or v is None for v in raw):
115
+ continue
116
+ rows.append(dict(zip(headers, raw)))
117
+
118
+ return _resolve_env_placeholders(rows)