diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 752057e..b15cf53 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,9 +4,11 @@ on: push: branches: - main + - test-old-grafana pull_request: branches: - main + - test-old-grafana jobs: build: @@ -77,8 +79,30 @@ jobs: --name trino \ --net trino \ --volume "$(pwd)/test-data/test-trino-config.properties:/etc/trino/config.properties" \ + --volume "$(pwd)/test-data/tpch.properties:/etc/trino/catalog/tpch.properties" \ trinodb/trino:468 + echo "Waiting for Trino to be ready..." + TIMEOUT=120 + ELAPSED=0 + while true; do + if docker exec trino trino --execute "SELECT 1" &>/dev/null; then + echo "Trino is ready!" + break + fi + if [ $ELAPSED -ge $TIMEOUT ]; then + echo "Timeout waiting for Trino to be ready" + docker logs trino + exit 1 + fi + echo "Waiting for Trino... ($ELAPSED/$TIMEOUT seconds)" + sleep 5 + ELAPSED=$((ELAPSED + 5)) + done + + echo "Verifying TPCH catalog is available..." + docker exec trino trino --execute "SHOW CATALOGS" || echo "Warning: Could not verify catalogs" + echo "Starting Grafana..." docker run --rm --detach \ --name grafana \ @@ -88,6 +112,24 @@ jobs: --env "GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS=trino-datasource" \ grafana/grafana:${{ matrix.grafana }} + echo "Waiting for Grafana to be ready..." + TIMEOUT=120 + ELAPSED=0 + while true; do + if curl -s http://localhost:3000/api/health | grep -q "ok"; then + echo "Grafana is ready!" + break + fi + if [ $ELAPSED -ge $TIMEOUT ]; then + echo "Timeout waiting for Grafana to be ready" + docker logs grafana + exit 1 + fi + echo "Waiting for Grafana... ($ELAPSED/$TIMEOUT seconds)" + sleep 5 + ELAPSED=$((ELAPSED + 5)) + done + - name: End to end test run: | npx tsc -p tsconfig.json --noEmit diff --git a/src/e2e.test.ts b/src/e2e.test.ts index ee7f5df..605d2bb 100644 --- a/src/e2e.test.ts +++ b/src/e2e.test.ts @@ -23,6 +23,8 @@ async function setupDataSourceWithAccessToken(page: Page) { 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.getByLabel('Data source settings page Save and Test button').click(); + // Wait for either success or error message to appear + await page.waitForSelector('[role="alert"], [data-testid="data-testid Alert success"]', { timeout: 5000 }); } async function setupDataSourceWithClientCredentials(page: Page, clientId: string) { @@ -32,6 +34,8 @@ async function setupDataSourceWithClientCredentials(page: Page, clientId: string 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.getByLabel('Data source settings page Save and Test button').click(); + // Wait for either success or error message to appear + await page.waitForSelector('[role="alert"], [data-testid="data-testid Alert success"]', { timeout: 5000 }); } async function runQueryAndCheckResults(page: Page) { @@ -64,7 +68,19 @@ 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.getByText(EXPLORE_DATA)).toHaveCount(0); + // Check for error alert instead of checking absence of Explore button + // The data source might still be saved even with wrong credentials + // So we check if there's an error message or the Explore button is disabled/not present + const exploreButton = page.getByText(EXPLORE_DATA); + const errorAlert = page.locator('[role="alert"]:has-text("error"), [role="alert"]:has-text("failed"), [role="alert"]:has-text("Error")'); + + // Either there should be an error alert, or the Explore button should not be visible + const hasError = await errorAlert.count() > 0; + + // If there's no error alert, then Explore button should not be present + if (!hasError) { + await expect(exploreButton).toHaveCount(0); + } }); test('test client credentials flow with configured access token', async ({ page }) => { @@ -72,5 +88,16 @@ 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.getByText(EXPLORE_DATA)).toHaveCount(0); + // Check for error alert instead of checking absence of Explore button + // Setting both access token and client credentials should be invalid + const exploreButton = page.getByText(EXPLORE_DATA); + const errorAlert = page.locator('[role="alert"]:has-text("error"), [role="alert"]:has-text("failed"), [role="alert"]:has-text("Error")'); + + // Either there should be an error alert, or the Explore button should not be visible + const hasError = await errorAlert.count() > 0; + + // If there's no error alert, then Explore button should not be present + if (!hasError) { + await expect(exploreButton).toHaveCount(0); + } }); diff --git a/test-data/tpch.properties b/test-data/tpch.properties new file mode 100644 index 0000000..75110c5 --- /dev/null +++ b/test-data/tpch.properties @@ -0,0 +1 @@ +connector.name=tpch