remove flakey has no pending logic, let them do whatever they want (#3457)
* remove flakey has no pending logic Signed-off-by: Jess Frazelle <github@jessfraz.com> * add test for many at once w dismiss bug Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * toastid Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixup more tests Signed-off-by: Jess Frazelle <github@jessfraz.com> --------- Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
@ -460,6 +460,206 @@ test.describe('Text-to-CAD tests', () => {
|
|||||||
|
|
||||||
await expect(page.getByText(promptWithNewline)).toBeVisible()
|
await expect(page.getByText(promptWithNewline)).toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('can do many at once and get many prompts back, and interact with many', async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
const u = await getUtils(page)
|
||||||
|
|
||||||
|
await page.setViewportSize({ width: 1000, height: 500 })
|
||||||
|
|
||||||
|
await u.waitForAuthSkipAppStart()
|
||||||
|
|
||||||
|
await sendPromptFromCommandBar(page, 'a 2x4 lego')
|
||||||
|
|
||||||
|
await sendPromptFromCommandBar(page, 'a 2x8 lego')
|
||||||
|
|
||||||
|
await sendPromptFromCommandBar(page, 'a 2x10 lego')
|
||||||
|
|
||||||
|
// Find the toast.
|
||||||
|
// Look out for the toast message
|
||||||
|
const submittingToastMessage = page.getByText(
|
||||||
|
`Submitting to Text-to-CAD API...`
|
||||||
|
)
|
||||||
|
await expect(submittingToastMessage.first()).toBeVisible()
|
||||||
|
|
||||||
|
const generatingToastMessage = page.getByText(
|
||||||
|
`Generating parametric model...`
|
||||||
|
)
|
||||||
|
await expect(generatingToastMessage.first()).toBeVisible({ timeout: 10000 })
|
||||||
|
|
||||||
|
const successToastMessage = page.getByText(`Text-to-CAD successful`)
|
||||||
|
// We should have three success toasts.
|
||||||
|
await expect(successToastMessage).toHaveCount(3, { timeout: 15000 })
|
||||||
|
|
||||||
|
await expect(page.getByText('Copied')).not.toBeVisible()
|
||||||
|
|
||||||
|
await expect(page.getByText(`a 2x4 lego`)).toBeVisible()
|
||||||
|
await expect(page.getByText(`a 2x8 lego`)).toBeVisible()
|
||||||
|
await expect(page.getByText(`a 2x10 lego`)).toBeVisible()
|
||||||
|
|
||||||
|
// Ensure if you reject one, the others stay.
|
||||||
|
const rejectButton = page.getByRole('button', { name: 'Reject' })
|
||||||
|
await expect(rejectButton.first()).toBeVisible()
|
||||||
|
// Click the reject button on the first toast.
|
||||||
|
rejectButton.first().click()
|
||||||
|
|
||||||
|
// The first toast should disappear, but not the others.
|
||||||
|
await expect(page.getByText(`a 2x10 lego`)).not.toBeVisible()
|
||||||
|
await expect(page.getByText(`a 2x8 lego`)).toBeVisible()
|
||||||
|
await expect(page.getByText(`a 2x4 lego`)).toBeVisible()
|
||||||
|
|
||||||
|
// Ensure you can copy the code for one of the models remaining.
|
||||||
|
const copyToClipboardButton = page.getByRole('button', {
|
||||||
|
name: 'Copy to clipboard',
|
||||||
|
})
|
||||||
|
await expect(copyToClipboardButton.first()).toBeVisible()
|
||||||
|
// Click the button.
|
||||||
|
await copyToClipboardButton.first().click()
|
||||||
|
|
||||||
|
// Expect the code to be copied.
|
||||||
|
await expect(page.getByText('Copied')).toBeVisible()
|
||||||
|
|
||||||
|
// Click in the code editor.
|
||||||
|
await page.locator('.cm-content').click({ position: { x: 10, y: 10 } })
|
||||||
|
|
||||||
|
// Paste the code.
|
||||||
|
await page.keyboard.down(CtrlKey)
|
||||||
|
await page.keyboard.press('KeyV')
|
||||||
|
await page.keyboard.up(CtrlKey)
|
||||||
|
|
||||||
|
// Expect the code to be pasted.
|
||||||
|
await expect(page.locator('.cm-content')).toContainText(`2x8`)
|
||||||
|
|
||||||
|
// Find the toast close button.
|
||||||
|
const closeButton = page.getByRole('button', { name: 'Close' })
|
||||||
|
await expect(closeButton).toBeVisible()
|
||||||
|
await closeButton.click()
|
||||||
|
|
||||||
|
// Ensure the final toast remains.
|
||||||
|
await expect(page.getByText(`a 2x10 lego`)).not.toBeVisible()
|
||||||
|
await expect(page.getByText(`a 2x8 lego`)).not.toBeVisible()
|
||||||
|
await expect(page.getByText(`a 2x4 lego`)).toBeVisible()
|
||||||
|
|
||||||
|
// Ensure you can copy the code for the final model.
|
||||||
|
await expect(copyToClipboardButton).toBeVisible()
|
||||||
|
// Click the button.
|
||||||
|
await copyToClipboardButton.click()
|
||||||
|
|
||||||
|
// Expect the code to be copied.
|
||||||
|
await expect(page.getByText('Copied')).toBeVisible()
|
||||||
|
|
||||||
|
// Click in the code editor.
|
||||||
|
await page.locator('.cm-content').click({ position: { x: 10, y: 10 } })
|
||||||
|
|
||||||
|
// Paste the code.
|
||||||
|
await page.keyboard.down(CtrlKey)
|
||||||
|
await page.keyboard.press('KeyA')
|
||||||
|
await page.keyboard.up(CtrlKey)
|
||||||
|
await page.keyboard.press('Backspace')
|
||||||
|
await page.keyboard.down(CtrlKey)
|
||||||
|
await page.keyboard.press('KeyV')
|
||||||
|
await page.keyboard.up(CtrlKey)
|
||||||
|
|
||||||
|
// Expect the code to be pasted.
|
||||||
|
await expect(page.locator('.cm-content')).toContainText(`2x4`)
|
||||||
|
|
||||||
|
// Expect the toast to disappear.
|
||||||
|
// Find the toast close button.
|
||||||
|
await expect(closeButton).toBeVisible()
|
||||||
|
await closeButton.click()
|
||||||
|
await expect(page.getByText('Copied')).not.toBeVisible()
|
||||||
|
await expect(successToastMessage).not.toBeVisible()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('can do many at once with errors, clicking dismiss error does not dismiss all', async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
const u = await getUtils(page)
|
||||||
|
|
||||||
|
await page.setViewportSize({ width: 1000, height: 500 })
|
||||||
|
|
||||||
|
await u.waitForAuthSkipAppStart()
|
||||||
|
|
||||||
|
await sendPromptFromCommandBar(page, 'a 2x4 lego')
|
||||||
|
|
||||||
|
await sendPromptFromCommandBar(
|
||||||
|
page,
|
||||||
|
'alkjsdnlajshdbfjlhsbdf a;skjdnf;askjdnf'
|
||||||
|
)
|
||||||
|
|
||||||
|
// Find the toast.
|
||||||
|
// Look out for the toast message
|
||||||
|
const submittingToastMessage = page.getByText(
|
||||||
|
`Submitting to Text-to-CAD API...`
|
||||||
|
)
|
||||||
|
await expect(submittingToastMessage.first()).toBeVisible()
|
||||||
|
|
||||||
|
const generatingToastMessage = page.getByText(
|
||||||
|
`Generating parametric model...`
|
||||||
|
)
|
||||||
|
await expect(generatingToastMessage.first()).toBeVisible({ timeout: 10000 })
|
||||||
|
|
||||||
|
const successToastMessage = page.getByText(`Text-to-CAD successful`)
|
||||||
|
// We should have three success toasts.
|
||||||
|
await expect(successToastMessage).toHaveCount(1, { timeout: 15000 })
|
||||||
|
|
||||||
|
await expect(page.getByText('Copied')).not.toBeVisible()
|
||||||
|
|
||||||
|
const failureToastMessage = page.getByText(
|
||||||
|
`The prompt must clearly describe a CAD model`
|
||||||
|
)
|
||||||
|
await expect(failureToastMessage).toBeVisible()
|
||||||
|
|
||||||
|
// Make sure the toast did not say it was successful.
|
||||||
|
await expect(page.getByText(`Text-to-CAD failed`)).toBeVisible()
|
||||||
|
|
||||||
|
await expect(page.getByText(`a 2x4 lego`)).toBeVisible()
|
||||||
|
|
||||||
|
// Ensure if you dismiss the error the others stay.
|
||||||
|
const dismissButton = page.getByRole('button', { name: 'Dismiss' })
|
||||||
|
await expect(dismissButton).toBeVisible()
|
||||||
|
// Click the dismiss button on the first toast.
|
||||||
|
dismissButton.first().click()
|
||||||
|
|
||||||
|
// Make sure the failure toast disappears.
|
||||||
|
await expect(failureToastMessage).not.toBeVisible()
|
||||||
|
await expect(page.getByText(`Text-to-CAD failed`)).not.toBeVisible()
|
||||||
|
|
||||||
|
// The first toast should disappear, but not the others.
|
||||||
|
await expect(page.getByText(`a 2x4 lego`)).toBeVisible()
|
||||||
|
|
||||||
|
// Ensure you can copy the code for one of the models remaining.
|
||||||
|
const copyToClipboardButton = page.getByRole('button', {
|
||||||
|
name: 'Copy to clipboard',
|
||||||
|
})
|
||||||
|
await expect(copyToClipboardButton.first()).toBeVisible()
|
||||||
|
// Click the button.
|
||||||
|
await copyToClipboardButton.first().click()
|
||||||
|
|
||||||
|
// Expect the code to be copied.
|
||||||
|
await expect(page.getByText('Copied')).toBeVisible()
|
||||||
|
|
||||||
|
// Click in the code editor.
|
||||||
|
await page.locator('.cm-content').click({ position: { x: 10, y: 10 } })
|
||||||
|
|
||||||
|
// Paste the code.
|
||||||
|
await page.keyboard.down(CtrlKey)
|
||||||
|
await page.keyboard.press('KeyV')
|
||||||
|
await page.keyboard.up(CtrlKey)
|
||||||
|
|
||||||
|
// Expect the code to be pasted.
|
||||||
|
await expect(page.locator('.cm-content')).toContainText(`2x4`)
|
||||||
|
|
||||||
|
// Find the toast close button.
|
||||||
|
const closeButton = page.getByRole('button', { name: 'Close' })
|
||||||
|
await expect(closeButton).toBeVisible()
|
||||||
|
await closeButton.click()
|
||||||
|
|
||||||
|
// Expect the toast to disappear.
|
||||||
|
await expect(page.getByText('Copied')).not.toBeVisible()
|
||||||
|
await expect(successToastMessage).not.toBeVisible()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
async function sendPromptFromCommandBar(page: Page, promptStr: string) {
|
async function sendPromptFromCommandBar(page: Page, promptStr: string) {
|
||||||
|
@ -467,12 +467,6 @@ export const ModelingMachineProvider = ({
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
'Add pending text-to-cad prompt': assign({
|
|
||||||
pendingTextToCad: (_, event) => event.data.prompt.trim(),
|
|
||||||
}),
|
|
||||||
'Remove pending text-to-cad prompt': assign({
|
|
||||||
pendingTextToCad: undefined,
|
|
||||||
}),
|
|
||||||
'Submit to Text-to-CAD API': async (_, { data }) => {
|
'Submit to Text-to-CAD API': async (_, { data }) => {
|
||||||
const trimmedPrompt = data.prompt.trim()
|
const trimmedPrompt = data.prompt.trim()
|
||||||
if (!trimmedPrompt) return
|
if (!trimmedPrompt) return
|
||||||
@ -549,8 +543,6 @@ export const ModelingMachineProvider = ({
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'Has no pending text-to-cad submissions': ({ pendingTextToCad }) =>
|
|
||||||
!pendingTextToCad,
|
|
||||||
},
|
},
|
||||||
services: {
|
services: {
|
||||||
'AST-undo-startSketchOn': async ({ sketchDetails }) => {
|
'AST-undo-startSketchOn': async ({ sketchDetails }) => {
|
||||||
|
@ -36,10 +36,12 @@ const FRUSTUM_SIZE = 0.5
|
|||||||
const OUTPUT_KEY = 'source.glb'
|
const OUTPUT_KEY = 'source.glb'
|
||||||
|
|
||||||
export function ToastTextToCadError({
|
export function ToastTextToCadError({
|
||||||
|
toastId,
|
||||||
message,
|
message,
|
||||||
prompt,
|
prompt,
|
||||||
commandBarSend,
|
commandBarSend,
|
||||||
}: {
|
}: {
|
||||||
|
toastId: string
|
||||||
message: string
|
message: string
|
||||||
prompt: string
|
prompt: string
|
||||||
commandBarSend: (
|
commandBarSend: (
|
||||||
@ -63,7 +65,7 @@ export function ToastTextToCadError({
|
|||||||
}}
|
}}
|
||||||
name="Dismiss"
|
name="Dismiss"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
toast.dismiss()
|
toast.dismiss(toastId)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Dismiss
|
Dismiss
|
||||||
@ -85,7 +87,7 @@ export function ToastTextToCadError({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
toast.dismiss()
|
toast.dismiss(toastId)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Edit prompt
|
Edit prompt
|
||||||
@ -96,6 +98,7 @@ export function ToastTextToCadError({
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function ToastTextToCadSuccess({
|
export function ToastTextToCadSuccess({
|
||||||
|
toastId,
|
||||||
data,
|
data,
|
||||||
navigate,
|
navigate,
|
||||||
context,
|
context,
|
||||||
@ -103,7 +106,7 @@ export function ToastTextToCadSuccess({
|
|||||||
fileMachineSend,
|
fileMachineSend,
|
||||||
settings,
|
settings,
|
||||||
}: {
|
}: {
|
||||||
// TODO: update this type to match the actual data when API is done
|
toastId: string
|
||||||
data: TextToCad_type & { fileName: string }
|
data: TextToCad_type & { fileName: string }
|
||||||
navigate: (to: string) => void
|
navigate: (to: string) => void
|
||||||
context: ReturnType<typeof useFileContext>['context']
|
context: ReturnType<typeof useFileContext>['context']
|
||||||
@ -265,7 +268,7 @@ export function ToastTextToCadSuccess({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
toast.dismiss()
|
toast.dismiss(toastId)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{hasCopied ? 'Close' : 'Reject'}
|
{hasCopied ? 'Close' : 'Reject'}
|
||||||
@ -284,7 +287,7 @@ export function ToastTextToCadSuccess({
|
|||||||
`${context.project.path}${sep()}${data.fileName}`
|
`${context.project.path}${sep()}${data.fileName}`
|
||||||
)}`
|
)}`
|
||||||
)
|
)
|
||||||
toast.dismiss()
|
toast.dismiss(toastId)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Accept
|
Accept
|
||||||
|
@ -91,6 +91,7 @@ export async function submitAndAwaitTextToKcl({
|
|||||||
toast.error(
|
toast.error(
|
||||||
() =>
|
() =>
|
||||||
ToastTextToCadError({
|
ToastTextToCadError({
|
||||||
|
toastId,
|
||||||
message,
|
message,
|
||||||
commandBarSend,
|
commandBarSend,
|
||||||
prompt: trimmedPrompt,
|
prompt: trimmedPrompt,
|
||||||
@ -214,6 +215,7 @@ export async function submitAndAwaitTextToKcl({
|
|||||||
toast.success(
|
toast.success(
|
||||||
() =>
|
() =>
|
||||||
ToastTextToCadSuccess({
|
ToastTextToCadSuccess({
|
||||||
|
toastId,
|
||||||
data: textToCadOutputCreated,
|
data: textToCadOutputCreated,
|
||||||
token,
|
token,
|
||||||
navigate,
|
navigate,
|
||||||
|
@ -287,7 +287,6 @@ export const modelingMachineDefaultContext = {
|
|||||||
streamDimensions: { streamWidth: 1280, streamHeight: 720 },
|
streamDimensions: { streamWidth: 1280, streamHeight: 720 },
|
||||||
openPanes: getPersistedContext().openPanes || ['code'],
|
openPanes: getPersistedContext().openPanes || ['code'],
|
||||||
} as Store,
|
} as Store,
|
||||||
pendingTextToCad: undefined as string | undefined,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const modelingMachine = createMachine(
|
export const modelingMachine = createMachine(
|
||||||
@ -354,12 +353,7 @@ export const modelingMachine = createMachine(
|
|||||||
'Text-to-CAD': {
|
'Text-to-CAD': {
|
||||||
target: 'idle',
|
target: 'idle',
|
||||||
internal: true,
|
internal: true,
|
||||||
actions: [
|
actions: ['Submit to Text-to-CAD API'],
|
||||||
'Add pending text-to-cad prompt',
|
|
||||||
'Submit to Text-to-CAD API',
|
|
||||||
'Remove pending text-to-cad prompt',
|
|
||||||
],
|
|
||||||
cond: 'Has no pending text-to-cad submissions',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user