A python node's params reach process() as whatever its author put there, but there was no way to put anything there: the settings form is built from a type's declared schema, and a function node declares none. Node types now say whether they take settings beyond their schema, and the panel offers a key/value editor for the ones that do — named, typed as text, number, on/off or JSON, and laid out like the port list beside it. Rows are keyed by position rather than by name, so renaming a setting does not remount the row and lose what was being typed into it. Verified in the running app in both themes.
73 lines
2.6 KiB
JavaScript
73 lines
2.6 KiB
JavaScript
/** Feature check: the free-form settings editor on a function node. */
|
|
import { mkdir } from "node:fs/promises"
|
|
import { chromium } from "@playwright/test"
|
|
|
|
const APP_URL = process.env.APP_URL || "http://app.localhost"
|
|
const EMAIL = process.env.FIRST_SUPERUSER
|
|
const PASSWORD = process.env.FIRST_SUPERUSER_PASSWORD
|
|
const OUT = process.env.SCREENSHOT_DIR || "screenshots"
|
|
|
|
const browser = await chromium.launch()
|
|
for (const theme of ["light", "dark"]) {
|
|
const dir = `${OUT}/${theme}`
|
|
await mkdir(dir, { recursive: true })
|
|
const context = await browser.newContext({
|
|
viewport: { width: 1440, height: 900 },
|
|
colorScheme: theme,
|
|
})
|
|
await context.addInitScript((t) => {
|
|
localStorage.setItem("fluksio-ui-theme", t)
|
|
}, theme)
|
|
const page = await context.newPage()
|
|
|
|
await page.goto(`${APP_URL}/login`, { waitUntil: "networkidle" })
|
|
await page.getByTestId("email-input").fill(EMAIL)
|
|
await page.getByTestId("password-input").fill(PASSWORD)
|
|
await page.getByRole("button", { name: /log in/i }).click()
|
|
await page.waitForURL(`${APP_URL}/`, { timeout: 15000 })
|
|
|
|
await page.goto(`${APP_URL}/flows`, { waitUntil: "networkidle" })
|
|
const seed = page.getByTestId("create-first-flow")
|
|
if (await seed.count()) {
|
|
await seed.click()
|
|
await page.waitForURL(/\/flows\/.+/, { timeout: 15000 })
|
|
}
|
|
if (!(await page.locator(".react-flow__node").count())) {
|
|
await page.getByTestId("add-node").click()
|
|
await page
|
|
.getByRole("option", { name: /function/i })
|
|
.first()
|
|
.click()
|
|
await page.waitForSelector(".react-flow__node")
|
|
}
|
|
await page.locator(".react-flow__node").first().click()
|
|
await page.waitForSelector("[data-testid=node-panel]", { timeout: 15000 })
|
|
|
|
// Add two settings and give them values.
|
|
await page.getByTestId("add-param").click()
|
|
await page.waitForTimeout(300)
|
|
const names = page.getByLabel("Setting name")
|
|
const values = page.getByLabel("Setting value")
|
|
await names.first().fill("threshold")
|
|
await names.first().blur()
|
|
await page.waitForTimeout(200)
|
|
await page.getByLabel("Type").first().click()
|
|
await page.getByRole("option", { name: "number" }).click()
|
|
await page.waitForTimeout(200)
|
|
await values.first().fill("21.5")
|
|
await page.waitForTimeout(200)
|
|
|
|
await page.getByTestId("add-param").click()
|
|
await page.waitForTimeout(300)
|
|
await names.nth(1).fill("label")
|
|
await names.nth(1).blur()
|
|
await page.waitForTimeout(200)
|
|
await values.nth(1).fill("living room")
|
|
await page.waitForTimeout(1200)
|
|
|
|
await page.screenshot({ path: `${dir}/app-node-params.png` })
|
|
console.log(` wrote ${dir}/app-node-params.png`)
|
|
await context.close()
|
|
}
|
|
await browser.close()
|