| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  | import { test, expect, Page } from '@playwright/test' | 
					
						
							| 
									
										
										
										
											2024-10-28 16:18:06 -04:00
										 |  |  | import { | 
					
						
							|  |  |  |   getUtils, | 
					
						
							|  |  |  |   setup, | 
					
						
							|  |  |  |   tearDown, | 
					
						
							|  |  |  |   setupElectron, | 
					
						
							|  |  |  |   createProject, | 
					
						
							|  |  |  | } from './test-utils' | 
					
						
							| 
									
										
										
										
											2024-08-27 16:36:05 +10:00
										 |  |  | import { join } from 'path' | 
					
						
							|  |  |  | import fs from 'fs' | 
					
						
							| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | test.beforeEach(async ({ context, page }) => { | 
					
						
							|  |  |  |   await setup(context, page) | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | test.afterEach(async ({ page }, testInfo) => { | 
					
						
							|  |  |  |   await tearDown(page, testInfo) | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-16 18:06:20 -04:00
										 |  |  | test.describe('Text-to-CAD tests', () => { | 
					
						
							| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  |   test('basic lego happy case', async ({ page }) => { | 
					
						
							|  |  |  |     const u = await getUtils(page) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-16 18:06:20 -04:00
										 |  |  |     await test.step('Set up', async () => { | 
					
						
							|  |  |  |       await page.setViewportSize({ width: 1000, height: 500 }) | 
					
						
							|  |  |  |       await u.waitForAuthSkipAppStart() | 
					
						
							|  |  |  |     }) | 
					
						
							| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     await sendPromptFromCommandBar(page, 'a 2x4 lego') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Find the toast.
 | 
					
						
							|  |  |  |     // Look out for the toast message
 | 
					
						
							|  |  |  |     const submittingToastMessage = page.getByText( | 
					
						
							|  |  |  |       `Submitting to Text-to-CAD API...` | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     await expect(submittingToastMessage).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const generatingToastMessage = page.getByText( | 
					
						
							|  |  |  |       `Generating parametric model...` | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2024-08-19 09:38:47 -04:00
										 |  |  |     await expect(generatingToastMessage).toBeVisible({ timeout: 10000 }) | 
					
						
							| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     const successToastMessage = page.getByText(`Text-to-CAD successful`) | 
					
						
							| 
									
										
										
										
											2024-08-19 09:38:47 -04:00
										 |  |  |     await expect(successToastMessage).toBeVisible({ timeout: 15000 }) | 
					
						
							| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     await expect(page.getByText('Copied')).not.toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Hit copy to clipboard.
 | 
					
						
							|  |  |  |     const copyToClipboardButton = page.getByRole('button', { | 
					
						
							|  |  |  |       name: 'Copy to clipboard', | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     await expect(copyToClipboardButton).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Paste the code.
 | 
					
						
							| 
									
										
										
										
											2024-08-16 18:06:20 -04:00
										 |  |  |     await page.keyboard.press('ControlOrMeta+KeyV') | 
					
						
							| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Expect the code to be pasted.
 | 
					
						
							|  |  |  |     await expect(page.locator('.cm-content')).toContainText(`const`) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // make sure a model renders.
 | 
					
						
							|  |  |  |     // wait for execution done
 | 
					
						
							|  |  |  |     await u.openDebugPanel() | 
					
						
							|  |  |  |     await u.expectCmdLog('[data-message-type="execution-done"]') | 
					
						
							|  |  |  |     await u.closeDebugPanel() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Find the toast close button.
 | 
					
						
							| 
									
										
										
										
											2024-08-16 18:06:20 -04:00
										 |  |  |     const closeButton = page | 
					
						
							|  |  |  |       .getByRole('status') | 
					
						
							|  |  |  |       .locator('div') | 
					
						
							|  |  |  |       .filter({ hasText: 'Text-to-CAD successfulPrompt' }) | 
					
						
							|  |  |  |       .first() | 
					
						
							|  |  |  |       .getByRole('button', { name: 'Close' }) | 
					
						
							| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  |     await expect(closeButton).toBeVisible() | 
					
						
							|  |  |  |     await closeButton.click() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // The toast should disappear.
 | 
					
						
							|  |  |  |     await expect(successToastMessage).not.toBeVisible() | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-14 21:39:55 -07:00
										 |  |  |   test('success model, then ignore success toast, user can create new prompt from command bar', async ({ | 
					
						
							|  |  |  |     page, | 
					
						
							|  |  |  |   }) => { | 
					
						
							|  |  |  |     const u = await getUtils(page) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await page.setViewportSize({ width: 1000, height: 500 }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await u.waitForAuthSkipAppStart() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await sendPromptFromCommandBar(page, 'a 2x6 lego') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Find the toast.
 | 
					
						
							|  |  |  |     // Look out for the toast message
 | 
					
						
							|  |  |  |     const submittingToastMessage = page.getByText( | 
					
						
							|  |  |  |       `Submitting to Text-to-CAD API...` | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     await expect(submittingToastMessage).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const generatingToastMessage = page.getByText( | 
					
						
							|  |  |  |       `Generating parametric model...` | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2024-08-19 09:38:47 -04:00
										 |  |  |     await expect(generatingToastMessage).toBeVisible({ timeout: 10000 }) | 
					
						
							| 
									
										
										
										
											2024-08-14 21:39:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     const successToastMessage = page.getByText(`Text-to-CAD successful`) | 
					
						
							| 
									
										
										
										
											2024-08-19 09:38:47 -04:00
										 |  |  |     await expect(successToastMessage).toBeVisible({ timeout: 15000 }) | 
					
						
							| 
									
										
										
										
											2024-08-14 21:39:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     await expect(page.getByText('Copied')).not.toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await expect(successToastMessage).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Can send a new prompt from the command bar.
 | 
					
						
							|  |  |  |     await sendPromptFromCommandBar(page, 'a 2x4 lego') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Find the toast.
 | 
					
						
							|  |  |  |     // Look out for the toast message
 | 
					
						
							|  |  |  |     await expect(submittingToastMessage).toBeVisible() | 
					
						
							| 
									
										
										
										
											2024-08-19 09:38:47 -04:00
										 |  |  |     await expect(generatingToastMessage).toBeVisible({ timeout: 10000 }) | 
					
						
							| 
									
										
										
										
											2024-08-14 21:39:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Expect 2 success toasts.
 | 
					
						
							| 
									
										
										
										
											2024-08-19 09:38:47 -04:00
										 |  |  |     await expect(successToastMessage).toHaveCount(2, { | 
					
						
							|  |  |  |       timeout: 15000, | 
					
						
							|  |  |  |     }) | 
					
						
							| 
									
										
										
										
											2024-08-14 21:39:55 -07:00
										 |  |  |     await expect(page.getByText('a 2x4 lego')).toBeVisible() | 
					
						
							|  |  |  |     await expect(page.getByText('a 2x6 lego')).toBeVisible() | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  |   test('you can reject text-to-cad output and it does nothing', async ({ | 
					
						
							|  |  |  |     page, | 
					
						
							|  |  |  |   }) => { | 
					
						
							|  |  |  |     const u = await getUtils(page) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await page.setViewportSize({ width: 1000, height: 500 }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await u.waitForAuthSkipAppStart() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await sendPromptFromCommandBar(page, 'a 2x4 lego') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Find the toast.
 | 
					
						
							|  |  |  |     // Look out for the toast message
 | 
					
						
							|  |  |  |     const submittingToastMessage = page.getByText( | 
					
						
							|  |  |  |       `Submitting to Text-to-CAD API...` | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     await expect(submittingToastMessage).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const generatingToastMessage = page.getByText( | 
					
						
							|  |  |  |       `Generating parametric model...` | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2024-08-19 09:38:47 -04:00
										 |  |  |     await expect(generatingToastMessage).toBeVisible({ timeout: 10000 }) | 
					
						
							| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     const successToastMessage = page.getByText(`Text-to-CAD successful`) | 
					
						
							| 
									
										
										
										
											2024-08-19 09:38:47 -04:00
										 |  |  |     await expect(successToastMessage).toBeVisible({ timeout: 15000 }) | 
					
						
							| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Hit copy to clipboard.
 | 
					
						
							|  |  |  |     const rejectButton = page.getByRole('button', { name: 'Reject' }) | 
					
						
							|  |  |  |     await expect(rejectButton).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await rejectButton.click() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // The toast should disappear.
 | 
					
						
							|  |  |  |     await expect(successToastMessage).not.toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Expect no code.
 | 
					
						
							|  |  |  |     await expect(page.locator('.cm-content')).toContainText(``) | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   test('sending a bad prompt fails, can dismiss', async ({ page }) => { | 
					
						
							|  |  |  |     const u = await getUtils(page) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await page.setViewportSize({ width: 1000, height: 500 }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await u.waitForAuthSkipAppStart() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const commandBarButton = page.getByRole('button', { name: 'Commands' }) | 
					
						
							|  |  |  |     await expect(commandBarButton).toBeVisible() | 
					
						
							|  |  |  |     // Click the command bar button
 | 
					
						
							|  |  |  |     await commandBarButton.click() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Wait for the command bar to appear
 | 
					
						
							|  |  |  |     const cmdSearchBar = page.getByPlaceholder('Search commands') | 
					
						
							|  |  |  |     await expect(cmdSearchBar).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const textToCadCommand = page.getByText('Text-to-CAD') | 
					
						
							|  |  |  |     await expect(textToCadCommand.first()).toBeVisible() | 
					
						
							|  |  |  |     // Click the Text-to-CAD command
 | 
					
						
							|  |  |  |     await textToCadCommand.first().click() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Enter the prompt.
 | 
					
						
							|  |  |  |     const prompt = page.getByText('Prompt') | 
					
						
							|  |  |  |     await expect(prompt.first()).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Type the prompt.
 | 
					
						
							| 
									
										
										
										
											2024-08-20 22:16:44 -04:00
										 |  |  |     const randomPrompt = `aslkdfja;` + Date.now() + `FFFFEIWJF` | 
					
						
							|  |  |  |     await page.keyboard.type(randomPrompt) | 
					
						
							| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  |     await page.waitForTimeout(1000) | 
					
						
							|  |  |  |     await page.keyboard.press('Enter') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Find the toast.
 | 
					
						
							|  |  |  |     // Look out for the toast message
 | 
					
						
							|  |  |  |     const submittingToastMessage = page.getByText( | 
					
						
							|  |  |  |       `Submitting to Text-to-CAD API...` | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     await expect(submittingToastMessage).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const generatingToastMessage = page.getByText( | 
					
						
							|  |  |  |       `Generating parametric model...` | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     await expect(generatingToastMessage).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const failureToastMessage = page.getByText( | 
					
						
							|  |  |  |       `The prompt must clearly describe a CAD model` | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     await expect(failureToastMessage).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await page.waitForTimeout(1000) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Make sure the toast did not say it was successful.
 | 
					
						
							|  |  |  |     const successToastMessage = page.getByText(`Text-to-CAD successful`) | 
					
						
							|  |  |  |     await expect(successToastMessage).not.toBeVisible() | 
					
						
							|  |  |  |     await expect(page.getByText(`Text-to-CAD failed`)).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Find the toast dismiss button.
 | 
					
						
							|  |  |  |     const dismissButton = page.getByRole('button', { name: 'Dismiss' }) | 
					
						
							|  |  |  |     await expect(dismissButton).toBeVisible() | 
					
						
							|  |  |  |     await dismissButton.click() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // The toast should disappear.
 | 
					
						
							|  |  |  |     await expect(failureToastMessage).not.toBeVisible() | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-14 21:39:55 -07:00
										 |  |  |   test('sending a bad prompt fails, can start over from toast', async ({ | 
					
						
							|  |  |  |     page, | 
					
						
							|  |  |  |   }) => { | 
					
						
							| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  |     const u = await getUtils(page) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await page.setViewportSize({ width: 1000, height: 500 }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await u.waitForAuthSkipAppStart() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const commandBarButton = page.getByRole('button', { name: 'Commands' }) | 
					
						
							|  |  |  |     await expect(commandBarButton).toBeVisible() | 
					
						
							|  |  |  |     // Click the command bar button
 | 
					
						
							|  |  |  |     await commandBarButton.click() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Wait for the command bar to appear
 | 
					
						
							|  |  |  |     const cmdSearchBar = page.getByPlaceholder('Search commands') | 
					
						
							|  |  |  |     await expect(cmdSearchBar).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const textToCadCommand = page.getByText('Text-to-CAD') | 
					
						
							|  |  |  |     await expect(textToCadCommand.first()).toBeVisible() | 
					
						
							|  |  |  |     // Click the Text-to-CAD command
 | 
					
						
							|  |  |  |     await textToCadCommand.first().click() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Enter the prompt.
 | 
					
						
							|  |  |  |     const prompt = page.getByText('Prompt') | 
					
						
							|  |  |  |     await expect(prompt.first()).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-16 18:06:20 -04:00
										 |  |  |     const badPrompt = 'akjsndladf lajbhflauweyfaaaljhr472iouafyvsssssss' | 
					
						
							| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Type the prompt.
 | 
					
						
							|  |  |  |     await page.keyboard.type(badPrompt) | 
					
						
							|  |  |  |     await page.waitForTimeout(1000) | 
					
						
							|  |  |  |     await page.keyboard.press('Enter') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Find the toast.
 | 
					
						
							|  |  |  |     // Look out for the toast message
 | 
					
						
							|  |  |  |     const submittingToastMessage = page.getByText( | 
					
						
							|  |  |  |       `Submitting to Text-to-CAD API...` | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     await expect(submittingToastMessage).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const generatingToastMessage = page.getByText( | 
					
						
							|  |  |  |       `Generating parametric model...` | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     await expect(generatingToastMessage).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const failureToastMessage = page.getByText( | 
					
						
							|  |  |  |       `The prompt must clearly describe a CAD model` | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     await expect(failureToastMessage).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await page.waitForTimeout(1000) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Make sure the toast did not say it was successful.
 | 
					
						
							|  |  |  |     const successToastMessage = page.getByText(`Text-to-CAD successful`) | 
					
						
							|  |  |  |     await expect(successToastMessage).not.toBeVisible() | 
					
						
							|  |  |  |     await expect(page.getByText(`Text-to-CAD failed`)).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Click the edit prompt button to try again.
 | 
					
						
							|  |  |  |     const editPromptButton = page.getByRole('button', { name: 'Edit prompt' }) | 
					
						
							|  |  |  |     await expect(editPromptButton).toBeVisible() | 
					
						
							|  |  |  |     await editPromptButton.click() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // The toast should disappear.
 | 
					
						
							|  |  |  |     await expect(failureToastMessage).not.toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Make sure the old prompt is still there and can be edited.
 | 
					
						
							|  |  |  |     await expect(page.locator('textarea')).toContainText(badPrompt) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Select all and start a new prompt.
 | 
					
						
							| 
									
										
										
										
											2024-08-22 19:13:27 -04:00
										 |  |  |     await page.keyboard.down('ControlOrMeta') | 
					
						
							| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  |     await page.keyboard.press('KeyA') | 
					
						
							| 
									
										
										
										
											2024-08-22 19:13:27 -04:00
										 |  |  |     await page.keyboard.up('ControlOrMeta') | 
					
						
							| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  |     await page.keyboard.type('a 2x4 lego') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Submit the new prompt.
 | 
					
						
							|  |  |  |     await page.keyboard.press('Enter') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Make sure the new prompt works.
 | 
					
						
							|  |  |  |     // Find the toast.
 | 
					
						
							|  |  |  |     // Look out for the toast message
 | 
					
						
							|  |  |  |     await expect(submittingToastMessage).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-19 09:38:47 -04:00
										 |  |  |     await expect(generatingToastMessage).toBeVisible({ timeout: 10000 }) | 
					
						
							| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-19 09:38:47 -04:00
										 |  |  |     await expect(successToastMessage).toBeVisible({ timeout: 15000 }) | 
					
						
							| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-14 21:39:55 -07:00
										 |  |  |   test('sending a bad prompt fails, can ignore toast, can start over from command bar', async ({ | 
					
						
							|  |  |  |     page, | 
					
						
							|  |  |  |   }) => { | 
					
						
							|  |  |  |     const u = await getUtils(page) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await page.setViewportSize({ width: 1000, height: 500 }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await u.waitForAuthSkipAppStart() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const commandBarButton = page.getByRole('button', { name: 'Commands' }) | 
					
						
							|  |  |  |     await expect(commandBarButton).toBeVisible() | 
					
						
							|  |  |  |     // Click the command bar button
 | 
					
						
							|  |  |  |     await commandBarButton.click() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Wait for the command bar to appear
 | 
					
						
							|  |  |  |     const cmdSearchBar = page.getByPlaceholder('Search commands') | 
					
						
							|  |  |  |     await expect(cmdSearchBar).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const textToCadCommand = page.getByText('Text-to-CAD') | 
					
						
							|  |  |  |     await expect(textToCadCommand.first()).toBeVisible() | 
					
						
							|  |  |  |     // Click the Text-to-CAD command
 | 
					
						
							|  |  |  |     await textToCadCommand.first().click() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Enter the prompt.
 | 
					
						
							|  |  |  |     const prompt = page.getByText('Prompt') | 
					
						
							|  |  |  |     await expect(prompt.first()).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-19 08:08:07 -04:00
										 |  |  |     const badPrompt = 'akjsndladflajbhflauweyf15;' | 
					
						
							| 
									
										
										
										
											2024-08-14 21:39:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Type the prompt.
 | 
					
						
							|  |  |  |     await page.keyboard.type(badPrompt) | 
					
						
							|  |  |  |     await page.waitForTimeout(1000) | 
					
						
							|  |  |  |     await page.keyboard.press('Enter') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Find the toast.
 | 
					
						
							|  |  |  |     // Look out for the toast message
 | 
					
						
							|  |  |  |     const submittingToastMessage = page.getByText( | 
					
						
							|  |  |  |       `Submitting to Text-to-CAD API...` | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     await expect(submittingToastMessage).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const generatingToastMessage = page.getByText( | 
					
						
							|  |  |  |       `Generating parametric model...` | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     await expect(generatingToastMessage).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const failureToastMessage = page.getByText( | 
					
						
							|  |  |  |       `The prompt must clearly describe a CAD model` | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     await expect(failureToastMessage).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await page.waitForTimeout(1000) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Make sure the toast did not say it was successful.
 | 
					
						
							|  |  |  |     const successToastMessage = page.getByText(`Text-to-CAD successful`) | 
					
						
							|  |  |  |     await expect(successToastMessage).not.toBeVisible() | 
					
						
							|  |  |  |     await expect(page.getByText(`Text-to-CAD failed`)).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // They should be able to try again from the command bar.
 | 
					
						
							|  |  |  |     await sendPromptFromCommandBar(page, 'a 2x4 lego') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Find the toast.
 | 
					
						
							|  |  |  |     // Look out for the toast message
 | 
					
						
							|  |  |  |     await expect(submittingToastMessage).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-19 09:38:47 -04:00
										 |  |  |     await expect(generatingToastMessage).toBeVisible({ timeout: 10000 }) | 
					
						
							| 
									
										
										
										
											2024-08-14 21:39:55 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-19 09:38:47 -04:00
										 |  |  |     await expect(successToastMessage).toBeVisible({ timeout: 15000 }) | 
					
						
							| 
									
										
										
										
											2024-08-14 21:39:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     await expect(page.getByText('Copied')).not.toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // old failure toast should stick around.
 | 
					
						
							|  |  |  |     await expect(failureToastMessage).toBeVisible() | 
					
						
							|  |  |  |     await expect(page.getByText(`Text-to-CAD failed`)).toBeVisible() | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  |   test('ensure you can shift+enter in the prompt box', async ({ page }) => { | 
					
						
							|  |  |  |     const u = await getUtils(page) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await page.setViewportSize({ width: 1000, height: 500 }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await u.waitForAuthSkipAppStart() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const promptWithNewline = `a 2x4\nlego` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const commandBarButton = page.getByRole('button', { name: 'Commands' }) | 
					
						
							|  |  |  |     await expect(commandBarButton).toBeVisible() | 
					
						
							|  |  |  |     // Click the command bar button
 | 
					
						
							|  |  |  |     await commandBarButton.click() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Wait for the command bar to appear
 | 
					
						
							|  |  |  |     const cmdSearchBar = page.getByPlaceholder('Search commands') | 
					
						
							|  |  |  |     await expect(cmdSearchBar).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const textToCadCommand = page.getByText('Text-to-CAD') | 
					
						
							|  |  |  |     await expect(textToCadCommand.first()).toBeVisible() | 
					
						
							|  |  |  |     // Click the Text-to-CAD command
 | 
					
						
							|  |  |  |     await textToCadCommand.first().click() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Enter the prompt.
 | 
					
						
							|  |  |  |     const prompt = page.getByText('Prompt') | 
					
						
							|  |  |  |     await expect(prompt.first()).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Type the prompt.
 | 
					
						
							|  |  |  |     await page.keyboard.type('a 2x4') | 
					
						
							|  |  |  |     await page.waitForTimeout(1000) | 
					
						
							|  |  |  |     await page.keyboard.down('Shift') | 
					
						
							|  |  |  |     await page.keyboard.press('Enter') | 
					
						
							|  |  |  |     await page.keyboard.up('Shift') | 
					
						
							|  |  |  |     await page.keyboard.type('lego') | 
					
						
							|  |  |  |     await page.waitForTimeout(1000) | 
					
						
							|  |  |  |     await page.keyboard.press('Enter') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Find the toast.
 | 
					
						
							|  |  |  |     // Look out for the toast message
 | 
					
						
							|  |  |  |     const submittingToastMessage = page.getByText( | 
					
						
							|  |  |  |       `Submitting to Text-to-CAD API...` | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     await expect(submittingToastMessage).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const generatingToastMessage = page.getByText( | 
					
						
							|  |  |  |       `Generating parametric model...` | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2024-08-19 09:38:47 -04:00
										 |  |  |     await expect(generatingToastMessage).toBeVisible({ timeout: 10000 }) | 
					
						
							| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     const successToastMessage = page.getByText(`Text-to-CAD successful`) | 
					
						
							| 
									
										
										
										
											2024-08-19 09:38:47 -04:00
										 |  |  |     await expect(successToastMessage).toBeVisible({ timeout: 15000 }) | 
					
						
							| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     await expect(page.getByText(promptWithNewline)).toBeVisible() | 
					
						
							|  |  |  |   }) | 
					
						
							| 
									
										
										
										
											2024-08-14 23:08:37 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-02 11:58:17 -04:00
										 |  |  |   test( | 
					
						
							|  |  |  |     'can do many at once and get many prompts back, and interact with many', | 
					
						
							|  |  |  |     { tag: ['@skipWin'] }, | 
					
						
							|  |  |  |     async ({ page }) => { | 
					
						
							|  |  |  |       // Let this test run longer since we've seen it timeout.
 | 
					
						
							|  |  |  |       test.setTimeout(180_000) | 
					
						
							|  |  |  |       // skip on windows
 | 
					
						
							|  |  |  |       test.skip( | 
					
						
							|  |  |  |         process.platform === 'win32', | 
					
						
							|  |  |  |         'This test is flaky, skipping for now' | 
					
						
							|  |  |  |       ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const u = await getUtils(page) | 
					
						
							| 
									
										
										
										
											2024-08-14 23:08:37 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-02 11:58:17 -04:00
										 |  |  |       await page.setViewportSize({ width: 1000, height: 500 }) | 
					
						
							| 
									
										
										
										
											2024-08-14 23:08:37 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-02 11:58:17 -04:00
										 |  |  |       await u.waitForAuthSkipAppStart() | 
					
						
							| 
									
										
										
										
											2024-08-14 23:08:37 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-02 11:58:17 -04:00
										 |  |  |       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: 10_000, | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const successToastMessage = page.getByText(`Text-to-CAD successful`) | 
					
						
							|  |  |  |       // We should have three success toasts.
 | 
					
						
							|  |  |  |       await expect(successToastMessage).toHaveCount(3, { timeout: 25_000 }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       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.
 | 
					
						
							|  |  |  |       await 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('ControlOrMeta') | 
					
						
							|  |  |  |       await page.keyboard.press('KeyV') | 
					
						
							|  |  |  |       await page.keyboard.up('ControlOrMeta') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // Expect the code to be pasted.
 | 
					
						
							|  |  |  |       await expect(page.locator('.cm-content')).toContainText(`2x8`) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // Find the toast close button.
 | 
					
						
							|  |  |  |       const closeButton = page.locator('[data-negative-button="close"]').first() | 
					
						
							|  |  |  |       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(`Prompt: "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('ControlOrMeta') | 
					
						
							|  |  |  |       await page.keyboard.press('KeyA') | 
					
						
							|  |  |  |       await page.keyboard.up('ControlOrMeta') | 
					
						
							|  |  |  |       await page.keyboard.press('Backspace') | 
					
						
							|  |  |  |       await page.keyboard.down('ControlOrMeta') | 
					
						
							|  |  |  |       await page.keyboard.press('KeyV') | 
					
						
							|  |  |  |       await page.keyboard.up('ControlOrMeta') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // 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(successToastMessage).not.toBeVisible() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   ) | 
					
						
							| 
									
										
										
										
											2024-08-14 23:08:37 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   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') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-16 18:06:20 -04:00
										 |  |  |     await sendPromptFromCommandBar(page, 'alkjsdnlajshdbfjlhsbdf a;askjdnf') | 
					
						
							| 
									
										
										
										
											2024-08-14 23:08:37 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // 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.
 | 
					
						
							| 
									
										
										
										
											2024-08-15 14:24:27 -04:00
										 |  |  |     await dismissButton.first().click() | 
					
						
							| 
									
										
										
										
											2024-08-14 23:08:37 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // 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.
 | 
					
						
							| 
									
										
										
										
											2024-08-22 19:13:27 -04:00
										 |  |  |     await page.keyboard.down('ControlOrMeta') | 
					
						
							| 
									
										
										
										
											2024-08-14 23:08:37 -07:00
										 |  |  |     await page.keyboard.press('KeyV') | 
					
						
							| 
									
										
										
										
											2024-08-22 19:13:27 -04:00
										 |  |  |     await page.keyboard.up('ControlOrMeta') | 
					
						
							| 
									
										
										
										
											2024-08-14 23:08:37 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Expect the code to be pasted.
 | 
					
						
							|  |  |  |     await expect(page.locator('.cm-content')).toContainText(`2x4`) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Find the toast close button.
 | 
					
						
							| 
									
										
										
										
											2024-08-16 18:06:20 -04:00
										 |  |  |     const closeButton = page | 
					
						
							|  |  |  |       .getByRole('status') | 
					
						
							|  |  |  |       .locator('div') | 
					
						
							|  |  |  |       .filter({ hasText: 'Text-to-CAD successfulPrompt' }) | 
					
						
							|  |  |  |       .first() | 
					
						
							|  |  |  |       .getByRole('button', { name: 'Close' }) | 
					
						
							| 
									
										
										
										
											2024-08-14 23:08:37 -07:00
										 |  |  |     await expect(closeButton).toBeVisible() | 
					
						
							|  |  |  |     await closeButton.click() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Expect the toast to disappear.
 | 
					
						
							|  |  |  |     await expect(page.getByText('Copied')).not.toBeVisible() | 
					
						
							|  |  |  |     await expect(successToastMessage).not.toBeVisible() | 
					
						
							|  |  |  |   }) | 
					
						
							| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | async function sendPromptFromCommandBar(page: Page, promptStr: string) { | 
					
						
							| 
									
										
										
										
											2024-08-16 18:06:20 -04:00
										 |  |  |   await test.step(`Send prompt from command bar: ${promptStr}`, async () => { | 
					
						
							|  |  |  |     const commandBarButton = page.getByRole('button', { name: 'Commands' }) | 
					
						
							|  |  |  |     await expect(commandBarButton).toBeVisible() | 
					
						
							|  |  |  |     // Click the command bar button
 | 
					
						
							|  |  |  |     await commandBarButton.click() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Wait for the command bar to appear
 | 
					
						
							|  |  |  |     const cmdSearchBar = page.getByPlaceholder('Search commands') | 
					
						
							|  |  |  |     await expect(cmdSearchBar).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const textToCadCommand = page.getByText('Use the Zoo Text-to-CAD API ') | 
					
						
							|  |  |  |     await expect(textToCadCommand.first()).toBeVisible() | 
					
						
							|  |  |  |     // Click the Text-to-CAD command
 | 
					
						
							|  |  |  |     await textToCadCommand.first().click() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Enter the prompt.
 | 
					
						
							|  |  |  |     const prompt = page.getByText('Prompt') | 
					
						
							|  |  |  |     await expect(prompt.first()).toBeVisible() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Type the prompt.
 | 
					
						
							|  |  |  |     await page.keyboard.type(promptStr) | 
					
						
							| 
									
										
										
										
											2024-08-19 22:38:17 +10:00
										 |  |  |     await page.waitForTimeout(200) | 
					
						
							| 
									
										
										
										
											2024-08-16 18:06:20 -04:00
										 |  |  |     await page.keyboard.press('Enter') | 
					
						
							|  |  |  |   }) | 
					
						
							| 
									
										
										
										
											2024-08-14 14:26:44 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2024-08-24 17:31:27 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | test( | 
					
						
							|  |  |  |   'Text-to-CAD functionality', | 
					
						
							|  |  |  |   { tag: '@electron' }, | 
					
						
							|  |  |  |   async ({ browserName }, testInfo) => { | 
					
						
							| 
									
										
										
										
											2024-09-06 17:14:02 -04:00
										 |  |  |     const projectName = 'project-000' | 
					
						
							|  |  |  |     const prompt = 'lego 2x4' | 
					
						
							|  |  |  |     const textToCadFileName = 'lego-2x4.kcl' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-27 16:36:05 +10:00
										 |  |  |     const { electronApp, page, dir } = await setupElectron({ testInfo }) | 
					
						
							|  |  |  |     const fileExists = () => | 
					
						
							| 
									
										
										
										
											2024-09-06 17:14:02 -04:00
										 |  |  |       fs.existsSync(join(dir, projectName, textToCadFileName)) | 
					
						
							| 
									
										
										
										
											2024-08-28 06:38:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-28 16:18:06 -04:00
										 |  |  |     const { openFilePanel, openKclCodePanel, waitForPageLoad } = await getUtils( | 
					
						
							|  |  |  |       page, | 
					
						
							|  |  |  |       test | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2024-08-24 17:31:27 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     await page.setViewportSize({ width: 1200, height: 500 }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-06 17:14:02 -04:00
										 |  |  |     // Locators
 | 
					
						
							| 
									
										
										
										
											2024-10-28 14:29:47 -04:00
										 |  |  |     const projectMenuButton = page | 
					
						
							|  |  |  |       .getByTestId('project-sidebar-toggle') | 
					
						
							|  |  |  |       .filter({ hasText: projectName }) | 
					
						
							| 
									
										
										
										
											2024-09-06 17:14:02 -04:00
										 |  |  |     const textToCadFileButton = page.getByRole('listitem').filter({ | 
					
						
							|  |  |  |       has: page.getByRole('button', { name: textToCadFileName }), | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     const textToCadComment = page.getByText( | 
					
						
							|  |  |  |       `// Generated by Text-to-CAD: ${prompt}` | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2024-08-28 06:38:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-24 17:31:27 -05:00
										 |  |  |     // Create and navigate to the project
 | 
					
						
							| 
									
										
										
										
											2024-10-28 16:18:06 -04:00
										 |  |  |     await createProject({ name: 'project-000', page }) | 
					
						
							| 
									
										
										
										
											2024-08-24 17:31:27 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Wait for Start Sketch otherwise you will not have access Text-to-CAD command
 | 
					
						
							| 
									
										
										
										
											2024-09-06 17:14:02 -04:00
										 |  |  |     await waitForPageLoad() | 
					
						
							|  |  |  |     await openFilePanel() | 
					
						
							|  |  |  |     await openKclCodePanel() | 
					
						
							| 
									
										
										
										
											2024-08-24 17:31:27 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     await test.step(`Test file creation`, async () => { | 
					
						
							| 
									
										
										
										
											2024-09-06 17:14:02 -04:00
										 |  |  |       await sendPromptFromCommandBar(page, prompt) | 
					
						
							| 
									
										
										
										
											2024-08-24 17:31:27 -05:00
										 |  |  |       // File is considered created if it shows up in the Project Files pane
 | 
					
						
							| 
									
										
										
										
											2024-09-06 17:14:02 -04:00
										 |  |  |       await expect(textToCadFileButton).toBeVisible({ timeout: 20_000 }) | 
					
						
							| 
									
										
										
										
											2024-08-27 16:36:05 +10:00
										 |  |  |       expect(fileExists()).toBeTruthy() | 
					
						
							| 
									
										
										
										
											2024-08-24 17:31:27 -05:00
										 |  |  |     }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await test.step(`Test file navigation`, async () => { | 
					
						
							| 
									
										
										
										
											2024-09-06 17:14:02 -04:00
										 |  |  |       await expect(projectMenuButton).toContainText('main.kcl') | 
					
						
							|  |  |  |       await textToCadFileButton.click() | 
					
						
							| 
									
										
										
										
											2024-08-24 17:31:27 -05:00
										 |  |  |       // File can be navigated and loaded assuming a specific KCL comment is loaded into the KCL code pane
 | 
					
						
							| 
									
										
										
										
											2024-09-06 17:14:02 -04:00
										 |  |  |       await expect(textToCadComment).toBeVisible({ timeout: 20_000 }) | 
					
						
							|  |  |  |       await expect(projectMenuButton).toContainText(textToCadFileName) | 
					
						
							| 
									
										
										
										
											2024-08-24 17:31:27 -05:00
										 |  |  |     }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await test.step(`Test file deletion on rejection`, async () => { | 
					
						
							|  |  |  |       const rejectButton = page.getByRole('button', { name: 'Reject' }) | 
					
						
							|  |  |  |       // A file is created and can be navigated to while this prompt is still opened
 | 
					
						
							|  |  |  |       // Click the "Reject" button within the prompt and it will delete the file.
 | 
					
						
							|  |  |  |       await rejectButton.click() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const submittingToastMessage = page.getByText( | 
					
						
							|  |  |  |         `Successfully deleted file "lego-2x4.kcl"` | 
					
						
							|  |  |  |       ) | 
					
						
							|  |  |  |       await expect(submittingToastMessage).toBeVisible() | 
					
						
							| 
									
										
										
										
											2024-08-27 16:36:05 +10:00
										 |  |  |       expect(fileExists()).toBeFalsy() | 
					
						
							| 
									
										
										
										
											2024-09-06 17:14:02 -04:00
										 |  |  |       // Confirm we've navigated back to the main.kcl file after deletion
 | 
					
						
							|  |  |  |       await expect(projectMenuButton).toContainText('main.kcl') | 
					
						
							| 
									
										
										
										
											2024-08-24 17:31:27 -05:00
										 |  |  |     }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await electronApp.close() | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | ) |