Search code examples
djangoseleniumdockerdocker-composeselenium-grid

selenium.common.exceptions.InvalidCookieDomainException: Message: invalid cookie domain while executing tests in Django with Selenium


I am setting up tests for both chrome and firefox using seleniumgrid.I am using docker images selenium-hub and selenium node-chrome and node-firefox as below.

  app:
    build: .
    command: gunicorn --reload --capture-output --log-level debug --access-logfile - -w 3 -b 0.0.0.0 app.wsgi
    restart: always
    volumes_from:
        - initialize
    ports:
      - "8000:8000"
    links:
      - db
      - rabbitmq
      - selenium_hub
    env_file: secrets.env
    volumes:
        - ./app/:/code/

  selenium_hub:
    image: selenium/hub
    ports:
      - 4444:4444
    expose:
      - 4444
    tty: true
    environment:
      - GRID_MAX_SESSION=20
      - GRID_NEW_SESSION_WAIT_TIMEOUT=60000
      - GRID_BROWSER_TIMEOUT=300
      - GRID_TIMEOUT=300
      - TIMEOUT=300
  node_1:
    image: selenium/node-chrome
    depends_on:
      - selenium_hub
    environment:
      - HUB_HOST=selenium_hub
      - HUB_PORT=4444
      - NODE_MAX_SESSION=3
      - NODE_MAX_INSTANCES=2
    shm_size: 2GB
  node_2:
    image: selenium/node-firefox
    environment:
      - HUB_HOST=selenium_hub
      - HUB_PORT=4444
      - NODE_MAX_SESSION=3
      - NODE_MAX_INSTANCES=2
    shm_size: 2GB
    depends_on:
      - selenium_hub

When I try to run the tests I am always running into this error InvalidCookieDomainException: Message: invalid cookie domain. I have already set domain to self.live_server_url. below is the full traceback with the test setup.

  Traceback (most recent call last):
    File "/code/frontend/tests/test_user_auth.py", line 75, in setUp
        "port": "8082",
    File "/usr/local/lib/python3.5/site-packages/selenium/webdriver/remote/webdriver.py", line 894, in add_cookie
        self.execute(Command.ADD_COOKIE, {'cookie': cookie_dict})
    File "/usr/local/lib/python3.5/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
        self.error_handler.check_response(response)
    File "/usr/local/lib/python3.5/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
        raise exception_class(message, screen, stacktrace)
    selenium.common.exceptions.InvalidCookieDomainException: Message: invalid cookie domain
    (Session info: chrome=77.0.3865.75)

Test reference tutorial.

class TestUserCreate(StaticLiveServerTestCase):
    fixtures = ["test.json"]
    port = 8082

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        caps = {
            "browserName": os.getenv("BROWSER", "chrome"),
            "javascriptEnabled": True,
         }
        cls.driver = webdriver.Remote(
            command_executor="http://selenium_hub:4444/wd/hub",
            desired_capabilities=caps,
         )
        cls.driver.implicitly_wait(10)

    @classmethod
    def tearDownClass(cls):
        cls.driver.quit()
        super().tearDownClass()

    def setUp(self):
        # Login the user
        self.assertTrue(self.client.login(username="james", password="changemequick"))

        # Add cookie to log in the browser
        cookie = self.client.cookies["sessionid"]
        self.driver.get(self.live_server_url + reverse("find_patient"))
        self.driver.add_cookie(
            {
                "name": "sessionid",
                "value": cookie.value,
                "domain": "localhost"
            }
         )
        super().setUp()

    def test_form_loader(self):
        # test forms loader is functioning properly

        driver = self.driver
        driver.get(self.live_server_url + "/accounts/login/")

        driver.find_element_by_xpath("//input[@type='submit']").click()
        driver.get_screenshot_as_file("login.png")
        assert len(driver.find_elements_by_css_selector(".loading")) == 0

Solution

  • In selenium we must use the URL of the testing server by default this is localhost, to enable access to an external accessible server address which is the hosting docker container's address we need to use the server machine's ip address, So set as below,

    class BaseTestCase(StaticLiveServerTestCase):
    """
    Provides base test class which connects to the Docker
    container running Selenium.
    """
    host = '0.0.0.0'  # Bind to 0.0.0.0 to allow external access
    
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        # Set host to externally accessible web server address
        cls.host = socket.gethostbyname(socket.gethostname())
    

    reference here