From 0e54c62622d7305a43c1015cc73b5c55bf4f6b3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Wa=C5=9B?= Date: Tue, 6 May 2025 13:47:40 +0200 Subject: [PATCH 1/4] Test with oldest supported Grafana and bump that version --- .github/workflows/ci.yml | 8 ++++++-- src/plugin.json | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ab44ba8..4290f73 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,10 @@ on: jobs: build: runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + grafana: ['9.5.0', '11.6.1'] steps: - uses: actions/checkout@v4 @@ -55,7 +59,7 @@ jobs: --env POSTGRES_PASSWORD=keycloak \ --env POSTGRES_DB=keycloak \ postgres:17.4 - + echo "Starting Keycloak..." docker run --rm --detach \ --name keycloak \ @@ -96,7 +100,7 @@ jobs: --publish 3000:3000 \ --volume "$(pwd):/var/lib/grafana/plugins/trino" \ --env "GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS=trino-datasource" \ - grafana/grafana:11.4.0 + grafana/grafana:${{ matrix.grafana }} - name: End to end test run: | diff --git a/src/plugin.json b/src/plugin.json index d6f45ec..a551318 100644 --- a/src/plugin.json +++ b/src/plugin.json @@ -51,7 +51,7 @@ "updated": "%TODAY%" }, "dependencies": { - "grafanaDependency": ">=8.3.0", + "grafanaDependency": ">=9.5.0", "plugins": [] } } From 645ea8c1cf02ca19d9f896e263acd7bae5747e35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Wa=C5=9B?= Date: Tue, 6 May 2025 13:49:00 +0200 Subject: [PATCH 2/4] Don't use any DB in Keycloack in CI tests --- .github/workflows/ci.yml | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4290f73..62cbecd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,19 +47,10 @@ jobs: version: latest args: buildAll - - name: Setup services (Trino, Grafana, PostgreSQL, Keycloak) + - name: Setup services (Trino, Grafana, Keycloak) run: | docker network create trino - echo "Starting PostgreSQL..." - docker run --rm --detach \ - --name postgres \ - --net trino \ - --env POSTGRES_USER=keycloak \ - --env POSTGRES_PASSWORD=keycloak \ - --env POSTGRES_DB=keycloak \ - postgres:17.4 - echo "Starting Keycloak..." docker run --rm --detach \ --name keycloak \ @@ -67,11 +58,6 @@ jobs: --publish 18080:8080 \ --env KC_BOOTSTRAP_ADMIN_USERNAME=admin \ --env KC_BOOTSTRAP_ADMIN_PASSWORD=admin \ - --env KC_DB=postgres \ - --env KC_DB_URL_HOST=postgres \ - --env KC_DB_URL_DATABASE=keycloak \ - --env KC_DB_USERNAME=keycloak \ - --env KC_DB_PASSWORD=keycloak \ --volume "$(pwd)/test-data/test-keycloak-realm.json:/opt/keycloak/data/import/realm.json" \ quay.io/keycloak/keycloak:26.1.4 \ start-dev --import-realm From bde0f1cd39a2ecf4328ad4aa7da32efd134378f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Wa=C5=9B?= Date: Tue, 6 May 2025 14:11:59 +0200 Subject: [PATCH 3/4] Upload test report artifacts and dump container logs --- .github/workflows/ci.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 62cbecd..4f1f753 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -93,3 +93,25 @@ jobs: npx tsc -p tsconfig.json --noEmit npx playwright install npx playwright test + + - uses: actions/upload-artifact@v4 + if: ${{ !cancelled() }} + with: + name: playwright-report + path: playwright-report/ + retention-days: 5 + + - name: Dump logs + if: always() + run: | + echo "::group::Trino logs" + docker logs trino + echo "::endgroup::" + + echo "::group::Keycloak logs" + docker logs keycloak + echo "::endgroup::" + + echo "::group::Grafana logs" + docker logs grafana + echo "::endgroup::" From 2e52b6fb3877d4d4e4c6c0f18dd4ff1d65e17598 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Wa=C5=9B?= Date: Tue, 6 May 2025 15:27:05 +0200 Subject: [PATCH 4/4] Make e2e test locators more generic --- .github/workflows/ci.yml | 2 +- src/e2e.test.ts | 40 +++++++++++++++++++--------------------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4f1f753..752057e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -97,7 +97,7 @@ jobs: - uses: actions/upload-artifact@v4 if: ${{ !cancelled() }} with: - name: playwright-report + name: playwright-report-${{ matrix.grafana }} path: playwright-report/ retention-days: 5 diff --git a/src/e2e.test.ts b/src/e2e.test.ts index 14caeb6..ee7f5df 100644 --- a/src/e2e.test.ts +++ b/src/e2e.test.ts @@ -1,51 +1,49 @@ import { test, expect, Page } from '@playwright/test'; const GRAFANA_CLIENT = 'grafana-client'; -const EXPORT_DATA = 'Explore data'; +const EXPLORE_DATA = 'Explore'; async function login(page: Page) { await page.goto('http://localhost:3000/login'); - await page.getByTestId('data-testid Username input field').fill('admin'); - await page.getByTestId('data-testid Password input field').fill('admin'); - await page.getByTestId('data-testid Login button').click(); - await page.getByTestId('data-testid Skip change password button').click(); + await page.getByLabel('Username input field').fill('admin'); + await page.getByLabel('Password input field').fill('admin'); + await page.getByLabel('Login button').click(); + await page.getByLabel('Skip change password button').click(); } async function goToTrinoSettings(page: Page) { - await page.getByTestId('data-testid Toggle menu').click(); + await page.getByLabel('Toggle menu').click(); await page.getByRole('link', {name: 'Connections'}).click(); await page.getByRole('link', {name: 'Trino'}).click(); - await page.locator('.css-1yhi3xa').click(); - await page.getByRole('button', {name: 'Add new data source'}).click(); + await page.getByText('Create a Trino data source').click(); } async function setupDataSourceWithAccessToken(page: Page) { - await page.getByTestId('data-testid Datasource HTTP settings url').fill('http://trino:8080'); + await page.getByLabel('Datasource HTTP settings url').fill('http://trino:8080'); await page.locator('div').filter({hasText: /^Impersonate logged in userAccess token$/}).getByLabel('Toggle switch').click(); await page.locator('div').filter({hasText: /^Access token$/}).locator('input[type="password"]').fill('aaa'); - await page.getByTestId('data-testid Data source settings page Save and Test button').click(); + await page.getByLabel('Data source settings page Save and Test button').click(); } async function setupDataSourceWithClientCredentials(page: Page, clientId: string) { - await page.getByTestId('data-testid Datasource HTTP settings url').fill('http://trino:8080'); + await page.getByLabel('Datasource HTTP settings url').fill('http://trino:8080'); await page.locator('div').filter({hasText: /^Token URL$/}).locator('input').fill('http://keycloak:8080/realms/trino-realm/protocol/openid-connect/token'); await page.locator('div').filter({hasText: /^Client id$/}).locator('input').fill(clientId); await page.locator('div').filter({hasText: /^Client secret$/}).locator('input[type="password"]').fill('grafana-secret'); await page.locator('div').filter({hasText: /^Impersonation user$/}).locator('input').fill('service-account-grafana-client'); - await page.getByTestId('data-testid Data source settings page Save and Test button').click(); + await page.getByLabel('Data source settings page Save and Test button').click(); } async function runQueryAndCheckResults(page: Page) { - await page.getByLabel(EXPORT_DATA).click(); + await page.getByText(EXPLORE_DATA).click(); await page.getByTestId('data-testid TimePicker Open Button').click(); - await page.getByTestId('data-testid Time Range from field').fill('1995-01-01'); - await page.getByTestId('data-testid Time Range to field').fill('1995-12-31'); + await page.getByLabel('Time Range from field').fill('1995-01-01'); + await page.getByLabel('Time Range to field').fill('1995-12-31'); await page.getByTestId('data-testid TimePicker submit button').click(); - await page.locator('div').filter({hasText: /^Format asChoose$/}).locator('svg').click(); - await page.getByRole('option', {name: 'Table'}).click(); - await page.getByTestId('data-testid Code editor container').click(); + await page.getByLabel('Format as').click(); + await page.getByText('Table', { exact: true }).click(); await page.getByTestId('data-testid RefreshPicker run button').click(); - await expect(page.getByTestId('data-testid table body')).toContainText(/.*1995-01-19 0.:00:005703857F.*/); + await expect(page.getByTestId('data-testid table body')).toContainText(/.*1995-01-19 0.:00:00.*/); } test('test with access token', async ({ page }) => { @@ -66,7 +64,7 @@ test('test client credentials flow with wrong credentials', async ({ page }) => await login(page); await goToTrinoSettings(page); await setupDataSourceWithClientCredentials(page, "some-wrong-client"); - await expect(page.getByLabel(EXPORT_DATA)).toHaveCount(0); + await expect(page.getByText(EXPLORE_DATA)).toHaveCount(0); }); test('test client credentials flow with configured access token', async ({ page }) => { @@ -74,5 +72,5 @@ test('test client credentials flow with configured access token', async ({ page await goToTrinoSettings(page); await page.locator('div').filter({hasText: /^Access token$/}).locator('input[type="password"]').fill('aaa'); await setupDataSourceWithClientCredentials(page, GRAFANA_CLIENT); - await expect(page.getByLabel(EXPORT_DATA)).toHaveCount(0); + await expect(page.getByText(EXPLORE_DATA)).toHaveCount(0); });