@dev-blinq/cucumber_client 1.0.1595-dev → 1.0.1597-dev

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.
@@ -214,9 +214,8 @@ export class PublishService {
214
214
  export class RemoteBrowserService extends EventEmitter {
215
215
  CDP_CONNECT_URL;
216
216
  context;
217
- // stableTabId, Page Info
218
217
  pages = new Map();
219
- _selectedPageId = null; // This will be a stableTabId
218
+ _selectedPageId = null;
220
219
  constructor({ CDP_CONNECT_URL, context }) {
221
220
  super();
222
221
  this.CDP_CONNECT_URL = CDP_CONNECT_URL;
@@ -228,15 +227,46 @@ export class RemoteBrowserService extends EventEmitter {
228
227
  const timestamp = new Date().toISOString();
229
228
  console.log(`[${timestamp}] [RemoteBrowserService] ${message}`, data ? JSON.stringify(data, null, 2) : "");
230
229
  }
230
+ // Simplified: Get the ID directly from the page
231
+ async getCdpTargetId(page) {
232
+ try {
233
+ const cdpSession = await page.context().newCDPSession(page);
234
+ const { targetInfo } = await cdpSession.send("Target.getTargetInfo");
235
+ await cdpSession.detach();
236
+ if (targetInfo && targetInfo.targetId) {
237
+ this.log("✅ Found CDP ID by session", { id: targetInfo.targetId, url: page.url() });
238
+ return targetInfo.targetId;
239
+ }
240
+ throw new Error("Target.getTargetInfo did not return a targetId");
241
+ }
242
+ catch (error) {
243
+ this.log("❌ Error getting CDP ID by session", { url: page.url(), error });
244
+ return null;
245
+ }
246
+ }
247
+ async getDebugURLs() {
248
+ const url = `${this.CDP_CONNECT_URL}/json?t=${Date.now()}`; // Cache-busting
249
+ try {
250
+ const response = await fetch(url, { cache: "no-store" });
251
+ if (!response.ok) {
252
+ this.log("❌ Failed to fetch debug URLs", { status: response.status });
253
+ throw new Error("Error while fetching debug URL");
254
+ }
255
+ return await response.json();
256
+ }
257
+ catch (error) {
258
+ this.log("❌ Exception while fetching debug URLs", { error });
259
+ return [];
260
+ }
261
+ }
231
262
  async initializeListeners() {
232
263
  this.log("📡 Initializing listeners");
233
264
  this.context.on("page", async (page) => {
234
265
  const stableTabId = uuidv4();
235
266
  this.log("🆕 New page event triggered", { stableTabId, url: page.url() });
236
- this.pages.set(stableTabId, { page, cdpTargetId: null });
237
- const cdpTargetId = await this.findCdpTargetId(page);
267
+ const cdpTargetId = await this.getCdpTargetId(page);
268
+ this.pages.set(stableTabId, { page, cdpTargetId });
238
269
  if (cdpTargetId) {
239
- this.pages.get(stableTabId).cdpTargetId = cdpTargetId;
240
270
  this.log("✅ Page mapped to CDP ID", { stableTabId, cdpTargetId });
241
271
  }
242
272
  else {
@@ -246,115 +276,37 @@ export class RemoteBrowserService extends EventEmitter {
246
276
  this._selectedPageId = stableTabId;
247
277
  }
248
278
  await this.syncState();
249
- page.on("load", async () => {
250
- this.log("🔄 Page load event", { stableTabId, url: page.url() });
251
- const newCdpId = await this.findCdpTargetId(page);
252
- const pageInfo = this.pages.get(stableTabId);
253
- if (pageInfo && newCdpId && pageInfo.cdpTargetId !== newCdpId) {
254
- this.log("🔄 CDP Target ID changed on navigation", {
255
- stableTabId,
256
- old: pageInfo.cdpTargetId,
257
- new: newCdpId,
258
- });
259
- pageInfo.cdpTargetId = newCdpId;
260
- }
261
- await this.syncState();
262
- });
279
+ page.on("load", () => this.syncState());
280
+ page.on("framenavigated", () => this.syncState());
263
281
  page.on("close", async () => {
264
- this.log("🗑️ Page close event", { stableTabId, url: page.url() });
282
+ this.log("🗑️ Page close event", { stableTabId });
265
283
  this.pages.delete(stableTabId);
266
- this.log("✅ Page removed from internal map", {
267
- stableTabId,
268
- remaining: this.pages.size,
269
- });
270
284
  if (this._selectedPageId === stableTabId) {
271
- const firstPage = Array.from(this.pages.keys())[0];
272
- this._selectedPageId = firstPage || null;
273
- this.log("🔄 Selected page changed after close", {
274
- oldSelectedId: stableTabId,
275
- newSelectedId: this._selectedPageId,
276
- });
285
+ this._selectedPageId = this.pages.size > 0 ? Array.from(this.pages.keys())[0] : null;
286
+ this.log("🔄 Selected page changed after close", { newSelectedId: this._selectedPageId });
277
287
  }
278
288
  await this.syncState();
279
289
  });
280
- page.on("framenavigated", async (frame) => {
281
- this.log("🔄 Frame navigated event", { stableTabId, url: frame.url() });
282
- await this.syncState();
283
- });
284
290
  });
291
+ // Initialize with existing pages
285
292
  const existingPages = this.context.pages();
286
293
  this.log("📄 Found existing pages", { count: existingPages.length });
287
294
  for (const page of existingPages) {
288
295
  const stableTabId = uuidv4();
289
- const cdpTargetId = await this.findCdpTargetId(page);
296
+ const cdpTargetId = await this.getCdpTargetId(page);
290
297
  this.pages.set(stableTabId, { page, cdpTargetId });
291
- this.log("✅ Existing page added to map", {
292
- stableTabId,
293
- cdpTargetId,
294
- url: page.url(),
295
- });
298
+ this.log("✅ Existing page added to map", { stableTabId, cdpTargetId, url: page.url() });
296
299
  }
297
300
  if (this.pages.size > 0 && !this._selectedPageId) {
298
301
  this._selectedPageId = Array.from(this.pages.keys())[0];
299
- this.log("🎯 Initial selected page set", { selectedPageId: this._selectedPageId });
300
302
  }
301
303
  await this.syncState();
302
304
  }
303
- async findCdpTargetId(page) {
304
- try {
305
- // This is the most direct and reliable way to get the ID
306
- const cdpSession = await page.context().newCDPSession(page);
307
- const { targetInfo } = await cdpSession.send("Target.getTargetInfo");
308
- await cdpSession.detach();
309
- if (targetInfo && targetInfo.targetId) {
310
- this.log("🎭 Target info", targetInfo);
311
- this.log("✅ Found CDP ID by session", { id: targetInfo.targetId, url: page.url() });
312
- return targetInfo.targetId;
313
- }
314
- else {
315
- throw new Error("Target.getTargetInfo did not return a targetId");
316
- }
317
- }
318
- catch (cdpError) {
319
- // If the session fails, fall back to a simple URL match
320
- this.log("⚠️ CDP session failed, trying URL match as fallback...", { url: page.url(), cdpError });
321
- try {
322
- const debugData = await this.getDebugURLs(); // This now has the cache-busting fix
323
- const match = debugData.find((p) => p.type === "page" && p.url === page.url());
324
- if (match) {
325
- this.log("✅ Found CDP ID by exact URL as fallback", { id: match.id, url: page.url() });
326
- return match.id;
327
- }
328
- }
329
- catch (fetchError) {
330
- this.log("❌ Error in fallback getDebugURLs", { fetchError });
331
- }
332
- }
333
- this.log("❌ No match found for page", { url: page.url() });
334
- return null;
335
- }
336
- async getDebugURLs() {
337
- const url = `${this.CDP_CONNECT_URL}/json?_=${Date.now()}`; // Cache-busting query param
338
- try {
339
- const response = await fetch(url, { cache: "no-store" });
340
- if (!response.ok) {
341
- throw new Error("Error while fetching debug URL");
342
- }
343
- return await response.json();
344
- }
345
- catch (error) {
346
- this.log("❌ Exception while fetching debug URLs", { error });
347
- return [];
348
- }
349
- }
350
305
  async syncState() {
351
306
  try {
352
307
  this.log("🔄 Starting state sync");
353
308
  const state = await this.getState();
354
- this.log("✅ State sync complete", {
355
- pagesCount: state.pages.length,
356
- selectedPageId: state.selectedPageId,
357
- });
309
+ this.log("✅ State sync complete", { pagesCount: state.pages.length, selectedPageId: state.selectedPageId });
358
310
  this.emit("BrowserService.stateSync", state);
359
311
  }
360
312
  catch (error) {
@@ -363,35 +315,36 @@ export class RemoteBrowserService extends EventEmitter {
363
315
  }
364
316
  async getState() {
365
317
  this.log("📊 Getting current state");
318
+ // Get the *live* list of debuggable pages
366
319
  const debugData = await this.getDebugURLs();
320
+ const debugMap = new Map(debugData.map((d) => [d.id, d]));
367
321
  const pagesData = [];
368
322
  for (const [stableTabId, pageInfo] of this.pages.entries()) {
369
- let currentCdpId = pageInfo.cdpTargetId;
370
- let debugInfo = debugData.find((d) => d.id === currentCdpId);
371
- if (!debugInfo) {
372
- this.log("⚠️ Re-finding CDP ID for", { stableTabId });
373
- const newCdpId = await this.findCdpTargetId(pageInfo.page);
374
- if (newCdpId) {
375
- pageInfo.cdpTargetId = newCdpId;
376
- debugInfo = debugData.find((d) => d.id === newCdpId);
377
- this.log("✅ Re-found CDP ID", { stableTabId, newCdpId });
378
- }
379
- }
380
323
  try {
324
+ // Re-verify the CDP ID in case it changed
325
+ const currentCdpId = await this.getCdpTargetId(pageInfo.page);
326
+ if (currentCdpId && pageInfo.cdpTargetId !== currentCdpId) {
327
+ this.log("🔄 CDP ID changed", { stableTabId, old: pageInfo.cdpTargetId, new: currentCdpId });
328
+ pageInfo.cdpTargetId = currentCdpId;
329
+ }
330
+ // Get the debug info from the live map
331
+ const debugInfo = currentCdpId ? debugMap.get(currentCdpId) : undefined;
381
332
  pagesData.push({
382
- id: stableTabId, // Use the STABLE ID
333
+ id: stableTabId,
383
334
  title: await pageInfo.page.title(),
384
335
  url: pageInfo.page.url(),
385
- wsDebuggerUrl: debugInfo?.webSocketDebuggerUrl || "", // Get the *current* ws url
336
+ wsDebuggerUrl: debugInfo?.webSocketDebuggerUrl || "",
386
337
  });
387
338
  }
388
339
  catch (error) {
340
+ // This likely means the page was closed during the loop
389
341
  this.log("❌ Error getting page data (page might be closed)", { stableTabId });
342
+ this.pages.delete(stableTabId); // Clean up dead page
390
343
  }
391
344
  }
345
+ // Ensure selectedPageId is valid
392
346
  if (this._selectedPageId && !this.pages.has(this._selectedPageId)) {
393
- this._selectedPageId = this.pages.size > 0 ? Array.from(this.pages.keys())[0] : null;
394
- this.log("🔄 Corrected selectedPageId", { new: this._selectedPageId });
347
+ this._selectedPageId = pagesData.length > 0 ? pagesData[0].id : null;
395
348
  }
396
349
  const state = {
397
350
  pages: pagesData,
@@ -403,10 +356,11 @@ export class RemoteBrowserService extends EventEmitter {
403
356
  async createTab(url = "about:blank") {
404
357
  try {
405
358
  this.log("🆕 Creating new tab", { url });
406
- const page = await this.context.newPage(); // This will trigger the 'page' event
359
+ const page = await this.context.newPage(); // Triggers 'page' event
407
360
  if (url !== "about:blank") {
408
361
  await page.goto(url, { waitUntil: "domcontentloaded" });
409
362
  }
363
+ // Find the stableTabId that was just created by the 'page' event
410
364
  for (const [stableTabId, pageInfo] of this.pages.entries()) {
411
365
  if (pageInfo.page === page) {
412
366
  this._selectedPageId = stableTabId;
@@ -425,7 +379,7 @@ export class RemoteBrowserService extends EventEmitter {
425
379
  this.log("🗑️ Closing tab", { stableTabId });
426
380
  const pageInfo = this.pages.get(stableTabId);
427
381
  if (pageInfo) {
428
- await pageInfo.page.close(); // This will trigger the 'close' event
382
+ await pageInfo.page.close(); // Triggers 'close' event
429
383
  }
430
384
  else {
431
385
  this.log("⚠️ Page not found for closing", { stableTabId });
@@ -455,462 +409,16 @@ export class RemoteBrowserService extends EventEmitter {
455
409
  }
456
410
  getSelectedPage() {
457
411
  const pageInfo = this._selectedPageId ? this.pages.get(this._selectedPageId) : null;
458
- this.log("🔍 Getting selected page", {
459
- selectedPageId: this._selectedPageId,
460
- found: !!pageInfo,
461
- url: pageInfo?.page.url(),
462
- });
463
412
  return pageInfo?.page || null;
464
413
  }
465
414
  destroy() {
466
415
  this.log("💥 Destroying RemoteBrowserService");
467
- // Remove all listeners *this* instance has registered
468
- // This stops it from listening to context/page events
469
416
  this.context.removeAllListeners("page");
470
- for (const [stableId, pageInfo] of this.pages.entries()) {
471
- pageInfo.page.removeAllListeners("load");
472
- pageInfo.page.removeAllListeners("close");
473
- pageInfo.page.removeAllListeners("framenavigated");
417
+ for (const [, pageInfo] of this.pages.entries()) {
418
+ pageInfo.page.removeAllListeners();
474
419
  }
475
- // Clear internal maps
476
420
  this.pages.clear();
477
421
  this._selectedPageId = null;
478
- // Remove all listeners *on this* emitter
479
422
  this.removeAllListeners();
480
423
  }
481
424
  }
482
- // export class RemoteBrowserService extends EventEmitter {
483
- // private CDP_CONNECT_URL: string;
484
- // private context: BrowserContext;
485
- // private pages: Map<string, Page> = new Map();
486
- // private _selectedPageId: string | null = null;
487
- // constructor({ CDP_CONNECT_URL, context }: { CDP_CONNECT_URL: string; context: BrowserContext }) {
488
- // super();
489
- // this.CDP_CONNECT_URL = CDP_CONNECT_URL;
490
- // this.context = context;
491
- // this.log("🚀 RemoteBrowserService initialized", { CDP_CONNECT_URL });
492
- // this.initializeListeners();
493
- // }
494
- // private log(message: string, data?: any) {
495
- // const timestamp = new Date().toISOString();
496
- // console.log(`[${timestamp}] [RemoteBrowserService] ${message}`, data ? JSON.stringify(data, null, 2) : "");
497
- // }
498
- // private async initializeListeners() {
499
- // this.log("📡 Initializing listeners");
500
- // // Listen for new pages
501
- // this.context.on("page", async (page) => {
502
- // this.log("🆕 New page event triggered", { url: page.url() });
503
- // const id = await this.getPageId(page);
504
- // this.log("🔍 Got page ID from CDP", { id, url: page.url() });
505
- // if (id) {
506
- // this.pages.set(id, page);
507
- // this.log("✅ Page added to internal map", {
508
- // id,
509
- // url: page.url(),
510
- // totalPages: this.pages.size,
511
- // allPageIds: Array.from(this.pages.keys()),
512
- // });
513
- // await this.syncState();
514
- // } else {
515
- // this.log("❌ Failed to get page ID, page not added to map", { url: page.url() });
516
- // }
517
- // // Listen for page updates
518
- // page.on("load", async () => {
519
- // this.log("🔄 Page load event", { id, url: page.url() });
520
- // await this.syncState();
521
- // });
522
- // page.on("close", async () => {
523
- // this.log("🗑️ Page close event", { id, url: page.url() });
524
- // if (id) {
525
- // this.pages.delete(id);
526
- // this.log("✅ Page removed from internal map", {
527
- // id,
528
- // remainingPages: this.pages.size,
529
- // allPageIds: Array.from(this.pages.keys()),
530
- // });
531
- // if (this._selectedPageId === id) {
532
- // const firstPage = Array.from(this.pages.keys())[0];
533
- // this._selectedPageId = firstPage || null;
534
- // this.log("🔄 Selected page changed after close", {
535
- // oldSelectedId: id,
536
- // newSelectedId: this._selectedPageId,
537
- // });
538
- // }
539
- // await this.syncState();
540
- // }
541
- // });
542
- // });
543
- // // Initialize with existing pages
544
- // const existingPages = this.context.pages();
545
- // this.log("📄 Found existing pages", { count: existingPages.length });
546
- // for (const page of existingPages) {
547
- // const id = await this.getPageId(page);
548
- // this.log("🔍 Processing existing page", { id, url: page.url() });
549
- // if (id) {
550
- // this.pages.set(id, page);
551
- // this.log("✅ Existing page added to map", {
552
- // id,
553
- // url: page.url(),
554
- // totalPages: this.pages.size,
555
- // });
556
- // }
557
- // }
558
- // // Set initial selected page
559
- // if (this.pages.size > 0 && !this._selectedPageId) {
560
- // this._selectedPageId = Array.from(this.pages.keys())[0];
561
- // this.log("🎯 Initial selected page set", { selectedPageId: this._selectedPageId });
562
- // }
563
- // this.log("✅ Initialization complete", {
564
- // totalPages: this.pages.size,
565
- // selectedPageId: this._selectedPageId,
566
- // allPageIds: Array.from(this.pages.keys()),
567
- // });
568
- // await this.syncState();
569
- // }
570
- // private async getPageId(page: Page): Promise<string | null> {
571
- // try {
572
- // const pageUrl = page.url();
573
- // this.log("🔍 Getting page ID", { pageUrl });
574
- // // Fetch debug data from /json endpoint (more reliable for matching)
575
- // const debugData = await this.getDebugURLs();
576
- // this.log("📊 CDP debug data received", {
577
- // totalPages: debugData.length,
578
- // pages: debugData.map((p) => ({ id: p.id, type: p.type, url: p.url })),
579
- // });
580
- // // Exact URL match
581
- // for (const pageData of debugData) {
582
- // if (pageData.type === "page" && pageData.url === pageUrl) {
583
- // this.log("✅ Found exact URL match in /json", {
584
- // id: pageData.id,
585
- // url: pageUrl,
586
- // });
587
- // return pageData.id;
588
- // }
589
- // }
590
- // this.log("⚠️ No exact match found, trying normalized URLs", { pageUrl });
591
- // // Normalized URL match
592
- // const normalizeUrl = (url: string) => {
593
- // try {
594
- // const u = new URL(url);
595
- // const normalized = u.hostname.replace(/^www\./, "") + u.pathname + u.search;
596
- // return normalized;
597
- // } catch {
598
- // return url;
599
- // }
600
- // };
601
- // const normalizedPageUrl = normalizeUrl(pageUrl);
602
- // for (const pageData of debugData) {
603
- // if (pageData.type === "page") {
604
- // const normalizedDebugUrl = normalizeUrl(pageData.url);
605
- // if (normalizedDebugUrl === normalizedPageUrl) {
606
- // this.log("✅ Found normalized URL match in /json", {
607
- // id: pageData.id,
608
- // pageUrl: normalizedPageUrl,
609
- // debugUrl: normalizedDebugUrl,
610
- // });
611
- // return pageData.id;
612
- // }
613
- // }
614
- // }
615
- // // If still not found, try CDP session as fallback
616
- // this.log("⚠️ Not found in /json, trying CDP Target.getTargetInfo", { pageUrl });
617
- // try {
618
- // const cdpSession = await page.context().newCDPSession(page);
619
- // const { targetInfo } = await cdpSession.send("Target.getTargetInfo");
620
- // await cdpSession.detach();
621
- // if (targetInfo && targetInfo.targetId) {
622
- // // Verify this target ID exists in debug data
623
- // const targetExists = debugData.some((d) => d.id === targetInfo.targetId);
624
- // if (targetExists) {
625
- // this.log("✅ Got target ID from CDP session and verified in /json", {
626
- // targetId: targetInfo.targetId,
627
- // url: pageUrl,
628
- // });
629
- // return targetInfo.targetId;
630
- // } else {
631
- // this.log("⚠️ Target ID from CDP session not found in /json (ID mismatch)", {
632
- // cdpTargetId: targetInfo.targetId,
633
- // availableIds: debugData.map((d) => d.id),
634
- // });
635
- // }
636
- // }
637
- // } catch (cdpError) {
638
- // this.log("⚠️ Failed to get target ID from CDP session", {
639
- // error: cdpError instanceof Error ? cdpError.message : String(cdpError),
640
- // });
641
- // }
642
- // this.log("❌ No match found for page", {
643
- // pageUrl,
644
- // normalizedPageUrl,
645
- // availablePages: debugData.filter((p) => p.type === "page").map((p) => p.url),
646
- // });
647
- // return null;
648
- // } catch (error) {
649
- // this.log("❌ Error getting page ID", {
650
- // error: error instanceof Error ? error.message : String(error),
651
- // stack: error instanceof Error ? error.stack : undefined,
652
- // });
653
- // return null;
654
- // }
655
- // }
656
- // private async getDebugURLs(): Promise<DebugPageInfo[]> {
657
- // const url = `${this.CDP_CONNECT_URL}/json`;
658
- // this.log("📡 Fetching debug URLs", { url });
659
- // try {
660
- // const response = await fetch(url);
661
- // if (!response.ok) {
662
- // this.log("❌ Failed to fetch debug URLs", {
663
- // status: response.status,
664
- // statusText: response.statusText,
665
- // });
666
- // throw new Error("Error while fetching debug URL");
667
- // }
668
- // const data = await response.json();
669
- // this.log("✅ Debug URLs fetched successfully", {
670
- // count: data.length,
671
- // pages: data.map((p: any) => ({ id: p.id, type: p.type, url: p.url })),
672
- // });
673
- // return data;
674
- // } catch (error) {
675
- // this.log("❌ Exception while fetching debug URLs", {
676
- // error: error instanceof Error ? error.message : String(error),
677
- // });
678
- // throw error;
679
- // }
680
- // }
681
- // private async syncState() {
682
- // try {
683
- // this.log("🔄 Starting state sync");
684
- // const state = await this.getState();
685
- // this.log("✅ State sync complete", {
686
- // pagesCount: state.pages.length,
687
- // selectedPageId: state.selectedPageId,
688
- // pages: state.pages.map((p) => ({ id: p.id, title: p.title, url: p.url })),
689
- // });
690
- // this.emit("BrowserService.stateSync", state);
691
- // } catch (error) {
692
- // this.log("❌ Error syncing state", {
693
- // error: error instanceof Error ? error.message : String(error),
694
- // stack: error instanceof Error ? error.stack : undefined,
695
- // });
696
- // }
697
- // }
698
- // async getState(): Promise<BrowserState> {
699
- // this.log("📊 Getting current state", {
700
- // internalPagesCount: this.pages.size,
701
- // internalPageIds: Array.from(this.pages.keys()),
702
- // selectedPageId: this._selectedPageId,
703
- // });
704
- // const debugData = await this.getDebugURLs();
705
- // this.log("📊 Debug data for state", {
706
- // debugPagesCount: debugData.length,
707
- // debugPages: debugData.map((p) => ({ id: p.id, type: p.type, url: p.url })),
708
- // });
709
- // const pagesData: PageData[] = [];
710
- // const updatedPages = new Map<string, Page>();
711
- // const matchedDebugIds = new Set<string>(); // Track which CDP IDs we've already matched
712
- // let updatedSelectedPageId = this._selectedPageId;
713
- // for (const [oldId, page] of this.pages.entries()) {
714
- // this.log("🔍 Processing page from internal map", {
715
- // oldId,
716
- // url: page.url(),
717
- // });
718
- // // Try to find by old ID first (most common case - ID hasn't changed)
719
- // let debugInfo = debugData.find((d) => d.id === oldId && !matchedDebugIds.has(d.id));
720
- // // Fallback: Try to find by URL (page ID may have changed)
721
- // if (!debugInfo) {
722
- // this.log("⚠️ Page ID not found in CDP, attempting to match by URL", {
723
- // oldId,
724
- // pageUrl: page.url(),
725
- // });
726
- // debugInfo = debugData.find((d) => d.type === "page" && d.url === page.url() && !matchedDebugIds.has(d.id));
727
- // if (debugInfo) {
728
- // this.log("✅ Found page by URL match, updating ID", {
729
- // oldId,
730
- // newId: debugInfo.id,
731
- // url: page.url(),
732
- // });
733
- // // Update selected page ID if this was the selected page and ID changed
734
- // if (oldId === this._selectedPageId) {
735
- // updatedSelectedPageId = debugInfo.id;
736
- // this.log("🔄 Updated selected page ID", {
737
- // oldId,
738
- // newId: debugInfo.id,
739
- // });
740
- // }
741
- // }
742
- // } else {
743
- // this.log("✅ Found matching debug info by ID", {
744
- // id: debugInfo.id,
745
- // debugUrl: debugInfo.url,
746
- // pageUrl: page.url(),
747
- // });
748
- // }
749
- // if (debugInfo) {
750
- // // Mark this CDP ID as matched to avoid duplicate matches
751
- // matchedDebugIds.add(debugInfo.id);
752
- // try {
753
- // const pageData = {
754
- // id: debugInfo.id,
755
- // title: await page.title(),
756
- // url: page.url(),
757
- // wsDebuggerUrl: debugInfo.webSocketDebuggerUrl || "",
758
- // };
759
- // pagesData.push(pageData);
760
- // updatedPages.set(debugInfo.id, page);
761
- // this.log("✅ Page added to state", pageData);
762
- // } catch (error) {
763
- // this.log("❌ Error getting page data", {
764
- // id: oldId,
765
- // error: error instanceof Error ? error.message : String(error),
766
- // });
767
- // }
768
- // } else {
769
- // this.log("⚠️ No matching debug info found by ID or URL", {
770
- // oldId,
771
- // pageUrl: page.url(),
772
- // availableDebugIds: debugData.map((d) => d.id),
773
- // availableDebugUrls: debugData.map((d) => d.url),
774
- // alreadyMatched: Array.from(matchedDebugIds),
775
- // });
776
- // }
777
- // }
778
- // // Update the internal pages map with current CDP IDs
779
- // if (updatedPages.size !== this.pages.size || updatedSelectedPageId !== this._selectedPageId) {
780
- // this.log("🔄 Updating internal state with new CDP IDs", {
781
- // oldPagesCount: this.pages.size,
782
- // newPagesCount: updatedPages.size,
783
- // oldSelectedId: this._selectedPageId,
784
- // newSelectedId: updatedSelectedPageId,
785
- // });
786
- // this.pages = updatedPages;
787
- // this._selectedPageId = updatedSelectedPageId;
788
- // }
789
- // const state = {
790
- // pages: pagesData,
791
- // selectedPageId: this._selectedPageId,
792
- // };
793
- // this.log("📦 Final state", state);
794
- // return state;
795
- // }
796
- // async createTab(url: string = "about:blank"): Promise<void> {
797
- // try {
798
- // this.log("🆕 Creating new tab", { url });
799
- // const page = await this.context.newPage();
800
- // this.log("✅ New page created by Playwright", { url: page.url() });
801
- // if (typeof url === "string" && url !== "about:blank") {
802
- // this.log("🌐 Navigating to URL", { url });
803
- // await page.goto(url, { waitUntil: "domcontentloaded" });
804
- // this.log("✅ Navigation complete", { finalUrl: page.url() });
805
- // }
806
- // // Wait longer for CDP to register and stabilize the page
807
- // this.log("⏳ Waiting for CDP registration and stabilization...");
808
- // await new Promise((resolve) => setTimeout(resolve, 1000)); // Increased to 1 second
809
- // // Try multiple times to get a stable page ID
810
- // let id: string | null = null;
811
- // let attempts = 0;
812
- // const maxAttempts = 5;
813
- // while (!id && attempts < maxAttempts) {
814
- // attempts++;
815
- // this.log(`🔍 Attempt ${attempts}/${maxAttempts} to get page ID`);
816
- // id = await this.getPageId(page);
817
- // if (!id) {
818
- // this.log(`⏳ Page ID not found, waiting 500ms before retry...`);
819
- // await new Promise((resolve) => setTimeout(resolve, 500));
820
- // }
821
- // }
822
- // this.log("🔍 Retrieved page ID after retries", {
823
- // id,
824
- // url: page.url(),
825
- // attempts,
826
- // });
827
- // if (id) {
828
- // this.pages.set(id, page);
829
- // this._selectedPageId = id;
830
- // this.log("✅ Tab created successfully", {
831
- // id,
832
- // url: page.url(),
833
- // totalPages: this.pages.size,
834
- // allPageIds: Array.from(this.pages.keys()),
835
- // selectedPageId: this._selectedPageId,
836
- // });
837
- // } else {
838
- // this.log("❌ Failed to get page ID for new tab after all retries", {
839
- // url: page.url(),
840
- // attempts,
841
- // });
842
- // // Try to get debug data to see what's available
843
- // const debugData = await this.getDebugURLs();
844
- // this.log("🔍 Current CDP state after failed ID retrieval", {
845
- // debugPages: debugData.map((p) => ({ id: p.id, url: p.url, type: p.type })),
846
- // });
847
- // }
848
- // await this.syncState();
849
- // } catch (error) {
850
- // this.log("❌ Error creating tab", {
851
- // url,
852
- // error: error instanceof Error ? error.message : String(error),
853
- // stack: error instanceof Error ? error.stack : undefined,
854
- // });
855
- // throw error;
856
- // }
857
- // }
858
- // async closeTab(pageId: string): Promise<void> {
859
- // try {
860
- // this.log("🗑️ Closing tab", { pageId });
861
- // const page = this.pages.get(pageId);
862
- // if (page) {
863
- // this.log("✅ Found page to close", { pageId, url: page.url() });
864
- // await page.close();
865
- // this.log("✅ Page closed successfully", { pageId });
866
- // } else {
867
- // this.log("⚠️ Page not found", {
868
- // pageId,
869
- // availablePageIds: Array.from(this.pages.keys()),
870
- // });
871
- // }
872
- // } catch (error) {
873
- // this.log("❌ Error closing tab", {
874
- // pageId,
875
- // error: error instanceof Error ? error.message : String(error),
876
- // });
877
- // throw error;
878
- // }
879
- // }
880
- // async selectTab(pageId: string): Promise<void> {
881
- // try {
882
- // this.log("🎯 Selecting tab", { pageId });
883
- // const page = this.pages.get(pageId);
884
- // if (page) {
885
- // this._selectedPageId = pageId;
886
- // await page.bringToFront();
887
- // this.log("✅ Tab selected successfully", {
888
- // pageId,
889
- // url: page.url(),
890
- // selectedPageId: this._selectedPageId,
891
- // });
892
- // await this.syncState();
893
- // } else {
894
- // this.log("⚠️ Page not found for selection", {
895
- // pageId,
896
- // availablePageIds: Array.from(this.pages.keys()),
897
- // });
898
- // }
899
- // } catch (error) {
900
- // this.log("❌ Error selecting tab", {
901
- // pageId,
902
- // error: error instanceof Error ? error.message : String(error),
903
- // });
904
- // throw error;
905
- // }
906
- // }
907
- // getSelectedPage(): Page | null {
908
- // const page = this._selectedPageId ? this.pages.get(this._selectedPageId) || null : null;
909
- // this.log("🔍 Getting selected page", {
910
- // selectedPageId: this._selectedPageId,
911
- // found: !!page,
912
- // url: page?.url(),
913
- // });
914
- // return page;
915
- // }
916
- // }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dev-blinq/cucumber_client",
3
- "version": "1.0.1595-dev",
3
+ "version": "1.0.1597-dev",
4
4
  "description": " ",
5
5
  "main": "bin/index.js",
6
6
  "types": "bin/index.d.ts",