fix: enhance email input detection and add tests for unified OpenAI login page
This commit is contained in:
+45
-5
@@ -3484,6 +3484,10 @@ function summarizePhoneInputCandidate(element, options = {}) {
|
|||||||
const normalizedName = summary.name.toLowerCase();
|
const normalizedName = summary.name.toLowerCase();
|
||||||
const normalizedId = summary.id.toLowerCase();
|
const normalizedId = summary.id.toLowerCase();
|
||||||
const combinedText = `${normalizedName} ${normalizedId} ${summary.placeholder} ${summary.ariaLabel}`;
|
const combinedText = `${normalizedName} ${normalizedId} ${summary.placeholder} ${summary.ariaLabel}`;
|
||||||
|
if (isLoginEmailLikeInput(element)) {
|
||||||
|
summary.skipReason = 'email_like';
|
||||||
|
return summary;
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
summary.type === 'tel'
|
summary.type === 'tel'
|
||||||
|| summary.autocomplete === 'tel'
|
|| summary.autocomplete === 'tel'
|
||||||
@@ -3517,14 +3521,50 @@ function findUsablePhoneInput(selector, options = {}) {
|
|||||||
.find((element) => isUsablePhoneInputElement(element, options)) || null;
|
.find((element) => isUsablePhoneInputElement(element, options)) || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getLoginInputAttributeText(input) {
|
||||||
|
return {
|
||||||
|
type: String(input?.getAttribute?.('type') || input?.type || '').trim().toLowerCase(),
|
||||||
|
autocomplete: String(input?.getAttribute?.('autocomplete') || '').trim().toLowerCase(),
|
||||||
|
name: String(input?.getAttribute?.('name') || input?.name || '').trim(),
|
||||||
|
id: String(input?.getAttribute?.('id') || input?.id || '').trim(),
|
||||||
|
placeholder: String(input?.getAttribute?.('placeholder') || '').trim(),
|
||||||
|
ariaLabel: String(input?.getAttribute?.('aria-label') || '').trim(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function isLoginEmailLikeInput(input) {
|
||||||
|
const summary = getLoginInputAttributeText(input);
|
||||||
|
const nameId = `${summary.name} ${summary.id}`;
|
||||||
|
const labelText = `${summary.placeholder} ${summary.ariaLabel}`;
|
||||||
|
return summary.type === 'email'
|
||||||
|
|| summary.autocomplete === 'email'
|
||||||
|
|| /email/i.test(nameId)
|
||||||
|
|| /email|电子邮件|邮箱/i.test(labelText);
|
||||||
|
}
|
||||||
|
|
||||||
function getLoginEmailInput() {
|
function getLoginEmailInput() {
|
||||||
const input = document.querySelector(
|
const input = Array.from(document.querySelectorAll([
|
||||||
'input[type="email"], input[name="email"], input[name="username"], input[id*="email"], input[placeholder*="email" i], input[placeholder*="Email"]'
|
'input[type="email"]',
|
||||||
);
|
'input[autocomplete="email"]',
|
||||||
if (isLoginPhoneUsernameKind() || isLoginPhoneEntryPageText()) {
|
'input[name="email"]',
|
||||||
|
'input[name="username"]',
|
||||||
|
'input[autocomplete="username"]',
|
||||||
|
'input[id*="email" i]',
|
||||||
|
'input[placeholder*="email" i]',
|
||||||
|
'input[placeholder*="Email"]',
|
||||||
|
'input[placeholder*="电子邮件"]',
|
||||||
|
'input[placeholder*="邮箱"]',
|
||||||
|
'input[aria-label*="email" i]',
|
||||||
|
'input[aria-label*="电子邮件"]',
|
||||||
|
'input[aria-label*="邮箱"]',
|
||||||
|
].join(', '))).find((candidate) => isVisibleElement(candidate)) || null;
|
||||||
|
if (!input) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return input && isVisibleElement(input) ? input : null;
|
if ((isLoginPhoneUsernameKind() || isLoginPhoneEntryPageText()) && !isLoginEmailLikeInput(input)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLoginPhoneInput() {
|
function getLoginPhoneInput() {
|
||||||
|
|||||||
@@ -135,14 +135,18 @@ ${extractFunction('getPageTextSnapshot')}
|
|||||||
${extractFunction('isLoginPhoneUsernameKind')}
|
${extractFunction('isLoginPhoneUsernameKind')}
|
||||||
${extractFunction('isLoginPhoneEntryPageText')}
|
${extractFunction('isLoginPhoneEntryPageText')}
|
||||||
${extractFunction('isInsideHiddenPhoneControl')}
|
${extractFunction('isInsideHiddenPhoneControl')}
|
||||||
|
${extractFunction('getLoginInputAttributeText')}
|
||||||
|
${extractFunction('isLoginEmailLikeInput')}
|
||||||
${extractFunction('summarizePhoneInputCandidate')}
|
${extractFunction('summarizePhoneInputCandidate')}
|
||||||
${extractFunction('isUsablePhoneInputElement')}
|
${extractFunction('isUsablePhoneInputElement')}
|
||||||
${extractFunction('collectPhoneInputCandidates')}
|
${extractFunction('collectPhoneInputCandidates')}
|
||||||
${extractFunction('findUsablePhoneInput')}
|
${extractFunction('findUsablePhoneInput')}
|
||||||
|
${extractFunction('getLoginEmailInput')}
|
||||||
${extractFunction('getLoginPhoneInput')}
|
${extractFunction('getLoginPhoneInput')}
|
||||||
${extractFunction('isAddPhonePageReady')}
|
${extractFunction('isAddPhonePageReady')}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
getLoginEmailInput,
|
||||||
getLoginPhoneInput,
|
getLoginPhoneInput,
|
||||||
isAddPhonePageReady,
|
isAddPhonePageReady,
|
||||||
};
|
};
|
||||||
@@ -168,6 +172,18 @@ test('step 7 does not mistake email entry with a phone switch action for phone i
|
|||||||
assert.equal(api.isAddPhonePageReady(), false);
|
assert.equal(api.isAddPhonePageReady(), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('step 7 treats unified OpenAI login page as email input despite phone option text', () => {
|
||||||
|
const api = createPhoneLoginEntryApi({
|
||||||
|
href: 'https://auth.openai.com/log-in-or-create-account',
|
||||||
|
pathname: '/log-in-or-create-account',
|
||||||
|
pageText: '\u767b\u5f55\u6216\u6ce8\u518c \u7535\u5b50\u90ae\u4ef6\u5730\u5740 \u7ee7\u7eed \u4f7f\u7528\u7535\u8bdd\u53f7\u7801\u7ee7\u7eed',
|
||||||
|
inputAttributes: { type: 'text', placeholder: '\u7535\u5b50\u90ae\u4ef6\u5730\u5740' },
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.ok(api.getLoginEmailInput(), 'unified login email input should be detected');
|
||||||
|
assert.equal(api.getLoginPhoneInput(), null, 'phone option button must not turn email input into phone input');
|
||||||
|
});
|
||||||
|
|
||||||
test('step 7 detects username text input when usernameKind is phone_number', () => {
|
test('step 7 detects username text input when usernameKind is phone_number', () => {
|
||||||
const api = createPhoneLoginEntryApi({
|
const api = createPhoneLoginEntryApi({
|
||||||
phoneUsernameKind: true,
|
phoneUsernameKind: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user