Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
5879911
fix: fix Web Console hanging or signing out when SSO tokens expire
glasstiger Oct 19, 2026
58add5e
update submodule
glasstiger Oct 19, 2026
05335a0
fix: keep uploads, the schema tree and notebook results intact when t…
glasstiger Oct 20, 2026
732385f
test: test SSO 401 recovery against a real Enterprise server
glasstiger Oct 20, 2026
6465989
update submodule
glasstiger Oct 20, 2026
240f68a
update submodule
glasstiger Oct 20, 2026
a1d867d
ci: run the OSS submodule check on Python 3.12
glasstiger Oct 20, 2026
f2d4d00
fix: warn before leaving the page would cancel uploads still being sent
glasstiger Oct 20, 2026
156ecb5
test: test startup 401 recovery in the required auth e2e lane
glasstiger Oct 20, 2026
9e69600
fix: keep CSV uploads and edits when a delayed table check returns
glasstiger Oct 20, 2026
bf03f0e
fix: stop a query rejected with 401 from waiting 60s for renewal
glasstiger Oct 20, 2026
ecc1a14
fix: stop asking to sign in again on queries the old session interrupted
glasstiger Oct 20, 2026
ee45055
fix: clear the Schema panel's renewal error once the tables load again
glasstiger Oct 20, 2026
908c39e
fix: end the identity provider's renewal error as a sentence
glasstiger Oct 20, 2026
6ea0ef1
fix: keep downloads working after the console recovers from a 401
glasstiger Oct 21, 2026
6df38c5
fix: stop showing the old table's status for a renamed CSV import
glasstiger Oct 21, 2026
36c1cdf
fix: keep the unfinished-upload warning after signing in again
glasstiger Oct 21, 2026
af79bde
fix: stop an editor script cleanly when the session ends
glasstiger Oct 21, 2026
a11f9f9
chore: drop gitleaks fingerprints of a commit outside this branch
glasstiger Oct 21, 2026
ad75e49
fix: reopen the cookie session after any 401, not only a query's
glasstiger Oct 21, 2026
b4985a1
fix: keep dropped CSV files when their table check fails
glasstiger Oct 21, 2026
da587ac
fix: keep notebook snapshots when a refresh is not executed
glasstiger Oct 21, 2026
d0f621b
fix: stop presenting auth failures as SQL errors or unsent requests
glasstiger Oct 21, 2026
8b77342
fix: clear the last query result when the session ends
glasstiger Oct 21, 2026
ee4d631
update submodule
glasstiger Oct 21, 2026
8f9229d
fix: renew the SSO session when Retry is pressed after a failure
glasstiger Oct 21, 2026
46809b2
fix: stop an edited chart drawing forever when it is not executed
glasstiger Oct 21, 2026
2ef62f9
fix: end the previous login when settings recovery shows Login
glasstiger Oct 21, 2026
0a119a8
fix: close gaps around session end and failed SSO renewal
glasstiger Oct 21, 2026
a37f2ee
update submodule
glasstiger Oct 21, 2026
93d55dd
fix: close more gaps around logout, session end and SSO renewal
glasstiger Oct 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/check_oss_submodule.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,8 @@ jobs:
uses: astral-sh/setup-uv@v3

- name: Check OSS branch
# pygit2 1.14.1 ships wheels only up to CPython 3.12. On runner images
# with a newer default Python (ubuntu-26.04 has 3.14), uv would build it
# from source and fail, because the libgit2 headers are not installed.
run: |
uv run --with "pygit2==1.14.1" submodule_is_mergeable.py
uv run --python 3.12 --with "pygit2==1.14.1" submodule_is_mergeable.py
79 changes: 79 additions & 0 deletions .github/workflows/enterprise_e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: Enterprise E2E

on:
push:
branches: [main]
pull_request:
workflow_dispatch:

permissions:
contents: read

concurrency:
group: enterprise-e2e-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
dispatch:
name: Dispatch Enterprise Web Console E2E
runs-on: ubuntu-latest
timeout-minutes: 5
# Mirrors the TypeScript client lane. Fork PRs never receive dispatch
# credentials; live EE tests/builds execute only in the private repository.
if: >-
vars.ENTERPRISE_E2E_ENABLED == 'true' && (github.event_name !=
'pull_request' ||
github.event.pull_request.head.repo.full_name == github.repository)
steps:
- name: Queue private Enterprise Web Console pipeline
env:
ENT_DISPATCH_PAT: ${{ secrets.ENT_DISPATCH_PAT }}
UI_COMMIT: ${{ github.event.pull_request.head.sha || github.sha }}
UI_PR_NUMBER: ${{ github.event.pull_request.number || '' }}
UI_BRANCH: ${{ github.head_ref || github.ref_name }}
run: |
set -euo pipefail
test -n "${ENT_DISPATCH_PAT:-}" || {
echo "ENT_DISPATCH_PAT is not configured" >&2
exit 1
}
[[ "$UI_COMMIT" =~ ^[0-9a-f]{40}$ ]] || {
echo "Expected an immutable UI commit SHA" >&2
exit 1
}
ORG_URL="https://dev.azure.com/questdb/"
PROJECT="questdb-enterprise"
PIPELINE_NAME="build-and-test-e2e-web-console"
azure_failure() {
if [ -z "$2" ]; then
echo "Azure DevOps $1 failed without a response body; see curl's error above." >&2
else
echo "Azure DevOps rejected $1: $(
jq -er '.message | strings | select(length > 0)' <<<"$2" 2>/dev/null ||
head -c 500 <<<"$2"
)" >&2
fi
}
if ! PIPELINES=$(curl --fail-with-body -sS -u ":${ENT_DISPATCH_PAT}" \
"${ORG_URL}${PROJECT}/_apis/pipelines?api-version=7.0"); then
azure_failure "pipeline lookup" "$PIPELINES"
exit 1
fi
PIPELINE_ID=$(jq -r --arg name "$PIPELINE_NAME" \
'.value[] | select(.name == $name) | .id' <<<"$PIPELINES" | head -1)
test -n "$PIPELINE_ID" && [ "$PIPELINE_ID" != "null" ] || {
echo "Enterprise pipeline '$PIPELINE_NAME' is not registered" >&2
exit 1
}
BODY=$(jq -n --arg commit "$UI_COMMIT" --arg pr "$UI_PR_NUMBER" --arg branch "$UI_BRANCH" '
{templateParameters: (
{webConsoleCommit: $commit, clientBranch: $branch}
+ (if $pr == "" then {} else {webConsolePrNumber: $pr} end)
)}')
if ! RESPONSE=$(curl --fail-with-body -sS -u ":${ENT_DISPATCH_PAT}" \
-H "Content-Type: application/json" -X POST -d "$BODY" \
"${ORG_URL}${PROJECT}/_apis/pipelines/${PIPELINE_ID}/runs?api-version=7.0"); then
azure_failure "dispatch" "$RESPONSE"
exit 1
fi
echo "Enterprise E2E queued: $(jq -r '._links.web.href' <<<"$RESPONSE")"
65 changes: 61 additions & 4 deletions e2e/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@

To run browser tests in a local dev environment:

* make sure `localhost:9999` points to QuestDB Web Console
* disable telemetry in QuestDB Web Console. Use env variable `QDB_TELEMETRY_ENABLED=false`
if running with docker, you can pass the variable like this:
- make sure `localhost:9999` points to QuestDB Web Console
- disable telemetry in QuestDB Web Console. Use env variable
`QDB_TELEMETRY_ENABLED=false` if running with docker, you can pass the
variable like this:

```
docker run -e QDB_TELEMETRY_ENABLED=false -p 9000:9000 -p 9009:9009 questdb/questdb:latest
```

* run `cypress` through `yarn`:
- run `cypress` through `yarn`:

```
yarn test:e2e # console tests
yarn test:e2e:auth # auth tests
Expand All @@ -21,3 +24,57 @@ If you want to interact with cypress, you can start it like so:
```
yarn cypress open
```

## Enterprise integration lane

The ordinary CI workflow always runs `e2e/tests/auth/*.spec.js`. These use
stubbed HTTP responses and cover token parsing (including string/zero expiry),
JSON 429/503 refresh failures, credential precedence, error focus/dismissal and
retrying the initial SQL check without requiring a licensed database.

Live EE builds and authentication fixtures belong in the **private Enterprise
repository**, following its JavaScript-client cross-repository lane. This
repository's `.github/workflows/enterprise_e2e.yml` only dispatches Azure; it
neither checks out Enterprise source nor downloads an EE binary.

One-time maintainer setup:

1. Register Enterprise's `ci/build-and-test-e2e-web-console.yaml` as the Azure
pipeline `build-and-test-e2e-web-console` in the `questdb-enterprise`
project. Authorize its existing `github-public-read` variable group and
ensure the private lane's `GITHUB_TOKEN` can post commit statuses to
`questdb/ui`.
2. Give the UI repository the Actions secret `ENT_DISPATCH_PAT`, scoped to Azure
Build (Read & execute) with permission to queue that pipeline. It needs no
access to the private GitHub repository or to Enterprise binaries.
3. Set the UI Actions variable `ENTERPRISE_E2E_ENABLED=true`.

Same-repository PRs, main pushes and manual runs dispatch the exact UI commit
SHA. Fork PRs never receive the PAT. Enterprise matches the UI branch when an EE
branch of the same name exists (otherwise uses main), builds EE with its
existing private test harness, and builds the public UI checkout at that SHA.
The private pytest driver runs `yarn test:e2e:enterprise` against a fresh EE
server, validates that invalid credentials are rejected, and supplies the
server-side userinfo fixture. Cypress still stubs browser code/token exchange.
The result is posted to the tested SHA as `enterprise-e2e-web-console`, even if
the PR head moves while tests run. A successful dispatch is **not** a passed
integration run: check that separate status.

One `oidc.spec.js` test leaves `/exec` unstubbed to check the tandem server
change (questdb#7799). After a reload installs a bearer that the userinfo
fixture rejects, the server answers 401 even though the browser still sends a
valid `qdb_session` cookie, and the console renews its token once and resends
once. The 401 also deleted the cookie, so the resend asks the server for a new
session: downloads authenticate with that cookie alone. ID-token bearers
(`acl.oidc.groups.encoded.in.token=true`) are tested only by unit and stubbed
browser tests: the lane would need a fixture that signs ID tokens.
`auth/auth.spec.js` replays that startup sequence with stubbed 401s, for both
bearer kinds, so the required auth lane covers the console side of it. It cannot
replace this lane: only a real server shows how the server responds.

For local runs, follow the Enterprise e2e README and set
`QDB_WEB_CONSOLE_DIR=/absolute/path/to/built/ui`, then run
`pytest -m web_console` in `questdb-ent/e2e`. The UI checkout needs
`yarn install --immutable`, `yarn build`, and a working Cypress installation
(`yarn cypress verify`). Ports 9000 and 9999 must be free; the harness owns and
tears down both services.
19 changes: 12 additions & 7 deletions e2e/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -581,13 +581,18 @@ Cypress.Commands.add("selectQueries", (selection) => {
})

Cypress.Commands.add("execQuery", (query) => {
const authHeader = localStorage.getItem("basic.auth.header")
cy.request({
method: "GET",
url: `${baseUrl}/exec?query=${encodeURIComponent(query)};`,
headers: {
Authorization: authHeader,
},
return cy.window().then(({ localStorage }) => {
// EE password login stores a REST token, OSS stores a Basic header.
// Read the application's storage at request time, not the runner window.
const restToken = localStorage.getItem("rest.token")
const authorization = restToken
? `Bearer ${restToken}`
: localStorage.getItem("basic.auth.header")
return cy.request({
method: "GET",
url: `${baseUrl}/exec?query=${encodeURIComponent(query)};`,
headers: authorization ? { Authorization: authorization } : {},
})
})
})

Expand Down
2 changes: 1 addition & 1 deletion e2e/questdb
Submodule questdb updated 509 files
Loading
Loading