@sridharkikkeri/playwright-common 1.0.19 → 1.0.22

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.
@@ -9,17 +9,26 @@ const projectPath = path.join(process.cwd(), projectName);
9
9
 
10
10
  console.log(`\nšŸš€ Creating HealthEdge Playwright project: ${projectName}\n`);
11
11
 
12
- // Comprehensive Directory Structure
13
- const dirs = [
14
- 'src/core/api/auth',
15
- 'src/core/config',
16
- 'src/core/i18n',
17
- 'src/core/pages',
18
- 'src/core/reporting',
19
- 'src/core/selfhealing',
20
- 'src/core/utils',
21
- 'src/core/visual',
22
- 'src/core/wrappers',
12
+ // Recursive Copy Helper
13
+ function copyRecursiveSync(src, dest) {
14
+ const exists = fs.existsSync(src);
15
+ const stats = exists && fs.statSync(src);
16
+ const isDirectory = exists && stats.isDirectory();
17
+ if (isDirectory) {
18
+ if (!fs.existsSync(dest)) {
19
+ fs.mkdirSync(dest, { recursive: true });
20
+ }
21
+ fs.readdirSync(src).forEach((childItemName) => {
22
+ copyRecursiveSync(path.join(src, childItemName), path.join(dest, childItemName));
23
+ });
24
+ } else {
25
+ fs.copyFileSync(src, dest);
26
+ }
27
+ }
28
+
29
+ // 1. Create Directories
30
+ const baseDirs = [
31
+ 'src/core',
23
32
  'src/pages',
24
33
  'src/tests',
25
34
  'src/fixtures',
@@ -27,36 +36,55 @@ const dirs = [
27
36
  'src/utils',
28
37
  'allure-results',
29
38
  'allure-report',
30
- 'api-docs/assets',
31
- 'api-docs/classes',
32
- 'api-docs/interfaces',
33
- 'api-docs/types',
34
- 'api-docs/variables'
39
+ 'api-docs'
35
40
  ];
36
41
 
37
- dirs.forEach(idr => {
38
- fs.mkdirSync(path.join(projectPath, idr), { recursive: true });
39
- });
42
+ baseDirs.forEach(d => fs.mkdirSync(path.join(projectPath, d), { recursive: true }));
43
+
44
+ // 2. Copy Framework Source (The "As It Is" Magic)
45
+ const frameworkSrc = path.join(__dirname, 'src');
46
+
47
+ if (fs.existsSync(frameworkSrc)) {
48
+ console.log('šŸ“„ Copying framework source files...');
49
+
50
+ // Copy Core files
51
+ if (fs.existsSync(path.join(frameworkSrc, 'core'))) {
52
+ copyRecursiveSync(path.join(frameworkSrc, 'core'), path.join(projectPath, 'src/core'));
53
+ }
54
+
55
+ // Copy Fixture templates
56
+ if (fs.existsSync(path.join(frameworkSrc, 'fixtures'))) {
57
+ copyRecursiveSync(path.join(frameworkSrc, 'fixtures'), path.join(projectPath, 'src/fixtures'));
58
+ }
59
+
60
+ // Copy Quality Pages to user Pages
61
+ if (fs.existsSync(path.join(frameworkSrc, 'quality/pages'))) {
62
+ copyRecursiveSync(path.join(frameworkSrc, 'quality/pages'), path.join(projectPath, 'src/pages'));
63
+ }
64
+
65
+ // Copy Sample Tests
66
+ if (fs.existsSync(path.join(frameworkSrc, 'tests'))) {
67
+ copyRecursiveSync(path.join(frameworkSrc, 'tests'), path.join(projectPath, 'src/tests'));
68
+ }
69
+ } else {
70
+ console.log('āš ļø Framework source not found in package. Using fallback templates.');
71
+ // Fallback (minimal)
72
+ fs.writeFileSync(path.join(projectPath, 'src/core/placeholder.ts'), '// Framework source missing in package');
73
+ }
40
74
 
41
- // package.json for the NEW project
75
+ // 3. package.json for the target project
42
76
  const packageJson = {
43
77
  name: projectName,
44
78
  version: '1.0.0',
45
- description: 'HealthEdge Enterprise Playwright Test Project',
79
+ description: 'HealthEdge Enterprise Test Project',
46
80
  scripts: {
47
81
  'test': 'playwright test',
48
82
  'test:dev': 'TEST_ENV=dev playwright test',
49
- 'test:qa': 'TEST_ENV=qa playwright test',
50
- 'test:auto': 'TEST_ENV=auto playwright test',
51
- 'test:staging': 'TEST_ENV=staging playwright test',
52
- 'test:prod': 'TEST_ENV=prod playwright test',
53
- 'test:visual': 'playwright test src/tests/visual.spec.ts',
54
83
  'report': 'allure generate allure-results --clean -o allure-report && allure open allure-report',
55
- 'lint': 'eslint .',
56
- 'lint:fix': 'eslint . --fix'
84
+ 'lint': 'eslint . --ext .ts'
57
85
  },
58
86
  dependencies: {
59
- '@sridharkikkeri/playwright-common': '^1.0.19',
87
+ '@sridharkikkeri/playwright-common': '^1.0.22',
60
88
  '@playwright/test': '^1.42.0',
61
89
  'allure-playwright': '^3.4.5'
62
90
  },
@@ -67,189 +95,10 @@ const packageJson = {
67
95
  'typescript': '^5.3.0'
68
96
  }
69
97
  };
70
-
71
98
  fs.writeFileSync(path.join(projectPath, 'package.json'), JSON.stringify(packageJson, null, 2));
72
99
 
73
- // --- ENHANCED CORE EXTENSION BOILERPLATE ---
74
-
75
- const apiClientTs = `import { ApiClient as CommonApiClient } from '@sridharkikkeri/playwright-common';
76
-
77
- /**
78
- * Enterprise API Client.
79
- */
80
- export class ApiClient extends CommonApiClient {
81
- constructor(baseUrl: string) {
82
- super(baseUrl);
83
- }
84
-
85
- async getWithAuth(endpoint: string) {
86
- const token = 'YOUR_AUTH_TOKEN';
87
- return this.get(endpoint, {
88
- headers: { 'Authorization': \`Bearer \${token}\` }
89
- });
90
- }
91
-
92
- async postData(endpoint: string, data: any) {
93
- return this.post(endpoint, data);
94
- }
95
- }
96
- `;
97
- fs.writeFileSync(path.join(projectPath, 'src/core/api/ApiClient.ts'), apiClientTs);
98
-
99
- const authStrategyTs = `import { CookieAuth, AuthStrategy as CommonAuthStrategy } from '@sridharkikkeri/playwright-common';
100
-
101
- export class AuthStrategy extends CommonAuthStrategy {
102
- async login(credentials: any): Promise<void> {
103
- await this.page.goto('/login');
104
- await this.page.fill('#username', credentials.username);
105
- await this.page.fill('#password', credentials.password);
106
- await this.page.click('#login-btn');
107
- }
108
- }
109
- `;
110
- fs.writeFileSync(path.join(projectPath, 'src/core/api/auth/AuthStrategy.ts'), authStrategyTs);
111
-
112
- const configManagerTs = `import { ConfigManager as CommonConfigManager } from '@sridharkikkeri/playwright-common';
113
-
114
- export class ConfigManager extends CommonConfigManager {
115
- static getEnvironmentConfig() {
116
- return this.getConfig();
117
- }
118
-
119
- static isSelfHealingEnabled() {
120
- return this.getConfig().healingEnabled ?? true;
121
- }
122
- }
123
- `;
124
- fs.writeFileSync(path.join(projectPath, 'src/core/config/ConfigManager.ts'), configManagerTs);
125
-
126
- const localizationTs = `import { Localization as CommonLocalization } from '@sridharkikkeri/playwright-common';
127
-
128
- export class Localization extends CommonLocalization {
129
- static getTranslate(key: string) {
130
- return this.t(key);
131
- }
132
- }
133
- `;
134
- fs.writeFileSync(path.join(projectPath, 'src/core/i18n/Localization.ts'), localizationTs);
135
-
136
- const basePageTs = `import { Page } from '@playwright/test';
137
- import { BasePage as CommonBasePage, ActionOrchestrator } from '@sridharkikkeri/playwright-common';
138
-
139
- /**
140
- * Global Base Page for all project Page Objects.
141
- */
142
- export abstract class BasePage extends CommonBasePage {
143
- constructor(page: Page, options?: { pageName: string; orchestrator?: ActionOrchestrator }) {
144
- super(page, options);
145
- }
146
-
147
- async waitForLoadingFinished() {
148
- await this.page.waitForSelector('.loading-spinner', { state: 'hidden' });
149
- }
150
- }
151
- `;
152
- fs.writeFileSync(path.join(projectPath, 'src/core/pages/BasePage.ts'), basePageTs);
153
-
154
- const allureUtilTs = `import { AllureUtil as CommonAllureUtil } from '@sridharkikkeri/playwright-common';
155
-
156
- export class AllureUtil extends CommonAllureUtil {
157
- static async captureStep(name: string, body: () => Promise<void>) {
158
- await this.step(name, body);
159
- }
160
- }
161
- `;
162
- fs.writeFileSync(path.join(projectPath, 'src/core/reporting/AllureUtil.ts'), allureUtilTs);
163
-
164
- const locatorHealingTs = `import { LocatorHealing as CommonLocatorHealing } from '@sridharkikkeri/playwright-common';
165
-
166
- export class LocatorHealing extends CommonLocatorHealing {
167
- }
168
- `;
169
- fs.writeFileSync(path.join(projectPath, 'src/core/selfhealing/LocatorHealing.ts'), locatorHealingTs);
170
-
171
- const actionOrchestratorTs = `import { ActionOrchestrator as CommonActionOrchestrator } from '@sridharkikkeri/playwright-common';
172
-
173
- export class ActionOrchestrator extends CommonActionOrchestrator {
174
- }
175
- `;
176
- fs.writeFileSync(path.join(projectPath, 'src/core/selfhealing/ActionOrchestrator.ts'), actionOrchestratorTs);
177
-
178
- const visualTestingTs = `import { VisualTesting as CommonVisualTesting } from '@sridharkikkeri/playwright-common';
179
-
180
- export class VisualTesting extends CommonVisualTesting {
181
- }
182
- `;
183
- fs.writeFileSync(path.join(projectPath, 'src/core/visual/VisualTesting.ts'), visualTestingTs);
184
-
185
- const elementWrapperTs = `import { ElementWrapper as CommonElementWrapper } from '@sridharkikkeri/playwright-common';
186
-
187
- /**
188
- * Enterprise Element Wrapper.
189
- */
190
- export class ElementWrapper extends CommonElementWrapper {
191
- async clickAndLog(stepDescription?: string): Promise<void> {
192
- console.log(\`[AUTO-LOG] Clicking element: \${stepDescription || 'unknown'}\`);
193
- await this.click(stepDescription);
194
- }
195
- }
196
- `;
197
- fs.writeFileSync(path.join(projectPath, 'src/core/wrappers/ElementWrapper.ts'), elementWrapperTs);
198
-
199
- const loggerTs = `import { Logger as CommonLogger } from '@sridharkikkeri/playwright-common';
200
-
201
- export class Logger extends CommonLogger {
202
- }
203
- `;
204
- fs.writeFileSync(path.join(projectPath, 'src/core/utils/Logger.ts'), loggerTs);
205
-
206
- const errorUtilsTs = `import { ErrorUtils as CommonErrorUtils } from '@sridharkikkeri/playwright-common';
207
-
208
- export class ErrorUtils extends CommonErrorUtils {
209
- }
210
- `;
211
- fs.writeFileSync(path.join(projectPath, 'src/core/utils/ErrorUtils.ts'), errorUtilsTs);
212
-
213
- // --- UTILS & I18N POPULATION ---
214
- const stringUtilsTs = `export class StringUtils {
215
- static capitalize(str: string) { return str.charAt(0).toUpperCase() + str.slice(1); }
216
- }`;
217
- fs.writeFileSync(path.join(projectPath, 'src/utils/StringUtils.ts'), stringUtilsTs);
218
-
219
- const dateUtilsTs = `export class DateUtils {
220
- static now() { return new Date().toISOString(); }
221
- }`;
222
- fs.writeFileSync(path.join(projectPath, 'src/utils/DateUtils.ts'), dateUtilsTs);
223
-
224
- fs.writeFileSync(path.join(projectPath, 'src/i18n/en.json'), JSON.stringify({ "welcome": "Welcome to HealthEdge" }, null, 2));
225
- fs.writeFileSync(path.join(projectPath, 'src/i18n/fr.json'), JSON.stringify({ "welcome": "Bienvenue chez HealthEdge" }, null, 2));
226
-
227
- // --- DOCUMENTATION ---
228
- fs.writeFileSync(path.join(projectPath, 'api-docs/assets/style.css'), 'body { font-family: sans-serif; padding: 20px; }');
229
- const indexHtmlContent = `
230
- <html>
231
- <head>
232
- <title>${projectName} API Docs</title>
233
- <link rel="stylesheet" href="assets/style.css">
234
- </head>
235
- <body>
236
- <h1>${projectName} - Enterprise API Documentation</h1>
237
- <p>Welcome to the central documentation hub.</p>
238
- </body>
239
- </html>`;
240
- fs.writeFileSync(path.join(projectPath, 'api-docs/index.html'), indexHtmlContent);
241
-
242
- ['classes', 'interfaces', 'types', 'variables'].forEach(fold => {
243
- fs.writeFileSync(path.join(projectPath, `api-docs/${fold}/README.md`), `# ${fold.toUpperCase()}\nDocumentation for ${fold} in ${projectName}.`);
244
- });
245
-
246
- // --- STANDARD CONFIG & EXAMPLES ---
247
- const baseConfig = { healingEnabled: true, environment: 'dev', baseUrl: 'https://example.com', apiUrl: 'https://api.example.com', timeout: 30000, retries: 2 };
248
- const environments = ['dev', 'qa', 'auto', 'staging', 'prod'];
249
- environments.forEach(env => {
250
- const config = { ...baseConfig, environment: env, baseUrl: `https://${env}.example.com`, apiUrl: `https://api-${env}.example.com` };
251
- fs.writeFileSync(path.join(projectPath, `framework.config.${env}.json`), JSON.stringify(config, null, 2));
252
- });
100
+ // 4. Configuration Boilerplate
101
+ const baseConfig = { healingEnabled: true, environment: 'dev', baseUrl: 'https://example.com', apiUrl: 'https://api.example.com', timeout: 30000 };
253
102
  fs.writeFileSync(path.join(projectPath, 'framework.config.json'), JSON.stringify(baseConfig, null, 2));
254
103
 
255
104
  const playwrightConfig = `import { defineConfig } from '@playwright/test';
@@ -261,65 +110,6 @@ export default defineConfig({
261
110
  });`;
262
111
  fs.writeFileSync(path.join(projectPath, 'playwright.config.ts'), playwrightConfig);
263
112
 
264
- const fixturesTs = `import { test as base } from '@sridharkikkeri/playwright-common';
265
- import { HomePage } from '../pages/HomePage';
266
- import { LoginPage } from '../pages/LoginPage';
267
-
268
- export const test = base.extend<{ homePage: HomePage; loginPage: LoginPage }>({
269
- homePage: async ({ page, orchestrator }, use) => { await use(new HomePage(page, orchestrator)); },
270
- loginPage: async ({ page, orchestrator }, use) => { await use(new LoginPage(page, orchestrator)); },
271
- });
272
-
273
- export { expect } from '@playwright/test';`;
274
- fs.writeFileSync(path.join(projectPath, 'src/fixtures/fixtures.ts'), fixturesTs);
275
-
276
- const homePageTs = `import { Page } from '@playwright/test';
277
- import { BasePage } from '../core/pages/BasePage';
278
- import { ActionOrchestrator } from '../core/selfhealing/ActionOrchestrator';
279
-
280
- export class HomePage extends BasePage {
281
- constructor(page: Page, orchestrator?: ActionOrchestrator) {
282
- super(page, { pageName: 'HomePage', orchestrator });
283
- }
284
- private readonly searchBtn = this.element('button[type="submit"]');
285
- async clickSearch() { await this.searchBtn.click('Click Search Button'); }
286
- }
287
- `;
288
- fs.writeFileSync(path.join(projectPath, 'src/pages/HomePage.ts'), homePageTs);
289
-
290
- const loginPageTs = `import { Page } from '@playwright/test';
291
- import { BasePage } from '../core/pages/BasePage';
292
- import { ActionOrchestrator } from '../core/selfhealing/ActionOrchestrator';
293
-
294
- export class LoginPage extends BasePage {
295
- constructor(page: Page, orchestrator?: ActionOrchestrator) {
296
- super(page, { pageName: 'LoginPage', orchestrator });
297
- }
298
- }
299
- `;
300
- fs.writeFileSync(path.join(projectPath, 'src/pages/LoginPage.ts'), loginPageTs);
301
-
302
- const visualTest = `import { test, expect } from '../fixtures/fixtures';
303
-
304
- test.describe('Enterprise Visual Regression', () => {
305
- test('HP Visual Verification', async ({ page }) => {
306
- await page.goto('https://playwright.dev');
307
- await expect(page).toHaveScreenshot('homepage.png', {
308
- mask: [page.locator('.navbar')],
309
- threshold: 0.1
310
- });
311
- });
312
- });`;
313
- fs.writeFileSync(path.join(projectPath, 'src/tests/visual.spec.ts'), visualTest);
314
-
315
- const sampleTest = `import { test, expect } from '../fixtures/fixtures';
316
-
317
- test('Standard Smoke Test', async ({ page }) => {
318
- await page.goto('https://playwright.dev');
319
- await expect(page).toHaveTitle(/Playwright/);
320
- });`;
321
- fs.writeFileSync(path.join(projectPath, 'src/tests/sample.spec.ts'), sampleTest);
322
-
323
113
  const tsConfig = {
324
114
  compilerOptions: {
325
115
  target: 'ES2020', module: 'commonjs', lib: ['ES2020', 'DOM'],
@@ -329,35 +119,17 @@ const tsConfig = {
329
119
  };
330
120
  fs.writeFileSync(path.join(projectPath, 'tsconfig.json'), JSON.stringify(tsConfig, null, 2));
331
121
 
332
- const gitignore = `node_modules/
333
- allure-results/
334
- allure-report/
335
- test-results/
336
- playwright-report/
337
- .env
338
- *.log
339
- dist/
340
- `;
122
+ const gitignore = `node_modules/\nallure-results/\nallure-report/\n.env\n*.log\n`;
341
123
  fs.writeFileSync(path.join(projectPath, '.gitignore'), gitignore);
342
124
 
343
- const readme = `# ${projectName}
344
-
345
- ## Getting Started
346
- \`\`\`bash
347
- npm install
348
- npm run test:dev
349
- \`\`\`
350
- `;
351
- fs.writeFileSync(path.join(projectPath, 'README.md'), readme);
352
-
353
- console.log('āœ… Comprehensive Project Structure Created');
354
- console.log('\nšŸ“¦ Installing dependencies...\n');
125
+ console.log('\nāœ… Project structure created "as it is" from framework source.');
126
+ console.log('šŸ“¦ Installing dependencies...\n');
355
127
 
356
128
  try {
357
129
  execSync('npm install', { cwd: projectPath, stdio: 'inherit' });
358
130
  console.log('\nāœ… Dependencies installed');
359
131
  } catch (error) {
360
- console.log('\nāš ļø npm install failed. Please run manually.');
132
+ console.log('\nāš ļø npm install failed. Run manually.');
361
133
  }
362
134
 
363
- console.log(`\nšŸŽ‰ Project ready! cd ${projectName} and try: npm run test:dev\n`);
135
+ console.log(`\nšŸŽ‰ Project ready! cd ${projectName} and try: npm run test\n`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sridharkikkeri/playwright-common",
3
- "version": "1.0.19",
3
+ "version": "1.0.22",
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",
@@ -12,6 +12,7 @@
12
12
  },
13
13
  "files": [
14
14
  "dist",
15
+ "src",
15
16
  "create-healthedge-tests.js",
16
17
  "README.md",
17
18
  "HEALING_CACHE_STRATEGY.md",