fix(tabs): scope payment task tab lookup

This commit is contained in:
朴圣佑
2026-05-12 11:10:03 +08:00
parent 80c3e6217f
commit 7a5b7a26cf
6 changed files with 58 additions and 6 deletions
+4 -1
View File
@@ -16,6 +16,7 @@
addLog: rawAddLog = async () => {},
chrome,
completeStepFromBackground,
createAutomationTab = null,
ensureContentScriptReadyOnTabUntilStopped,
fetch: fetchImpl = null,
registerTab,
@@ -63,7 +64,9 @@
}
async function openFreshChatGptTabForCheckoutCreate() {
const tab = await chrome.tabs.create({ url: PLUS_CHECKOUT_ENTRY_URL, active: true });
const tab = typeof createAutomationTab === 'function'
? await createAutomationTab({ url: PLUS_CHECKOUT_ENTRY_URL, active: true })
: await chrome.tabs.create({ url: PLUS_CHECKOUT_ENTRY_URL, active: true });
const tabId = Number(tab?.id);
if (!Number.isInteger(tabId)) {
throw new Error('步骤 6:打开 ChatGPT 页面失败,无法创建订阅页。');
+6 -2
View File
@@ -88,6 +88,7 @@
getTabId,
isTabAlive,
markCurrentRegistrationAccountUsed,
queryTabsInAutomationWindow = null,
setState,
sleepWithStop,
waitForTabCompleteUntilStopped,
@@ -1364,13 +1365,16 @@
return null;
}
const activeTabs = await chrome.tabs.query({ active: true, currentWindow: true }).catch(() => []);
const queryTabs = typeof queryTabsInAutomationWindow === 'function'
? queryTabsInAutomationWindow
: (queryInfo) => chrome.tabs.query(queryInfo);
const activeTabs = await queryTabs({ active: true, currentWindow: true }).catch(() => []);
const activeCheckoutTab = activeTabs.find((tab) => Number.isInteger(tab?.id) && isPlusCheckoutUrl(tab.url));
if (activeCheckoutTab) {
return activeCheckoutTab.id;
}
const checkoutTabs = await chrome.tabs.query({ url: 'https://chatgpt.com/checkout/*' }).catch(() => []);
const checkoutTabs = await queryTabs({ url: 'https://chatgpt.com/checkout/*' }).catch(() => []);
const checkoutTab = checkoutTabs.find((tab) => Number.isInteger(tab?.id) && isPlusCheckoutUrl(tab.url));
return checkoutTab?.id || null;
}
+5 -1
View File
@@ -21,6 +21,7 @@
ensureContentScriptReadyOnTabUntilStopped,
getTabId,
isTabAlive,
queryTabsInAutomationWindow = null,
registerTab,
sendTabMessageUntilStopped,
setState,
@@ -110,7 +111,10 @@
if (!chrome?.tabs?.query) {
return 0;
}
const tabs = await chrome.tabs.query({}).catch(() => []);
const queryTabs = typeof queryTabsInAutomationWindow === 'function'
? queryTabsInAutomationWindow
: (queryInfo) => chrome.tabs.query(queryInfo);
const tabs = await queryTabs({}).catch(() => []);
const candidates = (Array.isArray(tabs) ? tabs : [])
.filter((tab) => Number.isInteger(tab?.id) && predicate(tab.url || ''));
if (!candidates.length) {
+4 -1
View File
@@ -10,6 +10,7 @@
addLog,
broadcastDataUpdate,
chrome,
createAutomationTab = null,
getTabId,
isTabAlive,
registerTab,
@@ -48,7 +49,9 @@
throw new Error('步骤 7:无法自动重新打开 GoPay 订阅页。');
}
const tab = await chrome.tabs.create({ url: checkoutUrl, active: true });
const tab = typeof createAutomationTab === 'function'
? await createAutomationTab({ url: checkoutUrl, active: true })
: await chrome.tabs.create({ url: checkoutUrl, active: true });
const tabId = Number(tab?.id) || 0;
if (!tabId) {
throw new Error('步骤 7:重新打开 GoPay 订阅页失败。');
+5 -1
View File
@@ -15,6 +15,7 @@
ensureContentScriptReadyOnTabUntilStopped,
getTabId,
isTabAlive,
queryTabsInAutomationWindow = null,
sendTabMessageUntilStopped,
setState,
sleepWithStop,
@@ -48,7 +49,10 @@
return 0;
}
const tabs = await chrome.tabs.query({}).catch(() => []);
const queryTabs = typeof queryTabsInAutomationWindow === 'function'
? queryTabsInAutomationWindow
: (queryInfo) => chrome.tabs.query(queryInfo);
const tabs = await queryTabs({}).catch(() => []);
const candidates = (Array.isArray(tabs) ? tabs : [])
.filter((tab) => Number.isInteger(tab?.id) && isPayPalUrl(tab.url || ''));
if (!candidates.length) {
@@ -82,6 +82,7 @@ function createExecutorHarness({
fetchImpl = null,
getAddressSeedForCountry = () => createAddressSeed(),
getState = null,
queryTabsInAutomationWindow = null,
markCurrentRegistrationAccountUsed = async () => {},
probeIpProxyExit = null,
onSetState = null,
@@ -161,6 +162,7 @@ function createExecutorHarness({
getTabId: async () => null,
isTabAlive: async () => false,
markCurrentRegistrationAccountUsed,
...(typeof queryTabsInAutomationWindow === 'function' ? { queryTabsInAutomationWindow } : {}),
setState: async (updates) => {
events.states.push(updates);
if (typeof onSetState === 'function') {
@@ -240,6 +242,38 @@ test('Plus checkout billing uses the current checkout tab when step 6 did not re
assert.equal(events.logs.some((entry) => /当前已在 Plus Checkout 页面/.test(entry.message)), true);
});
test('Plus checkout billing searches checkout tabs inside the locked automation window', async () => {
const queries = [];
const { checkoutTab, executor } = createExecutorHarness({
frames: [{ frameId: 0, url: 'https://chatgpt.com/checkout/openai_ie/cs_test' }],
queryTabsInAutomationWindow: async (queryInfo) => {
queries.push(queryInfo);
if (queryInfo?.active) {
return [];
}
if (queryInfo?.url === 'https://chatgpt.com/checkout/*') {
return [checkoutTab];
}
return [];
},
stateByFrame: {
0: {
hasPayPal: true,
paypalCandidates: [{ tag: 'button', text: 'PayPal' }],
billingFieldsVisible: true,
hasSubscribeButton: true,
},
},
});
await executor.executePlusCheckoutBilling({});
assert.deepEqual(queries, [
{ active: true, currentWindow: true },
{ url: 'https://chatgpt.com/checkout/*' },
]);
});
test('Plus checkout billing sends the billing command to the iframe that contains PayPal', async () => {
const { events, executor } = createExecutorHarness({
frames: [