agentic-qe 3.7.6 → 3.7.8
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/.claude/helpers/statusline-v3.cjs +13 -1
- package/.claude/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +39 -0
- package/README.md +36 -0
- package/dist/cli/bundle.js +2052 -183
- package/dist/coordination/complexity-composition/index.d.ts +2 -0
- package/dist/coordination/complexity-composition/index.d.ts.map +1 -0
- package/dist/coordination/complexity-composition/index.js +2 -0
- package/dist/coordination/complexity-composition/index.js.map +1 -0
- package/dist/coordination/complexity-composition/team-composer.d.ts +72 -0
- package/dist/coordination/complexity-composition/team-composer.d.ts.map +1 -0
- package/dist/coordination/complexity-composition/team-composer.js +221 -0
- package/dist/coordination/complexity-composition/team-composer.js.map +1 -0
- package/dist/coordination/consensus/consensus-engine.d.ts +10 -1
- package/dist/coordination/consensus/consensus-engine.d.ts.map +1 -1
- package/dist/coordination/consensus/consensus-engine.js +31 -1
- package/dist/coordination/consensus/consensus-engine.js.map +1 -1
- package/dist/coordination/consensus/index.d.ts +1 -0
- package/dist/coordination/consensus/index.d.ts.map +1 -1
- package/dist/coordination/consensus/index.js +4 -0
- package/dist/coordination/consensus/index.js.map +1 -1
- package/dist/coordination/consensus/interfaces.d.ts +5 -0
- package/dist/coordination/consensus/interfaces.d.ts.map +1 -1
- package/dist/coordination/consensus/interfaces.js +1 -0
- package/dist/coordination/consensus/interfaces.js.map +1 -1
- package/dist/coordination/consensus/sycophancy-scorer.d.ts +62 -0
- package/dist/coordination/consensus/sycophancy-scorer.d.ts.map +1 -0
- package/dist/coordination/consensus/sycophancy-scorer.js +200 -0
- package/dist/coordination/consensus/sycophancy-scorer.js.map +1 -0
- package/dist/coordination/fleet-tiers/tier-selector.d.ts +20 -0
- package/dist/coordination/fleet-tiers/tier-selector.d.ts.map +1 -1
- package/dist/coordination/fleet-tiers/tier-selector.js +31 -0
- package/dist/coordination/fleet-tiers/tier-selector.js.map +1 -1
- package/dist/coordination/fleet-tiers/types.d.ts +2 -0
- package/dist/coordination/fleet-tiers/types.d.ts.map +1 -1
- package/dist/domains/test-execution/services/e2e/adaptive-locator-service.d.ts +71 -0
- package/dist/domains/test-execution/services/e2e/adaptive-locator-service.d.ts.map +1 -0
- package/dist/domains/test-execution/services/e2e/adaptive-locator-service.js +456 -0
- package/dist/domains/test-execution/services/e2e/adaptive-locator-service.js.map +1 -0
- package/dist/domains/test-execution/services/e2e/adaptive-locator-types.d.ts +81 -0
- package/dist/domains/test-execution/services/e2e/adaptive-locator-types.d.ts.map +1 -0
- package/dist/domains/test-execution/services/e2e/adaptive-locator-types.js +20 -0
- package/dist/domains/test-execution/services/e2e/adaptive-locator-types.js.map +1 -0
- package/dist/domains/test-execution/services/e2e/browser-orchestrator.d.ts +19 -0
- package/dist/domains/test-execution/services/e2e/browser-orchestrator.d.ts.map +1 -1
- package/dist/domains/test-execution/services/e2e/browser-orchestrator.js +82 -0
- package/dist/domains/test-execution/services/e2e/browser-orchestrator.js.map +1 -1
- package/dist/domains/test-execution/services/e2e/index.d.ts +2 -0
- package/dist/domains/test-execution/services/e2e/index.d.ts.map +1 -1
- package/dist/domains/test-execution/services/e2e/index.js +5 -0
- package/dist/domains/test-execution/services/e2e/index.js.map +1 -1
- package/dist/domains/test-execution/services/e2e/step-executors.d.ts +6 -0
- package/dist/domains/test-execution/services/e2e/step-executors.d.ts.map +1 -1
- package/dist/domains/test-execution/services/e2e/step-executors.js +17 -2
- package/dist/domains/test-execution/services/e2e/step-executors.js.map +1 -1
- package/dist/domains/test-execution/services/e2e/types.d.ts +18 -1
- package/dist/domains/test-execution/services/e2e/types.d.ts.map +1 -1
- package/dist/domains/test-execution/services/e2e/types.js.map +1 -1
- package/dist/domains/test-generation/blind-review/blind-review-orchestrator.d.ts +65 -0
- package/dist/domains/test-generation/blind-review/blind-review-orchestrator.d.ts.map +1 -0
- package/dist/domains/test-generation/blind-review/blind-review-orchestrator.js +189 -0
- package/dist/domains/test-generation/blind-review/blind-review-orchestrator.js.map +1 -0
- package/dist/domains/test-generation/blind-review/index.d.ts +2 -0
- package/dist/domains/test-generation/blind-review/index.d.ts.map +1 -0
- package/dist/domains/test-generation/blind-review/index.js +2 -0
- package/dist/domains/test-generation/blind-review/index.js.map +1 -0
- package/dist/domains/test-generation/gates/index.d.ts +2 -0
- package/dist/domains/test-generation/gates/index.d.ts.map +1 -0
- package/dist/domains/test-generation/gates/index.js +2 -0
- package/dist/domains/test-generation/gates/index.js.map +1 -0
- package/dist/domains/test-generation/gates/test-quality-gate.d.ts +85 -0
- package/dist/domains/test-generation/gates/test-quality-gate.d.ts.map +1 -0
- package/dist/domains/test-generation/gates/test-quality-gate.js +320 -0
- package/dist/domains/test-generation/gates/test-quality-gate.js.map +1 -0
- package/dist/domains/test-generation/interfaces.d.ts +3 -0
- package/dist/domains/test-generation/interfaces.d.ts.map +1 -1
- package/dist/domains/test-generation/pattern-injection/edge-case-injector.d.ts +68 -0
- package/dist/domains/test-generation/pattern-injection/edge-case-injector.d.ts.map +1 -0
- package/dist/domains/test-generation/pattern-injection/edge-case-injector.js +225 -0
- package/dist/domains/test-generation/pattern-injection/edge-case-injector.js.map +1 -0
- package/dist/domains/test-generation/pattern-injection/index.d.ts +2 -0
- package/dist/domains/test-generation/pattern-injection/index.d.ts.map +1 -0
- package/dist/domains/test-generation/pattern-injection/index.js +2 -0
- package/dist/domains/test-generation/pattern-injection/index.js.map +1 -0
- package/dist/domains/test-generation/services/test-generator.d.ts +6 -0
- package/dist/domains/test-generation/services/test-generator.d.ts.map +1 -1
- package/dist/domains/test-generation/services/test-generator.js +29 -0
- package/dist/domains/test-generation/services/test-generator.js.map +1 -1
- package/dist/integrations/agentic-flow/reasoning-bank/experience-replay.d.ts +8 -2
- package/dist/integrations/agentic-flow/reasoning-bank/experience-replay.d.ts.map +1 -1
- package/dist/integrations/agentic-flow/reasoning-bank/experience-replay.js +62 -38
- package/dist/integrations/agentic-flow/reasoning-bank/experience-replay.js.map +1 -1
- package/dist/integrations/browser/client-factory.d.ts +6 -1
- package/dist/integrations/browser/client-factory.d.ts.map +1 -1
- package/dist/integrations/browser/client-factory.js +37 -2
- package/dist/integrations/browser/client-factory.js.map +1 -1
- package/dist/integrations/browser/index.d.ts +5 -1
- package/dist/integrations/browser/index.d.ts.map +1 -1
- package/dist/integrations/browser/index.js +8 -1
- package/dist/integrations/browser/index.js.map +1 -1
- package/dist/integrations/browser/page-pool-types.d.ts +70 -0
- package/dist/integrations/browser/page-pool-types.d.ts.map +1 -0
- package/dist/integrations/browser/page-pool-types.js +19 -0
- package/dist/integrations/browser/page-pool-types.js.map +1 -0
- package/dist/integrations/browser/page-pool.d.ts +79 -0
- package/dist/integrations/browser/page-pool.d.ts.map +1 -0
- package/dist/integrations/browser/page-pool.js +288 -0
- package/dist/integrations/browser/page-pool.js.map +1 -0
- package/dist/integrations/browser/resource-blocking.d.ts +47 -0
- package/dist/integrations/browser/resource-blocking.d.ts.map +1 -0
- package/dist/integrations/browser/resource-blocking.js +195 -0
- package/dist/integrations/browser/resource-blocking.js.map +1 -0
- package/dist/integrations/browser/stealth/index.d.ts +8 -0
- package/dist/integrations/browser/stealth/index.d.ts.map +1 -0
- package/dist/integrations/browser/stealth/index.js +7 -0
- package/dist/integrations/browser/stealth/index.js.map +1 -0
- package/dist/integrations/browser/stealth/stealth-client.d.ts +51 -0
- package/dist/integrations/browser/stealth/stealth-client.d.ts.map +1 -0
- package/dist/integrations/browser/stealth/stealth-client.js +359 -0
- package/dist/integrations/browser/stealth/stealth-client.js.map +1 -0
- package/dist/integrations/browser/stealth/stealth-types.d.ts +35 -0
- package/dist/integrations/browser/stealth/stealth-types.d.ts.map +1 -0
- package/dist/integrations/browser/stealth/stealth-types.js +17 -0
- package/dist/integrations/browser/stealth/stealth-types.js.map +1 -0
- package/dist/integrations/browser/types.d.ts +13 -10
- package/dist/integrations/browser/types.d.ts.map +1 -1
- package/dist/integrations/browser/types.js.map +1 -1
- package/dist/learning/experience-capture.d.ts +12 -2
- package/dist/learning/experience-capture.d.ts.map +1 -1
- package/dist/learning/experience-capture.js +28 -35
- package/dist/learning/experience-capture.js.map +1 -1
- package/dist/learning/experience-consolidation.d.ts +74 -0
- package/dist/learning/experience-consolidation.d.ts.map +1 -0
- package/dist/learning/experience-consolidation.js +403 -0
- package/dist/learning/experience-consolidation.js.map +1 -0
- package/dist/mcp/bundle.js +3050 -341
- package/dist/routing/calibration/ema-calibrator.d.ts +93 -0
- package/dist/routing/calibration/ema-calibrator.d.ts.map +1 -0
- package/dist/routing/calibration/ema-calibrator.js +140 -0
- package/dist/routing/calibration/ema-calibrator.js.map +1 -0
- package/dist/routing/calibration/index.d.ts +2 -0
- package/dist/routing/calibration/index.d.ts.map +1 -0
- package/dist/routing/calibration/index.js +2 -0
- package/dist/routing/calibration/index.js.map +1 -0
- package/dist/routing/escalation/auto-escalation-tracker.d.ts +62 -0
- package/dist/routing/escalation/auto-escalation-tracker.d.ts.map +1 -0
- package/dist/routing/escalation/auto-escalation-tracker.js +116 -0
- package/dist/routing/escalation/auto-escalation-tracker.js.map +1 -0
- package/dist/routing/escalation/index.d.ts +2 -0
- package/dist/routing/escalation/index.d.ts.map +1 -0
- package/dist/routing/escalation/index.js +2 -0
- package/dist/routing/escalation/index.js.map +1 -0
- package/dist/routing/index.d.ts +4 -0
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/index.js +4 -0
- package/dist/routing/index.js.map +1 -1
- package/dist/routing/routing-config.d.ts +4 -0
- package/dist/routing/routing-config.d.ts.map +1 -1
- package/dist/routing/routing-config.js +2 -0
- package/dist/routing/routing-config.js.map +1 -1
- package/dist/routing/routing-feedback.d.ts +35 -2
- package/dist/routing/routing-feedback.d.ts.map +1 -1
- package/dist/routing/routing-feedback.js +97 -3
- package/dist/routing/routing-feedback.js.map +1 -1
- package/dist/routing/types.d.ts +2 -0
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/routing/types.js.map +1 -1
- package/dist/workers/workers/learning-consolidation.d.ts.map +1 -1
- package/dist/workers/workers/learning-consolidation.js +32 -0
- package/dist/workers/workers/learning-consolidation.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser Page Pool Types
|
|
3
|
+
*
|
|
4
|
+
* Manages concurrent browser pages for parallel E2E test execution.
|
|
5
|
+
* Follows the ConnectionPoolImpl pattern from src/mcp/connection-pool.ts.
|
|
6
|
+
*
|
|
7
|
+
* @module integrations/browser/page-pool-types
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* State of a pooled browser page
|
|
11
|
+
*/
|
|
12
|
+
export type PageState = 'ready' | 'busy' | 'error' | 'closed';
|
|
13
|
+
/**
|
|
14
|
+
* A managed browser page within the pool
|
|
15
|
+
*/
|
|
16
|
+
export interface PooledPage {
|
|
17
|
+
/** Unique page identifier */
|
|
18
|
+
id: string;
|
|
19
|
+
/** Current page state */
|
|
20
|
+
state: PageState;
|
|
21
|
+
/** When the page was created (ms since epoch) */
|
|
22
|
+
createdAt: number;
|
|
23
|
+
/** When the page was last used (ms since epoch) */
|
|
24
|
+
lastUsedAt: number;
|
|
25
|
+
/** Health score (0-1, where 1 is healthy) */
|
|
26
|
+
health: number;
|
|
27
|
+
/** Current URL */
|
|
28
|
+
url?: string;
|
|
29
|
+
/** Cumulative error count */
|
|
30
|
+
errorCount: number;
|
|
31
|
+
/** Total requests served by this page */
|
|
32
|
+
requestsServed: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Browser page pool configuration
|
|
36
|
+
*/
|
|
37
|
+
export interface BrowserPagePoolConfig {
|
|
38
|
+
/** Maximum concurrent pages (default: 6) */
|
|
39
|
+
maxPages: number;
|
|
40
|
+
/** Minimum pre-warmed pages (default: 1) */
|
|
41
|
+
minPages: number;
|
|
42
|
+
/** Idle timeout before page is closed in ms (default: 120000) */
|
|
43
|
+
idleTimeoutMs: number;
|
|
44
|
+
/** Health check interval in ms (default: 15000) */
|
|
45
|
+
healthCheckIntervalMs: number;
|
|
46
|
+
/** Minimum health score to keep a page (default: 0.5) */
|
|
47
|
+
healthThreshold: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Default page pool configuration
|
|
51
|
+
*/
|
|
52
|
+
export declare const DEFAULT_PAGE_POOL_CONFIG: BrowserPagePoolConfig;
|
|
53
|
+
/**
|
|
54
|
+
* Page pool statistics for monitoring
|
|
55
|
+
*/
|
|
56
|
+
export interface PagePoolStats {
|
|
57
|
+
/** Total pages in the pool */
|
|
58
|
+
totalPages: number;
|
|
59
|
+
/** Pages ready for use */
|
|
60
|
+
readyPages: number;
|
|
61
|
+
/** Pages currently in use */
|
|
62
|
+
busyPages: number;
|
|
63
|
+
/** Pages in error state */
|
|
64
|
+
errorPages: number;
|
|
65
|
+
/** Ratio of successful acquisitions to total attempts */
|
|
66
|
+
poolHitRate: number;
|
|
67
|
+
/** Average time to acquire a page in ms */
|
|
68
|
+
avgAcquisitionTimeMs: number;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=page-pool-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-pool-types.d.ts","sourceRoot":"","sources":["../../../src/integrations/browser/page-pool-types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,6BAA6B;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,yBAAyB;IACzB,KAAK,EAAE,SAAS,CAAC;IACjB,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,cAAc,EAAE,MAAM,CAAC;CACxB;AAMD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,aAAa,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,qBAAqB,EAAE,MAAM,CAAC;IAC9B,yDAAyD;IACzD,eAAe,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,eAAO,MAAM,wBAAwB,EAAE,qBAMtC,CAAC;AAMF;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,8BAA8B;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,0BAA0B;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,2BAA2B;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,oBAAoB,EAAE,MAAM,CAAC;CAC9B"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser Page Pool Types
|
|
3
|
+
*
|
|
4
|
+
* Manages concurrent browser pages for parallel E2E test execution.
|
|
5
|
+
* Follows the ConnectionPoolImpl pattern from src/mcp/connection-pool.ts.
|
|
6
|
+
*
|
|
7
|
+
* @module integrations/browser/page-pool-types
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Default page pool configuration
|
|
11
|
+
*/
|
|
12
|
+
export const DEFAULT_PAGE_POOL_CONFIG = {
|
|
13
|
+
maxPages: 6,
|
|
14
|
+
minPages: 1,
|
|
15
|
+
idleTimeoutMs: 120_000,
|
|
16
|
+
healthCheckIntervalMs: 15_000,
|
|
17
|
+
healthThreshold: 0.5,
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=page-pool-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-pool-types.js","sourceRoot":"","sources":["../../../src/integrations/browser/page-pool-types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAqDH;;GAEG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAA0B;IAC7D,QAAQ,EAAE,CAAC;IACX,QAAQ,EAAE,CAAC;IACX,aAAa,EAAE,OAAO;IACtB,qBAAqB,EAAE,MAAM;IAC7B,eAAe,EAAE,GAAG;CACrB,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser Page Pool
|
|
3
|
+
*
|
|
4
|
+
* Manages concurrent browser pages with state tracking for parallel E2E execution.
|
|
5
|
+
* Follows the ConnectionPoolImpl pattern from src/mcp/connection-pool.ts.
|
|
6
|
+
*
|
|
7
|
+
* @module integrations/browser/page-pool
|
|
8
|
+
*/
|
|
9
|
+
import type { PooledPage, BrowserPagePoolConfig, PagePoolStats } from './page-pool-types';
|
|
10
|
+
/**
|
|
11
|
+
* Browser Page Pool
|
|
12
|
+
*
|
|
13
|
+
* Manages a pool of browser pages for concurrent E2E test execution.
|
|
14
|
+
* Uses semaphore pattern for thread-safe acquisition and idle set for O(1) lookup.
|
|
15
|
+
*/
|
|
16
|
+
export declare class BrowserPagePool {
|
|
17
|
+
private readonly pages;
|
|
18
|
+
private readonly readyPages;
|
|
19
|
+
private readonly config;
|
|
20
|
+
private healthCheckInterval;
|
|
21
|
+
private initialized;
|
|
22
|
+
private totalRequests;
|
|
23
|
+
private cacheHits;
|
|
24
|
+
private acquisitionTimes;
|
|
25
|
+
private readonly MAX_SAMPLES;
|
|
26
|
+
private acquireQueue;
|
|
27
|
+
private processing;
|
|
28
|
+
constructor(config?: Partial<BrowserPagePoolConfig>);
|
|
29
|
+
/**
|
|
30
|
+
* Initialize the pool, pre-warming minPages
|
|
31
|
+
*/
|
|
32
|
+
initialize(): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Acquire a ready page from the pool (sync fast path)
|
|
35
|
+
*/
|
|
36
|
+
acquire(): PooledPage | null;
|
|
37
|
+
/**
|
|
38
|
+
* Acquire a page asynchronously (thread-safe for concurrent callers)
|
|
39
|
+
*/
|
|
40
|
+
acquireAsync(): Promise<PooledPage | null>;
|
|
41
|
+
/**
|
|
42
|
+
* Release a page back to the pool.
|
|
43
|
+
* If there are pending acquireAsync waiters, resolves the next one immediately.
|
|
44
|
+
*/
|
|
45
|
+
release(pageId: string): void;
|
|
46
|
+
/**
|
|
47
|
+
* Mark a page as errored
|
|
48
|
+
*/
|
|
49
|
+
markError(pageId: string): void;
|
|
50
|
+
/**
|
|
51
|
+
* Remove errored and timed-out pages, maintain minPages
|
|
52
|
+
*/
|
|
53
|
+
prune(): number;
|
|
54
|
+
/**
|
|
55
|
+
* Get pool statistics
|
|
56
|
+
*/
|
|
57
|
+
getStats(): PagePoolStats;
|
|
58
|
+
/**
|
|
59
|
+
* Shut down the pool and release all resources
|
|
60
|
+
*/
|
|
61
|
+
shutdown(): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Get a page by id (for diagnostics)
|
|
64
|
+
*/
|
|
65
|
+
getPage(pageId: string): PooledPage | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* Get all pages (for diagnostics)
|
|
68
|
+
*/
|
|
69
|
+
getAllPages(): PooledPage[];
|
|
70
|
+
private createPage;
|
|
71
|
+
private processQueue;
|
|
72
|
+
private runHealthChecks;
|
|
73
|
+
private trackAcquisitionTime;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Create a new browser page pool instance
|
|
77
|
+
*/
|
|
78
|
+
export declare function createBrowserPagePool(config?: Partial<BrowserPagePoolConfig>): BrowserPagePool;
|
|
79
|
+
//# sourceMappingURL=page-pool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-pool.d.ts","sourceRoot":"","sources":["../../../src/integrations/browser/page-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAEV,UAAU,EACV,qBAAqB,EACrB,aAAa,EACd,MAAM,mBAAmB,CAAC;AAO3B;;;;;GAKG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IACvD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;IAC/C,OAAO,CAAC,mBAAmB,CAA+C;IAC1E,OAAO,CAAC,WAAW,CAAS;IAG5B,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,gBAAgB,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAO;IAGnC,OAAO,CAAC,YAAY,CAAgD;IACpE,OAAO,CAAC,UAAU,CAAS;gBAEf,MAAM,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC;IAInD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBjC;;OAEG;IACH,OAAO,IAAI,UAAU,GAAG,IAAI;IA8B5B;;OAEG;IACH,YAAY,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAO1C;;;OAGG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAuB7B;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAU/B;;OAEG;IACH,KAAK,IAAI,MAAM;IA2Bf;;OAEG;IACH,QAAQ,IAAI,aAAa;IAkCzB;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB/B;;OAEG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAI/C;;OAEG;IACH,WAAW,IAAI,UAAU,EAAE;IAQ3B,OAAO,CAAC,UAAU;IAiBlB,OAAO,CAAC,YAAY;IAepB,OAAO,CAAC,eAAe;IA0BvB,OAAO,CAAC,oBAAoB;CAM7B;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,GACtC,eAAe,CAEjB"}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser Page Pool
|
|
3
|
+
*
|
|
4
|
+
* Manages concurrent browser pages with state tracking for parallel E2E execution.
|
|
5
|
+
* Follows the ConnectionPoolImpl pattern from src/mcp/connection-pool.ts.
|
|
6
|
+
*
|
|
7
|
+
* @module integrations/browser/page-pool
|
|
8
|
+
*/
|
|
9
|
+
import { randomUUID } from 'crypto';
|
|
10
|
+
import { DEFAULT_PAGE_POOL_CONFIG } from './page-pool-types';
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Browser Page Pool
|
|
13
|
+
// ============================================================================
|
|
14
|
+
/**
|
|
15
|
+
* Browser Page Pool
|
|
16
|
+
*
|
|
17
|
+
* Manages a pool of browser pages for concurrent E2E test execution.
|
|
18
|
+
* Uses semaphore pattern for thread-safe acquisition and idle set for O(1) lookup.
|
|
19
|
+
*/
|
|
20
|
+
export class BrowserPagePool {
|
|
21
|
+
pages = new Map();
|
|
22
|
+
readyPages = new Set();
|
|
23
|
+
config;
|
|
24
|
+
healthCheckInterval = null;
|
|
25
|
+
initialized = false;
|
|
26
|
+
// Performance tracking
|
|
27
|
+
totalRequests = 0;
|
|
28
|
+
cacheHits = 0;
|
|
29
|
+
acquisitionTimes = [];
|
|
30
|
+
MAX_SAMPLES = 100;
|
|
31
|
+
// Semaphore for async acquire
|
|
32
|
+
acquireQueue = [];
|
|
33
|
+
processing = false;
|
|
34
|
+
constructor(config) {
|
|
35
|
+
this.config = { ...DEFAULT_PAGE_POOL_CONFIG, ...config };
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Initialize the pool, pre-warming minPages
|
|
39
|
+
*/
|
|
40
|
+
async initialize() {
|
|
41
|
+
if (this.initialized)
|
|
42
|
+
return;
|
|
43
|
+
for (let i = 0; i < this.config.minPages; i++) {
|
|
44
|
+
this.createPage();
|
|
45
|
+
}
|
|
46
|
+
if (this.config.healthCheckIntervalMs > 0) {
|
|
47
|
+
this.healthCheckInterval = setInterval(() => {
|
|
48
|
+
this.runHealthChecks();
|
|
49
|
+
}, this.config.healthCheckIntervalMs);
|
|
50
|
+
if (this.healthCheckInterval.unref) {
|
|
51
|
+
this.healthCheckInterval.unref();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
this.initialized = true;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Acquire a ready page from the pool (sync fast path)
|
|
58
|
+
*/
|
|
59
|
+
acquire() {
|
|
60
|
+
const start = performance.now();
|
|
61
|
+
this.totalRequests++;
|
|
62
|
+
for (const pageId of this.readyPages) {
|
|
63
|
+
const page = this.pages.get(pageId);
|
|
64
|
+
if (page && page.health >= this.config.healthThreshold) {
|
|
65
|
+
page.state = 'busy';
|
|
66
|
+
page.lastUsedAt = Date.now();
|
|
67
|
+
this.readyPages.delete(pageId);
|
|
68
|
+
this.cacheHits++;
|
|
69
|
+
this.trackAcquisitionTime(performance.now() - start);
|
|
70
|
+
return page;
|
|
71
|
+
}
|
|
72
|
+
this.readyPages.delete(pageId);
|
|
73
|
+
}
|
|
74
|
+
// Try to create a new page if under capacity (not a cache hit — page is new)
|
|
75
|
+
if (this.pages.size < this.config.maxPages) {
|
|
76
|
+
const page = this.createPage();
|
|
77
|
+
page.state = 'busy';
|
|
78
|
+
this.readyPages.delete(page.id);
|
|
79
|
+
this.trackAcquisitionTime(performance.now() - start);
|
|
80
|
+
return page;
|
|
81
|
+
}
|
|
82
|
+
this.trackAcquisitionTime(performance.now() - start);
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Acquire a page asynchronously (thread-safe for concurrent callers)
|
|
87
|
+
*/
|
|
88
|
+
acquireAsync() {
|
|
89
|
+
return new Promise((resolve) => {
|
|
90
|
+
this.acquireQueue.push(resolve);
|
|
91
|
+
this.processQueue();
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Release a page back to the pool.
|
|
96
|
+
* If there are pending acquireAsync waiters, resolves the next one immediately.
|
|
97
|
+
*/
|
|
98
|
+
release(pageId) {
|
|
99
|
+
const page = this.pages.get(pageId);
|
|
100
|
+
if (!page)
|
|
101
|
+
return;
|
|
102
|
+
page.state = 'ready';
|
|
103
|
+
page.lastUsedAt = Date.now();
|
|
104
|
+
page.requestsServed++;
|
|
105
|
+
if (page.health >= this.config.healthThreshold) {
|
|
106
|
+
// If a waiter is queued, give this page directly to them
|
|
107
|
+
if (this.acquireQueue.length > 0) {
|
|
108
|
+
const resolve = this.acquireQueue.shift();
|
|
109
|
+
page.state = 'busy';
|
|
110
|
+
page.lastUsedAt = Date.now();
|
|
111
|
+
this.totalRequests++;
|
|
112
|
+
this.cacheHits++;
|
|
113
|
+
resolve(page);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
this.readyPages.add(pageId);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Mark a page as errored
|
|
121
|
+
*/
|
|
122
|
+
markError(pageId) {
|
|
123
|
+
const page = this.pages.get(pageId);
|
|
124
|
+
if (!page)
|
|
125
|
+
return;
|
|
126
|
+
page.state = 'error';
|
|
127
|
+
page.errorCount++;
|
|
128
|
+
page.health = Math.max(0, page.health - 0.3);
|
|
129
|
+
this.readyPages.delete(pageId);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Remove errored and timed-out pages, maintain minPages
|
|
133
|
+
*/
|
|
134
|
+
prune() {
|
|
135
|
+
const now = Date.now();
|
|
136
|
+
const toRemove = [];
|
|
137
|
+
for (const [id, page] of this.pages) {
|
|
138
|
+
const isError = page.state === 'error' || page.health < this.config.healthThreshold;
|
|
139
|
+
const isIdleExpired = page.state === 'ready' && now - page.lastUsedAt > this.config.idleTimeoutMs;
|
|
140
|
+
if (isError || isIdleExpired) {
|
|
141
|
+
toRemove.push(id);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
for (const id of toRemove) {
|
|
145
|
+
this.pages.delete(id);
|
|
146
|
+
this.readyPages.delete(id);
|
|
147
|
+
}
|
|
148
|
+
// Maintain minimum pages
|
|
149
|
+
while (this.pages.size < this.config.minPages) {
|
|
150
|
+
this.createPage();
|
|
151
|
+
}
|
|
152
|
+
return toRemove.length;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Get pool statistics
|
|
156
|
+
*/
|
|
157
|
+
getStats() {
|
|
158
|
+
let readyCount = 0;
|
|
159
|
+
let busyCount = 0;
|
|
160
|
+
let errorCount = 0;
|
|
161
|
+
for (const page of this.pages.values()) {
|
|
162
|
+
switch (page.state) {
|
|
163
|
+
case 'ready':
|
|
164
|
+
readyCount++;
|
|
165
|
+
break;
|
|
166
|
+
case 'busy':
|
|
167
|
+
busyCount++;
|
|
168
|
+
break;
|
|
169
|
+
case 'error':
|
|
170
|
+
errorCount++;
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
const avg = this.acquisitionTimes.length > 0
|
|
175
|
+
? this.acquisitionTimes.reduce((a, b) => a + b, 0) / this.acquisitionTimes.length
|
|
176
|
+
: 0;
|
|
177
|
+
return {
|
|
178
|
+
totalPages: this.pages.size,
|
|
179
|
+
readyPages: readyCount,
|
|
180
|
+
busyPages: busyCount,
|
|
181
|
+
errorPages: errorCount,
|
|
182
|
+
poolHitRate: this.totalRequests > 0 ? this.cacheHits / this.totalRequests : 0,
|
|
183
|
+
avgAcquisitionTimeMs: avg,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Shut down the pool and release all resources
|
|
188
|
+
*/
|
|
189
|
+
async shutdown() {
|
|
190
|
+
if (this.healthCheckInterval) {
|
|
191
|
+
clearInterval(this.healthCheckInterval);
|
|
192
|
+
this.healthCheckInterval = null;
|
|
193
|
+
}
|
|
194
|
+
for (const page of this.pages.values()) {
|
|
195
|
+
page.state = 'closed';
|
|
196
|
+
}
|
|
197
|
+
this.pages.clear();
|
|
198
|
+
this.readyPages.clear();
|
|
199
|
+
this.initialized = false;
|
|
200
|
+
// Reject any pending acquire requests
|
|
201
|
+
for (const resolve of this.acquireQueue) {
|
|
202
|
+
resolve(null);
|
|
203
|
+
}
|
|
204
|
+
this.acquireQueue = [];
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Get a page by id (for diagnostics)
|
|
208
|
+
*/
|
|
209
|
+
getPage(pageId) {
|
|
210
|
+
return this.pages.get(pageId);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Get all pages (for diagnostics)
|
|
214
|
+
*/
|
|
215
|
+
getAllPages() {
|
|
216
|
+
return Array.from(this.pages.values());
|
|
217
|
+
}
|
|
218
|
+
// ==========================================================================
|
|
219
|
+
// Private
|
|
220
|
+
// ==========================================================================
|
|
221
|
+
createPage() {
|
|
222
|
+
const id = `page-${randomUUID().split('-')[0]}`;
|
|
223
|
+
const now = Date.now();
|
|
224
|
+
const page = {
|
|
225
|
+
id,
|
|
226
|
+
state: 'ready',
|
|
227
|
+
createdAt: now,
|
|
228
|
+
lastUsedAt: now,
|
|
229
|
+
health: 1.0,
|
|
230
|
+
errorCount: 0,
|
|
231
|
+
requestsServed: 0,
|
|
232
|
+
};
|
|
233
|
+
this.pages.set(id, page);
|
|
234
|
+
this.readyPages.add(id);
|
|
235
|
+
return page;
|
|
236
|
+
}
|
|
237
|
+
processQueue() {
|
|
238
|
+
if (this.processing || this.acquireQueue.length === 0)
|
|
239
|
+
return;
|
|
240
|
+
this.processing = true;
|
|
241
|
+
const resolve = this.acquireQueue.shift();
|
|
242
|
+
try {
|
|
243
|
+
resolve(this.acquire());
|
|
244
|
+
}
|
|
245
|
+
finally {
|
|
246
|
+
this.processing = false;
|
|
247
|
+
if (this.acquireQueue.length > 0) {
|
|
248
|
+
setImmediate(() => this.processQueue());
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
runHealthChecks() {
|
|
253
|
+
for (const page of this.pages.values()) {
|
|
254
|
+
if (page.state === 'closed')
|
|
255
|
+
continue;
|
|
256
|
+
// Degrade health based on error rate
|
|
257
|
+
const total = page.requestsServed + page.errorCount;
|
|
258
|
+
if (total > 0) {
|
|
259
|
+
const errorRate = page.errorCount / total;
|
|
260
|
+
page.health = Math.max(0, 1 - errorRate * 0.8);
|
|
261
|
+
}
|
|
262
|
+
const wasReady = this.readyPages.has(page.id);
|
|
263
|
+
const isHealthy = page.health >= this.config.healthThreshold;
|
|
264
|
+
if (page.state === 'ready' && !isHealthy) {
|
|
265
|
+
page.state = 'error';
|
|
266
|
+
this.readyPages.delete(page.id);
|
|
267
|
+
}
|
|
268
|
+
else if (page.state === 'error' && isHealthy && !wasReady) {
|
|
269
|
+
page.state = 'ready';
|
|
270
|
+
this.readyPages.add(page.id);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
this.prune();
|
|
274
|
+
}
|
|
275
|
+
trackAcquisitionTime(ms) {
|
|
276
|
+
this.acquisitionTimes.push(ms);
|
|
277
|
+
if (this.acquisitionTimes.length > this.MAX_SAMPLES) {
|
|
278
|
+
this.acquisitionTimes.shift();
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Create a new browser page pool instance
|
|
284
|
+
*/
|
|
285
|
+
export function createBrowserPagePool(config) {
|
|
286
|
+
return new BrowserPagePool(config);
|
|
287
|
+
}
|
|
288
|
+
//# sourceMappingURL=page-pool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-pool.js","sourceRoot":"","sources":["../../../src/integrations/browser/page-pool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resource Blocking for Browser Automation
|
|
3
|
+
*
|
|
4
|
+
* Inspired by Scrapling's resource filtering patterns.
|
|
5
|
+
* Blocks non-essential resources (images, fonts, tracking) during E2E tests
|
|
6
|
+
* to improve page load speed and reduce flakiness.
|
|
7
|
+
*
|
|
8
|
+
* @module integrations/browser/resource-blocking
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Categories of resources that can be blocked
|
|
12
|
+
*/
|
|
13
|
+
export type ResourceCategory = 'image' | 'font' | 'media' | 'stylesheet' | 'tracking' | 'advertising' | 'websocket';
|
|
14
|
+
/**
|
|
15
|
+
* Configuration for resource blocking
|
|
16
|
+
*/
|
|
17
|
+
export interface ResourceBlockingConfig {
|
|
18
|
+
/** Enable resource blocking */
|
|
19
|
+
enabled: boolean;
|
|
20
|
+
/** Resource categories to block */
|
|
21
|
+
blockedCategories: ResourceCategory[];
|
|
22
|
+
/** URL patterns to always allow (overrides blocked categories) */
|
|
23
|
+
allowPatterns?: string[];
|
|
24
|
+
/** URL patterns to always block (in addition to categories) */
|
|
25
|
+
blockPatterns?: string[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Preset names for resource blocking configurations
|
|
29
|
+
*/
|
|
30
|
+
export type ResourceBlockingPreset = 'functional' | 'visual' | 'performance';
|
|
31
|
+
/**
|
|
32
|
+
* Determine if a request should be blocked based on URL, resource type, and config.
|
|
33
|
+
*
|
|
34
|
+
* @param url - The request URL
|
|
35
|
+
* @param resourceType - The CDP/Playwright resource type string (e.g., 'image', 'script', 'font')
|
|
36
|
+
* @param config - The resource blocking configuration
|
|
37
|
+
* @returns true if the request should be blocked
|
|
38
|
+
*/
|
|
39
|
+
export declare function shouldBlockRequest(url: string, resourceType: string, config: ResourceBlockingConfig): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Get a resource blocking preset by name.
|
|
42
|
+
*
|
|
43
|
+
* @param name - Preset name or a ResourceBlockingConfig object (passed through)
|
|
44
|
+
* @returns A ResourceBlockingConfig
|
|
45
|
+
*/
|
|
46
|
+
export declare function getResourceBlockingPreset(name: ResourceBlockingPreset | ResourceBlockingConfig): ResourceBlockingConfig;
|
|
47
|
+
//# sourceMappingURL=resource-blocking.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-blocking.d.ts","sourceRoot":"","sources":["../../../src/integrations/browser/resource-blocking.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH;;GAEG;AACH,MAAM,MAAM,gBAAgB,GACxB,OAAO,GACP,MAAM,GACN,OAAO,GACP,YAAY,GACZ,UAAU,GACV,aAAa,GACb,WAAW,CAAC;AAEhB;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,+BAA+B;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,mCAAmC;IACnC,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;IACtC,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,YAAY,GAAG,QAAQ,GAAG,aAAa,CAAC;AAsG7E;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAuCT;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,sBAAsB,GAAG,sBAAsB,GACpD,sBAAsB,CAUxB"}
|