@sridharkikkeri/playwright-common 1.0.23 → 1.0.24

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sridharkikkeri/playwright-common",
3
- "version": "1.0.23",
3
+ "version": "1.0.24",
4
4
  "description": "Production-grade Playwright framework with AI-powered self-healing, visual regression, and enterprise features",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/CLEAN_IMPORTS.md DELETED
@@ -1,184 +0,0 @@
1
- # Clean Import Guide (v1.0.1+)
2
-
3
- ## ✅ What Changed in v1.0.1
4
-
5
- **Before (v1.0.0):**
6
- ```typescript
7
- // ❌ Ugly deep imports
8
- import { test } from '@sridharkikkeri/playwright-common/dist/com/healthedge/common/fixtures/fixtures';
9
- import { BasePage } from '@sridharkikkeri/playwright-common/dist/com/healthedge/common/core/pages/BasePage';
10
- ```
11
-
12
- **After (v1.0.1):**
13
- ```typescript
14
- // ✅ Clean barrel imports
15
- import { test, BasePage, VisualTesting } from '@sridharkikkeri/playwright-common';
16
- ```
17
-
18
- ---
19
-
20
- ## Usage Examples
21
-
22
- ### Basic Test
23
- ```typescript
24
- import { test } from '@sridharkikkeri/playwright-common';
25
-
26
- test('My test', async ({ page }) => {
27
- await page.goto('https://example.com');
28
- });
29
- ```
30
-
31
- ### Page Object Pattern
32
- ```typescript
33
- import { BasePage } from '@sridharkikkeri/playwright-common';
34
- import { Page } from '@playwright/test';
35
-
36
- export class LoginPage extends BasePage {
37
- constructor(page: Page) {
38
- super(page, 'LoginPage');
39
- }
40
-
41
- private readonly username = this.element('#username');
42
- private readonly loginBtn = this.element('button[type="submit"]');
43
-
44
- async login(user: string) {
45
- await this.username.fill(user, 'Enter username');
46
- await this.loginBtn.click('Click login');
47
- }
48
- }
49
- ```
50
-
51
- ### Visual Testing
52
- ```typescript
53
- import { test, VisualTesting } from '@sridharkikkeri/playwright-common';
54
-
55
- test('Visual regression', async ({ page }) => {
56
- const visual = new VisualTesting(page);
57
- await page.goto('/dashboard');
58
- await visual.compareFullPage({ name: 'dashboard' });
59
- });
60
- ```
61
-
62
- ### API Testing
63
- ```typescript
64
- import { test, ApiClient } from '@sridharkikkeri/playwright-common';
65
-
66
- test('API test', async ({ request }) => {
67
- const client = new ApiClient(request);
68
- const response = await client.get('/api/users/1');
69
- expect(response.status).toBe(200);
70
- });
71
- ```
72
-
73
- ### Configuration
74
- ```typescript
75
- import { ConfigManager } from '@sridharkikkeri/playwright-common';
76
-
77
- const config = ConfigManager.getConfig();
78
- console.log(config.healingEnabled); // true
79
- console.log(config.environment); // 'dev'
80
- ```
81
-
82
- ### Localization
83
- ```typescript
84
- import { Localization } from '@sridharkikkeri/playwright-common';
85
-
86
- const message = Localization.get('welcome_message', 'en');
87
- ```
88
-
89
- ### Allure Reporting
90
- ```typescript
91
- import { AllureUtil } from '@sridharkikkeri/playwright-common';
92
-
93
- await AllureUtil.step('Custom step', async () => {
94
- // Your logic
95
- AllureUtil.attachJson('Data', { key: 'value' });
96
- });
97
- ```
98
-
99
- ---
100
-
101
- ## All Available Exports
102
-
103
- ```typescript
104
- import {
105
- // Testing
106
- test,
107
-
108
- // Pages
109
- BasePage,
110
- LoginPage,
111
-
112
- // Wrappers
113
- ElementWrapper,
114
-
115
- // Self-Healing
116
- ActionOrchestrator,
117
- LocatorHealing,
118
- ElementProfileStore,
119
-
120
- // API
121
- ApiClient,
122
- AuthStrategy,
123
- CookieAuth,
124
- OAuth2Auth,
125
-
126
- // Visual
127
- VisualTesting,
128
-
129
- // Config
130
- ConfigManager,
131
-
132
- // i18n
133
- Localization,
134
-
135
- // Reporting
136
- AllureUtil,
137
-
138
- // Utils
139
- Logger,
140
- ErrorUtils
141
- } from '@sridharkikkeri/playwright-common';
142
- ```
143
-
144
- ---
145
-
146
- ## TypeScript Support
147
-
148
- Full TypeScript support with auto-completion:
149
-
150
- ```typescript
151
- import { BasePage } from '@sridharkikkeri/playwright-common';
152
- // ^
153
- // VS Code will show type hints and documentation
154
- ```
155
-
156
- ---
157
-
158
- ## Migration from v1.0.0 to v1.0.1
159
-
160
- **Find and replace in your project:**
161
-
162
- ```bash
163
- # Old pattern
164
- @sridharkikkeri/playwright-common/dist/com/healthedge/common/
165
-
166
- # New pattern
167
- @sridharkikkeri/playwright-common
168
- ```
169
-
170
- **Or use this script:**
171
- ```bash
172
- find . -name "*.ts" -type f -exec sed -i '' \
173
- 's|@sridharkikkeri/playwright-common/dist/com/healthedge/common/[^'"'"']*|@sridharkikkeri/playwright-common|g' {} +
174
- ```
175
-
176
- ---
177
-
178
- ## Installation
179
-
180
- ```bash
181
- npm install @sridharkikkeri/playwright-common@latest
182
- ```
183
-
184
- **Package URL:** https://www.npmjs.com/package/@sridharkikkeri/playwright-common
@@ -1,222 +0,0 @@
1
- # Self-Healing Cache Strategy
2
-
3
- ## Overview
4
- The framework's self-healing mechanism uses an in-memory cache to store element profiles and healed selectors, enabling intelligent locator recovery without repeated AI calls.
5
-
6
- ---
7
-
8
- ## Architecture
9
-
10
- ### 1. Element Profile Store
11
- **Location**: `ElementProfileStore.ts`
12
-
13
- **Purpose**: Maintains a runtime cache of element "fingerprints" captured during successful interactions.
14
-
15
- ```typescript
16
- interface ElementProfile {
17
- selector: string; // Original selector
18
- intent: string; // Human-readable action intent
19
- attributes: Record<string, string>; // DOM attributes snapshot
20
- lastHealedSelector?: string; // Last successful healed selector
21
- healingFailed?: boolean; // Flag if healing exhausted
22
- failureType?: string; // Reason for healing failure
23
- }
24
- ```
25
-
26
- **Key**: `{pageName}:{intent}` (e.g., `LoginPage:Click Login Button`)
27
-
28
- ---
29
-
30
- ## Caching Flow
31
-
32
- ### Phase 1: Profile Capture (Success Path)
33
- ```
34
- User Action → Element Found → Capture Attributes → Store Profile
35
- ```
36
-
37
- **When**: After every successful element interaction
38
- **What's Stored**:
39
- - Original selector
40
- - Element tag, text, id, class, data-* attributes
41
- - Action intent for context
42
-
43
- ### Phase 2: Healing Attempt (Failure Path)
44
- ```
45
- Selector Fails → Check Cache → Use lastHealedSelector → If Fails → AI Healing → Update Cache
46
- ```
47
-
48
- **Decision Tree**:
49
- 1. **Cache Hit + Valid Healed Selector**: Use cached healed selector (fast path)
50
- 2. **Cache Hit + Failed Flag**: Skip healing, fail fast
51
- 3. **Cache Miss or Stale**: Trigger AI healing via LLM
52
-
53
- ### Phase 3: AI Healing (Expensive Path)
54
- ```
55
- Extract Profile → LLM Analysis → Generate New Selector → Validate → Cache Result
56
- ```
57
-
58
- **LLM Input**:
59
- - Element attributes from profile
60
- - Page context (pageName)
61
- - Action intent
62
- - DOM snapshot (optional)
63
-
64
- **LLM Output**: Alternative selector candidates
65
-
66
- **Validation**: Test each candidate; first success is cached
67
-
68
- ---
69
-
70
- ## Cache Lifecycle
71
-
72
- ### Scope
73
- - **Per Test Run**: Cache is in-memory, resets between test executions
74
- - **Per Worker**: Isolated cache per Playwright worker (no cross-worker sharing)
75
-
76
- ### Persistence
77
- **Current**: No persistence (ephemeral)
78
-
79
- **Future Enhancement**: Serialize to `.healing-cache.json` for cross-run reuse
80
- ```json
81
- {
82
- "LoginPage:Click Login Button": {
83
- "lastHealedSelector": "button[data-testid='login-submit']",
84
- "timestamp": 1704067200000,
85
- "successRate": 0.95
86
- }
87
- }
88
- ```
89
-
90
- ---
91
-
92
- ## Performance Optimization
93
-
94
- ### 1. Fast Path (Cache Hit)
95
- - **Latency**: ~5ms (in-memory lookup)
96
- - **Cost**: $0
97
- - **Success Rate**: 85-90% for stable apps
98
-
99
- ### 2. Slow Path (AI Healing)
100
- - **Latency**: 2-5 seconds (LLM API call)
101
- - **Cost**: ~$0.001-0.01 per healing
102
- - **Success Rate**: 70-80% for moderate DOM changes
103
-
104
- ### 3. Fail Fast
105
- - **Latency**: ~10ms
106
- - **Triggered**: When `healingFailed=true` in cache
107
- - **Prevents**: Repeated expensive AI calls for permanently broken elements
108
-
109
- ---
110
-
111
- ## Configuration
112
-
113
- ### Global Toggle
114
- ```json
115
- // framework.config.json
116
- {
117
- "healingEnabled": true // Master switch
118
- }
119
- ```
120
-
121
- ### Per-Action Override
122
- ```typescript
123
- // Disable healing for a specific action
124
- await this.loginBtn.withHealing(false).click();
125
-
126
- // Force healing even if globally disabled
127
- await this.dynamicElement.withHealing(true).click();
128
- ```
129
-
130
- ---
131
-
132
- ## Cache Invalidation
133
-
134
- ### Automatic Invalidation
135
- - Test run completion (cache cleared)
136
- - Worker restart
137
-
138
- ### Manual Invalidation
139
- ```typescript
140
- // Clear specific profile
141
- ElementProfileStore.clearProfile('LoginPage', 'Click Login Button');
142
-
143
- // Clear all profiles for a page
144
- ElementProfileStore.clearPage('LoginPage');
145
-
146
- // Nuclear option: clear entire cache
147
- ElementProfileStore.clearAll();
148
- ```
149
-
150
- ---
151
-
152
- ## Monitoring & Debugging
153
-
154
- ### Healing Metrics
155
- ```typescript
156
- const stats = ElementProfileStore.getStats();
157
- console.log(stats);
158
- // {
159
- // totalProfiles: 45,
160
- // healedCount: 12,
161
- // failedCount: 2,
162
- // cacheHitRate: 0.73
163
- // }
164
- ```
165
-
166
- ### Allure Reporting
167
- Healing events are automatically logged:
168
- - ✅ **Cache Hit**: "Used cached healed selector"
169
- - 🔄 **AI Healing**: "Triggered AI healing (took 3.2s)"
170
- - ❌ **Healing Failed**: "Exhausted healing attempts"
171
-
172
- ---
173
-
174
- ## Best Practices
175
-
176
- ### 1. Meaningful Intents
177
- ```typescript
178
- // ❌ Bad: Generic intent
179
- await this.btn.click('click');
180
-
181
- // ✅ Good: Descriptive intent
182
- await this.btn.click('Submit Login Form');
183
- ```
184
-
185
- ### 2. Stable Attributes
186
- Prefer selectors with stable attributes:
187
- - `data-testid`
188
- - `aria-label`
189
- - `id` (if not auto-generated)
190
-
191
- ### 3. Healing Budget
192
- Set a healing attempt limit to prevent infinite loops:
193
- ```typescript
194
- // In ActionOrchestrator
195
- const MAX_HEALING_ATTEMPTS = 3;
196
- ```
197
-
198
- ---
199
-
200
- ## Troubleshooting
201
-
202
- ### Issue: High AI Healing Costs
203
- **Solution**: Increase cache persistence, improve selector stability
204
-
205
- ### Issue: Low Healing Success Rate
206
- **Solution**: Enrich element profiles with more attributes, improve LLM prompt
207
-
208
- ### Issue: Stale Cached Selectors
209
- **Solution**: Add TTL (time-to-live) to cached entries
210
- ```typescript
211
- profile.expiresAt = Date.now() + 24 * 60 * 60 * 1000; // 24h
212
- ```
213
-
214
- ---
215
-
216
- ## Future Enhancements
217
-
218
- 1. **Persistent Cache**: Save to disk for cross-run reuse
219
- 2. **Distributed Cache**: Redis/Memcached for multi-worker sharing
220
- 3. **ML-Based Healing**: Train a model on historical healing data
221
- 4. **Visual Healing**: Use screenshot comparison for element identification
222
- 5. **Healing Analytics Dashboard**: Visualize healing patterns and costs
package/NPM_PUBLISHING.md DELETED
@@ -1,213 +0,0 @@
1
- # NPM Publishing Guide
2
-
3
- ## Package Information
4
- - **Name**: `@healthedge/playwright-common`
5
- - **Version**: `1.0.0`
6
- - **Size**: ~34 KB (compressed)
7
-
8
- ---
9
-
10
- ## Pre-Publish Checklist
11
-
12
- ✅ TypeScript compiled to `dist/`
13
- ✅ Type definitions generated
14
- ✅ Documentation included (README, HEALING_CACHE_STRATEGY, VISUAL_TESTING)
15
- ✅ Project generator script included
16
- ✅ Test files excluded from package
17
-
18
- ---
19
-
20
- ## Publishing Steps
21
-
22
- ### 1. Enable 2FA on NPM Account (Web Interface)
23
- **NPM no longer supports TOTP via CLI. Use web interface:**
24
-
25
- 1. Go to https://www.npmjs.com/settings/YOUR_USERNAME/tfa
26
- 2. Click "Add 2FA Method"
27
- 3. Choose "Authenticator App" or "Security Key"
28
- 4. Follow setup instructions
29
- 5. Save backup codes
30
-
31
- **OR use Automation Token (recommended for publishing):**
32
- 1. Go to https://www.npmjs.com/settings/YOUR_USERNAME/tokens
33
- 2. Click "Generate New Token"
34
- 3. Select **"Automation"** type (bypasses 2FA)
35
- 4. Copy token and save securely
36
- 5. Use token for publishing:
37
- ```bash
38
- npm config set //registry.npmjs.org/:_authToken YOUR_TOKEN
39
- ```
40
-
41
- ### 2. Test Package Locally
42
- ```bash
43
- # Build the package
44
- npm run build
45
-
46
- # Test package contents
47
- npm pack --dry-run
48
-
49
- # Create tarball for local testing
50
- npm pack
51
- ```
52
-
53
- ### 3. Test in Another Project
54
- ```bash
55
- # In another project directory
56
- npm install /path/to/healthedge-playwright-common-1.0.0.tgz
57
-
58
- # Test imports
59
- import { BasePage, VisualTesting, test } from '@healthedge/playwright-common';
60
- ```
61
-
62
- ### 4. Login to NPM
63
- ```bash
64
- # If using automation token, skip this step
65
- # Token is already configured in step 1
66
-
67
- # If using 2FA with authenticator app:
68
- npm login
69
- # Enter credentials + 2FA code when prompted
70
- ```
71
-
72
- ### 5. Publish to NPM
73
- ```bash
74
- # With automation token (no 2FA prompt)
75
- npm publish --access public
76
-
77
- # With 2FA authenticator (enter code when prompted)
78
- npm publish --access public
79
- ```
80
-
81
- ### 6. Verify Publication
82
- ```bash
83
- npm view @healthedge/playwright-common
84
- ```
85
-
86
- ---
87
-
88
- ## Installation (After Publishing)
89
-
90
- ### For End Users
91
- ```bash
92
- # Install the framework
93
- npm install @healthedge/playwright-common
94
-
95
- # Create new project
96
- npx create-healthedge-tests my-project
97
- ```
98
-
99
- ### Usage
100
- ```typescript
101
- import { test, BasePage, VisualTesting } from '@healthedge/playwright-common';
102
-
103
- test('My test', async ({ page }) => {
104
- // Use framework features
105
- });
106
- ```
107
-
108
- ---
109
-
110
- ## Version Management
111
-
112
- ### Update Version
113
- ```bash
114
- # Patch (1.0.0 -> 1.0.1)
115
- npm version patch
116
-
117
- # Minor (1.0.0 -> 1.1.0)
118
- npm version minor
119
-
120
- # Major (1.0.0 -> 2.0.0)
121
- npm version major
122
- ```
123
-
124
- ### Publish Update
125
- ```bash
126
- npm run build
127
- npm publish
128
- ```
129
-
130
- ---
131
-
132
- ## CI/CD Publishing (GitHub Actions)
133
-
134
- ```yaml
135
- name: Publish to NPM
136
-
137
- on:
138
- release:
139
- types: [created]
140
-
141
- jobs:
142
- publish:
143
- runs-on: ubuntu-latest
144
- steps:
145
- - uses: actions/checkout@v3
146
- - uses: actions/setup-node@v3
147
- with:
148
- node-version: '18'
149
- registry-url: 'https://registry.npmjs.org'
150
-
151
- - run: npm ci
152
- - run: npm run build
153
- - run: npm publish --access public
154
- env:
155
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
156
- ```
157
-
158
- ---
159
-
160
- ## Troubleshooting
161
-
162
- ### Issue: 403 Forbidden - 2FA required
163
- **Solution**: Use Automation Token (easiest)
164
- 1. Go to https://www.npmjs.com/settings/YOUR_USERNAME/tokens
165
- 2. Generate "Automation" token
166
- 3. Configure:
167
- ```bash
168
- npm config set //registry.npmjs.org/:_authToken YOUR_TOKEN
169
- npm publish --access public
170
- ```
171
-
172
- ### Issue: TOTP 2FA no longer supported via CLI
173
- **Solution**: NPM deprecated CLI-based 2FA setup. Use web interface at https://www.npmjs.com/settings/YOUR_USERNAME/tfa or use Automation tokens instead.
174
-
175
- ### Issue: Package name already exists
176
- **Solution**: Change package name in `package.json` or use scoped name like `@yourorg/playwright-common`
177
-
178
- ### Issue: Build fails
179
- **Solution**: Run `npm run build` and fix TypeScript errors
180
-
181
- ### Issue: Large package size
182
- **Solution**: Check `.npmignore` to exclude unnecessary files
183
-
184
- ---
185
-
186
- ## Package Registry Alternatives
187
-
188
- ### GitHub Packages
189
- ```bash
190
- # Update package.json
191
- "publishConfig": {
192
- "registry": "https://npm.pkg.github.com"
193
- }
194
-
195
- # Publish
196
- npm publish
197
- ```
198
-
199
- ### Private Registry (Artifactory, Verdaccio)
200
- ```bash
201
- npm config set registry https://your-registry.com
202
- npm publish
203
- ```
204
-
205
- ---
206
-
207
- ## Post-Publish
208
-
209
- 1. Update README with installation instructions
210
- 2. Create GitHub release with changelog
211
- 3. Announce on team channels
212
- 4. Update documentation site
213
- 5. Monitor npm download stats: `npm view @healthedge/playwright-common`
package/PUBLISHED.md DELETED
@@ -1,153 +0,0 @@
1
- # 🎉 Package Published Successfully!
2
-
3
- ## Package Details
4
- - **Name**: `@sridharkikkeri/playwright-common`
5
- - **Version**: `1.0.0`
6
- - **Published**: ✅ Live on NPM
7
- - **Size**: 131.3 kB (unpacked), 33.9 kB (tarball)
8
- - **NPM Page**: https://www.npmjs.com/package/@sridharkikkeri/playwright-common
9
-
10
- ---
11
-
12
- ## Installation
13
-
14
- ### For End Users
15
- ```bash
16
- # Install the framework (use latest for clean imports)
17
- npm install @sridharkikkeri/playwright-common@latest
18
-
19
- # Or create new project with generator
20
- npx create-healthedge-tests my-project
21
- cd my-project
22
- npm install
23
- npm run test:dev
24
- ```
25
-
26
- ### Clean Imports (v1.0.1+)
27
- ```typescript
28
- // ✅ Clean barrel imports
29
- import { test, BasePage, VisualTesting } from '@sridharkikkeri/playwright-common';
30
-
31
- // ❌ Don't use deep imports (v1.0.0 style)
32
- import { test } from '@sridharkikkeri/playwright-common/dist/com/healthedge/common/...';
33
- ```
34
-
35
- See [CLEAN_IMPORTS.md](./CLEAN_IMPORTS.md) for complete usage guide.
36
-
37
- ---
38
-
39
- ## Usage Examples
40
-
41
- ### Basic Test
42
- ```typescript
43
- import { test, BasePage } from '@sridharkikkeri/playwright-common';
44
-
45
- test('My first test', async ({ page }) => {
46
- await page.goto('https://example.com');
47
- // Your test logic
48
- });
49
- ```
50
-
51
- ### Visual Regression
52
- ```typescript
53
- import { test, VisualTesting } from '@sridharkikkeri/playwright-common';
54
-
55
- test('Visual check', async ({ page }) => {
56
- const visual = new VisualTesting(page);
57
- await page.goto('/dashboard');
58
- await visual.compareFullPage({ name: 'dashboard' });
59
- });
60
- ```
61
-
62
- ### Page Object Pattern
63
- ```typescript
64
- import { BasePage } from '@sridharkikkeri/playwright-common';
65
-
66
- export class LoginPage extends BasePage {
67
- constructor(page) {
68
- super(page, 'LoginPage');
69
- }
70
-
71
- private readonly username = this.element('#username');
72
- private readonly password = this.element('#password');
73
- private readonly loginBtn = this.element('button[type="submit"]');
74
-
75
- async login(user: string, pass: string) {
76
- await this.username.fill(user, 'Enter username');
77
- await this.password.fill(pass, 'Enter password');
78
- await this.loginBtn.click('Click login');
79
- }
80
- }
81
- ```
82
-
83
- ---
84
-
85
- ## Features Included
86
-
87
- ✅ **AI-Powered Self-Healing** - Automatic locator recovery
88
- ✅ **Visual Regression Testing** - Built-in snapshot comparison
89
- ✅ **Environment Configs** - dev, qa, auto, staging, prod
90
- ✅ **API Testing** - Robust ApiClient with auth strategies
91
- ✅ **Allure Reporting** - Integrated test reporting
92
- ✅ **Localization (i18n)** - Multi-language support
93
- ✅ **Enterprise Fixtures** - Zero-boilerplate test setup
94
- ✅ **Project Generator** - Bootstrap new projects instantly
95
-
96
- ---
97
-
98
- ## Documentation
99
-
100
- - [README](https://github.com/healthedge/playwright-framework#readme)
101
- - [Healing Cache Strategy](./HEALING_CACHE_STRATEGY.md)
102
- - [Visual Testing Guide](./VISUAL_TESTING.md)
103
- - [NPM Publishing Guide](./NPM_PUBLISHING.md)
104
-
105
- ---
106
-
107
- ## Next Steps
108
-
109
- ### Update Package
110
- ```bash
111
- # Bump version
112
- npm version patch # 1.0.0 -> 1.0.1
113
- npm version minor # 1.0.0 -> 1.1.0
114
- npm version major # 1.0.0 -> 2.0.0
115
-
116
- # Rebuild and publish
117
- npm run build
118
- npm publish --access public
119
- ```
120
-
121
- ### Share with Team
122
- ```bash
123
- # Share installation command
124
- npm install @sridharkikkeri/playwright-common
125
-
126
- # Or share project generator
127
- npx create-healthedge-tests my-project
128
- ```
129
-
130
- ---
131
-
132
- ## Stats & Monitoring
133
-
134
- **View package stats:**
135
- - NPM page: https://www.npmjs.com/package/@sridharkikkeri/playwright-common
136
- - Download stats: https://npm-stat.com/charts.html?package=@sridharkikkeri/playwright-common
137
-
138
- **Monitor usage:**
139
- ```bash
140
- npm view @sridharkikkeri/playwright-common
141
- ```
142
-
143
- ---
144
-
145
- ## Support
146
-
147
- For issues or questions:
148
- - GitHub Issues: https://github.com/healthedge/playwright-framework/issues
149
- - Email: sridharkikkeri@gmail.com
150
-
151
- ---
152
-
153
- **Congratulations! Your framework is now available to the world! 🚀**
package/QUICK_FIX.md DELETED
@@ -1,40 +0,0 @@
1
- # Quick Fix: NPM Token Issue
2
-
3
- ## Steps to Publish
4
-
5
- 1. **Generate NEW Automation Token:**
6
- - Go to: https://www.npmjs.com/settings/sridharkikkeri/tokens
7
- - Click "Generate New Token"
8
- - Select **"Automation"** (NOT Classic or Publish)
9
- - Copy the token
10
-
11
- 2. **Clear old config and set new token:**
12
- ```bash
13
- npm config delete //registry.npmjs.org/:_authToken
14
- npm config set //registry.npmjs.org/:_authToken YOUR_NEW_TOKEN_HERE
15
- ```
16
-
17
- 3. **Verify token works:**
18
- ```bash
19
- npm whoami
20
- # Should show: sridharkikkeri
21
- ```
22
-
23
- 4. **Publish:**
24
- ```bash
25
- npm publish --access public
26
- ```
27
-
28
- ## Alternative: Use unscoped name (no @ prefix)
29
-
30
- If token issues persist, change package name to unscoped:
31
-
32
- In `package.json`:
33
- ```json
34
- "name": "playwright-common-healthedge"
35
- ```
36
-
37
- Then publish:
38
- ```bash
39
- npm publish
40
- ```
package/VISUAL_TESTING.md DELETED
@@ -1,319 +0,0 @@
1
- # Visual Regression Testing
2
-
3
- ## Overview
4
- The framework includes built-in visual regression testing using Playwright's snapshot comparison, wrapped in `VisualTesting` utility with Allure integration.
5
-
6
- ---
7
-
8
- ## Quick Start
9
-
10
- ### 1. Basic Usage
11
-
12
- ```typescript
13
- import { test } from '@healthedge/common';
14
- import { VisualTesting } from '@healthedge/common';
15
-
16
- test('Visual regression - Homepage', async ({ page }) => {
17
- const visual = new VisualTesting(page);
18
-
19
- await page.goto('https://example.com');
20
-
21
- // Compare full page
22
- await visual.compareFullPage({ name: 'homepage' });
23
- });
24
- ```
25
-
26
- ### 2. Element-Specific Comparison
27
-
28
- ```typescript
29
- test('Visual regression - Login button', async ({ page }) => {
30
- const visual = new VisualTesting(page);
31
- const loginBtn = page.locator('#login-btn');
32
-
33
- await visual.compareElement(loginBtn, {
34
- name: 'login-button',
35
- threshold: 0.02 // Allow 2% difference
36
- });
37
- });
38
- ```
39
-
40
- ### 3. Masking Dynamic Content
41
-
42
- ```typescript
43
- test('Visual regression - Mask timestamps', async ({ page }) => {
44
- const visual = new VisualTesting(page);
45
-
46
- await page.goto('/dashboard');
47
-
48
- // Mask elements that change frequently
49
- await visual.compareFullPage({
50
- name: 'dashboard',
51
- mask: [
52
- page.locator('.timestamp'),
53
- page.locator('.user-avatar'),
54
- page.locator('[data-dynamic="true"]')
55
- ]
56
- });
57
- });
58
- ```
59
-
60
- ---
61
-
62
- ## API Reference
63
-
64
- ### compareFullPage(options?)
65
- Compare entire page screenshot against baseline.
66
-
67
- **Options:**
68
- - `name`: Snapshot filename (default: 'full-page')
69
- - `threshold`: Max pixel difference ratio 0-1 (default: 0.01)
70
- - `mask`: Array of locators to mask
71
- - `fullPage`: Capture full scrollable page (default: true)
72
-
73
- ### compareElement(locator, options?)
74
- Compare specific element screenshot.
75
-
76
- **Options:**
77
- - `name`: Snapshot filename (default: 'element')
78
- - `threshold`: Max pixel difference ratio 0-1 (default: 0.01)
79
-
80
- ### compareViewport(options?)
81
- Compare visible viewport only (no scrolling).
82
-
83
- **Options:**
84
- - `name`: Snapshot filename (default: 'viewport')
85
- - `threshold`: Max pixel difference ratio 0-1 (default: 0.01)
86
- - `mask`: Array of locators to mask
87
-
88
- ### captureBaseline(name, fullPage?)
89
- Manually capture baseline (for documentation purposes).
90
-
91
- ---
92
-
93
- ## Workflow
94
-
95
- ### 1. Create Baselines (First Run)
96
- ```bash
97
- # Generate baseline snapshots
98
- npx playwright test --update-snapshots
99
- ```
100
-
101
- Baselines are stored in `**/__snapshots__/` directories.
102
-
103
- ### 2. Run Visual Tests
104
- ```bash
105
- # Compare against baselines
106
- npx playwright test
107
- ```
108
-
109
- ### 3. Review Failures
110
- When visual tests fail, Playwright generates:
111
- - **Actual**: Current screenshot
112
- - **Expected**: Baseline screenshot
113
- - **Diff**: Highlighted differences
114
-
115
- Located in: `test-results/*/`
116
-
117
- ### 4. Update Baselines
118
- ```bash
119
- # Update specific test
120
- npx playwright test visual.spec.ts --update-snapshots
121
-
122
- # Update all
123
- npx playwright test --update-snapshots
124
- ```
125
-
126
- ---
127
-
128
- ## Configuration
129
-
130
- ### Playwright Config
131
- ```typescript
132
- // playwright.config.ts
133
- export default defineConfig({
134
- expect: {
135
- toHaveScreenshot: {
136
- maxDiffPixels: 100, // Max different pixels
137
- threshold: 0.2, // Per-pixel color threshold
138
- animations: 'disabled', // Disable CSS animations
139
- }
140
- }
141
- });
142
- ```
143
-
144
- ### Per-Test Override
145
- ```typescript
146
- await visual.compareFullPage({
147
- threshold: 0.05, // Allow 5% difference for this test
148
- });
149
- ```
150
-
151
- ---
152
-
153
- ## Best Practices
154
-
155
- ### 1. Stable Test Data
156
- ```typescript
157
- // ❌ Bad: Random data causes failures
158
- await page.fill('#name', Math.random().toString());
159
-
160
- // ✅ Good: Fixed test data
161
- await page.fill('#name', 'Test User');
162
- ```
163
-
164
- ### 2. Mask Dynamic Content
165
- ```typescript
166
- // Mask timestamps, user-specific data, ads
167
- await visual.compareFullPage({
168
- mask: [
169
- page.locator('.timestamp'),
170
- page.locator('.ad-banner'),
171
- page.locator('[data-user-id]')
172
- ]
173
- });
174
- ```
175
-
176
- ### 3. Wait for Stability
177
- ```typescript
178
- // Wait for animations/loading
179
- await page.waitForLoadState('networkidle');
180
- await page.waitForTimeout(500); // Allow CSS transitions
181
-
182
- await visual.compareFullPage();
183
- ```
184
-
185
- ### 4. Descriptive Names
186
- ```typescript
187
- // ❌ Bad
188
- await visual.compareFullPage({ name: 'test1' });
189
-
190
- // ✅ Good
191
- await visual.compareFullPage({ name: 'checkout-page-logged-in' });
192
- ```
193
-
194
- ### 5. Cross-Browser Baselines
195
- ```bash
196
- # Generate baselines per browser
197
- npx playwright test --update-snapshots --project=chromium
198
- npx playwright test --update-snapshots --project=firefox
199
- ```
200
-
201
- Snapshots are stored separately: `homepage-chromium.png`, `homepage-firefox.png`
202
-
203
- ---
204
-
205
- ## CI/CD Integration
206
-
207
- ### GitHub Actions
208
- ```yaml
209
- - name: Run Visual Tests
210
- run: npx playwright test
211
-
212
- - name: Upload Visual Diffs
213
- if: failure()
214
- uses: actions/upload-artifact@v3
215
- with:
216
- name: visual-diffs
217
- path: test-results/
218
- ```
219
-
220
- ### Baseline Management
221
- **Option 1**: Commit baselines to Git
222
- ```bash
223
- git add **/__snapshots__/
224
- git commit -m "Update visual baselines"
225
- ```
226
-
227
- **Option 2**: Store in artifact repository (S3, Artifactory)
228
-
229
- ---
230
-
231
- ## Troubleshooting
232
-
233
- ### Issue: Flaky Visual Tests
234
- **Causes:**
235
- - Animations not disabled
236
- - Fonts not loaded
237
- - Network requests pending
238
-
239
- **Solution:**
240
- ```typescript
241
- await page.waitForLoadState('networkidle');
242
- await page.evaluate(() => document.fonts.ready);
243
- await page.waitForTimeout(500);
244
- ```
245
-
246
- ### Issue: Cross-Platform Differences
247
- **Cause**: Font rendering differs between OS
248
-
249
- **Solution**: Run tests in Docker with consistent environment
250
- ```dockerfile
251
- FROM mcr.microsoft.com/playwright:v1.42.0-focal
252
- ```
253
-
254
- ### Issue: Large Snapshot Files
255
- **Solution**: Use viewport comparison instead of full page
256
- ```typescript
257
- await visual.compareViewport({ name: 'above-fold' });
258
- ```
259
-
260
- ---
261
-
262
- ## Example Test Suite
263
-
264
- ```typescript
265
- import { test } from '@healthedge/common';
266
- import { VisualTesting } from '@healthedge/common';
267
-
268
- test.describe('Visual Regression Suite', () => {
269
- test.beforeEach(async ({ page }) => {
270
- await page.goto('/');
271
- await page.waitForLoadState('networkidle');
272
- });
273
-
274
- test('Homepage - Desktop', async ({ page }) => {
275
- const visual = new VisualTesting(page);
276
- await visual.compareFullPage({ name: 'homepage-desktop' });
277
- });
278
-
279
- test('Homepage - Mobile', async ({ page }) => {
280
- await page.setViewportSize({ width: 375, height: 667 });
281
- const visual = new VisualTesting(page);
282
- await visual.compareFullPage({ name: 'homepage-mobile' });
283
- });
284
-
285
- test('Login Modal', async ({ page }) => {
286
- const visual = new VisualTesting(page);
287
- await page.click('#login-btn');
288
-
289
- const modal = page.locator('.login-modal');
290
- await visual.compareElement(modal, { name: 'login-modal' });
291
- });
292
-
293
- test('Dashboard - Mask Dynamic', async ({ page }) => {
294
- const visual = new VisualTesting(page);
295
- await page.goto('/dashboard');
296
-
297
- await visual.compareFullPage({
298
- name: 'dashboard',
299
- mask: [
300
- page.locator('.last-login-time'),
301
- page.locator('.notification-badge')
302
- ]
303
- });
304
- });
305
- });
306
- ```
307
-
308
- ---
309
-
310
- ## Allure Integration
311
-
312
- Visual test results automatically appear in Allure reports:
313
- - ✅ **Passed**: Green checkmark
314
- - ❌ **Failed**: Diff image attached
315
- - 📸 **Baseline**: Attached for reference
316
-
317
- ```bash
318
- npm run report # View in Allure
319
- ```