feat: 完善 AI Studio Key 自动化流程
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const { _private } = require('../src/services/change_password_service');
|
||||
|
||||
function locator(overrides = {}) {
|
||||
return {
|
||||
scrollIntoViewIfNeeded: async () => {},
|
||||
waitFor: async () => {},
|
||||
isDisabled: async () => false,
|
||||
isVisible: async () => true,
|
||||
click: async () => {},
|
||||
press: async () => {},
|
||||
evaluate: async () => true,
|
||||
inputValue: async () => '',
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
(async () => {
|
||||
const calls = [];
|
||||
const button = locator({
|
||||
click: async (options) => calls.push(['click', options]),
|
||||
evaluate: async () => { calls.push(['domClick']); return true; },
|
||||
});
|
||||
const confirm = locator({
|
||||
press: async key => calls.push(['press', key]),
|
||||
});
|
||||
const log = () => {};
|
||||
|
||||
assert.strictEqual(await _private.submitPasswordForm({}, button, confirm, 1, log), true);
|
||||
assert.deepStrictEqual(calls[0], ['click', { timeout: 10000, noWaitAfter: true }],
|
||||
'首次提交必须使用正常点击且禁止 force');
|
||||
|
||||
assert.strictEqual(await _private.submitPasswordForm({}, button, confirm, 2, log), true);
|
||||
assert.deepStrictEqual(calls[1], ['press', 'Enter'], '第二次必须复用原表单并按回车提交');
|
||||
|
||||
assert.strictEqual(await _private.submitPasswordForm({}, button, confirm, 3, log), true);
|
||||
assert.deepStrictEqual(calls[2], ['domClick'], '第三次必须走 DOM 按钮点击兜底');
|
||||
|
||||
assert.strictEqual(await _private.canRetryPasswordSubmit(button, locator(), confirm), true);
|
||||
assert.strictEqual(await _private.canRetryPasswordSubmit(
|
||||
locator({ isDisabled: async () => true }),
|
||||
locator(),
|
||||
confirm,
|
||||
), false, '按钮仍禁用时不得重复提交');
|
||||
|
||||
assert.strictEqual(_private.hasPasswordFieldsInUrl(
|
||||
'https://myaccount.google.com/signinoptions/password?password=secret&confirmation_password=secret',
|
||||
), true, '密码字段进入 URL 时必须触发安全保护');
|
||||
assert.strictEqual(_private.hasPasswordFieldsInUrl(
|
||||
'https://myaccount.google.com/signinoptions/password?rapt=token',
|
||||
), false);
|
||||
assert.strictEqual(_private.hasPasswordFieldsInUrl(
|
||||
'https://myaccount.google.com/signinoptions/password?NEW_PASSWORD=secret',
|
||||
), true, '敏感查询参数检查必须忽略大小写');
|
||||
|
||||
let passwordSelector = '';
|
||||
const visibleInputs = await _private.pickVisiblePasswordInputs({
|
||||
locator: (selector) => {
|
||||
passwordSelector = selector;
|
||||
return {
|
||||
count: async () => 2,
|
||||
nth: () => locator(),
|
||||
};
|
||||
},
|
||||
});
|
||||
assert.strictEqual(visibleInputs.length, 2);
|
||||
assert(passwordSelector.includes('input[name="password"]'),
|
||||
'显示密码后 type 可能变成 text,仍必须按 name 识别密码控件');
|
||||
|
||||
let dialogConfirmClicks = 0;
|
||||
const makeDialog = (visible, hasConfirm) => ({
|
||||
isVisible: async () => visible,
|
||||
locator: () => ({ first: () => ({ isVisible: async () => true }) }),
|
||||
getByRole: (_role, options) => {
|
||||
const isConfirm = /Change password/.test(String(options.name));
|
||||
if (!isConfirm) return { first: () => ({ isVisible: async () => true }) };
|
||||
return {
|
||||
count: async () => (hasConfirm ? 1 : 0),
|
||||
nth: () => locator({ click: async () => { dialogConfirmClicks++; } }),
|
||||
};
|
||||
},
|
||||
waitFor: async () => {},
|
||||
});
|
||||
const dialogs = [makeDialog(true, false), makeDialog(true, true)];
|
||||
const dialogHandled = await _private.confirmPasswordChangeDialog({
|
||||
locator: () => ({
|
||||
count: async () => dialogs.length,
|
||||
nth: index => dialogs[index],
|
||||
}),
|
||||
}, log);
|
||||
assert.strictEqual(dialogHandled, true);
|
||||
assert.strictEqual(dialogConfirmClicks, 1, '必须点击弹窗作用域内的确认按钮');
|
||||
|
||||
console.log('change_password_submit_fallback.test.js: PASS');
|
||||
})().catch(error => {
|
||||
console.error(error);
|
||||
process.exitCode = 1;
|
||||
});
|
||||
Reference in New Issue
Block a user