Skip to content

Scalable, stateless selenium hub for Kubernetes cluster

License

Notifications You must be signed in to change notification settings

HarryHoudini/selenosis

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

selenosis

Scalable, stateless selenium hub for Kubernetes cluster.

Overview

Available flags

[user@host]$ ./selenosis --help
Scallable, stateless selenium grid for Kubernetes cluster

Usage:
  selenosis [flags]

Flags:
      --port string                          port for selenosis (default ":4444")
      --proxy-port string                    proxy continer port (default "4445")
      --browsers-config string               browsers config (default "./config/browsers.yaml")
      --browser-limit int                    active sessions max limit (default 10)
      --namespace string                     kubernetes namespace (default "selenosis")
      --service-name string                  kubernetes service name for browsers (default "seleniferous")
      --browser-wait-timeout duration        time in seconds that a browser will be ready (default 30s)
      --session-wait-timeout duration        time in seconds that a session will be ready (default 1m0s)
      --session-iddle-timeout duration       time in seconds that a session will iddle (default 5m0s)
      --session-retry-count int              session retry count (default 3)
      --graceful-shutdown-timeout duration   time in seconds  gracefull shutdown timeout (default 30s)
      --image-pull-secret-name string        secret name to private registry
      --proxy-image string                   in case you use private registry replace with image from private registry (default "alcounit/seleniferous:latest")
  -h, --help                                 help for selenosis

Available endpoints

Protocol Endpoint
HTTP /wd/hub/session
HTTP /wd/hub/session/{sessionId}/
HTTP /wd/hub/status
WS /vnc/{sessionId}
WS/HTTP /devtools/{sessionId}
HTTP /download/{sessionId}
HTTP /clipboard/{sessionId}
HTTP /status
HTTP /healthz

Configuration

Selenosis requires config to start browsers in K8 cluster. Config can be JSON or YAML file.
Basic configuration be like (all fields in this example are mandatory):

{
    "chrome": {
        "defaultVersion": "85.0",
        "path": "/",
        "versions": {
            "85.0": {
                "image": "selenoid/vnc:chrome_85.0"
            },
            "86.0": {
                "image": "selenoid/vnc:chrome_86.0"
            }
        }
    },
    "firefox": {
        "defaultVersion": "82.0",
        "path": "/wd/hub",
        "versions": {
            "81.0": {
                "image": "selenoid/vnc:firefox_81.0"
            },
            "82.0": {
                "image": "selenoid/vnc:firefox_82.0"
            }
        }
    },

    "opera" : {
        "defaultVersion": "70.0",
        "path": "/",
        "versions": {
            "70.0": {
                "image": "selenoid/vnc:opera_70.0"
            },
            "71.0": {
                "image": "selenoid/vnc:opera_71.0"
            }
        }
    }
}
---
chrome:
  defaultVersion: "85.0"
  path: "/"
  versions:
    '85.0':
      image: selenoid/vnc:chrome_85.0
    '86.0':
      image: selenoid/vnc:chrome_86.0
firefox:
  defaultVersion: "82.0"
  path: "/wd/hub"
  versions:
    '81.0':
      image: selenoid/vnc:firefox_81.0
    '82.0':
      image: selenoid/vnc:firefox_82.0
opera:
  defaultVersion: "70.0"
  path: "/"
  versions:
    '70.0':
      image: selenoid/vnc:opera_70.0
    '71.0':
      image: selenoid/vnc:opera_71.0

Browser name and browser version are taken from Selenium desired capabilities.

Each browser can have default spec/annotations/labels, they will merged to all browsers listed in the versions section.

{
  "chrome": {
    "defaultVersion": "85.0",
    "path": "/",
    "meta": {
      "labels": {
        "environment": "aqa",
        "app": "myCoolApp"
      },
      "annotations": {
        "build": "dev-v1.11.2",
        "builder": "jenkins"
      }
    },
    "spec": {
      "resources": {
        "requests": {
          "memory": "500Mi",
          "cpu": "0.5"
        },
        "limits": {
          "memory": "1000Gi",
          "cpu": "1"
        }
      },
      "hostAliases": [
        {
          "ip": "127.0.0.1",
          "hostnames": [
            "foo.local",
            "bar.local"
          ]
        },
        {
          "ip": "10.1.2.3",
          "hostnames": [
            "foo.remote",
            "bar.remote"
          ]
        }
      ],
      "env": [
        {
          "name": "TZ",
          "value": "Europe/Kiev"
        },
        {
          "name": "SCREEN_RESOLUTION",
          "value": "1920x1080x24"
        },
        {
          "name": "ENABLE_VNC",
          "value": "true"
        }
      ]
    },
    "versions": {
      "85.0": {
        "image": "selenoid/vnc:chrome_85.0"
      },
      "86.0": {
        "image": "selenoid/vnc:chrome_86.0"
      }
    }
  }
}
---
chrome:
  defaultVersion: "85.0"
  path: "/"
  meta:
    labels:
      environment: aqa
      app: myCoolApp
    annotations:
      build: dev-v1.11.2
      builder: jenkins
  spec:
    resources:
      requests:
        memory: 500Mi
        cpu: '0.5'
      limits:
        memory: 1000Gi
        cpu: '1'
    hostAliases:
    - ip: 127.0.0.1
      hostnames:
      - foo.local
      - bar.local
    - ip: 10.1.2.3
      hostnames:
      - foo.remote
      - bar.remote
    env:
    - name: TZ
      value: Europe/Kiev
    - name: SCREEN_RESOLUTION
      value: 1920x1080x24
    - name: ENABLE_VNC
      value: 'true'
  versions:
    '85.0':
      image: selenoid/vnc:chrome_85.0
    '86.0':
      image: selenoid/vnc:chrome_86.0

You can override default browser spec/annotation/labels by providing individual spec/annotation/labels to browser version

{
  "chrome": {
    "defaultVersion": "85.0",
    "path": "/",
    "meta": {
      "labels": {
        "environment": "aqa",
        "app": "myCoolApp"
      },
      "annotations": {
        "build": "dev-v1.11.2",
        "builder": "jenkins"
      }
    },
    "spec": {
      "resources": {
        "requests": {
          "memory": "500Mi",
          "cpu": "0.5"
        },
        "limits": {
          "memory": "1000Gi",
          "cpu": "1"
        }
      },
      "hostAliases": [
        {
          "ip": "127.0.0.1",
          "hostnames": [
            "foo.local",
            "bar.local"
          ]
        },
        {
          "ip": "10.1.2.3",
          "hostnames": [
            "foo.remote",
            "bar.remote"
          ]
        }
      ],
      "env": [
        {
          "name": "TZ",
          "value": "Europe/Kiev"
        },
        {
          "name": "SCREEN_RESOLUTION",
          "value": "1920x1080x24"
        },
        {
          "name": "ENABLE_VNC",
          "value": "true"
        }
      ]
    },
    "versions": {
      "85.0": {
        "image": "selenoid/vnc:chrome_85.0",
        "spec": {
          "resources": {
            "requests": {
              "memory": "750Mi",
              "cpu": "0.5"
            },
            "limits": {
              "memory": "1500Gi",
              "cpu": "1"
            }
          }
        }
      },
      "86.0": {
        "image": "selenoid/vnc:chrome_86.0",
        "spec": {
          "hostAliases": [
            {
              "ip": "127.0.0.1",
              "hostnames": [
                "bla-bla.com"
              ]
            }
          ]
        },
        "meta": {
          "labels": {
            "environment": "dev",
            "app": "veryCoolApp"
          }
        }
      }
    }
  }
}
---
chrome:
  defaultVersion: "85.0"
  path: "/"
  meta:
    labels:
      environment: aqa
      app: myCoolApp
    annotations:
      build: dev-v1.11.2
      builder: jenkins
  spec:
    resources:
      requests:
        memory: 500Mi
        cpu: '0.5'
      limits:
        memory: 1000Gi
        cpu: '1'
    hostAliases:
    - ip: 127.0.0.1
      hostnames:
      - foo.local
      - bar.local
    - ip: 10.1.2.3
      hostnames:
      - foo.remote
      - bar.remote
    env:
    - name: TZ
      value: Europe/Kiev
    - name: SCREEN_RESOLUTION
      value: 1920x1080x24
    - name: ENABLE_VNC
      value: 'true'
  versions:
    '85.0':
      image: selenoid/vnc:chrome_85.0
      spec:
        resources:
          requests:
            memory: 750Mi
            cpu: '0.5'
          limits:
            memory: 1500Gi
            cpu: '1'
    '86.0':
      image: selenoid/vnc:chrome_86.0
      spec:
        hostAliases:
        - ip: 127.0.0.1
          hostnames:
          - bla-bla.com
      meta:
        labels:
          environment: dev
          app: veryCoolApp

Deployment

Files and steps required for selenosis deployment available in selenosis-deploy repository

Run yout tests

DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setBrowserName("chrome");
capabilities.setVersion("85.0");

RemoteWebDriver driver = new RemoteWebDriver(
   URI.create("http://<loadBalancerIP|nodeIP>:<port>/wd/hub").toURL(), 
   capabilities
);
from selenium import webdriver
      
capabilities = {
  "browserName": "chrome",
  "version": "85.0",
}

driver = webdriver.Remote(
  command_executor="http://<loadBalancerIP|nodeIP>:<port>/wd/hub",
  desired_capabilities=capabilities)

Note: you can omit browser version in your desired capabilities, make sure you set defaultVersion property in the config file.

Features

Scalability

By default selenosis starts with 2 replica sets. To change it, edit selenosis deployment file: 03-selenosis.yaml

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: selenosis
  namespace: selenosis
spec:
  replicas: 2
  selector:
...

Stateless

Selenosis doesn't store any session info. All connections to the browsers are automatically assigned via headless service.

Hot config reload

Selenosis supports hot config reload, to do so update you configMap

kubectl edit configmap -n selenosis selenosis-config -o yaml

UI for debug

Selenosis itself doesn't have ui. If you need such functionality you can use selenoid-ui with special adapter container. Deployment steps and minifests you can find in selenosis-deploy repository.


Currently this project is under development and can be unstable, in case of any bugs or ideas please report

About

Scalable, stateless selenium hub for Kubernetes cluster

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Go 99.4%
  • Dockerfile 0.6%