background-step6-retry-limit.test.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. const test = require('node:test');
  2. const assert = require('node:assert/strict');
  3. const fs = require('node:fs');
  4. test('step 6 runs cookie cleanup and completes from background', async () => {
  5. const source = fs.readFileSync('background/steps/clear-login-cookies.js', 'utf8');
  6. const globalScope = {};
  7. const api = new Function('self', `${source}; return self.MultiPageBackgroundStep6;`)(globalScope);
  8. const events = {
  9. cleanupCalls: 0,
  10. completedSteps: [],
  11. };
  12. const executor = api.createStep6Executor({
  13. completeStepFromBackground: async (step) => {
  14. events.completedSteps.push(step);
  15. },
  16. runPreStep6CookieCleanup: async () => {
  17. events.cleanupCalls += 1;
  18. },
  19. });
  20. await executor.executeStep6();
  21. assert.equal(events.cleanupCalls, 1);
  22. assert.deepStrictEqual(events.completedSteps, [6]);
  23. });
  24. test('step 7 retries up to configured limit and then fails', async () => {
  25. const source = fs.readFileSync('background/steps/oauth-login.js', 'utf8');
  26. const globalScope = {};
  27. const api = new Function('self', `${source}; return self.MultiPageBackgroundStep7;`)(globalScope);
  28. const events = {
  29. refreshCalls: 0,
  30. sendCalls: 0,
  31. completed: 0,
  32. };
  33. const executor = api.createStep7Executor({
  34. addLog: async () => {},
  35. completeStepFromBackground: async () => {
  36. events.completed += 1;
  37. },
  38. getErrorMessage: (error) => error?.message || String(error || ''),
  39. getLoginAuthStateLabel: (state) => state || 'unknown',
  40. getState: async () => ({ email: 'user@example.com', password: 'secret' }),
  41. isStep6RecoverableResult: (result) => result?.step6Outcome === 'recoverable',
  42. isStep6SuccessResult: (result) => result?.step6Outcome === 'success',
  43. refreshOAuthUrlBeforeStep6: async () => {
  44. events.refreshCalls += 1;
  45. return `https://oauth.example/${events.refreshCalls}`;
  46. },
  47. reuseOrCreateTab: async () => {},
  48. sendToContentScriptResilient: async () => {
  49. events.sendCalls += 1;
  50. return {
  51. step6Outcome: 'recoverable',
  52. state: 'email_page',
  53. message: '当前仍停留在邮箱页。',
  54. };
  55. },
  56. shouldSkipLoginVerificationForCpaCallback: () => false,
  57. skipLoginVerificationStepsForCpaCallback: async () => {},
  58. STEP6_MAX_ATTEMPTS: 3,
  59. throwIfStopped: () => {},
  60. });
  61. await assert.rejects(
  62. () => executor.executeStep7({ email: 'user@example.com', password: 'secret' }),
  63. /已重试 2 次,仍未成功/
  64. );
  65. assert.equal(events.refreshCalls, 3);
  66. assert.equal(events.sendCalls, 3);
  67. assert.equal(events.completed, 0);
  68. });