A message shows its shape, and its contents when asked
A record or an artifact reference was serialised into the port row, and the panel widened until the type selects and the buttons beside them were pushed off its edge — a checkpoint reference is 130 characters of digest, and none of them are what you want while wiring a flow. What shows now is what the value *is*: 'artifact · weights.json · 60B', 'record · 3 fields'. A chevron unfolds the whole of it, wrapped, inside the panel it belongs to. A scalar still reads as itself, and scrolls its own overflow into view when it is longer than the room it was given. That behaviour already existed inside the edge inspector; it moves to Common/Marquee so the panel can have it too, and the inspector drops its own copy of the raw-JSON block along with it. The rows are smaller for it: the type select finally fits the word 'artifact', and a port nothing has come through on says so with a dash rather than a sentence — nine ports of 'nothing has come through yet' is a panel of prose about the absence of values. The e2e check asserts both halves: that the summary is what appears, and that the panel is still exactly 400px with the value unfolded. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AD8SfVhzXBG2nAfFcVh3iD
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
import { expect, test } from "@playwright/test"
|
||||
import { api, apiPage, deleteAll } from "./utils/api"
|
||||
|
||||
/**
|
||||
* What a message carrying a dictionary looks like in a panel four hundred
|
||||
* pixels wide.
|
||||
*
|
||||
* The regression this exists for: a record or an artifact reference was
|
||||
* serialised into the row, and the panel widened until the type selects and
|
||||
* the buttons beside them were pushed off the edge. The shape shows instead,
|
||||
* and the contents unfold on request — so the check is both that the summary
|
||||
* is what appears, and that the panel is still the width it was told to be.
|
||||
*/
|
||||
|
||||
const flowName = `test_values_${Date.now().toString(36)}`
|
||||
/** The panel's fixed width; the whole point is that a value cannot change it. */
|
||||
const PANEL_WIDTH = 400
|
||||
|
||||
test.use({ storageState: "playwright/.auth/user.json" })
|
||||
test.describe.configure({ mode: "serial" })
|
||||
|
||||
test.beforeAll(async ({ browser }) => {
|
||||
const page = await apiPage(browser)
|
||||
await api(page, `/flows/${flowName}`, {
|
||||
method: "PUT",
|
||||
data: {
|
||||
name: flowName,
|
||||
title: "Values",
|
||||
version: 1,
|
||||
nodes: [
|
||||
{
|
||||
id: "emit",
|
||||
type: "python",
|
||||
provides: [
|
||||
{ name: "shape", dtype: "record" },
|
||||
{ name: "label", dtype: "str" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
// Saving writes a draft and moves the version on, so publish what is
|
||||
// actually there rather than what it was a moment ago.
|
||||
const draft = await (await api(page, `/flows/${flowName}?draft=true`)).json()
|
||||
await api(page, `/flows/${flowName}/publish`, {
|
||||
method: "POST",
|
||||
data: { version: draft.definition.version },
|
||||
})
|
||||
// Values a flow could plausibly hold: one structured, one longer than the
|
||||
// room a 400px panel has for it.
|
||||
await api(page, `/messages/${flowName}.shape`, {
|
||||
method: "POST",
|
||||
data: {
|
||||
value: { title: "Recovered", body: "R2 = 0.98", severity: "info" },
|
||||
},
|
||||
})
|
||||
await api(page, `/messages/${flowName}.label`, {
|
||||
method: "POST",
|
||||
data: {
|
||||
value: "ubuntu-gpu-node-01.lab.internal (numpy 2.5.2, cuda 12.4)",
|
||||
},
|
||||
})
|
||||
await page.close()
|
||||
})
|
||||
|
||||
test.afterAll(async ({ browser }) => {
|
||||
await deleteAll(browser, [`/flows/${flowName}`])
|
||||
})
|
||||
|
||||
test("a dictionary shows its shape, and its contents on request", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto(`/flows/${flowName}`)
|
||||
const node = page.locator(".react-flow__node").first()
|
||||
await node.waitFor({ timeout: 20000 })
|
||||
await node.click()
|
||||
|
||||
const panel = page.locator('aside[role="complementary"]').first()
|
||||
await expect(panel).toBeVisible()
|
||||
|
||||
// The shape, not the values.
|
||||
const summary = page.getByTestId("value-preview-toggle")
|
||||
await expect(summary).toContainText("record · 3 fields")
|
||||
await expect(panel).not.toContainText("Recovered")
|
||||
|
||||
// A value cannot push the panel open, however long it is.
|
||||
expect((await panel.boundingBox())?.width).toBe(PANEL_WIDTH)
|
||||
|
||||
// The contents are one click away.
|
||||
await summary.click()
|
||||
await expect(panel).toContainText("Recovered")
|
||||
expect((await panel.boundingBox())?.width).toBe(PANEL_WIDTH)
|
||||
})
|
||||
Reference in New Issue
Block a user