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

# Tab

> Control browser tabs, navigate pages, and interact with elements

## Overview

The `Tab` class represents a browser tab (or target) and provides methods for navigation, element interaction, and page manipulation. A tab could be a browser window, an iframe, a service worker, or a background script.

<Note>
  Tab objects are created by the Browser. Access them via `browser.tabs`, `browser.main_tab`, or by calling `browser.get()`.
</Note>

## Properties

<ResponseField name="browser" type="Browser">
  Reference to the parent Browser instance.
</ResponseField>

<ResponseField name="url" type="str">
  Current URL of the tab (updated when you `await tab`).
</ResponseField>

<ResponseField name="target_id" type="str">
  Unique identifier for this target.
</ResponseField>

<ResponseField name="type_" type="str">
  Type of target: "page", "iframe", "worker", etc.
</ResponseField>

<ResponseField name="frame_id" type="str">
  Frame identifier for the current page.
</ResponseField>

<ResponseField name="inspector_url" type="str">
  URL to open Chrome DevTools inspector for this tab.
</ResponseField>

## Element Finding Methods

### find()

Find a single element by text content. Retries until timeout if not found.

```python theme={null}
async def find(
    self,
    text: str,
    best_match: bool = True,
    return_enclosing_element: bool = True,
    timeout: Union[int, float] = 10,
) -> Element
```

<ParamField path="text" type="str" required>
  Text to search for. Script contents are also considered text.
</ParamField>

<ParamField path="best_match" type="bool" default="True">
  When True, returns the element with the most similar text length. This helps find specific elements like a "login" button instead of scripts containing "login". When False, returns the first match (faster).
</ParamField>

<ParamField path="return_enclosing_element" type="bool" default="True">
  When True, returns the parent element containing the text node. Set to False to get the text node itself.
</ParamField>

<ParamField path="timeout" type="float | int" default="10">
  Maximum seconds to wait for the element to appear.
</ParamField>

**Example:**

```python theme={null}
# Find login button
login_btn = await tab.find('Login')
await login_btn.click()

# Find with exact first match (faster)
heading = await tab.find('Welcome', best_match=False)
```

### select()

Find a single element by CSS selector. Retries until timeout if not found.

```python theme={null}
async def select(
    self,
    selector: str,
    timeout: Union[int, float] = 10,
) -> Element
```

<ParamField path="selector" type="str" required>
  CSS selector string (e.g., `a[href]`, `button[class*=close]`, `a > img[src]`).
</ParamField>

<ParamField path="timeout" type="float | int" default="10">
  Maximum seconds to wait for the element to appear.
</ParamField>

**Example:**

```python theme={null}
# Find submit button
submit = await tab.select('button[type="submit"]')
await submit.click()

# Find link with specific class
link = await tab.select('a.external-link')
print(link.attrs.href)
```

### find\_all()

Find multiple elements by text content.

```python theme={null}
async def find_all(
    self,
    text: str,
    timeout: Union[int, float] = 10,
) -> List[Element]
```

<ParamField path="text" type="str" required>
  Text to search for.
</ParamField>

<ParamField path="timeout" type="float | int" default="10">
  Maximum seconds to wait.
</ParamField>

**Example:**

```python theme={null}
# Find all "Read more" links
links = await tab.find_all('Read more')
for link in links:
    await link.click()
    await tab.wait(1)
```

### select\_all()

Find multiple elements by CSS selector.

```python theme={null}
async def select_all(
    self, 
    selector: str, 
    timeout: Union[int, float] = 10, 
    include_frames: bool = False
) -> List[Element]
```

<ParamField path="selector" type="str" required>
  CSS selector string.
</ParamField>

<ParamField path="timeout" type="float | int" default="10">
  Maximum seconds to wait.
</ParamField>

<ParamField path="include_frames" type="bool" default="False">
  Whether to include results from iframes.
</ParamField>

**Example:**

```python theme={null}
# Get all images
images = await tab.select_all('img')
for img in images:
    print(img.attrs.src)

# Get all inputs including those in iframes
inputs = await tab.select_all('input', include_frames=True)
```

### xpath()

Find elements by XPath expression.

```python theme={null}
async def xpath(
    self, 
    xpath: str, 
    timeout: float = 2.5
) -> List[Element]
```

<ParamField path="xpath" type="str" required>
  XPath expression string.
</ParamField>

<ParamField path="timeout" type="float" default="2.5">
  Maximum seconds to wait.
</ParamField>

**Example:**

```python theme={null}
# Find all inline scripts (without src attribute)
scripts = await tab.xpath('//script[not(@src)]')

# Case-insensitive text search
elems = await tab.xpath(
    '//text()[contains(translate(., "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz"), "test")]'
)
```

### query\_selector()

Low-level CSS selector query (equivalent to `document.querySelector`).

```python theme={null}
async def query_selector(
    self, 
    selector: str
) -> Element
```

### query\_selector\_all()

Low-level CSS selector query for multiple elements (equivalent to `document.querySelectorAll`).

```python theme={null}
async def query_selector_all(
    self, 
    selector: str
) -> List[Element]
```

## Navigation Methods

### get()

Navigate to a URL.

```python theme={null}
async def get(
    self, 
    url: str = "chrome://welcome", 
    new_tab: bool = False, 
    new_window: bool = False
) -> Tab
```

<ParamField path="url" type="str" default="chrome://welcome">
  URL to navigate to.
</ParamField>

<ParamField path="new_tab" type="bool" default="False">
  Open in a new tab.
</ParamField>

<ParamField path="new_window" type="bool" default="False">
  Open in a new window.
</ParamField>

**Example:**

```python theme={null}
# Navigate in current tab
await tab.get('https://example.com')

# Open in new tab
new_tab = await tab.get('https://example.org', new_tab=True)
```

### back()

Navigate back in history.

```python theme={null}
async def back(self)
```

### forward()

Navigate forward in history.

```python theme={null}
async def forward(self)
```

### reload()

Reload the current page.

```python theme={null}
async def reload(
    self,
    ignore_cache: bool = True,
    script_to_evaluate_on_load: str = None
)
```

<ParamField path="ignore_cache" type="bool" default="True">
  Whether to bypass the cache.
</ParamField>

<ParamField path="script_to_evaluate_on_load" type="str" default="None">
  JavaScript to execute when the page loads.
</ParamField>

**Example:**

```python theme={null}
# Navigate through history
await tab.get('https://example.com')
await tab.get('https://example.org')
await tab.back()  # Back to example.com
await tab.forward()  # Forward to example.org
await tab.reload()  # Refresh page
```

## Page Content Methods

### get\_content()

Get the HTML content of the page.

```python theme={null}
async def get_content(self) -> str
```

**Example:**

```python theme={null}
html = await tab.get_content()
print(html)
```

### evaluate()

Execute JavaScript and get the result.

```python theme={null}
async def evaluate(
    self, 
    expression: str, 
    await_promise: bool = False,
    return_by_value: bool = True,
    max_depth: int = 2
)
```

<ParamField path="expression" type="str" required>
  JavaScript expression to evaluate.
</ParamField>

<ParamField path="await_promise" type="bool" default="False">
  Whether to await the result if it's a Promise.
</ParamField>

<ParamField path="return_by_value" type="bool" default="True">
  Return the value directly instead of a remote object reference.
</ParamField>

**Example:**

```python theme={null}
# Get page title
title = await tab.evaluate('document.title')

# Get multiple values
data = await tab.evaluate('''
    ({
        title: document.title,
        url: window.location.href,
        cookies: document.cookie
    })
''')
print(data)
```

### js\_dumps()

Dump a JavaScript object with its properties and values as a Python dictionary.

```python theme={null}
async def js_dumps(
    self,
    obj_name: str,
    return_by_value: bool = True
) -> Union[Dict, Tuple]
```

<ParamField path="obj_name" type="str" required>
  Name of the JavaScript object to dump (e.g., "window", "document", "navigator").
</ParamField>

<ParamField path="return_by_value" type="bool" default="True">
  Return the value directly as a dict. If False, returns the remote object reference.
</ParamField>

<Note>
  Complex objects might not be fully serializable. This method provides a best-effort conversion to Python dictionaries.
</Note>

**Example:**

```python theme={null}
# Dump the navigator object
navigator_data = await tab.js_dumps('navigator')
print(navigator_data['userAgent'])
print(navigator_data['platform'])

# Dump window.performance
performance = await tab.js_dumps('window.performance')
```

## Window Management

### maximize()

Maximize the window.

```python theme={null}
async def maximize(self)
```

### minimize()

Minimize the window.

```python theme={null}
async def minimize(self)
```

### fullscreen()

Set window to fullscreen.

```python theme={null}
async def fullscreen(self)
```

### medimize()

Restore window to normal size (not minimized, maximized, or fullscreen).

```python theme={null}
async def medimize(self)
```

<Note>
  This is a convenience alias for `set_window_state(state="normal")`.
</Note>

### set\_window\_size()

Set window position and size.

```python theme={null}
async def set_window_size(
    self, 
    left: int = 0, 
    top: int = 0, 
    width: int = 1280, 
    height: int = 1024
)
```

**Example:**

```python theme={null}
# Set custom window size
await tab.set_window_size(0, 0, 1920, 1080)

# Maximize window
await tab.maximize()
```

### activate()

Bring this tab to the front.

```python theme={null}
async def activate(self)
```

### close()

Close this tab.

```python theme={null}
async def close(self)
```

## Scrolling Methods

### scroll\_down()

Scroll down by a specified amount.

```python theme={null}
async def scroll_down(self, amount: int = 25)
```

### scroll\_up()

Scroll up by a specified amount.

```python theme={null}
async def scroll_up(self, amount: int = 25)
```

**Example:**

```python theme={null}
# Scroll down 100 pixels
await tab.scroll_down(100)

# Scroll up 50 pixels
await tab.scroll_up(50)
```

## Mouse Interaction

### mouse\_move()

Move the mouse to specific coordinates.

```python theme={null}
async def mouse_move(
    self, 
    x: float, 
    y: float, 
    steps: int = 10, 
    flash: bool = False
)
```

<ParamField path="x" type="float" required>
  X coordinate.
</ParamField>

<ParamField path="y" type="float" required>
  Y coordinate.
</ParamField>

<ParamField path="steps" type="int" default="10">
  Number of steps for smooth movement.
</ParamField>

<ParamField path="flash" type="bool" default="False">
  Flash the point for visibility.
</ParamField>

### mouse\_click()

Click at specific coordinates.

```python theme={null}
async def mouse_click(
    self,
    x: float = None,
    y: float = None,
    button: str = 'left',
    buttons: int = 1,
    modifiers: int = 0,
    click_count: int = 1
)
```

### mouse\_drag()

Drag from one position to another.

```python theme={null}
async def mouse_drag(
    self,
    from_x: float,
    from_y: float,
    to_x: float,
    to_y: float,
    steps: int = 20
)
```

## Screenshots

### save\_screenshot()

Save a screenshot of the page.

```python theme={null}
async def save_screenshot(
    self,
    filename: str = 'screenshot.png',
    format: str = 'png',
    full_page: bool = False
)
```

<ParamField path="filename" type="str" default="screenshot.png">
  Path to save the screenshot.
</ParamField>

<ParamField path="format" type="str" default="png">
  Image format: 'png' or 'jpeg'.
</ParamField>

<ParamField path="full_page" type="bool" default="False">
  Capture the entire page, not just the viewport.
</ParamField>

**Example:**

```python theme={null}
# Save viewport screenshot
await tab.save_screenshot('page.png')

# Save full page screenshot
await tab.save_screenshot('fullpage.png', full_page=True)

# Save as JPEG
await tab.save_screenshot('page.jpg', format='jpeg')
```

## File Downloads

### download\_file()

Download a file from a URL.

```python theme={null}
async def download_file(
    self, 
    url: str, 
    filename: Optional[PathLike] = None
) -> pathlib.Path
```

<ParamField path="url" type="str" required>
  URL of the file to download.
</ParamField>

<ParamField path="filename" type="PathLike" default="None">
  Optional filename. If None, uses the filename from the URL.
</ParamField>

**Example:**

```python theme={null}
# Download file
path = await tab.download_file(
    'https://example.com/file.pdf',
    'downloaded.pdf'
)
print(f"Downloaded to: {path}")
```

### set\_download\_path()

Set the default download directory.

```python theme={null}
async def set_download_path(self, path: Union[str, PathLike])
```

## Storage Methods

### get\_local\_storage()

Get all localStorage items.

```python theme={null}
async def get_local_storage(self) -> dict
```

### set\_local\_storage()

Set localStorage items.

```python theme={null}
async def set_local_storage(self, items: dict)
```

**Example:**

```python theme={null}
# Set localStorage
await tab.set_local_storage({
    'theme': 'dark',
    'user': 'john'
})

# Get localStorage
storage = await tab.get_local_storage()
print(storage)
```

## Anti-Detection & Security

### verify\_cf()

Verify Cloudflare checkbox challenge automatically. This method locates and clicks the Cloudflare verification checkbox.

```python theme={null}
async def verify_cf(
    self,
    template_image: str = None,
    flash: bool = False
)
```

<ParamField path="template_image" type="str" default="None">
  Custom template image for locating the checkbox. The default template is in English. If you need a different language, create a cropped image (111x71 pixels) with the checkbox target centered.
</ParamField>

<ParamField path="flash" type="bool" default="False">
  If True, flashes the located checkbox area for debugging.
</ParamField>

<Warning>
  This method only works when NOT in expert mode. Requires the `opencv-python` package to be installed.
</Warning>

**Example:**

```python theme={null}
# Verify Cloudflare challenge
await tab.verify_cf()

# Use custom template for different language
await tab.verify_cf(template_image='path/to/custom_cf_template.png')
```

### bypass\_insecure\_connection\_warning()

Bypass the browser's insecure connection warning (e.g., when a certificate is invalid).

```python theme={null}
async def bypass_insecure_connection_warning(self)
```

<Note>
  This method sends the special string "thisisunsafe" to bypass Chrome's SSL warning page.
</Note>

**Example:**

```python theme={null}
# Navigate to site with invalid certificate
await tab.get('https://site-with-invalid-cert.com')

# Bypass the warning
await tab.bypass_insecure_connection_warning()
```

## Waiting and Timing

### wait()

Wait for a specified time.

```python theme={null}
async def wait(self, t: Union[int, float] = 0.5)
```

### sleep()

Alias for `wait()`.

```python theme={null}
async def sleep(self, t: float | int = 1)
```

### wait\_for()

Wait for a condition to be true.

```python theme={null}
async def wait_for(
    self,
    condition: Callable,
    timeout: float = 10
)
```

**Example:**

```python theme={null}
# Wait 2 seconds
await tab.wait(2)

# Wait for element to appear
await tab.wait_for(lambda: tab.select('button#submit', timeout=0.1))
```

## Inspector

### open\_external\_inspector()

Open Chrome DevTools inspector in your system browser.

```python theme={null}
async def open_external_inspector(self)
```

**Example:**

```python theme={null}
# Open inspector for debugging
await tab.open_external_inspector()
```

## Custom CDP Commands

Send custom Chrome DevTools Protocol commands:

```python theme={null}
from nodriver import cdp

# Navigate using CDP
await tab.send(cdp.page.navigate(url='https://example.com'))

# Take screenshot using CDP
screenshot = await tab.send(cdp.page.capture_screenshot())
```

## Examples

### Complete scraping example

```python theme={null}
import nodriver as uc

async def main():
    browser = await uc.start()
    tab = await browser.get('https://example.com')
    
    # Find and click button
    button = await tab.find('Click me')
    await button.click()
    
    # Wait for content to load
    await tab.wait(2)
    
    # Get all links
    links = await tab.select_all('a')
    for link in links:
        print(f"Link: {link.attrs.href}")
    
    # Take screenshot
    await tab.save_screenshot('result.png')
    
    browser.stop()

uc.loop().run_until_complete(main())
```

## See also

* [Element class](/api/element) - Interact with page elements
* [Browser class](/api/browser) - Manage browser and tabs
* [CDP Usage](/api/cdp/usage) - Use Chrome DevTools Protocol
