Merge remote-tracking branch 'origin/dev' into codex/pr278-review

This commit is contained in:
QLHazyCoder
2026-05-28 02:25:38 +08:00
7 changed files with 682 additions and 1 deletions
@@ -46,6 +46,7 @@ test('logging/status add-phone detection ignores step 2 phone-entry switch failu
assert.equal(loggingStatus.getLoginAuthStateLabel('phone_verification_page'), '手机验证码页');
assert.equal(loggingStatus.getLoginAuthStateLabel('add_email_page'), '添加邮箱页');
assert.equal(loggingStatus.getLoginAuthStateLabel('oauth_consent_page'), 'OAuth 授权页');
assert.equal(loggingStatus.getLoginAuthStateLabel('choose_account_page'), 'OpenAI choose account page');
assert.equal(
loggingStatus.getErrorMessage(new Error('GPC_TASK_ENDED::GPC OTP 超时,请重新创建任务')),
'GPC OTP 超时,请重新创建任务'
+21
View File
@@ -143,6 +143,10 @@ function isOAuthConsentPage() {
return ${JSON.stringify(Boolean(overrides.oauthConsentPage))};
}
function isChooseAccountPage() {
return ${JSON.stringify(Boolean(overrides.chooseAccountPage))};
}
${bundle}
return {
@@ -287,6 +291,18 @@ return {
assert.strictEqual(snapshot.state, 'entry_page');
}
{
const api = createApi({
pathname: '/choose-an-account',
href: 'https://auth.openai.com/choose-an-account',
chooseAccountPage: true,
});
const snapshot = api.inspectLoginAuthState();
assert.strictEqual(snapshot.state, 'choose_account_page');
assert.strictEqual(snapshot.chooseAccountPage, true);
}
{
const api = createApi({
phoneInput: { id: 'phone' },
@@ -326,4 +342,9 @@ assert.ok(
'inspectLoginAuthState 应产出 add_email_page 状态'
);
assert.ok(
extractFunction('inspectLoginAuthState').includes("state: 'choose_account_page'"),
'inspectLoginAuthState should produce choose_account_page state'
);
console.log('step6 login state tests passed');
+349
View File
@@ -51,6 +51,15 @@ function extractFunction(name) {
return source.slice(start, end);
}
function extractConst(name) {
const pattern = new RegExp(`const\\s+${name}\\s*=\\s*[\\s\\S]*?;`);
const match = source.match(pattern);
if (!match) {
throw new Error(`missing const ${name}`);
}
return match[0];
}
test('password submit treats direct OAuth consent as a login-code skip', async () => {
const api = new Function(`
const location = { href: 'https://auth.openai.com/authorize' };
@@ -132,3 +141,343 @@ return {
assert.equal(result.directOAuthConsentPage, true);
assert.equal(logs.some(({ level }) => level === 'ok'), true);
});
test('step 7 clicks matching choose-account card and skips login code after OAuth consent', async () => {
const api = new Function(`
let pageState = 'choose_account_page';
const clicked = [];
const location = {
href: 'https://auth.openai.com/choose-an-account',
pathname: '/choose-an-account',
};
const targetCard = {
id: 'target-card',
textContent: 'Tall Slept Fancy tall-slept-fancy@duck.com',
value: '',
parentElement: null,
disabled: false,
getAttribute(name) {
if (name === 'role') return 'button';
if (name === 'aria-disabled') return 'false';
return '';
},
closest() {
return null;
},
};
const removeButton = {
id: 'remove-button',
textContent: '',
value: '',
parentElement: targetCard,
disabled: false,
getAttribute(name) {
if (name === 'aria-label') return 'Remove tall-slept-fancy@duck.com';
if (name === 'aria-disabled') return 'false';
return '';
},
closest() {
return null;
},
};
const otherCard = {
id: 'other-card',
textContent: 'Other User other@example.com',
value: '',
parentElement: null,
disabled: false,
getAttribute(name) {
if (name === 'role') return 'button';
if (name === 'aria-disabled') return 'false';
return '';
},
closest() {
return null;
},
};
const document = {
body: {
innerText: 'Welcome back Choose an account tall-slept-fancy@duck.com other@example.com',
textContent: 'Welcome back Choose an account tall-slept-fancy@duck.com other@example.com',
},
querySelectorAll(selector) {
if (String(selector).includes('body *')) return [removeButton, targetCard, otherCard];
return [removeButton, targetCard, otherCard];
},
};
function getOperationDelayRunner() {
return async (_metadata, operation) => operation();
}
function isVisibleElement(element) {
return Boolean(element);
}
function isActionEnabled(element) {
return Boolean(element) && !element.disabled && element.getAttribute('aria-disabled') !== 'true';
}
function simulateClick(element) {
clicked.push(element.id);
if (element === targetCard) {
pageState = 'oauth_consent_page';
location.href = 'https://auth.openai.com/sign-in-with-chatgpt/codex/consent';
location.pathname = '/sign-in-with-chatgpt/codex/consent';
}
}
function inspectLoginAuthState() {
return { state: pageState, url: location.href, chooseAccountPage: pageState === 'choose_account_page' };
}
function throwIfStopped() {}
async function sleep() {}
async function humanPause() {}
function log() {}
async function finalizeStep6VerificationReady() { return { routed: 'verification' }; }
async function step6LoginFromPasswordPage() { return { routed: 'password' }; }
async function step6LoginFromEmailPage() { return { routed: 'email' }; }
async function step6LoginFromPhonePage() { return { routed: 'phone' }; }
async function createStep6LoginTimeoutRecoveryTransition() { return { action: 'recoverable', result: { routed: 'timeout' } }; }
${extractConst('CHOOSE_ACCOUNT_PAGE_PATTERN')}
${extractConst('CHOOSE_ACCOUNT_REMOVE_ACTION_PATTERN')}
${extractConst('CHOOSE_ACCOUNT_OTHER_ACCOUNT_PATTERN')}
${extractConst('CHOOSE_ACCOUNT_ACTION_SELECTOR')}
${extractFunction('getPageTextSnapshot')}
${extractFunction('normalizeAuthAccountIdentifier')}
${extractFunction('getChooseAccountCandidateText')}
${extractFunction('isChooseAccountPage')}
${extractFunction('isChooseAccountRemovalAction')}
${extractFunction('resolveChooseAccountClickTarget')}
${extractFunction('findChooseAccountButtonForEmail')}
${extractFunction('createStep6SuccessResult')}
${extractFunction('createStep6OAuthConsentSuccessResult')}
${extractFunction('createStep6AddEmailSuccessResult')}
${extractFunction('createStep6RecoverableResult')}
${extractFunction('normalizeStep6Snapshot')}
${extractFunction('isOpenAiOAuthAuthorizationRoute')}
${extractFunction('isPostChooseAccountOAuthRoute')}
${extractFunction('waitForChooseAccountTransition')}
${extractFunction('step6ChooseExistingAccount')}
return {
clicked,
run() {
return step6ChooseExistingAccount(
{ email: 'TALL-SLEPT-FANCY@DUCK.COM', loginIdentifierType: 'email', visibleStep: 7 },
{ state: 'choose_account_page', url: location.href }
);
},
};
`)();
const result = await api.run();
assert.deepEqual(api.clicked, ['target-card']);
assert.equal(result.step6Outcome, 'success');
assert.equal(result.state, 'oauth_consent_page');
assert.equal(result.skipLoginVerificationStep, true);
assert.equal(result.directOAuthConsentPage, true);
assert.equal(result.via, 'choose_account_oauth_consent_page');
});
test('step 7 skips login code when choose-account leaves for OAuth authorize route before consent DOM is ready', async () => {
const api = new Function(`
let pageState = 'choose_account_page';
const clicked = [];
const location = {
href: 'https://auth.openai.com/choose-an-account',
pathname: '/choose-an-account',
};
const targetCard = {
id: 'target-card',
textContent: 'Tall Slept Fancy tall-slept-fancy@duck.com',
value: '',
parentElement: null,
disabled: false,
getAttribute(name) {
if (name === 'role') return 'button';
if (name === 'aria-disabled') return 'false';
return '';
},
closest() {
return null;
},
};
const document = {
body: {
innerText: 'Welcome back Choose an account tall-slept-fancy@duck.com',
textContent: 'Welcome back Choose an account tall-slept-fancy@duck.com',
},
querySelectorAll(selector) {
if (String(selector).includes('body *')) return [targetCard];
return [targetCard];
},
};
function getOperationDelayRunner() {
return async (_metadata, operation) => operation();
}
function isVisibleElement(element) {
return Boolean(element);
}
function isActionEnabled(element) {
return Boolean(element) && !element.disabled && element.getAttribute('aria-disabled') !== 'true';
}
function simulateClick(element) {
clicked.push(element.id);
if (element === targetCard) {
pageState = 'unknown';
location.href = 'https://auth.openai.com/authorize?client_id=codex-test&state=oauth-state';
location.pathname = '/authorize';
}
}
function inspectLoginAuthState() {
return { state: pageState, url: location.href, chooseAccountPage: pageState === 'choose_account_page' };
}
function throwIfStopped() {}
async function sleep() {}
async function humanPause() {}
function log() {}
async function finalizeStep6VerificationReady() { return { routed: 'verification' }; }
async function step6LoginFromPasswordPage() { return { routed: 'password' }; }
async function step6LoginFromEmailPage() { return { routed: 'email' }; }
async function step6LoginFromPhonePage() { return { routed: 'phone' }; }
async function createStep6LoginTimeoutRecoveryTransition() { return { action: 'recoverable', result: { routed: 'timeout' } }; }
${extractConst('CHOOSE_ACCOUNT_PAGE_PATTERN')}
${extractConst('CHOOSE_ACCOUNT_REMOVE_ACTION_PATTERN')}
${extractConst('CHOOSE_ACCOUNT_OTHER_ACCOUNT_PATTERN')}
${extractConst('CHOOSE_ACCOUNT_ACTION_SELECTOR')}
${extractFunction('getPageTextSnapshot')}
${extractFunction('normalizeAuthAccountIdentifier')}
${extractFunction('getChooseAccountCandidateText')}
${extractFunction('isChooseAccountPage')}
${extractFunction('isChooseAccountRemovalAction')}
${extractFunction('resolveChooseAccountClickTarget')}
${extractFunction('findChooseAccountButtonForEmail')}
${extractFunction('createStep6SuccessResult')}
${extractFunction('createStep6OAuthConsentSuccessResult')}
${extractFunction('createStep6AddEmailSuccessResult')}
${extractFunction('createStep6RecoverableResult')}
${extractFunction('normalizeStep6Snapshot')}
${extractFunction('isOpenAiOAuthAuthorizationRoute')}
${extractFunction('isPostChooseAccountOAuthRoute')}
${extractFunction('waitForChooseAccountTransition')}
${extractFunction('step6ChooseExistingAccount')}
return {
clicked,
run() {
return step6ChooseExistingAccount(
{ email: 'tall-slept-fancy@duck.com', loginIdentifierType: 'email', visibleStep: 7 },
{ state: 'choose_account_page', url: location.href }
);
},
};
`)();
const result = await api.run();
assert.deepEqual(api.clicked, ['target-card']);
assert.equal(result.step6Outcome, 'success');
assert.equal(result.state, 'unknown');
assert.equal(result.skipLoginVerificationStep, true);
assert.equal(result.directOAuthConsentPage, true);
assert.equal(result.via, 'choose_account_oauth_authorization_route');
});
test('step 7 does not click choose-account page when target email is missing', async () => {
const api = new Function(`
const clicked = [];
const location = {
href: 'https://auth.openai.com/choose-an-account',
pathname: '/choose-an-account',
};
const otherCard = {
id: 'other-card',
textContent: 'Other User other@example.com',
value: '',
parentElement: null,
disabled: false,
getAttribute(name) {
if (name === 'role') return 'button';
if (name === 'aria-disabled') return 'false';
return '';
},
closest() {
return null;
},
};
const document = {
body: {
innerText: 'Welcome back Choose an account other@example.com',
textContent: 'Welcome back Choose an account other@example.com',
},
querySelectorAll() {
return [otherCard];
},
};
function getOperationDelayRunner() {
return async (_metadata, operation) => operation();
}
function isVisibleElement(element) {
return Boolean(element);
}
function isActionEnabled(element) {
return Boolean(element) && !element.disabled && element.getAttribute('aria-disabled') !== 'true';
}
function simulateClick(element) {
clicked.push(element.id);
}
function inspectLoginAuthState() {
return { state: 'choose_account_page', url: location.href, chooseAccountPage: true };
}
function throwIfStopped() {}
async function sleep() {}
async function humanPause() {}
function log() {}
async function finalizeStep6VerificationReady() { return { routed: 'verification' }; }
async function step6LoginFromPasswordPage() { return { routed: 'password' }; }
async function step6LoginFromEmailPage() { return { routed: 'email' }; }
async function step6LoginFromPhonePage() { return { routed: 'phone' }; }
async function createStep6LoginTimeoutRecoveryTransition() { return { action: 'recoverable', result: { routed: 'timeout' } }; }
${extractConst('CHOOSE_ACCOUNT_PAGE_PATTERN')}
${extractConst('CHOOSE_ACCOUNT_REMOVE_ACTION_PATTERN')}
${extractConst('CHOOSE_ACCOUNT_OTHER_ACCOUNT_PATTERN')}
${extractConst('CHOOSE_ACCOUNT_ACTION_SELECTOR')}
${extractFunction('getPageTextSnapshot')}
${extractFunction('normalizeAuthAccountIdentifier')}
${extractFunction('getChooseAccountCandidateText')}
${extractFunction('isChooseAccountPage')}
${extractFunction('isChooseAccountRemovalAction')}
${extractFunction('resolveChooseAccountClickTarget')}
${extractFunction('findChooseAccountButtonForEmail')}
${extractFunction('createStep6SuccessResult')}
${extractFunction('createStep6OAuthConsentSuccessResult')}
${extractFunction('createStep6AddEmailSuccessResult')}
${extractFunction('createStep6RecoverableResult')}
${extractFunction('normalizeStep6Snapshot')}
${extractFunction('isOpenAiOAuthAuthorizationRoute')}
${extractFunction('isPostChooseAccountOAuthRoute')}
${extractFunction('waitForChooseAccountTransition')}
${extractFunction('step6ChooseExistingAccount')}
return {
clicked,
run() {
return step6ChooseExistingAccount(
{ email: 'target@example.com', loginIdentifierType: 'email', visibleStep: 7 },
{ state: 'choose_account_page', url: location.href }
);
},
};
`)();
const result = await api.run();
assert.deepEqual(api.clicked, []);
assert.equal(result.step6Outcome, 'recoverable');
assert.equal(result.reason, 'choose_account_target_not_found');
});