@testsmith/perfornium 0.6.3 → 0.6.5

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 (191) hide show
  1. package/dist/cli/commands/distributed.js +2 -2
  2. package/dist/cli/commands/report.js +2 -2
  3. package/dist/cli/commands/run.js +2 -0
  4. package/dist/config/parser.js +2 -2
  5. package/dist/config/types/global-config.d.ts +82 -2
  6. package/dist/config/types/scenario-config.d.ts +2 -2
  7. package/dist/core/data/data-manager.d.ts +70 -0
  8. package/dist/core/data/data-manager.js +186 -0
  9. package/dist/core/data/data-provider.d.ts +85 -0
  10. package/dist/core/data/data-provider.js +468 -0
  11. package/dist/core/data/index.d.ts +8 -0
  12. package/dist/core/data/index.js +13 -0
  13. package/dist/core/execution/check-evaluator.d.ts +10 -0
  14. package/dist/core/execution/check-evaluator.js +79 -0
  15. package/dist/core/execution/data-extractor.d.ts +6 -0
  16. package/dist/core/execution/data-extractor.js +70 -0
  17. package/dist/core/execution/index.d.ts +3 -0
  18. package/dist/core/execution/index.js +9 -0
  19. package/dist/core/execution/json-payload-processor.d.ts +7 -0
  20. package/dist/core/execution/json-payload-processor.js +140 -0
  21. package/dist/core/factories/index.d.ts +2 -0
  22. package/dist/core/factories/index.js +7 -0
  23. package/dist/core/factories/output-handler-factory.d.ts +10 -0
  24. package/dist/core/factories/output-handler-factory.js +91 -0
  25. package/dist/core/factories/protocol-handler-factory.d.ts +12 -0
  26. package/dist/core/factories/protocol-handler-factory.js +96 -0
  27. package/dist/core/index.d.ts +3 -2
  28. package/dist/core/index.js +8 -3
  29. package/dist/core/reporting/dashboard-reporter.d.ts +17 -0
  30. package/dist/core/reporting/dashboard-reporter.js +127 -0
  31. package/dist/core/reporting/index.d.ts +1 -0
  32. package/dist/core/reporting/index.js +5 -0
  33. package/dist/core/step-executor.d.ts +6 -20
  34. package/dist/core/step-executor.js +72 -366
  35. package/dist/core/strategies/index.d.ts +2 -0
  36. package/dist/core/strategies/index.js +7 -0
  37. package/dist/core/strategies/scenario-selector.d.ts +13 -0
  38. package/dist/core/strategies/scenario-selector.js +37 -0
  39. package/dist/core/strategies/think-time-strategy.d.ts +15 -0
  40. package/dist/core/strategies/think-time-strategy.js +71 -0
  41. package/dist/core/test-runner.d.ts +4 -11
  42. package/dist/core/test-runner.js +105 -312
  43. package/dist/core/virtual-user.d.ts +7 -37
  44. package/dist/core/virtual-user.js +29 -269
  45. package/dist/dashboard/routes/api.d.ts +64 -0
  46. package/dist/dashboard/routes/api.js +569 -0
  47. package/dist/dashboard/routes/index.d.ts +2 -0
  48. package/dist/dashboard/routes/index.js +7 -0
  49. package/dist/dashboard/routes/static.d.ts +6 -0
  50. package/dist/dashboard/routes/static.js +76 -0
  51. package/dist/dashboard/server.d.ts +8 -84
  52. package/dist/dashboard/server.js +76 -2007
  53. package/dist/dashboard/services/file-scanner.d.ts +7 -0
  54. package/dist/dashboard/services/file-scanner.js +114 -0
  55. package/dist/dashboard/services/index.d.ts +5 -0
  56. package/dist/dashboard/services/index.js +13 -0
  57. package/dist/dashboard/services/influxdb-service.d.ts +41 -0
  58. package/dist/dashboard/services/influxdb-service.js +329 -0
  59. package/dist/dashboard/services/metrics-parser.d.ts +12 -0
  60. package/dist/dashboard/services/metrics-parser.js +209 -0
  61. package/dist/dashboard/services/results-manager.d.ts +17 -0
  62. package/dist/dashboard/services/results-manager.js +311 -0
  63. package/dist/dashboard/services/test-executor.d.ts +41 -0
  64. package/dist/dashboard/services/test-executor.js +250 -0
  65. package/dist/dashboard/services/workers-manager.d.ts +13 -0
  66. package/dist/dashboard/services/workers-manager.js +81 -0
  67. package/dist/dashboard/templates/index.html +122 -0
  68. package/dist/dashboard/templates/scripts/main.js +3280 -0
  69. package/dist/dashboard/templates/styles.css +402 -0
  70. package/dist/dashboard/types.d.ts +168 -0
  71. package/dist/dashboard/types.js +2 -0
  72. package/dist/distributed/result-aggregator.js +1 -3
  73. package/dist/metrics/batch/batch-processor.d.ts +27 -0
  74. package/dist/metrics/batch/batch-processor.js +85 -0
  75. package/dist/metrics/batch/index.d.ts +1 -0
  76. package/dist/metrics/batch/index.js +5 -0
  77. package/dist/metrics/collector.d.ts +46 -45
  78. package/dist/metrics/collector.js +179 -640
  79. package/dist/metrics/core/error-tracker.d.ts +9 -0
  80. package/dist/metrics/core/error-tracker.js +52 -0
  81. package/dist/metrics/core/index.d.ts +3 -0
  82. package/dist/metrics/core/index.js +9 -0
  83. package/dist/metrics/core/result-storage.d.ts +19 -0
  84. package/dist/metrics/core/result-storage.js +56 -0
  85. package/dist/metrics/core/statistics-engine.d.ts +27 -0
  86. package/dist/metrics/core/statistics-engine.js +91 -0
  87. package/dist/metrics/output/file-writer.d.ts +19 -0
  88. package/dist/metrics/output/file-writer.js +129 -0
  89. package/dist/metrics/output/index.d.ts +2 -0
  90. package/dist/metrics/output/index.js +10 -0
  91. package/dist/metrics/output/influxdb-writer.d.ts +89 -0
  92. package/dist/metrics/output/influxdb-writer.js +404 -0
  93. package/dist/metrics/realtime/dispatcher.d.ts +18 -0
  94. package/dist/metrics/realtime/dispatcher.js +45 -0
  95. package/dist/metrics/realtime/endpoints/graphite.d.ts +3 -0
  96. package/dist/metrics/realtime/endpoints/graphite.js +61 -0
  97. package/dist/metrics/realtime/endpoints/influxdb.d.ts +3 -0
  98. package/dist/metrics/realtime/endpoints/influxdb.js +35 -0
  99. package/dist/metrics/realtime/endpoints/webhook.d.ts +3 -0
  100. package/dist/metrics/realtime/endpoints/webhook.js +22 -0
  101. package/dist/metrics/realtime/endpoints/websocket.d.ts +3 -0
  102. package/dist/metrics/realtime/endpoints/websocket.js +25 -0
  103. package/dist/metrics/realtime/index.d.ts +5 -0
  104. package/dist/metrics/realtime/index.js +13 -0
  105. package/dist/metrics/reporting/index.d.ts +3 -0
  106. package/dist/metrics/reporting/index.js +9 -0
  107. package/dist/metrics/reporting/step-statistics.d.ts +6 -0
  108. package/dist/metrics/reporting/step-statistics.js +59 -0
  109. package/dist/metrics/reporting/summary-generator.d.ts +16 -0
  110. package/dist/metrics/reporting/summary-generator.js +46 -0
  111. package/dist/metrics/reporting/timeline-calculator.d.ts +7 -0
  112. package/dist/metrics/reporting/timeline-calculator.js +86 -0
  113. package/dist/metrics/types.d.ts +58 -0
  114. package/dist/outputs/csv.d.ts +2 -0
  115. package/dist/outputs/csv.js +21 -2
  116. package/dist/outputs/json.js +6 -2
  117. package/dist/protocols/rest/handler.d.ts +4 -53
  118. package/dist/protocols/rest/handler.js +73 -454
  119. package/dist/protocols/rest/request/auth-handler.d.ts +4 -0
  120. package/dist/protocols/rest/request/auth-handler.js +30 -0
  121. package/dist/protocols/rest/request/body-processor.d.ts +11 -0
  122. package/dist/protocols/rest/request/body-processor.js +62 -0
  123. package/dist/protocols/rest/request/index.d.ts +2 -0
  124. package/dist/protocols/rest/request/index.js +7 -0
  125. package/dist/protocols/rest/response/checks.d.ts +6 -0
  126. package/dist/protocols/rest/response/checks.js +71 -0
  127. package/dist/protocols/rest/response/index.d.ts +2 -0
  128. package/dist/protocols/rest/response/index.js +7 -0
  129. package/dist/protocols/rest/response/size-calculator.d.ts +12 -0
  130. package/dist/protocols/rest/response/size-calculator.js +64 -0
  131. package/dist/protocols/web/browser/highlight.d.ts +7 -0
  132. package/dist/protocols/web/browser/highlight.js +47 -0
  133. package/dist/protocols/web/browser/index.d.ts +4 -0
  134. package/dist/protocols/web/browser/index.js +11 -0
  135. package/dist/protocols/web/browser/manager.d.ts +20 -0
  136. package/dist/protocols/web/browser/manager.js +189 -0
  137. package/dist/protocols/web/browser/screenshot.d.ts +8 -0
  138. package/dist/protocols/web/browser/screenshot.js +69 -0
  139. package/dist/protocols/web/browser/storage.d.ts +5 -0
  140. package/dist/protocols/web/browser/storage.js +45 -0
  141. package/dist/protocols/web/commands/index.d.ts +5 -0
  142. package/dist/protocols/web/commands/index.js +11 -0
  143. package/dist/protocols/web/commands/interaction.d.ts +13 -0
  144. package/dist/protocols/web/commands/interaction.js +68 -0
  145. package/dist/protocols/web/commands/measurement.d.ts +16 -0
  146. package/dist/protocols/web/commands/measurement.js +33 -0
  147. package/dist/protocols/web/commands/navigation.d.ts +11 -0
  148. package/dist/protocols/web/commands/navigation.js +43 -0
  149. package/dist/protocols/web/commands/types.d.ts +12 -0
  150. package/dist/protocols/web/commands/types.js +2 -0
  151. package/dist/protocols/web/commands/verification.d.ts +11 -0
  152. package/dist/protocols/web/commands/verification.js +98 -0
  153. package/dist/protocols/web/handler.d.ts +19 -30
  154. package/dist/protocols/web/handler.js +160 -650
  155. package/dist/protocols/web/network/capture.d.ts +19 -0
  156. package/dist/protocols/web/network/capture.js +225 -0
  157. package/dist/protocols/web/network/filters.d.ts +5 -0
  158. package/dist/protocols/web/network/filters.js +49 -0
  159. package/dist/protocols/web/network/index.d.ts +4 -0
  160. package/dist/protocols/web/network/index.js +9 -0
  161. package/dist/protocols/web/network/types.d.ts +13 -0
  162. package/dist/protocols/web/network/types.js +2 -0
  163. package/dist/protocols/web/network/utils.d.ts +8 -0
  164. package/dist/protocols/web/network/utils.js +29 -0
  165. package/dist/recorder/native-recorder.js +2 -1
  166. package/dist/reporting/chart-data/index.d.ts +5 -0
  167. package/dist/reporting/chart-data/index.js +13 -0
  168. package/dist/reporting/chart-data/network.d.ts +25 -0
  169. package/dist/reporting/chart-data/network.js +78 -0
  170. package/dist/reporting/chart-data/scenario.d.ts +37 -0
  171. package/dist/reporting/chart-data/scenario.js +76 -0
  172. package/dist/reporting/chart-data/step-statistics.d.ts +24 -0
  173. package/dist/reporting/chart-data/step-statistics.js +94 -0
  174. package/dist/reporting/chart-data/throughput.d.ts +16 -0
  175. package/dist/reporting/chart-data/throughput.js +24 -0
  176. package/dist/reporting/chart-data/timeline.d.ts +17 -0
  177. package/dist/reporting/chart-data/timeline.js +46 -0
  178. package/dist/reporting/handlebars-helpers.d.ts +1 -0
  179. package/dist/reporting/handlebars-helpers.js +63 -0
  180. package/dist/reporting/{enhanced-html-generator.d.ts → html-generator.d.ts} +1 -1
  181. package/dist/reporting/{enhanced-html-generator.js → html-generator.js} +10 -7
  182. package/dist/reporting/templates/{enhanced-report.hbs → report.hbs} +9 -9
  183. package/dist/utils/data-utils.d.ts +17 -0
  184. package/dist/utils/data-utils.js +129 -0
  185. package/dist/utils/template.js +2 -2
  186. package/package.json +5 -2
  187. package/dist/core/csv-data-provider.d.ts +0 -47
  188. package/dist/core/csv-data-provider.js +0 -265
  189. package/dist/reporting/generator.d.ts +0 -42
  190. package/dist/reporting/generator.js +0 -1217
  191. package/dist/reporting/templates/html.hbs +0 -2453
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StorageManager = void 0;
4
+ const logger_1 = require("../../../utils/logger");
5
+ class StorageManager {
6
+ async clearStorageIfConfigured(page, context, clearConfig) {
7
+ if (!clearConfig)
8
+ return;
9
+ const config = typeof clearConfig === 'boolean'
10
+ ? { local_storage: true, session_storage: true, cookies: true, cache: false }
11
+ : clearConfig;
12
+ try {
13
+ await page.goto('about:blank');
14
+ if (config.cookies !== false) {
15
+ await context.clearCookies();
16
+ logger_1.logger.debug('Cleared cookies');
17
+ }
18
+ if (config.local_storage !== false || config.session_storage !== false) {
19
+ await page.evaluate((opts) => {
20
+ if (opts.local_storage !== false) {
21
+ try {
22
+ localStorage.clear();
23
+ }
24
+ catch (e) { /* ignore */ }
25
+ }
26
+ if (opts.session_storage !== false) {
27
+ try {
28
+ sessionStorage.clear();
29
+ }
30
+ catch (e) { /* ignore */ }
31
+ }
32
+ }, { local_storage: config.local_storage, session_storage: config.session_storage });
33
+ if (config.local_storage !== false)
34
+ logger_1.logger.debug('Cleared localStorage');
35
+ if (config.session_storage !== false)
36
+ logger_1.logger.debug('Cleared sessionStorage');
37
+ }
38
+ logger_1.logger.debug('Browser storage cleared');
39
+ }
40
+ catch (error) {
41
+ logger_1.logger.warn('Failed to clear storage:', error);
42
+ }
43
+ }
44
+ }
45
+ exports.StorageManager = StorageManager;
@@ -0,0 +1,5 @@
1
+ export { NavigationCommands } from './navigation';
2
+ export { InteractionCommands } from './interaction';
3
+ export { VerificationCommands } from './verification';
4
+ export { MeasurementCommands } from './measurement';
5
+ export { CommandResult, CommandHandler, HighlightFunction } from './types';
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MeasurementCommands = exports.VerificationCommands = exports.InteractionCommands = exports.NavigationCommands = void 0;
4
+ var navigation_1 = require("./navigation");
5
+ Object.defineProperty(exports, "NavigationCommands", { enumerable: true, get: function () { return navigation_1.NavigationCommands; } });
6
+ var interaction_1 = require("./interaction");
7
+ Object.defineProperty(exports, "InteractionCommands", { enumerable: true, get: function () { return interaction_1.InteractionCommands; } });
8
+ var verification_1 = require("./verification");
9
+ Object.defineProperty(exports, "VerificationCommands", { enumerable: true, get: function () { return verification_1.VerificationCommands; } });
10
+ var measurement_1 = require("./measurement");
11
+ Object.defineProperty(exports, "MeasurementCommands", { enumerable: true, get: function () { return measurement_1.MeasurementCommands; } });
@@ -0,0 +1,13 @@
1
+ import { Page } from 'playwright';
2
+ import { WebAction } from '../../../config';
3
+ import { CommandResult, HighlightFunction } from './types';
4
+ export declare class InteractionCommands {
5
+ private highlightElement;
6
+ constructor(highlightElement: HighlightFunction);
7
+ handleClick(page: Page, action: WebAction): Promise<CommandResult>;
8
+ handleFill(page: Page, action: WebAction): Promise<CommandResult>;
9
+ handleSelect(page: Page, action: WebAction): Promise<CommandResult>;
10
+ handlePress(page: Page, action: WebAction): Promise<CommandResult>;
11
+ handleHover(page: Page, action: WebAction): Promise<CommandResult>;
12
+ handleEvaluate(page: Page, action: WebAction): Promise<CommandResult>;
13
+ }
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InteractionCommands = void 0;
4
+ class InteractionCommands {
5
+ constructor(highlightElement) {
6
+ this.highlightElement = highlightElement;
7
+ }
8
+ async handleClick(page, action) {
9
+ const timeout = action.timeout || 30000;
10
+ const selector = action.selector;
11
+ await page.waitForSelector(selector, {
12
+ state: 'visible',
13
+ timeout
14
+ });
15
+ await this.highlightElement(page, selector);
16
+ await page.locator(selector).click({ timeout });
17
+ return { clicked: selector };
18
+ }
19
+ async handleFill(page, action) {
20
+ const timeout = action.timeout || 30000;
21
+ await page.waitForSelector(action.selector, {
22
+ state: 'visible',
23
+ timeout
24
+ });
25
+ await this.highlightElement(page, action.selector);
26
+ await page.locator(action.selector).fill(action.value, { timeout });
27
+ return { filled: action.selector, value: action.value };
28
+ }
29
+ async handleSelect(page, action) {
30
+ const timeout = action.timeout || 30000;
31
+ await page.waitForSelector(action.selector, {
32
+ state: 'visible',
33
+ timeout
34
+ });
35
+ await this.highlightElement(page, action.selector);
36
+ await page.locator(action.selector).selectOption(action.value, { timeout });
37
+ return { selected: action.selector, value: action.value };
38
+ }
39
+ async handlePress(page, action) {
40
+ const timeout = action.timeout || 30000;
41
+ const key = action.key;
42
+ if (action.selector) {
43
+ await page.waitForSelector(action.selector, {
44
+ state: 'visible',
45
+ timeout
46
+ });
47
+ await this.highlightElement(page, action.selector);
48
+ await page.locator(action.selector).press(key, { timeout });
49
+ return { pressed: key, selector: action.selector };
50
+ }
51
+ else {
52
+ await page.keyboard.press(key);
53
+ return { pressed: key };
54
+ }
55
+ }
56
+ async handleHover(page, action) {
57
+ await page.hover(action.selector);
58
+ return { hovered: action.selector };
59
+ }
60
+ async handleEvaluate(page, action) {
61
+ if (action.script) {
62
+ const result = await page.evaluate(action.script);
63
+ return { evaluation_result: result };
64
+ }
65
+ throw new Error('No script provided for evaluate command');
66
+ }
67
+ }
68
+ exports.InteractionCommands = InteractionCommands;
@@ -0,0 +1,16 @@
1
+ import { Page } from 'playwright';
2
+ import { WebAction } from '../../../config';
3
+ import { CommandResult } from './types';
4
+ import { CoreWebVitals, VerificationStepMetrics } from '../core-web-vitals';
5
+ export declare class MeasurementCommands {
6
+ handleMeasureWebVitals(page: Page, action: WebAction): Promise<CommandResult & {
7
+ web_vitals: CoreWebVitals;
8
+ }>;
9
+ handlePerformanceAudit(page: Page, action: WebAction, verificationMetrics?: VerificationStepMetrics): Promise<CommandResult>;
10
+ handleScreenshot(page: Page, action: WebAction): Promise<CommandResult>;
11
+ collectWebVitalsIfNeeded(page: Page, action: WebAction, shouldCollect: boolean): Promise<CoreWebVitals | undefined>;
12
+ evaluateVitals(webVitals: CoreWebVitals, thresholds?: any): {
13
+ score: 'good' | 'needs-improvement' | 'poor';
14
+ details: any;
15
+ };
16
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MeasurementCommands = void 0;
4
+ const core_web_vitals_1 = require("../core-web-vitals");
5
+ class MeasurementCommands {
6
+ async handleMeasureWebVitals(page, action) {
7
+ const webVitals = await core_web_vitals_1.CoreWebVitalsCollector.collectVitals(page, action.webVitalsWaitTime || 3000);
8
+ return { web_vitals: webVitals };
9
+ }
10
+ async handlePerformanceAudit(page, action, verificationMetrics) {
11
+ const performanceMetrics = await core_web_vitals_1.WebPerformanceCollector.collectAllMetrics(page, verificationMetrics);
12
+ return { performance_audit: performanceMetrics };
13
+ }
14
+ async handleScreenshot(page, action) {
15
+ const screenshot = await page.screenshot({
16
+ type: 'png',
17
+ fullPage: action.options?.fullPage || false
18
+ });
19
+ return {
20
+ screenshot: screenshot.length,
21
+ screenshot_data: action.options?.includeData ? screenshot.toString('base64') : undefined
22
+ };
23
+ }
24
+ async collectWebVitalsIfNeeded(page, action, shouldCollect) {
25
+ if (!shouldCollect)
26
+ return undefined;
27
+ return core_web_vitals_1.CoreWebVitalsCollector.collectVitals(page, action.webVitalsWaitTime || 1000);
28
+ }
29
+ evaluateVitals(webVitals, thresholds) {
30
+ return core_web_vitals_1.CoreWebVitalsCollector.evaluateVitals(webVitals, thresholds);
31
+ }
32
+ }
33
+ exports.MeasurementCommands = MeasurementCommands;
@@ -0,0 +1,11 @@
1
+ import { Page } from 'playwright';
2
+ import { WebAction, BrowserConfig } from '../../../config';
3
+ import { CommandResult } from './types';
4
+ export declare class NavigationCommands {
5
+ private config;
6
+ constructor(config: BrowserConfig);
7
+ handleGoto(page: Page, action: WebAction): Promise<CommandResult>;
8
+ handleWaitForLoadState(page: Page, action: WebAction): Promise<CommandResult>;
9
+ handleNetworkIdle(page: Page, action: WebAction): Promise<CommandResult>;
10
+ handleDomReady(page: Page, action: WebAction): Promise<CommandResult>;
11
+ }
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NavigationCommands = void 0;
4
+ class NavigationCommands {
5
+ constructor(config) {
6
+ this.config = config;
7
+ }
8
+ async handleGoto(page, action) {
9
+ const fullUrl = action.url?.startsWith('http')
10
+ ? action.url
11
+ : `${this.config.base_url}${action.url || ''}`;
12
+ const response = await page.goto(fullUrl, {
13
+ timeout: action.timeout || 30000,
14
+ waitUntil: action.waitUntil || 'domcontentloaded'
15
+ });
16
+ return {
17
+ url: page.url(),
18
+ status: response?.status(),
19
+ headers: await response?.allHeaders(),
20
+ loading_time: Date.now() - performance.now()
21
+ };
22
+ }
23
+ async handleWaitForLoadState(page, action) {
24
+ const waitUntil = action.waitUntil === 'commit' ? 'load' : (action.waitUntil || 'load');
25
+ await page.waitForLoadState(waitUntil, {
26
+ timeout: action.timeout || 30000
27
+ });
28
+ return { load_state: waitUntil };
29
+ }
30
+ async handleNetworkIdle(page, action) {
31
+ await page.waitForLoadState('networkidle', {
32
+ timeout: action.networkIdleTimeout || 30000
33
+ });
34
+ return { network_idle: true };
35
+ }
36
+ async handleDomReady(page, action) {
37
+ await page.waitForLoadState('domcontentloaded', {
38
+ timeout: action.timeout || 30000
39
+ });
40
+ return { dom_ready: true };
41
+ }
42
+ }
43
+ exports.NavigationCommands = NavigationCommands;
@@ -0,0 +1,12 @@
1
+ import { Page } from 'playwright';
2
+ import { WebAction } from '../../../config';
3
+ export interface CommandResult {
4
+ [key: string]: any;
5
+ action_time?: number;
6
+ }
7
+ export interface CommandHandler {
8
+ execute(page: Page, action: WebAction): Promise<CommandResult>;
9
+ }
10
+ export interface HighlightFunction {
11
+ (page: Page, selector: string): Promise<void>;
12
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,11 @@
1
+ import { Page } from 'playwright';
2
+ import { WebAction } from '../../../config';
3
+ import { CommandResult } from './types';
4
+ export declare class VerificationCommands {
5
+ handleWaitForSelector(page: Page, action: WebAction): Promise<CommandResult>;
6
+ handleVerifyExists(page: Page, action: WebAction): Promise<CommandResult>;
7
+ handleVerifyVisible(page: Page, action: WebAction): Promise<CommandResult>;
8
+ handleVerifyText(page: Page, action: WebAction): Promise<CommandResult>;
9
+ handleVerifyContains(page: Page, action: WebAction): Promise<CommandResult>;
10
+ handleVerifyNotExists(page: Page, action: WebAction): Promise<CommandResult>;
11
+ }
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VerificationCommands = void 0;
4
+ class VerificationCommands {
5
+ async handleWaitForSelector(page, action) {
6
+ await page.waitForSelector(action.selector, {
7
+ timeout: action.timeout || 30000
8
+ });
9
+ return { waited_for: action.selector };
10
+ }
11
+ async handleVerifyExists(page, action) {
12
+ await page.waitForSelector(action.selector, {
13
+ state: 'attached',
14
+ timeout: action.timeout || 30000
15
+ });
16
+ const elementCount = await page.locator(action.selector).count();
17
+ return {
18
+ verified: 'exists',
19
+ selector: action.selector,
20
+ name: action.name,
21
+ found_elements: elementCount,
22
+ element_count: elementCount
23
+ };
24
+ }
25
+ async handleVerifyVisible(page, action) {
26
+ await page.waitForSelector(action.selector, {
27
+ state: 'visible',
28
+ timeout: action.timeout || 30000
29
+ });
30
+ return {
31
+ verified: 'visible',
32
+ selector: action.selector,
33
+ name: action.name,
34
+ is_visible: true
35
+ };
36
+ }
37
+ async handleVerifyText(page, action) {
38
+ await page.waitForSelector(action.selector, {
39
+ state: 'attached',
40
+ timeout: action.timeout || 30000
41
+ });
42
+ const textLocator = page.locator(action.selector);
43
+ const actualText = await textLocator.textContent();
44
+ const expectedText = action.expected_text;
45
+ if (!actualText || !actualText.includes(expectedText)) {
46
+ throw new Error(`Verification failed: Element "${action.selector}" text "${actualText}" does not contain expected text "${expectedText}"${action.name ? ` (${action.name})` : ''}`);
47
+ }
48
+ return {
49
+ verified: 'text',
50
+ selector: action.selector,
51
+ name: action.name,
52
+ expected_text: expectedText,
53
+ actual_text: actualText,
54
+ text_match: true
55
+ };
56
+ }
57
+ async handleVerifyContains(page, action) {
58
+ await page.waitForSelector(action.selector, {
59
+ state: 'attached',
60
+ timeout: action.timeout || 30000
61
+ });
62
+ const textLocator = page.locator(action.selector);
63
+ const actualText = await textLocator.textContent();
64
+ const expectedText = action.value;
65
+ if (!actualText || !actualText.includes(expectedText)) {
66
+ throw new Error(`Verification failed: Element "${action.selector}" text "${actualText}" does not contain "${expectedText}"${action.name ? ` (${action.name})` : ''}`);
67
+ }
68
+ return {
69
+ verified: 'contains',
70
+ selector: action.selector,
71
+ name: action.name,
72
+ expected_text: expectedText,
73
+ actual_text: actualText,
74
+ text_match: true
75
+ };
76
+ }
77
+ async handleVerifyNotExists(page, action) {
78
+ try {
79
+ await page.waitForSelector(action.selector, {
80
+ state: 'detached',
81
+ timeout: action.timeout || 5000
82
+ });
83
+ }
84
+ catch (error) {
85
+ const count = await page.locator(action.selector).count();
86
+ if (count > 0) {
87
+ throw new Error(`Verification failed: Element "${action.selector}" exists but should not exist${action.name ? ` (${action.name})` : ''}`);
88
+ }
89
+ }
90
+ return {
91
+ verified: 'not_exists',
92
+ selector: action.selector,
93
+ name: action.name,
94
+ found_elements: 0
95
+ };
96
+ }
97
+ }
98
+ exports.VerificationCommands = VerificationCommands;
@@ -1,30 +1,31 @@
1
1
  import { ProtocolHandler, ProtocolResult } from '../base';
2
2
  import { VUContext, WebAction, BrowserConfig } from '../../config';
3
3
  import { VerificationStepMetrics } from './core-web-vitals';
4
+ import { CapturedNetworkCall } from '../../metrics/types';
5
+ import { NetworkCallCallback } from './network';
4
6
  export declare class WebHandler implements ProtocolHandler {
5
- private browsers;
6
- private contexts;
7
- private pages;
8
- private verificationMetrics;
9
7
  private config;
10
- constructor(config: BrowserConfig);
8
+ private verificationMetrics;
9
+ private browserManager;
10
+ private networkManager;
11
+ private storageManager;
12
+ private highlighter;
13
+ private screenshotCapture;
14
+ private navigationCommands;
15
+ private interactionCommands;
16
+ private verificationCommands;
17
+ private measurementCommands;
18
+ constructor(config: BrowserConfig, onNetworkCall?: NetworkCallCallback);
11
19
  initialize(): Promise<void>;
12
20
  execute(action: WebAction, context: VUContext): Promise<ProtocolResult>;
13
- private handleGoto;
14
- private handleClick;
15
- private handleFill;
16
- private handleSelect;
17
- private handlePress;
18
- private handleWaitForSelector;
19
- private handleVerifyExists;
20
- private handleVerifyVisible;
21
- private handleVerifyText;
22
- private handleVerifyContains;
23
- private handleVerifyNotExists;
24
- private handleLegacyAction;
21
+ private executeWithTiming;
22
+ private executeInteractionWithMeasurement;
23
+ private executeVerificationWithMeasurement;
24
+ private executeVerification;
25
+ private handleExecutionError;
25
26
  private getPage;
26
- private createBrowserForVU;
27
27
  getVerificationMetrics(vuId: number): VerificationStepMetrics[];
28
+ getNetworkCalls(vuId: number): CapturedNetworkCall[];
28
29
  getAggregatedVerificationMetrics(): {
29
30
  total_verifications: number;
30
31
  success_rate: number;
@@ -39,16 +40,4 @@ export declare class WebHandler implements ProtocolHandler {
39
40
  connected: boolean;
40
41
  } | null;
41
42
  getActiveVUCount(): number;
42
- /**
43
- * Clear browser storage (localStorage, sessionStorage, cookies) if configured
44
- */
45
- private clearStorageIfConfigured;
46
- /**
47
- * Highlight an element before interacting with it (for debugging)
48
- */
49
- private highlightElement;
50
- /**
51
- * Capture a screenshot when a test step fails
52
- */
53
- private captureFailureScreenshot;
54
43
  }