I am creating a Chrome extension that will interact with a specific page of a React web app. The page includes a table, containing many rows of data, which the extension must extract. However, since the table is implemented using react-virtualized, only a subset of the total available data rows are present at any time, and the extension must simulate user behavior by scrolling the table and waiting for the UI to stabilize, before attempting to extract the next batch of row data.
I have successfully implemented a mechanism to achieve this, and it works reliably. The following snippet shows the structure of the function that is injected into the target web page by the Chrome extension. Note that it is async, since it needs to pause and wait for UI operations to complete.
async function extractTableContent() {
return new Promise((resolve) => {
// Not shown here is a fully working mechanism that
// progressively scrapes row data from a virtualized
// HTML table, scrolling the table after each scrape
// cycle and waiting for the UI to stabilize.
resolve(tableContent);
});
}
With the above script code injected into the target page, I can call it from the Dev Tools Console and it always returns the compelete set of table row data, even if that entails scrolling the table many times to discover all the rows:
await extractTableContent()
However, the real-world usage of this mechanism requires it to be invoked in response to a message received from the extension's service worker. Here's how I have configured my injected script to listen for and respond to messages:
const port = chrome.runtime.connect('MY_EXTENSION_ID');
port.onMessage.addListener((request) => {
(async () => {
switch (request.action) {
case 'extract-table-content':
port.postMessage(await extractTableContent());
break;
//
// Other request actions are implemented here
//
default:
console.error('Invalid request action', request.action);
}
})();
return true;
});
When my service worker sends the extract-table-content
request message to the target web page, the extraction function is invoked, but it always returns a single batch of row data. In other words, it seems to be terminating prematurely.
In contrast, if I add a button to the target page to trigger the function, the complete extraction cycle is executed and the result set is complete.
Can you please suggest what I have done wrong, in hooking up the extraction function to the chrome.runtime.connect
API?