> ## Documentation Index
> Fetch the complete documentation index at: https://intunedhq.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# clickUntilExhausted

Repeatedly click a button until no new content appears or max clicks reached.

This function is useful for "Load More" buttons or paginated content where you need to
keep clicking until all content is loaded. It provides several stopping conditions:

* Button becomes invisible/disabled
* Maximum number of clicks reached
* No change detected in container content (when containerLocator is provided)

```typescript theme={null}
export declare function clickUntilExhausted(input: {
  page: Page;
  buttonLocator: Locator;
  heartbeat?: CallableFunction;
  containerLocator?: Locator;
  maxClicks?: number;
  clickDelay?: number;
  noChangeThreshold?: number;
}): Promise<void>;
```

## Examples

<CodeGroup>
  ```typescript Load All Items theme={null}
  import { clickUntilExhausted } from "@intuned/browser";
  import { BrowserContext, Page } from "playwright";

  interface Params {}

  export default async function handler(
    params: Params,
    page: Page,
    context: BrowserContext
  ) {
    await page.goto("https://sandbox.intuned.dev/load-more");
    const loadMoreButton = page.locator("main main button"); // Select the main button in the main content area.

    // Click until button disappears or is disabled
    await clickUntilExhausted({
      page,
      buttonLocator: loadMoreButton,
      maxClicks: 20,
    });
    // Will keep clicking the button until the button disappears or is disabled or the maxClicks is reached.
  }
  ```

  ```typescript Track Container Changes theme={null}
  import { clickUntilExhausted } from "@intuned/browser";
  import { BrowserContext, Page } from "playwright";

  interface Params {}

  export default async function handler(
    params: Params,
    page: Page,
    context: BrowserContext
  ) {
    await page.goto("https://sandbox.intuned.dev/load-more");
    const loadMoreButton = page.locator("aside button"); // Select the button in the sidebar.
    const container = page.locator(
      'xpath=//*[@id="root"]/div[1]/main/slot/div/aside/div/div/slot/slot'
    ); // Watch the sidebar container to detect changes.
    // This will count the elements under the container given before each click and after, if the count is the same, the function will stop.
    let clickCount = 0;
    await clickUntilExhausted({
      page,
      buttonLocator: loadMoreButton,
      containerLocator: container,
      heartbeat: () => {
        clickCount++;
        console.log(`Clicked ${clickCount} times`);
      },
      maxClicks: 30,
      clickDelay: 0.5,
      noChangeThreshold: 0,
    });
    // Will keep clicking the button until the button disappears or is disabled or the maxClicks is reached or no more content is loaded.
  }
  ```
</CodeGroup>

## Arguments

<ResponseField name="input" type="Object" required>
  Configuration options

  <Expandable title="properties" defaultOpen>
    <ResponseField name="input.page" type="Page" required>
      Playwright Page object
    </ResponseField>

    <ResponseField name="input.buttonLocator" type="Locator" required>
      Locator for the button to click repeatedly
    </ResponseField>

    <ResponseField name="input.heartbeat" type="CallableFunction">
      Optional callback invoked after each click
    </ResponseField>

    <ResponseField name="input.containerLocator" type="Locator">
      Optional content container to detect changes
    </ResponseField>

    <ResponseField name="input.maxClicks" type="number">
      Maximum number of times to click the button. Defaults to 50.
    </ResponseField>

    <ResponseField name="input.clickDelay" type="number">
      Delay after each click (in seconds). Defaults to 0.5.
    </ResponseField>

    <ResponseField name="input.noChangeThreshold" type="number">
      Minimum change in content size to continue clicking. Defaults to 0.
    </ResponseField>
  </Expandable>
</ResponseField>

## Returns: `Promise<void>`

Promise that resolves when clicking is exhausted
