Setting up Selenium Grid on AWS EC2
AWS become more and more popular if we talk about testing infrastructure. EC2's can be used for Selenium Grid infrastructure and it can work perfectly when our CI environment is also on EC2 (it is not required). In this article I will describe how to configure Linux image on EC2 to run Selenium Grid Hub/Node and how to minimise the AWS costs by running those machines from CI tool before tests run.
In the article I will not be going into details of configuration AWS infrastructure. I assume that you are able to create EC2 with Linux operating system and create dedicated configuration to make them accessible from your Continuous Integration (e.g. Jenkins) workers.
First of all we need two EC2 machines with any Linux operating system(I will use Ubuntu): first for Selenium Grid Hub and second for Selenium Grid Node. On both machines we have to download and install java and Selenium Server Standalone.
sudo add-apt-repository ppa:webupd8team/java sudo apt update; sudo apt install oracle-java8-installer sudo apt install oracle-java8-set-default wget http://selenium-release.storage.googleapis.com/X.XX/selenium-server-standalone-X.XX.X.jar
sudo java -jar /home/ubuntu/selenium-server-standalone-X.XX.X.jar -role hub -port 4444 &
Now after restarting this machine Selenium Grid Hub should be up and running. Just
remember to add for this instance to security group that port 4444 should be opened for
all Selenium Grid Nodes instances and workers to be able to ru tests.
Now lets focus on creating instance with Selenium Grid Node. First we have to update
system, install X-server and Xvfb to be able to perform virtual graphic operations on
the instance.
sudo apt-get -y update sudo apt-get -y install xvfb sudo apt-get -y install xserver-xorg-core sudo apt-get -y install xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic
The next thing we need is to download and install Google Chrome and chrome driver:
sudo add-apt-repository universe sudo apt-get -y install google-chrome-stable wget https://chromedriver.storage.googleapis.com/2.41/chromedriver_linux64.zip sudo apt-get -y install unzip unzip chromedriver_linux64.zip rm chromedriver_linux64.zip chmod +x chromedriver sudo mv -f chromedriver /usr/local/bin
We are also installing Firefox and downloading geckodriver:
sudo apt-get -y install firefox wget https://github.com/mozilla/geckodriver/releases/download/vX.XX.X/geckodriver-vX.XX.X-linux64.zip unzip geckodriver_linux64.zip rm geckodriver_linux64.zip chmod +x geckodriver sudo mv -f geckodriver /usr/local/bin
To be able to use Xvfb we have to export DISPLAY to system variables:
echo DISPLAY=":99" | sudo tee -a /etc/environment
Now we have to create two commands in /etc/rc.local file. The firs one is running the virtual screen and the second one run Selenium Grid Node with e.g. 4 instances of Firefox and 4 instances of Google Chrome. In that command we are also indicating where Selenium Grid Hub is located.
Xvfb $DISPLAY -screen 0 1920x1080x24 -ac 2>&1 > /dev/null & sudo -u ubuntu screen -d -m java -Dwebdriver.chrome.driver="/usr/local/bin/chromedriver" -jar /home/ubuntu/selenium-server-standalone-X.XX.X.jar -role node -maxSession 4 -browser browserName=chrome,maxInstances=4 -Dwebdriver.gecko.driver="/usr/local/bin/geckodriver" -jar /home/ubuntu/selenium-server-standalone-X.XX.X.jar -role node -maxSession 4 -browser browserName=firefox,maxInstances=4 -hub http://IP_OF_SELENIUM_GRID_HUB:4444/grid/register -port 5555 &
We have to set up security group of every the Selenium Grid Node on this way that Selenium
Grid Hub should be able to access the Node via port 5555.
The only thing left is to starting the instances between running the tests
SELENIUM_GRID_HUB="i-XXXXXXXXXXXXXX" SELENIUM_GRID_NODE="i-XXXXXXXXXXXXXX" aws ec2 start-instances --region "eu-west-1" --instance-ids $SELENIUM_GRID_HUB aws ec2 start-instances --region "eu-west-1" --instance-ids $SELENIUM_GRID_NODE aws ec2 wait instance-running --region "eu-west-1" --instance-ids $SELENIUM_GRID_HUB aws ec2 wait instance-running --region "eu-west-1" --instance-ids $SELENIUM_GRID_NODE
and stopping them when the test have finished.
aws ec2 stop-instances --region 'eu-west-1' --instance-ids $SELENIUM_GRID_HUB aws ec2 stop-instances --region 'eu-west-1' --instance-ids $SELENIUM_GRID_NODE
Script for stopping instances should be run from e.g. Post build task plugin to prevent leaving EC2 instances running when the tests are failed.