Compare commits
	
		
			9 Commits
		
	
	
		
			pierremtb/
			...
			zoom-tweak
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| d87cb03411 | |||
| 3c09d835ef | |||
| 87e412536b | |||
| 576fa5f257 | |||
| 121e563a17 | |||
| af2c58a5b0 | |||
| f089f97285 | |||
| 49951f4326 | |||
| 5766d023ec | 
| @ -3,7 +3,6 @@ import { | ||||
|   makeTemplate, | ||||
|   getUtils, | ||||
|   getMovementUtils, | ||||
|   wiggleMove, | ||||
|   doExport, | ||||
|   metaModifier, | ||||
| } from './test-utils' | ||||
| @ -3302,7 +3301,7 @@ test.describe('Testing segment overlays', () => { | ||||
|         expectAfterUnconstrained, | ||||
|         expectFinal, | ||||
|         ang = 45, | ||||
|         steps = 10, | ||||
|         wait, | ||||
|       }: { | ||||
|         hoverPos: { x: number; y: number } | ||||
|         constraintType: | ||||
| @ -3315,49 +3314,63 @@ test.describe('Testing segment overlays', () => { | ||||
|         expectFinal: string | ||||
|         ang?: number | ||||
|         steps?: number | ||||
|         wait?: number | ||||
|       }) => { | ||||
|         const u = await getUtils(page) | ||||
|         await expect(page.getByText('Added variable')).not.toBeVisible() | ||||
|  | ||||
|         await page.mouse.move(0, 0) | ||||
|         await page.waitForTimeout(1000) | ||||
|         await page.getByTestId('app-logo').hover() | ||||
|         await page.waitForTimeout(100) | ||||
|         await expect(page.locator('.cm-content')).toContainText( | ||||
|           expectBeforeUnconstrained | ||||
|         ) | ||||
|         let x = 0, | ||||
|           y = 0 | ||||
|         x = hoverPos.x + Math.cos(ang * deg) * 32 | ||||
|         y = hoverPos.y - Math.sin(ang * deg) * 32 | ||||
|         await page.mouse.move(x, y) | ||||
|         await wiggleMove(page, x, y, 20, 30, ang, 10, 5) | ||||
|  | ||||
|         await expect(page.locator('.cm-content')).toContainText( | ||||
|           expectBeforeUnconstrained | ||||
|         ) | ||||
|         const constrainedLocator = page.locator( | ||||
|           `[data-constraint-type="${constraintType}"][data-is-constrained="true"]` | ||||
|         ) | ||||
|         await expect(constrainedLocator).toBeVisible() | ||||
|         await constrainedLocator.hover() | ||||
|         await expect( | ||||
|           await page.getByTestId('constraint-symbol-popover').count() | ||||
|         ).toBeGreaterThan(0) | ||||
|         if (wait) { | ||||
|           await page.waitForTimeout(wait) | ||||
|         } | ||||
|         await page.locator('#stream').hover({ | ||||
|           position: { x, y }, | ||||
|           timeout: 5000, | ||||
|         }) | ||||
|  | ||||
|         const constrainedLocator = await u.wiggleMove({ | ||||
|           locatorString: `[data-constraint-type="${constraintType}"][data-is-constrained="true"]`, | ||||
|           pos: { x, y }, | ||||
|           steps: 500, | ||||
|           dist: 30, | ||||
|           ang, | ||||
|           amplitude: 10, | ||||
|           freq: 5, | ||||
|         }) | ||||
|  | ||||
|         await constrainedLocator.click() | ||||
|         await expect(page.locator('.cm-content')).toContainText( | ||||
|           expectAfterUnconstrained | ||||
|         ) | ||||
|         await expect(u.codeLocator).toContainText(expectAfterUnconstrained) | ||||
|  | ||||
|         await page.mouse.move(0, 0) | ||||
|         await page.waitForTimeout(1000) | ||||
|         await page.getByTestId('app-logo').hover() | ||||
|         await page.waitForTimeout(100) | ||||
|         x = hoverPos.x + Math.cos(ang * deg) * 32 | ||||
|         y = hoverPos.y - Math.sin(ang * deg) * 32 | ||||
|         await page.mouse.move(x, y) | ||||
|         await wiggleMove(page, x, y, 20, 30, ang, 10, 5) | ||||
|  | ||||
|         const unconstrainedLocator = page.locator( | ||||
|           `[data-constraint-type="${constraintType}"][data-is-constrained="false"]` | ||||
|         ) | ||||
|         await expect(unconstrainedLocator).toBeVisible() | ||||
|         await unconstrainedLocator.hover() | ||||
|         await expect( | ||||
|           await page.getByTestId('constraint-symbol-popover').count() | ||||
|         ).toBeGreaterThan(0) | ||||
|         if (wait) { | ||||
|           await page.waitForTimeout(wait) | ||||
|         } | ||||
|         await page.locator('#stream').hover({ | ||||
|           position: { x, y }, | ||||
|         }) | ||||
|         const unconstrainedLocator = await u.wiggleMove({ | ||||
|           locatorString: `[data-constraint-type="${constraintType}"][data-is-constrained="false"]`, | ||||
|           pos: { x, y }, | ||||
|           steps: 500, | ||||
|           dist: 30, | ||||
|           ang, | ||||
|           amplitude: 10, | ||||
|           freq: 5, | ||||
|         }) | ||||
|  | ||||
|         await unconstrainedLocator.click() | ||||
|         await page.getByText('Add variable').click() | ||||
|         await expect(page.locator('.cm-content')).toContainText(expectFinal) | ||||
| @ -3381,7 +3394,7 @@ test.describe('Testing segment overlays', () => { | ||||
|         expectAfterUnconstrained, | ||||
|         expectFinal, | ||||
|         ang = 45, | ||||
|         steps = 5, | ||||
|         wait, | ||||
|       }: { | ||||
|         hoverPos: { x: number; y: number } | ||||
|         constraintType: | ||||
| @ -3394,28 +3407,36 @@ test.describe('Testing segment overlays', () => { | ||||
|         expectFinal: string | ||||
|         ang?: number | ||||
|         steps?: number | ||||
|         wait?: number | ||||
|       }) => { | ||||
|         await page.mouse.move(0, 0) | ||||
|         await page.waitForTimeout(1000) | ||||
|         const u = await getUtils(page) | ||||
|         await page.getByTestId('app-logo').hover() | ||||
|         await page.waitForTimeout(100) | ||||
|         let x = 0, | ||||
|           y = 0 | ||||
|         x = hoverPos.x + Math.cos(ang * deg) * 32 | ||||
|         y = hoverPos.y - Math.sin(ang * deg) * 32 | ||||
|         await page.mouse.move(x, y) | ||||
|         await wiggleMove(page, x, y, 20, 30, ang, 10, 5) | ||||
|  | ||||
|         await expect(page.getByText('Added variable')).not.toBeVisible() | ||||
|  | ||||
|         if (wait) { | ||||
|           await page.waitForTimeout(wait) | ||||
|         } | ||||
|         await page.locator('#stream').hover({ | ||||
|           position: { x, y }, | ||||
|         }) | ||||
|  | ||||
|         await expect(page.locator('.cm-content')).toContainText( | ||||
|           expectBeforeUnconstrained | ||||
|         ) | ||||
|         const unconstrainedLocator = page.locator( | ||||
|           `[data-constraint-type="${constraintType}"][data-is-constrained="false"]` | ||||
|         ) | ||||
|         await expect(unconstrainedLocator).toBeVisible() | ||||
|         await unconstrainedLocator.hover() | ||||
|         await expect( | ||||
|           await page.getByTestId('constraint-symbol-popover').count() | ||||
|         ).toBeGreaterThan(0) | ||||
|         const unconstrainedLocator = await u.wiggleMove({ | ||||
|           locatorString: `[data-constraint-type="${constraintType}"][data-is-constrained="false"]`, | ||||
|           pos: { x, y }, | ||||
|           steps: 500, | ||||
|           dist: 30, | ||||
|           ang, | ||||
|           amplitude: 10, | ||||
|           freq: 5, | ||||
|         }) | ||||
|         await unconstrainedLocator.click() | ||||
|         await page.getByText('Add variable').click() | ||||
|         await expect(page.locator('.cm-content')).toContainText( | ||||
| @ -3423,28 +3444,33 @@ test.describe('Testing segment overlays', () => { | ||||
|         ) | ||||
|         await expect(page.getByText('Added variable')).not.toBeVisible() | ||||
|  | ||||
|         await page.mouse.move(0, 0) | ||||
|         await page.waitForTimeout(1000) | ||||
|         await page.getByTestId('app-logo').hover() | ||||
|         await page.waitForTimeout(100) | ||||
|         x = hoverPos.x + Math.cos(ang * deg) * 32 | ||||
|         y = hoverPos.y - Math.sin(ang * deg) * 32 | ||||
|         await page.mouse.move(x, y) | ||||
|         await wiggleMove(page, x, y, 20, 30, ang, 10, 5) | ||||
|  | ||||
|         const constrainedLocator = page.locator( | ||||
|           `[data-constraint-type="${constraintType}"][data-is-constrained="true"]` | ||||
|         ) | ||||
|         await expect(constrainedLocator).toBeVisible() | ||||
|         await constrainedLocator.hover() | ||||
|         await expect( | ||||
|           await page.getByTestId('constraint-symbol-popover').count() | ||||
|         ).toBeGreaterThan(0) | ||||
|         if (wait) { | ||||
|           await page.waitForTimeout(wait) | ||||
|         } | ||||
|         await page.locator('#stream').hover({ | ||||
|           position: { x, y }, | ||||
|         }) | ||||
|         const constrainedLocator = await u.wiggleMove({ | ||||
|           locatorString: `[data-constraint-type="${constraintType}"][data-is-constrained="true"]`, | ||||
|           pos: { x, y }, | ||||
|           steps: 500, | ||||
|           dist: 30, | ||||
|           ang, | ||||
|           amplitude: 10, | ||||
|           freq: 5, | ||||
|         }) | ||||
|         await constrainedLocator.click() | ||||
|         await expect(page.locator('.cm-content')).toContainText(expectFinal) | ||||
|       } | ||||
|     test.setTimeout(120000) | ||||
|     test('for segments [line, angledLine, lineTo, xLineTo]', async ({ | ||||
|       page, | ||||
|     }) => { | ||||
|       test.setTimeout(120_000) | ||||
|       await page.addInitScript(async () => { | ||||
|         localStorage.setItem( | ||||
|           'persistCode', | ||||
| @ -3586,6 +3612,8 @@ test.describe('Testing segment overlays', () => { | ||||
|         ang: ang + 180, | ||||
|       }) | ||||
|  | ||||
|       await page.waitForTimeout(100) | ||||
|       await page.getByTestId('app-logo').hover() | ||||
|       const xLineTo = await u.getBoundingBox(`[data-overlay-index="3"]`) | ||||
|       ang = await u.getAngle(`[data-overlay-index="3"]`) | ||||
|       console.log('xlineTo1') | ||||
| @ -3781,6 +3809,7 @@ const part001 = startSketchOn('XZ') | ||||
|         expectFinal: 'angledLineOfYLength({ angle: -91, length: 19 + 0 }, %)', | ||||
|         ang: ang + 180, | ||||
|         steps: 6, | ||||
|         // wait: 800, | ||||
|       }) | ||||
|       console.log('angledLineOfYLength2') | ||||
|       await clickConstrained({ | ||||
| @ -3798,6 +3827,9 @@ const part001 = startSketchOn('XZ') | ||||
|     test('for segments [angledLineToX, angledLineToY, angledLineThatIntersects]', async ({ | ||||
|       page, | ||||
|     }) => { | ||||
|       test.setTimeout(120_000) | ||||
|       const isWebKit = | ||||
|         page.context().browser()?.browserType().name() !== 'chromium' | ||||
|       await page.addInitScript(async () => { | ||||
|         localStorage.setItem( | ||||
|           'persistCode', | ||||
| @ -3855,6 +3887,7 @@ const part001 = startSketchOn('XZ') | ||||
|         expectAfterUnconstrained: 'angledLineToX({ angle: 3, to: 26 }, %)', | ||||
|         expectFinal: 'angledLineToX({ angle: angle001, to: 26 }, %)', | ||||
|         ang: ang + 180, | ||||
|         wait: isWebKit ? 1000 : 0, | ||||
|       }) | ||||
|       console.log('angledLineToX2') | ||||
|       await clickUnconstrained({ | ||||
| @ -3866,6 +3899,7 @@ const part001 = startSketchOn('XZ') | ||||
|           'angledLineToX({ angle: angle001, to: xAbs001 }, %)', | ||||
|         expectFinal: 'angledLineToX({ angle: angle001, to: 26 }, %)', | ||||
|         ang: ang + 180, | ||||
|         wait: isWebKit ? 1000 : 0, | ||||
|       }) | ||||
|  | ||||
|       const angledLineToY = await u.getBoundingBox(`[data-overlay-index="10"]`) | ||||
| @ -3881,6 +3915,7 @@ const part001 = startSketchOn('XZ') | ||||
|         expectFinal: 'angledLineToY({ angle: 89, to: 9.14 + 0 }, %)', | ||||
|         steps: process.platform === 'darwin' ? 8 : 9, | ||||
|         ang: ang + 180, | ||||
|         wait: isWebKit ? 1000 : 0, | ||||
|       }) | ||||
|       console.log('angledLineToY2') | ||||
|       await clickConstrained({ | ||||
| @ -3891,6 +3926,7 @@ const part001 = startSketchOn('XZ') | ||||
|         expectAfterUnconstrained: 'angledLineToY({ angle: 89, to: 9.14 }, %)', | ||||
|         expectFinal: 'angledLineToY({ angle: 89, to: yAbs001 }, %)', | ||||
|         ang: ang + 180, | ||||
|         wait: isWebKit ? 1000 : 0, | ||||
|       }) | ||||
|  | ||||
|       const angledLineThatIntersects = await u.getBoundingBox( | ||||
| @ -3920,6 +3956,7 @@ const part001 = startSketchOn('XZ') | ||||
|       intersectTag: 'a' | ||||
|     }, %)`, | ||||
|         ang: ang + 180, | ||||
|         wait: isWebKit ? 1000 : 0, | ||||
|       }) | ||||
|       console.log('angledLineThatIntersects2') | ||||
|       await clickUnconstrained({ | ||||
| @ -3944,6 +3981,7 @@ const part001 = startSketchOn('XZ') | ||||
|       intersectTag: 'a' | ||||
|     }, %)`, | ||||
|         ang: ang + 180, | ||||
|         wait: isWebKit ? 1000 : 0, | ||||
|       }) | ||||
|     }) | ||||
|     test('for segment [tangentialArcTo]', async ({ page }) => { | ||||
| @ -4268,7 +4306,7 @@ ${extraLine ? "const myVar = segLen('seg01', part001)" : ''}` | ||||
|           await page.getByText(lineOfInterest).click() | ||||
|           await page.waitForTimeout(100) | ||||
|           await page.getByRole('button', { name: 'Edit Sketch' }).click() | ||||
|           await page.waitForTimeout(500) | ||||
|           await page.waitForTimeout(600) | ||||
|  | ||||
|           await expect(page.getByTestId('segment-overlay')).toHaveCount(3) | ||||
|           const segmentToDelete = await u.getBoundingBox( | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| import { test, expect, Page, Download } from '@playwright/test' | ||||
| import { test, expect, Page, Download, Locator } from '@playwright/test' | ||||
| import { EngineCommand } from '../../src/lang/std/engineConnection' | ||||
| import os from 'os' | ||||
| import fsp from 'fs/promises' | ||||
| @ -99,30 +99,6 @@ async function waitForCmdReceive(page: Page, commandType: string) { | ||||
|     .waitFor() | ||||
| } | ||||
|  | ||||
| export const wiggleMove = async ( | ||||
|   page: any, | ||||
|   x: number, | ||||
|   y: number, | ||||
|   steps: number, | ||||
|   dist: number, | ||||
|   ang: number, | ||||
|   amplitude: number, | ||||
|   freq: number | ||||
| ) => { | ||||
|   const tau = Math.PI * 2 | ||||
|   const deg = tau / 360 | ||||
|   const step = dist / steps | ||||
|   for (let i = 0, j = 0; i < dist; i += step, j += 1) { | ||||
|     const [x1, y1] = [0, Math.sin((tau / steps) * j * freq) * amplitude] | ||||
|     const [x2, y2] = [ | ||||
|       Math.cos(-ang * deg) * i - Math.sin(-ang * deg) * y1, | ||||
|       Math.sin(-ang * deg) * i + Math.cos(-ang * deg) * y1, | ||||
|     ] | ||||
|     const [xr, yr] = [x2, y2] | ||||
|     await page.mouse.move(x + xr, y + yr, { steps: 2 }) | ||||
|   } | ||||
| } | ||||
|  | ||||
| export const getMovementUtils = (opts: any) => { | ||||
|   // The way we truncate is kinda odd apparently, so we need this function | ||||
|   // "[k]itty[c]ad round" | ||||
| @ -317,6 +293,72 @@ export async function getUtils(page: Page) { | ||||
|  | ||||
|       cdpSession?.send('Network.emulateNetworkConditions', networkOptions) | ||||
|     }, | ||||
|     wiggleMove: async ({ | ||||
|       locatorString, | ||||
|       pos: { x, y }, | ||||
|       steps, | ||||
|       dist, | ||||
|       ang, | ||||
|       amplitude, | ||||
|       freq, | ||||
|     }: { | ||||
|       locatorString: string | ||||
|       pos: { x: number; y: number } | ||||
|       steps: number | ||||
|       dist: number | ||||
|       ang: number | ||||
|       amplitude: number | ||||
|       freq: number | ||||
|     }) => { | ||||
|       return new Promise<Locator>(async (resolve) => { | ||||
|         const locator = await page.locator(locatorString) | ||||
|         const isElementGoodToGo = async (): Promise<boolean> => { | ||||
|           const isVisible = await locator.isVisible() | ||||
|           if (isVisible) { | ||||
|             try { | ||||
|               await locator.hover({ timeout: 100 }) | ||||
|  | ||||
|               const count = await page | ||||
|                 .getByTestId('constraint-symbol-popover') | ||||
|                 .count() | ||||
|               if (count < 1) { | ||||
|                 throw new Error('nope, try again') | ||||
|               } | ||||
|  | ||||
|               return true | ||||
|             } catch (e) { | ||||
|               // do nothing, we'll try again later | ||||
|             } | ||||
|           } | ||||
|           return false | ||||
|         } | ||||
|         if (await isElementGoodToGo()) { | ||||
|           resolve(locator) | ||||
|           return | ||||
|         } | ||||
|  | ||||
|         const tau = Math.PI * 2 | ||||
|         const deg = tau / 360 | ||||
|         const step = dist / steps | ||||
|         for (let i = 0, j = 0; i < dist; i += step, j += 1) { | ||||
|           const y1 = Math.sin((tau / steps) * j * freq) * amplitude | ||||
|           const [x2, y2] = [ | ||||
|             Math.cos(-ang * deg) * i - Math.sin(-ang * deg) * y1, | ||||
|             Math.sin(-ang * deg) * i + Math.cos(-ang * deg) * y1, | ||||
|           ] | ||||
|           const [xr, yr] = [x2, y2] | ||||
|           await page.locator('#stream').hover({ | ||||
|             position: { x: x + xr, y: y + yr }, | ||||
|           }) | ||||
|           if (await isElementGoodToGo()) { | ||||
|             resolve(locator) | ||||
|             return | ||||
|           } | ||||
|           await page.waitForTimeout(100) | ||||
|         } | ||||
|         throw new Error('Element not found') | ||||
|       }) | ||||
|     }, | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -433,7 +433,6 @@ export class CameraControls { | ||||
|   } | ||||
|  | ||||
|   onMouseWheel = (event: WheelEvent) => { | ||||
|     // Assume trackpad if the deltas are small and integers | ||||
|     this.handleStart() | ||||
|  | ||||
|     if (this.syncDirection === 'engineToClient') { | ||||
| @ -445,12 +444,35 @@ export class CameraControls { | ||||
|         return | ||||
|       } | ||||
|       this.engineCommandManager.sendSceneCommand({ | ||||
|         type: 'modeling_cmd_req', | ||||
|         cmd: { | ||||
|           type: 'default_camera_zoom', | ||||
|           magnitude: -event.deltaY * 0.4, | ||||
|         }, | ||||
|         cmd_id: uuidv4(), | ||||
|         type: 'modeling_cmd_batch_req', | ||||
|         batch_id: uuidv4(), | ||||
|         requests: [ | ||||
|           { | ||||
|             cmd: { | ||||
|               type: 'camera_drag_start', | ||||
|               interaction: 'zoom', | ||||
|               window: { x: 5, y: 5 }, | ||||
|             }, | ||||
|             cmd_id: uuidv4(), | ||||
|           }, | ||||
|           { | ||||
|             cmd: { | ||||
|               type: 'camera_drag_move', | ||||
|               interaction: 'zoom', | ||||
|               window: { x: 0, y: 5 - event.deltaY }, | ||||
|             }, | ||||
|             cmd_id: uuidv4(), | ||||
|           }, | ||||
|           { | ||||
|             cmd: { | ||||
|               type: 'camera_drag_end', | ||||
|               interaction: 'zoom', | ||||
|               window: { x: 5, y: 5 - event.deltaY }, | ||||
|             }, | ||||
|             cmd_id: uuidv4(), | ||||
|           }, | ||||
|         ], | ||||
|         responses: false, | ||||
|       }) | ||||
|       this.handleEnd() | ||||
|       return | ||||
|  | ||||
| @ -7,7 +7,6 @@ import { | ||||
|   getSelectionType, | ||||
|   getSelectionTypeDisplayText, | ||||
| } from 'lib/selections' | ||||
| import { kclManager } from 'lib/singletons' | ||||
| import { modelingMachine } from 'machines/modelingMachine' | ||||
| import { useCallback, useEffect, useRef, useState } from 'react' | ||||
| import { useHotkeys } from 'react-hotkeys-hook' | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	