Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions apps/docs/components/workflow-preview/workflow-preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ function PreviewFlow({
nodes={nodes}
edges={initialEdges}
onNodesChange={onNodesChange}
onNodeClick={onNodeClick ? (_, node) => onNodeClick(node.id) : undefined}
onPaneClick={onPaneClick}
nodeTypes={NODE_TYPES}
edgeTypes={EDGE_TYPES}
Expand Down
67 changes: 56 additions & 11 deletions apps/docs/scripts/benchmark-readiness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -949,7 +949,7 @@ async function interactions(browser: Browser, profile: Profile, repetition: numb
}
})
await apiControls(run, profile, repetition)
await measure(profile, '/workflows', repetition, 'workflow-inspector-control', async () => {
await measure(profile, '/workflows', repetition, 'workflow-canvas-control', async () => {
await run.page.goto(new URL('/workflows', base).href, { waitUntil: 'domcontentloaded' })
await meaningful(run.page, new URL('/workflows', base).pathname)
const trigger = run.page
Expand All @@ -963,20 +963,65 @@ async function interactions(browser: Browser, profile: Profile, repetition: numb
await dialog.waitFor()
await painted(run.page)
const feedbackMs = performance.now() - start
const block = dialog
.getByRole('group', { name: 'Inspect a block' })
.getByRole('button')
.first()
if (await block.count()) {
await block.click()
await painted(run.page)
}
const canvas = dialog.locator('.react-flow__pane')
const viewport = dialog.locator('.react-flow__viewport')
const node = dialog.locator('.react-flow__node').first()
await expect(node).toBeVisible()
await painted(run.page)
const bounds = await canvas.boundingBox()
if (!bounds) throw new Error('Workflow canvas has no visible bounds')
const transform = (element: Locator) =>
element.evaluate((element) => {
const matrix = new DOMMatrixReadOnly(getComputedStyle(element).transform)
return { x: matrix.e, y: matrix.f, scale: matrix.a }
})
const beforePan = await transform(viewport)
const x = bounds.x + bounds.width / 2
const y = bounds.y + bounds.height - 24
await run.page.mouse.move(x, y)
await run.page.mouse.down()
await run.page.mouse.move(x + 24, y - 24, { steps: 5 })
await run.page.mouse.up()
await expect.poll(async () => (await transform(viewport)).x).not.toBe(beforePan.x)
const afterPan = await transform(viewport)
expect(afterPan.scale).toBe(beforePan.scale)
const beforeZoom = afterPan.scale
await run.page.mouse.wheel(0, -80)
await expect
.poll(() =>
viewport.evaluate(
(element) => new DOMMatrixReadOnly(getComputedStyle(element).transform).a
)
)
.toBeGreaterThan(beforeZoom)
await node.click({ trial: true, position: { x: 8, y: 8 } })
const afterZoom = await transform(viewport)
const nodeBefore = await transform(node)
const nodeBounds = await node.boundingBox()
if (!nodeBounds) throw new Error('Workflow node has no visible bounds')
await run.page.mouse.move(nodeBounds.x + nodeBounds.width / 2, nodeBounds.y + 8)
await run.page.mouse.down()
await run.page.mouse.move(nodeBounds.x + nodeBounds.width / 2 + 20, nodeBounds.y + 28, {
steps: 5,
})
await run.page.mouse.up()
await expect
.poll(async () => {
const position = await transform(node)
return Math.hypot(position.x - nodeBefore.x, position.y - nodeBefore.y)
})
.toBeGreaterThan(1)
expect(await transform(viewport)).toEqual(afterZoom)
const data = {
selectedBlock: (await block.count()) ? await block.textContent() : undefined,
dialogTextLength: (await dialog.textContent())?.length,
beforePan,
afterPan,
afterZoom,
nodeBefore,
nodeAfter: await transform(node),
}
await run.page.keyboard.press('Escape')
await dialog.waitFor({ state: 'hidden' })
await expect(trigger).toBeFocused()
return { status: 'completed', feedbackMs, data }
})
for (const route of [
Expand Down
20 changes: 20 additions & 0 deletions apps/docs/scripts/test-navigation-e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,26 @@ try {
}
})
}
for (const kind of ['loop', 'parallel']) {
await check(`Inline ${kind} body opens lightbox at ${width}px`, async () => {
const page = await context.newPage()
try {
await open(page, `/workflows/blocks/${kind}`)
const container = page.locator('.react-flow__node-previewContainer').first()
await expect(container).toBeVisible()
const bounds = await container.boundingBox()
if (!bounds) throw new Error('Container has no visible bounds')
await container.click({ position: { x: bounds.width / 2, y: bounds.height - 8 } })
const viewer = page.getByRole('dialog')
await expect(viewer).toBeVisible()
await page.screenshot({ path: join(directory, `${kind}-body-${width}.png`) })
await page.keyboard.press('Escape')
await expect(viewer).toHaveCount(0)
} finally {
await page.close()
}
})
}
await check(`Workflow lightbox at ${width}px`, async () => {
const page = await context.newPage()
try {
Expand Down
23 changes: 23 additions & 0 deletions apps/sim/scripts/test-organization-search-e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,29 @@ try {
)
assert.equal(response.status(), 404)
})
await check('A streamed denied chat remains navigable after hydration', async () => {
const releaseScripts = createDeferred<void>()
const scripts = '**/_next/static/**/*.js'
await page.route(scripts, async (route) => {
await releaseScripts.promise
await route.continue()
})
try {
const response = await page.goto(`${baseUrl.origin}${root}/search/chat/${deniedChatId}`, {
waitUntil: 'commit',
})
assert(response, 'The denied chat navigation must return a document')
await response.body()
} finally {
releaseScripts.resolve()
await page.unrouteAll({ behavior: 'wait' })
}
await page.waitForLoadState()
await expect(page.getByRole('heading', { name: 'Page not found' })).toBeVisible()
await page.getByRole('link', { name: 'Return home', exact: true }).click()
await expect(page).toHaveURL(`${baseUrl.origin}${root}/home`)
await expect(page.getByRole('textbox', { name: 'Ask Sim' })).toBeVisible()
})
await check('Both search modes fit desktop and 320px/390px phones', async () => {
for (const width of [1440, 390, 320]) {
await page.setViewportSize({ width, height: width === 1440 ? 1000 : 844 })
Expand Down
Loading