Content script of my extension scans some page for vendor codes and send them with chrome.runtime.sendMessage to my background script which creates new tabs and executes some co
You didn't specify the tab id so executeScript uses the active tab. Since the API is asynchronous your executeScript is running at some unspecified time in the future when the active tab is not the tab you've created in the past.
Simply reuse the tab id provided to chrome.tabs.create's callback:
chrome.runtime.onMessage.addListener(
(request, sender, sendResponse) => {
if (request.message === 'open_new_tab') {
for (let vCode of request.vCodes) {
chrome.tabs.create({url: 'https://example.com/' + vCode}, tab => {
chrome.tabs.executeScript(tab.id, {code: `console.log(${vCode})`});
});
}
}
});
If you want to open just one tab and reuse it to load the sites sequentially, I suggest utilizing Mozilla's WebExtension polyfill and async/await:
browser.runtime.onMessage.addListener(
async (request, sender) => {
if (request.message === 'open_new_tab') {
let tab;
for (const vCode of request.vCodes) {
const url = 'https://example.com/' + vCode;
tab = tab ?
await browser.tabs.update(tab.id, {url}) :
await browser.tabs.create({url});
await browser.tabs.executeScript(tab.id, {code: `console.log(${vCode})`});
}
}
});