or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

configuration.mdcontent-matching.mddialog-management.mdelement-interaction.mdform-handling.mdindex.md
tile.json

content-matching.mddocs/

Content Matching

Content matching and element discovery functionality with text-based filtering, flexible waiting options, and advanced search patterns. These matchers are part of the expect-puppeteer library included with jest-puppeteer and work with global page and element objects.

Capabilities

toMatchElement

Waits for an element to appear and returns an ElementHandle for further interaction. This is a fundamental matcher used by many other matchers internally.

/**
 * Wait for an element to appear and return it for further interaction
 * @param selector - CSS selector or Selector object to identify the element
 * @param options - Element matching options including text filtering and visibility
 * @returns Promise that resolves to ElementHandle when element is found
 */
toMatchElement(selector: string | Selector, options?: ToMatchElementOptions): Promise<ElementHandle<Element>>;

interface ToMatchElementOptions extends Options {
  /** Text content that must be present within the element */
  text?: string | RegExp;
  /** Whether to wait for element to be visible (not just present in DOM) */
  visible?: boolean;
}

Usage Examples:

import { expect } from "expect-puppeteer";

// Find element by selector
const button = await expect(page).toMatchElement("button");

// Find element with specific text
const submitBtn = await expect(page).toMatchElement("button", { 
  text: "Submit Form" 
});

// Find element with regex text matching
const errorMsg = await expect(page).toMatchElement(".alert", { 
  text: /error|failed/i 
});

// Wait for visible element (not just in DOM)
const modal = await expect(page).toMatchElement(".modal", { 
  visible: true 
});

// Find element within another element
const table = await expect(page).toMatchElement("table");
const row = await expect(table).toMatchElement("tr", { 
  text: "John Doe" 
});

// Use returned element for further actions
const userRow = await expect(page).toMatchElement("tr", { text: "Alice" });
await expect(userRow).toClick("button", { text: "Edit" });

// XPath selector usage
const link = await expect(page).toMatchElement({
  type: "xpath",
  value: "//a[contains(@href, '/profile')]"
}, { text: "View Profile" });

toMatchTextContent

Waits for specific text content to appear anywhere in the page or element context. Supports both exact text matching and regular expressions.

/**
 * Wait for specific text content to appear in the page or element
 * @param matcher - Text string or RegExp to match against content
 * @param options - Text matching options including shadow DOM traversal
 * @returns Promise that resolves when text is found
 */
toMatchTextContent(matcher: string | RegExp, options?: MatchTextContentOptions): Promise<void>;

interface MatchTextContentOptions extends Options {
  /** Whether to include content from shadow DOM elements */
  traverseShadowRoots?: boolean;
}

Usage Examples:

import { expect } from "expect-puppeteer";

// Match exact text
await expect(page).toMatchTextContent("Welcome to our website");

// Match with regular expression
await expect(page).toMatchTextContent(/user.*logged.*in/i);

// Match text within specific element context
const notification = await expect(page).toMatchElement(".notification");
await expect(notification).toMatchTextContent("Operation completed successfully");

// Match text including shadow DOM content
await expect(page).toMatchTextContent("Shadow content text", {
  traverseShadowRoots: true
});

// Wait for dynamic content to load
await expect(page).toMatchTextContent(/Loading.*complete|Data.*loaded/);

// Verify error messages
await expect(page).toMatchTextContent("Invalid email address");

// Match multi-line content
await expect(page).toMatchTextContent(/Name:.*John.*Email:.*john@/s);

Negative Matching

Both content matching functions have negative variants accessible via the .not property for testing absence of content.

/**
 * Wait for element to not be present or not match conditions
 * @param selector - CSS selector or Selector object
 * @param options - Element matching options
 */
not.toMatchElement(selector: string | Selector, options?: ToMatchElementOptions): Promise<void>;

/**
 * Wait for text content to not be present
 * @param matcher - Text string or RegExp that should not match
 * @param options - Text matching options
 */
not.toMatchTextContent(matcher: string | RegExp, options?: MatchTextContentOptions): Promise<void>;

Usage Examples:

import { expect } from "expect-puppeteer";

// Verify element is not present
await expect(page).not.toMatchElement(".error-message");

// Verify specific text is not present
await expect(page).not.toMatchTextContent("Page not found");

// Verify element with text is removed
await expect(page).not.toMatchElement(".notification", { 
  text: "Loading..." 
});

// Verify error state is cleared
await expect(page).not.toMatchTextContent(/error|failed/i);

// Verify dynamic content is hidden
const modal = await expect(page).toMatchElement(".modal");
await expect(modal).not.toMatchTextContent("Processing...");

// Verify removal after action
await expect(page).toClick("button", { text: "Delete Item" });
await expect(page).not.toMatchElement(".item", { text: "Item to delete" });

Advanced Text Matching

Text Sanitization

Text matching automatically sanitizes whitespace by:

  • Trimming leading/trailing whitespace
  • Collapsing multiple consecutive whitespace characters into single spaces
  • This ensures robust matching even with dynamic layouts

Regular Expression Patterns

// Case-insensitive matching
await expect(page).toMatchTextContent(/welcome/i);

// Word boundaries
await expect(page).toMatchTextContent(/\\buser\\b/);

// Optional content
await expect(page).toMatchTextContent(/Profile( Page)?/);

// Multiple alternatives
await expect(page).toMatchTextContent(/success|complete|done/i);

// Multiline matching with dotall flag
await expect(page).toMatchTextContent(/Header.*Footer/s);

Shadow DOM Support

When traverseShadowRoots: true is used, the matcher will:

  • Traverse into shadow DOM boundaries
  • Include text content from shadow roots
  • Handle slotted content correctly
  • Process nested shadow DOMs recursively

Performance Considerations

  • Text Matching Performance: Direct selector matching is faster than text-based searches
  • Shadow DOM: traverseShadowRoots option adds overhead but may be necessary for web components
  • Regular Expressions: Complex regex patterns may impact performance on large pages
  • Element Context: Matching within specific elements (using returned ElementHandles) is more efficient than page-wide searches