channel-worker 2.5.71 → 2.5.73

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "channel-worker",
3
- "version": "2.5.71",
3
+ "version": "2.5.73",
4
4
  "description": "Channel Manager worker daemon — runs on remote machines to execute video pipeline jobs",
5
5
  "main": "lib/daemon.js",
6
6
  "bin": {
@@ -574,6 +574,30 @@ async function isThumbnailEditorVisible(page) {
574
574
  }, THUMBNAIL_EDITOR_TEXT_MARKERS).catch(() => false);
575
575
  }
576
576
 
577
+ // Bằng chứng "thumb tuỳ chỉnh ĐANG được áp" không thể nhầm: nút "Gỡ hình thu
578
+ // nhỏ tùy chỉnh khỏi thước phim" chỉ tồn tại khi đã có thumb tuỳ chỉnh. Cần
579
+ // cho biến thể INLINE (bắt 03/09, idea 6a965a32 fail 5 lượt liên tiếp):
580
+ // editor "nested" nằm HẲN trong bước "Cài đặt thước phim" và không bao giờ
581
+ // "đóng" — marker "Chỉnh sửa hình thu nhỏ" thường trực trong innerText của
582
+ // dialog nên isThumbnailEditorVisible kẹt true, vòng chờ đóng cạn 60s rồi
583
+ // ESC+Hủy phá lượt dù thumb đã dán xong (diag 158386: Gỡ/Lưu/Hủy + Đăng
584
+ // cùng hiện trên một bước).
585
+ async function isCustomThumbApplied(page) {
586
+ return page.evaluate(() => {
587
+ const vis = (el) => {
588
+ const r = el.getBoundingClientRect();
589
+ if (r.width < 8 || r.height < 8) return false;
590
+ const cs = getComputedStyle(el);
591
+ return cs.visibility !== 'hidden' && cs.display !== 'none' && cs.opacity !== '0';
592
+ };
593
+ for (const el of document.querySelectorAll('[aria-label]')) {
594
+ const al = el.getAttribute('aria-label') || '';
595
+ if (/Gỡ hình thu nhỏ tùy chỉnh|Remove( your)? custom thumbnail/i.test(al) && vis(el)) return true;
596
+ }
597
+ return false;
598
+ }).catch(() => false);
599
+ }
600
+
577
601
  const SAFE_RETRY_COMPOSER_CLOSED = 'FB_SAFE_RETRY_COMPOSER_CLOSED';
578
602
 
579
603
  function safeComposerRetryError(message) {
@@ -617,8 +641,16 @@ async function hasVisibleReelComposer(page) {
617
641
  const aria = dlg.getAttribute('aria-label') || '';
618
642
  const text = (dlg.innerText || '').slice(0, 500);
619
643
  const signature = `${aria}\n${text}`;
620
- if (/Chỉnh sửa hình thu nhỏ|Edit thumbnail/i.test(signature)) continue;
644
+ // Dấu hiệu composer phải xét TRƯỚC dòng loại trừ editor bìa. Biến thể
645
+ // INLINE dựng editor "Chỉnh sửa hình thu nhỏ" HẲN BÊN TRONG dialog
646
+ // composer, nên innerText của composer chứa luôn marker đó: loại trừ
647
+ // trước là ăn mất chính composer → báo "composer closed after saving
648
+ // thumbnail" dù composer còn nguyên và thumb đã dán (6 lượt fail
649
+ // 03-04/09, ảnh dump composer-closed-after-thumb-save cho thấy panel
650
+ // bìa + nút "Gỡ" vẫn hiện trong composer). Modal bìa độc lập không có
651
+ // chữ "thước phim"/"reel" trong text nên vẫn bị loại đúng ở dòng sau.
621
652
  if (/Tạo thước phim|Chỉnh sửa thước phim|Cài đặt thước phim|Create (?:a )?reel|Edit reel|Reel settings/i.test(signature)) return true;
653
+ if (/Chỉnh sửa hình thu nhỏ|Edit thumbnail/i.test(signature)) continue;
622
654
  }
623
655
  return false;
624
656
  }).catch(() => false);
@@ -1654,6 +1686,7 @@ async function runOnce({ page, payload, log }) {
1654
1686
  const closeDeadline = Date.now() + 60_000;
1655
1687
  let modalClosed = false;
1656
1688
  let closedPolls = 0;
1689
+ let appliedPolls = 0;
1657
1690
  let retryCount = 0;
1658
1691
  const RETRY_AFTER_MS = 12_000;
1659
1692
  let lastRetryAt = Date.now();
@@ -1663,6 +1696,23 @@ async function runOnce({ page, payload, log }) {
1663
1696
  // nested form (no own dialog — its upload button, aria
1664
1697
  // "Tải hình thu nhỏ tùy chỉnh lên…", only exists while the
1665
1698
  // editor is showing).
1699
+ // Biến thể inline: panel không bao giờ đóng nhưng nút "Gỡ hình
1700
+ // thu nhỏ tùy chỉnh" đã hiện = thumb ĐÃ áp. Chỉ tin ở nhánh
1701
+ // nested (modal thật vẫn phải đóng sau Lưu như cũ) và đòi 2
1702
+ // mẫu liên tiếp như luật closedPolls; bấm Lưu chốt một nhịp
1703
+ // cuối phòng cohort nào đó vẫn cần Lưu để giữ trạng thái.
1704
+ if (thumbEditorVia === 'nested' && await isCustomThumbApplied(page)) {
1705
+ if (++appliedPolls >= 2) {
1706
+ for (const sel of saveCandidates) {
1707
+ const btn = await firstVisible(page.locator(sel), 1);
1708
+ if (btn) { await btn.click({ timeout: 1500 }).catch(() => {}); break; }
1709
+ }
1710
+ log('info', '[fb-pw] page-wall thumb — panel inline không đóng nhưng nút "Gỡ hình thu nhỏ" đang hiện → coi như dán xong');
1711
+ modalClosed = true; break;
1712
+ }
1713
+ } else {
1714
+ appliedPolls = 0;
1715
+ }
1666
1716
  const still = await isThumbnailEditorVisible(page);
1667
1717
  if (!still) {
1668
1718
  // Require two consecutive closed samples. Facebook briefly
@@ -1702,6 +1752,11 @@ async function runOnce({ page, payload, log }) {
1702
1752
  }
1703
1753
  thumbApplied = true;
1704
1754
  log('info', `[fb-pw] page-wall thumb — modal closed after save (retries=${retryCount})`);
1755
+ } else if (thumbEditorVia === 'nested' && await isCustomThumbApplied(page)) {
1756
+ // Hết giờ chờ đóng nhưng bằng chứng áp thumb còn đó — tuyệt
1757
+ // đối không ESC/Hủy (Hủy trên panel inline là GỠ thumb).
1758
+ log('info', '[fb-pw] page-wall thumb — hết giờ chờ đóng nhưng nút "Gỡ hình thu nhỏ" đang hiện → giữ panel, coi như dán xong');
1759
+ thumbApplied = true;
1705
1760
  } else {
1706
1761
  log('warn', '[fb-pw] page-wall thumb — modal still open 60s after Lưu click; trying ESC + click Hủy fallback');
1707
1762
  await page.keyboard.press('Escape').catch(() => {});
@@ -2077,13 +2132,22 @@ async function runOnce({ page, payload, log }) {
2077
2132
  // output. (Observed on reel 1506614811005729: step 1 → click Tiếp
2078
2133
  // → publish, the thumb-edit pill never appeared.)
2079
2134
  if (thumbPath && !customThumbDone) {
2080
- // Defensive: we normally fail at the caption step (before any Tiếp)
2081
- // when a required custom thumb can't be applied. If we somehow reach
2082
- // here without it, refuse to publishbut BEFORE clicking Đăng, so
2083
- // nothing ships and a retry can't double-post. (The v2.5.14 double-post
2084
- // came from failing AFTER publish; this throw is pre-publish.)
2085
- await dumpFailure(page, 'thumb-required-at-publish', log);
2086
- throw new Error('Custom thumbnail required but not applied — refusing to publish with FB auto-thumb');
2135
+ // Cứu theo BẰNG CHỨNG trước khi chặn: biến thể inline có thể làm cờ
2136
+ // customThumbDone lỡ false trong khi nút "Gỡ hình thu nhỏ tùy chỉnh"
2137
+ // ngay trên bước này chứng minh thumb ĐANG được áp cả 5 lượt fail
2138
+ // 02-03/09 của idea 6a965a32 đều trạng thái này (diag 158386).
2139
+ if (await isCustomThumbApplied(page)) {
2140
+ log('info', '[fb-pw] pre-publish: nút "Gỡ hình thu nhỏ tùy chỉnh" đang hiện — thumb đã áp dù cờ chưa bật, tiếp tục đăng');
2141
+ customThumbDone = true;
2142
+ } else {
2143
+ // Defensive: we normally fail at the caption step (before any Tiếp)
2144
+ // when a required custom thumb can't be applied. If we somehow reach
2145
+ // here without it, refuse to publish — but BEFORE clicking Đăng, so
2146
+ // nothing ships and a retry can't double-post. (The v2.5.14 double-post
2147
+ // came from failing AFTER publish; this throw is pre-publish.)
2148
+ await dumpFailure(page, 'thumb-required-at-publish', log);
2149
+ throw new Error('Custom thumbnail required but not applied — refusing to publish with FB auto-thumb');
2150
+ }
2087
2151
  }
2088
2152
  log('info', `[fb-pw] click publish "${pub.verb}" via "${pub.sel}" (step ${step + 1})`);
2089
2153
  // Snapshot the captured-IDs list RIGHT BEFORE the publish click. The
@@ -2850,6 +2914,7 @@ module.exports.__testables = {
2850
2914
  PUBLISH_ENABLE_TIMEOUT_MS,
2851
2915
  PUBLISH_CTA_ABSENT_GRACE_MS,
2852
2916
  THUMBNAIL_EDITOR_TEXT_MARKERS,
2917
+ isCustomThumbApplied,
2853
2918
  REEL_CREATE_SELECTORS,
2854
2919
  REEL_ENTRY_SELECTORS,
2855
2920
  ADD_VIDEO_SELECTORS,