ci: add ui(dashboard) tests based on pytest and selenium

This commit is contained in:
Ivan Dyachkov 2023-06-01 20:01:24 +02:00
parent d320497d0c
commit 8cdb1458c7
4 changed files with 116 additions and 2 deletions

View File

@ -165,7 +165,7 @@ jobs:
path: _packages/**/*
docker:
runs-on: ubuntu-22.04
runs-on: aws-amd64
strategy:
fail-fast: false
@ -196,12 +196,17 @@ jobs:
tags: ${{ env.EMQX_IMAGE_TAG }}
build-args: |
EMQX_NAME=${{ env.EMQX_NAME }}
- name: test docker image
- name: smoke test
run: |
CID=$(docker run -d --rm -P $EMQX_IMAGE_TAG)
HTTP_PORT=$(docker inspect --format='{{(index (index .NetworkSettings.Ports "18083/tcp") 0).HostPort}}' $CID)
./scripts/test/emqx-smoke-test.sh localhost $HTTP_PORT
docker stop $CID
- name: dashboard tests
working-directory: ./scripts/ui-tests
run: |
set -eu
docker compose up --abort-on-container-exit --exit-code-from selenium
- name: test two nodes cluster with proto_dist=inet_tls in docker
run: |
./scripts/test/start-two-nodes-in-docker.sh -P $EMQX_IMAGE_TAG $EMQX_IMAGE_OLD_VERSION_TAG
@ -216,6 +221,11 @@ jobs:
with:
name: "${{ matrix.profile[0] }}-docker"
path: "${{ env.EMQX_NAME }}-${{ env.PKG_VSN }}.tar.gz"
- name: cleanup
if: always()
working-directory: ./scripts/ui-tests
run: |
docker compose rm -fs
spellcheck:
needs: linux

View File

@ -0,0 +1,15 @@
import pytest
from selenium import webdriver
def pytest_addoption(parser):
parser.addoption("--dashboard-host", action="store", default="localhost", help="Dashboard host")
parser.addoption("--dashboard-port", action="store", default="18083", help="Dashboard port")
@pytest.fixture
def dashboard_host(request):
return request.config.getoption("--dashboard-host")
@pytest.fixture
def dashboard_port(request):
return request.config.getoption("--dashboard-port")

View File

@ -0,0 +1,73 @@
import time
import unittest
import pytest
from urllib.parse import urljoin
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common import utils
@pytest.fixture
def driver():
options = Options()
options.add_argument("--headless")
options.add_argument("--no-sandbox")
_driver = webdriver.Chrome(options=options)
yield _driver
_driver.quit()
@pytest.fixture(autouse=True)
def dashboard_url(dashboard_host, dashboard_port):
count = 0
while utils.is_connectable(port=dashboard_port, host=dashboard_host) is False:
if count == 30:
raise Exception("Dashboard is not ready")
count += 1
time.sleep(1)
return f"http://{dashboard_host}:{dashboard_port}"
@pytest.fixture
def login(driver, dashboard_url):
driver.get(dashboard_url)
assert "EMQX Dashboard" == driver.title
assert f"{dashboard_url}/#/login?to=/dashboard/overview" == driver.current_url
driver.find_element(By.XPATH, "//div[@class='login']//form[1]//input[@type='text']").send_keys("admin")
driver.find_element(By.XPATH, "//div[@class='login']//form[1]//input[@type='password']").send_keys("admin")
driver.find_element(By.XPATH, "//div[@class='login']//form[1]//button[1]").click()
dest_url = urljoin(dashboard_url, "/#/dashboard/overview")
driver.get(dest_url)
ensure_current_url(driver, dest_url)
def ensure_current_url(driver, url):
count = 0
while url != driver.current_url:
if count == 10:
raise Exception(f"Failed to load {url}")
count += 1
time.sleep(1)
def wait_title(driver):
return WebDriverWait(driver, 10).until(lambda x: x.find_element("xpath", "//div[@id='app']//h1[@class='header-title']"))
def test_basic(driver, login, dashboard_url):
driver.get(dashboard_url)
title = wait_title(driver)
assert "Cluster Overview" == title.text
def test_log(driver, login, dashboard_url):
dest_url = urljoin(dashboard_url, "/#/log")
driver.get(dest_url)
ensure_current_url(driver, dest_url)
title = wait_title(driver)
assert "Logging" == title.text
label = driver.find_element(By.XPATH, "//div[@id='app']//form//label[./label/span[text()='Enable Log Handler']]")
assert driver.find_elements(By.ID, label.get_attribute("for"))
label = driver.find_element(By.XPATH, "//div[@id='app']//form//label[./label/span[text()='Log Level']]")
assert driver.find_elements(By.ID, label.get_attribute("for"))
label = driver.find_element(By.XPATH, "//div[@id='app']//form//label[./label/span[text()='Log Formatter']]")
assert driver.find_elements(By.ID, label.get_attribute("for"))
label = driver.find_element(By.XPATH, "//div[@id='app']//form//label[./label/span[text()='Time Offset']]")
assert driver.find_elements(By.ID, label.get_attribute("for"))

View File

@ -0,0 +1,16 @@
version: '3.9'
services:
emqx:
image: ${EMQX_IMAGE_TAG:-emqx/emqx:latest}
environment:
EMQX_DASHBOARD__DEFAULT_PASSWORD: admin
selenium:
shm_size: '2gb'
image: ghcr.io/emqx/selenium-chrome:latest
volumes:
- ./:/app
depends_on:
- emqx
command: python3 -m pytest --dashboard-host emqx --dashboard-port 18083