Now I want to test its browser interactions using Selenium.
To keep the container lightweight (without browser or X-Window), I run Selenium and the browser driver (chromedriver in my case) on the host.
To get it to work, I created:
class LiveServerInsideContainerTestCase(LiveServerTestCase):
# We need the following to get Selenium to communicate with our
# Live Server, which needs to work for us to be able to
# authenticate users in the test.
host = '172.17.0.2' # TODO: bring in argument properly
where the IP of the outside computer is 172.17.0.1 and the IP of the running container itself is 172.17.0.2.
I force the port to 5000 because Docker maps container's port 5000 to host's port 5000, So that the Selenium standalone server will be able to drive the browser using
http://localhost:5000 as the schema+host+port parts of the URL.
The chromedriver is activated using:
./chromedriver --whitelisted-ips=172.17.0.2 &
(works for version 2.39, not for the most recent version 2.40)
The Selenium standalone is activated using:
java -jar selenium-server-standalone-3.13.0.jar &
The problem:
The tests using Selenium are too flaky.
When they work, they pass.
When they fail, they fail due to OSError: [Errno 98] Address already in use
A sample stacktrace is as follows.
ERROR: setUpClass (activists.tests.browser_test_admin.AdminTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/developer/.local/share/virtualenvs/memb-Wv4pRnjx/lib/python3.6/site-packages/django/test/testcases.py", line 1297, in setUpClass
raise cls.server_thread.error
File "/home/developer/.local/share/virtualenvs/memb-Wv4pRnjx/lib/python3.6/site-packages/django/test/testcases.py", line 1227, in run
self.httpd = self._create_server()
File "/home/developer/.local/share/virtualenvs/memb-Wv4pRnjx/lib/python3.6/site-packages/django/test/testcases.py", line 1241, in _create_server
return ThreadedWSGIServer((self.host, self.port), QuietWSGIRequestHandler, allow_reuse_address=False)
File "/home/developer/.local/share/virtualenvs/memb-Wv4pRnjx/lib/python3.6/site-packages/django/core/servers/basehttp.py", line 66, in __init__
super().__init__(*args, **kwargs)
File "/usr/lib/python3.6/socketserver.py", line 453, in __init__
self.server_bind()
File "/usr/lib/python3.6/wsgiref/simple_server.py", line 50, in server_bind
HTTPServer.server_bind(self)
File "/usr/lib/python3.6/http/server.py", line 136, in server_bind
socketserver.TCPServer.server_bind(self)
File "/usr/lib/python3.6/socketserver.py", line 467, in server_bind
self.socket.bind(self.server_address)
OSError: [Errno 98] Address already in use
Possible solutions:
1. Set up a virtual machine and run my application together with Selenium inside it.
2. Set up the Docker container in such a way that all of its ports above 1024 or so are mapped to the host's ports.
However, before giving up the container's advantage of lightweightness, or figuring out how to map all container's ports, I'd like to know if anyone has another solution to the problem.
Thanks,
--- Omer Zak