UNPKG

@coinbase/onchaintestkit

Version:

End-to-end testing toolkit for blockchain applications, powered by Playwright

107 lines (106 loc) 3.87 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LoadingStateDetector = void 0; const ConditionWatcher_1 = require("./ConditionWatcher"); /** * Simple loading state detector that waits for loading indicators to disappear */ class LoadingStateDetector { constructor(page, options = {}) { this.page = page; this.options = { timeout: 30000, ...options, }; } /** * Wait for all loading indicators to disappear */ async waitForLoadingComplete() { const allSelectors = [ ...LoadingStateDetector.COMMON_LOADING_SELECTORS, ...(this.options.customLoadingSelectors ?? []), ]; // Wait for each loading indicator to disappear for (const element of allSelectors) { try { await ConditionWatcher_1.ConditionWatcher.waitForCondition(async () => { const locator = this.page.locator(element.selector); const count = await locator.count(); if (count === 0) { return true; // No loading elements found - good! } // Check if any are visible const visibleCount = await locator.locator("visible=true").count(); if (visibleCount === 0) { return true; // All are hidden - good! } return null; // Still have visible loading elements }, this.options.timeout, `${element.description} to disappear`); } catch (_error) { // If we can't find the selector, that's actually good - it means no loading elements console.log(`Loading check for "${element.description}" completed (${element.selector})`); } } } /** * Static helper method for quick loading completion check */ static async waitForPageLoadingComplete(page, timeout = 10000, customSelectors) { const detector = new LoadingStateDetector(page, { timeout, customLoadingSelectors: customSelectors, }); await detector.waitForLoadingComplete(); } } exports.LoadingStateDetector = LoadingStateDetector; // Common loading element patterns that should disappear when loading is complete LoadingStateDetector.COMMON_LOADING_SELECTORS = [ // Spinners { selector: '[data-testid*="loading"], [data-testid*="spinner"]', description: "loading/spinner elements", }, { selector: ".loading, .spinner, .rotating", description: "loading classes", }, { selector: '[class*="loading"], [class*="spinner"], [class*="rotating"]', description: "loading class patterns", }, // Skeleton loaders { selector: '.skeleton, [class*="skeleton"]', description: "skeleton loaders", }, { selector: '[data-testid*="skeleton"]', description: "skeleton test elements", }, // Progress indicators { selector: '.progress, [class*="progress"]', description: "progress indicators", }, { selector: 'progress, [role="progressbar"]', description: "progress bars", }, // Text-based loading { selector: "text=Loading", description: "loading text" }, { selector: "text=Please wait", description: "wait text" }, { selector: "text=Processing", description: "processing text" }, { selector: '[aria-label*="loading"], [aria-label*="Loading"]', description: "loading aria labels", }, // Generic busy states { selector: '[aria-busy="true"]', description: "busy elements" }, { selector: '[data-loading="true"]', description: "loading data attributes", }, ];