# Run Tests in Containers

## Configure the Test Run

Regardless of the scaling option you go with (Selenoid, Zalenium, Docker vs Kubernetes, etc.), you will need to connect your tests to a **Remote URL.**

You can do this two ways:

* Update <mark style="color:yellow;">**remote\_url**</mark> in **`pylenium.json`**
* Pass in the argument when running the tests in the CLI

### Run Tests in CLI

{% hint style="info" %}
This is the most common option since it is what you will use in your pipelines and CI
{% endhint %}

{% code title="Terminal" %}

```bash
pytest tests/ui -n 2 --remote_url="http://localhost:4444/wd/hub"
```

{% endcode %}

### Update pylenium.json

{% code title="pylenium.json" %}

```bash
"remote_url": "http://localhost:4444/wd/hub"
```

{% endcode %}

You can have multiple `pylenium.json` files, so you might have:

* **`dev-pylenium.json`** for local development
* **`ci-pylenium.json`** for CI Pipelines

Then pick which config file to use in the CLI. For example, in a CI Pipeline:

{% code title="Terminal" %}

```bash
pytest pylenium_json=ci-pylenium.json
```

{% endcode %}

### Config Layers

* Layer 1 - `pylenium.json` is deserialized into **PyleniumConfig**
* Layer 2 - If there are any CLI args, they will override their respective values in **PyleniumConfig**

## Docker Example

With **Docker** installed, you can easily spin up a **Selenium Grid** with the `docker-compose` command.

### docker-compose.yml

You will need a `docker-compose.yml` file and then open a Terminal in the same directory as this file.

{% code title="docker-compose.yml" %}

```yaml
version: "3"
services:

  selenium-hub:
    image: selenium/hub
    ports:
      - "4444:4444"
    environment:
        GRID_MAX_SESSION: 16
        GRID_BROWSER_TIMEOUT: 300
        GRID_TIMEOUT: 300

  chrome:
    image: selenium/node-chrome
    depends_on:
      - selenium-hub
    environment:
      HUB_PORT_4444_TCP_ADDR: selenium-hub
      HUB_PORT_4444_TCP_PORT: 4444
      NODE_MAX_SESSION: 2
      NODE_MAX_INSTANCES: 2

  firefox:
    image: selenium/node-firefox
    depends_on:
      - selenium-hub
    environment:
      HUB_PORT_4444_TCP_ADDR: selenium-hub
      HUB_PORT_4444_TCP_PORT: 4444
      NODE_MAX_SESSION: 4
      NODE_MAX_INSTANCES: 4
```

{% endcode %}

This configuration will spin up a **Hub** node (load balancer), a **Chrome** node with 2 available drivers and a **Firefox** node with 4 available drivers.

### Spin up the Grid

With a single command you will have all of this created for you:

{% code title="Terminal $" %}

```bash
docker-compose up -d
```

{% endcode %}

{% hint style="info" %}
Once complete, you can visually see this Grid by going to <http://localhost:4444/grid/console>
{% endhint %}

Now **Configure the Test Run** (steps at top of this doc) to target the Hub which will balance the tests across its Nodes.

### Scale Nodes

With the YAML file example above, it will create 1 chrome Node with 2 available drivers by default. You can easily scale this to the number you need.

{% code title="Terminal $" %}

```bash
docker-compose up -d --scale chrome=5
```

{% endcode %}

This will spin up the Grid with 5 chrome Nodes!

### Tear Down the Grid

When you're done using the Grid, a single command will tear it completely down.

{% code title="Terminal $" %}

```bash
docker-compose down
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.pylenium.io/guides/run-tests-in-containers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
