修复手机号注册绑定邮箱节点执行与资料提交等待
This commit is contained in:
+43
-6
@@ -68,29 +68,56 @@ const NORMAL_STEP_DEFINITIONS = self.MultiPageStepDefinitions?.getSteps?.({
|
||||
activeFlowId: DEFAULT_ACTIVE_FLOW_ID,
|
||||
plusModeEnabled: false,
|
||||
}) || [];
|
||||
const NORMAL_PHONE_STEP_DEFINITIONS = self.MultiPageStepDefinitions?.getSteps?.({
|
||||
activeFlowId: DEFAULT_ACTIVE_FLOW_ID,
|
||||
plusModeEnabled: false,
|
||||
signupMethod: 'phone',
|
||||
}) || NORMAL_STEP_DEFINITIONS;
|
||||
const PLUS_PAYPAL_STEP_DEFINITIONS = self.MultiPageStepDefinitions?.getSteps?.({
|
||||
activeFlowId: DEFAULT_ACTIVE_FLOW_ID,
|
||||
plusModeEnabled: true,
|
||||
plusPaymentMethod: 'paypal',
|
||||
}) || NORMAL_STEP_DEFINITIONS;
|
||||
const PLUS_PAYPAL_PHONE_STEP_DEFINITIONS = self.MultiPageStepDefinitions?.getSteps?.({
|
||||
activeFlowId: DEFAULT_ACTIVE_FLOW_ID,
|
||||
plusModeEnabled: true,
|
||||
plusPaymentMethod: 'paypal',
|
||||
signupMethod: 'phone',
|
||||
}) || PLUS_PAYPAL_STEP_DEFINITIONS;
|
||||
const PLUS_GOPAY_STEP_DEFINITIONS = self.MultiPageStepDefinitions?.getSteps?.({
|
||||
activeFlowId: DEFAULT_ACTIVE_FLOW_ID,
|
||||
plusModeEnabled: true,
|
||||
plusPaymentMethod: 'gopay',
|
||||
}) || PLUS_PAYPAL_STEP_DEFINITIONS;
|
||||
const PLUS_GOPAY_PHONE_STEP_DEFINITIONS = self.MultiPageStepDefinitions?.getSteps?.({
|
||||
activeFlowId: DEFAULT_ACTIVE_FLOW_ID,
|
||||
plusModeEnabled: true,
|
||||
plusPaymentMethod: 'gopay',
|
||||
signupMethod: 'phone',
|
||||
}) || PLUS_GOPAY_STEP_DEFINITIONS;
|
||||
const PLUS_GPC_STEP_DEFINITIONS = self.MultiPageStepDefinitions?.getSteps?.({
|
||||
activeFlowId: DEFAULT_ACTIVE_FLOW_ID,
|
||||
plusModeEnabled: true,
|
||||
plusPaymentMethod: 'gpc-helper',
|
||||
}) || PLUS_GOPAY_STEP_DEFINITIONS;
|
||||
const PLUS_GPC_PHONE_STEP_DEFINITIONS = self.MultiPageStepDefinitions?.getSteps?.({
|
||||
activeFlowId: DEFAULT_ACTIVE_FLOW_ID,
|
||||
plusModeEnabled: true,
|
||||
plusPaymentMethod: 'gpc-helper',
|
||||
signupMethod: 'phone',
|
||||
}) || PLUS_GPC_STEP_DEFINITIONS;
|
||||
const PLUS_STEP_DEFINITIONS = PLUS_PAYPAL_STEP_DEFINITIONS;
|
||||
const ALL_STEP_DEFINITIONS = self.MultiPageStepDefinitions?.getAllSteps?.({
|
||||
activeFlowId: DEFAULT_ACTIVE_FLOW_ID,
|
||||
}) || [
|
||||
...NORMAL_STEP_DEFINITIONS,
|
||||
...NORMAL_PHONE_STEP_DEFINITIONS,
|
||||
...PLUS_PAYPAL_STEP_DEFINITIONS,
|
||||
...PLUS_PAYPAL_PHONE_STEP_DEFINITIONS,
|
||||
...PLUS_GOPAY_STEP_DEFINITIONS,
|
||||
...PLUS_GOPAY_PHONE_STEP_DEFINITIONS,
|
||||
...PLUS_GPC_STEP_DEFINITIONS,
|
||||
...PLUS_GPC_PHONE_STEP_DEFINITIONS,
|
||||
];
|
||||
const STEP_IDS = Array.from(new Set(ALL_STEP_DEFINITIONS
|
||||
.map((definition) => Number(definition?.id))
|
||||
@@ -9608,6 +9635,7 @@ const STEP_COMPLETION_SIGNAL_STEP_KEYS = new Set([
|
||||
'platform-verify',
|
||||
]);
|
||||
const STEP_COMPLETION_SIGNAL_TIMEOUTS_BY_STEP_KEY = new Map([
|
||||
['fill-profile', 150000],
|
||||
['gopay-subscription-confirm', 1800000],
|
||||
]);
|
||||
const AUTO_RUN_PRE_EXECUTION_DELAYS_BY_STEP_KEY = new Map([
|
||||
@@ -10379,8 +10407,9 @@ async function executeNodeAndWait(nodeId, delayAfter = 2000) {
|
||||
const latestState = await getState();
|
||||
await addLog(`自动运行:节点 ${normalizedNodeId} 已执行返回,当前状态为 ${latestState.nodeStatuses?.[normalizedNodeId] || 'pending'},准备继续后续节点。`, 'info');
|
||||
} else if (doesNodeUseCompletionSignal(normalizedNodeId, executionState)) {
|
||||
await addLog(`自动运行:节点 ${normalizedNodeId} 已发起,正在等待完成信号(超时 ${AUTO_RUN_SIGNAL_COMPLETION_TIMEOUT_MS / 1000} 秒)。`, 'info');
|
||||
completionPayload = await executeNodeViaCompletionSignal(normalizedNodeId, AUTO_RUN_SIGNAL_COMPLETION_TIMEOUT_MS);
|
||||
const completionSignalTimeoutMs = getNodeCompletionSignalTimeoutMs(normalizedNodeId, executionState);
|
||||
await addLog(`自动运行:节点 ${normalizedNodeId} 已发起,正在等待完成信号(超时 ${Math.round(completionSignalTimeoutMs / 1000)} 秒)。`, 'info');
|
||||
completionPayload = await executeNodeViaCompletionSignal(normalizedNodeId, completionSignalTimeoutMs);
|
||||
await addLog(`自动运行:节点 ${normalizedNodeId} 已收到完成信号,准备继续后续节点。`, 'info');
|
||||
} else {
|
||||
await executeNode(normalizedNodeId);
|
||||
@@ -10391,7 +10420,7 @@ async function executeNodeAndWait(nodeId, delayAfter = 2000) {
|
||||
if (signupTabId) {
|
||||
await addLog('自动运行:填写资料节点已收到完成信号,正在等待当前页面完成加载并稳定...', 'info');
|
||||
await waitForTabStableComplete(signupTabId, {
|
||||
timeoutMs: 30000,
|
||||
timeoutMs: 120000,
|
||||
retryDelayMs: 300,
|
||||
stableMs: 1000,
|
||||
initialDelayMs: 800,
|
||||
@@ -12560,23 +12589,31 @@ async function acquireTopLevelAuthChainExecution(step, state = {}) {
|
||||
}
|
||||
|
||||
const normalStepRegistry = buildStepRegistry(NORMAL_STEP_DEFINITIONS);
|
||||
const normalPhoneStepRegistry = buildStepRegistry(NORMAL_PHONE_STEP_DEFINITIONS);
|
||||
const plusPayPalStepRegistry = buildStepRegistry(PLUS_PAYPAL_STEP_DEFINITIONS);
|
||||
const plusPayPalPhoneStepRegistry = buildStepRegistry(PLUS_PAYPAL_PHONE_STEP_DEFINITIONS);
|
||||
const plusGoPayStepRegistry = buildStepRegistry(PLUS_GOPAY_STEP_DEFINITIONS);
|
||||
const plusGoPayPhoneStepRegistry = buildStepRegistry(PLUS_GOPAY_PHONE_STEP_DEFINITIONS);
|
||||
const plusGpcStepRegistry = buildStepRegistry(PLUS_GPC_STEP_DEFINITIONS);
|
||||
const plusGpcPhoneStepRegistry = buildStepRegistry(PLUS_GPC_PHONE_STEP_DEFINITIONS);
|
||||
|
||||
function getStepRegistryForState(state = {}) {
|
||||
const activeFlowId = String(state?.activeFlowId || DEFAULT_ACTIVE_FLOW_ID).trim().toLowerCase() || DEFAULT_ACTIVE_FLOW_ID;
|
||||
if (activeFlowId !== DEFAULT_ACTIVE_FLOW_ID) {
|
||||
throw new Error(`当前尚未注册 flow=${activeFlowId} 的步骤执行器。`);
|
||||
}
|
||||
const signupMethod = getSignupMethodForStepDefinitions(state);
|
||||
if (!isPlusModeState(state)) {
|
||||
return normalStepRegistry;
|
||||
return signupMethod === SIGNUP_METHOD_PHONE ? normalPhoneStepRegistry : normalStepRegistry;
|
||||
}
|
||||
const paymentMethod = normalizePlusPaymentMethod(state?.plusPaymentMethod);
|
||||
if (paymentMethod === PLUS_PAYMENT_METHOD_GPC_HELPER) {
|
||||
return plusGpcStepRegistry;
|
||||
return signupMethod === SIGNUP_METHOD_PHONE ? plusGpcPhoneStepRegistry : plusGpcStepRegistry;
|
||||
}
|
||||
return paymentMethod === PLUS_PAYMENT_METHOD_GOPAY ? plusGoPayStepRegistry : plusPayPalStepRegistry;
|
||||
if (paymentMethod === PLUS_PAYMENT_METHOD_GOPAY) {
|
||||
return signupMethod === SIGNUP_METHOD_PHONE ? plusGoPayPhoneStepRegistry : plusGoPayStepRegistry;
|
||||
}
|
||||
return signupMethod === SIGNUP_METHOD_PHONE ? plusPayPalPhoneStepRegistry : plusPayPalStepRegistry;
|
||||
}
|
||||
|
||||
async function requestOAuthUrlFromPanel(state, options = {}) {
|
||||
|
||||
@@ -593,6 +593,7 @@
|
||||
|
||||
function getContentScriptResponseTimeoutMs(message) {
|
||||
if (!message || typeof message !== 'object') return 30000;
|
||||
if (message.type === 'EXECUTE_NODE' && String(message.nodeId || message.payload?.nodeId || '').trim() === 'fill-profile') return 150000;
|
||||
if (message.type === 'EXECUTE_NODE' && String(message.nodeId || message.payload?.nodeId || '').trim() === 'wait-registration-success') return 75000;
|
||||
if (message.type === 'POLL_EMAIL') {
|
||||
const maxAttempts = Math.max(1, Number(message.payload?.maxAttempts) || 1);
|
||||
|
||||
@@ -6753,7 +6753,7 @@ function installStep5NavigationCompletionReporter(completeOnce) {
|
||||
|
||||
async function waitForStep5SubmitOutcome(options = {}) {
|
||||
const {
|
||||
timeoutMs = 45000,
|
||||
timeoutMs = 120000,
|
||||
maxAuthRetryRecoveries = 2,
|
||||
maxSubmitClicks = 3,
|
||||
retryClickIntervalMs = 3500,
|
||||
|
||||
@@ -12,10 +12,26 @@ test('background imports node registry and shared workflow definitions', () => {
|
||||
assert.match(source, /buildNodeRegistry\(definitions/);
|
||||
assert.match(source, /PLUS_PAYPAL_STEP_DEFINITIONS/);
|
||||
assert.match(source, /PLUS_GOPAY_STEP_DEFINITIONS/);
|
||||
assert.match(source, /NORMAL_PHONE_STEP_DEFINITIONS/);
|
||||
assert.match(source, /PLUS_PAYPAL_PHONE_STEP_DEFINITIONS/);
|
||||
assert.match(source, /PLUS_GOPAY_PHONE_STEP_DEFINITIONS/);
|
||||
assert.match(source, /PLUS_GPC_PHONE_STEP_DEFINITIONS/);
|
||||
assert.match(source, /plusPayPalStepRegistry/);
|
||||
assert.match(source, /plusGoPayStepRegistry/);
|
||||
assert.match(source, /normalizePlusPaymentMethod\(state\?\.plusPaymentMethod\) === PLUS_PAYMENT_METHOD_GOPAY/);
|
||||
assert.match(source, /normalPhoneStepRegistry/);
|
||||
assert.match(source, /plusPayPalPhoneStepRegistry/);
|
||||
assert.match(source, /plusGoPayPhoneStepRegistry/);
|
||||
assert.match(source, /plusGpcPhoneStepRegistry/);
|
||||
assert.match(source, /const signupMethod = getSignupMethodForStepDefinitions\(state\);/);
|
||||
assert.match(source, /signupMethod === SIGNUP_METHOD_PHONE \? normalPhoneStepRegistry : normalStepRegistry/);
|
||||
assert.match(source, /const paymentMethod = normalizePlusPaymentMethod\(state\?\.plusPaymentMethod\);/);
|
||||
assert.match(source, /paymentMethod === PLUS_PAYMENT_METHOD_GOPAY/);
|
||||
assert.match(source, /signupMethod === SIGNUP_METHOD_PHONE \? plusGoPayPhoneStepRegistry : plusGoPayStepRegistry/);
|
||||
assert.match(source, /signupMethod === SIGNUP_METHOD_PHONE \? plusPayPalPhoneStepRegistry : plusPayPalStepRegistry/);
|
||||
assert.match(source, /signupMethod === SIGNUP_METHOD_PHONE \? plusGpcPhoneStepRegistry : plusGpcStepRegistry/);
|
||||
assert.match(source, /activeStepRegistry\.executeNode\(normalizedNodeId,\s*\{/);
|
||||
assert.match(source, /'bind-email': \(state\) => step8Executor\.executeBindEmail\(state\)/);
|
||||
assert.match(source, /'fetch-bind-email-code': \(state\) => step8Executor\.executeFetchBindEmailCode\(state\)/);
|
||||
assert.match(source, /background\/steps\/create-plus-checkout\.js/);
|
||||
assert.match(source, /background\/steps\/fill-plus-checkout\.js/);
|
||||
assert.match(source, /background\/steps\/gopay-manual-confirm\.js/);
|
||||
|
||||
@@ -121,6 +121,37 @@ test('tab runtime caps per-attempt response timeout to the remaining resilient t
|
||||
);
|
||||
});
|
||||
|
||||
test('tab runtime gives step 5 profile submit enough response time for slow page transitions', () => {
|
||||
const source = fs.readFileSync('background/tab-runtime.js', 'utf8');
|
||||
const globalScope = {};
|
||||
const api = new Function('self', `${source}; return self.MultiPageBackgroundTabRuntime;`)(globalScope);
|
||||
|
||||
const runtime = api.createTabRuntime({
|
||||
LOG_PREFIX: '[test]',
|
||||
addLog: async () => {},
|
||||
chrome: {
|
||||
tabs: {
|
||||
get: async () => ({ id: 1, url: 'https://example.com', status: 'complete' }),
|
||||
query: async () => [],
|
||||
},
|
||||
},
|
||||
getSourceLabel: (sourceName) => sourceName || 'unknown',
|
||||
getState: async () => ({ tabRegistry: {}, sourceLastUrls: {} }),
|
||||
matchesSourceUrlFamily: () => false,
|
||||
setState: async () => {},
|
||||
throwIfStopped: () => {},
|
||||
});
|
||||
|
||||
assert.equal(
|
||||
runtime.getContentScriptResponseTimeoutMs({ type: 'EXECUTE_NODE', nodeId: 'fill-profile' }),
|
||||
150000
|
||||
);
|
||||
assert.equal(
|
||||
runtime.getContentScriptResponseTimeoutMs({ type: 'EXECUTE_NODE', payload: { nodeId: 'fill-profile' } }),
|
||||
150000
|
||||
);
|
||||
});
|
||||
|
||||
test('tab runtime waitForTabComplete waits until tab status becomes complete', async () => {
|
||||
const source = fs.readFileSync('background/tab-runtime.js', 'utf8');
|
||||
const globalScope = {};
|
||||
|
||||
Reference in New Issue
Block a user