45340 Commits

Author SHA1 Message Date
Fraser
afa79587c2 Lint without building cljs (#83718) 2026-10-07 16:06:33 +13:00
Romeo Van Snick
2b271c6987 Remove unreferenced images from app/assets/img and app/img (#82788)
* Remove unreferenced static images

* Remove unreferenced images from app/img

* Remove four more unreferenced images kept by a loose name match
2026-10-07 14:03:22 +11:00
Timothy S. Dean
37d5c5b042 Fix the revision history of an edited transform test (#83818) 2026-10-06 18:19:47 -06:00
Maz Ameli
30d6158ea1 Replace dashboard loading spinner with an instant skeleton (DSN-749) (#83288)
* Replace dashboard loading spinner with an instant skeleton (DSN-749)

Dashboards no longer show a loading spinner when opened. Instead they render
a skeleton of the dashboard shell and card layout instantly:

- New DashboardSkeleton renders the header chrome (title, action buttons,
  tabs), a full-width border, a secondary-background body, filter-widget
  placeholders, and the card grid constrained to a centered 1024px column.
- New DashboardGridSkeleton draws the card grid. When the layout is cached
  in Redux from a prior visit (getLastSeenTabDashcards), it reproduces
  react-grid-layout's real geometry so the cards land where the real ones
  will; heading/text cards render title-style line skeletons. Otherwise a
  generic placeholder layout is used.
- Grid no longer shows a spinner while refetching; the header no longer
  shows a spinner while its collection query loads.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Draw the real dashboard layout before query metadata loads (DSN-749)

fetchDashboard awaited both GET /api/dashboard/:id and the slower
/query_metadata before any of the dashboard reached the store, even though
the GET alone already holds the card layout. On a fresh open it now
publishes the GET response's normalized dashboard and dashcards as soon as
it arrives (dashboardLayoutFetched), so the loading skeleton switches from
the generic layout to the dashboard's real one without waiting for
metadata. The full load transition is unchanged, and a refetch of a
dashboard already on screen publishes nothing early.

The virtual-card copy is extracted into copyVirtualCardsToCards so the
early layout and the fulfilled payload are built the same way.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Render dashboard skeletons inside the real dashboard layout (DSN-749)

Replace the separate full-page dashboard skeleton with skeletons that the
header, filter panel and card grid each render while the dashboard loads,
so the surrounding page, widths and theming are the real ones and can't
drift.

- Grid renders DashboardGridSkeleton when there's no dashboard yet. This
  also covers public links, static embeds, X-rays and SDK dashboards, which
  showed "This dashboard is empty" while loading. Its spinner is restored
  for refetches of an already-open dashboard.
- The skeletons read the dashboard as last seen in the in-memory Redux
  cache: its width (assuming the default fixed width when it isn't
  cached), its tabs (a tab row only for two or more), the cards of the tab
  the user is landing on, and its header filters (excluding inline and
  hidden ones).
- The grid skeleton takes its geometry from the grid constants, including
  a new shared GRID_MARGINS, and drops the heightPx special case.
- The skeletons are marked aria-busy, and the grid announces "Loading…".
- waitForDashboardToLoad waits for a loading dashboard in tests, since
  waitForLoaderToBeRemoved no longer does.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Draw no placeholder cards until the dashboard's layout is known (DSN-749)

While a dashboard that isn't in the in-memory Redux cache loads, the grid
skeleton used to draw a generic layout of placeholder cards, which rarely
matched the dashboard about to appear. It now draws no cards until the
dashboard's real layout is known, so the content area stays empty under
the header skeleton and then fills with the real layout. The grid still
marks itself busy and announces "Loading…".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Size the dashboard header skeleton from the real title (DSN-749)

The header skeleton drew a bare title bar, but the real title area is
taller: the title is an EditableText box with its own padding, border and
line height, and the last-edit label sits on a row beneath it. The header
grew when the dashboard arrived, pushing the page down.

The title and label bars now sit over invisible copies of the real
elements, so the skeleton takes their exact height without copying their
styles. The label row is only reserved when the real header would show
it; a dashboard that isn't cached is assumed to have an edit history.

Also replace a file path in a CSS comment, and note in dashboard_grid.ts
that the grid skeleton's mobile container query repeats MOBILE_BREAKPOINT.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-07 00:06:34 +00:00
Romeo Van Snick
3d9a6743c6 Hash static images through the rspack build (#82726)
* Declare png and gif module imports for the bundler

* Hash onboarding, upsell and example images through the build

* Assert the Slack app icon link against the bundled asset

* Hash the upsell card story illustration through the build

* Take image sources as props instead of building paths from a base string

* Add a ?url image import that the SDK bundle references instead of inlining

* Hash empty state, upsell and driver logo images through the build

* Hash the map skeleton sprite and the bridge illustration through the build
2026-10-07 10:25:24 +11:00
bryan
1c0661fa03 GHY-4737: Remote sync: name the cause of a diverged-export conflict (#83682)
* GHY-4737: Remote sync: name the cause of a diverged-export conflict

A plain export against a remote that moved past the last sync ended in a
conflict task with conflicts [], so API clients (the mb CLI, agents) saw
"conflict" with no reason: the task row stores only conflicts, and
handle-task-result! drops :message. Record a factual label instead.

Also pin that such a conflict leaves the sync base alone, so a later
export with merge still sees the remote's changes.

* GHY-4737: pin the conflict label on the task row; trim the label comment

* GHY-4737: record the diverged-export cause as a stable token

Review feedback: conflicts otherwise holds short identifiers on the
import path, and an untranslated English sentence would become a wording
contract for clients. Record "remote-changed" and let clients word it.

* GHY-4737: don't let auto-import repeat an unresolved conflict

A conflict is no longer a sync base, so auto-import's "source version
matches last import" skip no longer stops a conflicted read-only
auto-import: it retried, and recorded a new conflict task, every tick.
Skip when the newest task conflicted at the current source version;
a new remote commit or a manual import still proceeds. Review feedback.

* GHY-4737: name why a task stopped in outcome, keep conflicts for what collided

Review feedback: conflicts answers "what collided" (import categories,
merge entities). A diverged export has no collision; the divergence is
why it stopped. Record conflicts [] plus outcome {:kind "remote-changed"}
instead of a token inside conflicts, and add outcome
{:kind "history-rewritten"} to the no-merge-base paths (their conflicts
sentence stays for compatibility). handle-task-result! now writes outcome
on conflicts; the outcome schema and FE type gain both kinds.
2026-10-06 16:46:55 -06:00
Andrei Chernykh
e27d36ca15 Migrate the whitelabel settings off Emotion (#83691) 2026-10-06 15:23:45 -07:00
Nemanja Glumac
d764799f8f Reusable test gate logic (#82830)
* Let each test suite decide whether it should run

run-tests.yml computed a `skip` input for every suite it called, so the
decision for a suite lived in the caller rather than next to the jobs it
governs. A new callable workflow, test-gate.yml, carries the part that is the
same everywhere: the force-run / force-skip / defer verdict, and a paths filter
that only runs on `defer`, over a sparse `.github` checkout.

Each suite now calls the gate with the filters it cares about and reads `run`,
`matched` or `files`. app-db, drivers, semantic-search, loki, e2e-tests,
frontend, embedding-sdk, build-scripts, bundle-size and backend keep no `skip`
input; run-tests only decides whether to call them at all.

static-viz-files-changed moves into backend.yml, its only consumer, and now
runs only when `backend_all` did not already match.

The uberjar and SDK package conditions become the build_uberjar and
build_embedding_sdk_package filters, each the union of what the artifact feeds.

A force-run reports every requested filter as matched, so the project-level
backend, migration and ratchet checks now also run on master and `ci:run-all`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Drop the redundant always() from workflow conditions

`always() && !cancelled()` is `!cancelled()`: always() only adds "run even when
cancelled", which the second term takes straight back. The four conditions that
paired !cancelled() with a `needs.<job>.result == 'success'` check restated the
implicit rule instead, so they lose both terms and let a plain `if` apply it.

In e2e-tests.yml that also fixes a latent failure: the suite entered when
e2e-matrix-builder had failed, leaving `fromJson` to parse a matrix that was
never produced.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Stop gate jobs from skipping themselves

A skipped job skips everything downstream of it, which is why so many consumers
carried !cancelled() just to override the implicit success(). create-test-plan,
static-viz-files-changed and story-selection now always run and gate their steps
instead, emitting empty outputs, so their consumers keep only their real
condition. create-test-plan is best-effort: a planner failure means the suites
run in full, as a skipped one already did.

The app-db, drivers and semantic-search gates were skipped on a direct dispatch
for the same reason. They pass no filters on that path instead, which already
means "only check for a force-cancel".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Land the affected-tests stats row from the planner action

The upload job existed only to POST what create-test-plan had just computed,
so it re-checked out the repo and re-prepared bun to read one output back.
It is now the action's last step, which also drops the `stats` output that
only ever carried the payload across the job boundary.

A composite action has no `secrets` context, so the endpoint and key arrive as
inputs; an empty endpoint (a fork PR, which gets no secrets) skips the upload
rather than posting nowhere.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Reorder workflows

* Count the bookkeeping jobs in the result checks

`static-viz-files-changed` and `e2e-matrix-builder` feed every job in their
suite but were absent from the `*-result` needs, so a failure in either skipped
the whole suite and the required check reported success.

`sdk-tests` now requires a successful gate, like `e2e-tests`: a failed gate
skips the uberjar and SDK package builds for a reason the suite's own gate
cannot see, and the component tests would run against a missing artifact.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Hand out a test plan only from a clean planner run

The plan artifact is uploaded before the planner's reporting steps, so a
failure after the upload still exported an artifact id and both suites narrowed
from it. Reading the step outcome covers that; the job's `continue-on-error`
means its own `result` is always `success`, so a caller-side check would not.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Run the suites when the test gate changes

test-gate.yml matched no filter that gates a suite, so a diff touching only the
workflow that decides whether every suite runs ran nothing. Putting it in
shared_ci reaches backend, frontend, loki, e2e, the SDK suites and ci-scripts.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Keep file lists out of the test gate

The match step read every paths-filter output through one environment
variable, file lists included. That variable passes the 128 KiB Linux allows
a single one at around 130 changed files, so the gate failed on large PRs and
took every suite down with it.

The gate now lists no files and reads only the names of the matched filters.
The create-test-plan action, the one consumer of paths, runs its own paths
filter instead of taking file lists and infra flags as inputs, so the
run-tests gate asks only for the filters its own jobs read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* cleanup

* Address review: job-level skips, no frontend dispatch, no per-leg profiling

- story-selection, create-test-plan and static-viz-files-changed skip as a
  job again instead of skipping each step. Their consumers carry
  !cancelled() so a skipped one does not skip them, and the planner and
  static-viz probe no longer hold a large runner just to do nothing.
- frontend.yml loses its workflow_dispatch trigger and the skip inputs it
  fed.
- The profiling dispatch no longer picks a leg: the db input and every
  github.event.inputs.db read are gone, so a profile runs every leg of the
  suite.
- semantic-search drops ci:run-semantic-search-tests. The full suite runs on
  a force-run (master, release branches, ci:run-all) or a profile; every
  other run is the Postgres Latest smoke run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* cleanup

* Gate a profiling dispatch like any other run

The backend suites read the dispatch's `suite` input to run everything when
profiled. They now gate a profiling dispatch like any other run: in full on
master and release branches, by the diff anywhere else, with semantic-search
running its smoke leg.

The profiler switch keys off the dispatch event instead. backend.yml sets it
on the test step; app-db, drivers and semantic-search set it in their workflow
env, which the test-driver action inherits, so the stress-test workflows that
dispatch the action directly still never profile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* rename

* cleanup

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Ryan Laurie <iethree@gmail.com>
2026-10-06 22:05:46 +00:00
Oleksandr Yakushev
7d638168dd [pivot] Optimize node formatting (#83057) 2026-10-07 01:03:57 +03:00
Chris Vandoodewaard
519834f9ee Consolidate sharing e2e tests (#83657)
* Remove duplicate public sharing e2e tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Merge sharing reproductions e2e tests that share setup

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Merge downloads e2e tests that share setup

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Merge public sharing e2e tests that share setup

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Repair downloads e2e tests that cannot fail

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Repair sharing reproductions e2e tests that cannot fail

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Drop unused setup in sharing reproductions e2e tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Remove duplicate subscriptions e2e tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Repair public sharing e2e tests that cannot fail

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Drop unused setup in downloads e2e tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Drop unused setup in public sharing e2e tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Remove duplicate alert e2e tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Merge alert e2e tests that share setup

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Repair alert e2e tests that cannot fail

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Drop unused setup in alert e2e tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Remove duplicate public sharing e2e tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Merge subscriptions e2e tests that share setup

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Repair subscriptions e2e tests that cannot fail

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Drop unused setup in subscriptions e2e tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Fold public dashboard link creation e2e test into 20393 repro

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fold 30314 subscription cancel e2e test into 14117 test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Fold 16108 tooltip e2e test into download format test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Merge public sharing e2e tests that share setup

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Place merged 18352 card below the Orders card

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Type a name before Escape in the 24629 subscriptions e2e test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Repair public sharing e2e tests that cannot fail

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Tag sharing e2e tests that need maildev as external

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Drop unused setup in public sharing e2e tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Fix popover check after Escape in dashboard downloads e2e test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Keep the webhook channel in the 12349 alert e2e test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Tighten subscriptions e2e checks found in parity review

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Tighten sharing reproductions e2e checks found in parity review

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Restore admin and UI-created link coverage in public sharing e2e tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011Jc2P2sKm39MghfKPxCSiv

* Fix 7 sharing e2e failures from CI

* Restore 48402 coverage and merge more sharing e2e tests

- Restore the metabase#48402 delete-alert step in the 12349 test and check the delete modal
- Make 18669 check the email filter value and 21559 check the card image
- Merge public dashboard download flag tests with the real downloads
- Merge static-viz, branding, and default-filter subscription tests
- Merge dashboard PDF and PNG download tests and check download parameters
- Merge the two background=false public dashboard tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Address review on sharing e2e consolidation

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fix sharing e2e CI failures

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 17:39:59 -04:00
Chris Vandoodewaard
cc2db95954 Consolidate monitor e2e tests (#83655)
* Fold monitor e2e subset tests into their supersets

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CmvNCJoEdZwRpEkem3754T

* Merge monitor e2e tests that share setup

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CmvNCJoEdZwRpEkem3754T

* Repair monitor e2e checks that cannot fail

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CmvNCJoEdZwRpEkem3754T

* Strengthen weak monitor e2e checks

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CmvNCJoEdZwRpEkem3754T

* Flatten monitor erroring questions e2e setup and fix titles

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CmvNCJoEdZwRpEkem3754T

* Fold monitor empty task logs test into the task details test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CmvNCJoEdZwRpEkem3754T

* Anchor moved monitor e2e checks on rendered content

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CmvNCJoEdZwRpEkem3754T

* Allow extra rows in monitor task runs tab switch check

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CmvNCJoEdZwRpEkem3754T

* Fold monitor task logs test into the task details test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CmvNCJoEdZwRpEkem3754T

* Merge monitor task runs tab and details tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CmvNCJoEdZwRpEkem3754T

* Merge monitor task runs filtering and entity picker tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CmvNCJoEdZwRpEkem3754T

* Merge monitor MCP analytics tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CmvNCJoEdZwRpEkem3754T

* Fix review findings in monitor e2e tests

- Cold load the task run details page
- Check the entity loader right after the started-at selection
- Check task rows, not only the tasks table card
- Match only the MCP events query in the tool calls waits
- Remove a redundant empty state check

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 17:39:37 -04:00
Chris Vandoodewaard
ae0dbb421a flake fix: displays object details, breadcrumbs, relationships, email links, and 404 error state (#83762)
remove flaky assertion, match similar test
2026-10-06 17:39:22 -04:00
Chris Vandoodewaard
94ef260096 Consolidate explorations e2e tests (#83654)
* Fold explorations picker search test into the manual flow test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EmyW5RuqbkDJu7aUM3Po3J

* Fold explorations click-to-select test into the sidebar tabs test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EmyW5RuqbkDJu7aUM3Po3J

* Merge explorations trash page tests into the trash banner test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EmyW5RuqbkDJu7aUM3Po3J

* Strengthen weak explorations navigation checks

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EmyW5RuqbkDJu7aUM3Po3J

* Remove unused addMetricsToExploration e2e helper

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EmyW5RuqbkDJu7aUM3Po3J

* Consolidate more explorations e2e tests and fix weak checks

- Merge the Summary document test into the brush explore-further test
- Merge the personal collection test into the trash banner and /trash test
- Check that the toast View action moves to a different page
- Wait for the search request with the typed query in the metrics picker

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Address review feedback on explorations e2e consolidation

- Append an unfiltered page to the Summary and check both card embeds
- Check the new page renders after the cartesian toast View
- Load /trash cold before the trash row actions and flatten the trash test
- Merge the sidebar hide pages test into the tabs test
- Share one beforeEach and afterEach under a top-level describe

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 17:13:42 -04:00
Chris Vandoodewaard
c6b4dee91c run timing workflow daily with a one day lookback (#83780) 2026-10-06 16:52:46 -04:00
Nemanja Glumac
54fe3c4365 Consolidate data studio e2e tests (#83736)
* Remove duplicate data-studio e2e tests

Drop tests whose steps and assertions already run in another e2e test:
a measures-queries identity test that was copied line for line, a
CountIf-segment measure test that matches another one step for step,
an empty-folder snippet test that never exercised folder expansion, a
skipped segment-cycle test whose asserted text does not exist in the
product, and an MBQL SQL-preview LIMIT check that could not fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fold subset data-studio e2e tests into their supersets

Delete tests whose steps already run in a host test with the same setup,
and add their few unique checks to that host: empty states and /new
URLs into the create flows, unsaved-changes guards, breadcrumbs,
dependency graph tabs, read-only views into the edit tests, transform
target errors, the Python library entry and editing, the inspect tabs,
and the SQL-preview LIMIT check on a transform without a limit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Repair data-studio e2e assertions that could not fail

Make checks go red when the behavior breaks: wait for the run request
before reading the run label (it shows the previous result on mount),
assert values that differ before and after the action (checkpoints,
filtered rows, converted SQL, Python output, rewired dependents after a
new source row), fix selectors that never match (tab roles, a document-
wide get, wrong measure names), assert the outcome of saves that had
nothing after them, and drop checks on buttons that never render.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Strengthen weak data-studio e2e assertions

Give negative checks a positive precondition on the same element so
they cannot pass before the UI mounts, wait for the request before
checks that follow a save or a navigation, use the multi-toast helper
where a previous toast may still show, guard .each loops against empty
sets, and create the metric picker fixtures on the database the picker
shows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Merge data-studio e2e tests that share setup

Run tests with the same restore, user, fixtures and entry page as one
test, so each restore and page load serves several checks. Every part
keeps its original starting state: read-only parts run first, parts
that mutate data run last, each part starts from its own visit where
the state matters, and toasts are dismissed between parts. Tests that
replace a source or convert a model now create all dependents and run
the replacement once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Drop unused setup in data-studio e2e tests

Remove restores that a later restore overwrites, intercept aliases that
nothing waits on, duplicate snowplow resets, duplicate helpers and
unused helper parameters. Fix wrong logs, titles and comments.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fix data-studio e2e merges found in the parity pass

Load the notebook fresh before the second data-picker part, check the
closed popover without the visibility guard, delete segments after a
direct visit as before, remove the failed-run test that also runs in
the runs filter test, and keep the snowplow check for the job creation
flow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fix and restore data-studio e2e checks from review

Assert the Python transform output as a scalar, assert the archive
banner instead of a URL check that could not fail, and bring back the
collection checks after a direct library visit. Give the
multiple-template-tags part its own visit without a database pick, run
the non-admin source-replacement check before any sandbox exists, drop
the run-status polls before the run label, and match the join table
label by text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Add positive checks before data-studio e2e negatives from review

Assert the element or container is there before each remaining
negative check (sync modal, cleared-description hovercard, row
checkboxes before read-only mode, the transform row before deletion,
the transforms header in the empty state), and wait for the dashcard
query after a filter change before checking rows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Merge more data-studio e2e tests that share setup

Run more tests with the same restore, user and fixtures as one test:
measure queries on one measure fixture, template tags with the data
reference flow, inspect loading with the summary lenses, the transform
reproductions, transform ownership with the inline settings, tag
editing, published-table queries, metric editing and moving, table
dependencies, segment tabs and dependencies, sort orders, and table
details. Each part starts from its own visit where the state matters,
and parts that change data run last.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fix data-studio e2e tests that failed in CI

Drop the test tables before the writable-database restore again: the
restore cannot drop the source table while the child table still has a
foreign key to it. Submit the transform form by its submit button,
which shows "Failed" for a few seconds after the rejected save. Close
the run error modal with Escape, since it has two close buttons, and
check a tag that is listed in the dropdown, because selected tags are
not listed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 22:44:38 +02:00
Timofey Kachalov
ed1d3d1004 Data apps: move resource collections into a data-apps namespace and serialize them with the app (#83766) 2026-10-07 00:38:11 +04:00
Jeff Bruemmer
b9b5c25e7a docs - transform indexes (#83598) 2026-10-06 20:26:52 +00:00
Alexander Polyankin
d40e005888 Mock the engines endpoint in the DatabaseEditApp and DatabaseListApp specs (#83782)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 21:07:08 +02:00
Nemanja Glumac
b1ddf5b6c4 Consolidate dashboard filters 2 e2e specs (#83700)
* Move dashboard-filters-2 e2e specs into dashboard-filters

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Remove unused dashboard filter query-stage helpers

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Remove duplicate dashboard filter target picker empty state test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fold dashboard filter reproduction subsets into their supersets

Run the target picker empty-section search in the empty-state test, add a
never-connected card to the disconnected-card reload test, and count public
dashcard requests in the public remapping test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Repair dashboard filter e2e checks that could not fail

Prove click-through navigation, give negative checks a positive precondition
on the same element, assert filtered results that differ from the unfiltered
card, wait for reverts and stored last-used values, map the first-stage
breakout column in the query-stage test, and check the first card in the
first-stage aggregation test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Merge dashboard filter e2e tests that share setup

Run the remapping, comma-separated value, sql model field value and public
and embedded remapping reproductions once per setup, and apply a query-stage
filter after checking the mapping options on the same dashboard.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Drop unused dashboard filter e2e setup

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Tag the writable database filter linking reproduction as external

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Check merged dashboard filter reproductions against the right state

Assert the filtered public dashcard by row count, since its Name column is
outside the card, and clear the last used remapped value before loading it
from the url.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Select the city from the autocomplete suggestions in the city filter test

The city filter searches values instead of listing them, so the selected
value shows as a pill in the search input.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 20:36:16 +02:00
Nemanja Glumac
fd95839a47 Consolidate dashboard filter behavior e2e specs (#83692)
* Drop temporal unit public and embedded dashboard tests

The multiple column breakouts dashboard test sets temporal unit
parameters on the same dashboard through a public link and a static
embed, and checks the card columns after each change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Check the auto-wired card keeps its mappings in temporal unit test

Only the manually mapped card was asserted, so overwriting the category
mapping on the auto-wired card went unnoticed. Assert both cards and
drop a negative check that ran before any data loaded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Merge temporal unit parameter tests that share setup

Fold the model mapping into the question mapping test, the no-breakout
auto-wiring checks into the new card test, the default clearing into the
allowed units test, and the URL value tests and the native query tests
into one test each.

The no-breakout card check now waits for the other new card's
suggestion, and the default clearing checks the unit was excluded before
asserting the default stayed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fix temporal unit parameter test titles

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fold temporal unit chevron alignment check into reset test

The chevron alignment test built the same no-default temporal unit
parameter as the temporal unit reset & clear test. Run its check at the
end of that test, in the parameter sidebar it already opens, and assert
both chevrons are present before comparing them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fold reset-with-open-popover check into number filter test

The required number filter test already resets a changed value with the
widget's revert icon. Open the widget popover first and assert it closes
after the reset, which covers the standalone reset-with-open-popover
test. Drop that test along with its describe and duplicate beforeEach.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fold required text filter set-to-default check into reset test

The standalone test deselected all values of a required filter whose
value already equalled its default, then clicked "Set to default" and
asserted the unchanged "4 selections", so it passed even if the button
did nothing. The multi-value text reset test now changes its required
filter to a non-default value first, deselects all, clicks "Set to
default" and asserts the default is applied and the reset icon is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Use a distinct other value in multi-value text reset test

The other value had two selections, as did the default, so every
"2 selections" check passed whether the filter held the default or the
other value. Pick three values so the widget text tells them apart.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fold auto-wiring subset tests into their supersets

The Undo flow now runs in the "already has a parameter" test, which
undoes before mapping card 1 to Address instead of clearing it by hand.
The auto-connected toast check moves into the add-a-card Undo test, the
replace-a-card flow into the parameter mapping test (now also checking
the replaced card is mapped), and the 8s undo-toast timeout into the
12s timeout test with tighter bounds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Add positive preconditions to reset & clear negative checks

checkResetAllFiltersHidden asserted "Reset all filters" was absent
without showing the menu had opened; it now sees "Enter fullscreen" in
the same menu first. The first "no status icon" check on the required
filter now asserts the widget shows the default value first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Retitle number range reset test and drop dead comment

The number "multiple values" test uses "between" parameters, so call it
a range. Remove a commented-out line in the text multi-value test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Make foreign key auto-wiring filter checks able to fail

Both tests filtered by ID 1 and asserted cells contain "1", which the
unfiltered tables also satisfy, and waited on a card query alias that
matched the initial dashboard load. They now filter by 3, assert the
exact cell text "3", and wait on an alias registered just before the
filter is applied.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Add positive preconditions to auto-wiring absence checks

The card 1 "User.Name" absence check now first confirms card 1 shows
"Select…", and the no-suggestion toast check first confirms card 0 is
mapped to "User.Name", so neither passes before the mapping UI renders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Merge unsaved and reset draft filter auto-apply tests

Both tests set a draft filter value on the same dashboard with auto-apply
off. Run the reload check first, asserting the widget shows its
placeholder rather than the draft value, then the reset steps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Drop unused intercepts from auto-wiring spec

Nothing waits on the "@dashboard" alias or reads the card query spy,
and the "@cardQuery" alias has no remaining waits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fold cancelled-edit draft filter test into dashboard edit test

Both tests set the same draft filter value before entering edit mode.
The edit test now cancels an edit first and checks the draft value and
apply button survive, then edits and saves as before. Drop the emptied
describe.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fix stale comment in auto-wiring toast timeout test

The comment said auto-wiring toasts share an id; each toast now gets
its own id, so it states only what the test guards.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fold auto-apply enable snowplow test into disable test

After disabling auto-apply and seeing one "auto_apply_filters_disabled"
event, the disable test now enables it again and checks the event count
stays at one, covering the standalone enable test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Check the checkbox state in auto-apply filter reset test

The reset check asserted "not.be.checked" on the "Gadget" label text,
which is never checked, so it passed whether or not the reset worked.
Query the checkbox by its label instead, and assert it is checked after
selecting it so the final unchecked state is meaningful.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Check rows after disabling auto-apply in toggle test

The last step only checked the widget text after disabling auto-apply,
and its log described draft values although the change had already been
applied. Assert the card still shows the 107 Gadget and Widget rows and
describe the step as it runs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fold filter type change subset tests into their supersets

The default-operator walk through Number, ID, Date and Location now
runs in the mapping reset test before it saves, and the mapping
cleared/restored checks run in the saved parameter value test, which
already switches Text to Number and back on the same dashboard.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Order filter management checks after the state they test

The hidden filter widget check after saving now has a positive
precondition: the shared setup confirms the "Text" widget is shown
before editing. The operator change test checks the mapping survives
only after "No default" confirms the operator change applied, so the
check can't match the pre-change DOM.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Add menu precondition to auto-apply no-permission test

The test asserted "Edit settings" was absent without showing the
dashboard menu had opened. Assert "Enter fullscreen" in the same menu
first, and title the test after what it checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fix default operator log messages in filter management spec

The Number log said "Between" while asserting "Equal to", and the
Location log said "Date".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Merge dashboard filter default tests that share setup

Both tests built the same two-filter dashboard and visited it with the
same params. After setting Filter Two's default, the remaining test now
sets Filter One's default to "Baz" and checks the URL and widgets keep
Filter Two's value before and after saving.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fold static list clear-and-restore test into number source spec

The clear-and-restore spec built the same Orders count dashboard with a
number filter and static list source as the number source static list
test. That test now edits its dropdown filter afterwards, switches it to
a text filter (list cleared), connects it to Email, and switches it back
to number (list restored). Move the helpers and delete the spec.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Check number filter dropdown hides raw values behind labels

The number/string label test only checked the label is listed; it now
also checks the raw value "1" is not, as the string/string test does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Merge dashboard filter source tests that share setup

Each group now builds one dashboard with a distinctly named filter per
case and scopes every widget by name:
- structured Contains, structured Is and native Is question sources,
  archiving each source and checking the plural "2 filters" warning
  for the shared GUI source and the singular one for the SQL source
- string, number and id values remapped to string labels
- static list dropdown, static list search and field search box
- IP address and type/Quantity custom labels on postgres

The filter helpers take the filter name instead of clicking "Text".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Drop unused dataset intercept from filter source spec

Nothing waits on the "@dataset" alias.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Stop restoring twice before the UUID chained filter test

The test sat under the chained filter beforeEach, so it restored the
default snapshot and signed in before restoring postgres-writable
itself. It now has its own describe and does only its own setup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Retitle UUID chained filter test after what it checks

"should work for all field types" described none of it; the test
checks a UUID primary key column is offered for an ID filter under the
"Update a dashboard filter" click behavior.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Describe the default replacement step in filter defaults test

The log said the step removes the default value and its URL
placeholder, but it replaces Filter Two's default with "Foo".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fold nodata filter mapping checks into data permissions test

Merge the admin and nodata filter tests into one, and add the nodata
edit-mode checks there: the card actions panel shows without an
"Add a filter" button (shown to the admin in setup), and the filter
mapper shows the key icon. Remove the parameters spec tests that only
covered those nodata checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fold subset dashboard parameter tests into their supersets

Each removed test ran on the same setup as a test that already covered
its first steps, so its remaining steps now run at the end of that test:
- resetting a last used value and reloading: last used value test
- removing a heading dashcard: heading dashcard removal undo test
- removing a question dashcard: question dashcard filter edit test
- own-card connection message: other-tab connection test
- showing all inline parameters while editing one: question dashcard
  filter removal test
- undoing filter moves: single tab filter move test
- dashboard_filter_moved tracking: dashboard_filter_created test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Repair dashboard filter checks that could not fail

- Data permissions: drop the search intercept, whose alias was mangled
  into the URL, along with the unused 403 branch that waited on it.
  Open the filter through its widget instead of matching any "Text",
  drop the "Orders" and dashboard-title clicks that always matched,
  click "Add filter" in the popover without force, and check the
  widget value and URL param.
- Heading filters: check the grabber icon on the heading card holding
  the filter, not on the question card.
- Text card variables: check the Count widget instead of Category twice.
- Public dashboards: map the Count filter to the dashcard's own card so
  its widget renders, and check it does.
- Granular filter preference: wait for the dashcard query after updating
  the header filter before checking the card.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Strengthen weak dashboard parameter assertions

- Filter removal: check the filtered-out rows are present before
  filtering and that matching rows render before checking the others
  are gone; check only one filter widget remains after removal.
- Multiple filters: check the values request count after the reopened
  popover has rendered its values.
- Compare multi-slug URLs with expectSearchParams instead of exact
  search strings, whose param order is not deterministic.
- Inline auto-wiring and dashcard duplication: check the own-card
  message renders before checking the mapper has no Category option.
- Disabled embedded parameter: check the card shows unfiltered data.
- Filter focus: check the move toast renders before checking it has no
  "Show filter" button.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Merge dashcard refetch-on-save tests into one

The four tests shared the same setup. Run their saves in sequence in
one test, so each later count also catches a fetch an earlier save
should not have made: no fetch after saving a disconnected filter or
an unchanged dashboard, then 1 after connecting one card, 2 after
disconnecting it, and 4 after connecting both.

Register the request spy before the setup save instead of after it, so
the disconnected-filter check can fail if that save fetches data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Drop duplicate dashboard PUT intercept

The dashcard duplication test registered the same updateDashboard
intercept twice; keep the one at the top of the test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Retitle merged dashboard filter tests

Name the steps each merged test now covers, including the admin and
nodata usage and nodata edit-mode checks in the data permissions test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Drop auto-apply toast tests for public and signed embeds

The slow dashboard toast is only shown to users who can edit the
dashboard, and the tests could not make the dashboard slow: cy.clock
does not affect performance.now and the card request was never delayed.
Neither test could fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Check the other tab message while the inline filter is connected

Also compare the public dashboard URL params regardless of slug order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Name both toast timeouts in auto-wiring timeout test title

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Describe temporal unit parameter priority without an issue reference

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fix dashboard filter tests that failed in CI

The heading text is an input after the parameter sidebar closes, so
check the saved dashcards instead. The add-card sidebar stays open after
a card is added, so pick the next card from it. The auto-wired table card
is below the fold, so check its column header exists.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Restore the non-required filter reset with an open popover test

Only the non-required filter reset closes the popover. The required
filter reset keeps it open, so the check cannot run on the required
number filter. The test now uses the outer describe setup.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Find temporal unit auto-wired cards by name after save

Saved dashcards are ordered by their layout position, so the added
cards no longer have the indexes they had while editing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 20:35:33 +02:00
Maksym Yakubych
190a31be82 Derive the mini model only from what a connection was listed as serving (#83139)
* Derive the mini model only from what a connection was listed as serving

With nothing stored, llm-mini-model resolved to the provider type's mini
model straight from the registry. Connecting lists the account's own
catalog but never checked that guess against it, so a connection whose
listing did not include the cheaper tier ran every quick task — conversation
titles — on a model it could not serve, and the admin page showed the mini
model as unconfigured because the derived value was not among the options.

Every listing now records whether it included the type's mini model on the
connection, and the derivation reads that instead of the registry: the
cheaper model when the connection was seen to offer it, the Metabot model
otherwise. The per-type mini models stay in the registry as the tier a
listing looks for.

* Tighten mini-model docstrings
2026-10-06 17:33:20 +00:00
Nathan Voxland
f062ce0832 Improve error handling in query responses (#82531) 2026-10-06 17:20:30 +00:00
Oleksandr Yakushev
01bd5d9ea5 [metadata] Analysis optimizations (#83635) 2026-10-06 20:09:04 +03:00
Jeff Bruemmer
012e199084 docs - mcp tool documentation gen (#82592) 2026-10-06 12:58:25 -04:00
Andrei Chernykh
a6ed8f0fef Migrate the table info card off Emotion (#83444)
* Migrate the table info card off Emotion

* Use CS overflow utilities in the table info card
2026-10-06 09:57:10 -07:00
John Swanson
e53a1611b4 Log applied sandboxes in the query execution audit log (#78975)
* Log applied sandboxes in the query execution audit log

Sandboxed (row-level security) queries used to show up in Usage
Analytics' query log as completely normal queries, making sandboxing
impossible to debug from the audit log (#71604, UXW-3767).

The logged query blob can't carry this information: it lives in the
query table keyed by a hash computed before preprocessing, so a
sandboxed and an unsandboxed run of the same question share one row.
Instead, record the restrictions per-execution:

- The sandboxing middleware records each sandbox it applies on the
  query under a namespaced key, merged across preprocessing passes.
  Applied sandboxes are derived from the
  :query-permissions/sandboxed-table markers left on each replacement
  stage -- the same source of truth is_sandboxed comes from.
- merge-sandboxing-metadata copies the entries into the results
  metadata (userland queries only), next to is_sandboxed.
- process-userland-query saves them to the new
  query_execution.sandbox_details column and strips them back out of
  the response returned to the client.

Each entry records table_id, sandbox_id, group_id, card_id, and the
login attributes used (attribute name -> target field id). The user's
actual attribute values are only included when
analytics-pii-retention-enabled is set, matching how that setting
gates other user-specific data in Usage Analytics.

The column is exposed in v_query_log (v7) and the shipped Query log
model.

* Give the attached sandbox audit details a named schema

Review feedback:

- Rename `record-sandbox-details` to `attach-sandbox-details`. It puts data
  on the query; it doesn't persist anything.
- Replace the bare `:map` and `::lib.schema/query` schemas with
  `::details-entry`, `::details` and `::query-with-details`, so the key
  sandboxing attaches during preprocessing is typed both where it is
  produced and where `merge-sandboxing-metadata` reads it back.
- Mention sandbox attribute values in the `analytics-pii-retention-enabled`
  description.

* Declare sandbox_details in the schemas master closed

Rebasing onto master brought in closed argument schemas and the checker in
`metabase.util.malli.closed-schemas`, which rejects any undeclared key and any
shape it cannot see. Every schema the new key passes through has to name it:

- `metabase.lib.schema` gains `::sandboxing.details.entry` and
  `::sandboxing.details`, and declares the `::details` key on the query map
  next to the existing sandboxing key. This is the one definition of the entry
  shape; the enterprise middleware and the row schemas below point at it.
- The legacy MBQL query schema declares the same key, since preprocessing
  round-trips the query through legacy and back.
- The result metadata threaded through the rff chain, and the QueryExecution
  insert schema, declare `:sandbox_details`.
- The SDK and batch-processing tracking rows pass the value through, so they
  declare it as a deliberately-open map rather than restating the shape.

Also renumber the migration from v64 to v65: v64 has branched for release, so
a v64 id on master would not roll back with the rest of v65.

* Let the query-with-details conjunct through the closed-schema check

An `:and` conjunct that constrains a single key is an open map, which
`metabase.util.malli.closed-schemas` refuses as an argument schema. Mark it
with `:malli.core/default`, the escape the checker documents for exactly this
shape: every other key is validated by `::lib.schema/query`, the first
conjunct, which is where `::details` is declared.

* Cover the new internal query key in the serialize fixture

`internal-keys-fixture-covers-the-schemas-test` asserts the fixtures carry
every internal key the schemas declare, so the serialization tests cannot
drift. Add `::details` with a schema-valid sample entry.
2026-10-06 09:44:55 -07:00
Alexander Polyankin
2dd2330f97 Create stub databases for missing databases on serdes import (#83574)
* Create stub databases for missing databases on serdes import

* Synthesize stub databases in the import resolver

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Drop Database load dependencies and fix tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Trim the admin database page for stub databases

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Test importing content on a missing database as a stub

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Exclude stub databases from serdes export

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Show database status in the admin list and clarify the stub healthcheck message

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Exempt stubs from the network policy, keep is_stub out of serdes, and wait for the save in the stub e2e test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Update the is_stub extract test now that is_stub is never exported

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Import every serialized Database as a non-stub

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fix review findings: no Database load deps, empty details skip the network check, name-only config matching

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Remove dead missing-database handling now that imports stub missing databases

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Test the stub database admin page sections and list request

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Memoize every import lookup and drop the cache when an entity's load fails

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Drop the Dimension path helper master replaced with serdes/field-path->field-ref

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 12:42:23 -04:00
Maksym Yakubych
5927b9bce6 Let ee-embedding-provider name the connection semantic search embeds through (#82521)
* Let ee-embedding-provider name the connection semantic search embeds through

* Keep registered embedder names from being shadowed by connection keys

* Skip the connection lookup when ee-embedding-provider names an embedder

* Do not fall back to the openai connection once ee-embedding-provider names one

* Warn when removing the connection semantic search embeds through

* Let the vLLM preflight test see the losing probe start before it is cancelled

* Keep ee-embedding-provider to semantic search and to OpenAI connections
2026-10-06 13:40:29 -03:00
Tyler Plude
355147d6a9 [GHY-4748] Exclude tables hidden in user settings from sync (#83494)
* add table-user-visibility-type to the warehouse schema overlay

* exclude tables hidden in user settings from sync

* test that the 064 user-settings migration keeps hidden tables hidden

* match field sync batches over hidden tables before skipping them

* tighten hidden-table sync tests and docstrings
2026-10-06 09:25:42 -07:00
Nathan Voxland
3e57a280fe Apply the configured path settings to the Snowflake OIDC token file (#83496) 2026-10-06 11:06:09 -05:00
Will Fry
01d4659a3e GDGT-3241: SegmentedControl constrained text + icon props (#83336)
* GDGT-3241 Constrain SegmentedControl items to text and icon props

Items are now typed data (label, icon, ariaLabel) instead of arbitrary
label nodes, and the component owns icon size and spacing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Update Loki Snapshots

* set line height on SegmentedControl label

* add second click to assert handler doesnt refire on multiple clicks

* interface -> type

* add test

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Metabase Automation <github-automation@metabase.com>
2026-10-06 15:42:18 +00:00
Sébastien
db875cbd2a Add a Refresh button to the embedded question when automatic reruns are off (#83732) 2026-10-06 16:54:33 +02:00
Sébastien
8561804a1a Hide MCP UI tools from clients with inline charts turned off (#83644) 2026-10-06 16:54:00 +02:00
github-automation-metabase
66c6739fdd Auto-update documentation for master (#83697)
Update generated docs (master)

Co-authored-by: github-actions <github-actions@github.com>
2026-10-06 10:48:35 -04:00
Anderson
5ddcbeeedf Show the metric icon for bookmarked metrics in the app sidebar (#83666)
Show metric icon for bookmarked metrics in the sidebar
2026-10-06 11:19:27 -03:00
Anna Tomka
762512b71d GDGT-3291: drop creator from the create/send notification request schema (#83555)
* GDGT-3291: drop client-sent creator in POST /api/notification/send

* GDGT-3291: clarify why /send drops the client-sent creator

* GDGT-3291: drop creator from the create/send request schema and stop sending it on Send now
2026-10-06 13:58:32 +00:00
Jeff Bruemmer
12f8e514d4 docs - 432 note on remote sync (#83667) 2026-10-06 13:21:59 +00:00
Uladzimir Havenchyk
96e656af6e fix: port undolisting toasts to the toast spec always dark (#83311)
* port remaining toast contents to the always-dark toast surface

* add spacing between toast action buttons

* address review
2026-10-06 13:02:40 +00:00
Andrei Simionescu
83f20bc0b5 Add Claude Opus 5.5 and Sonnet 5.5 to Metabot (#83647) 2026-10-06 14:00:04 +01:00
YB
2d4ff73f16 Bump libthrift to 0.25.0 (#83721)
bump libthrift to 0.25.0 in databricks and hive-like drivers
2026-10-06 14:07:38 +02:00
Nemanja Glumac
6623df6c22 Consolidate permissions e2e tests (#83645)
* Remove duplicate permissions e2e tests

Drop the second copy of the create-queries 'query builder only' group
view test, the admin-permissions blocked-viz test that the nodata
reproduction already runs with the same graph and user, and the
transforms list denial test whose steps run in the grant-after-deny
test. The coverer for the blocked-viz test now scopes its error text to
the query builder, and the grant-after-deny test now asserts the key
image.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Merge permissions e2e tests that share setup

Fold tests into siblings that run the same restore, user, token and
permission graph, keeping every step and assertion in its original
starting state:

- create-queries: 'no' in group view runs after the 'query builder and
  native' save, as a second save for another group
- baseline: the unauthorized-path loop runs as one test; the nodata
  data-load check moves into the nodata reproduction, which also hosts
  the blocked viz-settings reproduction
- reproductions: duplicate-in-view-only-collection follows the
  save-modal reproduction; the two raw-mode pivot/combo checks share
  one test
- application/admin: the application help panel joins the data help
  test; default subscriptions and monitoring checks share one test;
  the collection options check runs inside the collections edit test
- transforms: list page joins create-via-UI; create and run API denials
  share one test
- view-data: the blocked-table QB question joins the native question
  test
- sandboxing via API: existing and new user attributes share one test;
  the three normal-user sandbox checks share one test
- impersonated: drop the outer beforeEach repeated by the inner one

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Repair permissions e2e assertions that could not fail

- view-data: the impersonation-then-granular test switched the wrong
  database to Granular; the database-view sandbox test clicked Save
  changes without confirming, then re-read the unsaved draft
- sandboxing via UI: every custom-column case only checked '20 rows',
  which the unsandboxed limit-20 query also shows; expression cases now
  check Gizmo-only rows, literal cases check sandboxed responses
- sandboxing via API: a misspelled columnAssertion and an undefined
  PEOPLE.USER_ID skipped the column checks; the user attribute test
  now checks the saves
- admin help: not.contain with a RegExp is stringified and never fails;
  the stub intercept now registers before the visit
- application settings: drop absence checks for texts that no longer
  exist in that container
- downloads: assert the limited/full download level, and reload after
  saving download permissions
- reproductions: the 20717 regex had a typo and the 22727 text check
  passed on an empty picker; 39221 now performs a real user-local
  setting write before checking for a site settings fetch

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Add positive preconditions and waits to permissions e2e tests

Pair negative assertions with a positive check on the same element,
wait for the requests that the following checks depend on, and assert
exclusive category lists for the native-question sandbox. The revoked
subscriptions test now sets up SMTP so the missing Subscriptions button
reflects the permission rather than the absent email channel, and the
download denials check the download button by label as well as icon.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Drop unused setup and fix names in permissions e2e tests

Remove intercepts that are never waited on, an unused erroring question,
a commented-out duplicate line, a reload followed by a visit, and a
data model click that only unhid a table before navigating away. Tag
the misconfiguration spec @external since it uses the writable
Postgres database. Fix the 45073 title, the 14873 describe name, a
typo, unused helper params, the OSS index constant used after the
downgrade, and the title of the no-token View data column test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Restore the reload before opening the native editor

Clicking a table on the browse page leaves the app on an ad-hoc
question URL, so the native editor helper's hash-only visit would not
reload the page without it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Test real models in native download permissions tests

The model steps only renamed the card, so they re-tested the plain
question. Convert the card to a model and visit it as one. Also assert
the visible category values before the absent ones, so the absence
checks can't pass before the values have loaded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Merge two more permissions e2e tests that share setup

- sandboxing via API: the 14990 subscriptions sidebar check runs in the
  sandboxed subscription test, which has the same SMTP setup, sandbox
  and user
- view-data: the unsaved impersonated-then-granular check runs before
  the saved variant, from a fresh visit

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Chain permissions e2e tests whose earlier parts save nothing

Run read-only or draft-only tests first and the saving test last, with
a full page load between parts:

- admin-permissions: the 30494 toggle check before collection editing;
  the group-view revision-change check before the database-view one
- view-data: preserve-on-granular and parent inference before the
  group-view granular save
- impersonated: impersonated access checks before the cache check,
  signing back in as admin first
- transforms: deny, grant, then deny again in one test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fix positive preconditions in permissions e2e tests

The native editor run button is scoped by test id because the hidden
floating run button also carries the Refresh label and stays enabled.
The view data popover omits the current value, so it is checked for
Blocked instead of Can view.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Close the collection permission popover by reloading

Escape does not dismiss the permission popover, so the test now visits
Second collection directly, which also discards the open popover.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Address permissions e2e review feedback

Merge the remaining tests that share setup: the transforms column check
and the save flow, the transform page denial and the API denials, the
adhoc native check and the unauthorized paths, the blocked card check and
the nodata reproduction, and the two database view create queries tests.
Run the steps of merged tests once instead of repeating them, and drop
the second #37811 check.

Remove an unused join and sandbox setup and a final visit with no check,
and assert the mini picker has loaded before checking an absent database.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Check a visible mini picker item before the absent database

The transforms mini picker lists no databases for this user, so the
positive check uses Our analytics.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 09:35:08 +00:00
Romeo Van Snick
7907c04a71 Fix parseZone day arithmetic for datetimes without an offset (#83394)
* Fix parseZone day arithmetic for datetimes without an offset

* Assert the sync start time with the formatter the component uses

* Parse both sides of the SmartScalar same-day comparison with parseZone
2026-10-06 19:00:23 +11:00
Romeo Van Snick
41661db787 Keep engines and the timezone list out of the bulk settings payloads (#80138)
* Keep engines and the timezone list out of the bulk settings payloads

Both are large, change only when the instance is upgraded, and are read by a
handful of screens, so inlining them into every document and into
GET /api/session/properties costs every visitor. :include-in-list? false leaves
them out of those payloads while GET /api/setting/:key still serves them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Fetch engines and the timezone list by key in the screens that need them

The settings payload no longer carries either value, so the consumers read them
through RTK queries against GET /api/setting/:key instead of getSetting. Both
queries hold their entry indefinitely, since neither value changes without a
restart.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Wait for model metadata before opening the Actions menu in e2e

The menu is gated on supportsImplicitActions(), which reads the source table's
metadata, so the test raced GET /api/card/:id/query_metadata. The existing
getModel alias does not cover that request, because a Cypress glob does not
cross a path separator.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-06 18:59:42 +11:00
Sébastien
0feec26aea Fix flaky cursor-filtering diagnostics test (#83398) 2026-10-06 09:30:32 +02:00
github-automation-metabase
39ea08c8d8 Update translations 2026-10-06 (#83725)
* Update translation sources 2026-10-06

* Update translations

---------

Co-authored-by: github-actions <github-actions@github.com>
2026-10-06 06:22:08 +00:00
Alexander Polyankin
9050b176d6 Move Dimensions to FieldUserSettings in serdes (#83652) 2026-10-06 02:26:31 +00:00
Fraser
145357fbb1 Skip unused addons and font loads in Loki screenshot runs (#83068) 2026-10-06 14:23:32 +13:00
Tyler Plude
e2369cc1d4 [GHY-4755] Only follow a discovered remote sync task the current user started (#83579)
only follow a discovered remote sync task the current user started
2026-10-05 16:28:49 -07:00
bryan
d6b2903ccd Skip the redundant audit DB sync after a fresh install (#83681)
Skip the redundant audit DB sync after a fresh install (GHY-4728)

The install sync in maybe-install-audit-db! sees every analytics view but
never recorded last-analytics-views-checksum, so maybe-sync-audit-db! always
found the views stale on a fresh install and synced the audit DB a second
time. Record the checksum after the install sync. On a Postgres app DB this
removes the second sync (~2s); H2/MySQL still sync again for the engine swap.
2026-10-05 23:17:21 +00:00
Braden Shepherdson
27e4890c7a Metric Dimensions: Healthy remote sync, with unportable but stable IDs (#82751)
There are two significant changes here.

First, properly signal a change to `dependencies` and the remote sync machinery when the dimension (mappings) are edited. They were ignored before because they didn't publish an `:event/card-update`.

Second, for pre-curation metrics (with `:card_schema` 23 and earlier) the `:dimensions` are regenerated on each read, until the first time they are saved by an edit being made. Such metrics originally had *randomized* `:id`s, but since they're not persisted it made them permanently dirty from remote sync's POV. These are now based on the metric card's `:entity_id` as well as the mapped column, which means they are *stable* on any particular instance, *unique* within that metric (since it includes join details, not just the target field ID), but they are not *reproducible* across instances.

That's fine - the instance that created a metric pre-64 will export it with a now-stable ID; that will be persisted by downstream instances on import. Eventually the originating instance will persist them too, when it makes an edit to the metric. Since the generated IDs are now *stable*, all instances will converge on the true IDs.

Apologies for the noise, since this required adding `:entity_id` to a pile of `(t2/select [:model/Card :field :lists] ...)`, but its required by the `:card_schema` upgrades so we need to ensure that it's fetched.

Co-authored-by: Ethan McCue <ethan@mccue.dev>
Co-authored-by: John Swanson <john.swanson@metabase.com>
Co-authored-by: appleby <86076+appleby@users.noreply.github.com>
2026-10-05 22:21:38 +00:00