diff --git a/e2e/playwright/sketch-tests.spec.ts b/e2e/playwright/sketch-tests.spec.ts index d412d03d0..1b90cbad0 100644 --- a/e2e/playwright/sketch-tests.spec.ts +++ b/e2e/playwright/sketch-tests.spec.ts @@ -346,6 +346,92 @@ test.describe('Sketch tests', () => { }) }) + test('Can edit a circle center and radius by dragging its handles', async ({ + page, + }) => { + const u = await getUtils(page) + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `const sketch001 = startSketchOn('XZ') + |> circle({ center: [4.61, -5.01], radius: 8 }, %)` + ) + }) + + await page.setViewportSize({ width: 1200, height: 500 }) + + await u.waitForAuthSkipAppStart() + await expect( + page.getByRole('button', { name: 'Start Sketch' }) + ).not.toBeDisabled() + + await page.waitForTimeout(100) + await u.openAndClearDebugPanel() + await u.sendCustomCmd({ + type: 'modeling_cmd_req', + cmd_id: uuidv4(), + cmd: { + type: 'default_camera_look_at', + vantage: { x: 0, y: -1250, z: 580 }, + center: { x: 0, y: 0, z: 0 }, + up: { x: 0, y: 0, z: 1 }, + }, + }) + await page.waitForTimeout(100) + await u.sendCustomCmd({ + type: 'modeling_cmd_req', + cmd_id: uuidv4(), + cmd: { + type: 'default_camera_get_settings', + }, + }) + await page.waitForTimeout(100) + + const startPX = [667, 325] + + const dragPX = 40 + + await page + .getByText('circle({ center: [4.61, -5.01], radius: 8 }, %)') + .click() + await expect( + page.getByRole('button', { name: 'Edit Sketch' }) + ).toBeVisible() + await page.getByRole('button', { name: 'Edit Sketch' }).click() + await page.waitForTimeout(400) + let prevContent = await page.locator('.cm-content').innerText() + + await expect(page.getByTestId('segment-overlay')).toHaveCount(1) + + await test.step('drag circle center handle', async () => { + await page.dragAndDrop('#stream', '#stream', { + sourcePosition: { x: startPX[0], y: startPX[1] }, + targetPosition: { x: startPX[0] + dragPX, y: startPX[1] - dragPX }, + }) + await page.waitForTimeout(100) + await expect(page.locator('.cm-content')).not.toHaveText(prevContent) + prevContent = await page.locator('.cm-content').innerText() + }) + + await test.step('drag circle radius handle', async () => { + await page.waitForTimeout(100) + + const lineEnd = await u.getBoundingBox('[data-overlay-index="0"]') + await page.waitForTimeout(100) + await page.dragAndDrop('#stream', '#stream', { + sourcePosition: { x: lineEnd.x - 5, y: lineEnd.y }, + targetPosition: { x: lineEnd.x + dragPX, y: lineEnd.y + dragPX }, + }) + await expect(page.locator('.cm-content')).not.toHaveText(prevContent) + prevContent = await page.locator('.cm-content').innerText() + }) + + // expect the code to have changed + await expect(page.locator('.cm-content')) + .toHaveText(`const sketch001 = startSketchOn('XZ') + |> circle({ center: [7.26, -2.37], radius: 11.79 }, %) +`) + }) test('Can edit a sketch that has been extruded in the same pipe', async ({ page, }) => { diff --git a/e2e/playwright/snapshot-tests.spec.ts b/e2e/playwright/snapshot-tests.spec.ts index 9aaeda388..c15367894 100644 --- a/e2e/playwright/snapshot-tests.spec.ts +++ b/e2e/playwright/snapshot-tests.spec.ts @@ -532,6 +532,64 @@ test( }) } ) +test( + 'Draft circle should look right', + { tag: '@snapshot' }, + async ({ page, context }) => { + // FIXME: Skip on macos its being weird. + // test.skip(process.platform === 'darwin', 'Skip on macos') + + const u = await getUtils(page) + await page.setViewportSize({ width: 1200, height: 500 }) + const PUR = 400 / 37.5 //pixeltoUnitRatio + + await u.waitForAuthSkipAppStart() + await u.openDebugPanel() + + await expect( + page.getByRole('button', { name: 'Start Sketch' }) + ).not.toBeDisabled() + await expect( + page.getByRole('button', { name: 'Start Sketch' }) + ).toBeVisible() + + // click on "Start Sketch" button + await u.clearCommandLogs() + await u.doAndWaitForImageDiff( + () => page.getByRole('button', { name: 'Start Sketch' }).click(), + 200 + ) + + // select a plane + await page.mouse.click(700, 200) + + await expect(page.locator('.cm-content')).toHaveText( + `const sketch001 = startSketchOn('XZ')` + ) + + await page.waitForTimeout(500) // TODO detect animation ending, or disable animation + await u.closeDebugPanel() + + const startXPx = 600 + + // Equip the rectangle tool + // await page.getByRole('button', { name: 'line Line', exact: true }).click() + await page.getByTestId('circle-center').click() + + // Draw the rectangle + await page.mouse.click(startXPx + PUR * 20, 500 - PUR * 20) + await page.mouse.move(startXPx + PUR * 10, 500 - PUR * 10, { steps: 5 }) + + // Ensure the draft rectangle looks the same as it usually does + await expect(page).toHaveScreenshot({ + maxDiffPixels: 100, + }) + await expect(page.locator('.cm-content')).toHaveText( + `const sketch001 = startSketchOn('XZ') + |> circle({ center: [14.44, -2.44], radius: 1 }, %)` + ) + } +) test.describe( 'Client side scene scale should match engine scale', diff --git a/e2e/playwright/testing-segment-overlays.spec.ts b/e2e/playwright/testing-segment-overlays.spec.ts index 2a08b2a9c..a3faa5b35 100644 --- a/e2e/playwright/testing-segment-overlays.spec.ts +++ b/e2e/playwright/testing-segment-overlays.spec.ts @@ -40,6 +40,7 @@ test.describe('Testing segment overlays', () => { | 'horizontal' | 'vertical' | 'tangentialWithPrevious' + | 'radius' | LineInputsType expectBeforeUnconstrained: string expectAfterUnconstrained: string @@ -121,6 +122,7 @@ test.describe('Testing segment overlays', () => { | 'horizontal' | 'vertical' | 'tangentialWithPrevious' + | 'radius' | LineInputsType expectBeforeUnconstrained: string expectAfterUnconstrained: string @@ -774,6 +776,80 @@ const part001 = startSketchOn('XZ') locator: '[data-overlay-toolbar-index="12"]', }) }) + test('for segment [circle]', async ({ page }) => { + await page.addInitScript(async () => { + localStorage.setItem( + 'persistCode', + `const part001 = startSketchOn('XZ') + |> circle({ center: [1 + 0, 0], radius: 8 }, %) + ` + ) + localStorage.setItem('disableAxis', 'true') + }) + const u = await getUtils(page) + await page.setViewportSize({ width: 1200, height: 500 }) + + await u.waitForAuthSkipAppStart() + + // wait for execution done + await u.openDebugPanel() + await u.expectCmdLog('[data-message-type="execution-done"]') + await u.closeDebugPanel() + + await page + .getByText('circle({ center: [1 + 0, 0], radius: 8 }, %)') + .click() + await page.waitForTimeout(100) + await page.getByRole('button', { name: 'Edit Sketch' }).click() + await page.waitForTimeout(500) + + await expect(page.getByTestId('segment-overlay')).toHaveCount(1) + + const clickUnconstrained = _clickUnconstrained(page) + const clickConstrained = _clickConstrained(page) + + const hoverPos = { x: 789, y: 114 } as const + let ang = await u.getAngle('[data-overlay-index="0"]') + console.log('angl', ang) + console.log('circle center x') + await clickConstrained({ + hoverPos, + constraintType: 'xAbsolute', + expectBeforeUnconstrained: + 'circle({ center: [1 + 0, 0], radius: 8 }, %)', + expectAfterUnconstrained: 'circle({ center: [1, 0], radius: 8 }, %)', + expectFinal: 'circle({ center: [xAbs001, 0], radius: 8 }, %)', + ang: ang + 105, + steps: 6, + locator: '[data-overlay-toolbar-index="0"]', + }) + console.log('circle center y') + await clickUnconstrained({ + hoverPos, + constraintType: 'yAbsolute', + expectBeforeUnconstrained: + 'circle({ center: [xAbs001, 0], radius: 8 }, %)', + expectAfterUnconstrained: + 'circle({ center: [xAbs001, yAbs001], radius: 8 }, %)', + expectFinal: 'circle({ center: [xAbs001, 0], radius: 8 }, %)', + ang: ang + 105, + steps: 10, + locator: '[data-overlay-toolbar-index="0"]', + }) + console.log('circle radius') + await clickUnconstrained({ + hoverPos, + constraintType: 'radius', + expectBeforeUnconstrained: + 'circle({ center: [xAbs001, 0], radius: 8 }, %)', + expectAfterUnconstrained: + 'circle({ center: [xAbs001, 0], radius: radius001 }, %)', + expectFinal: 'circle({ center: [xAbs001, 0], radius: 8 }, %)', + ang: ang + 105, + steps: 10, + locator: '[data-overlay-toolbar-index="0"]', + }) + }) }) test.describe('Testing deleting a segment', () => { const _deleteSegmentSequence = diff --git a/src/components/ModelingMachineProvider.tsx b/src/components/ModelingMachineProvider.tsx index 71b5941d4..6807b6f89 100644 --- a/src/components/ModelingMachineProvider.tsx +++ b/src/components/ModelingMachineProvider.tsx @@ -210,7 +210,8 @@ export const ModelingMachineProvider = ({ pathToNodeString, }, }) - }, 800) as unknown as number + // overlay timeout is 1s + }, 1000) as unknown as number return { ...segmentHoverMap, [pathToNodeString]: timeoutId, diff --git a/src/lang/std/sketch.ts b/src/lang/std/sketch.ts index e03a69146..febf70144 100644 --- a/src/lang/std/sketch.ts +++ b/src/lang/std/sketch.ts @@ -1105,11 +1105,7 @@ export const circle: SketchLineHelper = { isNotLiteralArrayOrStatic(radiusDetails.exp), code.slice(radiusDetails.exp.start, radiusDetails.exp.end), 'circle', - { - type: 'objectProperty', - key: 'radius', - argIndex: 0, - }, + 'radius', [radiusDetails.exp.start, radiusDetails.exp.end], pathToRadiusLiteral ),