Merge branch 'dev' of https://github.com/QLHazyCoder/codex-oauth-automation-extension into dev
This commit is contained in:
@@ -225,15 +225,20 @@
|
|||||||
const cardModeButton = modeButtons.find((element) => /卡密充值/.test(textOf(element)));
|
const cardModeButton = modeButtons.find((element) => /卡密充值/.test(textOf(element)));
|
||||||
const freeModeButton = modeButtons.find((element) => /免费充值/.test(textOf(element)));
|
const freeModeButton = modeButtons.find((element) => /免费充值/.test(textOf(element)));
|
||||||
const bodyText = String(document.body?.innerText || document.documentElement?.innerText || '').replace(/\r/g, '');
|
const bodyText = String(document.body?.innerText || document.documentElement?.innerText || '').replace(/\r/g, '');
|
||||||
|
const rawTextOf = (element) => String(element?.innerText || element?.textContent || element?.value || '');
|
||||||
const logNodes = Array.from(document.querySelectorAll('[class*="log"], [id*="log"], .design-log, .logs, pre, code'));
|
const logNodes = Array.from(document.querySelectorAll('[class*="log"], [id*="log"], .design-log, .logs, pre, code'));
|
||||||
const logText = logNodes.map(textOf).filter(Boolean).join('\n') || bodyText;
|
const logText = logNodes.map(rawTextOf).map((text) => text.trim()).filter(Boolean).join('\n') || bodyText;
|
||||||
const extractLastLogLine = (rawText = '') => {
|
const extractLastLogLine = (rawText = '') => {
|
||||||
const lines = String(rawText || '')
|
const normalizeLogLine = (line = '') => String(line || '').replace(/\s+/g, ' ').trim();
|
||||||
.split(/\n+/)
|
const ignoredLinePattern = /^(?:GPC Plus 充值|系统全自动出号|限量\d+份|自助购买卡密通道|实时进度|免费池|付费池|模式:|任务:|未开始|导出|充值模式|填写卡密|Access Token|开始 Plus 充值|停止当前任务|页面已就绪)$/i;
|
||||||
.map((line) => line.replace(/\s+/g, ' ').trim())
|
const timestampEntries = String(rawText || '')
|
||||||
|
.replace(/\r/g, '')
|
||||||
|
.match(/\[\d{2}:\d{2}:\d{2}\][\s\S]*?(?=\s*\[\d{2}:\d{2}:\d{2}\]|$)/g);
|
||||||
|
const entries = (timestampEntries && timestampEntries.length ? timestampEntries : String(rawText || '').split(/\n+/))
|
||||||
|
.map(normalizeLogLine)
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.filter((line) => !/^(?:GPC Plus 充值|系统全自动出号|限量\d+份|自助购买卡密通道|实时进度|免费池|付费池|模式:|任务:|未开始|导出|充值模式|填写卡密|Access Token|开始 Plus 充值|停止当前任务|页面已就绪)$/i.test(line));
|
.filter((line) => !ignoredLinePattern.test(line));
|
||||||
return lines[lines.length - 1] || '';
|
return entries[entries.length - 1] || '';
|
||||||
};
|
};
|
||||||
const lastLogLine = extractLastLogLine(logText) || extractLastLogLine(bodyText);
|
const lastLogLine = extractLastLogLine(logText) || extractLastLogLine(bodyText);
|
||||||
const cardInputs = Array.from(document.querySelectorAll('input.card-key-seg, input[placeholder*="XXXXXXXX"], input[maxlength="8"]'))
|
const cardInputs = Array.from(document.querySelectorAll('input.card-key-seg, input[placeholder*="XXXXXXXX"], input[maxlength="8"]'))
|
||||||
@@ -266,11 +271,13 @@
|
|||||||
|
|
||||||
function getGpcLastLogSummary(pageState = {}) {
|
function getGpcLastLogSummary(pageState = {}) {
|
||||||
const rawText = String(pageState.lastLogLine || pageState.logText || pageState.bodyText || '');
|
const rawText = String(pageState.lastLogLine || pageState.logText || pageState.bodyText || '');
|
||||||
const lines = rawText
|
const timestampEntries = rawText
|
||||||
.split(/\n+/)
|
.replace(/\r/g, '')
|
||||||
|
.match(/\[\d{2}:\d{2}:\d{2}\][\s\S]*?(?=\s*\[\d{2}:\d{2}:\d{2}\]|$)/g);
|
||||||
|
const entries = (timestampEntries && timestampEntries.length ? timestampEntries : rawText.split(/\n+/))
|
||||||
.map((line) => line.replace(/\s+/g, ' ').trim())
|
.map((line) => line.replace(/\s+/g, ' ').trim())
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
const line = lines[lines.length - 1] || '';
|
const line = entries[entries.length - 1] || '';
|
||||||
if (!line) {
|
if (!line) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@@ -282,6 +289,18 @@
|
|||||||
return summary ? ` 最近日志:${summary}` : '';
|
return summary ? ` 最近日志:${summary}` : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasGpcNoTrialFailure(pageState = {}) {
|
||||||
|
if (pageState.noTrial) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const text = normalizeText([
|
||||||
|
pageState.lastLogLine,
|
||||||
|
pageState.logText,
|
||||||
|
pageState.bodyText,
|
||||||
|
].filter(Boolean).join(' '));
|
||||||
|
return /(?:该|此|当前)?账[户号].{0,12}(?:没有|无|不具备).{0,8}试用资格|(?:没有|无|不具备).{0,8}试用资格/.test(text);
|
||||||
|
}
|
||||||
|
|
||||||
async function ensureGpcCardMode(tabId) {
|
async function ensureGpcCardMode(tabId) {
|
||||||
if (!chrome?.scripting?.executeScript) {
|
if (!chrome?.scripting?.executeScript) {
|
||||||
throw new Error('步骤 7:当前运行环境不支持脚本注入,无法切换 GPC 卡密充值模式。');
|
throw new Error('步骤 7:当前运行环境不支持脚本注入,无法切换 GPC 卡密充值模式。');
|
||||||
@@ -478,6 +497,7 @@
|
|||||||
while (Date.now() <= deadline) {
|
while (Date.now() <= deadline) {
|
||||||
throwIfStopped();
|
throwIfStopped();
|
||||||
const pageState = await inspectGpcPortalPage(tabId);
|
const pageState = await inspectGpcPortalPage(tabId);
|
||||||
|
pageState.noTrial = hasGpcNoTrialFailure(pageState);
|
||||||
const buttonText = normalizeText(pageState.startButtonText);
|
const buttonText = normalizeText(pageState.startButtonText);
|
||||||
await collectStatusLog(pageState, buttonText);
|
await collectStatusLog(pageState, buttonText);
|
||||||
|
|
||||||
|
|||||||
@@ -1058,7 +1058,10 @@ test('GPC billing restarts when start button returns without subscription done',
|
|||||||
const { events, executor, pageHarness } = createGpcPageExecutorHarness([
|
const { events, executor, pageHarness } = createGpcPageExecutorHarness([
|
||||||
{ startButtonText: '开始 Plus 充值', logText: 'SYSTEM 页面已就绪' },
|
{ startButtonText: '开始 Plus 充值', logText: 'SYSTEM 页面已就绪' },
|
||||||
{ startButtonText: '任务进行中', logText: '处理中' },
|
{ startButtonText: '任务进行中', logText: '处理中' },
|
||||||
{ startButtonText: '开始 Plus 充值', logText: 'SYSTEM\n卡密次数不足,任务已停止' },
|
{
|
||||||
|
startButtonText: '开始 Plus 充值',
|
||||||
|
logText: '[02:17:28] ACTION 任务已提交 [02:17:28] SYSTEM 排队中,等待 worker 调度... [02:17:31] SUCCESS [02/09] 购买短信号码:+6283******846 [02:17:59] ERROR 卡密次数不足,任务已停止',
|
||||||
|
},
|
||||||
{ startButtonText: '任务进行中', logText: '第二次处理中' },
|
{ startButtonText: '任务进行中', logText: '第二次处理中' },
|
||||||
{ startButtonText: '开始 Plus 充值', logText: '订阅完成', hasSubscriptionDone: true },
|
{ startButtonText: '开始 Plus 充值', logText: '订阅完成', hasSubscriptionDone: true },
|
||||||
]);
|
]);
|
||||||
@@ -1071,7 +1074,8 @@ test('GPC billing restarts when start button returns without subscription done',
|
|||||||
|
|
||||||
assert.equal(pageHarness.clicks.length, 2);
|
assert.equal(pageHarness.clicks.length, 2);
|
||||||
assert.equal(events.logs.some((entry) => /准备再次启动/.test(entry.message)), true);
|
assert.equal(events.logs.some((entry) => /准备再次启动/.test(entry.message)), true);
|
||||||
assert.equal(events.logs.some((entry) => /准备再次启动.*最近日志:卡密次数不足,任务已停止/.test(entry.message)), true);
|
assert.equal(events.logs.some((entry) => /准备再次启动.*最近日志:\[02:17:59\] ERROR 卡密次数不足,任务已停止/.test(entry.message)), true);
|
||||||
|
assert.equal(events.logs.some((entry) => /最近日志:\[02:17:28\] ACTION/.test(entry.message)), false);
|
||||||
assert.equal(events.completed.length, 1);
|
assert.equal(events.completed.length, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1099,7 +1103,7 @@ test('GPC billing collapses repeated running status logs with a multiplier', asy
|
|||||||
|
|
||||||
test('GPC billing fails current round without restart when account has no trial eligibility', async () => {
|
test('GPC billing fails current round without restart when account has no trial eligibility', async () => {
|
||||||
const { events, executor, pageHarness } = createGpcPageExecutorHarness([
|
const { events, executor, pageHarness } = createGpcPageExecutorHarness([
|
||||||
{ startButtonText: '开始 Plus 充值', logText: 'SYSTEM\n该账户没有试用资格', noTrial: true },
|
{ startButtonText: '开始 Plus 充值', logText: '[02:20:00] ACTION 任务开始执行... [02:20:09] ERROR 该账户没有试用资格', noTrial: true },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await assert.rejects(
|
await assert.rejects(
|
||||||
@@ -1108,13 +1112,38 @@ test('GPC billing fails current round without restart when account has no trial
|
|||||||
plusCheckoutSource: 'gpc-helper',
|
plusCheckoutSource: 'gpc-helper',
|
||||||
plusCheckoutTabId: 77,
|
plusCheckoutTabId: 77,
|
||||||
}),
|
}),
|
||||||
/PLUS_CHECKOUT_NON_FREE_TRIAL::.*该账户没有试用资格.*最近日志:该账户没有试用资格/
|
/PLUS_CHECKOUT_NON_FREE_TRIAL::.*该账户没有试用资格.*最近日志:\[02:20:09\] ERROR 该账户没有试用资格/
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.equal(pageHarness.clicks.length, 0);
|
assert.equal(pageHarness.clicks.length, 0);
|
||||||
assert.equal(events.completed.length, 0);
|
assert.equal(events.completed.length, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('GPC billing treats no-trial log text as terminal even when page flag is missing', async () => {
|
||||||
|
const { events, executor, pageHarness } = createGpcPageExecutorHarness([
|
||||||
|
{ startButtonText: '开始 Plus 充值', logText: 'SYSTEM 页面已就绪' },
|
||||||
|
{ startButtonText: '任务进行中', logText: '处理中' },
|
||||||
|
{
|
||||||
|
startButtonText: '开始 Plus 充值',
|
||||||
|
logText: '[02:30:00] ACTION 任务开始执行... [02:30:18] ERROR 该账号没有试用资格',
|
||||||
|
noTrial: false,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
await assert.rejects(
|
||||||
|
() => executor.executePlusCheckoutBilling({
|
||||||
|
plusPaymentMethod: 'gpc-helper',
|
||||||
|
plusCheckoutSource: 'gpc-helper',
|
||||||
|
plusCheckoutTabId: 77,
|
||||||
|
}),
|
||||||
|
/PLUS_CHECKOUT_NON_FREE_TRIAL::.*该账户没有试用资格.*最近日志:\[02:30:18\] ERROR 该账号没有试用资格/
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.equal(pageHarness.clicks.length, 1);
|
||||||
|
assert.equal(events.logs.some((entry) => /准备再次启动/.test(entry.message)), false);
|
||||||
|
assert.equal(events.completed.length, 0);
|
||||||
|
});
|
||||||
|
|
||||||
test('GPC billing times out when page never finishes', async () => {
|
test('GPC billing times out when page never finishes', async () => {
|
||||||
const { executor, pageHarness } = createGpcPageExecutorHarness([
|
const { executor, pageHarness } = createGpcPageExecutorHarness([
|
||||||
{ startButtonText: '任务进行中', logText: '处理中' },
|
{ startButtonText: '任务进行中', logText: '处理中' },
|
||||||
|
|||||||
Reference in New Issue
Block a user