| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- (function authPageRecoveryModule(root, factory) {
- if (typeof module !== 'undefined' && module.exports) {
- module.exports = factory();
- return;
- }
- root.MultiPageAuthPageRecovery = factory();
- })(typeof self !== 'undefined' ? self : globalThis, function createAuthPageRecoveryModule() {
- function createAuthPageRecovery(deps = {}) {
- const {
- detailPattern = null,
- getActionText,
- getPageTextSnapshot,
- humanPause,
- isActionEnabled,
- isVisibleElement,
- log,
- simulateClick,
- sleep,
- throwIfStopped,
- titlePattern = null,
- } = deps;
- function matchesPathPatterns(pathname, pathPatterns = []) {
- if (!Array.isArray(pathPatterns) || !pathPatterns.length) {
- return true;
- }
- return pathPatterns.some((pattern) => pattern instanceof RegExp && pattern.test(pathname));
- }
- function getAuthRetryButton(options = {}) {
- const { allowDisabled = false } = options;
- const direct = document.querySelector('button[data-dd-action-name="Try again"]');
- if (direct && isVisibleElement(direct) && (allowDisabled || isActionEnabled(direct))) {
- return direct;
- }
- const candidates = document.querySelectorAll('button, [role="button"]');
- return Array.from(candidates).find((element) => {
- if (!isVisibleElement(element) || (!allowDisabled && !isActionEnabled(element))) {
- return false;
- }
- const text = typeof getActionText === 'function' ? getActionText(element) : '';
- return /重试|try\s+again/i.test(text);
- }) || null;
- }
- function getAuthTimeoutErrorPageState(options = {}) {
- const { pathPatterns = [] } = options;
- const pathname = location.pathname || '';
- if (!matchesPathPatterns(pathname, pathPatterns)) {
- return null;
- }
- const retryButton = getAuthRetryButton({ allowDisabled: true });
- if (!retryButton) {
- return null;
- }
- const text = typeof getPageTextSnapshot === 'function' ? getPageTextSnapshot() : '';
- const title = typeof document !== 'undefined' ? String(document.title || '') : '';
- const titleMatched = titlePattern instanceof RegExp
- ? titlePattern.test(text) || titlePattern.test(title)
- : false;
- const detailMatched = detailPattern instanceof RegExp
- ? detailPattern.test(text)
- : false;
- if (!titleMatched && !detailMatched) {
- return null;
- }
- return {
- path: pathname,
- url: location.href,
- retryButton,
- retryEnabled: isActionEnabled(retryButton),
- titleMatched,
- detailMatched,
- };
- }
- async function waitForRetryPageRecoveryAfterClick(options = {}) {
- const {
- pathPatterns = [],
- pollIntervalMs = 250,
- settleAfterClickMs = 3000,
- } = options;
- const startedAt = Date.now();
- while (Date.now() - startedAt < settleAfterClickMs) {
- if (typeof throwIfStopped === 'function') {
- throwIfStopped();
- }
- const retryState = getAuthTimeoutErrorPageState({ pathPatterns });
- if (!retryState) {
- return {
- recovered: true,
- elapsedMs: Date.now() - startedAt,
- };
- }
- await sleep(pollIntervalMs);
- }
- return {
- recovered: false,
- elapsedMs: Date.now() - startedAt,
- };
- }
- async function recoverAuthRetryPage(options = {}) {
- const {
- logLabel = '',
- pathPatterns = [],
- pollIntervalMs = 250,
- step = null,
- timeoutMs = 12000,
- waitAfterClickMs = 3000,
- } = options;
- const start = Date.now();
- let clickCount = 0;
- while (Date.now() - start < timeoutMs) {
- if (typeof throwIfStopped === 'function') {
- throwIfStopped();
- }
- const retryState = getAuthTimeoutErrorPageState({ pathPatterns });
- if (!retryState) {
- return {
- recovered: clickCount > 0,
- clickCount,
- url: location.href,
- };
- }
- if (retryState.retryButton && retryState.retryEnabled) {
- clickCount += 1;
- if (typeof log === 'function') {
- const prefix = logLabel || `步骤 ${step || '?'}:检测到重试页,正在点击“重试”恢复`;
- log(`${prefix}(第 ${clickCount} 次)...`, 'warn');
- }
- if (typeof humanPause === 'function') {
- await humanPause(300, 800);
- }
- simulateClick(retryState.retryButton);
- const recoveryResult = await waitForRetryPageRecoveryAfterClick({
- pathPatterns,
- pollIntervalMs,
- settleAfterClickMs: waitAfterClickMs,
- });
- if (recoveryResult.recovered) {
- return {
- recovered: true,
- clickCount,
- url: location.href,
- };
- }
- continue;
- }
- await sleep(pollIntervalMs);
- }
- throw new Error(
- `${logLabel || `步骤 ${step || '?'}:重试页恢复`}超时。URL: ${location.href}`
- );
- }
- return {
- getAuthRetryButton,
- getAuthTimeoutErrorPageState,
- recoverAuthRetryPage,
- };
- }
- return {
- createAuthPageRecovery,
- };
- });
|