Integrating Github Actions with Selenium
Published: 2023-01-22 07:09:48


## Why integerate Selenium with Github Actions?
Well yes, why would you want to make things cumbersome when both of them are working well independently? 
Well the thing is with the flexible aspects of Selenium WebDrivers and GitHub Actions, one can create powerful, quick, and efficient automated testing workflows in the CI/CD environment. 

CI/CD pipelines have been contributing to the success of the DevOps cycle across all software development projects. It is a holistic process that builds bridges between development and operations. Continuous Integration assists the development team in efficiently delivering the code, and Continuous Delivery automates the delivery of code.

## Getting Started
This tutorial covers creating Github Actions and setting up a Workflow in GitHub. We will also look at the WorkFlow structures in detail. Lastly, we will execute Selenium Testing Scripts with GitHub Actions.
I will be using one of my repository to demonstrate how all of this works together

For this tutorial I am considering you have set up your workflow and also written your selenium script. Just in case you haven't I will add my workflow and the script for your reference.

1. **Setting up the workflow** : 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4azgtpwr3mzap9b7jnxg.png) 
This is my repository that will be used for this blog.
Now let us look at the workflow for this project 

```
name: "Website"

on:
  push:
    branches:
       - '*'
  pull_request:
    branches:
      - '*'
    types: [opened, synchronize, edited]

jobs:
  FrontendJob:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: Frontend
    steps:
      - name: Checkout to the repository
        uses: actions/checkout@v2

      - name: Set up NodeJS environment
        uses: actions/setup-node@v2

      - name: Install dependencies
        run: |
          if [ -e yarn.lock ]; then
          yarn install --frozen-lockfile
          else
          npm install
          fi
        
      - name: Create test build
        run: npm run build

  BackendJob:
    runs-on: ubuntu-latest
    defaults:
      run:
         working-directory: Backend

    strategy:
      matrix:
        node-version: [14.x, 15.x, 16.x]

    steps:
      - uses: actions/checkout@v3
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
      - name: Install dependencies
        run: |
          if [ -e yarn.lock ]; then
          yarn install --frozen-lockfile
          elif [ -e package-lock.json ]; then
          npm ci
          else
          npm i
          fi
      - run: npm run build --if-present

  MLJob:
    if: "'[ -d ML ]'"
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: ML
         
    strategy:
      matrix: 
        python-version: ["3.7", "3.8", "3.9", "3.10"]

    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install flake8 pytest
          if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
      - name: Lint with flake8
        run: |
          # stop the build if there are Python syntax errors or undefined names
          flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
          # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
          flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
  
          
```
2. **Execute Selenium TestScript with GitHub Actions**:
Create a file called browserTest.py and add the below code in that file

```
import os
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service as ChromeService
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

os.environ['PATH']+=r"C:/SeleniumDrivers"
service = ChromeService(executable_path="/snap/bin/chromium.chromedriver")
options = webdriver.ChromeOptions()
options.headless = True

driver=webdriver.Chrome(service=service, options=options)

driver.get("https://cozy-rabanadas-6d2b0b.netlify.app/")

buttons =driver.find_elements(By.CLASS_NAME,'sc-uhnfH')

for i in buttons:
    if i.text=='REGISTER':
        i.click()   
        print(i.text)
        time.sleep(2)
    if i.text=='SIGN IN':
        i.click()
        print(i.text)
        time.sleep(2)
    if i.text=='RECOMMEND':
        continue
    else : 
        i.click()
        time.sleep(2) 

buttons[1].click()
print(buttons[3].text)

driver.find_element(By.LINK_TEXT,'CREATE A NEW ACCOUNT').click()
time.sleep(2)

driver.find_element(By.CLASS_NAME,'sc-WKhSL').click() #Bookshelf
time.sleep(2)

driver.find_element(By.CLASS_NAME,'sc-iAEawV').click() #Image slide right direction
time.sleep(2)

driver.find_element(By.CLASS_NAME,'sc-ilhmMj').click() #shop now
time.sleep(2)

cart_icons=driver.find_elements(By.CLASS_NAME,'sc-jcMfQk')#cart icon

cart_icons[0].click()
time.sleep(2)

'''
driver.find_element(By.XPATH,'//div[@class="sc-iveFHk"]/*[name()="svg"]').click()

isko div m dalwa denge...kaam aasan ho jayga 
'''
c=0
while True:
    driver.find_element(By.CLASS_NAME,'sc-lllmON').click()
    time.sleep(1)
    c=c+1
    if c==2:
        time.sleep(2)
        break

buttons[3].click()
time.sleep(2)
buttons[2].click()
time.sleep(2)
driver.find_element(By.CLASS_NAME,'form-control').send_keys('1984')
time.sleep(2)
driver.find_element(By.CLASS_NAME,'btn').click()
time.sleep(2)
```
Now head over to the actions tab and create a new workflow , I have named it selenium.yml , you can call it whatever you like.
In the above created file add the below code :

```
name: "Selenium Integration"

on:
  push:
    branches:
       - '*'
  pull_request:
    branches:
      - '*'
    types: [opened, synchronize, edited]

jobs:
  SeleniumJob:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: Frontend
    steps:
      - name: Checkout to the repository
        uses: actions/checkout@v2
      - name: Set up Python 
        uses: actions/setup-python@v4
        with:
          python-version: '3.9'
      - name: Install dependencies
        run: |
         python -m pip install --upgrade pip
         pip install flake8 pytest
         pip install selenium
         pip install Service
         if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
      - name: Run Selenium script
        run:  python browserTest.py
```
We will now commit the above file and head over to the actions tab to see if our build has passed or failed 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tw8a70n1jbnkdsv2w3r8.png)
Well, our build has failed and the reason behind this is probably due to Google Chrome being not installed in the virtual machine that was configured. The error usually occurs because we are using Chrome in a headless mode. In our case ,we do not have Chrome Browser installed on the Ubuntu machine. Hence, we will add the following configuration in our browserTest.py file 

```
service = ChromeService(executable_path="/snap/bin/chromium.chromedriver")
options = webdriver.ChromeOptions()
options.headless = True

driver=webdriver.Chrome(service=service, options=options)

```
We can now see that the build has passed successfully !!

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qa3htjhdpnp48jvstw49.png)
We have tested this only for Google Chrome Browser , but you can test it for other browsers such as Edge and Firefox as well. 

## Conclusion
In this tutorial, we have created a series of CI workflows using Selenium and GitHub actions. In conclusion, Selenium WebDriver is an excellent open-source tool for cross-platform web-based testing. Combining Selenium WebDriver with GitHub Actions enables us to ensure Continuous Integration in the DevOps environment. A similar approach can be used to enable Selenium testing for any web browser simply by changing the WebDriver. 

We hope that this detailed guide will assist you in setting up your first automated testing with Selenium using GitHub Actions successfully. 

Github Repository : https://github.com/Team-BookShelf/Website
Website used for testing : https://cozy-rabanadas-6d2b0b.netlify.app/