@purepageio/fetch-engines 0.1.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 (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +205 -0
  3. package/dist/FetchEngine.d.ts +46 -0
  4. package/dist/FetchEngine.d.ts.map +1 -0
  5. package/dist/FetchEngine.js +137 -0
  6. package/dist/FetchEngine.js.map +1 -0
  7. package/dist/FetchEngine.test.d.ts +2 -0
  8. package/dist/FetchEngine.test.d.ts.map +1 -0
  9. package/dist/FetchEngine.test.js +44 -0
  10. package/dist/FetchEngine.test.js.map +1 -0
  11. package/dist/HybridEngine.d.ts +15 -0
  12. package/dist/HybridEngine.d.ts.map +1 -0
  13. package/dist/HybridEngine.js +45 -0
  14. package/dist/HybridEngine.js.map +1 -0
  15. package/dist/IEngine.d.ts +22 -0
  16. package/dist/IEngine.d.ts.map +1 -0
  17. package/dist/IEngine.js +2 -0
  18. package/dist/IEngine.js.map +1 -0
  19. package/dist/PlaywrightEngine.d.ts +88 -0
  20. package/dist/PlaywrightEngine.d.ts.map +1 -0
  21. package/dist/PlaywrightEngine.js +484 -0
  22. package/dist/PlaywrightEngine.js.map +1 -0
  23. package/dist/PlaywrightEngine.test.d.ts +2 -0
  24. package/dist/PlaywrightEngine.test.d.ts.map +1 -0
  25. package/dist/PlaywrightEngine.test.js +299 -0
  26. package/dist/PlaywrightEngine.test.js.map +1 -0
  27. package/dist/PuppeteerEngine.d.ts +21 -0
  28. package/dist/PuppeteerEngine.d.ts.map +1 -0
  29. package/dist/PuppeteerEngine.js +412 -0
  30. package/dist/PuppeteerEngine.js.map +1 -0
  31. package/dist/browser/BrowserPool.d.ts +29 -0
  32. package/dist/browser/BrowserPool.d.ts.map +1 -0
  33. package/dist/browser/BrowserPool.js +378 -0
  34. package/dist/browser/BrowserPool.js.map +1 -0
  35. package/dist/browser/PlaywrightBrowserPool.d.ts +78 -0
  36. package/dist/browser/PlaywrightBrowserPool.d.ts.map +1 -0
  37. package/dist/browser/PlaywrightBrowserPool.js +429 -0
  38. package/dist/browser/PlaywrightBrowserPool.js.map +1 -0
  39. package/dist/browser/PlaywrightBrowserPool.test.d.ts +2 -0
  40. package/dist/browser/PlaywrightBrowserPool.test.d.ts.map +1 -0
  41. package/dist/browser/PlaywrightBrowserPool.test.js +422 -0
  42. package/dist/browser/PlaywrightBrowserPool.test.js.map +1 -0
  43. package/dist/errors.d.ts +20 -0
  44. package/dist/errors.d.ts.map +1 -0
  45. package/dist/errors.js +30 -0
  46. package/dist/errors.js.map +1 -0
  47. package/dist/index.d.ts +8 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +5 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/types.d.ts +151 -0
  52. package/dist/types.d.ts.map +1 -0
  53. package/dist/types.js +2 -0
  54. package/dist/types.js.map +1 -0
  55. package/package.json +72 -0
@@ -0,0 +1,422 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
+ import { PlaywrightBrowserPool } from "./PlaywrightBrowserPool.js";
3
+ import { chromium } from "playwright"; // We need to mock methods on this
4
+ import EventEmitter from "events";
5
+ // --- Mock Playwright Components --- //
6
+ // Mock the top-level chromium object and its launch method
7
+ vi.mock("playwright", async (importOriginal) => {
8
+ const actual = await importOriginal();
9
+ return {
10
+ ...actual, // Keep other exports like types
11
+ chromium: {
12
+ launch: vi.fn(),
13
+ // Mock other chromium methods if needed
14
+ },
15
+ };
16
+ });
17
+ // Helper to create deep mocks for Browser, Context, Page
18
+ const createMockPage = () => {
19
+ const pageEmitter = new EventEmitter();
20
+ const mockPage = {
21
+ close: vi.fn().mockImplementation(() => {
22
+ pageEmitter.emit("close");
23
+ return Promise.resolve();
24
+ }),
25
+ isClosed: vi.fn().mockReturnValue(false),
26
+ context: vi.fn(), // Will be set later
27
+ on: pageEmitter.on.bind(pageEmitter), // Use EventEmitter for on/emit
28
+ once: pageEmitter.once.bind(pageEmitter),
29
+ off: pageEmitter.off.bind(pageEmitter),
30
+ // Add other methods/properties as needed by the pool
31
+ };
32
+ return mockPage;
33
+ };
34
+ const createMockContext = (mockBrowser) => {
35
+ const contextEmitter = new EventEmitter();
36
+ const mockContext = {
37
+ newPage: vi.fn().mockResolvedValue(createMockPage()),
38
+ close: vi.fn().mockImplementation(() => {
39
+ contextEmitter.emit("close");
40
+ return Promise.resolve();
41
+ }),
42
+ browser: vi.fn().mockReturnValue(mockBrowser),
43
+ pages: vi.fn().mockReturnValue([]), // Initially no pages
44
+ route: vi.fn().mockResolvedValue(undefined),
45
+ on: contextEmitter.on.bind(contextEmitter),
46
+ once: contextEmitter.once.bind(contextEmitter),
47
+ off: contextEmitter.off.bind(contextEmitter),
48
+ // Add other methods as needed
49
+ };
50
+ // Link pages back to context
51
+ vi.mocked(mockContext.newPage).mockImplementation(async () => {
52
+ const page = createMockPage();
53
+ vi.spyOn(page, "context").mockReturnValue(mockContext);
54
+ const currentPages = mockContext.pages();
55
+ vi.spyOn(mockContext, "pages").mockReturnValue([...currentPages, page]);
56
+ // Simulate page close removing it from context
57
+ page.on("close", () => {
58
+ const updatedPages = mockContext.pages().filter((p) => p !== page);
59
+ vi.spyOn(mockContext, "pages").mockReturnValue(updatedPages);
60
+ });
61
+ return page;
62
+ });
63
+ return mockContext;
64
+ };
65
+ const createMockBrowser = () => {
66
+ const browserEmitter = new EventEmitter();
67
+ const mockBrowser = {
68
+ newContext: vi.fn(), // Implementation below
69
+ close: vi.fn().mockImplementation(() => {
70
+ browserEmitter.emit("disconnected");
71
+ return Promise.resolve();
72
+ }),
73
+ isConnected: vi.fn().mockReturnValue(true),
74
+ on: browserEmitter.on.bind(browserEmitter),
75
+ once: browserEmitter.once.bind(browserEmitter),
76
+ off: browserEmitter.off.bind(browserEmitter),
77
+ // Add other methods as needed
78
+ };
79
+ // Setup context creation
80
+ vi.mocked(mockBrowser.newContext).mockImplementation(async () => {
81
+ return createMockContext(mockBrowser);
82
+ });
83
+ return mockBrowser;
84
+ };
85
+ // --- Tests --- //
86
+ describe("PlaywrightBrowserPool", () => {
87
+ let pool;
88
+ // Mock implementation for chromium.launch
89
+ let mockLaunch;
90
+ beforeEach(() => {
91
+ vi.clearAllMocks(); // Clear mocks between tests
92
+ vi.useFakeTimers(); // Use fake timers for health checks, etc.
93
+ // Reset the mock for chromium.launch for each test
94
+ mockLaunch = vi.mocked(chromium.launch).mockImplementation(async () => {
95
+ return createMockBrowser();
96
+ });
97
+ });
98
+ afterEach(async () => {
99
+ vi.useRealTimers(); // Restore real timers
100
+ if (pool) {
101
+ await pool.cleanup(); // Ensure pool resources are released
102
+ }
103
+ });
104
+ describe("Initialization", { timeout: 60000 }, () => {
105
+ it("should initialize with default settings and create one browser instance", async () => {
106
+ pool = new PlaywrightBrowserPool();
107
+ await pool.initialize();
108
+ expect(mockLaunch).toHaveBeenCalledTimes(1);
109
+ expect(mockLaunch).toHaveBeenCalledWith(expect.objectContaining({ headless: true }));
110
+ const metrics = pool.getMetrics();
111
+ expect(metrics).toHaveLength(1);
112
+ expect(metrics[0].isHealthy).toBe(true);
113
+ await pool.cleanup(); // Clean up this instance
114
+ });
115
+ it("should initialize in headed mode if specified", async () => {
116
+ pool = new PlaywrightBrowserPool({
117
+ maxBrowsers: 1,
118
+ maxPagesPerContext: 1,
119
+ maxBrowserAge: 30000,
120
+ healthCheckInterval: 10000,
121
+ useHeadedMode: true,
122
+ });
123
+ await pool.initialize();
124
+ expect(mockLaunch).toHaveBeenCalledTimes(1);
125
+ expect(mockLaunch).toHaveBeenCalledWith(expect.objectContaining({ headless: false }));
126
+ await pool.cleanup();
127
+ });
128
+ it("should not initialize more than maxBrowsers", async () => {
129
+ pool = new PlaywrightBrowserPool({ maxBrowsers: 2 }); // Max 2 browsers
130
+ await pool.initialize();
131
+ expect(mockLaunch).toHaveBeenCalledTimes(2); // ensureMinimumInstances aims for max
132
+ await pool.cleanup();
133
+ });
134
+ it("should start health checks after initialization", async () => {
135
+ const healthCheckInterval = 5000;
136
+ pool = new PlaywrightBrowserPool({
137
+ maxBrowsers: 1,
138
+ maxPagesPerContext: 1,
139
+ maxBrowserAge: 30000,
140
+ healthCheckInterval,
141
+ });
142
+ const healthCheckSpy = vi.spyOn(pool, "healthCheck");
143
+ await pool.initialize();
144
+ expect(healthCheckSpy).not.toHaveBeenCalled(); // Doesn't run immediately
145
+ await vi.advanceTimersByTimeAsync(healthCheckInterval + 100);
146
+ expect(healthCheckSpy).toHaveBeenCalledTimes(1);
147
+ await vi.advanceTimersByTimeAsync(healthCheckInterval);
148
+ expect(healthCheckSpy).toHaveBeenCalledTimes(2);
149
+ await pool.cleanup(); // Stops timer
150
+ healthCheckSpy.mockRestore();
151
+ });
152
+ });
153
+ describe("Page Acquisition", () => {
154
+ it("should acquire a page from an existing healthy instance", async () => {
155
+ pool = new PlaywrightBrowserPool({
156
+ maxBrowsers: 1,
157
+ maxPagesPerContext: 2,
158
+ });
159
+ await pool.initialize();
160
+ expect(mockLaunch).toHaveBeenCalledTimes(1);
161
+ // Acquire first page
162
+ const page1 = await pool.acquirePage();
163
+ expect(page1).toBeDefined();
164
+ expect(page1.isClosed()).toBe(false);
165
+ // Check metrics (approximate)
166
+ const metrics1 = pool.getMetrics();
167
+ expect(metrics1[0].activePages).toBe(1);
168
+ const initialLastUsed = metrics1[0].lastUsed.getTime();
169
+ // Acquire second page from the same instance
170
+ vi.advanceTimersByTime(10); // Ensure time advances for lastUsed check
171
+ const page2 = await pool.acquirePage();
172
+ expect(page2).toBeDefined();
173
+ expect(page2.isClosed()).toBe(false);
174
+ expect(page1).not.toBe(page2);
175
+ // Check metrics again
176
+ const metrics2 = pool.getMetrics();
177
+ expect(metrics2[0].activePages).toBe(2);
178
+ expect(metrics2[0].lastUsed.getTime()).toBeGreaterThan(initialLastUsed);
179
+ // Cleanup pages (using the pool's release method)
180
+ await pool.releasePage(page1);
181
+ await pool.releasePage(page2);
182
+ // Verify pages are closed and metrics updated
183
+ // NOTE: The mock page close needs to trigger the event correctly
184
+ // and the pool needs to listen to remove from activePages count.
185
+ // This part might require adjusting mocks if it fails.
186
+ // expect(page1.isClosed()).toBe(true);
187
+ // expect(page2.isClosed()).toBe(true);
188
+ // const metrics3 = pool.getMetrics();
189
+ // expect(metrics3[0].activePages).toBe(0);
190
+ });
191
+ it("should trigger new instance creation if pool < max and existing is full", async () => {
192
+ pool = new PlaywrightBrowserPool({
193
+ maxBrowsers: 2,
194
+ maxPagesPerContext: 1,
195
+ });
196
+ await pool.initialize();
197
+ expect(mockLaunch).toHaveBeenCalledTimes(2); // Pool initializes up to maxBrowsers
198
+ expect(pool.getMetrics().length).toBe(2);
199
+ // Acquire page from first instance
200
+ const page1 = await pool.acquirePage();
201
+ expect(page1).toBeDefined();
202
+ const metrics1 = pool.getMetrics();
203
+ // Find which instance got the page
204
+ const instance1Index = metrics1.findIndex((m) => m.activePages === 1);
205
+ expect(instance1Index).toBeGreaterThanOrEqual(0); // Should be 0 or 1
206
+ // Acquire page from second instance (first one is now full)
207
+ const page2 = await pool.acquirePage();
208
+ expect(page2).toBeDefined();
209
+ expect(page1.context()).not.toBe(page2.context()); // Should be from different contexts/browsers
210
+ const metrics2 = pool.getMetrics();
211
+ expect(metrics2[0].activePages + metrics2[1].activePages).toBe(2);
212
+ expect(metrics2.filter((m) => m.activePages === 1).length).toBe(2); // Both instances have 1 page
213
+ // Cleanup
214
+ await pool.releasePage(page1);
215
+ await pool.releasePage(page2);
216
+ });
217
+ it("should fail acquisition if pool is full and all instances are at max pages", async () => {
218
+ pool = new PlaywrightBrowserPool({
219
+ maxBrowsers: 1,
220
+ maxPagesPerContext: 1,
221
+ }); // Pool full after 1 page
222
+ await pool.initialize();
223
+ expect(mockLaunch).toHaveBeenCalledTimes(1);
224
+ // Acquire the only available page slot
225
+ const page1 = await pool.acquirePage();
226
+ expect(page1).toBeDefined();
227
+ expect(pool.getMetrics()[0].activePages).toBe(1);
228
+ // Attempt to acquire another page - should fail
229
+ await expect(pool.acquirePage()).rejects.toThrow(/Failed to acquire Playwright page.*pool may be unhealthy or overloaded/i);
230
+ // Check that metrics didn't change
231
+ expect(pool.getMetrics()[0].activePages).toBe(1);
232
+ // Cleanup
233
+ await pool.releasePage(page1);
234
+ });
235
+ it("should fail acquisition if pool is unhealthy or becomes unhealthy", async () => {
236
+ pool = new PlaywrightBrowserPool({
237
+ maxBrowsers: 1,
238
+ maxPagesPerContext: 1,
239
+ });
240
+ await pool.initialize();
241
+ expect(mockLaunch).toHaveBeenCalledTimes(1);
242
+ // Access internal pool array (use type assertion for needed properties)
243
+ const browserInstance = pool.pool[0];
244
+ // Manually mark the only instance as unhealthy
245
+ browserInstance.isHealthy = false;
246
+ // Attempt to acquire a page - should fail
247
+ await expect(pool.acquirePage()).rejects.toThrow(/Failed to acquire Playwright page.*pool may be unhealthy or overloaded/i);
248
+ // Instance should still be unhealthy, no pages acquired
249
+ expect(browserInstance.isHealthy).toBe(false);
250
+ expect(browserInstance.pages.size).toBe(0);
251
+ expect(pool.getMetrics()[0].activePages).toBe(0);
252
+ });
253
+ });
254
+ describe("Health Checks", { timeout: 60000 }, () => {
255
+ it("should remove an instance due to max age", async () => {
256
+ const maxAge = 10000; // 10 seconds
257
+ pool = new PlaywrightBrowserPool({
258
+ maxBrowsers: 1,
259
+ maxBrowserAge: maxAge,
260
+ healthCheckInterval: 1000,
261
+ });
262
+ await pool.initialize();
263
+ expect(mockLaunch).toHaveBeenCalledTimes(1);
264
+ expect(pool.getMetrics().length).toBe(1);
265
+ const initialInstanceId = pool.getMetrics()[0].id;
266
+ // Advance time past max age but before next health check
267
+ await vi.advanceTimersByTimeAsync(maxAge - 500);
268
+ expect(pool.getMetrics().length).toBe(1); // Still there
269
+ // Advance time to trigger health check after max age
270
+ await vi.advanceTimersByTimeAsync(1500);
271
+ // Health check should have run and removed the old instance
272
+ // and pool should have created a new one
273
+ expect(pool.getMetrics().length).toBe(1);
274
+ const newInstanceId = pool.getMetrics()[0].id;
275
+ expect(newInstanceId).not.toBe(initialInstanceId);
276
+ expect(mockLaunch).toHaveBeenCalledTimes(2); // One initial, one replacement
277
+ });
278
+ it("should remove an instance due to idle timeout (if pool size > 1)", async () => {
279
+ const idleTimeout = 5000; // Use a shorter timeout for testing
280
+ pool = new PlaywrightBrowserPool({
281
+ maxBrowsers: 2,
282
+ healthCheckInterval: 1000,
283
+ });
284
+ // Manually set idle timeout AFTER creating the instance
285
+ pool.maxIdleTime = idleTimeout;
286
+ await pool.initialize();
287
+ expect(mockLaunch).toHaveBeenCalledTimes(2); // Pool starts with 2 instances
288
+ expect(pool.getMetrics().length).toBe(2);
289
+ const instanceIds = pool.getMetrics().map((m) => m.id);
290
+ // Acquire and release a page from one instance to reset its idle timer
291
+ const page = await pool.acquirePage();
292
+ const activeInstanceMetric = pool.getMetrics().find((m) => m.activePages === 1);
293
+ expect(activeInstanceMetric).toBeDefined();
294
+ const activeInstanceId = activeInstanceMetric.id;
295
+ await pool.releasePage(page);
296
+ expect(pool.getMetrics().find((m) => m.id === activeInstanceId)?.activePages).toBe(0);
297
+ // Advance time just past the idle timeout
298
+ await vi.advanceTimersByTimeAsync(idleTimeout + 100);
299
+ // Let health check run
300
+ await vi.advanceTimersByTimeAsync(1000); // Trigger health check interval
301
+ // The instance that *wasn't* used should have been removed due to idle timeout
302
+ expect(pool.getMetrics().length).toBe(1);
303
+ const remainingInstanceMetric = pool.getMetrics()[0];
304
+ expect(remainingInstanceMetric.id).toBe(activeInstanceId);
305
+ expect(instanceIds).toContain(remainingInstanceMetric.id);
306
+ expect(mockLaunch).toHaveBeenCalledTimes(2); // No new instance created yet
307
+ });
308
+ it("should remove an instance due to browser disconnect event", async () => {
309
+ pool = new PlaywrightBrowserPool({
310
+ maxBrowsers: 1,
311
+ healthCheckInterval: 1000,
312
+ });
313
+ await pool.initialize();
314
+ expect(pool.getMetrics().length).toBe(1);
315
+ const browserInstance = pool.pool[0]; // Structural type
316
+ const initialInstanceId = pool.getMetrics()[0].id;
317
+ // Simulate the browser disconnecting (needs access to the mock browser's emitter)
318
+ // Find the mock browser associated with the instance
319
+ const mockBrowser = browserInstance.browser;
320
+ expect(mockBrowser).toBeDefined();
321
+ // Emit the 'disconnected' event on the mock browser
322
+ mockBrowser.emit("disconnected");
323
+ // Check that the instance is marked unhealthy immediately by the event handler
324
+ expect(browserInstance.isHealthy).toBe(false);
325
+ // Advance time to trigger health check
326
+ await vi.advanceTimersByTimeAsync(1100);
327
+ // Health check should remove the unhealthy instance and create a new one
328
+ expect(pool.getMetrics().length).toBe(1);
329
+ expect(pool.getMetrics()[0].id).not.toBe(initialInstanceId);
330
+ expect(mockLaunch).toHaveBeenCalledTimes(2); // Initial + replacement
331
+ });
332
+ it("should remove an instance due to failed health check (isConnected)", async () => {
333
+ pool = new PlaywrightBrowserPool({
334
+ maxBrowsers: 1,
335
+ healthCheckInterval: 1000,
336
+ });
337
+ await pool.initialize();
338
+ expect(pool.getMetrics().length).toBe(1);
339
+ const browserInstance = pool.pool[0]; // Structural type
340
+ const initialInstanceId = pool.getMetrics()[0].id;
341
+ // Mock the isConnected method on the specific mock browser instance
342
+ const mockBrowser = browserInstance.browser;
343
+ vi.spyOn(mockBrowser, "isConnected").mockReturnValue(false);
344
+ // Advance time to trigger health check
345
+ await vi.advanceTimersByTimeAsync(1100);
346
+ // Health check should detect disconnected state, remove instance, and create a new one
347
+ expect(pool.getMetrics().length).toBe(1);
348
+ expect(pool.getMetrics()[0].id).not.toBe(initialInstanceId);
349
+ expect(mockLaunch).toHaveBeenCalledTimes(2); // Initial + replacement
350
+ // Restore mock
351
+ vi.mocked(mockBrowser.isConnected).mockRestore();
352
+ });
353
+ it("should keep healthy instances during health check", async () => {
354
+ pool = new PlaywrightBrowserPool({
355
+ maxBrowsers: 2,
356
+ healthCheckInterval: 1000,
357
+ });
358
+ await pool.initialize();
359
+ expect(mockLaunch).toHaveBeenCalledTimes(2);
360
+ const initialMetrics = pool.getMetrics();
361
+ expect(initialMetrics.length).toBe(2);
362
+ const initialIds = initialMetrics.map((m) => m.id).sort();
363
+ // Ensure mocks are healthy
364
+ const instance1 = pool.pool[0];
365
+ const instance2 = pool.pool[1];
366
+ vi.spyOn(instance1.browser, "isConnected").mockReturnValue(true);
367
+ vi.spyOn(instance2.browser, "isConnected").mockReturnValue(true);
368
+ // Advance time to trigger multiple health checks
369
+ await vi.advanceTimersByTimeAsync(3500);
370
+ // Verify instances are still present and healthy (mockLaunch not called again)
371
+ const finalMetrics = pool.getMetrics();
372
+ expect(finalMetrics.length).toBe(2);
373
+ const finalIds = finalMetrics.map((m) => m.id).sort();
374
+ expect(finalIds).toEqual(initialIds);
375
+ expect(mockLaunch).toHaveBeenCalledTimes(2); // No replacements should have occurred
376
+ // Restore mocks
377
+ vi.mocked(instance1.browser.isConnected).mockRestore();
378
+ vi.mocked(instance2.browser.isConnected).mockRestore();
379
+ });
380
+ it("should replenish instances after removal to maintain pool size", async () => {
381
+ pool = new PlaywrightBrowserPool({
382
+ maxBrowsers: 2,
383
+ healthCheckInterval: 1000,
384
+ });
385
+ await pool.initialize();
386
+ expect(mockLaunch).toHaveBeenCalledTimes(2);
387
+ expect(pool.getMetrics().length).toBe(2);
388
+ const initialIds = pool.getMetrics().map((m) => m.id);
389
+ // Manually remove one instance (simulate external issue or previous health check removal)
390
+ const instanceToRemove = pool.pool[0];
391
+ await pool.closeAndRemoveInstance(instanceToRemove); // Use internal method for testing
392
+ expect(pool.getMetrics().length).toBe(1); // Should be 1 temporarily
393
+ // Advance time to trigger health check
394
+ await vi.advanceTimersByTimeAsync(1100);
395
+ // Health check should detect the shortage and create a new instance
396
+ expect(pool.getMetrics().length).toBe(2);
397
+ expect(mockLaunch).toHaveBeenCalledTimes(3); // Initial 2 + 1 replacement
398
+ // Verify the remaining original instance and one new instance are present
399
+ const finalIds = pool.getMetrics().map((m) => m.id);
400
+ const removedId = initialIds[0];
401
+ const keptId = initialIds[1];
402
+ expect(finalIds).toContain(keptId);
403
+ expect(finalIds).not.toContain(removedId);
404
+ expect(finalIds.length).toBe(2);
405
+ });
406
+ });
407
+ describe("Cleanup", () => {
408
+ it.todo("should be implemented");
409
+ // TODO: Add tests for cleanup
410
+ // - Cleanup closes all browser instances
411
+ // - Cleanup stops health checks
412
+ // - Cleanup prevents further acquisitions
413
+ });
414
+ describe("Error Handling", () => {
415
+ it.todo("should be implemented");
416
+ // TODO: Add tests for error scenarios
417
+ // - chromium.launch fails
418
+ // - browser.newContext fails
419
+ // - context.newPage fails
420
+ });
421
+ });
422
+ //# sourceMappingURL=PlaywrightBrowserPool.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlaywrightBrowserPool.test.js","sourceRoot":"","sources":["../../src/browser/PlaywrightBrowserPool.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Custom error class for fetch-related errors.
3
+ */
4
+ export declare class FetchError extends Error {
5
+ /** A specific error code (e.g., ERR_NAVIGATION_TIMEOUT, ERR_HTTP_ERROR). */
6
+ readonly code?: string;
7
+ /** The original error object, if available. */
8
+ readonly originalError?: Error;
9
+ /** HTTP status code, if relevant. */
10
+ readonly statusCode?: number;
11
+ /**
12
+ * Creates an instance of FetchError.
13
+ * @param message The error message.
14
+ * @param code Optional error code string.
15
+ * @param originalError Optional original error.
16
+ * @param statusCode Optional HTTP status code.
17
+ */
18
+ constructor(message: string, code?: string, originalError?: Error, statusCode?: number);
19
+ }
20
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,UAAW,SAAQ,KAAK;IACnC,4EAA4E;IAC5E,SAAgB,IAAI,CAAC,EAAE,MAAM,CAAC;IAC9B,+CAA+C;IAC/C,SAAgB,aAAa,CAAC,EAAE,KAAK,CAAC;IACtC,qCAAqC;IACrC,SAAgB,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpC;;;;;;OAMG;gBACS,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,EAAE,MAAM;CAYvF"}
package/dist/errors.js ADDED
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Custom error class for fetch-related errors.
3
+ */
4
+ export class FetchError extends Error {
5
+ /** A specific error code (e.g., ERR_NAVIGATION_TIMEOUT, ERR_HTTP_ERROR). */
6
+ code;
7
+ /** The original error object, if available. */
8
+ originalError;
9
+ /** HTTP status code, if relevant. */
10
+ statusCode;
11
+ /**
12
+ * Creates an instance of FetchError.
13
+ * @param message The error message.
14
+ * @param code Optional error code string.
15
+ * @param originalError Optional original error.
16
+ * @param statusCode Optional HTTP status code.
17
+ */
18
+ constructor(message, code, originalError, statusCode) {
19
+ super(message);
20
+ this.name = "FetchError";
21
+ this.code = code;
22
+ this.originalError = originalError;
23
+ this.statusCode = statusCode;
24
+ // Maintain proper stack trace
25
+ if (Error.captureStackTrace) {
26
+ Error.captureStackTrace(this, FetchError);
27
+ }
28
+ }
29
+ }
30
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnC,4EAA4E;IAC5D,IAAI,CAAU;IAC9B,+CAA+C;IAC/B,aAAa,CAAS;IACtC,qCAAqC;IACrB,UAAU,CAAU;IAEpC;;;;;;OAMG;IACH,YAAY,OAAe,EAAE,IAAa,EAAE,aAAqB,EAAE,UAAmB;QACpF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAE7B,8BAA8B;QAC9B,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC5B,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,8 @@
1
+ import type { IEngine } from "./IEngine.js";
2
+ import { FetchEngine } from "./FetchEngine.js";
3
+ import { PlaywrightEngine } from "./PlaywrightEngine.js";
4
+ import type { HTMLFetchResult, BrowserMetrics } from "./types.js";
5
+ export type { IEngine, HTMLFetchResult, BrowserMetrics };
6
+ export { FetchEngine, PlaywrightEngine };
7
+ export * from "./HybridEngine.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAElE,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,CAAC;AACzC,cAAc,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ import { FetchEngine } from "./FetchEngine.js";
2
+ import { PlaywrightEngine } from "./PlaywrightEngine.js";
3
+ export { FetchEngine, PlaywrightEngine };
4
+ export * from "./HybridEngine.js"; // Export the new engine
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAIzD,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,CAAC;AACzC,cAAc,mBAAmB,CAAC,CAAC,wBAAwB"}