| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- const test = require('node:test');
- const assert = require('node:assert/strict');
- const fs = require('node:fs');
- const step2Source = fs.readFileSync('background/steps/submit-signup-email.js', 'utf8');
- const step2GlobalScope = {};
- const step2Api = new Function('self', `${step2Source}; return self.MultiPageBackgroundStep2;`)(step2GlobalScope);
- const signupFlowSource = fs.readFileSync('background/signup-flow-helpers.js', 'utf8');
- const signupFlowGlobalScope = {};
- const signupFlowApi = new Function('self', `${signupFlowSource}; return self.MultiPageSignupFlowHelpers;`)(signupFlowGlobalScope);
- test('step 2 completes with password step skipped when landing on email verification page', async () => {
- const completedPayloads = [];
- const executor = step2Api.createStep2Executor({
- addLog: async () => {},
- chrome: { tabs: { update: async () => {} } },
- completeStepFromBackground: async (step, payload) => {
- completedPayloads.push({ step, payload });
- },
- ensureContentScriptReadyOnTab: async () => {},
- ensureSignupEntryPageReady: async () => ({ tabId: 11 }),
- ensureSignupPostEmailPageReadyInTab: async () => ({
- state: 'verification_page',
- url: 'https://auth.openai.com/email-verification',
- }),
- getTabId: async () => 11,
- isTabAlive: async () => true,
- resolveSignupEmailForFlow: async () => 'user@example.com',
- sendToContentScriptResilient: async () => ({ submitted: true }),
- SIGNUP_PAGE_INJECT_FILES: [],
- });
- await executor.executeStep2({ email: 'user@example.com' });
- assert.deepStrictEqual(completedPayloads, [
- {
- step: 2,
- payload: {
- email: 'user@example.com',
- nextSignupState: 'verification_page',
- nextSignupUrl: 'https://auth.openai.com/email-verification',
- skippedPasswordStep: true,
- },
- },
- ]);
- });
- test('step 2 keeps password flow when landing on password page', async () => {
- const completedPayloads = [];
- const executor = step2Api.createStep2Executor({
- addLog: async () => {},
- chrome: { tabs: { update: async () => {} } },
- completeStepFromBackground: async (step, payload) => {
- completedPayloads.push({ step, payload });
- },
- ensureContentScriptReadyOnTab: async () => {},
- ensureSignupEntryPageReady: async () => ({ tabId: 12 }),
- ensureSignupPostEmailPageReadyInTab: async () => ({
- state: 'password_page',
- url: 'https://auth.openai.com/create-account/password',
- }),
- getTabId: async () => 12,
- isTabAlive: async () => true,
- resolveSignupEmailForFlow: async () => 'user@example.com',
- sendToContentScriptResilient: async () => ({ submitted: true }),
- SIGNUP_PAGE_INJECT_FILES: [],
- });
- await executor.executeStep2({ email: 'user@example.com' });
- assert.deepStrictEqual(completedPayloads, [
- {
- step: 2,
- payload: {
- email: 'user@example.com',
- nextSignupState: 'password_page',
- nextSignupUrl: 'https://auth.openai.com/create-account/password',
- skippedPasswordStep: false,
- },
- },
- ]);
- });
- test('step 2 retries once after post-email landing check fails', async () => {
- const completedPayloads = [];
- let entryReadyCalls = 0;
- let sendCalls = 0;
- let landingCalls = 0;
- const executor = step2Api.createStep2Executor({
- addLog: async () => {},
- chrome: { tabs: { update: async () => {} } },
- completeStepFromBackground: async (step, payload) => {
- completedPayloads.push({ step, payload });
- },
- ensureContentScriptReadyOnTab: async () => {},
- ensureSignupEntryPageReady: async () => {
- entryReadyCalls += 1;
- return { tabId: 13 };
- },
- ensureSignupPostEmailPageReadyInTab: async () => {
- landingCalls += 1;
- if (landingCalls === 1) {
- throw new Error('等待邮箱提交后的页面跳转超时,请检查页面是否仍停留在邮箱输入页。');
- }
- return {
- state: 'password_page',
- url: 'https://auth.openai.com/create-account/password',
- };
- },
- getTabId: async () => 13,
- isTabAlive: async () => true,
- resolveSignupEmailForFlow: async () => 'user@example.com',
- sendToContentScriptResilient: async () => {
- sendCalls += 1;
- return { submitted: true };
- },
- SIGNUP_PAGE_INJECT_FILES: [],
- });
- await executor.executeStep2({ email: 'user@example.com' });
- assert.equal(entryReadyCalls, 1);
- assert.equal(sendCalls, 2);
- assert.equal(landingCalls, 2);
- assert.deepStrictEqual(completedPayloads, [
- {
- step: 2,
- payload: {
- email: 'user@example.com',
- nextSignupState: 'password_page',
- nextSignupUrl: 'https://auth.openai.com/create-account/password',
- skippedPasswordStep: false,
- },
- },
- ]);
- });
- test('signup flow helper recognizes email verification page as post-email landing page', async () => {
- let ensureCalls = 0;
- let passwordReadyChecks = 0;
- const helpers = signupFlowApi.createSignupFlowHelpers({
- buildGeneratedAliasEmail: () => '',
- chrome: {
- tabs: {
- get: async () => ({
- id: 21,
- url: 'https://auth.openai.com/email-verification',
- }),
- },
- },
- ensureContentScriptReadyOnTab: async () => {
- ensureCalls += 1;
- },
- ensureHotmailAccountForFlow: async () => ({}),
- ensureLuckmailPurchaseForFlow: async () => ({}),
- isGeneratedAliasProvider: () => false,
- isHotmailProvider: () => false,
- isLuckmailProvider: () => false,
- isSignupEmailVerificationPageUrl: (url) => /\/email-verification(?:[/?#]|$)/i.test(url || ''),
- isSignupPasswordPageUrl: (url) => /\/create-account\/password(?:[/?#]|$)/i.test(url || ''),
- reuseOrCreateTab: async () => 21,
- sendToContentScriptResilient: async () => {
- passwordReadyChecks += 1;
- return {};
- },
- setEmailState: async () => {},
- SIGNUP_ENTRY_URL: 'https://chatgpt.com/',
- SIGNUP_PAGE_INJECT_FILES: [],
- waitForTabUrlMatch: async () => ({
- id: 21,
- url: 'https://auth.openai.com/email-verification',
- }),
- });
- const result = await helpers.ensureSignupPostEmailPageReadyInTab(21, 2);
- assert.deepStrictEqual(result, {
- ready: true,
- state: 'verification_page',
- url: 'https://auth.openai.com/email-verification',
- });
- assert.equal(ensureCalls, 1);
- assert.equal(passwordReadyChecks, 0);
- });
- test('signup flow helper reuses existing managed alias email when it is still compatible', async () => {
- let buildCalls = 0;
- let setEmailCalls = 0;
- const helpers = signupFlowApi.createSignupFlowHelpers({
- buildGeneratedAliasEmail: () => {
- buildCalls += 1;
- return 'demo+fresh@gmail.com';
- },
- chrome: { tabs: { get: async () => ({ id: 21, url: 'https://auth.openai.com/create-account/password' }) } },
- ensureContentScriptReadyOnTab: async () => {},
- ensureHotmailAccountForFlow: async () => ({}),
- ensureLuckmailPurchaseForFlow: async () => ({}),
- isGeneratedAliasProvider: () => true,
- isReusableGeneratedAliasEmail: (_state, email) => email === 'demo+saved@gmail.com',
- isHotmailProvider: () => false,
- isLuckmailProvider: () => false,
- isSignupEmailVerificationPageUrl: () => false,
- isSignupPasswordPageUrl: () => true,
- reuseOrCreateTab: async () => 21,
- sendToContentScriptResilient: async () => ({}),
- setEmailState: async () => {
- setEmailCalls += 1;
- },
- SIGNUP_ENTRY_URL: 'https://chatgpt.com/',
- SIGNUP_PAGE_INJECT_FILES: [],
- waitForTabUrlMatch: async () => null,
- });
- const email = await helpers.resolveSignupEmailForFlow({
- mailProvider: 'gmail',
- email: 'demo+saved@gmail.com',
- });
- assert.equal(email, 'demo+saved@gmail.com');
- assert.equal(buildCalls, 0);
- assert.equal(setEmailCalls, 0);
- });
- test('signup flow helper finalizes step 3 submit by reusing signup verification preparation', async () => {
- let ensureCalls = 0;
- const messages = [];
- const sendOptions = [];
- const helpers = signupFlowApi.createSignupFlowHelpers({
- buildGeneratedAliasEmail: () => '',
- chrome: { tabs: { get: async () => ({ id: 31, url: 'https://auth.openai.com/create-account/password' }) } },
- ensureContentScriptReadyOnTab: async (...args) => {
- ensureCalls += 1;
- messages.push({ type: 'ensure', args });
- },
- ensureHotmailAccountForFlow: async () => ({}),
- ensureLuckmailPurchaseForFlow: async () => ({}),
- isGeneratedAliasProvider: () => false,
- isReusableGeneratedAliasEmail: () => false,
- isHotmailProvider: () => false,
- isLuckmailProvider: () => false,
- isSignupEmailVerificationPageUrl: () => false,
- isSignupPasswordPageUrl: () => true,
- reuseOrCreateTab: async () => 31,
- sendToContentScriptResilient: async (_source, message, options) => {
- messages.push({ type: 'send', message });
- sendOptions.push(options);
- return { ready: true, retried: 1 };
- },
- setEmailState: async () => {},
- SIGNUP_ENTRY_URL: 'https://chatgpt.com/',
- SIGNUP_PAGE_INJECT_FILES: ['content/utils.js', 'content/signup-page.js'],
- waitForTabUrlMatch: async () => null,
- });
- const result = await helpers.finalizeSignupPasswordSubmitInTab(31, 'Secret123!', 3);
- assert.deepStrictEqual(result, { ready: true, retried: 1 });
- assert.equal(ensureCalls, 1);
- assert.deepStrictEqual(messages.find((item) => item.type === 'send')?.message, {
- type: 'PREPARE_SIGNUP_VERIFICATION',
- step: 3,
- source: 'background',
- payload: {
- password: 'Secret123!',
- prepareSource: 'step3_finalize',
- prepareLogLabel: '步骤 3 收尾',
- },
- });
- assert.equal(sendOptions[0]?.timeoutMs, 65000);
- });
|