@sridharkikkeri/playwright-common 1.0.17 → 1.0.18

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.
@@ -56,7 +56,7 @@ const packageJson = {
56
56
  'lint:fix': 'eslint . --fix'
57
57
  },
58
58
  dependencies: {
59
- '@sridharkikkeri/playwright-common': '^1.0.17',
59
+ '@sridharkikkeri/playwright-common': '^1.0.18',
60
60
  '@playwright/test': '^1.42.0',
61
61
  'allure-playwright': '^3.4.5'
62
62
  },
@@ -70,104 +70,173 @@ const packageJson = {
70
70
 
71
71
  fs.writeFileSync(path.join(projectPath, 'package.json'), JSON.stringify(packageJson, null, 2));
72
72
 
73
- // --- CORE EXTENSION BOILERPLATE ---
73
+ // --- ENHANCED CORE EXTENSION BOILERPLATE ---
74
74
 
75
- const baseApiClientTs = `import { ApiClient } from '@sridharkikkeri/playwright-common';
75
+ const apiClientTs = `import { ApiClient as CommonApiClient } from '@sridharkikkeri/playwright-common';
76
76
 
77
- export class BaseApiClient extends ApiClient {
77
+ /**
78
+ * Enterprise API Client.
79
+ * Use this class to add project-specific headers,
80
+ * authentication tokens, or shared response validation.
81
+ */
82
+ export class ApiClient extends CommonApiClient {
78
83
  constructor(baseUrl: string) {
79
84
  super(baseUrl);
80
85
  }
81
- // Add shared project-specific headers or logic here
86
+
87
+ async getWithAuth(endpoint: string) {
88
+ const token = 'YOUR_AUTH_TOKEN'; // Replace with real auth logic
89
+ return this.get(endpoint, {
90
+ headers: { 'Authorization': \`Bearer \${token}\` }
91
+ });
92
+ }
93
+
94
+ async postData(endpoint: string, data: any) {
95
+ return this.post(endpoint, data);
96
+ }
82
97
  }
83
98
  `;
84
- fs.writeFileSync(path.join(projectPath, 'src/core/api/BaseApiClient.ts'), baseApiClientTs);
99
+ fs.writeFileSync(path.join(projectPath, 'src/core/api/ApiClient.ts'), apiClientTs);
85
100
 
86
- const projectAuthTs = `import { CookieAuth, AuthStrategy } from '@sridharkikkeri/playwright-common';
101
+ const authStrategyTs = `import { CookieAuth, AuthStrategy as CommonAuthStrategy } from '@sridharkikkeri/playwright-common';
87
102
 
88
- export class ProjectAuth {
89
- static async setupSession(auth: AuthStrategy) {
90
- // Implement custom complex auth setup if needed
103
+ export class AuthStrategy extends CommonAuthStrategy {
104
+ async login(credentials: any): Promise<void> {
105
+ // Implement project-specific login logic here
106
+ await this.page.goto('/login');
107
+ await this.page.fill('#username', credentials.username);
108
+ await this.page.fill('#password', credentials.password);
109
+ await this.page.click('#login-btn');
91
110
  }
92
111
  }
93
112
  `;
94
- fs.writeFileSync(path.join(projectPath, 'src/core/api/auth/ProjectAuth.ts'), projectAuthTs);
113
+ fs.writeFileSync(path.join(projectPath, 'src/core/api/auth/AuthStrategy.ts'), authStrategyTs);
95
114
 
96
- const envConfigTs = `import { ConfigManager } from '@sridharkikkeri/playwright-common';
115
+ const configManagerTs = `import { ConfigManager as CommonConfigManager } from '@sridharkikkeri/playwright-common';
97
116
 
98
- export class ProjectConfig extends ConfigManager {
99
- static getClientName() { return 'HealthEdge'; }
117
+ export class ConfigManager extends CommonConfigManager {
118
+ static getEnvironmentConfig() {
119
+ return this.getConfig();
120
+ }
121
+
122
+ static isSelfHealingEnabled() {
123
+ return this.getConfig().healingEnabled ?? true;
124
+ }
100
125
  }
101
126
  `;
102
- fs.writeFileSync(path.join(projectPath, 'src/core/config/ProjectConfig.ts'), envConfigTs);
127
+ fs.writeFileSync(path.join(projectPath, 'src/core/config/ConfigManager.ts'), configManagerTs);
103
128
 
104
- const localizationTs = `import { Localization } from '@sridharkikkeri/playwright-common';
129
+ const localizationTs = `import { Localization as CommonLocalization } from '@sridharkikkeri/playwright-common';
105
130
 
106
- export class ProjectLocalization extends Localization {
107
- static getAvailableLocales() { return ['en', 'fr']; }
131
+ export class Localization extends CommonLocalization {
132
+ static getTranslate(key: string) {
133
+ return this.t(key);
134
+ }
108
135
  }
109
136
  `;
110
- fs.writeFileSync(path.join(projectPath, 'src/core/i18n/ProjectLocalization.ts'), localizationTs);
137
+ fs.writeFileSync(path.join(projectPath, 'src/core/i18n/Localization.ts'), localizationTs);
111
138
 
112
- const baseComponentTs = `import { Page } from '@playwright/test';
113
- import { BasePage, ActionOrchestrator } from '@sridharkikkeri/playwright-common';
139
+ const basePageTs = `import { Page } from '@playwright/test';
140
+ import { BasePage as CommonBasePage, ActionOrchestrator } from '@sridharkikkeri/playwright-common';
114
141
 
115
- export abstract class BaseComponent extends BasePage {
116
- constructor(page: Page, orchestrator?: ActionOrchestrator) {
117
- super(page, { pageName: 'BaseComponent', orchestrator });
142
+ /**
143
+ * Global Base Page for all project Page Objects.
144
+ */
145
+ export abstract class BasePage extends CommonBasePage {
146
+ constructor(page: Page, options?: { pageName: string; orchestrator?: ActionOrchestrator }) {
147
+ super(page, options);
148
+ }
149
+
150
+ async waitForLoadingFinished() {
151
+ await this.page.waitForSelector('.loading-spinner', { state: 'hidden' });
118
152
  }
119
153
  }
120
154
  `;
121
- fs.writeFileSync(path.join(projectPath, 'src/core/pages/BaseComponent.ts'), baseComponentTs);
155
+ fs.writeFileSync(path.join(projectPath, 'src/core/pages/BasePage.ts'), basePageTs);
122
156
 
123
- const reporterTs = `import { AllureUtil } from '@sridharkikkeri/playwright-common';
157
+ const allureUtilTs = `import { AllureUtil as CommonAllureUtil } from '@sridharkikkeri/playwright-common';
124
158
 
125
- export class ProjectReporter {
126
- static async logEnterpriseStep(name: string) {
127
- console.log(\`[ENTERPRISE] \${name}\`);
159
+ export class AllureUtil extends CommonAllureUtil {
160
+ static async captureStep(name: string, body: () => Promise<void>) {
161
+ await this.step(name, body);
128
162
  }
129
163
  }
130
164
  `;
131
- fs.writeFileSync(path.join(projectPath, 'src/core/reporting/ProjectReporter.ts'), reporterTs);
165
+ fs.writeFileSync(path.join(projectPath, 'src/core/reporting/AllureUtil.ts'), allureUtilTs);
166
+
167
+ const locatorHealingTs = `import { LocatorHealing as CommonLocatorHealing } from '@sridharkikkeri/playwright-common';
168
+
169
+ export class LocatorHealing extends CommonLocatorHealing {
170
+ // Add project-specific healing logic or custom heuristics here
171
+ }
172
+ `;
173
+ fs.writeFileSync(path.join(projectPath, 'src/core/selfhealing/LocatorHealing.ts'), locatorHealingTs);
132
174
 
133
- const healingTs = `import { LocatorHealing } from '@sridharkikkeri/playwright-common';
175
+ const actionOrchestratorTs = `import { ActionOrchestrator as CommonActionOrchestrator } from '@sridharkikkeri/playwright-common';
134
176
 
135
- export class ProjectHealer extends LocatorHealing {
136
- // Override framework healing logic here
177
+ export class ActionOrchestrator extends CommonActionOrchestrator {
178
+ // Extend orchestration logic here
137
179
  }
138
180
  `;
139
- fs.writeFileSync(path.join(projectPath, 'src/core/selfhealing/ProjectHealer.ts'), healingTs);
181
+ fs.writeFileSync(path.join(projectPath, 'src/core/selfhealing/ActionOrchestrator.ts'), actionOrchestratorTs);
182
+
183
+ const visualTestingTs = `import { VisualTesting as CommonVisualTesting } from '@sridharkikkeri/playwright-common';
140
184
 
141
- const visualTs = `import { VisualTesting } from '@sridharkikkeri/playwright-common';
185
+ export class VisualTesting extends CommonVisualTesting {
186
+ static async verifyFullPage(name: string) {
187
+ // Custom full page screenshot logic
188
+ }
189
+ }
190
+ `;
191
+ fs.writeFileSync(path.join(projectPath, 'src/core/visual/VisualTesting.ts'), visualTestingTs);
192
+
193
+ const elementWrapperTs = `import { ElementWrapper as CommonElementWrapper } from '@sridharkikkeri/playwright-common';
194
+
195
+ /**
196
+ * Enterprise Element Wrapper.
197
+ * Extend this class to add project-specific element interactions.
198
+ */
199
+ export class ElementWrapper extends CommonElementWrapper {
200
+ async clickAndLog(stepDescription?: string): Promise<void> {
201
+ console.log(\`[AUTO-LOG] Clicking element: \${stepDescription || 'unknown'}\`);
202
+ await this.click(stepDescription);
203
+ }
142
204
 
143
- export class ProjectVisuals extends VisualTesting {
144
- // Custom exclusions or thresholds
205
+ async forceFill(value: string, stepDescription?: string): Promise<void> {
206
+ await this.locator.fill(value, { force: true });
207
+ }
145
208
  }
146
209
  `;
147
- fs.writeFileSync(path.join(projectPath, 'src/core/visual/ProjectVisuals.ts'), visualTs);
210
+ fs.writeFileSync(path.join(projectPath, 'src/core/wrappers/ElementWrapper.ts'), elementWrapperTs);
148
211
 
149
- const wrapperTs = `import { ElementWrapper } from '@sridharkikkeri/playwright-common';
212
+ const loggerTs = `import { Logger as CommonLogger } from '@sridharkikkeri/playwright-common';
150
213
 
151
- export class ProjectElement extends ElementWrapper {
152
- // Extend element behaviors (e.g., custom scrolls)
214
+ export class Logger extends CommonLogger {
215
+ static info(message: string) {
216
+ console.log(\`[INFO] \${message}\`);
217
+ }
153
218
  }
154
219
  `;
155
- fs.writeFileSync(path.join(projectPath, 'src/core/wrappers/ProjectElement.ts'), wrapperTs);
220
+ fs.writeFileSync(path.join(projectPath, 'src/core/utils/Logger.ts'), loggerTs);
221
+
222
+ const errorUtilsTs = `import { ErrorUtils as CommonErrorUtils } from '@sridharkikkeri/playwright-common';
156
223
 
157
- const projectUtilsTs = `export class ProjectUtils {
158
- static generateRandomID() { return Math.random().toString(36).substring(7); }
224
+ export class ErrorUtils extends CommonErrorUtils {
225
+ // Project-specific error handling
159
226
  }
160
227
  `;
161
- fs.writeFileSync(path.join(projectPath, 'src/core/utils/ProjectUtils.ts'), projectUtilsTs);
228
+ fs.writeFileSync(path.join(projectPath, 'src/core/utils/ErrorUtils.ts'), errorUtilsTs);
162
229
 
163
230
  // --- UTILS & I18N POPULATION ---
164
231
  const stringUtilsTs = `export class StringUtils {
165
232
  static capitalize(str: string) { return str.charAt(0).toUpperCase() + str.slice(1); }
233
+ static mask(str: string) { return str.replace(/./g, '*'); }
166
234
  }`;
167
235
  fs.writeFileSync(path.join(projectPath, 'src/utils/StringUtils.ts'), stringUtilsTs);
168
236
 
169
237
  const dateUtilsTs = `export class DateUtils {
170
238
  static now() { return new Date().toISOString(); }
239
+ static format(date: Date) { return date.toLocaleDateString(); }
171
240
  }`;
172
241
  fs.writeFileSync(path.join(projectPath, 'src/utils/DateUtils.ts'), dateUtilsTs);
173
242
 
@@ -175,51 +244,61 @@ fs.writeFileSync(path.join(projectPath, 'src/i18n/en.json'), JSON.stringify({ "w
175
244
  fs.writeFileSync(path.join(projectPath, 'src/i18n/fr.json'), JSON.stringify({ "welcome": "Bienvenue chez HealthEdge" }, null, 2));
176
245
 
177
246
  // --- 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'), `
247
+ fs.writeFileSync(path.join(projectPath, 'api-docs/assets/style.css'), 'body { font-family: sans-serif; padding: 20px; line-height: 1.6; }');
248
+ fs.writeFileSync(path.join(projectPath, 'api-docs/index.html'), \`
180
249
  <html>
181
- <head><link rel="stylesheet" href="assets/style.css"></head>
250
+ <head>
251
+ <title>\${projectName} API Docs</title>
252
+ <link rel="stylesheet" href="assets/style.css">
253
+ </head>
182
254
  <body>
183
- <h1>${projectName} - API Documentation</h1>
184
- <p>This folder is ready to host your TypeDoc or custom API documentation.</p>
255
+ <h1>\${projectName} - Enterprise API Documentation</h1>
256
+ <p>Welcome to the central documentation hub for your Playwright testing project.</p>
257
+ <ul>
258
+ <li><a href="classes/README.md">Class References</a></li>
259
+ <li><a href="interfaces/README.md">Interfaces</a></li>
260
+ </ul>
185
261
  </body>
186
- </html>`);
262
+ </html>\`);
263
+
187
264
  ['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.`);
265
+ fs.writeFileSync(path.join(projectPath, \`api-docs/\${fold}/README.md\`), \`# \${fold.toUpperCase()}\\nDetailed documentation for \${fold} in project \${projectName}.\`);
189
266
  });
190
267
 
191
268
  // --- STANDARD CONFIG & EXAMPLES ---
192
269
  const baseConfig = { healingEnabled: true, environment: 'dev', baseUrl: 'https://example.com', apiUrl: 'https://api.example.com', timeout: 30000, retries: 2 };
193
270
  const environments = ['dev', 'qa', 'auto', 'staging', 'prod'];
194
271
  environments.forEach(env => {
195
- const config = { ...baseConfig, environment: env, baseUrl: `https://${env}.example.com`, apiUrl: `https://api-${env}.example.com` };
196
- fs.writeFileSync(path.join(projectPath, `framework.config.${env}.json`), JSON.stringify(config, null, 2));
272
+ const config = { ...baseConfig, environment: env, baseUrl: \`https://\${env}.example.com\`, apiUrl: \`https://api-\${env}.example.com\` };
273
+ fs.writeFileSync(path.join(projectPath, \`framework.config.\${env}.json\`), JSON.stringify(config, null, 2));
197
274
  });
198
275
  fs.writeFileSync(path.join(projectPath, 'framework.config.json'), JSON.stringify(baseConfig, null, 2));
199
276
 
200
- const playwrightConfig = `import { defineConfig } from '@playwright/test';
277
+ const playwrightConfig = \`import { defineConfig } from '@playwright/test';
201
278
  export default defineConfig({
202
279
  testDir: './src/tests',
203
280
  timeout: 30000,
281
+ retries: process.env.CI ? 2 : 0,
204
282
  reporter: [['html'], ['allure-playwright', { outputFolder: 'allure-results' }]],
205
283
  use: { trace: 'on-first-retry', screenshot: 'only-on-failure' }
206
- });`;
284
+ });\`;
207
285
  fs.writeFileSync(path.join(projectPath, 'playwright.config.ts'), playwrightConfig);
208
286
 
209
- const fixturesTs = `import { test as base } from '@sridharkikkeri/playwright-common';
287
+ const fixturesTs = \`import { test as base } from '@sridharkikkeri/playwright-common';
210
288
  import { HomePage } from '../pages/HomePage';
289
+ import { LoginPage } from '../pages/LoginPage';
211
290
 
212
- export const test = base.extend<{ homePage: HomePage }>({
213
- homePage: async ({ page, orchestrator }, use) => {
214
- await use(new HomePage(page, orchestrator));
215
- },
291
+ export const test = base.extend<{ homePage: HomePage; loginPage: LoginPage }>({
292
+ homePage: async ({ page, orchestrator }, use) => { await use(new HomePage(page, orchestrator)); },
293
+ loginPage: async ({ page, orchestrator }, use) => { await use(new LoginPage(page, orchestrator)); },
216
294
  });
217
295
 
218
- export { expect } from '@playwright/test';`;
296
+ export { expect } from '@playwright/test';\`;
219
297
  fs.writeFileSync(path.join(projectPath, 'src/fixtures/fixtures.ts'), fixturesTs);
220
298
 
221
- const samplePage = `import { Page } from '@playwright/test';
222
- import { BasePage, ActionOrchestrator } from '@sridharkikkeri/playwright-common';
299
+ const homePageTs = \`import { Page } from '@playwright/test';
300
+ import { BasePage } from '../core/pages/BasePage';
301
+ import { ActionOrchestrator } from '../core/selfhealing/ActionOrchestrator';
223
302
 
224
303
  export class HomePage extends BasePage {
225
304
  constructor(page: Page, orchestrator?: ActionOrchestrator) {
@@ -228,10 +307,31 @@ export class HomePage extends BasePage {
228
307
  private readonly searchBtn = this.element('button[type="submit"]');
229
308
  async clickSearch() { await this.searchBtn.click('Click Search Button'); }
230
309
  }
231
- `;
232
- fs.writeFileSync(path.join(projectPath, 'src/pages/HomePage.ts'), samplePage);
310
+ \`;
311
+ fs.writeFileSync(path.join(projectPath, 'src/pages/HomePage.ts'), homePageTs);
233
312
 
234
- const visualTest = `import { test, expect } from '../fixtures/fixtures';
313
+ const loginPageTs = \`import { Page } from '@playwright/test';
314
+ import { BasePage } from '../core/pages/BasePage';
315
+ import { ActionOrchestrator } from '../core/selfhealing/ActionOrchestrator';
316
+
317
+ export class LoginPage extends BasePage {
318
+ constructor(page: Page, orchestrator?: ActionOrchestrator) {
319
+ super(page, { pageName: 'LoginPage', orchestrator });
320
+ }
321
+ private readonly userField = this.element('#user');
322
+ private readonly passField = this.element('#pass');
323
+ private readonly loginBtn = this.element('#login');
324
+
325
+ async login(u: string, p: string) {
326
+ await this.userField.fill(u, 'Enter username');
327
+ await this.passField.fill(p, 'Enter password');
328
+ await this.loginBtn.click('Click Login');
329
+ }
330
+ }
331
+ \`;
332
+ fs.writeFileSync(path.join(projectPath, 'src/pages/LoginPage.ts'), loginPageTs);
333
+
334
+ const visualTest = \`import { test, expect } from '../fixtures/fixtures';
235
335
 
236
336
  test.describe('Enterprise Visual Regression', () => {
237
337
  test('HP Visual Verification', async ({ page }) => {
@@ -241,32 +341,27 @@ test.describe('Enterprise Visual Regression', () => {
241
341
  threshold: 0.1
242
342
  });
243
343
  });
244
- });`;
344
+ });\`;
245
345
  fs.writeFileSync(path.join(projectPath, 'src/tests/visual.spec.ts'), visualTest);
246
346
 
247
- const sampleTest = `import { test, expect } from '../fixtures/fixtures';
347
+ const sampleTest = \`import { test, expect } from '../fixtures/fixtures';
248
348
 
249
- test('Standard Smoke Test', async ({ page }) => {
349
+ test('Standard Smoke Test', async ({ page, loginPage }) => {
250
350
  await page.goto('https://playwright.dev');
251
351
  await expect(page).toHaveTitle(/Playwright/);
252
- });`;
352
+ });\`;
253
353
  fs.writeFileSync(path.join(projectPath, 'src/tests/sample.spec.ts'), sampleTest);
254
354
 
255
- const tsConfig = {
256
- compilerOptions: {
257
- target: 'ES2020',
258
- module: 'commonjs',
259
- lib: ['ES2020'],
260
- strict: true,
261
- esModuleInterop: true,
262
- skipLibCheck: true,
263
- resolveJsonModule: true
264
- },
265
- include: ['src/**/*']
355
+ const tsConfig = {
356
+ compilerOptions: {
357
+ target: 'ES2020', module: 'commonjs', lib: ['ES2020', 'DOM'],
358
+ strict: true, esModuleInterop: true, skipLibCheck: true, resolveJsonModule: true
359
+ },
360
+ include: ['src/**/*']
266
361
  };
267
362
  fs.writeFileSync(path.join(projectPath, 'tsconfig.json'), JSON.stringify(tsConfig, null, 2));
268
363
 
269
- const gitignore = `node_modules/
364
+ const gitignore = \`node_modules/
270
365
  allure-results/
271
366
  allure-report/
272
367
  test-results/
@@ -274,35 +369,35 @@ playwright-report/
274
369
  .env
275
370
  *.log
276
371
  dist/
277
- `;
372
+ \`;
278
373
  fs.writeFileSync(path.join(projectPath, '.gitignore'), gitignore);
279
374
 
280
- const readme = `# ${projectName}
375
+ const readme = \`# \${projectName}
281
376
 
282
377
  ## Overview
283
378
  Enterprise automation test project powered by **@sridharkikkeri/playwright-common**.
284
379
 
285
380
  ## Getting Started
286
- \`\`\`bash
381
+ \\\`\\\`\\\`bash
287
382
  npm install
288
383
  npm run test:dev
289
- \`\`\`
384
+ \\\`\\\`\\\`
290
385
 
291
386
  ## Features
292
- - **Self-Healing**: Enabled by default
293
- - **Visual Regression**: \`npm run test:visual\`
294
- - **Enterprise Reporting**: Allure integration
295
- `;
387
+ - **Self-Healing**: Powered by AI Action Orchestrator
388
+ - **Visual Regression**: Built-in screenshot comparison
389
+ - **Enterprise Reporting**: Allure reporting with custom steps
390
+ \`;
296
391
  fs.writeFileSync(path.join(projectPath, 'README.md'), readme);
297
392
 
298
393
  console.log('āœ… Comprehensive Project Structure Created');
299
- console.log('\nšŸ“¦ Installing dependencies...\n');
394
+ console.log('\\nšŸ“¦ Installing dependencies...\\n');
300
395
 
301
396
  try {
302
397
  execSync('npm install', { cwd: projectPath, stdio: 'inherit' });
303
- console.log('\nāœ… Dependencies installed');
398
+ console.log('\\nāœ… Dependencies installed');
304
399
  } catch (error) {
305
- console.log('\nāš ļø npm install failed. Please run manually.');
400
+ console.log('\\nāš ļø npm install failed. Please run manually.');
306
401
  }
307
402
 
308
- console.log(`\nšŸŽ‰ Project ready! cd ${projectName} and try: npm run test:dev\n`);
403
+ 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.17",
3
+ "version": "1.0.18",
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",