chrome captureVisibleTab behavior

OS – macOS Sonoma

I am trying to capture images of all the tabs of a Chrome Window, B which is launched by another Chrome Window, A. This process is part of an extension. Following are the possibilities
B can be in

  1. foreground
  2. background of A
  3. background of any other Application window like Slack, for example

Workflow is

  1. extension loads code where Window A, with relevant permission activeTab, opens Window B.
  2. Window B opens 4 tabs, where first tab contains Take Screenshot button.
  3. User takes action on a Button on first Tab of Window B to initiate screenshot capture. 4. Algorithm triggers that iteratively makes every tab is active and injects a script is in active Tab’s foreground, which sends the message to the background to take screenshot.

Following is the code

manifest.json

{
"manifest_version": 3,
"name": "Screenshot Extension",
"version": "1.0",
"permissions": [
  "tabs",  "scripting", "activeTab"],
"host_permissions": [
    "<all_urls>",
    "*://*/*",
    "http://*/*",
    "https://*/*"
  ],
"background": {
  "service_worker": "background.js"
},
"content_scripts": [
  {
    "matches": ["<all_urls>"],
    "js": ["content.js"]
  }
],
"action": {
  "default_popup": "popup.html",
  "default_icon": {
    "16": "images/icon.png",
    "48": "images/icon.png",
    "128": "images/icon.png"
  }
}
  }

content.js

// Connect to the background script
//const port = chrome.runtime.connect();
console.log('in content script');
// Get the current window ID

  
chrome.runtime.sendMessage({ action: "captureTab" }, (response) => {
  
  console.log('logging status: ' + response.status);
  if (response.dataUrl) {
    // Optionally handle the captured image data URL here
    console.log('Captured image URL:', response.dataUrl);
  }
});

background.js

let captureVisibleTab;
let cwid;
let windowBId;

chrome.runtime.onInstalled.addListener(() => {
    chrome.contextMenus.create({
      id: "createWindowB",
      title: "Create Window B",
      contexts: ["action"]
    });
  });

chrome.runtime.onInstalled.addListener(() => {
  console.log('launching window');
  createWindowB();
  //setTimeout(startTakingScreenshots, 3000);
  });
  
  /*
chrome.contextMenus.onClicked.addListener((info, tab) => {
    if (info.menuItemId === "createWindowB") {
      createWindowB();
    }
  });*/
  
  function createWindowB() {
    const urls = [
      chrome.runtime.getURL("permission.html"),
      "/",
      "https://google.com/",
      "https://cricbuzz.com/"
    ];
  
    chrome.windows.create({
      url: urls,
      type: "normal",
      focused: true
    }, (window) => {
      windowBId = window.id;
      console.log('Window B created with ID:', window.id);
    });
  }


// Listener for messages to start the screenshot process
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
    if (request.action === 'startScreenshots') {
      console.log('received start taking screen shots');
      startTakingScreenshots();
    }
  });

  //startTakingScreenshots();
  
  function startTakingScreenshots() {
    chrome.tabs.query({ windowId: windowBId}, (tabs) => {
      tabs.forEach((tab, index) => {
        if (index > 0) { // Skip the first tab (index 0)
          setTimeout(() => {
            console.log('starting to take screenshot');
            chrome.tabs.update(tab.id, { active: true }, () => {
              chrome.scripting.executeScript({
                target: { tabId: tab.id },
                files: ['content.js']
              });
            });
          }, index * 6000); // Delay to allow the tab to activate and render
        }
      });
    });
  }
  
  /*
  function captureTab() {
    chrome.tabs.captureVisibleTab(null, { format: 'png' }, (dataUrl) => {
      console.log('Captured tab image data URL:', dataUrl);
    });
  }
*/


captureVisibleTab = (callback) => {
  chrome.windows.getCurrent((currentWindow) => {
      cwid = currentWindow.id;
      console.log(`Current window ID: ${cwid} & window B id: ${windowBId}`);
    });

  if (cwid !== windowBId) return;

  console.log('invoking captured tab with current window id: ' + cwid);
  chrome.tabs.captureVisibleTab(windowBId, { format: 'png' }, (dataUrl) => {
    console.log('Captured tab image data URL:', dataUrl);
    // Pass the dataUrl to the callback
    if (callback) callback(dataUrl);
  });
};

//setTimeout(captureVisibleTab, 1000);

// Listener to handle messages from the content script
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.action === "captureTab" && captureVisibleTab) {
  captureVisibleTab((dataUrl) => {
    console.log(dataUrl);
    sendResponse({ status: "Captured", dataUrl: dataUrl });
  });
  // Return true to indicate that we will respond asynchronously
  return true;
}
});

windowB.js

document.getElementById('startScreenshots').addEventListener('click', () => {
    chrome.runtime.sendMessage({ action: 'startScreenshots' });
  });

permission.html

<!DOCTYPE html>
<html>
<head>
  <title>Window B</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 20px;
    }
    button {
      padding: 10px 20px;
      font-size: 16px;
    }
  </style>
</head>
<body>
  <h1>Take Screenshots</h1>
  <button id="startScreenshots">Start Taking Screenshots</button>
  <script src="windowB.js"></script>
</body>
</html>

popup.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Mouse Cursor Mover</title>
</head>
<body>
  <h1>Click to Move Mouse Cursor</h1>
</body>
</html>

Observations: on loading extension, Window B is launched. I click on the button in the first tab to take snapshot, i observe the following behaviour

  1. Window B is foreground – Success (Screenshots of Tabs are captured)
  2. Window B is in background of another Application – Success
  3. Window B is in background of Window A, and completely overshadowed by it – Failure
  4. Window B is in background of Window A, and visible even by smallest of margin behind Window A – Success
  5. Window B is minimized – Failure

I can think of the reason of working of scenarios 1 and probably of 5, however, I cannot work out reason why 2 & 4 works while 3 fails.

Will appreciate suggestions or probably pointing out if I overlooked any point here.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật