@sridharkikkeri/playwright-common 1.0.14 ā 1.0.17
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/create-healthedge-tests.js +140 -63
- package/package.json +1 -1
|
@@ -9,9 +9,9 @@ const projectPath = path.join(process.cwd(), projectName);
|
|
|
9
9
|
|
|
10
10
|
console.log(`\nš Creating HealthEdge Playwright project: ${projectName}\n`);
|
|
11
11
|
|
|
12
|
-
//
|
|
12
|
+
// Comprehensive Directory Structure
|
|
13
13
|
const dirs = [
|
|
14
|
-
'src/core/api',
|
|
14
|
+
'src/core/api/auth',
|
|
15
15
|
'src/core/config',
|
|
16
16
|
'src/core/i18n',
|
|
17
17
|
'src/core/pages',
|
|
@@ -38,11 +38,11 @@ dirs.forEach(idr => {
|
|
|
38
38
|
fs.mkdirSync(path.join(projectPath, idr), { recursive: true });
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
-
// package.json
|
|
41
|
+
// package.json for the NEW project
|
|
42
42
|
const packageJson = {
|
|
43
43
|
name: projectName,
|
|
44
44
|
version: '1.0.0',
|
|
45
|
-
description: 'HealthEdge Playwright Test Project',
|
|
45
|
+
description: 'HealthEdge Enterprise Playwright Test Project',
|
|
46
46
|
scripts: {
|
|
47
47
|
'test': 'playwright test',
|
|
48
48
|
'test:dev': 'TEST_ENV=dev playwright test',
|
|
@@ -50,12 +50,13 @@ const packageJson = {
|
|
|
50
50
|
'test:auto': 'TEST_ENV=auto playwright test',
|
|
51
51
|
'test:staging': 'TEST_ENV=staging playwright test',
|
|
52
52
|
'test:prod': 'TEST_ENV=prod playwright test',
|
|
53
|
+
'test:visual': 'playwright test src/tests/visual.spec.ts',
|
|
53
54
|
'report': 'allure generate allure-results --clean -o allure-report && allure open allure-report',
|
|
54
55
|
'lint': 'eslint .',
|
|
55
56
|
'lint:fix': 'eslint . --fix'
|
|
56
57
|
},
|
|
57
58
|
dependencies: {
|
|
58
|
-
'@sridharkikkeri/playwright-common': '^1.0.
|
|
59
|
+
'@sridharkikkeri/playwright-common': '^1.0.17',
|
|
59
60
|
'@playwright/test': '^1.42.0',
|
|
60
61
|
'allure-playwright': '^3.4.5'
|
|
61
62
|
},
|
|
@@ -69,27 +70,48 @@ const packageJson = {
|
|
|
69
70
|
|
|
70
71
|
fs.writeFileSync(path.join(projectPath, 'package.json'), JSON.stringify(packageJson, null, 2));
|
|
71
72
|
|
|
72
|
-
// --- CORE BOILERPLATE
|
|
73
|
+
// --- CORE EXTENSION BOILERPLATE ---
|
|
73
74
|
|
|
74
75
|
const baseApiClientTs = `import { ApiClient } from '@sridharkikkeri/playwright-common';
|
|
75
76
|
|
|
76
|
-
/**
|
|
77
|
-
* Project-specific Base API Client.
|
|
78
|
-
*/
|
|
79
77
|
export class BaseApiClient extends ApiClient {
|
|
80
78
|
constructor(baseUrl: string) {
|
|
81
79
|
super(baseUrl);
|
|
82
80
|
}
|
|
81
|
+
// Add shared project-specific headers or logic here
|
|
83
82
|
}
|
|
84
83
|
`;
|
|
85
84
|
fs.writeFileSync(path.join(projectPath, 'src/core/api/BaseApiClient.ts'), baseApiClientTs);
|
|
86
85
|
|
|
86
|
+
const projectAuthTs = `import { CookieAuth, AuthStrategy } from '@sridharkikkeri/playwright-common';
|
|
87
|
+
|
|
88
|
+
export class ProjectAuth {
|
|
89
|
+
static async setupSession(auth: AuthStrategy) {
|
|
90
|
+
// Implement custom complex auth setup if needed
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
`;
|
|
94
|
+
fs.writeFileSync(path.join(projectPath, 'src/core/api/auth/ProjectAuth.ts'), projectAuthTs);
|
|
95
|
+
|
|
96
|
+
const envConfigTs = `import { ConfigManager } from '@sridharkikkeri/playwright-common';
|
|
97
|
+
|
|
98
|
+
export class ProjectConfig extends ConfigManager {
|
|
99
|
+
static getClientName() { return 'HealthEdge'; }
|
|
100
|
+
}
|
|
101
|
+
`;
|
|
102
|
+
fs.writeFileSync(path.join(projectPath, 'src/core/config/ProjectConfig.ts'), envConfigTs);
|
|
103
|
+
|
|
104
|
+
const localizationTs = `import { Localization } from '@sridharkikkeri/playwright-common';
|
|
105
|
+
|
|
106
|
+
export class ProjectLocalization extends Localization {
|
|
107
|
+
static getAvailableLocales() { return ['en', 'fr']; }
|
|
108
|
+
}
|
|
109
|
+
`;
|
|
110
|
+
fs.writeFileSync(path.join(projectPath, 'src/core/i18n/ProjectLocalization.ts'), localizationTs);
|
|
111
|
+
|
|
87
112
|
const baseComponentTs = `import { Page } from '@playwright/test';
|
|
88
113
|
import { BasePage, ActionOrchestrator } from '@sridharkikkeri/playwright-common';
|
|
89
114
|
|
|
90
|
-
/**
|
|
91
|
-
* Base Component for project-specific reusable UI elements.
|
|
92
|
-
*/
|
|
93
115
|
export abstract class BaseComponent extends BasePage {
|
|
94
116
|
constructor(page: Page, orchestrator?: ActionOrchestrator) {
|
|
95
117
|
super(page, { pageName: 'BaseComponent', orchestrator });
|
|
@@ -98,52 +120,92 @@ export abstract class BaseComponent extends BasePage {
|
|
|
98
120
|
`;
|
|
99
121
|
fs.writeFileSync(path.join(projectPath, 'src/core/pages/BaseComponent.ts'), baseComponentTs);
|
|
100
122
|
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
123
|
+
const reporterTs = `import { AllureUtil } from '@sridharkikkeri/playwright-common';
|
|
124
|
+
|
|
125
|
+
export class ProjectReporter {
|
|
126
|
+
static async logEnterpriseStep(name: string) {
|
|
127
|
+
console.log(\`[ENTERPRISE] \${name}\`);
|
|
107
128
|
}
|
|
108
129
|
}
|
|
109
130
|
`;
|
|
131
|
+
fs.writeFileSync(path.join(projectPath, 'src/core/reporting/ProjectReporter.ts'), reporterTs);
|
|
132
|
+
|
|
133
|
+
const healingTs = `import { LocatorHealing } from '@sridharkikkeri/playwright-common';
|
|
134
|
+
|
|
135
|
+
export class ProjectHealer extends LocatorHealing {
|
|
136
|
+
// Override framework healing logic here
|
|
137
|
+
}
|
|
138
|
+
`;
|
|
139
|
+
fs.writeFileSync(path.join(projectPath, 'src/core/selfhealing/ProjectHealer.ts'), healingTs);
|
|
140
|
+
|
|
141
|
+
const visualTs = `import { VisualTesting } from '@sridharkikkeri/playwright-common';
|
|
142
|
+
|
|
143
|
+
export class ProjectVisuals extends VisualTesting {
|
|
144
|
+
// Custom exclusions or thresholds
|
|
145
|
+
}
|
|
146
|
+
`;
|
|
147
|
+
fs.writeFileSync(path.join(projectPath, 'src/core/visual/ProjectVisuals.ts'), visualTs);
|
|
148
|
+
|
|
149
|
+
const wrapperTs = `import { ElementWrapper } from '@sridharkikkeri/playwright-common';
|
|
150
|
+
|
|
151
|
+
export class ProjectElement extends ElementWrapper {
|
|
152
|
+
// Extend element behaviors (e.g., custom scrolls)
|
|
153
|
+
}
|
|
154
|
+
`;
|
|
155
|
+
fs.writeFileSync(path.join(projectPath, 'src/core/wrappers/ProjectElement.ts'), wrapperTs);
|
|
156
|
+
|
|
157
|
+
const projectUtilsTs = `export class ProjectUtils {
|
|
158
|
+
static generateRandomID() { return Math.random().toString(36).substring(7); }
|
|
159
|
+
}
|
|
160
|
+
`;
|
|
110
161
|
fs.writeFileSync(path.join(projectPath, 'src/core/utils/ProjectUtils.ts'), projectUtilsTs);
|
|
111
162
|
|
|
112
|
-
// ---
|
|
163
|
+
// --- UTILS & I18N POPULATION ---
|
|
164
|
+
const stringUtilsTs = `export class StringUtils {
|
|
165
|
+
static capitalize(str: string) { return str.charAt(0).toUpperCase() + str.slice(1); }
|
|
166
|
+
}`;
|
|
167
|
+
fs.writeFileSync(path.join(projectPath, 'src/utils/StringUtils.ts'), stringUtilsTs);
|
|
168
|
+
|
|
169
|
+
const dateUtilsTs = `export class DateUtils {
|
|
170
|
+
static now() { return new Date().toISOString(); }
|
|
171
|
+
}`;
|
|
172
|
+
fs.writeFileSync(path.join(projectPath, 'src/utils/DateUtils.ts'), dateUtilsTs);
|
|
173
|
+
|
|
174
|
+
fs.writeFileSync(path.join(projectPath, 'src/i18n/en.json'), JSON.stringify({ "welcome": "Welcome to HealthEdge" }, null, 2));
|
|
175
|
+
fs.writeFileSync(path.join(projectPath, 'src/i18n/fr.json'), JSON.stringify({ "welcome": "Bienvenue chez HealthEdge" }, null, 2));
|
|
176
|
+
|
|
177
|
+
// --- DOCUMENTATION ---
|
|
178
|
+
fs.writeFileSync(path.join(projectPath, 'api-docs/assets/style.css'), 'body { font-family: sans-serif; padding: 20px; }');
|
|
179
|
+
fs.writeFileSync(path.join(projectPath, 'api-docs/index.html'), `
|
|
180
|
+
<html>
|
|
181
|
+
<head><link rel="stylesheet" href="assets/style.css"></head>
|
|
182
|
+
<body>
|
|
183
|
+
<h1>${projectName} - API Documentation</h1>
|
|
184
|
+
<p>This folder is ready to host your TypeDoc or custom API documentation.</p>
|
|
185
|
+
</body>
|
|
186
|
+
</html>`);
|
|
187
|
+
['classes', 'interfaces', 'types', 'variables'].forEach(fold => {
|
|
188
|
+
fs.writeFileSync(path.join(projectPath, `api-docs/${fold}/README.md`), `# ${fold}\nDocumentation for your project ${fold} goes here.`);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
// --- STANDARD CONFIG & EXAMPLES ---
|
|
113
192
|
const baseConfig = { healingEnabled: true, environment: 'dev', baseUrl: 'https://example.com', apiUrl: 'https://api.example.com', timeout: 30000, retries: 2 };
|
|
114
193
|
const environments = ['dev', 'qa', 'auto', 'staging', 'prod'];
|
|
115
|
-
|
|
116
194
|
environments.forEach(env => {
|
|
117
|
-
const config = {
|
|
118
|
-
...baseConfig,
|
|
119
|
-
environment: env,
|
|
120
|
-
baseUrl: `https://${env}.example.com`,
|
|
121
|
-
apiUrl: `https://api-${env}.example.com`
|
|
122
|
-
};
|
|
195
|
+
const config = { ...baseConfig, environment: env, baseUrl: `https://${env}.example.com`, apiUrl: `https://api-${env}.example.com` };
|
|
123
196
|
fs.writeFileSync(path.join(projectPath, `framework.config.${env}.json`), JSON.stringify(config, null, 2));
|
|
124
197
|
});
|
|
125
198
|
fs.writeFileSync(path.join(projectPath, 'framework.config.json'), JSON.stringify(baseConfig, null, 2));
|
|
126
199
|
|
|
127
|
-
// playwright.config.ts
|
|
128
200
|
const playwrightConfig = `import { defineConfig } from '@playwright/test';
|
|
129
|
-
|
|
130
201
|
export default defineConfig({
|
|
131
202
|
testDir: './src/tests',
|
|
132
203
|
timeout: 30000,
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
reporter: [
|
|
136
|
-
['html'],
|
|
137
|
-
['allure-playwright', { outputFolder: 'allure-results' }]
|
|
138
|
-
],
|
|
139
|
-
use: {
|
|
140
|
-
trace: 'on-first-retry',
|
|
141
|
-
screenshot: 'only-on-failure'
|
|
142
|
-
}
|
|
204
|
+
reporter: [['html'], ['allure-playwright', { outputFolder: 'allure-results' }]],
|
|
205
|
+
use: { trace: 'on-first-retry', screenshot: 'only-on-failure' }
|
|
143
206
|
});`;
|
|
144
207
|
fs.writeFileSync(path.join(projectPath, 'playwright.config.ts'), playwrightConfig);
|
|
145
208
|
|
|
146
|
-
// src/fixtures/fixtures.ts
|
|
147
209
|
const fixturesTs = `import { test as base } from '@sridharkikkeri/playwright-common';
|
|
148
210
|
import { HomePage } from '../pages/HomePage';
|
|
149
211
|
|
|
@@ -156,7 +218,6 @@ export const test = base.extend<{ homePage: HomePage }>({
|
|
|
156
218
|
export { expect } from '@playwright/test';`;
|
|
157
219
|
fs.writeFileSync(path.join(projectPath, 'src/fixtures/fixtures.ts'), fixturesTs);
|
|
158
220
|
|
|
159
|
-
// Sample Page Object
|
|
160
221
|
const samplePage = `import { Page } from '@playwright/test';
|
|
161
222
|
import { BasePage, ActionOrchestrator } from '@sridharkikkeri/playwright-common';
|
|
162
223
|
|
|
@@ -164,33 +225,33 @@ export class HomePage extends BasePage {
|
|
|
164
225
|
constructor(page: Page, orchestrator?: ActionOrchestrator) {
|
|
165
226
|
super(page, { pageName: 'HomePage', orchestrator });
|
|
166
227
|
}
|
|
167
|
-
|
|
168
|
-
private readonly searchInput = this.element('[data-testid="search"]');
|
|
169
228
|
private readonly searchBtn = this.element('button[type="submit"]');
|
|
170
|
-
|
|
171
|
-
async search(query: string) {
|
|
172
|
-
await this.searchInput.fill(query, 'Enter search query');
|
|
173
|
-
await this.searchBtn.click('Click search button');
|
|
174
|
-
}
|
|
229
|
+
async clickSearch() { await this.searchBtn.click('Click Search Button'); }
|
|
175
230
|
}
|
|
176
231
|
`;
|
|
177
232
|
fs.writeFileSync(path.join(projectPath, 'src/pages/HomePage.ts'), samplePage);
|
|
178
233
|
|
|
179
|
-
|
|
234
|
+
const visualTest = `import { test, expect } from '../fixtures/fixtures';
|
|
235
|
+
|
|
236
|
+
test.describe('Enterprise Visual Regression', () => {
|
|
237
|
+
test('HP Visual Verification', async ({ page }) => {
|
|
238
|
+
await page.goto('https://playwright.dev');
|
|
239
|
+
await expect(page).toHaveScreenshot('homepage.png', {
|
|
240
|
+
mask: [page.locator('.navbar')],
|
|
241
|
+
threshold: 0.1
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
});`;
|
|
245
|
+
fs.writeFileSync(path.join(projectPath, 'src/tests/visual.spec.ts'), visualTest);
|
|
246
|
+
|
|
180
247
|
const sampleTest = `import { test, expect } from '../fixtures/fixtures';
|
|
181
248
|
|
|
182
|
-
test
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
await homePage.search('playwright');
|
|
186
|
-
await expect(page).toHaveTitle(/Playwright/);
|
|
187
|
-
});
|
|
249
|
+
test('Standard Smoke Test', async ({ page }) => {
|
|
250
|
+
await page.goto('https://playwright.dev');
|
|
251
|
+
await expect(page).toHaveTitle(/Playwright/);
|
|
188
252
|
});`;
|
|
189
253
|
fs.writeFileSync(path.join(projectPath, 'src/tests/sample.spec.ts'), sampleTest);
|
|
190
254
|
|
|
191
|
-
const sampleI18n = { "login_welcome": "Welcome to HealthEdge" };
|
|
192
|
-
fs.writeFileSync(path.join(projectPath, 'src/i18n/en.json'), JSON.stringify(sampleI18n, null, 2));
|
|
193
|
-
|
|
194
255
|
const tsConfig = {
|
|
195
256
|
compilerOptions: {
|
|
196
257
|
target: 'ES2020',
|
|
@@ -199,7 +260,6 @@ const tsConfig = {
|
|
|
199
260
|
strict: true,
|
|
200
261
|
esModuleInterop: true,
|
|
201
262
|
skipLibCheck: true,
|
|
202
|
-
forceConsistentCasingInFileNames: true,
|
|
203
263
|
resolveJsonModule: true
|
|
204
264
|
},
|
|
205
265
|
include: ['src/**/*']
|
|
@@ -213,19 +273,36 @@ test-results/
|
|
|
213
273
|
playwright-report/
|
|
214
274
|
.env
|
|
215
275
|
*.log
|
|
276
|
+
dist/
|
|
216
277
|
`;
|
|
217
278
|
fs.writeFileSync(path.join(projectPath, '.gitignore'), gitignore);
|
|
218
279
|
|
|
219
|
-
|
|
280
|
+
const readme = `# ${projectName}
|
|
281
|
+
|
|
282
|
+
## Overview
|
|
283
|
+
Enterprise automation test project powered by **@sridharkikkeri/playwright-common**.
|
|
284
|
+
|
|
285
|
+
## Getting Started
|
|
286
|
+
\`\`\`bash
|
|
287
|
+
npm install
|
|
288
|
+
npm run test:dev
|
|
289
|
+
\`\`\`
|
|
290
|
+
|
|
291
|
+
## Features
|
|
292
|
+
- **Self-Healing**: Enabled by default
|
|
293
|
+
- **Visual Regression**: \`npm run test:visual\`
|
|
294
|
+
- **Enterprise Reporting**: Allure integration
|
|
295
|
+
`;
|
|
296
|
+
fs.writeFileSync(path.join(projectPath, 'README.md'), readme);
|
|
297
|
+
|
|
298
|
+
console.log('ā
Comprehensive Project Structure Created');
|
|
220
299
|
console.log('\nš¦ Installing dependencies...\n');
|
|
221
300
|
|
|
222
301
|
try {
|
|
223
302
|
execSync('npm install', { cwd: projectPath, stdio: 'inherit' });
|
|
224
303
|
console.log('\nā
Dependencies installed');
|
|
225
304
|
} catch (error) {
|
|
226
|
-
console.log('\nā ļø
|
|
305
|
+
console.log('\nā ļø npm install failed. Please run manually.');
|
|
227
306
|
}
|
|
228
307
|
|
|
229
|
-
console.log(`\nš Project ready!
|
|
230
|
-
console.log(` cd ${projectName}`);
|
|
231
|
-
console.log(` npm run test:dev\n`);
|
|
308
|
+
console.log(`\nš Project ready! cd ${projectName} and try: npm run test:dev\n`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sridharkikkeri/playwright-common",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.17",
|
|
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",
|