Skip to content

Commit b64e594

Browse files
committed
initial commit
0 parents  commit b64e594

File tree

14 files changed

+5608
-0
lines changed

14 files changed

+5608
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules/
2+
example/reports/*.png

README.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Selenium Grid on Fargate
2+
3+
This project shows how to use [CloudFormation](https://aws.amazon.com/cloudformation/) and [ECS Fargate](https://aws.amazon.com/fargate/) to deploy a private [Selenium Grid](https://github.com/SeleniumHQ/docker-selenium) with a Chrome node.
4+
5+
## Why
6+
7+
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.
8+
9+
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.
10+
11+
## How
12+
13+
The project is splitted into 5 stacks. Each stack takes care of a specific aspect of the infrastructure. The 5 domains are the following:
14+
* 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.
15+
* IAM: creates all the required IAM roles for the ECS, Cloudwatch and application auto-scaling.
16+
* Serice discovery: creates a AWS ServiceDiscovery namespace and register the routes for the hub and the Chrome node.
17+
* Selenium Grid: creates the ECS cluster and the tasks for the hub and Chrome as well as their services.
18+
* Auto scalers: adds AWS Application auto-scaler the nodes to increase the amount of instances in case of heavy work load.
19+
20+
Illustration:
21+
22+
![Selenium Grid ECS Fargate](documentation/selenium-grid.png)
23+
24+
## Using it
25+
26+
### Infrastructure
27+
28+
Before anything else, make sure that you have a valid AWS account (more info [here](https://aws.amazon.com/free/)).
29+
30+
Create a user in IAM for programmatic usage and export the related `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` in your terminal.
31+
32+
Once it's done, run the following commands in the specified order:
33+
34+
```bash
35+
$> aws cloudformation create-stack --stack-name grid-network --template-body="$(cat ./modules/network.yaml)" && aws cloudformation wait stack-update-complete --stack-name grid-network
36+
$> 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
37+
$> 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
38+
$> aws cloudformation create-stack --stack-name grid --template-body="$(cat ./modules/selenium-grid.yaml)" && aws cloudformation wait stack-update-complete --stack-name grid
39+
$> 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
40+
```
41+
42+
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.
43+
44+
### Front-End
45+
46+
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](https://webdriver.io/) as shown in the example folder of this repository.
47+
48+
The first thing is to define our capabilities for Chrome. Here is an example:
49+
50+
```javascript
51+
// wdio.conf.js
52+
exports.config = {
53+
// code before...
54+
capabilities: [{
55+
browserName: 'chrome',
56+
'goog:loggingPrefs': { browser: 'ALL' },
57+
'goog:chromeOptions': {
58+
args: ['--no-sandbox', '--disable-setuid-sandbox', '--headless', '--whitelisted-ips', '--disable-dev-shm-usage'],
59+
},
60+
}],
61+
// ... code after
62+
};
63+
```
64+
65+
The options passed to the Chromedriver are required. The most important ones are:
66+
* `--headless`: tells the Chromedriver to start in headless mode
67+
* `--whitelisted-ips`: tells the Chromedriver to bind `0.0.0.0` instead of `127.0.0.1` because of how networking works within Fargate
68+
* `--disable-dev-shm-usage`: tells the Chromedriver to not to look for extra resources in `/dev/shm` (aka _shared memory_)
69+
* `--no-sandbox` and `--disable-setuid-sandbox`: very bad practice - could potentially be removed
70+
71+
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):
72+
73+
```javascript
74+
// wdio.conf.js
75+
exports.config = {
76+
// code before...
77+
hostname: 'SeleniumGrid-randominteger.my-aws-region.elb.amazonaws.com',
78+
port: 4444, // default port
79+
path: '/wd/hub', // default path
80+
// ... code after
81+
};
82+
```
83+
84+
or provide some options to the `wdio` cli as follows:
85+
86+
```bash
87+
$> npx wdio --hostname SeleniumGrid-randominteger.my-aws-region.elb.amazonaws.com
88+
```
89+
90+
A complete example can be found [here](./example).
91+
92+
## Yet to be done
93+
94+
* No support for Firefox
95+
* No CloudWatch alerts defined
96+
* Stacks could be nested
97+
* Distribute the template through a (public?) S3 bucket
98+
* Make a better diagram
99+
* Add CI (GitHub Actions for the win)

documentation/selenium-grid.png

50.8 KB
Loading

0 commit comments

Comments
 (0)