From e64a456f5a4805713ddefbda35d42d3358c5b778 Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Sun, 19 Jan 2025 00:57:21 +0530 Subject: [PATCH 01/37] feat: add e2e tests Signed-off-by: 35C4n0r --- tests/e2e_tests/docker-compose-e2e-mysql.yml | 94 ++++++++++ .../e2e_tests/docker-compose-e2e-postgres.yml | 91 ++++++++++ tests/e2e_tests/test_end_to_end.py | 64 ++++++- tests/e2e_tests/test_grafana_provider.py | 169 ++++++++++++++++++ tests/e2e_tests/utils.py | 15 ++ tests/e2e_tests/workflow-sample.yaml | 22 +++ 6 files changed, 451 insertions(+), 4 deletions(-) create mode 100644 tests/e2e_tests/test_grafana_provider.py create mode 100644 tests/e2e_tests/utils.py create mode 100644 tests/e2e_tests/workflow-sample.yaml diff --git a/tests/e2e_tests/docker-compose-e2e-mysql.yml b/tests/e2e_tests/docker-compose-e2e-mysql.yml index 52d7fc101..03f5076f0 100644 --- a/tests/e2e_tests/docker-compose-e2e-mysql.yml +++ b/tests/e2e_tests/docker-compose-e2e-mysql.yml @@ -1,4 +1,6 @@ services: + ## Keep Services with NO_AUTH + # Database Service keep-database: image: mysql:latest environment: @@ -14,6 +16,7 @@ services: timeout: 5s retries: 5 + # Frontend Services keep-frontend: extends: file: docker-compose.common.yml @@ -28,6 +31,7 @@ services: - FRIGADE_DISABLED=true - SENTRY_DISABLED=true + # Backend Services keep-backend: extends: file: docker-compose.common.yml @@ -46,6 +50,81 @@ services: keep-database: condition: service_healthy + + ## Keep Services with DB + # Database Service (5433) + keep-database-db-auth: + image: mysql:latest + environment: + - MYSQL_ROOT_PASSWORD=keep + - MYSQL_DATABASE=keep + volumes: + - mysql-data:/var/lib/mysql-auth-db + ports: + - "3307:3306" + healthcheck: + test: ["CMD-SHELL", "mysqladmin ping -h localhost"] + interval: 10s + timeout: 5s + retries: 5 + + # Frontend Services (3001) + keep-frontend-db-auth: + build: + context: ./keep-ui/ + dockerfile: ../docker/Dockerfile.ui + ports: + - "3001:3000" + environment: + - NEXTAUTH_SECRET=secret + - NEXTAUTH_URL=https://3001-35c4n0r-keep-j5ok1nvq1vv.ws-us117.gitpod.io + - NEXT_PUBLIC_API_URL=https://8081-35c4n0r-keep-j5ok1nvq1vv.ws-us117.gitpod.io + - POSTHOG_KEY=phc_muk9qE3TfZsX3SZ9XxX52kCGJBclrjhkP9JxAQcm1PZ + - POSTHOG_HOST=https://ingest.keephq.dev + - NEXT_PUBLIC_SENTRY_DSN=https://0d4d59e3105ffe8afa27dcb95a222009@o4505515398922240.ingest.us.sentry.io/4508258058764288 + - PUSHER_HOST=localhost + - PUSHER_PORT=6001 + - PUSHER_APP_KEY=keepappkey + - NEXT_PUBLIC_KEEP_VERSION=0.2.9 + - AUTH_TYPE=DB + - API_URL=http://keep-backend-db-auth:8080 + - POSTHOG_DISABLED=true + - FRIGADE_DISABLED=true + - SENTRY_DISABLED=true + + # Backend Services (8081) + keep-backend-db-auth: + build: + context: . + dockerfile: docker/Dockerfile.api + ports: + - "8081:8080" + environment: + - PORT=8080 + - SECRET_MANAGER_TYPE=FILE + - SECRET_MANAGER_DIRECTORY=/state + - OPENAI_API_KEY=$OPENAI_API_KEY + - PUSHER_APP_ID=1 + - PUSHER_APP_KEY=keepappkey + - PUSHER_APP_SECRET=keepappsecret + - PUSHER_HOST=keep-websocket-server + - PUSHER_PORT=6001 + - USE_NGROK=false + - AUTH_TYPE=DB + - DATABASE_CONNECTION_STRING=mysql+pymysql://root:keep@keep-database-db-auth:3306/keep + - POSTHOG_DISABLED=true + - FRIGADE_DISABLED=true + - SECRET_MANAGER_DIRECTORY=/app + - SQLALCHEMY_WARN_20=1 + - KEEP_JWT_SECRET=verysecretkey + - KEEP_DEFAULT_USERNAME=keep + - KEEP_DEFAULT_PASSWORD=keep + depends_on: + keep-database-db-auth: + condition: service_healthy + + + # Other Services (Common) keep-websocket-server: extends: file: docker-compose.common.yml @@ -59,5 +138,20 @@ services: ports: - "9090:9090" + grafana: + image: grafana/grafana-enterprise:10.4.0 + user: "472" # Grafana's default user ID + ports: + - "3002:3000" + volumes: + - ./keep/providers/grafana_provider/grafana/provisioning:/etc/grafana/provisioning:ro + - ./keep/providers/grafana_provider/grafana/grafana.ini:/etc/grafana/grafana.ini:ro + - grafana-storage:/var/lib/grafana + environment: + - GF_SECURITY_ADMIN_PASSWORD=admin + depends_on: + - prometheus-server-for-test-target + volumes: mysql-data: + grafana-storage: {} diff --git a/tests/e2e_tests/docker-compose-e2e-postgres.yml b/tests/e2e_tests/docker-compose-e2e-postgres.yml index cd07a9e02..5cb362f51 100644 --- a/tests/e2e_tests/docker-compose-e2e-postgres.yml +++ b/tests/e2e_tests/docker-compose-e2e-postgres.yml @@ -1,4 +1,6 @@ services: + ## Keep Services with NO_AUTH + # Database Service keep-database: image: postgres:13 environment: @@ -12,6 +14,7 @@ services: - ./postgres-custom.conf:/etc/postgresql/conf.d/custom.conf - ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d + # Frontend Services keep-frontend: extends: file: docker-compose.common.yml @@ -26,6 +29,7 @@ services: - FRIGADE_DISABLED=true - SENTRY_DISABLED=true + # Backend Services keep-backend: extends: file: docker-compose.common.yml @@ -43,6 +47,78 @@ services: depends_on: - keep-database + + ## Keep Services with DB + # Database Service (5433) + keep-database-db-auth: + image: postgres:13 + environment: + POSTGRES_USER: keepuser + POSTGRES_PASSWORD: keeppassword + POSTGRES_DB: keepdb + ports: + - "5433:5432" + volumes: + - postgres-data:/var/lib/postgresql-auth-db/data + - ./postgres-custom.conf:/etc/postgresql-auth-db/conf.d/custom.conf + - ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d + + # Frontend Services (3001) + keep-frontend-db-auth: + build: + context: ./keep-ui/ + dockerfile: ../docker/Dockerfile.ui + ports: + - "3001:3000" + environment: + - NEXTAUTH_SECRET=secret + - NEXTAUTH_URL=https://3001-35c4n0r-keep-j5ok1nvq1vv.ws-us117.gitpod.io + - NEXT_PUBLIC_API_URL=https://8081-35c4n0r-keep-j5ok1nvq1vv.ws-us117.gitpod.io + - POSTHOG_KEY=phc_muk9qE3TfZsX3SZ9XxX52kCGJBclrjhkP9JxAQcm1PZ + - POSTHOG_HOST=https://ingest.keephq.dev + - NEXT_PUBLIC_SENTRY_DSN=https://0d4d59e3105ffe8afa27dcb95a222009@o4505515398922240.ingest.us.sentry.io/4508258058764288 + - PUSHER_HOST=localhost + - PUSHER_PORT=6001 + - PUSHER_APP_KEY=keepappkey + - NEXT_PUBLIC_KEEP_VERSION=0.2.9 + - AUTH_TYPE=DB + - API_URL=http://keep-backend-db-auth:8080 + - POSTHOG_DISABLED=true + - FRIGADE_DISABLED=true + - SENTRY_DISABLED=true + + # Backend Services (8081) + keep-backend-db-auth: + build: + context: . + dockerfile: docker/Dockerfile.api + ports: + - "8081:8080" + environment: + - PORT=8080 + - SECRET_MANAGER_TYPE=FILE + - SECRET_MANAGER_DIRECTORY=/state + - OPENAI_API_KEY=$OPENAI_API_KEY + - PUSHER_APP_ID=1 + - PUSHER_APP_KEY=keepappkey + - PUSHER_APP_SECRET=keepappsecret + - PUSHER_HOST=keep-websocket-server + - PUSHER_PORT=6001 + - USE_NGROK=false + - AUTH_TYPE=DB + - DATABASE_CONNECTION_STRING=postgresql+psycopg2://keepuser:keeppassword@keep-database-db-auth:5432/keepdb + - POSTHOG_DISABLED=true + - FRIGADE_DISABLED=true + - SECRET_MANAGER_DIRECTORY=/app + - SQLALCHEMY_WARN_20=1 + - KEEP_JWT_SECRET=verysecretkey + - KEEP_DEFAULT_USERNAME=keep + - KEEP_DEFAULT_PASSWORD=keep + depends_on: + - keep-database-db-auth + + + # Other Services (Common) keep-websocket-server: extends: file: docker-compose.common.yml @@ -56,5 +132,20 @@ services: ports: - "9090:9090" + grafana: + image: grafana/grafana-enterprise:10.4.0 + user: "472" # Grafana's default user ID + ports: + - "3002:3000" + volumes: + - ./keep/providers/grafana_provider/grafana/provisioning:/etc/grafana/provisioning:ro + - ./keep/providers/grafana_provider/grafana/grafana.ini:/etc/grafana/grafana.ini:ro + - grafana-storage:/var/lib/grafana + environment: + - GF_SECURITY_ADMIN_PASSWORD=admin + depends_on: + - prometheus-server-for-test-target + volumes: postgres-data: + grafana-storage: {} diff --git a/tests/e2e_tests/test_end_to_end.py b/tests/e2e_tests/test_end_to_end.py index 34530172f..dca509e05 100644 --- a/tests/e2e_tests/test_end_to_end.py +++ b/tests/e2e_tests/test_end_to_end.py @@ -24,6 +24,7 @@ import os import random + # Adding a new test: # 1. Manually: # - Create a new test function. @@ -36,6 +37,8 @@ import sys import re from datetime import datetime +import requests +from tests.e2e_tests.utils import trigger_alert from playwright.sync_api import expect @@ -130,6 +133,7 @@ def test_insert_new_alert(browser): # browser is actually a page object save_failure_artifacts(browser, log_entries) raise + def test_providers_page_is_accessible(browser): """ Test to check if the providers page is accessible @@ -191,7 +195,7 @@ def test_provider_validation(browser): expect(error_msg).to_have_count(1) host_input.fill("http://localhost") expect(error_msg).to_be_hidden() - host_input.fill( "https://keep.kb.us-central1.gcp.cloud.es.io") + host_input.fill("https://keep.kb.us-central1.gcp.cloud.es.io") expect(error_msg).to_be_hidden() # test `port` field validation port_input = browser.get_by_placeholder("Enter kibana_port") @@ -284,6 +288,7 @@ def test_provider_validation(browser): save_failure_artifacts(browser, log_entries) raise + def test_add_workflow(browser): """ Test to add a workflow node @@ -300,7 +305,9 @@ def test_add_workflow(browser): page.get_by_placeholder("Set the name").press("ControlOrMeta+a") page.get_by_placeholder("Set the name").fill("Example Console Workflow") page.get_by_placeholder("Set the name").press("Tab") - page.get_by_placeholder("Set the description").fill("Example workflow description") + page.get_by_placeholder("Set the description").fill( + "Example workflow description" + ) page.get_by_test_id("wf-add-trigger-button").first.click() page.get_by_text("Manual").click() page.get_by_test_id("wf-add-step-button").first.click() @@ -313,8 +320,57 @@ def test_add_workflow(browser): page.get_by_placeholder("message").fill("Hello world!") page.get_by_role("button", name="Save & Deploy").click() page.wait_for_url(re.compile("http://localhost:3000/workflows/.*")) - expect(page.get_by_test_id("wf-name")).to_contain_text("Example Console Workflow") - expect(page.get_by_test_id("wf-description")).to_contain_text("Example workflow description") + expect(page.get_by_test_id("wf-name")).to_contain_text( + "Example Console Workflow" + ) + expect(page.get_by_test_id("wf-description")).to_contain_text( + "Example workflow description" + ) except Exception: save_failure_artifacts(page, log_entries) raise + + +def test_add_upload_workflow_with_alert_trigger(browser): + log_entries = [] + setup_console_listener(browser, log_entries) + try: + provider_name = "playwright_test_add_upload_workflow_with_alert_trigger" + browser.goto("http://localhost:3000/signin") + browser.get_by_role("link", name="Workflows").hover() + browser.get_by_role("link", name="Workflows").click() + browser.get_by_role("button", name="Upload Workflows").click() + file_input = browser.locator("#workflowFile") + file_input.set_input_files( + [r"./workflow-sample.yaml"] + ) + browser.get_by_role("button", name="Upload") + browser.wait_for_timeout(10000) + trigger_alert("prometheus") + browser.wait_for_timeout(3000) + browser.reload() + browser.wait_for_timeout(3000) + workflow_card = browser.locator( + "[data-sentry-component='WorkflowTile']", + has_text="9b3664f4-b248-4eda-8cc7-e69bc5a8bd92", + ) + expect(workflow_card).not_to_contain_text("No data available") + except Exception: + save_failure_artifacts(browser, log_entries) + raise + + +def test_start_with_keep_db(browser): + log_entries = [] + setup_console_listener(browser, log_entries) + try: + browser.goto("http://localhost:3001/signin") + browser.wait_for_timeout(3000) + browser.get_by_placeholder("Enter your username").fill("keep") + browser.get_by_placeholder("Enter your password").fill("keep") + browser.get_by_role("button", name="Sign in").click() + browser.wait_for_timeout(5000) + expect(browser).to_have_url("http://localhost:3001/incidents") + except Exception: + save_failure_artifacts(browser, log_entries) + raise diff --git a/tests/e2e_tests/test_grafana_provider.py b/tests/e2e_tests/test_grafana_provider.py new file mode 100644 index 000000000..ccb27f8c4 --- /dev/null +++ b/tests/e2e_tests/test_grafana_provider.py @@ -0,0 +1,169 @@ +import os +import re +import sys +import time +from datetime import datetime + +import requests +from playwright.sync_api import expect + +from tests.e2e_tests.utils import trigger_alert + + +os.environ["PLAYWRIGHT_HEADLESS"] = "false" + +GRAFANA_HOST = "http://localhost:3002" +KEEP_UI_URL = "http://localhost:3000" + + +def get_grafana_access_token(role: str): + headers = { + "Content-Type": "application/json", + } + json_data_service_account = { + "name": f'test-{role}-{datetime.now().strftime("%Y%m%d%H%M%S")}', + "role": role, + } + auth = ("admin", "admin") + service_account = requests.post( + f"{GRAFANA_HOST}/api/serviceaccounts", + headers=headers, + json=json_data_service_account, + auth=auth, + ) + service_account = service_account.json() + + json_data__token = { + "name": f'test-token-{datetime.now().strftime("%Y%m%d%H%M%S")}', + } + + token_response = requests.post( + f'{GRAFANA_HOST}/api/serviceaccounts/{service_account["id"]}/tokens', + headers=headers, + json=json_data__token, + auth=("admin", "admin"), + ) + return token_response.json()["key"] + + +def open_grafana_card(browser): + browser.get_by_placeholder("Filter providers...").click() + browser.get_by_placeholder("Filter providers...").clear() + browser.get_by_placeholder("Filter providers...").fill("Grafana") + browser.get_by_placeholder("Filter providers...").press("Enter") + browser.get_by_text("Available Providers").hover() + grafana_tile = browser.locator( + "button:has-text('Grafana'):has-text('alert'):not(:has-text('Linked'))" + ) + grafana_tile.first.hover() + grafana_tile.first.click() + + +def test_grafana_provider(browser): + try: + provider_name = "playwright_test_" + datetime.now().strftime("%Y%m%d%H%M%S") + provider_name_invalid = provider_name + "-invalid" + provider_name_readonly = provider_name + "-read-only" + provider_name_success = provider_name + "-success" + + browser.goto(f"{KEEP_UI_URL}/signin") + browser.get_by_role("link", name="Providers").hover() + browser.get_by_role("link", name="Providers").click() + + browser.wait_for_timeout(10000) + # First trying to install with invalid token, provider installation should fail + open_grafana_card(browser) + browser.get_by_placeholder("Enter provider name").fill(provider_name_invalid) + browser.get_by_placeholder("Enter token").fill("random_token_UwU") + browser.get_by_placeholder("Enter host").fill(GRAFANA_HOST) + browser.get_by_role("button", name="Connect", exact=True).click() + expect( + browser.locator("span.tremor-Badge-text:has-text('Missing Scope')") + ).to_have_count(3) + browser.get_by_role("button", name="Cancel", exact=True).click() + + # Then trying to install with read scope, webhook installation should fail + open_grafana_card(browser) + browser.get_by_placeholder("Enter provider name").fill(provider_name_readonly) + browser.get_by_placeholder("Enter token").fill( + get_grafana_access_token("Viewer") + ) + browser.get_by_placeholder("Enter host").fill(GRAFANA_HOST) + browser.get_by_role("button", name="Connect", exact=True).click() + browser.wait_for_timeout(5000) + # browser.reload() + browser.locator( + f"button:has-text('Grafana'):has-text('Connected'):has-text('{provider_name_readonly}')" + ).click() + expect( + browser.locator("span.tremor-Badge-text:has-text('Missing Scope')") + ).to_have_count(2) + expect( + browser.locator("span.tremor-Badge-text:has-text('Valid')") + ).to_have_count(1) + browser.get_by_role("button", name="Cancel", exact=True).click() + + # Then trying to install with admin scope, webhook installation should pass + open_grafana_card(browser) + browser.get_by_placeholder("Enter provider name").fill(provider_name_success) + browser.get_by_placeholder("Enter token").fill( + get_grafana_access_token("Admin") + ) + browser.get_by_placeholder("Enter host").fill(GRAFANA_HOST) + browser.get_by_role("button", name="Connect", exact=True).click() + + browser.locator( + f"button:has-text('Grafana'):has-text('Connected'):has-text('{provider_name_success}')" + ).click() + toast_div = browser.locator("div.Toastify") + browser.get_by_role("button", name="Install/Update Webhook", exact=True).click() + expect(toast_div).to_contain_text("grafana webhook installed", timeout=10000) + expect( + browser.locator("span.tremor-Badge-text:has-text('Valid')") + ).to_have_count(3) + browser.get_by_role("button", name="Cancel", exact=True).click() + + trigger_alert("grafana") + browser.get_by_role("link", name="Feed").hover() + browser.get_by_role("link", name="Feed").click() + + max_attemps = 5 + + for attempt in range(max_attemps): + print(f"Attempt {attempt + 1} to load alerts...") + browser.get_by_role("link", name="Feed").click() + + try: + # Wait for an element that indicates alerts have loaded + try: + browser.wait_for_selector( + "text=HighMemoryConsumption", timeout=5000 + ) + print("Alerts loaded successfully.") + break + except Exception: + browser.wait_for_selector("text=NetworkLatencyIsHigh", timeout=5000) + print("Alerts loaded successfully.") + break + except Exception: + if attempt < max_attemps - 1: + print("Alerts not loaded yet. Retrying...") + browser.reload() + else: + print("Failed to load alerts after maximum attempts.") + raise Exception("Failed to load alerts after maximum attempts.") + + except Exception: + # Current file + test name for unique html and png dump. + current_test_name = ( + "playwright_dump_" + + os.path.basename(__file__)[:-3] + + "_" + + sys._getframe().f_code.co_name + ) + + browser.screenshot(path=current_test_name + ".png") + with open(current_test_name + ".html", "w") as f: + f.write(browser.content()) + + raise diff --git a/tests/e2e_tests/utils.py b/tests/e2e_tests/utils.py new file mode 100644 index 000000000..66c2a1c6e --- /dev/null +++ b/tests/e2e_tests/utils.py @@ -0,0 +1,15 @@ +from keep.providers.providers_factory import ProvidersFactory +import requests + + +def trigger_alert(provider_name): + provider = ProvidersFactory.get_provider_class(provider_name) + requests.post( + f"https://8080-35c4n0r-keep-j5ok1nvq1vv.ws-us117.gitpod.io/alerts/event/{provider_name}", + headers={ + "Content-Type": "application/json", + "Accept": "application/json", + "X-API-KEY": "3db87031-41c7-43cf-9a20-7cdbcf32f97d", + }, + json=provider.simulate_alert(), + ) diff --git a/tests/e2e_tests/workflow-sample.yaml b/tests/e2e_tests/workflow-sample.yaml new file mode 100644 index 000000000..d2a147191 --- /dev/null +++ b/tests/e2e_tests/workflow-sample.yaml @@ -0,0 +1,22 @@ +workflow: + actions: + - name: echo + provider: + config: "{{ providers.default-console }}" + type: console + with: + logger: true + message: "{{alert.payload.summary}}" + consts: {} + description: playwright_test_add_upload_workflow_with_alert_trigger + disabled: false + id: 9b3664f4-b248-4eda-8cc7-e69bc5a8bd92 + name: 9b3664f4-b248-4eda-8cc7-e69bc5a8bd92 + owners: [] + services: [] + steps: [] + triggers: + - filters: + - key: source + value: prometheus + type: alert From c7a8b8667e9ffed90dd925dceb43b845785b956c Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Sun, 19 Jan 2025 01:18:52 +0530 Subject: [PATCH 02/37] feat: gitpod --> localhost Signed-off-by: 35C4n0r --- tests/e2e_tests/docker-compose-e2e-mysql.yml | 4 ++-- tests/e2e_tests/docker-compose-e2e-postgres.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/e2e_tests/docker-compose-e2e-mysql.yml b/tests/e2e_tests/docker-compose-e2e-mysql.yml index 03f5076f0..bdefca7c3 100644 --- a/tests/e2e_tests/docker-compose-e2e-mysql.yml +++ b/tests/e2e_tests/docker-compose-e2e-mysql.yml @@ -77,8 +77,8 @@ services: - "3001:3000" environment: - NEXTAUTH_SECRET=secret - - NEXTAUTH_URL=https://3001-35c4n0r-keep-j5ok1nvq1vv.ws-us117.gitpod.io - - NEXT_PUBLIC_API_URL=https://8081-35c4n0r-keep-j5ok1nvq1vv.ws-us117.gitpod.io + - NEXTAUTH_URL=http://localhost:3001 + - NEXT_PUBLIC_API_URL=http://localhost:8081 - POSTHOG_KEY=phc_muk9qE3TfZsX3SZ9XxX52kCGJBclrjhkP9JxAQcm1PZ - POSTHOG_HOST=https://ingest.keephq.dev - NEXT_PUBLIC_SENTRY_DSN=https://0d4d59e3105ffe8afa27dcb95a222009@o4505515398922240.ingest.us.sentry.io/4508258058764288 diff --git a/tests/e2e_tests/docker-compose-e2e-postgres.yml b/tests/e2e_tests/docker-compose-e2e-postgres.yml index 5cb362f51..931750732 100644 --- a/tests/e2e_tests/docker-compose-e2e-postgres.yml +++ b/tests/e2e_tests/docker-compose-e2e-postgres.yml @@ -72,8 +72,8 @@ services: - "3001:3000" environment: - NEXTAUTH_SECRET=secret - - NEXTAUTH_URL=https://3001-35c4n0r-keep-j5ok1nvq1vv.ws-us117.gitpod.io - - NEXT_PUBLIC_API_URL=https://8081-35c4n0r-keep-j5ok1nvq1vv.ws-us117.gitpod.io + - NEXTAUTH_URL=http://localhost:3001 + - NEXT_PUBLIC_API_URL=http://localhost:8081 - POSTHOG_KEY=phc_muk9qE3TfZsX3SZ9XxX52kCGJBclrjhkP9JxAQcm1PZ - POSTHOG_HOST=https://ingest.keephq.dev - NEXT_PUBLIC_SENTRY_DSN=https://0d4d59e3105ffe8afa27dcb95a222009@o4505515398922240.ingest.us.sentry.io/4508258058764288 From 24b49dcdced2099cf8f17d08473af8502f2651a6 Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Sun, 19 Jan 2025 01:33:23 +0530 Subject: [PATCH 03/37] feat: multiple name instances Signed-off-by: 35C4n0r --- .github/workflows/test-pr-e2e.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-pr-e2e.yml b/.github/workflows/test-pr-e2e.yml index 2a8dfb696..76d768621 100644 --- a/.github/workflows/test-pr-e2e.yml +++ b/.github/workflows/test-pr-e2e.yml @@ -93,12 +93,12 @@ jobs: run: | # Add commands to wait for the database to be ready if [ "${{ matrix.db_type }}" == "mysql" ]; then - until docker exec $(docker ps -qf "name=keep-database") mysqladmin ping -h "localhost" --silent; do + until docker exec $(docker ps -qf "name=keep-database-1") mysqladmin ping -h "localhost" --silent; do echo "Waiting for MySQL to be ready..." sleep 2 done elif [ "${{ matrix.db_type }}" == "postgres" ]; then - until docker exec $(docker ps -qf "name=keep-database") pg_isready -h localhost -U keepuser; do + until docker exec $(docker ps -qf "name=keep-database-1") pg_isready -h localhost -U keepuser; do echo "Waiting for Postgres to be ready..." sleep 2 done From 3c3014f8d4cd9cfa8edc4517ca47064a4476f5dc Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Sun, 19 Jan 2025 02:49:08 +0530 Subject: [PATCH 04/37] chore: minor fix Signed-off-by: 35C4n0r --- tests/e2e_tests/test_end_to_end.py | 1 + tests/e2e_tests/utils.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_end_to_end.py b/tests/e2e_tests/test_end_to_end.py index dca509e05..b5c0f4132 100644 --- a/tests/e2e_tests/test_end_to_end.py +++ b/tests/e2e_tests/test_end_to_end.py @@ -340,6 +340,7 @@ def test_add_upload_workflow_with_alert_trigger(browser): browser.get_by_role("link", name="Workflows").hover() browser.get_by_role("link", name="Workflows").click() browser.get_by_role("button", name="Upload Workflows").click() + browser.wait_for_timeout(5000) file_input = browser.locator("#workflowFile") file_input.set_input_files( [r"./workflow-sample.yaml"] diff --git a/tests/e2e_tests/utils.py b/tests/e2e_tests/utils.py index 66c2a1c6e..0cfdb304f 100644 --- a/tests/e2e_tests/utils.py +++ b/tests/e2e_tests/utils.py @@ -5,7 +5,7 @@ def trigger_alert(provider_name): provider = ProvidersFactory.get_provider_class(provider_name) requests.post( - f"https://8080-35c4n0r-keep-j5ok1nvq1vv.ws-us117.gitpod.io/alerts/event/{provider_name}", + f"http://localhost:8080/alerts/event/{provider_name}", headers={ "Content-Type": "application/json", "Accept": "application/json", From 4df2cc2a2af53b06f76391afb81613662cb281be Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Sun, 19 Jan 2025 10:09:12 +0530 Subject: [PATCH 05/37] chore: minor fix Signed-off-by: 35C4n0r --- .github/workflows/test-pr-e2e.yml | 2 ++ tests/e2e_tests/test_end_to_end.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-pr-e2e.yml b/.github/workflows/test-pr-e2e.yml index 76d768621..77247f245 100644 --- a/.github/workflows/test-pr-e2e.yml +++ b/.github/workflows/test-pr-e2e.yml @@ -88,6 +88,8 @@ jobs: DOCKER_BUILDKIT=1 docker compose \ --project-directory . \ -f tests/e2e_tests/docker-compose-e2e-${{ matrix.db_type }}.yml up -d + + docker ps - name: Wait for database to be ready run: | diff --git a/tests/e2e_tests/test_end_to_end.py b/tests/e2e_tests/test_end_to_end.py index b5c0f4132..3aed22c31 100644 --- a/tests/e2e_tests/test_end_to_end.py +++ b/tests/e2e_tests/test_end_to_end.py @@ -343,7 +343,7 @@ def test_add_upload_workflow_with_alert_trigger(browser): browser.wait_for_timeout(5000) file_input = browser.locator("#workflowFile") file_input.set_input_files( - [r"./workflow-sample.yaml"] + [r"./keep/test/e2e_tests/workflow-sample.yaml"] ) browser.get_by_role("button", name="Upload") browser.wait_for_timeout(10000) From 305a59ba49207efa350eed5b2f7d3e9ca599ac37 Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Sun, 19 Jan 2025 10:28:57 +0530 Subject: [PATCH 06/37] chore: minor fix Signed-off-by: 35C4n0r --- .github/workflows/test-pr-e2e.yml | 44 +++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/.github/workflows/test-pr-e2e.yml b/.github/workflows/test-pr-e2e.yml index 77247f245..e3fa06fab 100644 --- a/.github/workflows/test-pr-e2e.yml +++ b/.github/workflows/test-pr-e2e.yml @@ -105,6 +105,20 @@ jobs: sleep 2 done fi + + + if [ "${{ matrix.db_type }}" == "mysql" ]; then + until docker exec $(docker ps -qf "name=keep-database-db-auth-1") mysqladmin ping -h "localhost" --silent; do + echo "Waiting for MySQL (DB AUTH) to be ready..." + sleep 2 + done + elif [ "${{ matrix.db_type }}" == "postgres" ]; then + until docker exec $(docker ps -qf "name=keep-database-db-auth-1") pg_isready -h localhost -U keepuser; do + echo "Waiting for Postgres (DB AUTH) to be ready..." + sleep 2 + done + fi + # wait to keep backend on port 8080 echo "Waiting for Keep backend to be ready..." @@ -120,6 +134,16 @@ jobs: attempt=$((attempt+1)) sleep 2 done + + until $(curl --output /dev/null --silent --fail http://localhost:8081/healthcheck); do + if [ "$attempt" -ge "$max_attempts" ]; then + echo "Max attempts reached, exiting... Sometimes Keep can't start because of double-headed migrations, use: 'alembic -c keep/alembic.ini history' to investigate, or check artifacts." + exit 1 + fi + echo "Waiting for Keep backend (DB AUTH) to be ready... (Attempt: $((attempt+1)))" + attempt=$((attempt+1)) + sleep 2 + done echo "Keep backend is ready!" # wait to the backend @@ -136,6 +160,26 @@ jobs: attempt=$((attempt+1)) sleep 2 done + + until $(curl --output /dev/null --silent --fail http://localhost:3001/); do + if [ "$attempt" -ge "$max_attempts" ]; then + echo "Max attempts reached, exiting..." + exit 1 + fi + echo "Waiting for Keep frontend (DB AUTH) to be ready... (Attempt: $((attempt+1)))" + attempt=$((attempt+1)) + sleep 2 + done + + until $(curl --output /dev/null --silent --fail http://localhost:3002/api/health); do + if [ "$attempt" -ge "$max_attempts" ]; then + echo "Max attempts reached, exiting... " + exit 1 + fi + echo "Waiting for Grafana to be ready... (Attempt: $((attempt+1)))" + attempt=$((attempt+1)) + sleep 2 + done # create the state directory # mkdir -p ./state && chown -R root:root ./state && chmod -R 777 ./state From fc19afd3b37a5e7eff4c6d84b248a7a268a22249 Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Sun, 19 Jan 2025 10:48:51 +0530 Subject: [PATCH 07/37] chore: minor fix Signed-off-by: 35C4n0r --- .github/workflows/test-pr-e2e.yml | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test-pr-e2e.yml b/.github/workflows/test-pr-e2e.yml index e3fa06fab..da587028d 100644 --- a/.github/workflows/test-pr-e2e.yml +++ b/.github/workflows/test-pr-e2e.yml @@ -94,6 +94,7 @@ jobs: - name: Wait for database to be ready run: | # Add commands to wait for the database to be ready + echo "Waiting for Database to be ready..." if [ "${{ matrix.db_type }}" == "mysql" ]; then until docker exec $(docker ps -qf "name=keep-database-1") mysqladmin ping -h "localhost" --silent; do echo "Waiting for MySQL to be ready..." @@ -105,8 +106,9 @@ jobs: sleep 2 done fi + echo "Database is ready!" - + echo "Waiting for Database (DB AUTH) to be ready..." if [ "${{ matrix.db_type }}" == "mysql" ]; then until docker exec $(docker ps -qf "name=keep-database-db-auth-1") mysqladmin ping -h "localhost" --silent; do echo "Waiting for MySQL (DB AUTH) to be ready..." @@ -117,7 +119,8 @@ jobs: echo "Waiting for Postgres (DB AUTH) to be ready..." sleep 2 done - fi + fi + echo "Database (DB AUTH) is ready!" # wait to keep backend on port 8080 @@ -134,7 +137,11 @@ jobs: attempt=$((attempt+1)) sleep 2 done + echo "Keep backend is ready!" + attempt=0 + max_attempts=10 + echo "Waiting for Keep backend (DB AUTH) to be ready..." until $(curl --output /dev/null --silent --fail http://localhost:8081/healthcheck); do if [ "$attempt" -ge "$max_attempts" ]; then echo "Max attempts reached, exiting... Sometimes Keep can't start because of double-headed migrations, use: 'alembic -c keep/alembic.ini history' to investigate, or check artifacts." @@ -144,9 +151,10 @@ jobs: attempt=$((attempt+1)) sleep 2 done - - echo "Keep backend is ready!" + echo "Keep backend (DB AUTH) is ready!" # wait to the backend + + echo "Waiting for Keep frontend to be ready..." attempt=0 max_attempts=10 @@ -160,7 +168,11 @@ jobs: attempt=$((attempt+1)) sleep 2 done + echo "Keep frontend is ready" + echo "Waiting for Keep frontend (DB AUTH) to be ready..." + attempt=0 + max_attempts=10 until $(curl --output /dev/null --silent --fail http://localhost:3001/); do if [ "$attempt" -ge "$max_attempts" ]; then echo "Max attempts reached, exiting..." @@ -170,7 +182,12 @@ jobs: attempt=$((attempt+1)) sleep 2 done - + echo "Keep frontend (DB AUTH) is ready" + + + echo "Waiting for Grafana to be ready..." + attempt=0 + max_attempts=10 until $(curl --output /dev/null --silent --fail http://localhost:3002/api/health); do if [ "$attempt" -ge "$max_attempts" ]; then echo "Max attempts reached, exiting... " @@ -180,6 +197,7 @@ jobs: attempt=$((attempt+1)) sleep 2 done + echo "Grafana is ready..." # create the state directory # mkdir -p ./state && chown -R root:root ./state && chmod -R 777 ./state From b0f4b97d1e03939224883f7c9504991af1e19cb5 Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Sun, 19 Jan 2025 11:08:15 +0530 Subject: [PATCH 08/37] chore: minor fix Signed-off-by: 35C4n0r --- tests/e2e_tests/test_grafana_provider.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_grafana_provider.py b/tests/e2e_tests/test_grafana_provider.py index ccb27f8c4..24b4d924d 100644 --- a/tests/e2e_tests/test_grafana_provider.py +++ b/tests/e2e_tests/test_grafana_provider.py @@ -12,7 +12,8 @@ os.environ["PLAYWRIGHT_HEADLESS"] = "false" -GRAFANA_HOST = "http://localhost:3002" +GRAFANA_HOST = "http://grafana:3002" +GRAFANA_HOST_LOCAL = "http://localhost:3002" KEEP_UI_URL = "http://localhost:3000" From 66a01b25a50f76be1df492f178924c8582f97f7e Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Sun, 19 Jan 2025 11:29:24 +0530 Subject: [PATCH 09/37] chore: minor fix Signed-off-by: 35C4n0r --- .github/workflows/test-pr-e2e.yml | 4 ++++ tests/e2e_tests/test_grafana_provider.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-pr-e2e.yml b/.github/workflows/test-pr-e2e.yml index da587028d..f9ac8f271 100644 --- a/.github/workflows/test-pr-e2e.yml +++ b/.github/workflows/test-pr-e2e.yml @@ -221,6 +221,8 @@ jobs: run: | docker compose --project-directory . -f tests/e2e_tests/docker-compose-e2e-${{ matrix.db_type }}.yml logs keep-backend > backend_logs-${{ matrix.db_type }}.txt docker compose --project-directory . -f tests/e2e_tests/docker-compose-e2e-${{ matrix.db_type }}.yml logs keep-frontend > frontend_logs-${{ matrix.db_type }}.txt + docker compose --project-directory . -f tests/e2e_tests/docker-compose-e2e-${{ matrix.db_type }}.yml logs keep-backend-db-auth > backend_logs-${{ matrix.db_type }}-db-auth.txt + docker compose --project-directory . -f tests/e2e_tests/docker-compose-e2e-${{ matrix.db_type }}.yml logs keep-frontend-db-auth > frontend_logs-${{ matrix.db_type }}-db-auth.txt continue-on-error: true - name: Upload test artifacts on failure @@ -233,6 +235,8 @@ jobs: playwright_dump_*.png backend_logs-${{ matrix.db_type }}.txt frontend_logs-${{ matrix.db_type }}.txt + backend_logs-${{ matrix.db_type }}-db-auth.txt + frontend_logs-${{ matrix.db_type }}-db-auth.txt continue-on-error: true - name: Tear down environment diff --git a/tests/e2e_tests/test_grafana_provider.py b/tests/e2e_tests/test_grafana_provider.py index 24b4d924d..963abc353 100644 --- a/tests/e2e_tests/test_grafana_provider.py +++ b/tests/e2e_tests/test_grafana_provider.py @@ -12,7 +12,7 @@ os.environ["PLAYWRIGHT_HEADLESS"] = "false" -GRAFANA_HOST = "http://grafana:3002" +GRAFANA_HOST = "http://grafana:3000" GRAFANA_HOST_LOCAL = "http://localhost:3002" KEEP_UI_URL = "http://localhost:3000" From 56b32db0981fcdda0c67043eb5a2c0842d0a60d0 Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Sun, 19 Jan 2025 11:43:53 +0530 Subject: [PATCH 10/37] chore: minor fix Signed-off-by: 35C4n0r --- tests/e2e_tests/test_grafana_provider.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e_tests/test_grafana_provider.py b/tests/e2e_tests/test_grafana_provider.py index 963abc353..9fc61bfff 100644 --- a/tests/e2e_tests/test_grafana_provider.py +++ b/tests/e2e_tests/test_grafana_provider.py @@ -27,7 +27,7 @@ def get_grafana_access_token(role: str): } auth = ("admin", "admin") service_account = requests.post( - f"{GRAFANA_HOST}/api/serviceaccounts", + f"{GRAFANA_HOST_LOCAL}/api/serviceaccounts", headers=headers, json=json_data_service_account, auth=auth, @@ -39,7 +39,7 @@ def get_grafana_access_token(role: str): } token_response = requests.post( - f'{GRAFANA_HOST}/api/serviceaccounts/{service_account["id"]}/tokens', + f'{GRAFANA_HOST_LOCAL}/api/serviceaccounts/{service_account["id"]}/tokens', headers=headers, json=json_data__token, auth=("admin", "admin"), From 7623917aa818e109178b43024620adda6b02d777 Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Sun, 19 Jan 2025 12:26:08 +0530 Subject: [PATCH 11/37] chore: minor fix Signed-off-by: 35C4n0r --- tests/e2e_tests/test_end_to_end.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/e2e_tests/test_end_to_end.py b/tests/e2e_tests/test_end_to_end.py index 3aed22c31..4cb22d5a5 100644 --- a/tests/e2e_tests/test_end_to_end.py +++ b/tests/e2e_tests/test_end_to_end.py @@ -335,7 +335,6 @@ def test_add_upload_workflow_with_alert_trigger(browser): log_entries = [] setup_console_listener(browser, log_entries) try: - provider_name = "playwright_test_add_upload_workflow_with_alert_trigger" browser.goto("http://localhost:3000/signin") browser.get_by_role("link", name="Workflows").hover() browser.get_by_role("link", name="Workflows").click() @@ -343,7 +342,7 @@ def test_add_upload_workflow_with_alert_trigger(browser): browser.wait_for_timeout(5000) file_input = browser.locator("#workflowFile") file_input.set_input_files( - [r"./keep/test/e2e_tests/workflow-sample.yaml"] + "./tests/e2e_tests/workflow-sample.yaml" ) browser.get_by_role("button", name="Upload") browser.wait_for_timeout(10000) From 6b01805c1298607c554ea808f3b84d62fb9af909 Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Sun, 19 Jan 2025 12:53:35 +0530 Subject: [PATCH 12/37] chore: fix prom test Signed-off-by: 35C4n0r --- tests/e2e_tests/test_pushing_prometheus_alerts.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tests/e2e_tests/test_pushing_prometheus_alerts.py b/tests/e2e_tests/test_pushing_prometheus_alerts.py index 63a14f7cb..f2caa5b4e 100644 --- a/tests/e2e_tests/test_pushing_prometheus_alerts.py +++ b/tests/e2e_tests/test_pushing_prometheus_alerts.py @@ -90,18 +90,17 @@ def test_pulling_prometheus_alerts_to_provider(browser): # Delete provider browser.get_by_role("link", name="Providers").click() - browser.locator("button").filter( - has_text=re.compile(re.escape(provider_name)) - ).first.hover() - browser.locator(".tile-basis").first.click() + browser.locator( + f"button:has-text('Prometheus'):has-text('Connected'):has-text('{provider_name}')" + ).click() browser.once("dialog", lambda dialog: dialog.accept()) browser.get_by_role("button", name="Delete").click() # Assert provider was deleted expect( - browser.locator("button") - .filter(has_text=re.compile(re.escape(provider_name))) - .first + browser.locator( + f"button:has-text('Prometheus'):has-text('Connected'):has-text('{provider_name}')" + ) ).not_to_be_visible() except Exception: # Current file + test name for unique html and png dump. From 461742e5af2779d249697c39305d55cf862ed5f3 Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Sun, 19 Jan 2025 13:20:26 +0530 Subject: [PATCH 13/37] chore: minor fixes Signed-off-by: 35C4n0r --- tests/e2e_tests/test_end_to_end.py | 1 + tests/e2e_tests/test_grafana_provider.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/tests/e2e_tests/test_end_to_end.py b/tests/e2e_tests/test_end_to_end.py index 4cb22d5a5..ea64a72d1 100644 --- a/tests/e2e_tests/test_end_to_end.py +++ b/tests/e2e_tests/test_end_to_end.py @@ -368,6 +368,7 @@ def test_start_with_keep_db(browser): browser.wait_for_timeout(3000) browser.get_by_placeholder("Enter your username").fill("keep") browser.get_by_placeholder("Enter your password").fill("keep") + browser.wait_for_timeout(3000) browser.get_by_role("button", name="Sign in").click() browser.wait_for_timeout(5000) expect(browser).to_have_url("http://localhost:3001/incidents") diff --git a/tests/e2e_tests/test_grafana_provider.py b/tests/e2e_tests/test_grafana_provider.py index 9fc61bfff..ae1bb3d51 100644 --- a/tests/e2e_tests/test_grafana_provider.py +++ b/tests/e2e_tests/test_grafana_provider.py @@ -154,6 +154,21 @@ def test_grafana_provider(browser): print("Failed to load alerts after maximum attempts.") raise Exception("Failed to load alerts after maximum attempts.") + # Delete provider + browser.get_by_role("link", name="Providers").click() + browser.locator( + f"button:has-text('Grafana'):has-text('Connected'):has-text('{provider_name}')" + ).click() + browser.once("dialog", lambda dialog: dialog.accept()) + browser.get_by_role("button", name="Delete").click() + + # Assert provider was deleted + expect( + browser.locator( + f"button:has-text('Prometheus'):has-text('Connected'):has-text('{provider_name}')" + ) + ).not_to_be_visible() + except Exception: # Current file + test name for unique html and png dump. current_test_name = ( From 2b3db30b02f65f262be66896bc42649bc72a46a0 Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Sun, 19 Jan 2025 13:23:50 +0530 Subject: [PATCH 14/37] chore: minor fixes Signed-off-by: 35C4n0r --- tests/e2e_tests/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/utils.py b/tests/e2e_tests/utils.py index 0cfdb304f..5deb6eba8 100644 --- a/tests/e2e_tests/utils.py +++ b/tests/e2e_tests/utils.py @@ -9,7 +9,7 @@ def trigger_alert(provider_name): headers={ "Content-Type": "application/json", "Accept": "application/json", - "X-API-KEY": "3db87031-41c7-43cf-9a20-7cdbcf32f97d", + "X-API-KEY": "really_random_secret", }, json=provider.simulate_alert(), ) From bb82f5050c35237d9235032afb73eade5b12d813 Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Sun, 19 Jan 2025 15:18:51 +0530 Subject: [PATCH 15/37] chore: minor fixes Signed-off-by: 35C4n0r --- tests/e2e_tests/test_grafana_provider.py | 25 +++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/tests/e2e_tests/test_grafana_provider.py b/tests/e2e_tests/test_grafana_provider.py index ae1bb3d51..95ff2d857 100644 --- a/tests/e2e_tests/test_grafana_provider.py +++ b/tests/e2e_tests/test_grafana_provider.py @@ -154,20 +154,23 @@ def test_grafana_provider(browser): print("Failed to load alerts after maximum attempts.") raise Exception("Failed to load alerts after maximum attempts.") + total_providers = 2 # Delete provider browser.get_by_role("link", name="Providers").click() - browser.locator( + for item in browser.locator( f"button:has-text('Grafana'):has-text('Connected'):has-text('{provider_name}')" - ).click() - browser.once("dialog", lambda dialog: dialog.accept()) - browser.get_by_role("button", name="Delete").click() - - # Assert provider was deleted - expect( - browser.locator( - f"button:has-text('Prometheus'):has-text('Connected'):has-text('{provider_name}')" - ) - ).not_to_be_visible() + ): + total_providers -= 1 + item.click() + browser.once("dialog", lambda dialog: dialog.accept()) + browser.get_by_role("button", name="Delete").click() + + # Assert provider was deleted + expect( + browser.locator( + f"button:has-text('Grafana'):has-text('Connected'):has-text('{provider_name}')" + ) + ).to_have_count(total_providers) except Exception: # Current file + test name for unique html and png dump. From 58e44eaf86d329aa5bc4a4b1f3dba877ba6391cf Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Sun, 19 Jan 2025 15:41:44 +0530 Subject: [PATCH 16/37] chore: minor fixes Signed-off-by: 35C4n0r --- tests/e2e_tests/test_grafana_provider.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tests/e2e_tests/test_grafana_provider.py b/tests/e2e_tests/test_grafana_provider.py index 95ff2d857..dbb4c663f 100644 --- a/tests/e2e_tests/test_grafana_provider.py +++ b/tests/e2e_tests/test_grafana_provider.py @@ -154,13 +154,20 @@ def test_grafana_provider(browser): print("Failed to load alerts after maximum attempts.") raise Exception("Failed to load alerts after maximum attempts.") - total_providers = 2 - # Delete provider - browser.get_by_role("link", name="Providers").click() - for item in browser.locator( + locator = browser.locator( f"button:has-text('Grafana'):has-text('Connected'):has-text('{provider_name}')" - ): - total_providers -= 1 + ) + + # Get the count of matching elements + count = locator.count() + + if count == 0: + raise Exception("No matching providers found.") + + for index in range(count): + count -= 1 + # Perform actions on each matching element + item = locator.nth(index) item.click() browser.once("dialog", lambda dialog: dialog.accept()) browser.get_by_role("button", name="Delete").click() @@ -170,7 +177,7 @@ def test_grafana_provider(browser): browser.locator( f"button:has-text('Grafana'):has-text('Connected'):has-text('{provider_name}')" ) - ).to_have_count(total_providers) + ).to_have_count(count) except Exception: # Current file + test name for unique html and png dump. From d3ae308e74e829d626831cef4c931454bc69eee8 Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Sun, 19 Jan 2025 16:44:11 +0530 Subject: [PATCH 17/37] chore: minor fixes Signed-off-by: 35C4n0r --- tests/e2e_tests/test_grafana_provider.py | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/tests/e2e_tests/test_grafana_provider.py b/tests/e2e_tests/test_grafana_provider.py index dbb4c663f..f65d5cb44 100644 --- a/tests/e2e_tests/test_grafana_provider.py +++ b/tests/e2e_tests/test_grafana_provider.py @@ -154,30 +154,22 @@ def test_grafana_provider(browser): print("Failed to load alerts after maximum attempts.") raise Exception("Failed to load alerts after maximum attempts.") - locator = browser.locator( - f"button:has-text('Grafana'):has-text('Connected'):has-text('{provider_name}')" - ) - - # Get the count of matching elements - count = locator.count() - - if count == 0: - raise Exception("No matching providers found.") + providers_to_delete = [provider_name_readonly, provider_name_success] - for index in range(count): - count -= 1 + for provider_to_delete in providers_to_delete: # Perform actions on each matching element - item = locator.nth(index) - item.click() + browser.locator( + f"button:has-text('Grafana'):has-text('Connected'):has-text('{provider_to_delete}')" + ).click() browser.once("dialog", lambda dialog: dialog.accept()) browser.get_by_role("button", name="Delete").click() # Assert provider was deleted expect( browser.locator( - f"button:has-text('Grafana'):has-text('Connected'):has-text('{provider_name}')" + f"button:has-text('Grafana'):has-text('Connected'):has-text('{provider_to_delete}')" ) - ).to_have_count(count) + ).to_have_count(0) except Exception: # Current file + test name for unique html and png dump. From 2a3bf9aae61e72c68dbc32c8236353c7c9f2bfdc Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Sun, 19 Jan 2025 17:00:31 +0530 Subject: [PATCH 18/37] chore: minor fixes Signed-off-by: 35C4n0r --- tests/e2e_tests/test_grafana_provider.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/e2e_tests/test_grafana_provider.py b/tests/e2e_tests/test_grafana_provider.py index f65d5cb44..55cc235be 100644 --- a/tests/e2e_tests/test_grafana_provider.py +++ b/tests/e2e_tests/test_grafana_provider.py @@ -154,6 +154,9 @@ def test_grafana_provider(browser): print("Failed to load alerts after maximum attempts.") raise Exception("Failed to load alerts after maximum attempts.") + + browser.get_by_role("link", name="Providers").hover() + browser.get_by_role("link", name="Providers").click() providers_to_delete = [provider_name_readonly, provider_name_success] for provider_to_delete in providers_to_delete: From 59bc901ccaa90eeb7d5373b0c913b1ec44626826 Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Sun, 19 Jan 2025 17:00:54 +0530 Subject: [PATCH 19/37] chore: minor fixes Signed-off-by: 35C4n0r --- tests/e2e_tests/test_grafana_provider.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/e2e_tests/test_grafana_provider.py b/tests/e2e_tests/test_grafana_provider.py index 55cc235be..7c0da2a5d 100644 --- a/tests/e2e_tests/test_grafana_provider.py +++ b/tests/e2e_tests/test_grafana_provider.py @@ -154,7 +154,6 @@ def test_grafana_provider(browser): print("Failed to load alerts after maximum attempts.") raise Exception("Failed to load alerts after maximum attempts.") - browser.get_by_role("link", name="Providers").hover() browser.get_by_role("link", name="Providers").click() providers_to_delete = [provider_name_readonly, provider_name_success] From bd40c233028bd200efbc3d0e8794fb97241195a4 Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Mon, 20 Jan 2025 18:02:21 +0530 Subject: [PATCH 20/37] chore: minor fixes Signed-off-by: 35C4n0r --- .github/workflows/test-pr-e2e.yml | 2 -- tests/e2e_tests/docker-compose-e2e-postgres.yml | 5 ----- 2 files changed, 7 deletions(-) diff --git a/.github/workflows/test-pr-e2e.yml b/.github/workflows/test-pr-e2e.yml index f9ac8f271..fea34da35 100644 --- a/.github/workflows/test-pr-e2e.yml +++ b/.github/workflows/test-pr-e2e.yml @@ -88,8 +88,6 @@ jobs: DOCKER_BUILDKIT=1 docker compose \ --project-directory . \ -f tests/e2e_tests/docker-compose-e2e-${{ matrix.db_type }}.yml up -d - - docker ps - name: Wait for database to be ready run: | diff --git a/tests/e2e_tests/docker-compose-e2e-postgres.yml b/tests/e2e_tests/docker-compose-e2e-postgres.yml index 931750732..e52e83838 100644 --- a/tests/e2e_tests/docker-compose-e2e-postgres.yml +++ b/tests/e2e_tests/docker-compose-e2e-postgres.yml @@ -76,11 +76,6 @@ services: - NEXT_PUBLIC_API_URL=http://localhost:8081 - POSTHOG_KEY=phc_muk9qE3TfZsX3SZ9XxX52kCGJBclrjhkP9JxAQcm1PZ - POSTHOG_HOST=https://ingest.keephq.dev - - NEXT_PUBLIC_SENTRY_DSN=https://0d4d59e3105ffe8afa27dcb95a222009@o4505515398922240.ingest.us.sentry.io/4508258058764288 - - PUSHER_HOST=localhost - - PUSHER_PORT=6001 - - PUSHER_APP_KEY=keepappkey - - NEXT_PUBLIC_KEEP_VERSION=0.2.9 - AUTH_TYPE=DB - API_URL=http://keep-backend-db-auth:8080 - POSTHOG_DISABLED=true From a13d2739adab38d6eaa8d0290c5146f1bb37c9b5 Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Mon, 20 Jan 2025 19:00:31 +0530 Subject: [PATCH 21/37] chore: minor fixes Signed-off-by: 35C4n0r --- .github/workflows/test-pr-e2e.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/test-pr-e2e.yml b/.github/workflows/test-pr-e2e.yml index fea34da35..1c9a44eb1 100644 --- a/.github/workflows/test-pr-e2e.yml +++ b/.github/workflows/test-pr-e2e.yml @@ -139,6 +139,10 @@ jobs: attempt=0 max_attempts=10 + echo attempt + echo "$attempt" + echo "$max_attempts" + curl http://localhost:8081/healthcheck echo "Waiting for Keep backend (DB AUTH) to be ready..." until $(curl --output /dev/null --silent --fail http://localhost:8081/healthcheck); do if [ "$attempt" -ge "$max_attempts" ]; then From 2d23bf39b9d56aed3ff6c006567a0d3392cc9816 Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Mon, 20 Jan 2025 19:24:28 +0530 Subject: [PATCH 22/37] chore: minor fixes Signed-off-by: 35C4n0r --- .github/workflows/test-pr-e2e.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test-pr-e2e.yml b/.github/workflows/test-pr-e2e.yml index 1c9a44eb1..917e953a7 100644 --- a/.github/workflows/test-pr-e2e.yml +++ b/.github/workflows/test-pr-e2e.yml @@ -137,20 +137,19 @@ jobs: done echo "Keep backend is ready!" - attempt=0 - max_attempts=10 - echo attempt - echo "$attempt" - echo "$max_attempts" - curl http://localhost:8081/healthcheck + attempt2=0 + max_attempts2=10 + echo "Hello world: $(attempt2)" + echo "MAX_ATTEMPTS: $(max_attempts2)" + echo $(curl http://localhost:8081/healthcheck) echo "Waiting for Keep backend (DB AUTH) to be ready..." until $(curl --output /dev/null --silent --fail http://localhost:8081/healthcheck); do - if [ "$attempt" -ge "$max_attempts" ]; then + if [ "$attempt2" -ge "$max_attempts2" ]; then echo "Max attempts reached, exiting... Sometimes Keep can't start because of double-headed migrations, use: 'alembic -c keep/alembic.ini history' to investigate, or check artifacts." exit 1 fi echo "Waiting for Keep backend (DB AUTH) to be ready... (Attempt: $((attempt+1)))" - attempt=$((attempt+1)) + attempt2=$((attempt2+1)) sleep 2 done echo "Keep backend (DB AUTH) is ready!" From c8da2c194c09da6cb287142fd6af2a29d4bd9af0 Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Fri, 24 Jan 2025 09:44:28 +0530 Subject: [PATCH 23/37] chore: review comments Signed-off-by: 35C4n0r --- tests/e2e_tests/docker-compose-e2e-mysql.yml | 10 ++-------- tests/e2e_tests/docker-compose-e2e-postgres.yml | 5 ++--- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/tests/e2e_tests/docker-compose-e2e-mysql.yml b/tests/e2e_tests/docker-compose-e2e-mysql.yml index bdefca7c3..cb670f904 100644 --- a/tests/e2e_tests/docker-compose-e2e-mysql.yml +++ b/tests/e2e_tests/docker-compose-e2e-mysql.yml @@ -79,13 +79,7 @@ services: - NEXTAUTH_SECRET=secret - NEXTAUTH_URL=http://localhost:3001 - NEXT_PUBLIC_API_URL=http://localhost:8081 - - POSTHOG_KEY=phc_muk9qE3TfZsX3SZ9XxX52kCGJBclrjhkP9JxAQcm1PZ - - POSTHOG_HOST=https://ingest.keephq.dev - - NEXT_PUBLIC_SENTRY_DSN=https://0d4d59e3105ffe8afa27dcb95a222009@o4505515398922240.ingest.us.sentry.io/4508258058764288 - - PUSHER_HOST=localhost - - PUSHER_PORT=6001 - - PUSHER_APP_KEY=keepappkey - - NEXT_PUBLIC_KEEP_VERSION=0.2.9 + - POSTHOG_DISABLED=true - AUTH_TYPE=DB - API_URL=http://keep-backend-db-auth:8080 - POSTHOG_DISABLED=true @@ -139,7 +133,7 @@ services: - "9090:9090" grafana: - image: grafana/grafana-enterprise:10.4.0 + image: grafana/grafana-enterprise:11.4.0 user: "472" # Grafana's default user ID ports: - "3002:3000" diff --git a/tests/e2e_tests/docker-compose-e2e-postgres.yml b/tests/e2e_tests/docker-compose-e2e-postgres.yml index e52e83838..0c7b926a1 100644 --- a/tests/e2e_tests/docker-compose-e2e-postgres.yml +++ b/tests/e2e_tests/docker-compose-e2e-postgres.yml @@ -74,8 +74,7 @@ services: - NEXTAUTH_SECRET=secret - NEXTAUTH_URL=http://localhost:3001 - NEXT_PUBLIC_API_URL=http://localhost:8081 - - POSTHOG_KEY=phc_muk9qE3TfZsX3SZ9XxX52kCGJBclrjhkP9JxAQcm1PZ - - POSTHOG_HOST=https://ingest.keephq.dev + - POSTHOG_DISABLED=true - AUTH_TYPE=DB - API_URL=http://keep-backend-db-auth:8080 - POSTHOG_DISABLED=true @@ -128,7 +127,7 @@ services: - "9090:9090" grafana: - image: grafana/grafana-enterprise:10.4.0 + image: grafana/grafana-enterprise:11.4.0 user: "472" # Grafana's default user ID ports: - "3002:3000" From 3eee54722ac15444fd9965d9b7ed97eedb277a29 Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Fri, 24 Jan 2025 10:26:40 +0530 Subject: [PATCH 24/37] test: change order Signed-off-by: 35C4n0r --- .github/workflows/test-pr-e2e.yml | 33 ++++++++++++++----------------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/.github/workflows/test-pr-e2e.yml b/.github/workflows/test-pr-e2e.yml index 917e953a7..a04326616 100644 --- a/.github/workflows/test-pr-e2e.yml +++ b/.github/workflows/test-pr-e2e.yml @@ -120,6 +120,21 @@ jobs: fi echo "Database (DB AUTH) is ready!" + attempt=0 + max_attempts=10 + echo "Waiting for Keep backend (DB AUTH) to be ready..." + until $(curl --output /dev/null --silent --fail http://localhost:8081/healthcheck); do + if [ "$attempt" -ge "$max_attempts" ]; then + echo "Max attempts reached, exiting... Sometimes Keep can't start because of double-headed migrations, use: 'alembic -c keep/alembic.ini history' to investigate, or check artifacts." + exit 1 + fi + echo "Waiting for Keep backend (DB AUTH) to be ready... (Attempt: $((attempt+1)))" + attempt=$((attempt+1)) + sleep 2 + done + echo "Keep backend (DB AUTH) is ready!" + # wait to the backend + # wait to keep backend on port 8080 echo "Waiting for Keep backend to be ready..." @@ -137,24 +152,6 @@ jobs: done echo "Keep backend is ready!" - attempt2=0 - max_attempts2=10 - echo "Hello world: $(attempt2)" - echo "MAX_ATTEMPTS: $(max_attempts2)" - echo $(curl http://localhost:8081/healthcheck) - echo "Waiting for Keep backend (DB AUTH) to be ready..." - until $(curl --output /dev/null --silent --fail http://localhost:8081/healthcheck); do - if [ "$attempt2" -ge "$max_attempts2" ]; then - echo "Max attempts reached, exiting... Sometimes Keep can't start because of double-headed migrations, use: 'alembic -c keep/alembic.ini history' to investigate, or check artifacts." - exit 1 - fi - echo "Waiting for Keep backend (DB AUTH) to be ready... (Attempt: $((attempt+1)))" - attempt2=$((attempt2+1)) - sleep 2 - done - echo "Keep backend (DB AUTH) is ready!" - # wait to the backend - echo "Waiting for Keep frontend to be ready..." attempt=0 From bc59f89b399373635056d73f32dc8eb91f733a7f Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Fri, 24 Jan 2025 16:02:42 +0530 Subject: [PATCH 25/37] test: change order Signed-off-by: 35C4n0r --- tests/e2e_tests/docker-compose-e2e-mysql.yml | 2 +- tests/e2e_tests/docker-compose-e2e-postgres.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e_tests/docker-compose-e2e-mysql.yml b/tests/e2e_tests/docker-compose-e2e-mysql.yml index cb670f904..44d795c95 100644 --- a/tests/e2e_tests/docker-compose-e2e-mysql.yml +++ b/tests/e2e_tests/docker-compose-e2e-mysql.yml @@ -133,7 +133,7 @@ services: - "9090:9090" grafana: - image: grafana/grafana-enterprise:11.4.0 + image: grafana/grafana-enterprise:10.4.0 user: "472" # Grafana's default user ID ports: - "3002:3000" diff --git a/tests/e2e_tests/docker-compose-e2e-postgres.yml b/tests/e2e_tests/docker-compose-e2e-postgres.yml index 0c7b926a1..53fa81562 100644 --- a/tests/e2e_tests/docker-compose-e2e-postgres.yml +++ b/tests/e2e_tests/docker-compose-e2e-postgres.yml @@ -127,7 +127,7 @@ services: - "9090:9090" grafana: - image: grafana/grafana-enterprise:11.4.0 + image: grafana/grafana-enterprise:10.4.0 user: "472" # Grafana's default user ID ports: - "3002:3000" From cb1c6c8ed0b4c2031ca838d02c5b0446be0c11ee Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Sat, 25 Jan 2025 21:34:02 +0530 Subject: [PATCH 26/37] feat: grafana latest Signed-off-by: 35C4n0r --- keep/providers/grafana_provider/grafana/grafana.ini | 5 +---- tests/e2e_tests/docker-compose-e2e-mysql.yml | 2 +- tests/e2e_tests/docker-compose-e2e-postgres.yml | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/keep/providers/grafana_provider/grafana/grafana.ini b/keep/providers/grafana_provider/grafana/grafana.ini index 09e6e2e7e..d6e79ef24 100644 --- a/keep/providers/grafana_provider/grafana/grafana.ini +++ b/keep/providers/grafana_provider/grafana/grafana.ini @@ -1,8 +1,5 @@ -[alerting] -enabled = true - [unified_alerting] -enabled = false +enabled = true [database] wal = true diff --git a/tests/e2e_tests/docker-compose-e2e-mysql.yml b/tests/e2e_tests/docker-compose-e2e-mysql.yml index 44d795c95..cb670f904 100644 --- a/tests/e2e_tests/docker-compose-e2e-mysql.yml +++ b/tests/e2e_tests/docker-compose-e2e-mysql.yml @@ -133,7 +133,7 @@ services: - "9090:9090" grafana: - image: grafana/grafana-enterprise:10.4.0 + image: grafana/grafana-enterprise:11.4.0 user: "472" # Grafana's default user ID ports: - "3002:3000" diff --git a/tests/e2e_tests/docker-compose-e2e-postgres.yml b/tests/e2e_tests/docker-compose-e2e-postgres.yml index 53fa81562..0c7b926a1 100644 --- a/tests/e2e_tests/docker-compose-e2e-postgres.yml +++ b/tests/e2e_tests/docker-compose-e2e-postgres.yml @@ -127,7 +127,7 @@ services: - "9090:9090" grafana: - image: grafana/grafana-enterprise:10.4.0 + image: grafana/grafana-enterprise:11.4.0 user: "472" # Grafana's default user ID ports: - "3002:3000" From c11686ccc0173ada25c07b6418a02b8c94deb8a8 Mon Sep 17 00:00:00 2001 From: Jay Kumar Date: Fri, 31 Jan 2025 02:58:58 +0000 Subject: [PATCH 27/37] feat: delete providers test --- tests/e2e_tests/test_end_to_end.py | 42 +++++++++++++++++ tests/e2e_tests/test_grafana_provider.py | 42 ++++------------- tests/e2e_tests/utils.py | 59 ++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 32 deletions(-) diff --git a/tests/e2e_tests/test_end_to_end.py b/tests/e2e_tests/test_end_to_end.py index ea64a72d1..464d1ac02 100644 --- a/tests/e2e_tests/test_end_to_end.py +++ b/tests/e2e_tests/test_end_to_end.py @@ -42,6 +42,8 @@ from playwright.sync_api import expect +from tests.e2e_tests.utils import install_webhook_provider, delete_provider, assert_connected_provider_count, assert_scope_text_count + # Running the tests in GitHub Actions: # - Look at the test-pr-e2e.yml file in the .github/workflows directory. @@ -375,3 +377,43 @@ def test_start_with_keep_db(browser): except Exception: save_failure_artifacts(browser, log_entries) raise + +def test_provider_deletion(browser): + log_entries = [] + setup_console_listener(browser, log_entries) + provider_name = "playwright_test_" + datetime.now().strftime("%Y%m%d%H%M%S") + try: + + # Checking deletion after Creation + browser.goto("https://3000-35c4n0r-keep-j5ok1nvq1vv.ws-us117.gitpod.io/signin") + browser.get_by_role("link", name="Providers").hover() + browser.get_by_role("link", name="Providers").click() + browser.wait_for_timeout(10000) + install_webhook_provider(browser=browser, provider_name=provider_name, webhook_url="https://8080-35c4n0r-keep-j5ok1nvq1vv.ws-us117.gitpod.io", webhook_action="GET") + browser.wait_for_timeout(2000) + assert_connected_provider_count(browser=browser, provider_type="Webhook", provider_name=provider_name, provider_count=1) + delete_provider(browser=browser, provider_type="Webhook", provider_name=provider_name) + assert_connected_provider_count(browser=browser, provider_type="Webhook", provider_name=provider_name, provider_count=0) + + # Checking deletion after Creation + Updation + install_webhook_provider(browser=browser, provider_name=provider_name, webhook_url="https://8080-35c4n0r-keep-j5ok1nvq1vv.ws-us117.gitpod.io", webhook_action="GET") + browser.wait_for_timeout(2000) + assert_connected_provider_count(browser=browser, provider_type="Webhook", provider_name=provider_name, provider_count=1) + # Updating provider + browser.locator( + f"button:has-text('Webhook'):has-text('Connected'):has-text('{provider_name}')" + ).click() + browser.get_by_placeholder("Enter url").clear() + browser.get_by_placeholder("Enter url").fill("https://this_is_UwU") + + browser.get_by_role("button", name="Update", exact=True).click() + # Refreshing the scope + browser.get_by_role("button", name="Refresh", exact=True).click() + assert_scope_text_count(browser=browser, contains_text="HTTPSConnectionPool", count=1) + browser.mouse.click(10, 10) + delete_provider(browser=browser, provider_type="Webhook", provider_name=provider_name) + assert_connected_provider_count(browser=browser, provider_type="Webhook", provider_name=provider_name, provider_count=0) + + except Exception: + save_failure_artifacts(browser, log_entries) + raise diff --git a/tests/e2e_tests/test_grafana_provider.py b/tests/e2e_tests/test_grafana_provider.py index 7c0da2a5d..4b0788112 100644 --- a/tests/e2e_tests/test_grafana_provider.py +++ b/tests/e2e_tests/test_grafana_provider.py @@ -7,7 +7,7 @@ import requests from playwright.sync_api import expect -from tests.e2e_tests.utils import trigger_alert +from tests.e2e_tests.utils import trigger_alert, assert_scope_text_count, open_connected_provider, delete_provider, assert_connected_provider_count os.environ["PLAYWRIGHT_HEADLESS"] = "false" @@ -54,7 +54,7 @@ def open_grafana_card(browser): browser.get_by_placeholder("Filter providers...").press("Enter") browser.get_by_text("Available Providers").hover() grafana_tile = browser.locator( - "button:has-text('Grafana'):has-text('alert'):not(:has-text('Linked'))" + "button:has-text('Grafana'):not(:has-text('Connected')):not(:has-text('Linked'))" ) grafana_tile.first.hover() grafana_tile.first.click() @@ -78,9 +78,7 @@ def test_grafana_provider(browser): browser.get_by_placeholder("Enter token").fill("random_token_UwU") browser.get_by_placeholder("Enter host").fill(GRAFANA_HOST) browser.get_by_role("button", name="Connect", exact=True).click() - expect( - browser.locator("span.tremor-Badge-text:has-text('Missing Scope')") - ).to_have_count(3) + assert_scope_text_count(browser=browser, contains_text="Missing Scope", count=3) browser.get_by_role("button", name="Cancel", exact=True).click() # Then trying to install with read scope, webhook installation should fail @@ -93,15 +91,9 @@ def test_grafana_provider(browser): browser.get_by_role("button", name="Connect", exact=True).click() browser.wait_for_timeout(5000) # browser.reload() - browser.locator( - f"button:has-text('Grafana'):has-text('Connected'):has-text('{provider_name_readonly}')" - ).click() - expect( - browser.locator("span.tremor-Badge-text:has-text('Missing Scope')") - ).to_have_count(2) - expect( - browser.locator("span.tremor-Badge-text:has-text('Valid')") - ).to_have_count(1) + open_connected_provider(browser=browser, provider_type="Grafana", provider_name=provider_name_readonly) + assert_scope_text_count(browser=browser, contains_text="Missing Scope", count=2) + assert_scope_text_count(browser=browser, contains_text="Valid", count=1) browser.get_by_role("button", name="Cancel", exact=True).click() # Then trying to install with admin scope, webhook installation should pass @@ -112,16 +104,11 @@ def test_grafana_provider(browser): ) browser.get_by_placeholder("Enter host").fill(GRAFANA_HOST) browser.get_by_role("button", name="Connect", exact=True).click() - - browser.locator( - f"button:has-text('Grafana'):has-text('Connected'):has-text('{provider_name_success}')" - ).click() + open_connected_provider(browser=browser, provider_type="Grafana", provider_name=provider_name_success) toast_div = browser.locator("div.Toastify") browser.get_by_role("button", name="Install/Update Webhook", exact=True).click() expect(toast_div).to_contain_text("grafana webhook installed", timeout=10000) - expect( - browser.locator("span.tremor-Badge-text:has-text('Valid')") - ).to_have_count(3) + assert_scope_text_count(browser=browser, contains_text="Valid", count=3) browser.get_by_role("button", name="Cancel", exact=True).click() trigger_alert("grafana") @@ -160,18 +147,9 @@ def test_grafana_provider(browser): for provider_to_delete in providers_to_delete: # Perform actions on each matching element - browser.locator( - f"button:has-text('Grafana'):has-text('Connected'):has-text('{provider_to_delete}')" - ).click() - browser.once("dialog", lambda dialog: dialog.accept()) - browser.get_by_role("button", name="Delete").click() - + delete_provider(browser=browser, provider_type="Grafana", provider_name=provider_to_delete) # Assert provider was deleted - expect( - browser.locator( - f"button:has-text('Grafana'):has-text('Connected'):has-text('{provider_to_delete}')" - ) - ).to_have_count(0) + assert_connected_provider_count(browser=browser, provider_type="Grafana", provider_name=provider_to_delete, provider_count=0) except Exception: # Current file + test name for unique html and png dump. diff --git a/tests/e2e_tests/utils.py b/tests/e2e_tests/utils.py index 5deb6eba8..60ae34205 100644 --- a/tests/e2e_tests/utils.py +++ b/tests/e2e_tests/utils.py @@ -1,5 +1,6 @@ from keep.providers.providers_factory import ProvidersFactory import requests +from playwright.sync_api import expect def trigger_alert(provider_name): @@ -13,3 +14,61 @@ def trigger_alert(provider_name): }, json=provider.simulate_alert(), ) + +def open_connected_provider(browser, provider_type, provider_name): + browser.locator( + f"button:has-text('{provider_type}'):has-text('Connected'):has-text('{provider_name}')" + ).click() + +def install_webhook_provider(browser, provider_name, webhook_url, webhook_action): + """ + Installs webhook provider, given that you are on the providers page. + """ + browser.get_by_placeholder("Filter providers...").click() + browser.get_by_placeholder("Filter providers...").clear() + browser.get_by_placeholder("Filter providers...").fill("Webhook") + browser.get_by_placeholder("Filter providers...").press("Enter") + browser.get_by_text("Available Providers").hover() + webhook_title = browser.locator( + "button:has-text('Webhook'):not(:has-text('Connected')):not(:has-text('Linked'))" + ) + webhook_title.first.hover() + webhook_title.first.click() + + browser.get_by_placeholder("Enter provider name").fill(provider_name) + browser.get_by_placeholder("Enter url").fill(webhook_url) + browser.mouse.wheel(1000, 10000) + browser.get_by_role("button", name="POST", exact=True).click() + browser.locator("li:has-text('GET')").click() + + browser.get_by_role("button", name="Connect", exact=True).click() + browser.mouse.wheel(0, 0) # Scrolling back to initial position + + +def delete_provider(browser, provider_type, provider_name): + """ + Deletes a Connected provider + """ + open_connected_provider(browser=browser, provider_type=provider_type, provider_name=provider_name) + browser.once("dialog", lambda dialog: dialog.accept()) + browser.get_by_role("button", name="Delete").click() + + +def assert_connected_provider_count(browser, provider_type, provider_name, provider_count): + """ + Asserts the number of **Connected** providers + """ + expect( + browser.locator( + f"button:has-text('{provider_type}'):has-text('Connected'):has-text('{provider_name}')" + ) + ).to_have_count(provider_count) + +def assert_scope_text_count(browser, contains_text, count): + """ + Validates the count of scopes having text "contains text". + To check for valid scopes, pass contains_text="Valid" + """ + expect( + browser.locator(f"span.tremor-Badge-text:has-text('{contains_text}')") + ).to_have_count(count) \ No newline at end of file From 05a801c9a4a74aa25406f41e791b7618b4ead8f1 Mon Sep 17 00:00:00 2001 From: Jay Kumar Date: Fri, 31 Jan 2025 03:22:44 +0000 Subject: [PATCH 28/37] fix: remove gitpod urls --- tests/e2e_tests/test_end_to_end.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/e2e_tests/test_end_to_end.py b/tests/e2e_tests/test_end_to_end.py index 464d1ac02..4c3b9ed6b 100644 --- a/tests/e2e_tests/test_end_to_end.py +++ b/tests/e2e_tests/test_end_to_end.py @@ -385,18 +385,18 @@ def test_provider_deletion(browser): try: # Checking deletion after Creation - browser.goto("https://3000-35c4n0r-keep-j5ok1nvq1vv.ws-us117.gitpod.io/signin") + browser.goto("http://localhost:3000/signin") browser.get_by_role("link", name="Providers").hover() browser.get_by_role("link", name="Providers").click() browser.wait_for_timeout(10000) - install_webhook_provider(browser=browser, provider_name=provider_name, webhook_url="https://8080-35c4n0r-keep-j5ok1nvq1vv.ws-us117.gitpod.io", webhook_action="GET") + install_webhook_provider(browser=browser, provider_name=provider_name, webhook_url="http://keep-backend:8080", webhook_action="GET") browser.wait_for_timeout(2000) assert_connected_provider_count(browser=browser, provider_type="Webhook", provider_name=provider_name, provider_count=1) delete_provider(browser=browser, provider_type="Webhook", provider_name=provider_name) assert_connected_provider_count(browser=browser, provider_type="Webhook", provider_name=provider_name, provider_count=0) # Checking deletion after Creation + Updation - install_webhook_provider(browser=browser, provider_name=provider_name, webhook_url="https://8080-35c4n0r-keep-j5ok1nvq1vv.ws-us117.gitpod.io", webhook_action="GET") + install_webhook_provider(browser=browser, provider_name=provider_name, webhook_url="http://keep-backend:8080", webhook_action="GET") browser.wait_for_timeout(2000) assert_connected_provider_count(browser=browser, provider_type="Webhook", provider_name=provider_name, provider_count=1) # Updating provider From b5d2d32c33d2b12a7c87db1a3c5bd6d4b273a562 Mon Sep 17 00:00:00 2001 From: Jay Kumar <70096901+35C4n0r@users.noreply.github.com> Date: Fri, 31 Jan 2025 10:25:27 +0530 Subject: [PATCH 29/37] fix: add timeout --- tests/e2e_tests/test_end_to_end.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/e2e_tests/test_end_to_end.py b/tests/e2e_tests/test_end_to_end.py index 4c3b9ed6b..78a802275 100644 --- a/tests/e2e_tests/test_end_to_end.py +++ b/tests/e2e_tests/test_end_to_end.py @@ -409,6 +409,7 @@ def test_provider_deletion(browser): browser.get_by_role("button", name="Update", exact=True).click() # Refreshing the scope browser.get_by_role("button", name="Refresh", exact=True).click() + browser.wait_for_timeout(5000) assert_scope_text_count(browser=browser, contains_text="HTTPSConnectionPool", count=1) browser.mouse.click(10, 10) delete_provider(browser=browser, provider_type="Webhook", provider_name=provider_name) From 5347fbb26ec88e4eed3fd3ae6586899c5b86a644 Mon Sep 17 00:00:00 2001 From: Jay Kumar <70096901+35C4n0r@users.noreply.github.com> Date: Fri, 31 Jan 2025 10:44:30 +0530 Subject: [PATCH 30/37] Update test_end_to_end.py --- tests/e2e_tests/test_end_to_end.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_end_to_end.py b/tests/e2e_tests/test_end_to_end.py index 78a802275..0fa5cf16d 100644 --- a/tests/e2e_tests/test_end_to_end.py +++ b/tests/e2e_tests/test_end_to_end.py @@ -409,7 +409,7 @@ def test_provider_deletion(browser): browser.get_by_role("button", name="Update", exact=True).click() # Refreshing the scope browser.get_by_role("button", name="Refresh", exact=True).click() - browser.wait_for_timeout(5000) + browser.wait_for_timeout(10000) assert_scope_text_count(browser=browser, contains_text="HTTPSConnectionPool", count=1) browser.mouse.click(10, 10) delete_provider(browser=browser, provider_type="Webhook", provider_name=provider_name) From 163de09eb9fef2d75cf35e3883e4b51324a43be3 Mon Sep 17 00:00:00 2001 From: Jay Kumar Date: Fri, 31 Jan 2025 12:20:44 +0000 Subject: [PATCH 31/37] fix: failed tests --- tests/e2e_tests/test_end_to_end.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_end_to_end.py b/tests/e2e_tests/test_end_to_end.py index 0fa5cf16d..c1620721b 100644 --- a/tests/e2e_tests/test_end_to_end.py +++ b/tests/e2e_tests/test_end_to_end.py @@ -407,9 +407,10 @@ def test_provider_deletion(browser): browser.get_by_placeholder("Enter url").fill("https://this_is_UwU") browser.get_by_role("button", name="Update", exact=True).click() + browser.wait_for_timeout(3000) # Refreshing the scope browser.get_by_role("button", name="Refresh", exact=True).click() - browser.wait_for_timeout(10000) + browser.wait_for_timeout(3000) assert_scope_text_count(browser=browser, contains_text="HTTPSConnectionPool", count=1) browser.mouse.click(10, 10) delete_provider(browser=browser, provider_type="Webhook", provider_name=provider_name) From 79ca01eb7add0f74c553bf3178c9cc3610c7f32c Mon Sep 17 00:00:00 2001 From: Jay Kumar Date: Fri, 31 Jan 2025 12:40:55 +0000 Subject: [PATCH 32/37] fix: revert original and new ini --- keep/providers/grafana_provider/grafana/grafana.ini | 5 ++++- tests/e2e_tests/docker-compose-e2e-postgres.yml | 8 +++----- tests/e2e_tests/grafana.ini | 9 +++++++++ 3 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 tests/e2e_tests/grafana.ini diff --git a/keep/providers/grafana_provider/grafana/grafana.ini b/keep/providers/grafana_provider/grafana/grafana.ini index d6e79ef24..09e6e2e7e 100644 --- a/keep/providers/grafana_provider/grafana/grafana.ini +++ b/keep/providers/grafana_provider/grafana/grafana.ini @@ -1,6 +1,9 @@ -[unified_alerting] +[alerting] enabled = true +[unified_alerting] +enabled = false + [database] wal = true url = sqlite3:///var/lib/grafana/grafana.db?_busy_timeout=500 diff --git a/tests/e2e_tests/docker-compose-e2e-postgres.yml b/tests/e2e_tests/docker-compose-e2e-postgres.yml index 0c7b926a1..04feade27 100644 --- a/tests/e2e_tests/docker-compose-e2e-postgres.yml +++ b/tests/e2e_tests/docker-compose-e2e-postgres.yml @@ -47,7 +47,6 @@ services: depends_on: - keep-database - ## Keep Services with DB # Database Service (5433) keep-database-db-auth: @@ -72,8 +71,8 @@ services: - "3001:3000" environment: - NEXTAUTH_SECRET=secret - - NEXTAUTH_URL=http://localhost:3001 - - NEXT_PUBLIC_API_URL=http://localhost:8081 + - NEXTAUTH_URL=https://3001-35c4n0r-keep-j5ok1nvq1vv.ws-us117.gitpod.io + - NEXT_PUBLIC_API_URL=https://8081-35c4n0r-keep-j5ok1nvq1vv.ws-us117.gitpod.io - POSTHOG_DISABLED=true - AUTH_TYPE=DB - API_URL=http://keep-backend-db-auth:8080 @@ -111,7 +110,6 @@ services: depends_on: - keep-database-db-auth - # Other Services (Common) keep-websocket-server: extends: @@ -133,7 +131,7 @@ services: - "3002:3000" volumes: - ./keep/providers/grafana_provider/grafana/provisioning:/etc/grafana/provisioning:ro - - ./keep/providers/grafana_provider/grafana/grafana.ini:/etc/grafana/grafana.ini:ro + - ./tests/e2e_tests/grafana.ini:/etc/grafana/grafana.ini:ro - grafana-storage:/var/lib/grafana environment: - GF_SECURITY_ADMIN_PASSWORD=admin diff --git a/tests/e2e_tests/grafana.ini b/tests/e2e_tests/grafana.ini new file mode 100644 index 000000000..d6e79ef24 --- /dev/null +++ b/tests/e2e_tests/grafana.ini @@ -0,0 +1,9 @@ +[unified_alerting] +enabled = true + +[database] +wal = true +url = sqlite3:///var/lib/grafana/grafana.db?_busy_timeout=500 + +[service_accounts] +enabled = true From 2acaf987b8ff9e916ddac38a7fda9156d843d210 Mon Sep 17 00:00:00 2001 From: Jay Kumar Date: Fri, 31 Jan 2025 13:31:34 +0000 Subject: [PATCH 33/37] fix: update mysql --- tests/e2e_tests/docker-compose-e2e-mysql.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/docker-compose-e2e-mysql.yml b/tests/e2e_tests/docker-compose-e2e-mysql.yml index cb670f904..ef4b459e3 100644 --- a/tests/e2e_tests/docker-compose-e2e-mysql.yml +++ b/tests/e2e_tests/docker-compose-e2e-mysql.yml @@ -139,7 +139,7 @@ services: - "3002:3000" volumes: - ./keep/providers/grafana_provider/grafana/provisioning:/etc/grafana/provisioning:ro - - ./keep/providers/grafana_provider/grafana/grafana.ini:/etc/grafana/grafana.ini:ro + - ./tests/e2e_tests/grafana.ini:/etc/grafana/grafana.ini:ro - grafana-storage:/var/lib/grafana environment: - GF_SECURITY_ADMIN_PASSWORD=admin From 61625f9216c3e3f17c5de586717ffce69c4d7f9a Mon Sep 17 00:00:00 2001 From: Jay Kumar Date: Fri, 31 Jan 2025 13:47:36 +0000 Subject: [PATCH 34/37] re: run --- tests/e2e_tests/docker-compose-e2e-mysql.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/docker-compose-e2e-mysql.yml b/tests/e2e_tests/docker-compose-e2e-mysql.yml index ef4b459e3..8b7580ae1 100644 --- a/tests/e2e_tests/docker-compose-e2e-mysql.yml +++ b/tests/e2e_tests/docker-compose-e2e-mysql.yml @@ -52,7 +52,7 @@ services: ## Keep Services with DB - # Database Service (5433) + # Database Service (5433) keep-database-db-auth: image: mysql:latest environment: From 681b6b6ef311d8c6172aef7079d1cac863e417fd Mon Sep 17 00:00:00 2001 From: Jay Kumar Date: Fri, 31 Jan 2025 14:06:59 +0000 Subject: [PATCH 35/37] chore: try fix --- tests/e2e_tests/test_end_to_end.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_end_to_end.py b/tests/e2e_tests/test_end_to_end.py index c1620721b..8906dee13 100644 --- a/tests/e2e_tests/test_end_to_end.py +++ b/tests/e2e_tests/test_end_to_end.py @@ -372,7 +372,7 @@ def test_start_with_keep_db(browser): browser.get_by_placeholder("Enter your password").fill("keep") browser.wait_for_timeout(3000) browser.get_by_role("button", name="Sign in").click() - browser.wait_for_timeout(5000) + browser.wait_for_timeout(10000) expect(browser).to_have_url("http://localhost:3001/incidents") except Exception: save_failure_artifacts(browser, log_entries) From afb4c0128d5b05e0bd26bbb00fa4f14119743a6d Mon Sep 17 00:00:00 2001 From: Jay Kumar Date: Fri, 31 Jan 2025 14:11:47 +0000 Subject: [PATCH 36/37] fix: remove links --- tests/e2e_tests/docker-compose-e2e-postgres.yml | 4 ++-- tests/e2e_tests/test_end_to_end.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/e2e_tests/docker-compose-e2e-postgres.yml b/tests/e2e_tests/docker-compose-e2e-postgres.yml index 04feade27..e09cf60da 100644 --- a/tests/e2e_tests/docker-compose-e2e-postgres.yml +++ b/tests/e2e_tests/docker-compose-e2e-postgres.yml @@ -71,8 +71,8 @@ services: - "3001:3000" environment: - NEXTAUTH_SECRET=secret - - NEXTAUTH_URL=https://3001-35c4n0r-keep-j5ok1nvq1vv.ws-us117.gitpod.io - - NEXT_PUBLIC_API_URL=https://8081-35c4n0r-keep-j5ok1nvq1vv.ws-us117.gitpod.io + - NEXTAUTH_URL=http://localhost:3001 + - NEXT_PUBLIC_API_URL=http://localhost:8080 - POSTHOG_DISABLED=true - AUTH_TYPE=DB - API_URL=http://keep-backend-db-auth:8080 diff --git a/tests/e2e_tests/test_end_to_end.py b/tests/e2e_tests/test_end_to_end.py index 8906dee13..c1620721b 100644 --- a/tests/e2e_tests/test_end_to_end.py +++ b/tests/e2e_tests/test_end_to_end.py @@ -372,7 +372,7 @@ def test_start_with_keep_db(browser): browser.get_by_placeholder("Enter your password").fill("keep") browser.wait_for_timeout(3000) browser.get_by_role("button", name="Sign in").click() - browser.wait_for_timeout(10000) + browser.wait_for_timeout(5000) expect(browser).to_have_url("http://localhost:3001/incidents") except Exception: save_failure_artifacts(browser, log_entries) From 0f86c73690e412a61da8c7f589ed2e2b98956120 Mon Sep 17 00:00:00 2001 From: 35C4n0r Date: Fri, 31 Jan 2025 20:24:18 +0530 Subject: [PATCH 37/37] chore: increase waiting time Signed-off-by: 35C4n0r --- .github/workflows/test-pr-e2e.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-pr-e2e.yml b/.github/workflows/test-pr-e2e.yml index a04326616..a99f16cad 100644 --- a/.github/workflows/test-pr-e2e.yml +++ b/.github/workflows/test-pr-e2e.yml @@ -110,7 +110,7 @@ jobs: if [ "${{ matrix.db_type }}" == "mysql" ]; then until docker exec $(docker ps -qf "name=keep-database-db-auth-1") mysqladmin ping -h "localhost" --silent; do echo "Waiting for MySQL (DB AUTH) to be ready..." - sleep 2 + sleep 3 done elif [ "${{ matrix.db_type }}" == "postgres" ]; then until docker exec $(docker ps -qf "name=keep-database-db-auth-1") pg_isready -h localhost -U keepuser; do @@ -130,7 +130,7 @@ jobs: fi echo "Waiting for Keep backend (DB AUTH) to be ready... (Attempt: $((attempt+1)))" attempt=$((attempt+1)) - sleep 2 + sleep 4 done echo "Keep backend (DB AUTH) is ready!" # wait to the backend @@ -148,7 +148,7 @@ jobs: fi echo "Waiting for Keep backend to be ready... (Attempt: $((attempt+1)))" attempt=$((attempt+1)) - sleep 2 + sleep 4 done echo "Keep backend is ready!"