@sridharkikkeri/playwright-common 1.0.11 ā 1.0.13
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 +87 -160
- package/package.json +1 -1
|
@@ -55,7 +55,7 @@ const packageJson = {
|
|
|
55
55
|
'lint:fix': 'eslint . --fix'
|
|
56
56
|
},
|
|
57
57
|
dependencies: {
|
|
58
|
-
'@sridharkikkeri/playwright-common': '^1.0.
|
|
58
|
+
'@sridharkikkeri/playwright-common': '^1.0.13',
|
|
59
59
|
'@playwright/test': '^1.42.0',
|
|
60
60
|
'allure-playwright': '^3.4.5'
|
|
61
61
|
},
|
|
@@ -67,193 +67,120 @@ const packageJson = {
|
|
|
67
67
|
}
|
|
68
68
|
};
|
|
69
69
|
|
|
70
|
-
fs.writeFileSync(
|
|
71
|
-
path.join(projectPath, 'package.json'),
|
|
72
|
-
JSON.stringify(packageJson, null, 2)
|
|
73
|
-
);
|
|
70
|
+
fs.writeFileSync(path.join(projectPath, 'package.json'), JSON.stringify(packageJson, null, 2));
|
|
74
71
|
|
|
75
|
-
//
|
|
76
|
-
const baseConfig = {
|
|
77
|
-
healingEnabled: true,
|
|
78
|
-
environment: 'dev',
|
|
79
|
-
baseUrl: 'https://example.com',
|
|
80
|
-
apiUrl: 'https://api.example.com',
|
|
81
|
-
timeout: 30000,
|
|
82
|
-
retries: 2
|
|
83
|
-
};
|
|
72
|
+
// --- CORE BOILERPLATE FILES ---
|
|
84
73
|
|
|
85
|
-
|
|
74
|
+
// src/core/api/BaseApiClient.ts
|
|
75
|
+
const baseApiClientTs = `import { ApiClient } from '@sridharkikkeri/playwright-common';
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Project-specific Base API Client.
|
|
79
|
+
* Extend this to add custom headers or shared error handling for your app.
|
|
80
|
+
*/
|
|
81
|
+
export class BaseApiClient extends ApiClient {
|
|
82
|
+
constructor(baseUrl: string) {
|
|
83
|
+
super(baseUrl);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
`;
|
|
87
|
+
fs.writeFileSync(path.join(projectPath, 'src/core/api/BaseApiClient.ts'), baseApiClientTs);
|
|
88
|
+
|
|
89
|
+
// src/core/pages/BaseComponent.ts
|
|
90
|
+
const baseComponentTs = `import { Page } from '@playwright/test';
|
|
91
|
+
import { BasePage, ActionOrchestrator } from '@sridharkikkeri/playwright-common';
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Base Component for project-specific reusable UI elements (e.g., Modals, Navbars).
|
|
95
|
+
*/
|
|
96
|
+
export abstract class BaseComponent extends BasePage {
|
|
97
|
+
constructor(page: Page, orchestrator?: ActionOrchestrator) {
|
|
98
|
+
super(page, { pageName: 'BaseComponent', orchestrator });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
`;
|
|
102
|
+
fs.writeFileSync(path.join(projectPath, 'src/core/pages/BaseComponent.ts'), baseComponentTs);
|
|
103
|
+
|
|
104
|
+
// src/core/utils/ProjectUtils.ts
|
|
105
|
+
const projectUtilsTs = `/**
|
|
106
|
+
* Shared utility functions for this specific test project.
|
|
107
|
+
*/
|
|
108
|
+
export class ProjectUtils {
|
|
109
|
+
static async sleep(ms: number) {
|
|
110
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
`;
|
|
114
|
+
fs.writeFileSync(path.join(projectPath, 'src/core/utils/ProjectUtils.ts'), projectUtilsTs);
|
|
86
115
|
|
|
116
|
+
// --- CONFIGURATION ---
|
|
117
|
+
const baseConfig = { healingEnabled: true, environment: 'dev', baseUrl: 'https://example.com', apiUrl: 'https://api.example.com', timeout: 30000, retries: 2 };
|
|
118
|
+
const environments = ['dev', 'qa', 'auto', 'staging', 'prod'];
|
|
87
119
|
environments.forEach(env => {
|
|
88
120
|
const config = { ...baseConfig, environment: env, baseUrl: `https://${env}.example.com`, apiUrl: `https://api-${env}.example.com` };
|
|
89
|
-
fs.writeFileSync(
|
|
90
|
-
path.join(projectPath, `framework.config.${env}.json`),
|
|
91
|
-
JSON.stringify(config, null, 2)
|
|
92
|
-
);
|
|
121
|
+
fs.writeFileSync(path.join(projectPath, `framework.config.${env}.json`), JSON.stringify(config, null, 2));
|
|
93
122
|
});
|
|
94
|
-
|
|
95
|
-
// Also create the default framework.config.json
|
|
96
|
-
fs.writeFileSync(
|
|
97
|
-
path.join(projectPath, 'framework.config.json'),
|
|
98
|
-
JSON.stringify(baseConfig, null, 2)
|
|
99
|
-
);
|
|
123
|
+
fs.writeFileSync(path.join(projectPath, 'framework.config.json'), JSON.stringify(baseConfig, null, 2));
|
|
100
124
|
|
|
101
125
|
// playwright.config.ts
|
|
102
126
|
const playwrightConfig = `import { defineConfig } from '@playwright/test';
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
['allure-playwright', { outputFolder: 'allure-results' }]
|
|
112
|
-
],
|
|
113
|
-
use: {
|
|
114
|
-
trace: 'on-first-retry',
|
|
115
|
-
screenshot: 'only-on-failure',
|
|
116
|
-
},
|
|
117
|
-
});
|
|
118
|
-
`;
|
|
119
|
-
|
|
127
|
+
export default defineConfig({
|
|
128
|
+
testDir: './src/tests',
|
|
129
|
+
timeout: 30000,
|
|
130
|
+
retries: process.env.CI ? 2 : 0,
|
|
131
|
+
workers: process.env.CI ? 1 : undefined,
|
|
132
|
+
reporter: [['html'], ['allure-playwright', { outputFolder: 'allure-results' }]],
|
|
133
|
+
use: { trace: 'on-first-retry', screenshot: 'only-on-failure' }
|
|
134
|
+
}); `;
|
|
120
135
|
fs.writeFileSync(path.join(projectPath, 'playwright.config.ts'), playwrightConfig);
|
|
121
136
|
|
|
122
|
-
//
|
|
137
|
+
// src/fixtures/fixtures.ts
|
|
123
138
|
const fixturesTs = `import { test as base } from '@sridharkikkeri/playwright-common';
|
|
124
|
-
import { HomePage } from '../pages/HomePage';
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
*/
|
|
130
|
-
export const test = base.extend<{
|
|
131
|
-
homePage: HomePage;
|
|
132
|
-
}>({
|
|
133
|
-
homePage: async ({ page, orchestrator }, use) => {
|
|
134
|
-
await use(new HomePage(page, orchestrator));
|
|
135
|
-
},
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
export { expect } from '@playwright/test';
|
|
139
|
-
`;
|
|
140
|
-
|
|
139
|
+
import { HomePage } from '../pages/HomePage';
|
|
140
|
+
export const test = base.extend < { homePage: HomePage } > ({
|
|
141
|
+
homePage: async ({ page, orchestrator }, use) => { await use(new HomePage(page, orchestrator)); },
|
|
142
|
+
});
|
|
143
|
+
export { expect } from '@playwright/test'; `;
|
|
141
144
|
fs.writeFileSync(path.join(projectPath, 'src/fixtures/fixtures.ts'), fixturesTs);
|
|
142
145
|
|
|
143
146
|
// Sample Page Object
|
|
144
147
|
const samplePage = `import { Page } from '@playwright/test';
|
|
145
|
-
import { BasePage, ActionOrchestrator } from '@sridharkikkeri/playwright-common';
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
148
|
+
import { BasePage, ActionOrchestrator } from '@sridharkikkeri/playwright-common';
|
|
149
|
+
export class HomePage extends BasePage {
|
|
150
|
+
constructor(page: Page, orchestrator?: ActionOrchestrator) { super(page, { pageName: 'HomePage', orchestrator }); }
|
|
151
|
+
private readonly searchInput = this.element('[data-testid="search"]');
|
|
152
|
+
private readonly searchBtn = this.element('button[type="submit"]');
|
|
153
|
+
async search(query: string) {
|
|
154
|
+
await this.searchInput.fill(query, 'Enter search query');
|
|
155
|
+
await this.searchBtn.click('Click search button');
|
|
156
|
+
}
|
|
150
157
|
}
|
|
151
|
-
|
|
152
|
-
private readonly searchInput = this.element('[data-testid="search"]');
|
|
153
|
-
private readonly searchBtn = this.element('button[type="submit"]');
|
|
154
|
-
|
|
155
|
-
async search(query: string) {
|
|
156
|
-
await this.searchInput.fill(query, 'Enter search query');
|
|
157
|
-
await this.searchBtn.click('Click search button');
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
`;
|
|
161
|
-
|
|
158
|
+
`;
|
|
162
159
|
fs.writeFileSync(path.join(projectPath, 'src/pages/HomePage.ts'), samplePage);
|
|
163
160
|
|
|
164
161
|
// Sample Test
|
|
165
162
|
const sampleTest = `import { test, expect } from '../fixtures/fixtures';
|
|
166
|
-
|
|
167
|
-
test
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
await expect(page).toHaveTitle(/Playwright/);
|
|
175
|
-
});
|
|
176
|
-
});
|
|
177
|
-
`;
|
|
178
|
-
|
|
163
|
+
test.describe('HealthEdge Framework Demo', () => {
|
|
164
|
+
test('Search functionality with Fixtures', async ({ page, homePage }) => {
|
|
165
|
+
await page.goto('https://playwright.dev');
|
|
166
|
+
await homePage.search('playwright');
|
|
167
|
+
await expect(page).toHaveTitle(/Playwright/);
|
|
168
|
+
});
|
|
169
|
+
}); `;
|
|
179
170
|
fs.writeFileSync(path.join(projectPath, 'src/tests/sample.spec.ts'), sampleTest);
|
|
180
171
|
|
|
181
|
-
|
|
182
|
-
const sampleI18n = {
|
|
183
|
-
"login_welcome": "Welcome to HealthEdge"
|
|
184
|
-
};
|
|
172
|
+
const sampleI18n = { "login_welcome": "Welcome to HealthEdge" };
|
|
185
173
|
fs.writeFileSync(path.join(projectPath, 'src/i18n/en.json'), JSON.stringify(sampleI18n, null, 2));
|
|
186
174
|
|
|
187
|
-
// tsconfig.json
|
|
188
175
|
const tsConfig = {
|
|
189
|
-
compilerOptions: {
|
|
190
|
-
target: 'ES2020',
|
|
191
|
-
module: 'commonjs',
|
|
192
|
-
lib: ['ES2020'],
|
|
193
|
-
strict: true,
|
|
194
|
-
esModuleInterop: true,
|
|
195
|
-
skipLibCheck: true,
|
|
196
|
-
forceConsistentCasingInFileNames: true,
|
|
197
|
-
resolveJsonModule: true
|
|
198
|
-
},
|
|
176
|
+
compilerOptions: { target: 'ES2020', module: 'commonjs', lib: ['ES2020'], strict: true, esModuleInterop: true, skipLibCheck: true, forceConsistentCasingInFileNames: true, resolveJsonModule: true },
|
|
199
177
|
include: ['src/**/*']
|
|
200
178
|
};
|
|
179
|
+
fs.writeFileSync(path.join(projectPath, 'tsconfig.json'), JSON.stringify(tsConfig, null, 2));
|
|
201
180
|
|
|
202
|
-
|
|
203
|
-
path.join(projectPath, 'tsconfig.json'),
|
|
204
|
-
JSON.stringify(tsConfig, null, 2)
|
|
205
|
-
);
|
|
206
|
-
|
|
207
|
-
// .gitignore
|
|
208
|
-
const gitignore = `node_modules/
|
|
209
|
-
allure-results/
|
|
210
|
-
allure-report/
|
|
211
|
-
test-results/
|
|
212
|
-
playwright-report/
|
|
213
|
-
.env
|
|
214
|
-
*.log
|
|
215
|
-
`;
|
|
216
|
-
|
|
181
|
+
const gitignore = `node_modules /\nallure - results /\nallure - report /\ntest - results /\nplaywright - report /\n.env\n *.log\n`;
|
|
217
182
|
fs.writeFileSync(path.join(projectPath, '.gitignore'), gitignore);
|
|
218
183
|
|
|
219
|
-
// README
|
|
220
|
-
const readme = `# ${projectName}
|
|
221
|
-
|
|
222
|
-
Generated with \`npx create-healthedge-tests\`
|
|
223
|
-
|
|
224
|
-
## Quick Start
|
|
225
|
-
|
|
226
|
-
\`\`\`bash
|
|
227
|
-
npm install
|
|
228
|
-
npm run test:dev
|
|
229
|
-
npm run report
|
|
230
|
-
\`\`\`
|
|
231
|
-
|
|
232
|
-
## Key Concepts
|
|
233
|
-
|
|
234
|
-
### Fixtures
|
|
235
|
-
This project uses an extended \`test\` object defined in \`src/fixtures/fixtures.ts\`.
|
|
236
|
-
Instead of importing from \`@playwright/test\`, always import from your local fixtures:
|
|
237
|
-
|
|
238
|
-
\`\`\`typescript
|
|
239
|
-
import { test } from '../fixtures/fixtures';
|
|
240
|
-
\`\`\`
|
|
241
|
-
|
|
242
|
-
### Page Objects
|
|
243
|
-
Add your pages to \`src/pages\` and register them in \`src/fixtures/fixtures.ts\`.
|
|
244
|
-
|
|
245
|
-
## Environment-Specific Tests
|
|
246
|
-
|
|
247
|
-
\`\`\`bash
|
|
248
|
-
npm run test:dev # Uses framework.config.dev.json
|
|
249
|
-
npm run test:qa # Uses framework.config.qa.json
|
|
250
|
-
npm run test:staging # Uses framework.config.staging.json
|
|
251
|
-
npm run test:prod # Uses framework.config.prod.json
|
|
252
|
-
\`\`\`
|
|
253
|
-
`;
|
|
254
|
-
|
|
255
|
-
fs.writeFileSync(path.join(projectPath, 'README.md'), readme);
|
|
256
|
-
|
|
257
184
|
console.log('ā
Project structure created');
|
|
258
185
|
console.log('\nš¦ Installing dependencies...\n');
|
|
259
186
|
|
|
@@ -264,6 +191,6 @@ try {
|
|
|
264
191
|
console.log('\nā ļø Run "npm install" manually in the project directory');
|
|
265
192
|
}
|
|
266
193
|
|
|
267
|
-
console.log(`\nš Project ready! Next steps
|
|
268
|
-
console.log(` cd
|
|
269
|
-
console.log(` npm run test:dev\n`);
|
|
194
|
+
console.log(`\nš Project ready! Next steps: \n`);
|
|
195
|
+
console.log(` cd \${ projectName } `);
|
|
196
|
+
console.log(` 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.13",
|
|
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",
|