pyplaykit 1.5.0__tar.gz → 1.7.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.
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/PKG-INFO +88 -23
- pyplaykit-1.5.0/pyplaykit.egg-info/PKG-INFO → pyplaykit-1.7.0/README.md +84 -58
- pyplaykit-1.5.0/README.md → pyplaykit-1.7.0/pyplaykit.egg-info/PKG-INFO +123 -22
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/pyplaykit.egg-info/SOURCES.txt +1 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/pyplaykit.egg-info/requires.txt +4 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/pyproject.toml +7 -1
- pyplaykit-1.7.0/utils/__init__.py +48 -0
- pyplaykit-1.7.0/utils/data_comparison_utils.py +856 -0
- pyplaykit-1.5.0/utils/__init__.py +0 -5
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/MANIFEST.in +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/components/__init__.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/components/base_component.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/components/data_table.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/components/form_field.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/components/modal.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/config/config.yaml +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/config/environments.yaml +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/config/projects/customs_modernization.yaml +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/config/projects/dispatcho.yaml +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/config/projects/timelyquote.yaml +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/core/__init__.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/core/base_page.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/core/base_test.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/core/browser_factory.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/core/playwright_manager.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/dist_pkg/__init__.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/dist_pkg/distribution.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/integrations/__init__.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/integrations/adapters.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/orchestration/__init__.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/orchestration/enforcer.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/orchestration/planner.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/pages/__init__.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/pages/dashboard_page.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/pages/login_page.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/pages/orangehrm_login_page.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/pages/saucedemo_inventory_page.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/pages/saucedemo_login_page.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/plugins/__init__.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/plugins/api_plugin.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/plugins/base.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/plugins/data_plugin.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/plugins/registry.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/plugins/security_plugin.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/pyplaykit/__init__.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/pyplaykit/cli.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/pyplaykit/plugin.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/pyplaykit.egg-info/dependency_links.txt +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/pyplaykit.egg-info/entry_points.txt +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/pyplaykit.egg-info/top_level.txt +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/resilience/__init__.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/resilience/locator_recovery.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/setup.cfg +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/test_data/api/ecom/auth_payloads.json +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/test_data/api/ecom/product_payloads.json +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/test_data/api_test_data.json +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/test_data/data_validation_test_data.json +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/test_data/login_test_data.json +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/test_data/orangehrm_login_data.json +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/test_data/ui_test_data.json +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/api_client.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/api_test_helper.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/assertion_helper.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/auth_manager.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/data_comparison_report.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/data_loader.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/data_source.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/data_validator.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/db_client.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/db_drivers/__init__.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/db_drivers/db2.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/db_drivers/mysql.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/db_drivers/oracle.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/db_drivers/snowflake.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/db_drivers/sqlite.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/db_drivers/sqlserver.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/db_factory.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/db_fixtures.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/db_pool.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/db_validation_helper.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/environment_validator.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/file_reader.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/graphql_client.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/logger.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/observability.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/response_validator.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/screenshot_helper.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/soap_client.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/tdm.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/transformation_validator.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.0}/utils/ui_db_validator.py +0 -0
- {pyplaykit-1.5.0 → pyplaykit-1.7.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.
|
|
3
|
+
Version: 1.7.0
|
|
4
4
|
Summary: Enterprise Python + Playwright automation framework
|
|
5
5
|
Author-email: Shan Konduru <shankonduru@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -33,6 +33,9 @@ Requires-Dist: jmespath>=1.0.0
|
|
|
33
33
|
Requires-Dist: xlrd>=2.0.1
|
|
34
34
|
Requires-Dist: zeep>=4.2.1
|
|
35
35
|
Requires-Dist: gql[httpx]>=3.5.0
|
|
36
|
+
Provides-Extra: data-comparison
|
|
37
|
+
Requires-Dist: pandas>=2.0.0; extra == "data-comparison"
|
|
38
|
+
Requires-Dist: openpyxl>=3.1.0; extra == "data-comparison"
|
|
36
39
|
|
|
37
40
|
# PyPlayKit - Enterprise Test Automation Framework
|
|
38
41
|
|
|
@@ -449,13 +452,18 @@ PyPlayKit provides comprehensive data comparison capabilities using the built-in
|
|
|
449
452
|
### Prerequisites for Data Comparison
|
|
450
453
|
|
|
451
454
|
```bash
|
|
452
|
-
# Install
|
|
455
|
+
# Option 1: Install with optional dependencies
|
|
456
|
+
pip install pyplaykit[data-comparison]
|
|
457
|
+
|
|
458
|
+
# Option 2: Install dependencies separately
|
|
453
459
|
pip install pandas openpyxl
|
|
454
460
|
|
|
455
|
-
#
|
|
461
|
+
# Option 3: Use the examples requirements file
|
|
456
462
|
pip install -r examples/requirements.txt
|
|
457
463
|
```
|
|
458
464
|
|
|
465
|
+
**Note**: Data comparison features require pandas and openpyxl. The framework will work without them for UI/API/Database testing.
|
|
466
|
+
|
|
459
467
|
### Supported Comparison Types
|
|
460
468
|
|
|
461
469
|
| Comparison Type | Use Case | Example |
|
|
@@ -466,22 +474,44 @@ pip install -r examples/requirements.txt
|
|
|
466
474
|
|
|
467
475
|
### Quick Example: Excel-to-Excel Comparison
|
|
468
476
|
|
|
477
|
+
**Simple One-Line API** (Recommended for QE Engineers):
|
|
478
|
+
|
|
479
|
+
```python
|
|
480
|
+
import pytest
|
|
481
|
+
from utils.data_comparison_utils import compare_excel_files
|
|
482
|
+
|
|
483
|
+
@pytest.mark.data
|
|
484
|
+
def test_compare_excel_files(logger):
|
|
485
|
+
# ONE function call - framework handles everything!
|
|
486
|
+
result = compare_excel_files(
|
|
487
|
+
source_file="report_baseline.xlsx",
|
|
488
|
+
target_file="report_current.xlsx",
|
|
489
|
+
float_tolerance=0.01
|
|
490
|
+
)
|
|
491
|
+
|
|
492
|
+
# Check results
|
|
493
|
+
logger.info(f"{result.summary}")
|
|
494
|
+
logger.info(f"HTML Report: {result.report_path}")
|
|
495
|
+
|
|
496
|
+
if not result.passed:
|
|
497
|
+
pytest.fail(f"Validation failed! {result.failed_count} discrepancies found.")
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
**Manual Validation** (For custom logic):
|
|
501
|
+
|
|
469
502
|
```python
|
|
470
503
|
import pytest
|
|
471
504
|
import pandas as pd
|
|
472
|
-
from pathlib import Path
|
|
473
505
|
from pyplaykit import DataValidator
|
|
474
506
|
|
|
475
507
|
@pytest.mark.data
|
|
476
|
-
def
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
df2 = pd.read_excel("report_current.xlsx")
|
|
508
|
+
def test_compare_with_custom_logic(logger):
|
|
509
|
+
df1 = pd.read_excel("baseline.xlsx")
|
|
510
|
+
df2 = pd.read_excel("current.xlsx")
|
|
480
511
|
|
|
481
512
|
records1 = df1.to_dict('records')
|
|
482
513
|
records2 = df2.to_dict('records')
|
|
483
514
|
|
|
484
|
-
# Compare row by row
|
|
485
515
|
for idx, (r1, r2) in enumerate(zip(records1, records2)):
|
|
486
516
|
DataValidator.assert_records_equal(r1, r2)
|
|
487
517
|
|
|
@@ -512,29 +542,61 @@ pytest examples/data_comparison_examples.py::test_excel_to_excel_basic -v -s
|
|
|
512
542
|
|
|
513
543
|
### Interactive HTML Reports ⭐ **NEW**
|
|
514
544
|
|
|
515
|
-
|
|
545
|
+
**Option 1: Automatic Report Generation** (Recommended):
|
|
546
|
+
|
|
547
|
+
```python
|
|
548
|
+
from utils.data_comparison_utils import compare_excel_files
|
|
549
|
+
|
|
550
|
+
# Framework automatically tracks ALL mismatches and generates HTML report
|
|
551
|
+
result = compare_excel_files(
|
|
552
|
+
source_file="baseline.xlsx",
|
|
553
|
+
target_file="current.xlsx",
|
|
554
|
+
float_tolerance=0.01
|
|
555
|
+
)
|
|
556
|
+
|
|
557
|
+
# Result includes:
|
|
558
|
+
print(f"Passed: {result.passed}")
|
|
559
|
+
print(f"Matched: {result.passed_count}")
|
|
560
|
+
print(f"Failed: {result.failed_count}")
|
|
561
|
+
print(f"Total Mismatches: {result.total_mismatches}")
|
|
562
|
+
print(f"Report: {result.report_path}")
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
**Available Functions:**
|
|
566
|
+
|
|
567
|
+
*File-to-File:*
|
|
568
|
+
- `compare_excel_files()` - Excel to Excel
|
|
569
|
+
- `compare_csv_files()` - CSV to CSV
|
|
570
|
+
|
|
571
|
+
*File-to-Database:*
|
|
572
|
+
- `compare_excel_to_db()` - Excel to Database
|
|
573
|
+
- `compare_csv_to_db()` - CSV to Database
|
|
574
|
+
|
|
575
|
+
*Database-to-File:*
|
|
576
|
+
- `compare_db_to_excel()` - Database to Excel
|
|
577
|
+
- `compare_db_to_csv()` - Database to CSV
|
|
578
|
+
|
|
579
|
+
*Database-to-Database:*
|
|
580
|
+
- `compare_db_to_db()` - Database to Database
|
|
581
|
+
|
|
582
|
+
*Advanced:*
|
|
583
|
+
- `compare_dataframes()` - DataFrame to DataFrame (custom sources)
|
|
584
|
+
|
|
585
|
+
**Option 2: Manual Report Building** (Advanced):
|
|
516
586
|
|
|
517
587
|
```python
|
|
518
588
|
from utils.data_comparison_report import DataComparisonReport
|
|
519
589
|
|
|
520
|
-
#
|
|
590
|
+
# For custom comparison logic
|
|
521
591
|
report = DataComparisonReport()
|
|
522
592
|
report.set_comparison_type("FILE_TO_FILE (Excel)")
|
|
523
593
|
report.set_source("baseline.xlsx", 100)
|
|
524
594
|
report.set_target("current.xlsx", 100)
|
|
525
595
|
|
|
526
|
-
#
|
|
527
|
-
report.add_mismatch(
|
|
528
|
-
mismatch_type="VALUE_MISMATCH",
|
|
529
|
-
row_index=5,
|
|
530
|
-
mismatching_fields=["Price"],
|
|
531
|
-
source_value=99.99,
|
|
532
|
-
target_value=100.00,
|
|
533
|
-
reason="Price increased by $0.01"
|
|
534
|
-
)
|
|
596
|
+
# Your custom comparison logic here...
|
|
597
|
+
# report.add_mismatch(...) for each discrepancy
|
|
535
598
|
|
|
536
|
-
|
|
537
|
-
report.generate_report("reports/data_validation/report.html")
|
|
599
|
+
report.generate_report("reports/validation.html")
|
|
538
600
|
```
|
|
539
601
|
|
|
540
602
|
**Report Features:**
|
|
@@ -543,8 +605,11 @@ report.generate_report("reports/data_validation/report.html")
|
|
|
543
605
|
- 📋 Row-by-row mismatch details
|
|
544
606
|
- 🎨 Color-coded status indicators
|
|
545
607
|
- 📱 Mobile-responsive design
|
|
608
|
+
- ⚡ Zero manual mismatch tracking required!
|
|
546
609
|
|
|
547
|
-
|
|
610
|
+
**Examples:**
|
|
611
|
+
- **Simple API**: [examples/simple_comparison_examples.py](examples/simple_comparison_examples.py) ⭐ **Recommended**
|
|
612
|
+
- **Manual Building**: [examples/data_comparison_with_html_report.py](examples/data_comparison_with_html_report.py)
|
|
548
613
|
|
|
549
614
|
### Full Documentation
|
|
550
615
|
|
|
@@ -1,39 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: pyplaykit
|
|
3
|
-
Version: 1.5.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
|
-
|
|
37
1
|
# PyPlayKit - Enterprise Test Automation Framework
|
|
38
2
|
|
|
39
3
|
**Tagline**: A modular, scalable, and CI/CD-ready Python + Playwright framework for enterprise automation supporting multiple projects and 50+ QE engineers.
|
|
@@ -449,13 +413,18 @@ PyPlayKit provides comprehensive data comparison capabilities using the built-in
|
|
|
449
413
|
### Prerequisites for Data Comparison
|
|
450
414
|
|
|
451
415
|
```bash
|
|
452
|
-
# Install
|
|
416
|
+
# Option 1: Install with optional dependencies
|
|
417
|
+
pip install pyplaykit[data-comparison]
|
|
418
|
+
|
|
419
|
+
# Option 2: Install dependencies separately
|
|
453
420
|
pip install pandas openpyxl
|
|
454
421
|
|
|
455
|
-
#
|
|
422
|
+
# Option 3: Use the examples requirements file
|
|
456
423
|
pip install -r examples/requirements.txt
|
|
457
424
|
```
|
|
458
425
|
|
|
426
|
+
**Note**: Data comparison features require pandas and openpyxl. The framework will work without them for UI/API/Database testing.
|
|
427
|
+
|
|
459
428
|
### Supported Comparison Types
|
|
460
429
|
|
|
461
430
|
| Comparison Type | Use Case | Example |
|
|
@@ -466,22 +435,44 @@ pip install -r examples/requirements.txt
|
|
|
466
435
|
|
|
467
436
|
### Quick Example: Excel-to-Excel Comparison
|
|
468
437
|
|
|
438
|
+
**Simple One-Line API** (Recommended for QE Engineers):
|
|
439
|
+
|
|
440
|
+
```python
|
|
441
|
+
import pytest
|
|
442
|
+
from utils.data_comparison_utils import compare_excel_files
|
|
443
|
+
|
|
444
|
+
@pytest.mark.data
|
|
445
|
+
def test_compare_excel_files(logger):
|
|
446
|
+
# ONE function call - framework handles everything!
|
|
447
|
+
result = compare_excel_files(
|
|
448
|
+
source_file="report_baseline.xlsx",
|
|
449
|
+
target_file="report_current.xlsx",
|
|
450
|
+
float_tolerance=0.01
|
|
451
|
+
)
|
|
452
|
+
|
|
453
|
+
# Check results
|
|
454
|
+
logger.info(f"{result.summary}")
|
|
455
|
+
logger.info(f"HTML Report: {result.report_path}")
|
|
456
|
+
|
|
457
|
+
if not result.passed:
|
|
458
|
+
pytest.fail(f"Validation failed! {result.failed_count} discrepancies found.")
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
**Manual Validation** (For custom logic):
|
|
462
|
+
|
|
469
463
|
```python
|
|
470
464
|
import pytest
|
|
471
465
|
import pandas as pd
|
|
472
|
-
from pathlib import Path
|
|
473
466
|
from pyplaykit import DataValidator
|
|
474
467
|
|
|
475
468
|
@pytest.mark.data
|
|
476
|
-
def
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
df2 = pd.read_excel("report_current.xlsx")
|
|
469
|
+
def test_compare_with_custom_logic(logger):
|
|
470
|
+
df1 = pd.read_excel("baseline.xlsx")
|
|
471
|
+
df2 = pd.read_excel("current.xlsx")
|
|
480
472
|
|
|
481
473
|
records1 = df1.to_dict('records')
|
|
482
474
|
records2 = df2.to_dict('records')
|
|
483
475
|
|
|
484
|
-
# Compare row by row
|
|
485
476
|
for idx, (r1, r2) in enumerate(zip(records1, records2)):
|
|
486
477
|
DataValidator.assert_records_equal(r1, r2)
|
|
487
478
|
|
|
@@ -512,29 +503,61 @@ pytest examples/data_comparison_examples.py::test_excel_to_excel_basic -v -s
|
|
|
512
503
|
|
|
513
504
|
### Interactive HTML Reports ⭐ **NEW**
|
|
514
505
|
|
|
515
|
-
|
|
506
|
+
**Option 1: Automatic Report Generation** (Recommended):
|
|
507
|
+
|
|
508
|
+
```python
|
|
509
|
+
from utils.data_comparison_utils import compare_excel_files
|
|
510
|
+
|
|
511
|
+
# Framework automatically tracks ALL mismatches and generates HTML report
|
|
512
|
+
result = compare_excel_files(
|
|
513
|
+
source_file="baseline.xlsx",
|
|
514
|
+
target_file="current.xlsx",
|
|
515
|
+
float_tolerance=0.01
|
|
516
|
+
)
|
|
517
|
+
|
|
518
|
+
# Result includes:
|
|
519
|
+
print(f"Passed: {result.passed}")
|
|
520
|
+
print(f"Matched: {result.passed_count}")
|
|
521
|
+
print(f"Failed: {result.failed_count}")
|
|
522
|
+
print(f"Total Mismatches: {result.total_mismatches}")
|
|
523
|
+
print(f"Report: {result.report_path}")
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
**Available Functions:**
|
|
527
|
+
|
|
528
|
+
*File-to-File:*
|
|
529
|
+
- `compare_excel_files()` - Excel to Excel
|
|
530
|
+
- `compare_csv_files()` - CSV to CSV
|
|
531
|
+
|
|
532
|
+
*File-to-Database:*
|
|
533
|
+
- `compare_excel_to_db()` - Excel to Database
|
|
534
|
+
- `compare_csv_to_db()` - CSV to Database
|
|
535
|
+
|
|
536
|
+
*Database-to-File:*
|
|
537
|
+
- `compare_db_to_excel()` - Database to Excel
|
|
538
|
+
- `compare_db_to_csv()` - Database to CSV
|
|
539
|
+
|
|
540
|
+
*Database-to-Database:*
|
|
541
|
+
- `compare_db_to_db()` - Database to Database
|
|
542
|
+
|
|
543
|
+
*Advanced:*
|
|
544
|
+
- `compare_dataframes()` - DataFrame to DataFrame (custom sources)
|
|
545
|
+
|
|
546
|
+
**Option 2: Manual Report Building** (Advanced):
|
|
516
547
|
|
|
517
548
|
```python
|
|
518
549
|
from utils.data_comparison_report import DataComparisonReport
|
|
519
550
|
|
|
520
|
-
#
|
|
551
|
+
# For custom comparison logic
|
|
521
552
|
report = DataComparisonReport()
|
|
522
553
|
report.set_comparison_type("FILE_TO_FILE (Excel)")
|
|
523
554
|
report.set_source("baseline.xlsx", 100)
|
|
524
555
|
report.set_target("current.xlsx", 100)
|
|
525
556
|
|
|
526
|
-
#
|
|
527
|
-
report.add_mismatch(
|
|
528
|
-
mismatch_type="VALUE_MISMATCH",
|
|
529
|
-
row_index=5,
|
|
530
|
-
mismatching_fields=["Price"],
|
|
531
|
-
source_value=99.99,
|
|
532
|
-
target_value=100.00,
|
|
533
|
-
reason="Price increased by $0.01"
|
|
534
|
-
)
|
|
557
|
+
# Your custom comparison logic here...
|
|
558
|
+
# report.add_mismatch(...) for each discrepancy
|
|
535
559
|
|
|
536
|
-
|
|
537
|
-
report.generate_report("reports/data_validation/report.html")
|
|
560
|
+
report.generate_report("reports/validation.html")
|
|
538
561
|
```
|
|
539
562
|
|
|
540
563
|
**Report Features:**
|
|
@@ -543,8 +566,11 @@ report.generate_report("reports/data_validation/report.html")
|
|
|
543
566
|
- 📋 Row-by-row mismatch details
|
|
544
567
|
- 🎨 Color-coded status indicators
|
|
545
568
|
- 📱 Mobile-responsive design
|
|
569
|
+
- ⚡ Zero manual mismatch tracking required!
|
|
546
570
|
|
|
547
|
-
|
|
571
|
+
**Examples:**
|
|
572
|
+
- **Simple API**: [examples/simple_comparison_examples.py](examples/simple_comparison_examples.py) ⭐ **Recommended**
|
|
573
|
+
- **Manual Building**: [examples/data_comparison_with_html_report.py](examples/data_comparison_with_html_report.py)
|
|
548
574
|
|
|
549
575
|
### Full Documentation
|
|
550
576
|
|
|
@@ -1,3 +1,42 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyplaykit
|
|
3
|
+
Version: 1.7.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
|
+
Provides-Extra: data-comparison
|
|
37
|
+
Requires-Dist: pandas>=2.0.0; extra == "data-comparison"
|
|
38
|
+
Requires-Dist: openpyxl>=3.1.0; extra == "data-comparison"
|
|
39
|
+
|
|
1
40
|
# PyPlayKit - Enterprise Test Automation Framework
|
|
2
41
|
|
|
3
42
|
**Tagline**: A modular, scalable, and CI/CD-ready Python + Playwright framework for enterprise automation supporting multiple projects and 50+ QE engineers.
|
|
@@ -413,13 +452,18 @@ PyPlayKit provides comprehensive data comparison capabilities using the built-in
|
|
|
413
452
|
### Prerequisites for Data Comparison
|
|
414
453
|
|
|
415
454
|
```bash
|
|
416
|
-
# Install
|
|
455
|
+
# Option 1: Install with optional dependencies
|
|
456
|
+
pip install pyplaykit[data-comparison]
|
|
457
|
+
|
|
458
|
+
# Option 2: Install dependencies separately
|
|
417
459
|
pip install pandas openpyxl
|
|
418
460
|
|
|
419
|
-
#
|
|
461
|
+
# Option 3: Use the examples requirements file
|
|
420
462
|
pip install -r examples/requirements.txt
|
|
421
463
|
```
|
|
422
464
|
|
|
465
|
+
**Note**: Data comparison features require pandas and openpyxl. The framework will work without them for UI/API/Database testing.
|
|
466
|
+
|
|
423
467
|
### Supported Comparison Types
|
|
424
468
|
|
|
425
469
|
| Comparison Type | Use Case | Example |
|
|
@@ -430,22 +474,44 @@ pip install -r examples/requirements.txt
|
|
|
430
474
|
|
|
431
475
|
### Quick Example: Excel-to-Excel Comparison
|
|
432
476
|
|
|
477
|
+
**Simple One-Line API** (Recommended for QE Engineers):
|
|
478
|
+
|
|
479
|
+
```python
|
|
480
|
+
import pytest
|
|
481
|
+
from utils.data_comparison_utils import compare_excel_files
|
|
482
|
+
|
|
483
|
+
@pytest.mark.data
|
|
484
|
+
def test_compare_excel_files(logger):
|
|
485
|
+
# ONE function call - framework handles everything!
|
|
486
|
+
result = compare_excel_files(
|
|
487
|
+
source_file="report_baseline.xlsx",
|
|
488
|
+
target_file="report_current.xlsx",
|
|
489
|
+
float_tolerance=0.01
|
|
490
|
+
)
|
|
491
|
+
|
|
492
|
+
# Check results
|
|
493
|
+
logger.info(f"{result.summary}")
|
|
494
|
+
logger.info(f"HTML Report: {result.report_path}")
|
|
495
|
+
|
|
496
|
+
if not result.passed:
|
|
497
|
+
pytest.fail(f"Validation failed! {result.failed_count} discrepancies found.")
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
**Manual Validation** (For custom logic):
|
|
501
|
+
|
|
433
502
|
```python
|
|
434
503
|
import pytest
|
|
435
504
|
import pandas as pd
|
|
436
|
-
from pathlib import Path
|
|
437
505
|
from pyplaykit import DataValidator
|
|
438
506
|
|
|
439
507
|
@pytest.mark.data
|
|
440
|
-
def
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
df2 = pd.read_excel("report_current.xlsx")
|
|
508
|
+
def test_compare_with_custom_logic(logger):
|
|
509
|
+
df1 = pd.read_excel("baseline.xlsx")
|
|
510
|
+
df2 = pd.read_excel("current.xlsx")
|
|
444
511
|
|
|
445
512
|
records1 = df1.to_dict('records')
|
|
446
513
|
records2 = df2.to_dict('records')
|
|
447
514
|
|
|
448
|
-
# Compare row by row
|
|
449
515
|
for idx, (r1, r2) in enumerate(zip(records1, records2)):
|
|
450
516
|
DataValidator.assert_records_equal(r1, r2)
|
|
451
517
|
|
|
@@ -476,29 +542,61 @@ pytest examples/data_comparison_examples.py::test_excel_to_excel_basic -v -s
|
|
|
476
542
|
|
|
477
543
|
### Interactive HTML Reports ⭐ **NEW**
|
|
478
544
|
|
|
479
|
-
|
|
545
|
+
**Option 1: Automatic Report Generation** (Recommended):
|
|
546
|
+
|
|
547
|
+
```python
|
|
548
|
+
from utils.data_comparison_utils import compare_excel_files
|
|
549
|
+
|
|
550
|
+
# Framework automatically tracks ALL mismatches and generates HTML report
|
|
551
|
+
result = compare_excel_files(
|
|
552
|
+
source_file="baseline.xlsx",
|
|
553
|
+
target_file="current.xlsx",
|
|
554
|
+
float_tolerance=0.01
|
|
555
|
+
)
|
|
556
|
+
|
|
557
|
+
# Result includes:
|
|
558
|
+
print(f"Passed: {result.passed}")
|
|
559
|
+
print(f"Matched: {result.passed_count}")
|
|
560
|
+
print(f"Failed: {result.failed_count}")
|
|
561
|
+
print(f"Total Mismatches: {result.total_mismatches}")
|
|
562
|
+
print(f"Report: {result.report_path}")
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
**Available Functions:**
|
|
566
|
+
|
|
567
|
+
*File-to-File:*
|
|
568
|
+
- `compare_excel_files()` - Excel to Excel
|
|
569
|
+
- `compare_csv_files()` - CSV to CSV
|
|
570
|
+
|
|
571
|
+
*File-to-Database:*
|
|
572
|
+
- `compare_excel_to_db()` - Excel to Database
|
|
573
|
+
- `compare_csv_to_db()` - CSV to Database
|
|
574
|
+
|
|
575
|
+
*Database-to-File:*
|
|
576
|
+
- `compare_db_to_excel()` - Database to Excel
|
|
577
|
+
- `compare_db_to_csv()` - Database to CSV
|
|
578
|
+
|
|
579
|
+
*Database-to-Database:*
|
|
580
|
+
- `compare_db_to_db()` - Database to Database
|
|
581
|
+
|
|
582
|
+
*Advanced:*
|
|
583
|
+
- `compare_dataframes()` - DataFrame to DataFrame (custom sources)
|
|
584
|
+
|
|
585
|
+
**Option 2: Manual Report Building** (Advanced):
|
|
480
586
|
|
|
481
587
|
```python
|
|
482
588
|
from utils.data_comparison_report import DataComparisonReport
|
|
483
589
|
|
|
484
|
-
#
|
|
590
|
+
# For custom comparison logic
|
|
485
591
|
report = DataComparisonReport()
|
|
486
592
|
report.set_comparison_type("FILE_TO_FILE (Excel)")
|
|
487
593
|
report.set_source("baseline.xlsx", 100)
|
|
488
594
|
report.set_target("current.xlsx", 100)
|
|
489
595
|
|
|
490
|
-
#
|
|
491
|
-
report.add_mismatch(
|
|
492
|
-
mismatch_type="VALUE_MISMATCH",
|
|
493
|
-
row_index=5,
|
|
494
|
-
mismatching_fields=["Price"],
|
|
495
|
-
source_value=99.99,
|
|
496
|
-
target_value=100.00,
|
|
497
|
-
reason="Price increased by $0.01"
|
|
498
|
-
)
|
|
596
|
+
# Your custom comparison logic here...
|
|
597
|
+
# report.add_mismatch(...) for each discrepancy
|
|
499
598
|
|
|
500
|
-
|
|
501
|
-
report.generate_report("reports/data_validation/report.html")
|
|
599
|
+
report.generate_report("reports/validation.html")
|
|
502
600
|
```
|
|
503
601
|
|
|
504
602
|
**Report Features:**
|
|
@@ -507,8 +605,11 @@ report.generate_report("reports/data_validation/report.html")
|
|
|
507
605
|
- 📋 Row-by-row mismatch details
|
|
508
606
|
- 🎨 Color-coded status indicators
|
|
509
607
|
- 📱 Mobile-responsive design
|
|
608
|
+
- ⚡ Zero manual mismatch tracking required!
|
|
510
609
|
|
|
511
|
-
|
|
610
|
+
**Examples:**
|
|
611
|
+
- **Simple API**: [examples/simple_comparison_examples.py](examples/simple_comparison_examples.py) ⭐ **Recommended**
|
|
612
|
+
- **Manual Building**: [examples/data_comparison_with_html_report.py](examples/data_comparison_with_html_report.py)
|
|
512
613
|
|
|
513
614
|
### Full Documentation
|
|
514
615
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pyplaykit"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.7.0"
|
|
8
8
|
description = "Enterprise Python + Playwright automation framework"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -42,6 +42,12 @@ dependencies = [
|
|
|
42
42
|
"gql[httpx]>=3.5.0",
|
|
43
43
|
]
|
|
44
44
|
|
|
45
|
+
[project.optional-dependencies]
|
|
46
|
+
data-comparison = [
|
|
47
|
+
"pandas>=2.0.0",
|
|
48
|
+
"openpyxl>=3.1.0",
|
|
49
|
+
]
|
|
50
|
+
|
|
45
51
|
[project.scripts]
|
|
46
52
|
pyplaykit = "pyplaykit.cli:main"
|
|
47
53
|
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""Utils package for PyPlayKit framework."""
|
|
2
|
+
|
|
3
|
+
from utils.data_comparison_report import DataComparisonReport
|
|
4
|
+
|
|
5
|
+
# Lazy imports for optional dependencies (pandas, openpyxl)
|
|
6
|
+
# These are only imported when actually used
|
|
7
|
+
def __getattr__(name):
|
|
8
|
+
"""Lazy import for optional comparison utilities."""
|
|
9
|
+
comparison_functions = (
|
|
10
|
+
"compare_excel_files", "compare_csv_files", "compare_dataframes",
|
|
11
|
+
"compare_excel_to_db", "compare_db_to_excel",
|
|
12
|
+
"compare_csv_to_db", "compare_db_to_csv",
|
|
13
|
+
"compare_db_to_db",
|
|
14
|
+
"ComparisonResult"
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
if name in comparison_functions:
|
|
18
|
+
try:
|
|
19
|
+
from utils.data_comparison_utils import (
|
|
20
|
+
compare_excel_files,
|
|
21
|
+
compare_csv_files,
|
|
22
|
+
compare_dataframes,
|
|
23
|
+
compare_excel_to_db,
|
|
24
|
+
compare_db_to_excel,
|
|
25
|
+
compare_csv_to_db,
|
|
26
|
+
compare_db_to_csv,
|
|
27
|
+
compare_db_to_db,
|
|
28
|
+
ComparisonResult,
|
|
29
|
+
)
|
|
30
|
+
return globals()[name] if name in globals() else locals()[name]
|
|
31
|
+
except ImportError as e:
|
|
32
|
+
raise ImportError(
|
|
33
|
+
f"'{name}' requires optional dependencies. Install with: pip install pandas openpyxl"
|
|
34
|
+
) from e
|
|
35
|
+
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
|
36
|
+
|
|
37
|
+
__all__ = [
|
|
38
|
+
"DataComparisonReport",
|
|
39
|
+
"compare_excel_files",
|
|
40
|
+
"compare_csv_files",
|
|
41
|
+
"compare_dataframes",
|
|
42
|
+
"compare_excel_to_db",
|
|
43
|
+
"compare_db_to_excel",
|
|
44
|
+
"compare_csv_to_db",
|
|
45
|
+
"compare_db_to_csv",
|
|
46
|
+
"compare_db_to_db",
|
|
47
|
+
"ComparisonResult",
|
|
48
|
+
]
|