Comprehensive Guide to Setting Up Automated Testing in CI/CD Pipelines with AWS and Selenium
Tags: selenium, testing, cicd
Published: 2024-05-31 20:20:16

<!-- wp:heading {"level":1} -->
<h1 class="wp-block-heading">Introduction</h1>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>In the modern development landscape, CI and CD pipelines ensure that changes in code are automatically tested, integrated, and deployed. This guide documents the basic steps of creating a CI/CD pipeline using Amazon Web Services (AWS) and Selenium for automated testing. Areas to be covered include CLI and console-based setups, setting up a Selenium test project, configuration of the CI/CD pipeline, running tests, and monitoring.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Prerequisites</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Before the actual work can begin, make sure you have the following:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li>An AWS Account</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>AWS CLI installed and configured in your local machine</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>AWS IAM user with the necessary permissions to create and manage resources</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Basic knowledge in the following AWS services: EC2, S3, CodePipeline, CodeBuild</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Setting Up AWS Environment</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">AWS CLI Setup Steps</h3>
<!-- /wp:heading -->

<!-- wp:list {"ordered":true} -->
<ol><!-- wp:list-item -->
<li><strong>Install AWS CLI</strong></li>
<!-- /wp:list-item --></ol>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>Visit <a href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html">AWS CLI Documentation</a> and follow the instructions to install the AWS CLI. Since the installation will depend on the operating system in your local machine, the steps will likely be slightly different. In a nutshell, for Unix-like systems, you can always execute the following commands:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"

sudo installer -pkg AWSCLIV2.pkg -target /</code></pre>
<!-- /wp:code -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><strong>Configure AWS CLI</strong></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>After installing the AWS CLI, configure it with following command. Replace the placeholders with your AWS Access Key, Secret Key, Region and Output format.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code><strong><em>aws configure</em></strong></code></pre>
<!-- /wp:code -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><strong>Create IAM Role</strong></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>To create the IAM role that our EC2 instances and CodeBuild will use, execute the following commands:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>aws iam create-role --role-name SeleniumTestRole --assume-role-policy-document file://trust-policy.json

aws iam attach-role-policy --role-name SeleniumTestRole --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess

aws iam attach-role-policy --role-name SeleniumTestRole --policy-arn arn:aws:iam::aws:policy/AWSCodePipelineFullAccess

aws iam attach-role-policy --role-name SeleniumTestRole --policy-arn arn:aws:iam::aws:policy/AWSCodeBuildAdminAccess</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Please replace file://trust-policy.json with your path to the trust policy JSON file. The trust-policy.json file should contain:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>{

 "Version": "2012-10-17",

 "Statement": &#91;

 {

 "Effect": "Allow",

 "Principal": {

 "Service": "ec2.amazonaws.com"

 },

 "Action": "sts:AssumeRole"

 }

 ]

}</code></pre>
<!-- /wp:code -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><strong>Create S3 Bucket</strong></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>Create an S3 bucket to store your build artifacts:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code><strong><em>aws s3 mb s3://my-selenium-artifacts</em></strong></code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Replace my-selenium-artifacts with a unique name for your S3 bucket. The bucket name must be unique among all bucket names in AWS.</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><strong>Create Key Pair for EC2</strong></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>Create a key pair that can be used to access your EC2 instances:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>aws ec2 create-key-pair --key-name SeleniumKeyPair --query 'KeyMaterial' --output text > SeleniumKeyPair.pem

chmod 400 SeleniumKeyPair.pem</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>This command will create a new key pair called SeleniumKeyPair and save the private key to a file called SeleniumKeyPair.pem The chmod 400 command ensures the private key file has the correct permissions.</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><strong>Launch EC2 Instance</strong></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p>Launch an EC2 instance that will be used for running Selenium tests:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code><strong><em>aws ec2 run-instances --image-id ami-0c55b159cbfafe1f0 --count 1 --instance-type t2.micro --key-name SeleniumKeyPair --security-group-ids sg-xxxxxxxx --subnet-id subnet-xxxxxxxx</em></strong></code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Replace ami-0c55b159cbfafe1f0 with the correct AMI ID according to your region, and replace security-group-ids and subnet-id with the appropriate values. The security group must have rules which grant inbound access on port 22 from your IP address.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">AWS Console Setup Steps</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p><strong>Login to AWS Management Console</strong></p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol></ol>
<!-- /wp:list -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li>Go to <a href="https://aws.amazon.com/console/">AWS Management Console</a> and login with your AWS credentials.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p> <strong>Create IAM Role</strong></p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li>Go to the IAM service.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Click on "Roles" in the left pane.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Click the "Create role" button.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Under "Select type of trusted entity", select "AWS service", then select the "EC2" service.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Click "Next: Permissions" button.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>In the search box provided, search for and select the following policies:</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>AmazonS3FullAccess</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>AWSCodePipelineFullAccess</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>AWSCodeBuildAdminAccess</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Click "Next: Tags" (optional) and then "Next: Review".</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Give the role a name: SeleniumTestRole</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><strong>Create an S3 Bucket </strong></p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li>Go to the S3 service.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Click on "Create bucket" and the page may look something like this.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Enter your bucket name which must be unique within all bucket names in AWS.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Set the configurations as you wish.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Click "Create bucket".</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><strong>Create Key Pair for EC2</strong></p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li>Go to the EC2 service.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>In the navigation pane, choose Key Pairs.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Choose the Create Key Pair button.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Enter a name for the key pair (e.g., SeleniumKeyPair).</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Choose Create key pair.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Your browser will download the key file automatically and store it securely.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><strong>Launch EC2 Instance</strong></p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li>Go to the EC2 service.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Choose the Launch Instance button.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Select an Amazon Linux 2 AMI.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Choose an instance type (e.g., t2.micro).</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Go through set up the instance details, including attaching the IAM role that we created previously.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Add storage as required.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Configure the security group to allow SSH access (port 22) and any other ports you may need.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Review and launch the instance, selecting the key pair we just created.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Creating a Selenium Test Project</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Initializing the Project</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Let's start by creating a new directory for your Selenium tests and initializing a new Node.js project:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>mkdir selenium-tests

cd selenium-tests

npm init -y

npm install selenium-webdriver mocha chai</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>This will create a new Node.js project with the necessary dependencies for Selenium, Mocha (a test framework), and Chai (an assertion library).</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Writing Test Cases</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Create a new test file e.g., test.js in your project directory and write the following code to jot down a simple Selenium test:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>const {Builder, By, until} = require('selenium-webdriver');

const {expect} = require('chai');

describe('Google Search', function() {

 it('should find the correct title', async function() {

 let driver = await new Builder().forBrowser('chrome').build();

 try {

 await driver.get('http://www.google.com');

 let title = await driver.getTitle();

 expect(title).to.equal('Google');

 } finally {

 await driver.quit();

 }

 });

});</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>This test will open the Google Chrome browser to google.com, get its title and confirm it with the expected title "Google".</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Installing WebDriver and Browsers</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>To run Selenium tests, you need WebDriver and a browser installed on your EC2 instance. Here's how to install Chrome and ChromeDriver:</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><!-- wp:list-item -->
<li><strong>Connect to your EC2 instance:</strong></li>
<!-- /wp:list-item --></ol>
<!-- /wp:list -->

<!-- wp:code -->
<pre class="wp-block-code"><code><em>ssh -i "SeleniumKeyPair.pem" ec2-user@&lt;your-ec2-instance-public-dns></em></code></pre>
<!-- /wp:code -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><strong>Install Google Chrome:</strong></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:code -->
<pre class="wp-block-code"><code>sudo yum install -y amazon-linux-extras

sudo amazon-linux-extras install epel -y

sudo yum install -y chromium</code></pre>
<!-- /wp:code -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><strong>Install ChromeDriver:</strong></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:code -->
<pre class="wp-block-code"><code>wget https://chromedriver.storage.googleapis.com/90.0.4430.24/chromedriver_linux64.zip

unzip chromedriver_linux64.zip

sudo mv chromedriver /usr/bin/</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Check the latest compatible version of Chrome and replace the version and URL as needed.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Configuring EC2 Instance for Selenium Tests</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>In order to make the EC2 instance capable of running the Selenium tests with Chrome, you need to configure Xvfb (X virtual framebuffer) for headless execution:</p>
<!-- /wp:paragraph -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><strong>Install Xvfb:</strong></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:list {"ordered":true} -->
<ol></ol>
<!-- /wp:list -->

<!-- wp:code -->
<pre class="wp-block-code"><code><strong><em>sudo yum install -y Xvfb</em></strong></code></pre>
<!-- /wp:code -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li><strong>Start Xvfb:</strong></li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:code -->
<pre class="wp-block-code"><code>Xvfb :99 -ac &amp;

export DISPLAY=:99</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Note these commands can be included in a startup script or initialization step for the CI/CD pipeline for ease of setup.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Configuring CI/CD Pipeline</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Creating a CodeCommit Repository</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Create a new CodeCommit repository for storing the code for your Selenium tests.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code><strong><em>aws codecommit create-repository --repository-name selenium-tests</em></strong></code></pre>
<!-- /wp:code -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Pushing Code to CodeCommit</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>From the terminal, in your project directory, initialize a git repository, add the remote repo for CodeCommit, and push the code.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>git init

git remote add origin codecommit::us-east-1://selenium-tests

git add .

git commit -m "Initial commit"

git push -u origin master</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>You would first need to have the correct IAM permissions configured for Git for it to interact with CodeCommit.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Creating Build Specification</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Create a file named buildspec.yml in your project directory. Insert the following content in it.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>version: 0.2

phases:

 install:

 commands:

 - npm install

 pre_build:

 commands:

 - echo Pre-build phase

 build:

 commands:

 - npm test

artifacts:

 files:

 - '**/*'</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>In the build specification, the CodeBuild project will execute commands to install dependencies, run your tests, and archive the test results.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Creating CodeBuild Project</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li>Open the AWS Management Console and navigate to the CodeBuild dashboard.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Click on the "Create build project" button.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Enter a project name. For example, SeleniumTestProject.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>For Source provider, choose CodeCommit. Under Source version, click "master" branch.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>For Environment image, choose Managed image. For Operating System, select Ubuntu. For runtime, select Node.js.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>For Service Role, select the CodeBuild service role.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>In the BuildSpec section, make sure "Use a buildspec file" is selected.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>In the Artifacts section, select the previously created S3 bucket.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Click Create build project button.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Creating CodePipeline</h3>
<!-- /wp:heading -->

<!-- wp:list -->
<ul><!-- wp:list-item -->
<li>Open the CodePipeline service from the AWS management console.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Hit the create pipeline button.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Specify a name for the pipeline (e.g., SeleniumPipeline).</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>In the "Source" stage, select the source provider as "CodeCommit" and provide the repository and the branch.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>In the "Build" stage, select the build provider as "CodeBuild" and provide the build project that was created in the previous steps.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Optionally, create a deploy stage in the pipeline.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Click the "Create pipeline" button.</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Running and Monitoring Tests</h2>
<!-- /wp:heading -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Committing Changes</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Now, whenever you make any modifications in your Selenium test or respective code, commit and push all the changes to the CodeCommit repository.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>git add .

git commit -m "Updated tests"

git push origin master</code></pre>
<!-- /wp:code -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Monitoring Pipeline Execution</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Go to the AWS Management Console and click on the CodePipeline service to monitor how your new pipeline is working. You will see the processes for each stage execution, like source, build, and, optionally, deploy.</p>
<!-- /wp:paragraph -->

<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">Viewing Build Logs</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Click on the CodeBuild service and select your build project. On this page, you can see the logs related to each build execution, including the output of your test cases.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2 class="wp-block-heading">Conclusion</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Well, that's it. You just set up a very solid environment for your Selenium automated test with a CI/CD AWS pipeline. With this setup, the changes in code are automatically tested and integrated into the software, making sure that all processes provide assurance on the code quality and software stability. This is a setup for you to customize the configurations and extend the pipeline according to the requirements of projects, scaling up your testing efforts.</p>
<!-- /wp:paragraph -->