Trying to do Selenium testing in Django in Docker getting ERR_CONNECTION_REFUSED

I am trying to get Selenium testing going in Docker with Django. But I keep getting ERR_CONNECTION_REFUSED when using the live_server_url. I have tried to use django's container with f"http://django:{self.port}{reverse('account_login')}" I have also tried to use the ip address of the django container, but that doesn't work either.

The selenium portion of the docker compose file is from https://github.com/SeleniumHQ/docker-selenium/blob/trunk/docker-compose-v3.yml

docker compose file

services:
  django:
    container_name: django_dev
    env_file:
      - ../environments/example.env
    image: &django django
    build:
      context: ..
      dockerfile: docker_development/Dockerfile
    command: python manage.py runserver 0.0.0.0:8006

    volumes:
      - ../site:/code
    ports:
      - "8006:8006"
    depends_on:
      - db

  celery:
    container_name: celery_dev
    image: *django
    restart: 'no'
    entrypoint: celery -A project worker --beat --scheduler django --loglevel=info
    volumes:
      - ../site:/code
    env_file:
      - ../environments/example.env
    depends_on:
      - db
      - rabbitmq3
      - django

  db:
    command: postgres
    container_name: devdb
    image: postgres:17
    restart: 'no' #always
    env_file:
      - ../environments/example.env
    ports:
      - "5432:5432"
    volumes:
      - postgres-data:/var/lib/postgresql/data


  rabbitmq3:
    container_name: "rabbitmq_dev"
    image: rabbitmq:3-management-alpine
    env_file:
      - ../environments/example.env
    ports:
      - "5672:5672"
      - "15672:15672"

  chrome:
    image: selenium/node-chrome:4.35.0-20250808
    platform: linux/amd64
    shm_size: 2gb
    depends_on:
      - selenium-hub
    environment:
      - SE_EVENT_BUS_HOST=selenium-hub

  edge:
    image: selenium/node-edge:4.35.0-20250808
    platform: linux/amd64
    shm_size: 2gb
    depends_on:
      - selenium-hub
    environment:
      - SE_EVENT_BUS_HOST=selenium-hub

  firefox:
    image: selenium/node-firefox:4.35.0-20250808
    shm_size: 2gb
    depends_on:
      - selenium-hub
    environment:
      - SE_EVENT_BUS_HOST=selenium-hub

  selenium-hub:
    image: selenium/hub:4.35.0-20250808
    container_name: selenium-hub
    ports:
      - "4442:4442"
      - "4443:4443"
      - "4444:4444"

networks:
  default:
    name: "my-net"
    driver: bridge
    ipam:
      config:
      - subnet: 172.16.58.0/24

volumes:
  postgres-data:
  staticfiles:

Selenium test:

from time import sleep
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from django.test import tag
from django.urls import reverse
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.chrome.options import Options

from selenium.webdriver import Remote

import time
from selenium.webdriver.common.action_chains import ActionChains

import logging
logger = logging.getLogger(__name__)


@tag('live')
class BaseSeleniumTests(StaticLiveServerTestCase):
    fixtures = ["f1"]
    port = 8086

    @classmethod
    def setUpClass(self):
        super().setUpClass()
        options = Options()
        options.add_argument("--no-sandbox")
        self.selenium = Remote("http://localhost:4444/wd/hub", options=options)
        # cls.selenium
        self.selenium.implicitly_wait(10)

        self.actions = ActionChains(self.selenium)


    @classmethod
    def tearDownClass(self):
        self.selenium.quit()
        super().tearDownClass()

    def login(self, email='emilynconlan@einrot.com'):
        self.selenium.get(f"{self.live_server_url}{reverse('account_login')}")
        email_element = self.selenium.find_element(By.ID, 'id_login')

        wait = WebDriverWait(self.selenium, timeout=2)
        wait.until(lambda _: email_element.is_displayed())
        email_element.send_keys(email)
        pw = self.selenium.find_element(By.ID, 'id_password')
        pw.send_keys('test_password123')
        buttons = self.selenium.find_elements(by=By.CSS_SELECTOR, value="button")
        logger.debug(buttons)
        for b in buttons:
            logger.debug(b.text)
            if b.text == 'Sign In':
                b.click()
                break
        time.sleep(1)

    def test_article(self):
        self.login()

        self.selenium.get(f"{self.live_server_url}/article_list/")

        add_btn = self.selenium.find_element(By.LINK_TEXT, 'Add Article')
        add_btn.click()

        title_text = self.selenium.find_element(By.ID, 'id_title')
        title_text.send_keys('Welcome')
        page_select_element = self.selenium.find_element(By.ID, 'id_page')
        page_select = Select(page_select_element)
        page_select.select_by_visible_text('index')

        status_select_element =self.selenium.find_element(By.ID, 'id_status')
        status_select = Select(status_select_element)
        status_select.select_by_visible_text('Publish')

        text = self.selenium.find_element(By.CLASS_NAME, 'ck-content')
        text.send_keys('test article content')
        btn = self.selenium.find_element(By.NAME, 'article_btn')
        logger.debug(btn.text)
        self.actions.move_to_element(btn).perform()
        sleep(2)
        btn.click()
        sleep(1)
        # self.selenium.implicitly_wait(0.5)
        h5 = self.selenium.find_element(By.TAG_NAME, 'h5')
        self.assertEqual(h5.text, 'Articles:')

Any help would be greatly appreciated.

In your case :

  1. Your Django test server is running inside the django container, exposing port 8006.

  2. Your Selenium container is a separate container and needs to access the Django server via the Docker network, not via localhost or the host machine IP.

  3. live_server_url by default uses localhost and the port you specify (8086 in your test), but this localhost is the Selenium container itself, which does not run Django.

  4. You tried to use http://django:<port>, but it’s not wired correctly or the port might not be open or the Django server isn't listening on the right interface/port.

Please try below :

Change your test class port to match the runserver port (8006), or vice versa.

class BaseSeleniumTests(StaticLiveServerTestCase):
    port = 8006  # must match runserver port

Alternatively, change your Docker command to run Django on port 8086 if you want to keep that port in tests:

command: python manage.py runserver 0.0.0.0:8086
ports:
  - "8086:8086"

Override live_server_url to use the django hostname (the service name in Docker network) so Selenium container can connect:

@classmethod
def setUpClass(cls):
    super().setUpClass()
    cls.live_server_url = f"http://django:{cls.port}"
    options = Options()
    options.add_argument("--no-sandbox")
    cls.selenium = Remote("http://selenium-hub:4444/wd/hub", options=options)
    cls.selenium.implicitly_wait(10)
    cls.actions = ActionChains(cls.selenium)

Ensure the Selenium container is on the same Docker network as Django.

Use the right WebDriver URL (you can try with below but):

self.selenium = Remote("http://localhost:4444/wd/hub", options=options)
Вернуться на верх