cypress_task 1.0.0

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.
Files changed (80) hide show
  1. package/.github/workflows/cyemial.yaml +98 -0
  2. package/Daily_Tracker.xlsx +0 -0
  3. package/Mannual_testcases.xlsx +0 -0
  4. package/clean_mochawesome.js +26 -0
  5. package/cleanupOutput.js +16 -0
  6. package/cleanupReports.js +15 -0
  7. package/cypress/e2e/Cart_Testcases/07_verify_Adding_single_item_to_cart.cy.js +40 -0
  8. package/cypress/e2e/Cart_Testcases/08_verify_removing_item_from_the_cart.cy.js +55 -0
  9. package/cypress/e2e/Cart_Testcases/09_verify_updating_of_cart_after_adding_multiple_item.cy.js +75 -0
  10. package/cypress/e2e/Checkout_Testcases/04_verify_complete_successful_purchase_of_single_item.cy.js +83 -0
  11. package/cypress/e2e/Checkout_Testcases/05_verify_checkout_with_missing_firstname_fails.cy.js +78 -0
  12. package/cypress/e2e/Checkout_Testcases/06_verify_user_can_cancel_checkout_and redirected_to_cart.cy.js +79 -0
  13. package/cypress/e2e/Login_Testcases/01_Verify_Valid_Login.cy.js +30 -0
  14. package/cypress/e2e/Login_Testcases/02_Verify_Invalid_Login_by_wrong_password.cy.js +29 -0
  15. package/cypress/e2e/Login_Testcases/03_Verify_Lockout_user_failed_login.cy.js +30 -0
  16. package/cypress/e2e/Regression_Suit/10_Verify_successful_purchase_multiple_items.cy.js +98 -0
  17. package/cypress/e2e/Regression_Suit/11_testfail.cy.js +98 -0
  18. package/cypress/e2e/Smoke_Suit/SMK001_Verify user can log in with valid credentials.cy.js +32 -0
  19. package/cypress/e2e/Smoke_Suit/SMK002_Verify product list loads after login.cy.js +34 -0
  20. package/cypress/e2e/Smoke_Suit/SMK003_Verify user can add a product to cart.cy.js +49 -0
  21. package/cypress/failed-specs.json +3 -0
  22. package/cypress/fixtures/Cart/01_Adding_product_to_cart.json +6 -0
  23. package/cypress/fixtures/Cart/02_Removing_product_from_cart.json +6 -0
  24. package/cypress/fixtures/Cart/03_Updating_of_cart_icon.json +7 -0
  25. package/cypress/fixtures/Checkout/01_purchase_of_single_product.json +10 -0
  26. package/cypress/fixtures/Checkout/02_missing_info_fail_purchase.json +8 -0
  27. package/cypress/fixtures/Checkout/03_cancel_purcahse_redirect_to_cart.json +9 -0
  28. package/cypress/fixtures/Login_Data/01_Valid_login.json +5 -0
  29. package/cypress/fixtures/Login_Data/02_Invalid_Login.json +6 -0
  30. package/cypress/fixtures/Login_Data/03_Lockout_user.json +6 -0
  31. package/cypress/fixtures/regression_data/01_regression_data.json +12 -0
  32. package/cypress/fixtures/smoke_test_data/SMK001_Verify user can log in with valid credentials.json +5 -0
  33. package/cypress/fixtures/smoke_test_data/SMK002_Verify product list loads after login.json +6 -0
  34. package/cypress/fixtures/smoke_test_data/SMK003_Verify user can add a product to cart.json +6 -0
  35. package/cypress/results/fail_2025-12-19T160847+0530-11_testfail.json +110 -0
  36. package/cypress/results/fail_2025-12-19T160936+0530-11_testfail.json +110 -0
  37. package/cypress/results/pass_2025-12-19T160750+0530-04_verify_complete_successful_purchase_of_single_item.json +106 -0
  38. package/cypress/results/pass_2025-12-19T160756+0530-05_verify_checkout_with_missing_firstname_fails.json +106 -0
  39. package/cypress/results/pass_2025-12-19T160802+0530-06_verify_user_can_cancel_checkout_and redirected_to_cart.json +106 -0
  40. package/cypress/results/pass_2025-12-19T160806+0530-07_verify_Adding_single_item_to_cart.json +106 -0
  41. package/cypress/results/pass_2025-12-19T160809+0530-08_verify_removing_item_from_the_cart.json +106 -0
  42. package/cypress/results/pass_2025-12-19T160814+0530-09_verify_updating_of_cart_after_adding_multiple_item.json +106 -0
  43. package/cypress/results/pass_2025-12-19T160822+0530-10_Verify_successful_purchase_multiple_items.json +106 -0
  44. package/cypress/results/pass_2025-12-19T160850+0530-SMK001_Verify user can log in with valid credentials.json +106 -0
  45. package/cypress/results/pass_2025-12-19T160854+0530-SMK002_Verify product list loads after login.json +106 -0
  46. package/cypress/results/pass_2025-12-19T160857+0530-SMK003_Verify user can add a product to cart.json +106 -0
  47. package/cypress/results/pass_2025-12-19T160900+0530-01_Verify_Valid_Login.json +106 -0
  48. package/cypress/results/pass_2025-12-19T160903+0530-02_Verify_Invalid_Login_by_wrong_password.json +106 -0
  49. package/cypress/results/pass_2025-12-19T160905+0530-03_Verify_Lockout_user_failed_login.json +106 -0
  50. package/cypress/screenshots/11_testfail.cy.js/11_failed -- 02_failed (failed) (attempt 2).png +0 -0
  51. package/cypress/screenshots/11_testfail.cy.js/11_failed -- 02_failed (failed).png +0 -0
  52. package/cypress/support/Locators/Common_Locators.js +57 -0
  53. package/cypress/support/commands.js +25 -0
  54. package/cypress/support/e2e.js +43 -0
  55. package/cypress/support/encryption.js +45 -0
  56. package/cypress/support/env.js +31 -0
  57. package/cypress/support/interface.js +6 -0
  58. package/cypress/support/pageObjects/CartPage.js +56 -0
  59. package/cypress/support/pageObjects/CheckoutPage.js +111 -0
  60. package/cypress/support/pageObjects/GenerateRandomData.js +62 -0
  61. package/cypress/support/pageObjects/Homepage.js +92 -0
  62. package/cypress/support/pageObjects/navigationPage.js +44 -0
  63. package/cypress.config.js +44 -0
  64. package/mochawesome-report/assets/MaterialIcons-Regular.woff +0 -0
  65. package/mochawesome-report/assets/MaterialIcons-Regular.woff2 +0 -0
  66. package/mochawesome-report/assets/app.css +14 -0
  67. package/mochawesome-report/assets/app.js +2 -0
  68. package/mochawesome-report/assets/app.js.LICENSE.txt +55 -0
  69. package/mochawesome-report/assets/roboto-light-webfont.woff +0 -0
  70. package/mochawesome-report/assets/roboto-light-webfont.woff2 +0 -0
  71. package/mochawesome-report/assets/roboto-medium-webfont.woff +0 -0
  72. package/mochawesome-report/assets/roboto-medium-webfont.woff2 +0 -0
  73. package/mochawesome-report/assets/roboto-regular-webfont.woff +0 -0
  74. package/mochawesome-report/assets/roboto-regular-webfont.woff2 +0 -0
  75. package/mochawesome-report/output.html +2 -0
  76. package/output.json +864 -0
  77. package/package.json +43 -0
  78. package/run-parallel-cypress.js +57 -0
  79. package/runAllSteps.js +47 -0
  80. package/syncTestResultsToExcel.js +219 -0
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "cypress_task",
3
+ "version": "1.0.0",
4
+ "main": "index.js",
5
+ "scripts": {
6
+ "Open_UI": "npx cypress open",
7
+ "Run_Tests": "npx cypress run",
8
+ "Run_Tests_Headed": "npx cypress run --headed",
9
+ "Run_Tests_Login_Testcases": "npx cypress run --headed --spec cypress/e2e/Login_Testcases/*",
10
+ "Run_Tests_Cart_Testcases": "npx cypress run --headed--spec cypress/e2e/Cart_Testcases/*",
11
+ "Run_Tests_Checkout_Testcases": "npx cypress run --headed--spec cypress/e2e/Checkout_Testcases/*",
12
+ "Run_Tests_Regression_Testcases": "npx cypress run --headed --spec cypress/e2e/Regression_e2e_Flow/*",
13
+ "getMochawesomeReport": "npx mochawesome-merge cypress/results/*.json -o output.json",
14
+ "clean:reports": "node cleanupReports.js",
15
+ "clean:output": "node cleanupOutput.js",
16
+ "clean_report_files": "npm run clean:reports && npm run clean:output",
17
+ "getHTMLReport": "npx marge output.json",
18
+ "generate_report": "npm run getMochawesomeReport && npm run getHTMLReport",
19
+ "Run_and_update_Result_sheet": "node runAllSteps.js",
20
+ "Run_parallel_Smoke": "concurrently \"cypress run --spec=\\\"cypress/e2e/Smoke_Suit/SMK001_Verify user can log in with valid credentials.cy.js\\\"\" \"cypress run --spec=\\\"cypress/e2e/Smoke_Suit/SMK002_Verify product list loads after login.cy.js\\\"\" \"cypress run --spec=\\\"cypress/e2e/Smoke_Suit/SMK003_Verify user can add a product to cart.cy.js\\\"\"",
21
+ "parallel_node_smoke": "node run-parallel-cypress.js",
22
+ "grep-run": "node run-grep-cypress.js"
23
+ },
24
+ "keywords": [],
25
+ "author": "",
26
+ "license": "ISC",
27
+ "description": "",
28
+ "dependencies": {
29
+ "exceljs": "^4.4.0",
30
+ "fs": "^0.0.1-security",
31
+ "mochawesome": "^7.1.3",
32
+ "mochawesome-merge": "^4.2.1",
33
+ "mochawesome-report-generator": "^6.2.0",
34
+ "npx": "^10.2.2",
35
+ "xlsx": "^0.18.5"
36
+ },
37
+ "devDependencies": {
38
+ "concurrently": "^9.2.0",
39
+ "cypress": "^14.5.2",
40
+ "cypress-rerun-failed-specs-sid-g": "^1.0.8",
41
+ "sid-cypress-rerun-failed": "^1.0.4"
42
+ }
43
+ }
@@ -0,0 +1,57 @@
1
+ // File: run-parallel-cypress.js
2
+
3
+ const { exec } = require('child_process');
4
+ const fs = require('fs');
5
+ const os = require('os');
6
+ const path = require('path');
7
+
8
+ // CONFIGURABLE: Folder where your spec files are located
9
+ const SPEC_FOLDER = path.join(__dirname, 'cypress', 'e2e', 'Smoke_Suit');
10
+
11
+ // CONFIGURABLE: Max parallel processes (default to CPU cores)
12
+ const MAX_PARALLEL = os.cpus().length; // You can hardcode e.g., 3
13
+
14
+ // Read all spec files
15
+ const specFiles = fs.readdirSync(SPEC_FOLDER)
16
+ .filter(file => file.endsWith('.cy.js'))
17
+ .map(file => path.join('cypress', 'e2e', 'Smoke_Suit', file));
18
+
19
+ if (specFiles.length === 0) {
20
+ console.error('No spec files found in', SPEC_FOLDER);
21
+ process.exit(1);
22
+ }
23
+
24
+ console.log(`Found ${specFiles.length} spec files. Running up to ${MAX_PARALLEL} in parallel...`);
25
+
26
+ let currentIndex = 0;
27
+ let activeProcesses = 0;
28
+
29
+ function runNextSpec() {
30
+ if (currentIndex >= specFiles.length) return;
31
+
32
+ const spec = specFiles[currentIndex++];
33
+ activeProcesses++;
34
+
35
+ console.log(`\n▶️ Starting: ${spec}`);
36
+
37
+ const child = exec(`npx cypress run --spec=\\"${spec}\\"`);
38
+
39
+ child.stdout.on('data', data => process.stdout.write(data));
40
+ child.stderr.on('data', data => process.stderr.write(data));
41
+
42
+ child.on('exit', code => {
43
+ console.log(`\n✅ Finished: ${spec} (exit code ${code})`);
44
+ activeProcesses--;
45
+ runNextSpec();
46
+
47
+ if (activeProcesses === 0 && currentIndex >= specFiles.length) {
48
+ console.log('\n🎉 All specs completed.');
49
+ }
50
+ });
51
+ }
52
+
53
+ // Start initial batch
54
+ const initialBatch = Math.min(MAX_PARALLEL, specFiles.length);
55
+ for (let i = 0; i < initialBatch; i++) {
56
+ runNextSpec();
57
+ }
package/runAllSteps.js ADDED
@@ -0,0 +1,47 @@
1
+ const { execSync } = require('child_process');
2
+
3
+ function runCommand(cmd, ignoreError = false) {
4
+ try {
5
+ console.log(`▶️ Running: ${cmd}`);
6
+ execSync(cmd, { stdio: 'inherit' });
7
+ return true;
8
+ } catch (err) {
9
+ if (!ignoreError) throw err;
10
+ console.warn(`⚠️ Ignored error in: ${cmd}`);
11
+ return false;
12
+ }
13
+ }
14
+
15
+ // ------------------------
16
+ // CLEANUP
17
+ // ------------------------
18
+ runCommand('node clean_mochawesome.js');
19
+ runCommand('npm run clean_report_files');
20
+
21
+ // ------------------------
22
+ // INITIAL TEST RUN
23
+ // ------------------------
24
+ const firstRunPassed = runCommand('npm run Run_Tests', true); // allow failure
25
+
26
+ // ------------------------
27
+ // REPORT GENERATION
28
+ // ------------------------
29
+ runCommand('npm run getMochawesomeReport');
30
+ runCommand('npm run getHTMLReport');
31
+
32
+ // ------------------------
33
+ // RERUN FAILED SPECS (CI + LOCAL)
34
+ // ------------------------
35
+ if (!firstRunPassed) {
36
+ console.log('🔁 Initial test run failed. Attempting rerun of failed specs...');
37
+ runCommand('npx cypress-rerun-failed', true);
38
+ } else {
39
+ console.log('✅ Initial test run passed. No rerun needed.');
40
+ }
41
+
42
+ // ------------------------
43
+ // POST-PROCESSING
44
+ // ------------------------
45
+ runCommand('node syncTestResultsToExcel.js');
46
+
47
+ console.log('✅ All steps completed.');
@@ -0,0 +1,219 @@
1
+ const fs = require('fs');
2
+ const ExcelJS = require('exceljs');
3
+
4
+ const reportPath = './output.json';
5
+ const excelPath = './Daily_Tracker.xlsx';
6
+ const todayDate = new Date().toLocaleDateString('en-GB').replace(/\//g, '-'); // dd-mm-yyyy
7
+ const MAX_DAYS = 60;
8
+
9
+ async function updateExcelWithDescribeBlocks() {
10
+ if (!fs.existsSync(reportPath)) {
11
+ console.error('❌ Mochawesome report not found!');
12
+ process.exit(1);
13
+ }
14
+
15
+ const reportData = JSON.parse(fs.readFileSync(reportPath, 'utf-8'));
16
+ const testResults = [];
17
+
18
+ function extractDescribeTitles(suites) {
19
+ suites.forEach(suite => {
20
+ const describeTitle = suite.title?.trim();
21
+ if (describeTitle) {
22
+ const hasFail = suite.tests?.some(test => test.state !== 'passed');
23
+ const hasPass = suite.tests?.some(test => test.state === 'passed');
24
+ let status = 'F';
25
+
26
+ if (hasPass && !hasFail) {
27
+ status = 'P';
28
+ }
29
+
30
+ testResults.push({ title: describeTitle, status });
31
+ console.log(`✅ Extracted Describe: "${describeTitle}" - ${status}`);
32
+ }
33
+
34
+ if (suite.suites?.length) {
35
+ extractDescribeTitles(suite.suites);
36
+ }
37
+ });
38
+ }
39
+
40
+ if (Array.isArray(reportData.results)) {
41
+ reportData.results.forEach(result => {
42
+ if (result.suites?.length) {
43
+ extractDescribeTitles(result.suites);
44
+ }
45
+ });
46
+ }
47
+
48
+ if (!testResults.length) {
49
+ console.error('❌ No describe block titles found!');
50
+ process.exit(1);
51
+ }
52
+
53
+ const workbook = new ExcelJS.Workbook();
54
+ let worksheet;
55
+
56
+ if (fs.existsSync(excelPath)) {
57
+ await workbook.xlsx.readFile(excelPath);
58
+ worksheet = workbook.getWorksheet('TestResults');
59
+ if (!worksheet) {
60
+ worksheet = workbook.addWorksheet('TestResults');
61
+ worksheet.addRow(['Test Case Title']);
62
+ }
63
+ } else {
64
+ worksheet = workbook.addWorksheet('TestResults');
65
+ worksheet.addRow(['Test Case Title']);
66
+ }
67
+
68
+ const headerRow = worksheet.getRow(1);
69
+ let dateColIndex = headerRow.values.indexOf(todayDate);
70
+
71
+ // Clean up old columns if exceeding 60 date columns
72
+ const allHeaders = headerRow.values;
73
+ const dateHeaders = allHeaders.filter(v => typeof v === 'string' && /^\d{2}-\d{2}-\d{4}$/.test(v));
74
+ if (dateHeaders.length >= MAX_DAYS) {
75
+ const oldestDate = dateHeaders[0];
76
+ const oldestColIndex = headerRow.values.indexOf(oldestDate);
77
+ worksheet.spliceColumns(oldestColIndex, 1);
78
+ console.log(`🗑️ Removed oldest date column: ${oldestDate}`);
79
+ }
80
+
81
+ dateColIndex = headerRow.values.indexOf(todayDate);
82
+ if (dateColIndex === -1) {
83
+ dateColIndex = headerRow.cellCount + 1;
84
+ headerRow.getCell(dateColIndex).value = todayDate;
85
+ headerRow.commit();
86
+
87
+ worksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => {
88
+ if (rowNumber > 1) {
89
+ row.getCell(dateColIndex).value = '';
90
+ row.commit();
91
+ }
92
+ });
93
+ }
94
+
95
+ const rowMap = new Map();
96
+ worksheet.eachRow((row, rowNumber) => {
97
+ if (rowNumber > 1) {
98
+ const testCaseTitle = row.getCell(1).value?.toString().trim();
99
+ if (testCaseTitle) {
100
+ rowMap.set(testCaseTitle, rowNumber);
101
+ }
102
+ }
103
+ });
104
+
105
+ const seen = new Set();
106
+
107
+ for (const { title, status } of testResults) {
108
+ if (seen.has(title)) continue;
109
+ seen.add(title);
110
+
111
+ let row;
112
+ if (rowMap.has(title)) {
113
+ row = worksheet.getRow(rowMap.get(title));
114
+ } else {
115
+ row = worksheet.addRow([title]);
116
+ for (let i = row.cellCount + 1; i <= dateColIndex; i++) {
117
+ row.getCell(i).value = '';
118
+ }
119
+ rowMap.set(title, row.number);
120
+ }
121
+
122
+ const cell = row.getCell(dateColIndex);
123
+ // Set cell value and color based on status
124
+ if (status === 'P') {
125
+ cell.value = 'P';
126
+ cell.fill = {
127
+ type: 'pattern',
128
+ pattern: 'solid',
129
+ fgColor: { argb: 'C6EFCE' }, // Green
130
+ };
131
+ cell.font = {
132
+ color: { argb: '006100' }, // Green text
133
+ bold: true,
134
+ };
135
+ } else if (status === 'F') {
136
+ cell.value = 'F';
137
+ cell.fill = {
138
+ type: 'pattern',
139
+ pattern: 'solid',
140
+ fgColor: { argb: 'FFC7CE' }, // Red
141
+ };
142
+ cell.font = {
143
+ color: { argb: '9C0006' }, // Red text
144
+ bold: true,
145
+ };
146
+ } else {
147
+ cell.value = status === 'S' ? 'S' : 'N/A'; // S for skipped, N/A for others
148
+ cell.fill = {
149
+ type: 'pattern',
150
+ pattern: 'solid',
151
+ fgColor: { argb: 'D9D9D9' }, // Grey
152
+ };
153
+ cell.font = {
154
+ color: { argb: '7F7F7F' }, // Grey text
155
+ bold: true,
156
+ };
157
+ }
158
+
159
+ row.commit();
160
+ }
161
+
162
+ worksheet.columns.forEach(col => {
163
+ col.width = Math.max(20, col.width || 20);
164
+ });
165
+
166
+ // ✅ Update or create Summary Sheet
167
+ let summarySheet = workbook.getWorksheet('Summary');
168
+ if (!summarySheet) {
169
+ summarySheet = workbook.addWorksheet('Summary');
170
+ }
171
+
172
+ // Ensure header row is present
173
+ const expectedHeaders = ['Date', 'Passed', 'Failed', 'Total', '% Passed'];
174
+ const summaryHeaderRow = summarySheet.getRow(1);
175
+ let headerNeedsUpdate = false;
176
+ for (let i = 0; i < expectedHeaders.length; i++) {
177
+ if (summaryHeaderRow.getCell(i + 1).value !== expectedHeaders[i]) {
178
+ headerNeedsUpdate = true;
179
+ break;
180
+ }
181
+ }
182
+ if (headerNeedsUpdate) {
183
+ summaryHeaderRow.values = expectedHeaders;
184
+ summaryHeaderRow.commit();
185
+ }
186
+
187
+ const updatedHeaderValues = worksheet.getRow(1).values;
188
+ const updatedDateHeaders = updatedHeaderValues.filter(v => typeof v === 'string' && /^\d{2}-\d{2}-\d{4}$/.test(v));
189
+
190
+ updatedDateHeaders.forEach((date, i) => {
191
+ const colIndex = updatedHeaderValues.indexOf(date);
192
+ let passed = 0, failed = 0;
193
+
194
+ worksheet.eachRow((row, rowNum) => {
195
+ if (rowNum === 1) return;
196
+ const status = row.getCell(colIndex).value;
197
+ if (status === 'P') passed++;
198
+ else if (status === 'F') failed++;
199
+ });
200
+
201
+ const total = passed + failed;
202
+ const percent = total === 0 ? 0 : Math.round((passed / total) * 100);
203
+
204
+ const summaryRow = summarySheet.getRow(i + 2);
205
+ summaryRow.getCell(1).value = date;
206
+ summaryRow.getCell(2).value = passed;
207
+ summaryRow.getCell(3).value = failed;
208
+ summaryRow.getCell(4).value = total;
209
+ summaryRow.getCell(5).value = `${percent}%`;
210
+ summaryRow.commit();
211
+ });
212
+
213
+ await workbook.xlsx.writeFile(excelPath);
214
+ console.log(`📊 Excel updated with today's results and 60-day limit maintained.`);
215
+ }
216
+
217
+ updateExcelWithDescribeBlocks().catch(err => {
218
+ console.error('❌ Error:', err);
219
+ });