CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-wd

WebDriver/Selenium 2 Node.js client for browser automation and testing

Pending
Overview
Eval results
Files

waiting.mddocs/

Waiting & Synchronization

Powerful waiting mechanisms with built-in asserters for handling dynamic content and asynchronous operations in web applications.

Capabilities

General Waiting

Wait for custom conditions using asserter functions.

/**
 * Wait for a condition to be satisfied using an asserter
 * @param asserter - Asserter function or object
 * @param timeout - Maximum wait time in milliseconds (default: 1000)
 * @param pollFreq - Polling frequency in milliseconds (default: 200)
 * @param cb - Callback receiving (err, value)
 */
waitFor(asserter: Asserter, timeout?: number, pollFreq?: number, cb?: callback): any;

/**
 * Base asserter class for creating custom wait conditions
 */
class Asserter {
  constructor(assertFunction: (target: any, callback: function) => void);
}

Usage Examples:

const wd = require('wd');

// Wait for element to have non-empty text
browser.elementById('status-message', function(err, element) {
  browser.waitFor(wd.asserters.nonEmptyText, 5000, function(err, value) {
    console.log('Element now has text:', value);
  });
});

// Custom asserter
const customAsserter = new wd.Asserter(function(target, callback) {
  target.text(function(err, text) {
    if (err) return callback(err);
    const satisfied = text.includes('Success');
    callback(null, satisfied, text);
  });
});

browser.elementById('result', function(err, element) {
  browser.waitFor(customAsserter, 10000, function(err, text) {
    console.log('Success message appeared:', text);
  });
});

Element Waiting

Wait for elements to exist, be visible, or meet other conditions.

/**
 * Wait for element to exist in DOM
 * @param using - Selector strategy
 * @param value - Selector value
 * @param timeout - Maximum wait time in milliseconds
 * @param cb - Callback receiving (err, element)
 */
waitForElement(using: string, value: string, timeout?: number, cb?: callback): Element;

/**
 * Wait for multiple elements to exist
 * @param using - Selector strategy
 * @param value - Selector value
 * @param timeout - Maximum wait time in milliseconds
 * @param cb - Callback receiving (err, elements)
 */
waitForElements(using: string, value: string, timeout?: number, cb?: callback): Element[];

/**
 * Wait for element to be visible
 * @param using - Selector strategy
 * @param value - Selector value
 * @param timeout - Maximum wait time in milliseconds
 * @param pollFreq - Polling frequency in milliseconds
 * @param cb - Callback receiving (err, element)
 */
waitForVisible(using: string, value: string, timeout?: number, pollFreq?: number, cb?: callback): Element;

/**
 * Wait for element by ID
 * @param id - Element ID
 * @param timeout - Maximum wait time in milliseconds
 * @param cb - Callback receiving (err, element)
 */
waitForElementById(id: string, timeout?: number, cb?: callback): Element;

/**
 * Wait for element by CSS selector
 * @param selector - CSS selector
 * @param timeout - Maximum wait time in milliseconds
 * @param cb - Callback receiving (err, element)
 */
waitForElementByCss(selector: string, timeout?: number, cb?: callback): Element;

Usage Examples:

// Wait for dynamically loaded element
browser.waitForElementById('dynamic-content', 10000, function(err, element) {
  if (err) {
    console.log('Element did not appear within 10 seconds');
    return;
  }
  console.log('Dynamic content loaded');
  element.text(function(err, text) {
    console.log('Content:', text);
  });
});

// Wait for AJAX-loaded elements
browser.waitForElementsByCss('.search-result', 15000, function(err, results) {
  console.log('Found', results.length, 'search results');
});

// Wait for element to be visible (not just present in DOM)
browser.waitForVisible('css selector', '.modal-dialog', 5000, function(err, modal) {
  console.log('Modal dialog is now visible');
});

// Promise chain waiting
browser
  .elementById('search-button')
  .click()
  .waitForElementsByCss('.search-result', 10000)
  .then(results => {
    console.log('Search completed with', results.length, 'results');
  });

JavaScript Condition Waiting

Wait for JavaScript expressions to evaluate to true.

/**
 * Wait for JavaScript condition to be true
 * @param jsCondition - JavaScript expression as string
 * @param timeout - Maximum wait time in milliseconds
 * @param pollFreq - Polling frequency in milliseconds
 * @param cb - Callback receiving (err, value)
 */
waitForJsCondition(jsCondition: string, timeout?: number, pollFreq?: number, cb?: callback): any;

/**
 * Alias for waitForJsCondition
 */
waitForCondition(jsCondition: string, timeout?: number, pollFreq?: number, cb?: callback): any;

/**
 * Wait for JavaScript condition evaluated in browser context
 * @param jsCondition - JavaScript expression as string
 * @param timeout - Maximum wait time in milliseconds
 * @param pollFreq - Polling frequency in milliseconds
 * @param cb - Callback receiving (err, value)
 */
waitForConditionInBrowser(jsCondition: string, timeout?: number, pollFreq?: number, cb?: callback): any;

Usage Examples:

// Wait for AJAX request to complete
browser.waitForJsCondition('window.ajaxInProgress === false', 10000, function(err) {
  console.log('AJAX requests completed');
});

// Wait for JavaScript library to load
browser.waitForCondition('typeof jQuery !== "undefined"', 5000, function(err) {
  console.log('jQuery library loaded');
});

// Wait for custom application state
browser.waitForConditionInBrowser('window.app && window.app.isReady', 15000, function(err) {
  console.log('Application is ready');
});

// Wait for element count condition
browser.waitForJsCondition(
  'document.querySelectorAll(".item").length >= 5',
  8000,
  function(err) {
    console.log('At least 5 items are now present');
  }
);

// Promise chain JS condition waiting
browser
  .elementById('load-more')
  .click()
  .waitForCondition('document.querySelector(".loading") === null', 10000)
  .then(() => {
    console.log('Loading spinner disappeared');
  });

Built-in Asserters

Pre-built asserter functions for common waiting scenarios.

const asserters: {
  /**
   * Assert element has non-empty text content
   */
  nonEmptyText: Asserter;
  
  /**
   * Assert element text includes specific content
   * @param content - Text content to look for
   */
  textInclude(content: string): Asserter;
  
  /**
   * Assert element is displayed (visible)
   */
  isDisplayed: Asserter;
  
  /**
   * Assert element is not displayed (hidden)
   */
  isNotDisplayed: Asserter;
  
  /**
   * Assert JavaScript condition evaluates to true
   * @param jsExpr - JavaScript expression
   * @param safe - Use safe execution (default: true)
   */
  jsCondition(jsExpr: string, safe?: boolean): Asserter;
  
  // Deprecated asserters (use alternatives above)
  isVisible: Asserter;      // Use isDisplayed
  isHidden: Asserter;       // Use isNotDisplayed
};

Usage Examples:

const wd = require('wd');

// Wait for element to have text
browser.elementById('message', function(err, element) {
  browser.waitFor(wd.asserters.nonEmptyText, 5000, function(err, text) {
    console.log('Message appeared:', text);
  });
});

// Wait for specific text content
browser.elementById('status', function(err, element) {
  const successAsserter = wd.asserters.textInclude('Success');
  browser.waitFor(successAsserter, 10000, function(err, text) {
    console.log('Success status confirmed:', text);
  });
});

// Wait for element to become visible
browser.elementByCss('.hidden-initially', function(err, element) {
  browser.waitFor(wd.asserters.isDisplayed, 3000, function(err) {
    console.log('Element is now visible');
  });
});

// Wait for element to be hidden
browser.elementById('loading-spinner', function(err, element) {
  browser.waitFor(wd.asserters.isNotDisplayed, 15000, function(err) {
    console.log('Loading spinner is now hidden');
  });
});

// Wait for JavaScript condition
const jsAsserter = wd.asserters.jsCondition('window.dataLoaded === true');
browser.waitFor(jsAsserter, 8000, function(err) {
  console.log('Data loading completed');
});

Advanced Waiting Patterns

Complex waiting scenarios combining multiple conditions.

Usage Examples:

// Wait for multiple conditions in sequence
browser
  .elementById('submit-form')
  .click()
  .waitFor(wd.asserters.jsCondition('document.querySelector(".loading")'), 1000) // Loading appears
  .waitFor(wd.asserters.jsCondition('!document.querySelector(".loading")'), 10000) // Loading disappears
  .waitForElementById('success-message', 5000)
  .text()
  .then(message => console.log('Form submitted:', message));

// Custom asserter for complex conditions
const complexAsserter = new wd.Asserter(function(browser, callback) {
  browser.elementsByCss('.item', function(err, items) {
    if (err) return callback(err);
    
    if (items.length < 3) {
      return callback(null, false); // Not satisfied yet
    }
    
    // Check if all items are visible
    let visibleCount = 0;
    let completed = 0;
    
    items.forEach((item, index) => {
      item.isDisplayed(function(err, visible) {
        if (visible) visibleCount++;
        completed++;
        
        if (completed === items.length) {
          const satisfied = visibleCount >= 3;
          callback(null, satisfied, visibleCount);
        }
      });
    });
  });
});

browser.waitFor(complexAsserter, 10000, function(err, visibleCount) {
  console.log('At least 3 items are visible:', visibleCount);
});

// Timeout handling
browser.waitForElementById('slow-element', 5000, function(err, element) {
  if (err && err.message.includes('timeout')) {
    console.log('Element did not appear within timeout, continuing with fallback');
    // Implement fallback behavior
  } else if (err) {
    throw err;
  } else {
    console.log('Element found:', element);
  }
});

Simple Sleep

Basic sleep functionality for fixed delays.

/**
 * Sleep for specified duration
 * @param ms - Duration in milliseconds
 * @param cb - Callback receiving (err)
 */
sleep(ms: number, cb?: callback): void;

Usage Examples:

// Simple delay
browser.sleep(2000, function() {
  console.log('Waited 2 seconds');
});

// Promise chain with sleep
browser
  .elementById('animate-button')
  .click()
  .sleep(1000)  // Wait for animation
  .elementByCss('.animated-element')
  .isDisplayed()
  .then(visible => console.log('Animation completed:', visible));

Install with Tessl CLI

npx tessl i tessl/npm-wd

docs

browser-sessions.md

configuration.md

element-location.md

index.md

javascript-execution.md

mobile-testing.md

navigation.md

touch-actions.md

user-input.md

waiting.md

window-management.md

tile.json