Giter Club home page Giter Club logo

selenium-grid-ecs-fargate's Introduction

Selenium Grid on Fargate

This project shows how to use CloudFormation and ECS Fargate to deploy a private Selenium Grid with a Chrome node.

Why

In many companies, people write e2e / UI / regression tests for their web-apps. Some solutions like Browserstack or SauceLabs provide a "public" Selenium Grid for running your tests against different environments. However, such as any paid service, it comes with a cost. The more VM instances you need, the more expensive it becomes.

Assuming you have a small subscription to a service like Browserstack, you might be interested in reserving your VMs for your principal branches (develop or master or release branches following your branching strategy) and use a private Selenium Grid to run the tests for your other branches.

How

The project is splitted into 5 stacks. Each stack takes care of a specific aspect of the infrastructure. The 5 domains are the following:

  • Network: creates a VPC for the ECS Cluster with 3 subnets, 2 public ones and 1 private one. It creates also a internet gateway and NAT gateway for the subnets. It finally adds a internet-facing load-balancer to route traffic to the Selenium Hub.
  • IAM: creates all the required IAM roles for the ECS, Cloudwatch and application auto-scaling.
  • Serice discovery: creates a AWS ServiceDiscovery namespace and register the routes for the hub and the Chrome node.
  • Selenium Grid: creates the ECS cluster and the tasks for the hub and Chrome as well as their services.
  • Auto scalers: adds AWS Application auto-scaler the nodes to increase the amount of instances in case of heavy work load.

Illustration:

Selenium Grid ECS Fargate

Using it

Infrastructure

Before anything else, make sure that you have a valid AWS account (more info here).

Create a user in IAM for programmatic usage and export the related AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY in your terminal.

Once it's done, run the following commands in the specified order:

$> aws cloudformation create-stack --stack-name grid-network --template-body="$(cat ./modules/network.yaml)" && aws cloudformation wait stack-update-complete --stack-name grid-network
$> aws cloudformation create-stack --stack-name grid-iam --template-body="$(cat ./modules/iam.yaml)" --capabilities CAPABILITY_IAM && aws cloudformation wait stack-update-complete --stack-name grid-iam
$> aws cloudformation create-stack --stack-name grid-service-discovery --template-body="$(cat ./modules/service-discovery.yaml)" && aws cloudformation wait stack-update-complete --stack-name grid-service-discovery
$> aws cloudformation create-stack --stack-name grid --template-body="$(cat ./modules/selenium-grid.yaml)" && aws cloudformation wait stack-update-complete --stack-name grid
$> aws cloudformation create-stack --stack-name grid-auto-scalers --template-body="$(cat ./modules/auto-scalers.yaml)" && aws cloudformation wait stack-update-complete --stack-name grid-auto-scalers

After all the deployments are made, go to your AWS console. Navigate to EC2 then LOAD BALANCING then Load Balancers. Finally, click on the load-balancer named SeleniumGrid, you should see the DNS name in the screen below the list of load balancers. Save the DNS somewhere, it will be re-used for the example.

Front-End

Now that our infrastructure is up and running, let's see what's needed for running our tests. For this example, we will use Webdriver I/O as shown in the example folder of this repository.

The first thing is to define our capabilities for Chrome. Here is an example:

// wdio.conf.js
exports.config = {
// code before...
    capabilities: [{
        browserName: 'chrome',
        'goog:loggingPrefs': { browser: 'ALL' },
        'goog:chromeOptions': {
            args: ['--no-sandbox', '--disable-setuid-sandbox', '--headless', '--whitelisted-ips', '--disable-dev-shm-usage'],
        },
    }],
// ... code after
};

The options passed to the Chromedriver are required. The most important ones are:

  • --headless: tells the Chromedriver to start in headless mode
  • --whitelisted-ips: tells the Chromedriver to bind 0.0.0.0 instead of 127.0.0.1 because of how networking works within Fargate
  • --disable-dev-shm-usage: tells the Chromedriver to not to look for extra resources in /dev/shm (aka shared memory)
  • --no-sandbox and --disable-setuid-sandbox: very bad practice - could potentially be removed

When your configuration is ready, let wdio know where to look for the Selenium Hub. To do so, you can either use the following configuration (make sure to replace randominteger and my-aws-region by the correct values):

// wdio.conf.js
exports.config = {
// code before...
    hostname: 'SeleniumGrid-randominteger.my-aws-region.elb.amazonaws.com',
    port: 4444, // default port
    path: '/wd/hub', // default path
// ... code after
};

or provide some options to the wdio cli as follows:

$> npx wdio --hostname SeleniumGrid-randominteger.my-aws-region.elb.amazonaws.com

A complete example can be found here.

Yet to be done

  • No support for Firefox
  • No CloudWatch alerts defined
  • Stacks could be nested
  • Distribute the template through a (public?) S3 bucket
  • Make a better diagram
  • Add CI (GitHub Actions for the win)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.